Android 版本适配文档(Android 12 → 17)

8 阅读42分钟

目录


一、Android 12(API 31)

1.1 行为变更

1.1.1 所有应用(不论 targetSdkVersion)

变更项关键细节
沉浸模式手势导航改进弃用 BEHAVIOR_SHOW_BARS_BY_TOUCHBEHAVIOR_SHOW_BARS_BY_SWIPE,统一映射为 BEHAVIOR_DEFAULT;粘性沉浸 BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE 不变
前台服务通知延迟系统延迟 10s 显示通知。例外:含操作按钮、foregroundServiceTypeconnectedDevice/mediaPlayback/mediaProjection/phoneCall、通话/导航/媒体播放用例、或调用 setShowForegroundImmediately()
MAC 地址限制target 12 返回 null;target 11- 返回 02:00:00:00:00:00。Logcat:Compat change id reported: 170188668
不受信任触摸事件屏蔽 ⚠️FLAG_NOT_TOUCHABLE 叠加层(TYPE_APPLICATION_OVERLAYToast)阻挡穿透触摸。允许穿透例外:应用内互动、可信窗口(TYPE_ACCESSIBILITY_OVERLAY/TYPE_INPUT_METHOD/Google 助理窗口)、不可见窗口、全透明(alpha 0.0)、足够半透明(组合不透明度 ≤ 0.8,用 InputManager.getMaximumObscuringOpacityForTouch() 查询)。Logcat:Untrusted touch due to occlusion by package_name。测试:adb shell am compat disable BLOCK_UNTRUSTED_TOUCHES com.example.app
无法关闭系统对话框弃用 ACTION_CLOSE_SYSTEM_DIALOGS。target 12 抛 SecurityException;低版本 Logcat 显示 Permission Denial: ... requires android.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS
Display API 废弃沙盒化废弃 Display.getRealSize()getRealMetrics()getSize()getMetrics() 先前已废弃)。推荐 WindowManager.getCurrentWindowMetrics()getMaximumWindowMetrics()、Jetpack androidx.window.WindowManagerConfiguration.densityDpi
刷新率切换改进setFrameRate() 无论是否无缝都生效;getAlternativeRefreshRates() 提前判断;onDisplayChanged() 回调
麦克风/摄像头设备开关设备级开关切断所有应用摄像头/麦克风。检查支持:SensorPrivacyManager.supportsSensorToggle(Sensors.MICROPHONE/CAMERA)。关闭后获空白画面/无音频;应急电话自动开麦;HIGH_SAMPLING_RATE_SENSORS 采样率受限
麦克风/摄像头指示标志状态栏显示图标,沉浸模式在右上角
权限包可见性getAllPermissionGroups()getPermissionGroupInfo()getPermissionInfo()queryPermissionsByGroup()PackageManager 包可见性过滤
移除 Bouncy Castle ⚠️加密改由 Conscrypt 实现:不支持 512 位密钥;AES 仅支持 128/192/256 位;GCM 的 GcmParameterSpec 必须 12 字节
剪贴板访问通知首次跨应用 getPrimaryClip() 显示 APP pasted from your clipboard.getPrimaryClipDescription() 不显示,新增 isStyledText()getConfidenceScore()
Task 间过渡动画Activity.overridePendingAppTransitionActivityOptions.makeCustomAnimation 无法作用于 Task 间跳转。需用主题 windowAnimationStyletaskOpenEnterAnimation 等,并设 windowDisablePreview=true

1.1.2 以 Android 12 为目标平台(targetSdk = 31)

  1. WebView SameSite Cookie:无 SameSite 视为 LaxSameSite=None 必须带 Secure;HTTP/HTTPS 间视为跨站。
  2. adb backup:默认不导出应用数据,需 android:debuggable="true"(发布前改回 false)。
  3. 组件安全性(强制项,不满足安装失败/抛异常) ⚠️
    • <intent-filter>activity/service/receiver 必须显式声明 android:exported,否则安装失败:Targeting S+ ... requires that an explicit value for android:exported be defined when intent filters are present
    • 创建 PendingIntent 必须指定可变性FLAG_MUTABLEFLAG_IMMUTABLE,否则抛 IllegalArgumentException: Targeting S+ ... requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified。推荐不可变;可变场景:通知直接回复、气泡。
    • 嵌套 intent 不安全启动:从 intent extra 解封并立即启动组件触发 StrictMode 违规,用 detectUnsafeIntentLaunch() 捕获;建议用 PendingIntent 替代。
  4. 前台服务启动限制:后台无法启动前台服务(特定例外除外),推荐 WorkManager 2.7.0-alpha01 加急作业。
  5. 非 SDK 接口限制:更新受限列表(灰名单转黑名单、部分入 SDK),用 StrictMode.detectNonSdkApiUsage() 捕获。
  6. 自定义通知变更 ⚠️:完全自定义通知改用标准模板(类似 Notification.DecoratedCustomViewStyle);收起高度从 106dp 降至 48dpsetCustomContentView() 等需重测;渠道重要性需「高」才弹出。
  7. 连接性:支持多点并发 WifiManager.isMultiStaConcurrencySupported(),P2P 不断开 Wi-Fi。
  8. 大致位置 ⚠️:请求 ACCESS_FINE_LOCATION 必须同时请求 ACCESS_COARSE_LOCATION,对话框提供「确切/大致」选项。
  9. 应用休眠:数月未互动自动重置权限并休眠(缓存清除、无后台作业、无推送)。豁免:DeviceAdminService、设备/资料所有者 DPC。退出休眠需重新调度(WorkManagerACTION_BOOT_COMPLETED)。测试:adb shell device_config put app_hibernation app_hibernation_enabled true + cmd app_hibernation set-state
  10. 通知 trampoline 限制 ⚠️:服务或广播接收器内无法调 startActivity() 启动 activity。Logcat:Indirect notification activity start (trampoline) from PACKAGE_NAME...。需用 PendingIntent 关联通知。

1.2 权限与隐私调整

  • MAC 地址:占位或 null,无专门权限但系统强制限制。
  • 媒体管理MANAGE_MEDIAREAD_EXTERNAL_STORAGEACCESS_MEDIA_LOCATION 用于 MediaStore.createWriteRequest()/createTrashRequest()/createDeleteRequest()ACTION_REQUEST_MANAGE_MEDIA 引导设置。
  • 存储访问MANAGE_EXTERNAL_STORAGEQUERY_ALL_PACKAGES 用于文件管理应用调 getManageSpaceActivityIntent()android:manageSpaceActivity 属性。
  • 摄像头/麦克风CAMERARECORD_AUDIOHIGH_SAMPLING_RATE_SENSORSSensorPrivacyManagerSensors.CAMERA/MICROPHONE
  • 位置ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION 成对请求。
  • 剪贴板:跨应用 getPrimaryClip() 触发系统消息框。
  • 包可见性queryPermissionsByGroup 等方法受过滤。
  • 应用休眠:自动重置上述所有权限(设备策略豁免)。

1.3 新增 API

  • 接收内容统一 APIOnReceiveContentListener.onReceiveContent(View, ContentInfoCompat)ContentInfoCompat.partition() 分离 URI 与非 URI;需 AndroidX Core 1.5.0-beta1、Appcompat 1.3.0-beta-01。
  • 兼容的媒体转码res/xml/media_capabilities.xml<format android:name="HEVC" supported="true"/>;清单引用 android:name="android.media.PROPERTY_MEDIA_CAPABILITIES";代码 ApplicationMediaCapabilities.Builder();访问 ContentResolver.openTypedAssetFileDescriptor()MediaStore.EXTRA_MEDIA_CAPABILITIES Bundle。支持 HEVC/HDR10/HDR10+ 自动转 AVC SDR。
  • 企业功能:密码复杂度(高/中/低/无)、工作资料安全验证简化、注册特定 ID 恢复出厂后稳定。
  • SplashScreenSplashScreen/SplashScreenView;主题 windowSplashScreenBackgroundwindowSplashScreenAnimatedIconAnimationDrawable/AnimatedVectorDrawable,时长 ≤1000ms 由 windowSplashScreenAnimationDuration 设)、windowSplashScreenIconBackgroundwindowSplashScreenBrandingImage(建议不用);延迟显示用 ViewTreeObserver.OnPreDrawListener;退出动画 Activity.getSplashScreen().setOnExitAnimationListener + SplashScreenView.getIconAnimationDurationMillis()/getIconAnimationStartMillis()
  • 画中画改进:单击显示控件,双击切换最大/原始;setAutoEnterEnabled(true) 手势导航更流畅;setSeamlessResizeEnabled(false) 非视频停用无缝;setSourceRectHint() 退出动画更流畅;新手势拖至边缘隐藏、双指张合缩放。
  • 存储:新目录 Environment.DIRECTORY_RECORDINGS、媒体库标记 IS_RECORDINGMediaStore.getMediaUri() 支持 MediaDocumentsProvider URI;createWriteRequest() 授予的 URI 支持 File API(读写重命名删除)。

1.4 废弃与受限 API

  • 沉浸模式 BEHAVIOR_SHOW_BARS_BY_TOUCHBEHAVIOR_SHOW_BARS_BY_SWIPE(映射 BEHAVIOR_DEFAULT)。
  • Display.getRealSize()getRealMetrics()(推荐 WindowMetrics)。
  • Bouncy Castle 的 AES 等实现(强制 Conscrypt)。
  • ACTION_CLOSE_SYSTEM_DIALOGS
  • Activity.overridePendingAppTransitionActivityOptions.makeCustomAnimation(Task 间失效)。
  • 非 SDK 接口:更新受限列表。
  • 自定义通知:弃用全区域自定义布局(强制标准模板)。

1.5 适配要点与注意事项

编译配置compileSdkVersion("android-S")targetSdkVersion("S")

两阶段迁移

  1. 确保兼容(不改 targetSdkVersion):测试「所有应用」行为变更;StrictMode.detectNonSdkApiUsage() 捕获非 SDK;测试库和 SDK;用兼容性框架(可调试应用切换开关、adb 管理、变更 ID 调试)。
  2. 更新 targetSdkVersion:重点解决显式 android:exported、PendingIntent 标志、后台前台服务限制、大致位置双权限、通知 trampoline。

⚠️ 第三方加固工具必须更新(否则 FC/ANR,文档内测实测):

  • 爱加密java.lang.VerifyErrorFragmentController.attachHost 崩溃。
  • 梆梆SIGSEGV in libDexHelper.soSuperNotCalledException: Activity {xxx} did not call through to super.onCreate()(须最新版)。
  • 乐固SIGABRT JNI GetObjectField 空指针;NoClassDefFoundError: androidx.core.content.FileProvider$PathStrategy
  • 360NoClassDefFoundError: com.stub.StubApp
  • 百度SIGSEGV in libbaiduprotect.so

其他注意:自定义通知高度缩小需 UI 重适配;麦克风/摄像头用户授权前不使用;adb backup 调试后务必关 debuggable;嵌套 Intent 改 PendingIntent 避免 StrictMode 违规。


二、Android 13(API 33)

2.1 行为变更

2.1.1 所有应用

变更项关键细节
前台服务任务管理器 ⚠️通知抽屉显示「使用中的应用」+「停止」按钮。用户按「停止」停止整个应用不发任何回调。检查 ApplicationExitInfo 新增 REASON_USER_REQUESTED。长时间运行 FGS(24h 内 ≥20h)系统发通知邀请互动。完全豁免显示:系统级、ROLE_EMERGENCY、演示模式。免于被停止:设备/资料所有者、常驻应用、ROLE_DIALER。测试:adb shell cmd activity stop-app PACKAGE_NAME
JobScheduler 预提取改进JobInfo.Builder.setPrefetch(true) 标记预提取,系统按估算下次启动时间运行
电池资源利用率进入「受限」应用待机分区新规则:8天无互动、24h内过多广播/绑定、耗电大。受限后台电池限制(仅 target 13 生效):无法启动前台服务、现有 FGS 移除、不触发闹钟、不执行作业、不传 BOOT_COMPLETED/LOCKED_BOOT_COMPLETED。系统通知:后台耗电过高(24h)、长时间运行 FGS(24h≥20h 且类型非 MEDIA_PLAYBACK/LOCATION 才显示;>4h 这些类型也不发 FGS 通知)。免受限分区:活跃 widget、SCHEDULE_EXACT_ALARMACCESS_BACKGROUND_LOCATION。测试:adb shell cmd appops set PACKAGE_NAME RUN_ANY_IN_BACKGROUND deny + adb shell am set-standby-bucket PACKAGE_NAME restricted

2.1.2 以 Android 13 为目标平台(targetSdk = 33)

  1. 通知运行时权限 ⚠️:POST_NOTIFICATIONS(详见 2.2)。
  2. 附近 Wi-Fi 设备新权限 ⚠️:NEARBY_WIFI_DEVICES(详见 2.2)。
  3. 后台身体传感器新权限BODY_SENSORS_BACKGROUND + BODY_SENSORS(详见 2.2)。
  4. intent 过滤器屏蔽不匹配 intent:向其他应用导出组件发 intent 时,仅当与 <intent-filter> 匹配才传送。例外:无过滤器组件、发给自己、系统发送、根级特权用户。
  5. 更安全地导出动态注册接收器 ⚠️:启用 DYNAMIC_RECEIVER_EXPLICIT_EXPORT_REQUIRED 兼容变更;必须指定 RECEIVER_EXPORTEDRECEIVER_NOT_EXPORTED,否则抛 SecurityException
    context.registerReceiver(sharedReceiver, filter, RECEIVER_EXPORTED);
    context.registerReceiver(privateReceiver, filter, RECEIVER_NOT_EXPORTED);
    

2.2 权限与隐私调整

  • 通知权限 POST_NOTIFICATIONS:清单声明 <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>。新装默认关;用户选「不允许」后仅点一次则不再提示(除非重装);滑开对话框可能保留临时授权。豁免:MediaSession 相关通知不受限。检查 NotificationManager.areNotificationsEnabled()
  • 附近 Wi-Fi 设备 NEARBY_WIFI_DEVICES:属 NEARBY_DEVICES 权限组,替代部分 ACCESS_FINE_LOCATION 场景。不需定位时声明 android:usesPermissionFlags="neverForLocation";向后兼容 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="32" />。仍需位置的 API:WifiManager.getScanResults()startScan()。需要此权限的 API:startLocalOnlyHotspot()WifiAwareManager.attach()WifiP2pManager.connect()WifiRttManager.startRanging() 等(未获权限抛 SecurityException)。
  • 后台身体传感器 BODY_SENSORS_BACKGROUND:target 13 且后台访问身体传感器时,需此权限 + BODY_SENSORS受限权限(硬性限制),需设备安装器列入许可名单。
  • 可由开发者降级的权限Context.revokeSelfPermissionOnKill(String) 撤单权限;Context.revokeSelfPermissionsOnKill(Collection<String>) 撤一组(需撤组内所有权限,系统设置才标不访问该组)。异步终止 UID 进程;有前台组件或他应用访问时不发生。
  • 照片选择器隐私MediaStore.ACTION_PICK_IMAGES 无需整个媒体库权限;返回 URI 不能持续访问,进程结束后无法访问。

2.3 新增 API

  • 照片选择器MediaStore.ACTION_PICK_IMAGESMediaStore.EXTRA_PICK_IMAGES_MAXandroid.provider.extra.PICK_IMAGES_MAX);上限 MediaStore.getPickImagesMaxLimit();类型过滤 intent.setType("video/*"|"images/*"|"image/gif");结果 data.getData()(单选)/ data.getClipData().getItemAt(i).getUri()(多选)。
  • 应用内语言选择器
    • AndroidX(Appcompat 1.6.0-alpha01+):AppCompatDelegate.setApplicationLocales(LocaleListCompat.forLanguageTags("xx-YY"))
    • 框架:Context.getSystemService(LocaleManager.class).setApplicationLocales(new LocaleList(Locale.forLanguageTag("xx-YY"))) / getApplicationLocales()
  • 可编程着色器RuntimeShader 对象,使用 Android 图形着色语言 (AGSL)。
  • 更快断字TextView.setHyphenationFrequency() 新值 Layout.HYPHENATION_FREQUENCY_FULL_FAST(xml fullFast)、HYPHENATION_FREQUENCY_NORMAL_FAST(xml normalFast)。
  • 其他:JobInfo.Builder.setPrefetch(boolean)ApplicationExitInfo 新原因 REASON_USER_REQUESTED、兼容变更 ID DYNAMIC_RECEIVER_EXPLICIT_EXPORT_REQUIRED

2.4 废弃与受限 API

文档未明确列出被废弃 API 名称。仅建议:

  • 自定义应用内语言选择器改用 AppCompatDelegate / LocaleManager
  • 断字新增 fullFast/normalFast 模式(未废弃旧模式)。

2.5 适配要点与注意事项

两阶段迁移:①确保兼容(不改 targetSdkVersion,检查受限非 SDK,测库/SDK);②更新目标平台(targetSdkVersion/compileSdkVersion → 13)。

target 13 通知权限弹窗差异

  • target 13+:通知权限弹窗完全自行控制(首次启动 activity 前);临时授权持续到首次启动 activity。
  • target 12L (API 32) 或更低:创建首个通知渠道时弹通知权限;临时授权持续到用户明确选择;失去上下文请求机会。

⚠️ Native Crash:移动安全联盟 msa SDK 崩溃,特征 linker64 报错 signal 11 (SIGSEGV), code 2 (SEGV_ACCERR),backtrace 含 __dl__ZNK6soinfo10gnu_lookup。需联系 SDK 提供方更新。

注意事项

  • 照片选择器上限设 1 时半屏打开;URI 不可持久访问。
  • 应用内语言:可用语言可能不含应用支持的语言;拆分 APK 不自动下载;界面为初步版会改。
  • 降级权限:撤销异步;立即撤销调 System.exit() 可能导致他应用未定义行为/崩溃。
  • 通知权限:用户滑开通知不算互动;临时授权需已有渠道且未在 12L 及以下停用。
  • Wi-Fi 权限:NEARBY_WIFI_DEVICES 在系统设置按组启停,不能单独关 Wi-Fi 留蓝牙。
  • 身体传感器:BODY_SENSORS_BACKGROUND 需安装器许可名单。
  • 电池优化:用户滑开通知不算互动;媒体播放/定位类 FGS 不弹长时间运行通知。
  • 接收器:启 DYNAMIC_RECEIVER_EXPLICIT_EXPORT_REQUIRED 后不指定导出标志必抛 SecurityException,Android Studio lint 会检查。

三、Android 14(API 34)

3.1 行为变更

3.1.1 所有应用

  1. 精确闹钟权限默认关闭 ⚠️

    • SCHEDULE_EXACT_ALARMtargetSDK>=13 新装应用默认拒绝;USE_EXACT_ALARM:日历/闹钟应用普通权限,安装时授予。
    • 受影响 API:setExact()setExactAndAllowWhileIdle()setAlarmClock() 无权限抛 SecurityException
    • 适配 API:AlarmManager.canScheduleExactAlarms()ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED 广播、意图 android.settings.REQUEST_SCHEDULE_EXACT_ALARM
    • 豁免:平台签名、特权应用、电源许可名单、SYSTEM_WELLBEING 角色预授权。
  2. 动态注册广播入队:应用 cached 时上下文注册广播入队,回前台分发(Manifest 声明广播不入队)。

  3. 三方 App 只能杀自己后台进程 ⚠️:killBackgroundProcesses() 传其他包名无效。Logcat:Invalid packageName: com.example.anotherapp

  4. 安装最小 targetSdk 级别 ⚠️:targetSdkVersion 低于 23 无法安装。报错:INSTALL_FAILED_DEPRECATED_SDK_VERSION: App package must target at least SDK version 23, but found 7。测试:adb install --bypass-low-target-sdk-block FILENAME.apk

  5. 隐藏媒体所在应用包名:查 OWNER_PACKAGE_NAME 列需包名对其他应用可见(<queries> 声明)或申请 QUERY_ALL_PACKAGES

  6. 常驻通知变化setOngoing(true)/FLAG_ONGOING_EVENT 用户可手动删除(锁屏、清除所有、CallStyle、MediaStyle、DPC 企业包除外)。

  7. 授权访问部分照片或视频 ⚠️(重要隐私调整):

    • READ_MEDIA_IMAGESREAD_MEDIA_VIDEO(Android 13 引入),Android 14 新增 READ_MEDIA_VISUAL_USER_SELECTED
    • 弹窗:「Select photos and videos」/「Allow all」/「Don't allow」。
    • 声明 READ_MEDIA_VISUAL_USER_SELECTED 且用户选部分时,READ_MEDIA_IMAGES/VIDEO 被拒,仅临时授予选中文件访问。
    • 从 13/12 升 14 且原有存储权限者,自动授予全部。
  8. 非线性缩放至 200%:用 sp 单位;API TypedValue.applyDimension()TypedValue.deriveDimension()。避免用 Configuration.fontScaleDisplayMetrics.scaledDensity(不再准确)。

3.1.2 以 Android 14 为目标平台(targetSdk = 34)

  1. 必须声明前台服务类型 ⚠️:android:foregroundServiceType(值:camera, connectedDevice, dataSync, health, location, mediaPlayback, mediaProjection, microphone, phoneCall, remoteMessaging, shortService, specialUse, systemExempted)。权限:FOREGROUND_SERVICE + 类型对应(如 FOREGROUND_SERVICE_MEDIA_PLAYBACK,normal 权限默认授予)。未声明调 startForeground()MissingForegroundServiceTypeException;权限不对抛 SecurityException
  2. OpenJDK 17 严格校验:正则无效组引用抛 IllegalArgumentException(标志 DISALLOW_INVALID_GROUP_REFERENCE);UUID.fromString() 严格(标志 ENABLE_STRICT_VALIDATION);ProGuard 中 java.lang.ClassValue 可能致优化问题。
  3. 隐式意图和挂起意图限制 ⚠️:隐式意图仅发往导出组件,否则抛异常;必须显式 setPackage()。可变 PendingIntent 无组件/包名抛异常。
  4. 动态广播接收器必须声明导出标志 ⚠️:必须传 RECEIVER_EXPORTEDRECEIVER_NOT_EXPORTEDContext.registerReceiver()
  5. 更安全的动态代码加载 ⚠️:动态加载文件(DEX/JAR/APK)必须 setReadOnly(),否则抛异常。jar.setReadOnly();
  6. 防止 Zip 路径穿透 ⚠️:ZipFile(String)ZipInputStream.getNextEntry()../ 开头抛 ZipException。可调 dalvik.system.ZipPathValidator.clearCallback() 关闭。
  7. 后台启动 Activity 附加限制 ⚠️:
    • 限制一:PendingIntent.send() 需设 ActivityOptions.setPendingIntentBackgroundActivityStartMode(MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
    • 限制二:bindService() 需加 BIND_ALLOW_ACTIVITY_STARTSBindServiceFlags.of(BIND_ALLOW_ACTIVITY_STARTS|BIND_AUTO_CREATE))。
  8. 加强 non-SDK API 限制StrictMode.detectNonSdkApiUsage() 捕获。
  9. 收紧全屏 intent 通知权限USE_FULL_SCREEN_INTENT 仅限通话/闹钟应用。检查 NotificationManager.canUseFullScreenIntent();意图 ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENT
  10. 数据安全信息更可见:位置共享扩大范围时,30 天内系统通知用户(设置 > Privacy 可查)。

3.2 权限与隐私调整

  • 精确闹钟:SCHEDULE_EXACT_ALARM(默认拒)/USE_EXACT_ALARM(普通权限)。
  • 媒体:READ_MEDIA_IMAGESREAD_MEDIA_VIDEOREAD_MEDIA_VISUAL_USER_SELECTED(部分访问)。
  • 截屏检测:android.permission.DETECT_SCREEN_CAPTURE
  • 包可见性:<queries> 声明或 QUERY_ALL_PACKAGES 查媒体所有者包名。
  • 全屏 intent:USE_FULL_SCREEN_INTENT 收紧。

3.3 新增 API

  • 应用级语言偏好:AGP 8.1.0-alpha07+ 自动生成 LocaleConfig 并在 Manifest 引用 android:localeConfig="@xml/locales_config"LocaleManager.setOverrideLocaleConfig()/getOverrideLocaleConfig() 动态更新;IME 用 getApplicationLocales() 查当前 App 语言。
  • 语法性别 APIGrammaticalInflectionManagersetRequestedApplicationGrammaticalGender(Configuration.GRAMMATICAL_GENDER_FEMININE)getApplicationGrammaticalGender()。常量:GRAMMATICAL_GENDER_NOT_SPECIFIED_NEUTRAL_FEMININE_MASCULINE。资源适配 values-fr-feminine/strings.xml
  • 地区偏好getTemperatureUnit()getFirstDayOfWeek();广播 ACTION_LOCALE_CHANGED;路径 Settings > System > Languages & input > Regional preferences。
  • 分享表自定义与直接共享排名ChooserAction.Builder 构建 ChooserAction,存 Intent.EXTRA_CHOOSER_CCUSTOM_ACTIONSEXTRA_CHOOSER_MODIFY_SHARE_ACTIONpushDynamicShortcut() 上报,ShortcutInfoCompat.Builder#addCapabilityBinding("actions.intent.SEND_MESSAGE") 绑定能力(要求 setLongLived(true)setRank()、唯一 shortcutId)。
  • 预测性返回android:enableOnBackInvokedCallback=true(按 Activity 设置);OnBackPressedCallback 新增 handleOnBackStarted(BackEvent)handleOnBackProgressed(BackEvent)handleOnBackCancelled()OnBackAnimationCallback 新增 onBackStartedonBackProgressedonBackCancelled过渡替代overrideActivityTransition(int, int, int) 代替 overridePendingTransition(int, int)
  • PackageInstaller API 改善requestUserPreapproval() 下载前请求同意;setRequestUpdateOwnership() 声明对未来更新负责;InstallConstraints API 与 commitSessionAfterInstallConstraintsAreMet() 合适时间更新;setDontKillApp() 无缝安装拆分 APK 不杀进程。
  • 监测用户截屏行为:权限 android.permission.DETECT_SCREEN_CAPTURE;回调 Activity.ScreenCaptureCallback(重写 onScreenCaptured());注册 registerScreenCaptureCallback(executor, callback)onStart)、注销 unregisterScreenCaptureCallback(callback)onStop)。触发条件:仅电源键+音量下键等特定组合;adb/仪器测试不触发。
  • 路径可查询和可插值Path.getPathIterator() 返回 PathIteratorSegment.getVerb()getPoints());Path.isInterpolatable(path2) 检查,Path.interpolate(path2, 0.8f, resultPath) 生成(要求内部结构相同、点数相同、conicTo 权重相同)。
  • OpenJDK 17 更新:约 300 个 java.base 类支持 Java 17。特性:Text Blocks、instanceof 模式匹配、密封类。

3.4 废弃与受限 API

类型废弃/受限替代/新要求
API 替代overridePendingTransition(int, int)overrideActivityTransition(int, int, int)
API 失效killBackgroundProcesses(其他包名)仅能杀自己进程
常量不准Configuration.fontScale / DisplayMetrics.scaledDensityTypedValue.applyDimension/deriveDimension
广播标志上下文注册无标志必须 RECEIVER_EXPORTED/RECEIVER_NOT_EXPORTED
意图限制隐式意图启动未导出组件必须显式 setPackage()
权限默认SCHEDULE_EXACT_ALARM 预授予默认拒绝,手动申请
通知行为常驻通知不可关用户可手动关闭(特定场景除外)
DCL 加载动态代码未只读必须 setReadOnly() 否则异常

3.5 适配要点与注意事项

targetSdk 要求

  • 最低安装要求:Android 14 起 targetSdkVersion >= 23
  • 精确闹钟:targetSDK >= 13 新装且声明 SCHEDULE_EXACT_ALARM 默认拒。
  • 媒体权限:targetSDK >= 33 受部分照片/视频弹窗影响。
  • target 34 必须适配:前台服务类型、动态广播导出标志、动态代码加载只读、隐式意图限制、后台启动 Activity 限制、全屏 intent 权限收紧。

两阶段迁移:①确保兼容(测核心流程,查行为变更,StrictMode.detectNonSdkApiUsage(),测第三方库/SDK);②更新目标平台(targetSdkVersion/compileSdkVersion → 34,用兼容性框架 adb 切换变更 ID 测试,如 DISALLOW_INVALID_GROUP_REFERENCEENABLE_STRICT_VALIDATION)。

最佳实践:照片权限不存权限状态(用 ContextCompat.checkSelfPermission()),URI 视为临时;闹钟判断是否真需精确,否则用 set()WorkManager

⚠️ 重点适配问题:加固策略须重点关注;SCHEDULE_EXACT_ALARM 不适配可能 SecurityException 闪退。

权限与隐私注意:声明 READ_MEDIA_VISUAL_USER_SELECTED 防多次弹窗,一次性申请媒体相关权限;DETECT_SCREEN_CAPTURE 需在 Manifest 声明并动态注册回调;用 <queries> 包名可见性查媒体所有者包名。


四、Android 15(API 35)

4.1 行为变更

4.1.1 所有应用

  1. 最低可安装 TargetSDK 级别为 24 ⚠️:Android 14 基础上加强,targetSdk < 24 无法安装,防止恶意软件避开运行时权限模型。报错 Logcat:INSTALL_FAILED_DEPRECATED_SDK_VERSION: App package must target at least SDK version 24, but found 7。升级到 15 的设备上原已装且 targetSdk < 24 的应用保留。测试:adb install --bypass-low-target-sdk-block FILENAME.apk

  2. 软件包停止状态变更:应用进入 force-stop 状态时,系统取消所有 PendingIntent,禁用 widget(灰显);用户移除停止状态时系统发 ACTION_BOOT_COMPLETED 广播。对比:adb shell dumpsys activity intentsmIntentSenderRecords 在 15 force-stop 后被删除(14 保留)。适配:结合 ApplicationStartInfowasForceStopped() 判断并重新注册 PendingIntent

  3. 资源限制时 direct/offload 音轨失效 ⚠️:请求 direct playbackoffload playback 时若资源达限制,已创建使用的 AudioTrack 对象失效(之前仅拒绝新建)。音频类 App 需适配。

  4. 支持 16KB Page Size ⚠️:Android 15 支持 16KB 页面大小设备。含 so 库应用必须重构建支持 16KB,否则 crash。性能提升:启动时间降 3.16%、功耗降 4.56%、相机冷启加快 6.60% 等。适配:AGP 8.3+ 未压缩共享库或 8.2- 压缩库;16KB ELF 对齐;用 Apk Analyzer 检查是否含 so。

  5. 默认开启预测性返回动画:移除开发者选项,对已完全或在 activity 级别选择启用预测性返回手势的应用,显示「返回主屏幕」「跨任务」「跨 activity」系统动画。适配:①迁移使用预测性返回手势;②fragment 转换支持;③停用动画/框架转换,改用 AnimatorAndroidX 转换;④从 FragmentManager 不知道的返回栈迁出,改用 FragmentManagerNavigation 组件管理。

4.1.2 以 Android 15 为目标平台(targetSdk = 35)

  1. 新的媒体处理前台服务类型 mediaProcessing ⚠️:如转码。24h 内总运行 6h,超时系统调 Service.onTimeout(int, int),需几秒内 stopSelf(),否则 ANR/异常。所有同类型服务共享 6h,用户置应用前台重置计时。

    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROCESSING" />
    <service android:foregroundServiceType="mediaProcessing" />
    

    超限启动抛 ForegroundServiceStartNotAllowedException

  2. BOOT_COMPLETED 广播接收器启动前台服务限制 ⚠️:BOOT_COMPLETED 接收方只能启动 LOCATIONCONNECTED_DEVICEREMOTE_MESSAGINGHEALTHSYSTEM_EXEMPTEDSPECIAL_USE 类型前台服务,否则抛 ForegroundServiceStartNotAllowedException。持 SYSTEM_ALERT_WINDOW 权限需有可见悬浮窗(TYPE_APPLICATION_OVERLAY),用 View.getWindowVisibility() 检查。

  3. 请求音频焦点的限制 ⚠️:必须是前台应用或运行音频相关前台服务(mediaPlayback/camera/microphone/phoneCall)才能请求焦点,否则 requestAudioFocus 返回 AUDIOFOCUS_REQUEST_FAILED,日志:Focus request DENIED for uid:xxx clientId:... req:1 procState:8

  4. elegantTextHeight 属性默认为 true:target > 15 时 TextViewelegantTextHeight 默认 true(影响阿拉伯语等,对汉语无影响)。设 false 可旧行为但未来版本可能不支持。

  5. Edge-to-edge 强制执行 ⚠️:target ≥ 15 强制全屏,状态/导航栏透明。setStatusBarColor/setNavigationBarColor 弃用或不生效(仅三键导航对 setNavigationBarColor 有效)。DecorView 去掉系统栏背景 View。适配:

    • 非 Compose:android:fitsSystemWindows="true"setFitsSystemWindows(true)
    • Compose:material3 组件(TopAppBar 等)正常;material2 需自行处理 paddingcontentWindowInsets
  6. 稳定的 configurationscreenWidthDp/screenHeightDp 包含系统条(除非 Window#setDecorFitSystemWindowWindows(false) 边到边)。影响 smallestScreenWidthDporientationDisplay.getSize(Point)(API30 废)、Display.getMetrics()。适配:布局计算改用 ViewGroup/WindowInsets/WindowMetricsCalculator

  7. 限制非 SDK 接口更新:更新受限列表 hiddenapi-flags.csv(SHA-256: 7aa0987aea4b25f5371b7e377c9f37375ada3b7e30465c0e2d910a5b646c10c1),建议迁移公开 SDK。

  8. OpenJDK 17 变更String.format/Formatter.format 严格验证(%0IllegalFormatArgumentIndexException,改用 %1);语言代码 iw→heji→yiin→idRandom.ints() 返回序列不同于 Random.nextInt()(JDK-8301574)。

  9. 安全的后台 Activity 启动:Manifest 设 allowCrossUidActivitySwitchFromBelow=false 阻跨 UID 启动;ActivityOptions#setPendingIntentCreatorBackgroundActivityStartMode(int)ActivityOptions#setPendingIntentBackgroundActivityStartMode(int);防不可见窗口后台启动。适配:考察测试后台启动场景。

4.2 权限与隐私调整

  • 安装安全:强制 targetSDK>=24,阻断低 API 恶意软件。
  • 停止状态清理:force-stop 取消 PendingIntent,增强隐私。
  • 前台服务权限FOREGROUND_SERVICE_MEDIA_PROCESSING 等;BOOT_COMPLETED 限制类型;SYSTEM_ALERT_WINDOW 需可见悬浮窗。
  • 音频焦点:后台限制请求,保护用户媒体隐私。
  • 非 SDK 接口:限制使用,降低安全风险。
  • 后台 Activity:跨 UID 及不可见窗口限制。
  • 屏幕录制检测:新增 Manifest.permission.DETECT_SCREEN_RECORDING
  • 端到端加密Manifest.permission.WRITE_CONTACTS;包可见性(<queries>QUERY_ALL_PACKAGES)。
  • 预测性返回:系统动画开放,导航隐私增强。

4.3 新增 API

  1. ApplicationStartInfoActivityManager.getHistoricalProcessStartReasons(int maxNum);方法 getDefiningUid()getIntent()getLaunchMode()getPackageUid()getPid()getProcessName()getRealUid()getReason()(0=ALARM, 1=BACKUP, 2=BOOT_COMPLETE, 6=LAUNCHER 等)、getStartType()(1=COLD, 3=HOT)、getStartupState()getStartupTimestamps()wasForceStopped()。监听 addApplicationStartInfoCompletionListener(Executor, Consumer<ApplicationStartInfo>)
  2. 局部屏幕共享MediaProjection.Callback#onCapturedContentResize(int, int)onCapturedContentVisibilityChanged(boolean)。⚠️ API 34+ 每个 MediaProjection 实例单次使用,重建需重新授权弹窗。
  3. 虚拟 MIDI 2.0 设备:新服务 MidiUmpDeviceService(旧 MidiDeviceService 仅 MIDI 1.0);onGetInputPortReceivers()getOutputPortReceivers()(输入/输出端口数必须相等);mMidiManager.getDevicesForTransport(MidiManager.TRANSPORT_UNIVERSAL_MIDI_PACKETS);Manifest 声明 android.media.midi.MidiUmpDeviceService
  4. 应用内相机控件(Camera2):常量 FLASH_SINGLE_STRENGTH_DEFAULT_LEVEL_MAX_LEVELFLASH_TORCH_STRENGTH_DEFAULT_LEVEL_MAX_LEVELCameraManager.turnOnTorchWithStrengthLevel(String, int)
  5. HDR 余量控制Window#setDesiredHdrHeadroom(float)(范围 [1.0, 10000.0],0.0 重置)、Display#getHdrSdrRatio();需先 setColorMode(ActivityInfo.COLOR_MODE_HDR)
  6. 音量控制(CTA-2075)LoudnessCodecController.create(int sessionId) / create(int, Executor, OnLoudnessCodecUpdateListener)
  7. 更顺畅的 NFCNfcAdapter#setObserveModeEnabled(boolean)isObserveModeSupportedHostApduService#processPollingFrames(List)CardEmulation#registerPollingLoopPatternFilterForService
  8. 详细的应用大小信息StorageStats.getAppBytesByDataType(int type);类型常量 APP_DATA_TYPE_FILE_TYPE_DEXOPT_ARTIFACT_REFERENCE_PROFILE_CURRENT_PROFILE_APK_LIB_DM
  9. SQLite 改进beginTransactionReadOnly()beginTransactionWithListenerReadOnly(SQLiteTransactionListener)getLastChangedRowCount()getTotalChangedRowCount()getLastInsertRowId()
  10. 屏幕录制检测WindowManager.addScreenRecordingCallback(Executor, Consumer<Integer>);常量 SCREEN_RECORDING_STATE_VISIBLE;权限 DETECT_SCREEN_RECORDING
  11. 扩展 IntentFilter:XML <uri-relative-filter-group>(含 android:allow="false")、<data android:query="..."><data android:fragmentPrefix="...">;类 UriRelativeFilterGroupACTION_ALLOW=0, ACTION_BLOCK=1)、UriRelativeFilterPATH=0, QUERY=1, FRAGMENT=2)。
  12. 改进「勿扰」规则AutomaticZenRule 新增 getType()getIconResID()triggerDescriptionZenDeviceEffectsZenDeviceEffects.Builder().setShouldUseNightMode(true).build()
  13. 端到端加密密钥管理E2eeContactKeysManagerE2eeContactKeyE2eeSelfKey;方法 updateOrInsertE2eeContactKey(lookupKey, deviceId, accountId, keyValue)(keyValue 1~5000 字节)、getE2eeContactKeygetAllE2eeContactKeysgetOwnerE2eeContactKeysremoveE2eeContactKey。验证状态常量 VERIFICATION_STATE_UNVERIFIED=0_VERIFICATION_FAILED=1_VERIFIED=2。权限 WRITE_CONTACTS
  14. PDF 改进PdfRenderer 模块化,PdfRendererPreV(兼容 Android 11);LoadParams.Builder().setPassword("123456")FormEditRecord.Builder(EDIT_TYPE_SET_TEXT,0,2).setText("pdf_Form")page.getFormWidgetInfos()page.applyEdit()page.searchText("LLM")List<PageMatchBounds>page.selectContent(SelectionBoundary, SelectionBoundary)
  15. 细化的换行符控件:保证词语同行可读性、不断字。

4.4 废弃与受限 API

  • 系统栏颜色setStatusBarColorsetNavigationBarColor 在 target≥15 不生效或仅三键导航有效(边到边强制)。
  • Configuration 旧行为screenWidthDp/screenHeightDp 不再排除系统栏,不鼓励用于布局计算。
  • Display 方法Display.getSize(Point)(API30 废)、Display.getMetrics()
  • 预测性返回开发者选项:已移除。
  • 旧 PdfRenderer 构造:无密码参数无法开加密 PDF。
  • MidiDeviceService:仅 MIDI 1.0,UMP 需 MidiUmpDeviceService
  • 非 SDK 接口:持续受限,列表更新。
  • OpenJDK 旧式%0 参数索引、语言代码 iw/ji/in 旧解析废弃。
  • 媒体处理前台服务:建议用 WorkManager 替代长时间后台。

4.5 适配要点与注意事项

targetSdk 要求

  • 影响所有应用:最低 SDK 24、停止状态、音频失效、16KB、预测性返回。
  • 影响 target ≥ 35:前台服务、广播限制、音频焦点、文本高度、边到边、Configuration、非 SDK、OpenJDK、后台启动。
  • 新功能 API:运行在 15 设备,代码判断 Build.VERSION.SDK_INT >= 35

关键注意事项

  1. 云测平台可弥补设备不足。
  2. 最低 SDK 24:仅限新安装拦截,已装保留;adb bypass 可测旧应用。
  3. 🟥 16KB 页面:Google 次年 Play 上架必要条件,国内厂商将跟随。
  4. 预测性返回:仅对「已选择启用」应用显示系统动画。
  5. mediaProcessing 前台服务:共享 6h 限制,用户前台重置;超时 Service.onTimeout 须秒级 stopSelf()
  6. 音频焦点:后台 WorkManager 申请失败日志 procState:8
  7. elegantTextHeight:对汉语无影响。
  8. Edge-to-edge:非 Compose 不设 fitsSystemWindows 会导致内容被 statusbar 遮挡。
  9. Configuration:setDecorFitSystemWindowWindows(false) 边到边时系统条不计入。
  10. 非 SDK:任何使用均有显著风险。
  11. OpenJDK:Random.ints() 不应期望匹配 nextInt() 序列。
  12. MediaProjection:API 34 起单次使用,重建弹授权。
  13. MIDI UMP:输入/输出端口数必须相等。
  14. HDR:仅 COLOR_MODE_HDRsetDesiredHdrHeadroom 生效,0.0 为重置。
  15. E2eeContactKeys:跨应用查询抹去 deviceId/timeUpdated/keyValue;仅能改自己创建的验证状态;keyValue 1~5000 字节。
  16. PDF:PdfRenderer 已移为模块,PdfRendererPreV 兼容 Android 11(API 30)。

五、Android 16(API 36)

5.1 行为变更

5.1.1 所有应用

  1. 锁屏后 MediaProjection 被自动停止 ⚠️:投/录屏时状态栏有标志;电源键锁屏或长时间搁置自然锁屏后 MediaProjection 被 stop。新增 MediaProjectionStopController 对象;息屏或先打电话后投屏再挂断会停止。适配:实现 MediaProjection.Callback.onStop() 回调响应。

  2. 提高对 Intent 重定向攻击的安全性 ⚠️:防止利用 Parcelable 嵌套 Intent 绕过安全检查启动非导出组件。默认安全防护。ActivityStarterIntentBaseBundleClipdata 类变动。关键常量/类:Intent 新增 EXTENDED_FLAG_MISSING_CREATOR_OR_INVALID_TOKEN、内部类 CreatorTokenInfoNestedIntentKey、方法 removeLaunchSecurityProtection()ActivityStarter 新增 ENABLE_PREVENT_INTENT_REDIRECT_TAKE_ACTIONmaybeMarkAsMissingCreatorTokenintentCreatorUidintentCreatorPackageDEFAULT_INTENT_CREATOR_UIDlogAndThrowExceptionForIntentRedirect。停用重定向处理代码:

    val iSublevel: Intent? = i.getParcelableExtra("sub_intent")
    iSublevel?.removeLaunchSecurityProtection() // Opt out
    iSublevel?.let { startActivity(it) }
    

    ⚠️ 嵌套 Intent 启动其他 APP 非导出组件的方式在 Android 16 后无法使用

  3. 支持 16KB Page Size ⚠️:开发者无需担心常规启动失败,但建议适配。性能提升数据同 Android 15(启动降 3.16%、功耗降 4.56%)。含 so 库应用需重构支持 16KB 否则 crash。适配:AGP 8.3+,16KB ELF 对齐,Apk Analyzer 检查。

  4. ART 内部变更 ⚠️:依赖 ART 内部结构的库/代码会崩溃(报 SIGSEGV 空指针)。已知库:HiddenApiBypass (org.lsposed.hiddenapibypass:hiddenapibypass)FlyCore (cn.fly:FlyCore) 版本 < v2025.0224.1629。源码改动:合并 Class.javaiFieldssFieldsfields(反射取私有变量 NPE,用公共 getDeclaredFields 不受影响)。谷歌建议:寻找公共 API 替代,而非简单升级库。

  5. setImportantWhileForeground 失效JobInfo.Builder#setImportantWhileForeground(boolean) 自 Android 12 废弃,Android 16 起忽略;JobInfo#isImportantWhileForeground() 返回 false。适配:改用 builder.setExpedited(true)

  6. JobScheduler 配额优化:调整常规/加急作业运行时配额:依据应用待机分桶、是否顶部状态、是否与前台服务同时执行。新 API JobScheduler#getPendingJobReasonsHistory。ADB:

    • adb shell am compat enable OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS PACKAGE
    • adb shell am compat enable OVERRIDE_QUOTA_ENFORCEMENT_TO_FGS_JOBS PACKAGE
    • adb shell am set-standby-bucket PACKAGE active|working_set|frequent|rare|restricted
  7. 被废弃的空作业停止原因JobParameters 被 GC 但未调 JobService#jobFinished 时,新停止原因 STOP_REASON_TIMEOUT_ABANDONED 替代 STOP_REASON_TIMEOUT。WorkManager/AsyncTask/DownloadManager 不受影响。

  8. 弃用干扰性无障碍公告:废弃 announceForAccessibilityTYPE_ANNOUNCEMENT。替代:Activity.setTitle()/setAccessibilityPaneTitle()setAccessibilityLiveRegion(int)(值 ACCESSIBILITY_LIVE_REGION_POLITE/ASSERTIVE/NONE);Compose Modifier.semantics { liveRegion = LiveRegionMode.[Polite|Assertive] };错误通知发 AccessibilityEvent#CONTENT_CHANGE_TYPE_ERROR + AccessibilityNodeInfo#setError/TextView#setError

  9. 有序广播优先级范围不再是全局android:priorityIntentFilter#setPriority() 仅同进程内有效,跨进程不保证顺序。

  10. 预测性返回支持三键导航 🟥:Android 16 三键导航(长按后退)也支持预测性返回动画。不适配需声明 android:enableOnBackInvokedCallback="false"(Application 或 Activity 级)。

  11. 桌面窗口模式 🟥:谷歌原生桌面窗口模式(Desktop Windowing)在 Hyper OS 上被屏蔽(避免与工作台模式/无极窗口冲突)。(dev.mi.com/xiaomihyper…

  12. 更新对 non-SDK API 的限制:继续增加限制名单。V→W 被屏蔽/移除示例:android/bluetooth/le/BluetoothLeScanner#startTruncatedScan(标签 removed,unsupported)、java/lang/Thread 多个底层方法。标签含义:blocked(blacklist)max-target-x(greylist-max-x)unsupported(greylist)public-api/sdk(whitelist)test-api。崩溃日志特征:Accessing hidden fieldNoSuchMethodExceptionNoSuchFieldException

5.1.2 以 Android 16 为目标平台(targetSdk = 36)

  1. Edge to edge 退出选项被停用 ⚠️:R.attr#windowOptOutEdgeToEdgeEnforcement 在 targetSdk≥36 且运行 16 时停用。适配:Compose M3 自动处理 insets;M2 用 Padding/contentWindowInsets;Views 用 ViewCompat.setOnApplyWindowInsetsListener

  2. Health and fitness permissions ⚠️:android.permissions.BODY_SENSORSBODY_SENSORS_BACKGROUND 需转为 android.permissions.health 下细粒度权限。涉及 HEART_RATE_BPMSensor.TYPE_HEART_RATEheartRateAccuracyheartRateBpmFOREGROUND_SERVICE_TYPE_HEALTH。适配:前台用心率等用 READ_HEART_RATE;后台用 READ_HEALTH_DATA_IN_BACKGROUND

  3. 大屏自适应 app 🟥:谷歌强制忽略 screenOrientationresizableActivityminAspectRatiomaxAspectRatiosetRequestedOrientation()getRequestedOrientation()Hyper OS 上暂不开启此特性。豁免属性 android.window.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY(仅 target 36 生效,未来≥37 不适用)。

  4. Fixed rate 定时任务调度优化ScheduledThreadPoolExecutor#scheduleAtFixedRate 错过多次后最多补发一次,后续按原间隔。适配:主动计算 missedCycles 或换定时器。

  5. 迁移到或停用预测性返回 ⚠️:targetSdk≥36 时 android:enableOnBackInvokedCallback 默认 true。不声明 false 则不回调 onBackPressed() 且不分发 KeyEvent.KEYCODE_BACK

  6. ElegantTextHeight 属性:废弃且忽略。影响阿拉伯语、泰语等,对汉语无影响。默认效果同 15 目标平台未设 false 时。

5.2 权限与隐私调整

  • 隐私安全(MediaProjection):投屏左上角醒目标志,锁屏自动停止。
  • Intent 重定向攻击防护:默认开启,限制嵌套 Intent 启动非导出组件,保护 URI 权限。
  • Health 权限转型BODY_SENSORSandroid.permissions.health.READ_HEART_RATE 等。
  • non-SDK 接口限制:限制反射/JNI 获取句柄,增黑名单。
  • 无障碍隐私/体验:废弃全局 announcement,改用更精准的 paneTitle / liveRegion。

5.3 新增 API

  • 预测性返回更新OnBackInvokedDispatcher.PRIORITY_SYSTEM_NAVIGATION_OBSERVER(仅注册一次);SystemOnBackInvokedCallbacks.finishAndRemoveTaskCallback(activity) → 触发 finishAndRemoveTask(),常量 OVERRIDE_FINISH_AND_REMOVE_TASKSystemOnBackInvokedCallbacks.moveTaskToBackCallback(activity) → 触发 moveTaskToBack(true),常量 OVERRIDE_MOVE_TASK_TO_BACK;标记 Flags.FLAG_PREDICTIVE_BACK_SYSTEM_OVERRIDE_CALLBACK
  • ApplicationStartInfo 启动组件getStartComponent()(Flag FLAGS.FLAG_APP_START_INFO_COMPONENT);常量 START_COMPONENT_ACTIVITY=1_BROADCAST=2_CONTENT_PROVIDER=3_SERVICE=4_OTHER=5
  • 自适应刷新率 ARRDisplay.hasArrSupport()Display.getSuggestedFrameRate(int category)(参数 FRAME_RATE_CATEGORY_NORMAL/_HIGH,异常 IllegalArgumentException);Display.getSupportedRefreshRates()
  • 更丰富的 job 自检 APIJobScheduler#getPendingJobReasons(int)#getPendingJobReasonsHistory(int)
  • 更丰富的触感反馈:类 VibratorEnvelopeEffectInfogetMaxSize()getMaxControlPointDurationMillis() 等);类 VibratorFrequencyProfilegetFrequenciesOutputAcceleration()getMaxOutputAcceleration(),返回 SparseArray/Range)。
  • 高级专业视频 APVMediaFormat.MIMETYPE_VIDEO_APV = "video/apv"(Flag FLAG_APV_SUPPORT);MediaCodecInfo Profile 常量 APVProfile422_10=0x01APVProfile422_10HDR10=0x1000APVProfile422_10HDR10Plus=0x2000APVLevel1Band0=0x101;设置 format.setInteger(MediaFormat.KEY_PROFILE, MediaCodecInfo.CodecProfileLevel.APVProfile422_10)
  • 相机夜间模式取景检测CaptureResult.EXTENSION_NIGHT_MODE_INDICATOR(0=UNKNOWN, 1=明亮可用, 2=低光建议);CameraExtensionCharacteristics.getSupportedExtensions()EXTENSION_NIGHT,及 getAvailableCaptureResultKeys()
  • Intent 安全新 APIIntent#removeLaunchSecurityProtection()

5.4 废弃与停用 API

  • 停用/失效JobInfo.Builder#setImportantWhileForegroundisImportantWhileForeground()(返 false);R.attr#windowOptOutEdgeToEdgeEnforcement(target≥36);elegantTextHeight 属性;谷歌原生桌面窗口模式(Hyper OS 屏蔽);跨进程有序广播优先级。
  • 废弃/转型announceForAccessibility/TYPE_ANNOUNCEMENTBODY_SENSORS/BODY_SENSORS_BACKGROUND → health 细粒度权限;BluetoothLeScanner.startTruncatedScan(non-SDK removed);java.lang.Thread 部分强制停止/挂起方法(non-SDK removed);嵌套 Intent 启动其他应用非导出组件方式。

5.5 适配要点与注意事项

关键代码精选

// Job 加急替代前台重要
builder.setExpedited(true); // 替代 builder.setImportantWhileForeground(true);
<!-- 预测性返回声明(target≥36 默认 true,用旧 onBackPressed() 须显式处理) -->
<application android:enableOnBackInvokedCallback="true" ...>
    <activity android:name=".MainActivity" android:enableOnBackInvokedCallback="true" ... />
</application>

适配要点

  1. Job 加急替代前台重要。
  2. 预测性返回声明 Manifest。
  3. Health 权限:请求 READ_HEART_RATE/READ_HEALTH_DATA_IN_BACKGROUND
  4. 16KB 页面:升级 AGP 8.3+,编译 16KB ELF 对齐。
  5. ART 兼容:勿依赖 Class.iFields/sFields 反射,改用 getDeclaredFields();移除 HiddenApiBypass 等库依赖。
  6. Job 调试:用 getPendingJobReasonsHistory 查停止原因。

其他注意:Beta 版本稳定性不可预估,建议用云测真机;SDK(如 MobTools/FlyCore)依赖 ART 内部结构致 SIGSEGV,需推动提供方改用公共 API;用 StrictMode.detectNonSdkApiUsage() 捕获 non-SDK 访问。


六、Android 17(API 37)

6.1 行为变更

6.1.1 所有应用

A. 安全相关
  1. usesCleartextTraffic 弃用预告 ⚠️:未来版本(预计 Android 18)弃用,系统忽略该值,明文流量被默认拒绝。替代方案 Network Security Config(API 24+)。当前状态:新增 CompatChange DEPRECATE_USES_CLEARTEXT_TRAFFICID: 415007211,当前 @Disabled)和 aconfig flag deprecate_uses_cleartext_traffic2R.attr.usesCleartextTraffic 已标注 @Deprecated @FlaggedApitargetSdk <= 37 且未配置 NSC 的应用暂不受影响。

  2. 限制隐式 URI 授权 ⚠️:此前 ACTION_SENDACTION_SEND_MULTIPLEACTION_IMAGE_CAPTURE 等 Intent 自动授予读写权限,存在安全隐患,Android 18(API 38)正式废止。17 状态:行为同 16(隐式授权仍发生),三个限制 Aconfig 标志默认关。StrictMode 新增 CompatChange DETECT_IMPLICIT_URI_PERMISSION_GRANTID: 460838111),对 targetSdk > 36 自动启用检测。logcat 提示 "discontinued from Android 18 onwards"

  3. Keystore 密钥数量限制 ⚠️:targetSdk >= 37 非系统应用上限 50,000;其他(非系统 <37 或系统应用)200,000。超出抛 KeyStoreExceptiontargetSdk >= 37 错误码 ERROR_TOO_MANY_KEYSERROR_INCORRECT_USAGE),表现 ProviderException: Keystore key generation failed

B. 用户体验和系统界面
  1. 旋转后恢复 IME 可见性:Aconfig Flag disable_ime_restore_on_activity_create 控制。开启后旋转读取新窗口 requestedVisibleTypes(默认不含 IME),不再自动恢复 IME,需应用显式请求。不受影响:windowSoftInputMode=stateAlwaysVisible、应用自行处理 configChanges、或已在 onCreate() 显式请求。
C. 人工输入
  1. 触控板指针捕获默认传递相对事件 ⚠️:Flag pointer_capture_modes + relative_capture_mode_by_default(均需开启)控制,不受 targetSdk 影响。默认从 ABSOLUTE 改为 RELATIVE(鼠标风格)。新增常量(View.java):POINTER_CAPTURE_MODE_UNCAPTURED=0POINTER_CAPTURE_MODE_ABSOLUTE=1(旧)、POINTER_CAPTURE_MODE_RELATIVE=2(新默认)。新 API requestPointerCapture(int mode) 重载。兼容问题:RELATIVE 模式返回 SOURCE_MOUSE_RELATIVE(非 SOURCE_TOUCHPAD),getX()/getY() 返回相对位移,多触点数据失效。
D. 媒体
  1. 后台音频操作强化(Background Audio Hardening) ⚠️:从 16 的 warning 升级为 strict 强制模式(aconfig flag:hardening_stricthardening_partial_volumero_foreground_audio_control)。表现:音量方法(adjustStreamVolume/setStreamVolume/setStreamMute 等)后台调用静默 no-oprequestAudioFocus 后台返回 AUDIOFOCUS_REQUEST_FAILED(0);AudioTrack.write()/AAudio/OpenSL ES 后台被系统静默(MUTED_BY_OP_CONTROL_AUDIO)。豁免:可见 Activity、可见时启动的非 SHORT_SERVICE FGS、特权权限等。不豁免后台启动的 FGS(如 BOOT_COMPLETE)。
E. 连接
  1. 蓝牙绑定丢失的自主重新配对:Flag autonomous_repairing_initiation + bluetooth_pairing_hardening 控制。系统可后台静默恢复 bond key,成功时不再广播 ACTION_KEY_MISSING;该广播升级为 <protected-broadcast>(第三方不可伪造)。
F. 核心功能(全局生效)
  1. 已回收 Parcel 对象的访问限制 ⚠️:Parcel.java 新增 assertNotRecycled(),在 readParcelableInternal() 入口调用。回收后继续读取直接抛 BadParcelableException(16 仅警告)。无 CompatChange。

  2. Parcel 序列化大小校验 ⚠️:Flag fail_on_parcel_size_mismatch 在所有发布配置中 ENABLEDwriteValue()readValue() 字节数不一致时抛 BadParcelableException(16 仅日志)。

  3. 相关配置变更不再重启 Activity ⚠️:Flag SKIP_ACTIVITY_RECREATION_ON_CONFIG_CHANGE,当 keyboardkeyboardHiddennavigationtouchscreencolorMode、进入/离开 UI_MODE_TYPE_DESK 变化时默认不重启,改走 onConfigurationChanged()。新属性 android:recreateOnConfigChanges(可声明上述值恢复重建)。

  4. 文件操作模式严格校验 ⚠️:FileUtils.translateModeStringToPosix() 改显式 switch,不在白名单直接抛 IllegalArgumentException。无 CompatChange。合法白名单:r(O_RDONLY)、w(O_WRONLY|O_CREAT)、wt/tw(O_TRUNC)、wa/aw(O_APPEND)、rw/wr(O_RDWR|O_CREAT)、rwt/rtw/...(O_RDWR|O_CREAT|O_TRUNC)。矛盾模式如 rwa 非法。

  5. 线程优先级越界强制校验 ⚠️:Process.setThreadPriority() 改 Java 层校验,超出 [-20, 19] 直接抛 IllegalArgumentException(16 静默 clamp)。

6.1.2 以 Android 17 为目标平台(targetSdk = 37)

A. 核心功能
  1. MessageQueue 新无锁实现(DeliQueue) ⚠️:CompatChange USE_NEW_MESSAGEQUEUEID: 421623328),targetSdk>=37 自动激活。破坏性:mMessages 字段恒为 null(新增 @UnsupportedAppUsage(maxTargetSdk = BAKLAVA));next() 新增废弃声明;消息对象复用禁用对象池。测试框架要求:Espresso 3.7.0+,Robolectric 4.17+。

  2. static final 字段不可修改 ⚠️:ART ArtField::IsUnmodifiable() 限制:反射 Field.set()IllegalAccessException;JNI SetStaticXxxField() 导致进程崩溃(LOG(FATAL))

  3. 通知自定义视图大小限制 ⚠️:CompatChange CHECK_SIZE_OF_INFLATED_CUSTOM_VIEWSID: 270553691)。SystemUI 层 lightenPayload() 超限时降级为标准通知模板(而非丢弃)。涉及 setCustomContentView() 等。

  4. NPU 直接访问需声明硬件功能 ⚠️:Flag npumanager_block_missing_feature ENABLED。NpuManager 检查 android.hardware.npu 声明,未声明则 hasDirectAccess=false(静默回退 CPU,logcat: NPU access is blocked.)。

B. 无障碍
  1. 复杂 IME 实体键盘输入的无障碍支持:新增 AccessibilityEvent 文本变更类型 TEXT_CHANGE_TYPE_UNDEFINEDTEXT_CHANGE_TYPE_IN_COMPOSITIONTEXT_CHANGE_TYPE_COMMITTED_BY_IMETEXT_CHANGE_TYPE_CONVERSION_SUGGESTION_SELECTED_BY_IMETextAttribute.isTextSuggestionSelected() 新方法(可选增强)。
C. 隐私权
  1. 机会性启用 ECH、访问本地网络需要权限、实体设备隐藏密码、短信 OTP 保护(详见 6.2)。
D. 安全
  1. 活动安全性增强(BAL 强化) ⚠️:旧常量 MODE_BACKGROUND_ACTIVITY_START_ALLOWED @Deprecated,新稳定常量 MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS=3MODE_BACKGROUND_ACTIVITY_START_ALLOW_IF_VISIBLE=4(推荐)、MODE_BACKGROUND_ACTIVITY_START_DENIED=2。CompatChange COVER_INTENT_SENDERID: 405995292):IntentSender.sendIntent() 不再自动豁免 BAL 检查。StrictMode detectBlockedBackgroundActivityLaunch() 对 targetSdk>35 自动启用。

  2. CT 证书透明度默认启用 ⚠️:CompatChange DEFAULT_ENABLE_CERTIFICATE_TRANSPARENCYID: 407952621)+ flag certificate_transparency_default_enabled。未提交 CT 日志的证书致 SSLHandshakeException

  3. 加载可写原生库抛 UnsatisfiedLinkError(原生 DCL 加强) ⚠️:CompatChange THROW_ERROR_FOR_WRITABLE_DCL + ART flag read_only_dynamic_code_load_throw_exceptionSystem.load() 加载 file.canWrite()==true 的 .so 抛 UnsatisfiedLinkError(root/system/adb 豁免)。

E. 设备类型
  1. 大屏设备忽略屏幕方向和尺寸调整限制 ⚠️:sw >= 600dp 设备无条件忽略方向请求;targetSdk>=37 时 PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY opt-out 完全失效(flag 已删除)。游戏类(appCategory="game")豁免。

6.2 权限与隐私调整

权限/特性要求与变化备注
ACCESS_LOCAL_NETWORK运行时危险权限,属 NEARBY_DEVICES 组。targetSdk>=37 必须声明并请求;<37 通过 split-permission(INTERNET→ACCESS_LOCAL_NETWORK) 自动兼容。BPF 层静默丢包影响 LAN Socket、mDNS、Wi-Fi Direct 等
短信 OTP 保护targetSdk>=37 受 FILTER_GENERIC_OTP(ID:437043173) 约束,普通应用无法通过 SMS_RECEIVED 解析 OTP,需迁移 SMS Retriever / User Consent API受信任应用:默认短信/系统/关联设备等
ECH(加密客户端 Hello)targetSdk>=37 默认 OPPORTUNISTIC 模式(CompatChange ENABLE_DEFAULT_ENCRYPTED_CLIENT_HELLO + flag)。新增 <domainEncryption> XML 元素控制企业防火墙可能不兼容,可设 mode="disabled"
实体设备隐藏密码Settings.Secure.TEXT_SHOW_PASSWORD_TOUCH=1(不变),TEXT_SHOW_PASSWORD_PHYSICAL=0(新隐藏),由 ShowSecretsSetting 管理仅实体键盘输入变化
联系人选择器ACTION_PICK_CONTACTS + ContactsPickerSessionContract无需 READ_CONTACTS 权限,一次性会话 URI详见 6.3
Android 高级保护模式 (AAPM)需 normal 权限 QUERY_ADVANCED_PROTECTION_MODE;开启后非工具型 AccessibilityService 被强制禁用(需 isAccessibilityTool="true"稳定 API
Android 开发者验证Android 17 引入框架,要求开发者注册。Google Play 分发 98% 自动注册;ADB 绕过;2026.9 部分地区强制。安装失败常量 DEVELOPER_VERIFICATION_FAILED_REASON_UNKNOWN(0)/NETWORK_UNAVAILABLE(1)/DEVELOPER_BLOCKED(2)影响侧载/非 Play 渠道

6.3 新增 API

  1. AlarmManager 精确闹钟 OnAlarmListener 变体setExactAndAllowWhileIdle(int type, long triggerAtMillis, String tag, Executor executor, OnAlarmListener listener)。⚠️ 无需 SCHEDULE_EXACT_ALARM 权限,进程内回调,进程 cached 时丢弃。需保持前台服务。
  2. 时区偏移量变化广播ACTION_TIMEZONE_OFFSET_CHANGED(受保护广播),携带 EXTRA_NEW_TIMEZONE_OFFSETEXTRA_OLD_TIMEZONE_OFFSET(秒)。DST 切换时触发(ID 不变仅偏移变)。
  3. 联系人选择器 ContactsPickerSessionContractACTION_PICK_CONTACTSEXTRA_PICK_CONTACTS_REQUESTED_DATA_FIELDSEXTRA_PICK_CONTACTS_SELECTION_LIMIT(默认50,最大100)、EXTRA_ALLOW_MULTIPLE
  4. Android 高级保护模式 AdvancedProtectionManagerisAdvancedProtectionEnabled()registerAdvancedProtectionCallback(executor, callback)unregisterAdvancedProtectionCallback()
  5. PQC APK 混合签名(ML-DSA):APK V3.2 签名方案(block ID 0x70e1c89f,minSDK 37)。KEY_ALGORITHM_ML_DSA/_65/_87。apksigner 参数 --hybrid-signer-role classical|pqc
  6. 触控板指针捕获模式常量与重载POINTER_CAPTURE_MODE_*requestPointerCapture(int mode)
  7. 无障碍文本变更 APIAccessibilityEvent.TEXT_CHANGE_TYPE_*TextAttribute.setTextSuggestionSelected()
  8. 开发者验证子系统:包 android.content.pm.verify.developer,Verification Agent 架构。

6.4 废弃 API 与弃用预告

废弃对象替代方案/说明
android:usesCleartextTraffic(R.attr @Deprecated)Network Security Config(res/xml/network_security_config.xml
隐式 URI 授权(Android 18 废止)显式 FLAG_GRANT_READ_URI_PERMISSION
MessageQueue.mMessages 字段@UnsupportedAppUsage(maxTargetSdk=BAKLAVA),改用 Handler.hasMessages()
MODE_BACKGROUND_ACTIVITY_START_ALLOWEDMODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS/IF_VISIBLE/DENIED
运行时修改 static final(target>=37)改非 final / 依赖注入 / 升级 Mockito
ACTION_KEY_MISSING 依赖同时监听 ACTION_BOND_STATE_CHANGED(BOND_NONE)

6.5 适配要点与注意事项

所有应用适配要点

  • 明文流量:检查 Manifest 有无 usesCleartextTraffic="true" 且无 NSC,按 minSdkVersion 迁移至 Network Security Config。
  • URI 授权:发送方显式加 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
  • Keystore:设置密钥有效期,定期 KeyStore.deleteEntry(alias),捕获 ERROR_TOO_MANY_KEYS
  • IME 旋转:在 onCreate() 显式 imm.showSoftInput() 或设 stateAlwaysVisible
  • Parcel:recycle() 前完成所有读取;writeToParcel/createFromParcel 严格对称。
  • 文件模式:将 "rwa" 改为 "rw""wa"
  • 线程优先级:调用前 Math.max(-20, Math.min(Process.THREAD_PRIORITY_LOWEST, priority))
  • 配置变更:实现 onConfigurationChanged() 处理 keyboard 等,或声明 recreateOnConfigChanges

targetSdk >= 37 专属适配要点

  • MessageQueue:禁止反射 mMessages;APM/监控 SDK 改用 TestLooperManagerLooper.setMessageLogging()
  • static final:移除反射/JNI 修改。
  • 通知视图:Bitmap 降采样(≤1024×1024),用 DecoratedCustomViewStyle,确保 setContentTitle 有文本。
  • NPU:Manifest 加 <uses-feature android:name="android.hardware.npu" android:required="false"/>
  • 本地网络:声明并运行时请求 ACCESS_LOCAL_NETWORK
  • OTP:改用 SmsRetrieverClient.startSmsRetriever()SmsUserConsentClient
  • BAL:IntentSender.sendIntent() 显式传 ActivityOptions.setPendingIntentBackgroundActivityStartMode(...ALLOW_IF_VISIBLE) 的 Bundle。
  • CT:确保证书提交 CT 日志,或 NSC 中 <certificateTransparency enabled="false"/>
  • 原生库:加载前 soFile.setWritable(false, false)Os.chmod(soPath, 0444)
  • 大屏:screenOrientation="fullUser" + resizableActivity="true",游戏用 appCategory="game"

崩溃日志特征(排查用)

  • Parcel:android.os.BadParcelableException: Parcel used while recycledUnparcelling of <Class> consumed <x> bytes, but <y> expected
  • 文件模式:java.lang.IllegalArgumentException: Bad mode: rwa at FileUtils.translateModeStringToPosix
  • 线程优先级:IllegalArgumentException: Priority/niceness 20 is invalid at Process.setThreadPriority
  • 静态 final JNI:A/art: Cannot set static final int field ... runtime aborting
  • 后台音频静默失败:logcat AudioHardening volume control ... ignored;本地验证 adb shell cmd audio set-enable-hardening 1
  • 蓝牙:ACTION_KEY_MISSING 不再保证每次收到,需监听 BOND_NONE

适配测试工具:兼容性切换开关(CompatChange ID 可 adb 管理),如 adb shell am compat enable USE_NEW_MESSAGEQUEUE <package>

targetSdk 要求总览

类别targetSdk 要求关键内容
影响所有应用无门槛usesCleartext 预告(生效18)、隐式URI(检测>36)、Keystore(限5万若≥37)、IME、触控板、后台音频、蓝牙、Parcel、配置变更、文件模式、线程优先级
targetSdk >= 37必须 ≥ 37DeliQueue、static final 锁、通知视图、NPU声明、IME a11y(可选)、ECH默认、本地网络权限、密码隐藏、OTP过滤、BAL强化、CT默认、可写.so拒绝、大屏忽略
新功能/API无限制AlarmManager 新重载、时区广播、联系人选择器、AAPM、PQC签名、开发者验证
向后兼容targetSdk < 37split-permission 自动获 ACCESS_LOCAL_NETWORK;usesCleartext 暂被忽略;BAL 旧常量仍可用(警告)

迁移指南建议:先测兼容性(不升 targetSdk),再更新 targetSdkVersion=37compileSdkVersion,用兼容性切换开关逐项验证。


七、跨版本渐进式适配建议清单

适配不是一次性动作,而是一条贯穿 Android 12 → 17 的渐进路径。以下按「先做硬性阻塞项,再做隐私与权限项,最后做体验与新能力项」的优先级梳理。每项标注涉及版本与风险等级。

7.1 第一优先级:硬性阻塞与崩溃风险(不做无法上架/启动/运行)

#适配项涉及版本风险关键动作
1含 intent-filter 的组件显式声明 android:exported12+⚠️ 安装失败Manifest 逐组件检查
2PendingIntent 必须指定 FLAG_MUTABLE/FLAG_IMMUTABLE12+⚠️ 运行崩溃全量排查 PendingIntent 创建点
3动态注册广播接收器传 RECEIVER_EXPORTED/RECEIVER_NOT_EXPORTED13+⚠️ SecurityException所有 registerReceiver 调用点
4前台服务声明 foregroundServiceType + 对应权限14+⚠️ MissingForegroundServiceTypeException每个前台服务配类型与权限
5targetSdkVersion 最低门槛14(≥23) / 15(≥24)⚠️ 安装失败持续抬升 targetSdk
6动态代码加载 setReadOnly()14+⚠️ 异常DEX/JAR/APK 加载点
7so 库支持 16KB Page Size15+⚠️ crashAGP 8.3+,ELF 对齐,Apk Analyzer 检查
8第三方加固 / ART 内部依赖 SDK 升级12/16+⚠️ FC/ANR/SIGSEGV升级加固版本;移除 HiddenApiBypassFlyCore
9static final 反射/JNI 修改移除17(target≥37)⚠️ 进程崩溃改非 final / 依赖注入 / 升级 Mockito
10加载可写 .so 抛 UnsatisfiedLinkError17(target≥37)⚠️ UnsatisfiedLinkError加载前 setWritable(false)chmod 0444
11Parcel 回收后再读 / 大小不一致17⚠️ BadParcelableExceptionrecycle() 前完成读取;读写对称
12文件模式非法串(如 rwa17⚠️ IllegalArgumentException统一改 rw/wa
13线程优先级越界 [-20,19]17⚠️ IllegalArgumentException调用前 clamp

7.2 第二优先级:权限与隐私(不做功能受限/被系统限制)

#适配项涉及版本关键动作
1位置权限:ACCESS_FINE_LOCATION + ACCESS_COARSE_LOCATION 成对请求12+运行时双权限弹窗适配
2通知权限 POST_NOTIFICATIONS13+运行时申请;用户滑开通知不算互动
3Wi-Fi 权限 NEARBY_WIFI_DEVICES(+ neverForLocation13+替代部分 ACCESS_FINE_LOCATIONmaxSdkVersion=32 兼容
4后台身体传感器 BODY_SENSORS_BACKGROUND13+受限权限,需安装器许可名单
5媒体权限:READ_MEDIA_IMAGES/VIDEO + READ_MEDIA_VISUAL_USER_SELECTED13/14一次性声明防多次弹窗;URI 视为临时
6精确闹钟 SCHEDULE_EXACT_ALARM(默认拒)14+canScheduleExactAlarms() 检查;不必要改 set()/WorkManager
7全屏 intent USE_FULL_SCREEN_INTENT 收紧14+仅通话/闹钟;canUseFullScreenIntent() 检查
8截屏检测 DETECT_SCREEN_CAPTURE14+Manifest 声明 + registerScreenCaptureCallback
9屏幕录制检测 DETECT_SCREEN_RECORDING15+addScreenRecordingCallback
10Health 权限转型 BODY_SENSORShealth.READ_HEART_RATE16(target≥36)前台 READ_HEART_RATE,后台 READ_HEALTH_DATA_IN_BACKGROUND
11本地网络权限 ACCESS_LOCAL_NETWORK17(target≥37)运行时申请;影响 LAN Socket/mDNS/Wi-Fi Direct
12短信 OTP 保护 FILTER_GENERIC_OTP17(target≥37)迁移 SmsRetriever/User Consent API
13ECH 加密客户端 Hello 默认开启17(target≥37)企业防火墙可能不兼容,NSC 可关
14CT 证书透明度默认启用17(target≥37)证书提交 CT 日志,或 NSC 关闭
15Keystore 密钥数量限制(5万/20万)17定期 deleteEntry,捕获 ERROR_TOO_MANY_KEYS
16Android 开发者验证172026.9 部分地区强制;影响侧载渠道

7.3 第三优先级:行为变更与新能力(不做体验降级/被系统静默)

#适配项涉及版本关键动作
1不受信任触摸事件屏蔽12叠加层 alpha ≤ 0.8 才穿透;测试 BLOCK_UNTRUSTED_TOUCHES
2自定义通知改标准模板(高度 106→48dp)12UI 重适配
3通知 trampoline 限制12服务/广播内不 startActivity,改 PendingIntent
4应用休眠(数月未互动重置权限)12+退出休眠用 WorkManager/BOOT_COMPLETED 重新调度
5前台服务任务管理器(用户可停止整个应用)13+检查 REASON_USER_REQUESTED;长时间 FGS 关注 24h≥20h 通知
6电池受限分区(不传广播/不启 FGS)13(target≥13)关注活跃 widget / SCHEDULE_EXACT_ALARM 免限
7应用内语言选择器13+AppCompatDelegate/LocaleManager 替代自定义
8照片选择器 MediaStore.ACTION_PICK_IMAGES13+URI 不可持久访问
9BOOT_COMPLETED 启动 FGS 类型限制15(target≥35)仅白名单类型;SYSTEM_ALERT_WINDOW 需可见悬浮窗
10音频焦点后台限制15(target≥35)后台 requestAudioFocus 返回 FAILED
11Edge-to-edge 强制15(target≥35)fitsSystemWindows;Compose M3 处理 insets
12预测性返回(默认开启)15/16(target≥36 默认 true)声明 enableOnBackInvokedCallback;用 OnBackPressedCallback
13MediaProjection 锁屏自动停止16+实现 onStop() 回调
14Intent 重定向防护(嵌套 Intent 启非导出组件失效)16+显式 setPackage()removeLaunchSecurityProtection() opt-out
15后台音频静默 no-op17+可见 Activity / 非 SHORT_SERVICE FGS 才可控音量
16配置变更不重启 Activity17实现 onConfigurationChanged;或声明 recreateOnConfigChanges
17大屏忽略方向/尺寸限制17(target≥37)fullUser + resizableActivity=true;游戏 appCategory="game"

7.4 推荐的渐进式 targetSdk 抬升节奏

  1. 当前 targetSdk < 31:必须先过 Android 12 三大硬性项(exported、PendingIntent、通知 trampoline),否则 12 设备即崩。同时排查加固版本。
  2. targetSdk 31-32:升 33,过通知权限、Wi-Fi 权限、动态接收器导出标志。这是 Google Play 当前最低要求基线。
  3. targetSdk 33:升 34,过前台服务类型、动态代码只读、隐式意图限制、后台启动 Activity 限制。
  4. targetSdk 34:升 35,过 16KB so 库、Edge-to-edge、音频焦点后台限制、mediaProcessing 超时。
  5. targetSdk 35:升 36,过 Health 权限转型、预测性返回默认 true、Edge-to-edge 退出停用、ART 内部依赖清理。
  6. targetSdk 36 → 37(待正式发布):预研 DeliQueue、static final 锁、NPU 声明、本地网络权限、OTP 迁移、CT 证书、可写 .so 拒绝。

每个版本抬升前的通用检查

  • StrictMode.detectNonSdkApiUsage() 跑全量非 SDK 排查。
  • 兼容性框架 adb 切换开关逐项验证变更 ID。
  • 第三方库/SDK/加固在目标版本真机或云测跑核心流程。
  • 权限相关:用 ContextCompat.checkSelfPermission() 而非缓存权限状态。

数据来源:小米澎湃OS开发者平台官方文档(dev.mi.com/xiaomihyperos/documentation/detail)