一张表看懂 Android 8-15 所有适配要点

一张表看懂 Android 8-15 所有适配要点

Android 系统每年发布一个新版本,每个版本都有行为变更和新的限制。本文以表格形式汇总 Android 8 到 Android 15 所有需要适配的核心要点,方便开发者快速查阅。建议收藏,新版本发布后会持续更新。


一、快速查阅总表

Android 版本 API 发布年份 必须适配的核心变更 适配优先级
8.0 Oreo 26 2017 通知渠道、后台执行限制 中(旧设备)
9.0 Pie 28 2018 Apache HTTP 移除、前台服务权限 中(旧设备)
10 Q 29 2019 分区存储、后台启动 Activity 限制 高(大量设备)
11 R 30 2020 包可见性、单次权限 高
12 S 31 2021 SplashScreen API、PendingIntent 可变性 高
13 Tiramisu 33 2022 通知权限、精细化媒体权限 高
14 Upside Down Cake 34 2023 前台服务类型、广播注册导出声明 高
15 Vanilla Ice Cream 35 2024 Edge-to-Edge、16KB 页面、前台服务超时 高(Google Play 强制)

二、Android 8.0(API 26)适配要点

变更 影响 适配方案
通知渠道(Notification Channel) targetSdk ≥ 26 必须创建渠道才能显示通知 使用 NotificationChannel 创建渠道
后台执行限制 对后台应用限制 Service 和 Broadcast 改用 JobIntentService、WorkManager
安装 APK 需要权限 安装 APK 需要 REQUEST_INSTALL_PACKAGES 权限 在 Manifest 中声明权限,并引导用户授权
透明 Activity 限制 不允许透明主题的全屏 Activity 移除透明主题或改为 Dialog 样式

代码示例:创建通知渠道

kotlin 复制代码
// Android 8.0+ 必须创建通知渠道
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    val channel = NotificationChannel(
        "default_channel_id",
        "默认通知渠道",
        NotificationManager.IMPORTANCE_DEFAULT
    ).apply {
        description = "默认渠道描述"
    }
    val notificationManager = getSystemService(NotificationManager::class.java)
    notificationManager.createNotificationChannel(channel)
}

三、Android 9.0(API 28)适配要点

变更 影响 适配方案
Apache HTTP 客户端移除 使用了 org.apache.http 的应用会崩溃 在 Manifest 中添加 useLibrary 'org.apache.http.legacy'
前台服务需要权限 启动前台服务需要 FOREGROUND_SERVICE 权限 在 Manifest 中声明权限
刘海屏适配 需要适配 DisplayCutout 使用 WindowInsets.getDisplayCutout()
HTTPS 网络请求限制 默认禁止明文流量(HTTP) 创建 res/xml/network_security_config.xml 允许明文流量,或全量迁移到 HTTPS

代码示例:允许明文流量(仅调试环境)

xml 复制代码
<!-- res/xml/network_security_config.xml -->
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config>
        <domain includeSubdomains="true">example.com</domain>
        <trust-anchors>
            <certificates src="user" />
        </trust-anchors>
    </domain-config>
</network-security-config>

<!-- AndroidManifest.xml 中 application 标签添加 -->
android:networkSecurityConfig="@xml/network_security_config"

四、Android 10(API 29)适配要点

变更 影响 适配方案
Scoped Storage(分区存储) 外部存储访问受限 使用 MediaStore 访问媒体文件
后台启动 Activity 限制 不能直接从后台启动 Activity 使用通知引导用户点击,或申请 SYSTEM_ALERT_WINDOW 权限
深色模式(Dark Mode) 系统级深色模式 适配 DayNight 主题
手势导航适配 需要处理 Window Insets 使用 ViewCompat.setOnApplyWindowInsetsListener

代码示例:兼容深色模式

kotlin 复制代码
// styles.xml(日间主题)
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
    <item name="colorPrimary">@color/primary</item>
    <item name="colorPrimaryDark">@color/primaryDark</item>
</style>

// colors.xml 中提供日间和夜间两套颜色
// values/colors.xml → 日间颜色
// values-night/colors.xml → 夜间颜色

五、Android 11(API 30)适配要点

变更 影响 适配方案
包可见性(Package Visibility) 查询其他应用需要声明 <queries> 在 Manifest 中添加 <queries> 元素
单次权限(One-time Permission) 位置、麦克风、摄像头支持单次授权 无需额外适配,系统自动处理
权限对话框频繁请求限制 用户在短时间内拒绝两次后,第三次不再弹出对话框 引导用户到设置页面授权
前台服务类型 需要指定前台服务类型(Android 14 强制) 提前声明 foregroundServiceType

代码示例:声明包可见性

xml 复制代码
<!-- 查询所有已安装应用(需要权限) -->
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />

<!-- 或精确声明需要查询的应用 -->
<queries>
    <package android:name="com.example.targetapp" />
    <intent>
        <action android:name="android.intent.action.SEND" />
    </intent>
</queries>

六、Android 12(API 31)适配要点

变更 影响 适配方案
SplashScreen API 统一启动页规范 使用 SplashScreen 兼容库
PendingIntent 必须声明可变性 不声明会崩溃 显式指定 FLAG_MUTABLE 或 FLAG_IMMUTABLE
前台服务通知延迟 前台服务启动后通知会延迟显示 无需适配,了解行为变化即可
蓝牙权限细化 旧蓝牙权限废弃 使用 BLUETOOTH_SCAN / BLUETOOTH_CONNECT
精确闹钟权限 需要 SCHEDULE_EXACT_ALARM 权限 请求权限或使用非精确闹钟

代码示例:PendingIntent 可变性

kotlin 复制代码
val pendingIntent = PendingIntent.getActivity(
    context,
    requestCode,
    intent,
    // ✅ 必须显式指定可变性
    PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)

代码示例:SplashScreen 适配

kotlin 复制代码
// 在 Activity 的 onCreate 中
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    
    // Android 12+ 的 SplashScreen API
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        val splashScreen = installSplashScreen()
        // 保持启动页,直到应用准备好
        splashScreen.setKeepOnScreenCondition { !isAppReady }
    }
    
    setContentView(R.layout.activity_main)
}

七、Android 13(API 33)适配要点

变更 影响 适配方案
通知权限 需要动态申请 POST_NOTIFICATIONS 权限 使用 requestPermissionLauncher 请求权限
精细化媒体权限 READ_EXTERNAL_STORAGE 拆分为三个权限 使用 READ_MEDIA_IMAGES 等权限
Wi-Fi 权限变更 靠近 Wi-Fi 设备不需要位置权限 使用 NEARBY_WIFI_DEVICES 权限
Clipboard 内容隐藏 敏感内容可以隐藏在剪贴板中 使用 ClipDescription.EXTRA_IS_SENSITIVE

代码示例:请求通知权限

kotlin 复制代码
private val requestPermissionLauncher =
    registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
        if (isGranted) {
            showNotification()
        } else {
            // 引导用户到设置页面开启
        }
    }

fun checkNotificationPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        if (ContextCompat.checkSelfPermission(
                this,
                Manifest.permission.POST_NOTIFICATIONS
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
        }
    }
}

八、Android 14(API 34)适配要点

变更 影响 适配方案
前台服务类型必须声明 Manifest 中必须指定 foregroundServiceType 在 <service> 标签中添加 android:foregroundServiceType
动态广播注册必须指定导出行为 registerReceiver() 必须传 RECEIVER_EXPORTED 或 RECEIVER_NOT_EXPORTED 显式指定导出行为
OpenJDK 17 行为变更 正则表达式、UUID 生成等行为变化 回归测试核心逻辑
更严格的 Intent 过滤规则 Intent 过滤器必须显式声明 exported 在 Manifest 中显式声明

代码示例:注册广播(Android 14+ 兼容)

kotlin 复制代码
val filter = IntentFilter("com.example.MY_ACTION")

// 接收其他应用的广播 → 需要导出
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
    context.registerReceiver(myReceiver, filter, Context.RECEIVER_EXPORTED)
} else {
    context.registerReceiver(myReceiver, filter)
}

// 只接收应用内部广播 → 不导出(更安全)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
    context.registerReceiver(myReceiver, filter, Context.RECEIVER_NOT_EXPORTED)
}

九、Android 15(API 35)适配要点

变更 影响 适配方案
Edge-to-Edge 强制适配 应用显示区域扩展至全屏 使用 WindowInsets 处理系统栏间距
16KB 页面大小 使用 NDK 的应用需要适配 升级 AGP 到 8.3+,重新编译 so 库
前台服务超时限制 dataSync/mediaProcessing 类型有 24 小时时长限制 改用 WorkManager 或处理 onTimeout 回调
最低 targetSdk 要求 targetSdk < 24 无法安装 升级 targetSdkVersion 到 24+
OpenJDK 17 对齐 字符串格式化等行为变更 避免使用 %0$s 等不合规格式

代码示例:Edge-to-Edge 适配(非 Compose)

kotlin 复制代码
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.root)) { v, insets ->
    val statusBar = insets.getInsets(WindowInsetsCompat.Type.statusBars())
    val navigationBar = insets.getInsets(WindowInsetsCompat.Type.navigationBars())
    
    v.setPadding(
        navigationBar.left,
        statusBar.top,
        navigationBar.right,
        navigationBar.bottom
    )
    
    insets
}

十、Gradle 配置建议(2026 年推荐)

gradle 复制代码
// app/build.gradle
android {
    compileSdk 35
    
    defaultConfig {
        minSdk 21        // 覆盖 99%+ 设备
        targetSdk 35      // 紧跟最新版本
        multiDexEnabled true
    }
    
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }
    
    kotlinOptions {
        jvmTarget = '17'
    }
}

dependencies {
    implementation "androidx.core:core-ktx:1.13.0"
    implementation "androidx.activity:activity-ktx:1.9.0"
    implementation "androidx.fragment:fragment-ktx:1.7.0"
}

十一、适配优先级建议

根据应用的目标用户和业务需求,按以下优先级进行适配:

优先级 版本 理由
P0(立即适配) Android 15 Google Play 强制要求
P0(立即适配) Android 13 通知权限影响消息到达
P1(3 个月内) Android 14 前台服务类型、广播注册
P1(3 个月内) Android 12 PendingIntent 可变性(安全)
P2(6 个月内) Android 10/11 分区存储、包可见性
P3(按需适配) Android 8/9 存量设备较少

十二、参考资源


本文会持续更新,建议收藏。如果你发现某个版本的适配要点有遗漏,欢迎在评论区补充。如果本文对你有帮助,欢迎点赞收藏。

相关推荐
三少爷的鞋5 小时前
AI 时代,我们都将成为通才型开发者:只懂 Android,已经不够了
android
Dovis(誓平步青云)9 小时前
家里设备越来越多,如何用一张空间地图控制灯光和温度![
android·java·前端·javascript·人工智能·电脑
晚风叙码10 小时前
MySQL 数据类型详解:从数值到字符串,一篇讲透
android·mysql·adb
传奇开心果编程11 小时前
【Compose Multiplatform 跨端开发学与练】第3课 布局与组件
android·windows·学习·ui·ios·kotlin·composer
传奇开心果编程14 小时前
【Compose Multiplatform 跨端开发学与练】第8课 资源管理与主题
android·windows·学习·ios·kotlin·web·composer
传奇开心果编程15 小时前
【Compose Multiplatform 跨端开发学与练】第9课 测试与调试
android·学习·macos·ios·kotlin·web·composer
传奇开心果编程15 小时前
【Compose Multiplatform 跨端开发学与练】第4课 导航与路由
android·windows·学习·ui·ios·kotlin·composer
传奇开心果编程16 小时前
【Compose Multiplatform 跨端开发学与练】第6课 状态管理与架构
android·学习·ui·ios·架构·kotlin·composer
事圆则缓16 小时前
Android AOSP 定制常见概念:源码目录、系统镜像与刷机流程
android
传奇开心果编程16 小时前
【Compose Multiplatform 跨端开发学与练】第2课 Compose 基础语法
android·windows·学习·ui·ios·kotlin·composer