Skip to content

行为变更(targetSdk 36):升级 Android 16 目标平台的硬骨头清单 ​

本页导读:本页覆盖官方「行为变更:仅影响以 Android 16 为目标平台的应用」全部条目。只要把 targetSdkVersion 升到 36,这些变更就全量生效:edge-to-edge 退出通道关闭、预测性返回默认接管、sw600dp+ 忽略方向与宽高比、健康权限重构、蓝牙新 intent、Safer Intents、本地网络权限与「应用自有照片」。每项按「变更内容 → 影响面 → 检测与适配」展开。

版本注记:事实源为官方行为变更:以 Android 16 为目标平台(API 36),核对时间 2026-10。不随 targetSdk 的那一半在 01 页。

一、先分清两种「中招」方式 ​

  • 设备升 Android 16 就生效 → 看 01 页。
  • 自己把 targetSdk 升到 36 才生效 → 本页。开关机制是 targetSdkVersion 与兼容性行为协商(官方 <uses-sdk> 文档)。
  • 本页多数变更配有 App Compatibility Framework 开关,可在旧 target 上提前模拟(逐项 flag 见各节);官方全量名录:兼容性变更参考。

二、Edge-to-edge:退出通道正式关闭 ​

版本注记:Android 16 / API 36,仅 target36。15 上是「强制但可退出」,16 上是「强制且不可退出」。

变更内容

  • Android 15 提供的停用开关 R.attr.windowOptOutEdgeToEdgeEnforcement(官方属性参考)对 target36 应用已弃用且失效:
    • target36 的应用跑在 Android 15 设备上:该开关仍然生效(给你过渡期)。
    • target36 的应用跑在 Android 16 设备上:该开关被忽略,必然无边框。

影响面:内容顶到状态栏/导航条、系统栏下控件被刘海与手势条遮挡、自绘顶栏对比度问题——凡是以前靠 opt-out 压住不适配的界面全部现形。

检测与适配

  1. 全工程搜 windowOptOutEdgeToEdgeEnforcement,删除全部使用;先在 Android 15 设备上验证(此时开关刚失效)。
  2. 按官方迁移指南处理两类工具链:Views 见边缘到边缘布局,Compose 见窗口边衬(insets)。
  3. 回归重点:系统栏图标与背景对比、滚动内容末段留白(WindowInsets 消费)、弹窗/Toast 层级。

三、预测性返回:默认启用且 onBackPressed 停发 ​

版本注记:Android 16 / API 36,仅 target36 且运行于 Android 16+ 设备。

变更内容

  • 三类系统返回动画(返回主屏幕、跨任务、跨 activity)默认启用;同时系统不再调用 onBackPressed()、不再分发 KEYCODE_BACK——旧的返回拦截链直接断供。

影响面:所有还挂在 onBackPressed/KEYCODE_BACK 上的确认弹窗、编辑栈回退、播放器退出逻辑将静默失效(不崩溃,是更难发现的「不再被调用」)。

检测与适配

  1. 首选迁移到 OnBackInvokedDispatcher/预测性返回。
  2. 来不及迁移:在 <application> 或 <activity> 上设 android:enableOnBackInvokedCallback="false" 临时退出(官方明示这是过渡阀)。
  3. Android 16 还补了一批配套 API(见 03 页 §三):PRIORITY_SYSTEM_NAVIGATION_OBSERVER 观察者回调、finishAndRemoveTaskCallback()、moveTaskToBackCallback(),可在不拦截返回的前提下观察/触发系统动画。
  4. 回归:返回键/手势的每个拦截点逐一验证;特别注意三方 SDK(如扫码页、支付页)内部对 back 的接管。

四、优雅字体 API:elegantTextHeight 被忽略 ​

版本注记:Android 16 / API 36,仅 target36。

变更内容:Android 15 把 elegantTextHeight 默认置 true 并可手动改回;Android 16 起该属性弃用并忽略,「界面字体」的紧凑排版即将停用。

影响面:阿拉伯文、老挝文、缅甸文、泰米尔文、古吉拉特文、卡纳达文、马拉雅拉姆文、奥里亚文、泰卢固文、泰文等复杂文种的行高/裁切表现变化。

适配:不再指望该属性救行高,按 elegantTextHeight=true 的排版全量回归以上语种的界面(重点:固定高度 TextView 的裁字);同时关注 04 页 §六 提到的竖排文本等新渲染能力对自绘文本的影响。

五、固定费率任务:错过的执行只补一次(闹钟类变更在这里) ​

版本注记:Android 16 / API 36,仅 target36。

变更内容:AlarmManager.scheduleAtFixedRate 过去错过 N 次就在回到有效生命周期时立刻连发 N 次;target36 起最多立即补 1 次。

影响面:依赖「补跑全部周期」语义的同步/轮询逻辑行为改变(官方预期是性能收益)。

检测:提前用兼容性开关模拟——

bash
adb shell am compat enable STPE_SKIP_MULTIPLE_MISSED_PERIODIC_TASKS <包名>

适配:把周期任务写成幂等(按时间戳差集补算,而不是按回调次数计数)。

澄清:这才是 Android 16 官方页上唯一的「闹钟类」变更。不存在所谓「16 收紧闹钟权限」——精确闹钟权限体系属于 Android 12–14 的既有约束(SCHEDULE_EXACT_ALARM)。

六、大屏自适应布局:方向、可调整性、宽高比被忽略(桌面窗口化的地基) ​

版本注记:Android 16 / API 36,仅 target36,作用于最小宽度 ≥ 600dp 的显示屏(sw600dp+)。

变更内容:在全屏与多窗口(含桌面窗口化/freeform)模式下,以下清单属性与运行时 API 在大屏上被忽略:

被忽略项类型
android:screenOrientation清单属性
android:resizeableActivity清单属性
android:minAspectRatio / android:maxAspectRatio清单属性
setRequestedOrientation() / getRequestedOrientation()运行时 API
  • screenOrientation 的 portrait/reversePortrait/sensorPortrait/userPortrait/landscape/reverseLandscape/sensorLandscape/userLandscape 八个值全部按忽略处理;应用直接填满整个显示窗口,不再有竖屏 letterbox。
  • 官方给出的例外(不适用忽略逻辑)三种情形:游戏类应用(按 android:appCategory 判定)、用户在设备「宽高比设置」里显式开启该应用的旧行为、屏宽 < sw600dp。

影响面:为竖屏小屏硬编码的布局在大屏/桌面窗口出现拉伸、动画错位、组件出界;旋转/窗口尺寸变化更频繁 → activity 重建概率大增,未保存状态直接丢。

检测与适配

  1. 提前测试:adb shell am compat enable UNIVERSAL_RESIZABLE_BY_DEFAULT <包名>;再配合分屏与桌面窗口化形态(平板/大折叠外屏)过一遍核心页。
  2. 状态保活:onSaveInstanceState/rememberSaveable 全量检查(保存界面状态)。
  3. 临时退出(activity 或 application 级,官方明示未来 target 37 作废):
xml
<activity ...>
  <property android:name="android.window.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY"
            android:value="true" />
</activity>
  1. 长期方向就是官方口号:布局自适应任意窗口尺寸与方向,见自适应布局与自适应应用。桌面窗口化模式的设计规范见桌面设计。

七、健康与健身:BODY_SENSORS 全面让位给细粒度权限 ​

版本注记:Android 16 / API 36,仅 target36。

变更内容:target36 起,过去要 BODY_SENSORS / BODY_SENSORS_BACKGROUND 的 API 一律改需 android.permission.health 族下的细粒度权限(与 Health Connect 同一套),官方点名四类受影响面:

  • Wear OS 健康服务的 HEART_RATE_BPM;
  • Sensor.TYPE_HEART_RATE(传感器框架);
  • Wear OS ProtoLayout 的 heartRateAccuracy / heartRateBpm;
  • FOREGROUND_SERVICE_TYPE_HEALTH 前台服务类型(需用对应 health 权限)。

迁移口径:使用期间心率/血氧/体表温度 → 申请 READ_HEART_RATE 等对应细分权限替代 BODY_SENSORS;后台传感 → READ_HEALTH_DATA_IN_BACKGROUND 替代 BODY_SENSORS_BACKGROUND。额外硬要求:移动应用必须声明用于展示隐私政策的 activity;理由缺失会被直接撤权。参见Health Connect 与前台服务类型。

检测:清单里出现 BODY_SENSORS* 且用到上述 API 的,升 target36 前后各跑一次授权/取数/FGS 启动全链路,验证无静默取数失败。

八、蓝牙(target36 增量):绑定丢失 intent 与解除配对 API ​

版本注记:Android 16 / API 36,仅 target36;全应用层面的绑定丢失行为改造见 01 页 §十二。

变更内容

  • 两个新 intent:ACTION_KEY_MISSING(检测到远端配对丢失时广播)与 ACTION_ENCRYPTION_CHANGE(链路加密状态/算法/密钥长度变化;若在丢失后又收到成功加密的该 intent,应视为绑定已恢复)。
  • 官方同时提醒 OEM 实现差异:有的设备广播 ACTION_KEY_MISSING(同时断 ACL、保留配对记录),有的不广播(行为同 Android 15,直接移除配对记录)——应用两套都要兜住。
  • CompanionDeviceManager 新增公开 removeBond(int):CDM 关联内的设备可由应用发起解除配对,配合监听 ACTION_BOND_STATE_CHANGED 跟踪结果。文档:配套设备配对。

适配策略(官方建议原样落地):收到 ACTION_KEY_MISSING 就把它当配对丢失的主信号,引导用户确认远端在范围内再重配对,断连后谨慎自动重连;收不到该 intent 就沿用旧版丢失处理兜底。

九、安全三项:MediaStore 版本锁定、Safer Intents、Mali GPU IOCTL 过滤 ​

版本注记:Android 16 / API 36,仅 target36。

9.1 MediaStore 版本锁定 ​

MediaStore#getVersion() 返回值改为每应用唯一,剥离可作指纹的标识属性;应用不得对版本字符串格式做任何假设(官方原话)。正常「检测版本变化→重同步」逻辑无需改动。

9.2 Safer Intents:接收侧严格匹配(选择启用) ​

  • 两项规则:显式 intent 必须命中目标组件的 intent-filter;无 action 的 intent 不再匹配任何 filter。仅跨应用场景生效,app 内不受影响。
  • 目前是选择启用(官方路线图:未来版本将转为默认强制)。清单开关 intentMatchingFlags,可对 <application> 开、单组件关:
xml
<application android:intentMatchingFlags="enforceIntentFilter">
    <receiver android:name=".MyBroadcastReceiver" android:exported="true"
              android:intentMatchingFlags="none">
        <intent-filter>
            <action android:name="com.example.MY_CUSTOM_ACTION" />
        </intent-filter>
    </receiver>
</application>
标志含义
enforceIntentFilter对传入 intent 启用更严格匹配
none关闭该组件的全部特殊匹配规则(多标志冲突时优先)
allowNullAction放宽允许匹配无 action intent,需与 enforceIntentFilter 并用
  • 检测:被拦 intent 会打告警日志,用官方过滤器盯住——
bash
# 官方给出的过滤式(Android Studio Logcat 查询语法):
# tag=:PackageManager & (message:"Intent does not match component's intent filter:" | message:"Access blocked:")
adb logcat -d | grep -E "PackageManager.*(does not match|Access blocked)"

9.3 GPU(Mali)系统调用过滤 ​

  • 面向 Mali GPU 的加固:正式版屏蔽弃用/开发用 IOCTL,GPU 性能分析类 IOCTL 仅留给 shell 与可调试应用;落地于 Pixel 6–9(Mali),AOSP 默认携带、OEM 可选择启用。受影响的典型症状是 SELinux avc: denied { ioctl } path="/dev/mali0"。
  • 官方口径:Vulkan/OpenGL 正常使用不受影响,Streamline/AGI 等剖析工具不受影响;分类表在 Arm 官方 Documentation/ioctl-categories.rst(r54p2)。
  • 若业务确需被屏蔽 IOCTL:官方渠道是提 bug 至 android-partner-security@google.com(OEM 向)。应用开发者一般只需在测试日志里扫 avc: denied 确认无感。

十、隐私两项:本地网络权限与应用自有照片 ​

版本注记:Android 16 / API 36。LNP 是跨 25Q2/26Q2 两个发布通道的长线项目,本页核对时(2026-10)处于「选择启用、即将强制」阶段。

10.1 本地网络保护(LNP) ​

  • 目标:把「有 INTERNET 就能扫局域网」收进运行时权限。官方节奏:25Q2 版本选择启用收集反馈,26Q2 前的版本强制;最终归入「附近的设备」权限组新权限。
  • 影响判定(官方表):
操作需要本地网络权限
建立出站 TCP 连接是
接受入站 TCP 连接是
发送 UDP 单播/多播/广播是
接收 UDP 单播/多播/广播是
  • 实施在网络栈深处:原生/托管 socket、OkHttp/Cronet、NsdManager、mDNS/SSDP 发现、.local 解析全覆盖;WebView 流量继承宿主应用状态。例外:DNS 服务器(:53)流量、使用输出切换器作应用内投屏选择器的场景。
  • 本地网络定义:Wi-Fi/以太等广播型接口所在 IP 网(含 RFC1918、CGNAT 100.64/10、链路本地、多播/广播地址),不含蜂窝与 VPN。
  • 提前测试(官方命令):
bash
adb shell am compat enable RESTRICT_LOCAL_NETWORK <包名>   # 开启限制
adb shell am compat disable RESTRICT_LOCAL_NETWORK <包名>  # 恢复
  • 症状识别:对本地地址 sendto failed: EPERM / ECONNABORTED。当前阶段被限时授予 NEARBY_WIFI_DEVICES(设置→应用→权限→附近的设备)可临时恢复。
  • 投屏类应用重点盯官方后续指南(媒体投屏多数依赖局域网发现与直连)。

10.2 应用自有照片 ​

target36 应用在 Android 16+ 触发「照片与视频」选权限流程时,用户若选「限制访问所选媒体」,系统会在照片选择器中预选本应用自有照片;用户可取消选择,从而一并收回应用对自有照片的访问。适配要点:不要再默认「自己拍的一定读得到」,对自有文件同样走用户授权路径(媒体 URI 或照片选择器,见 04 页 §五)。

十一、澄清区:这些常被安到 target36 头上但其实不是 ​

传言核实结果(2026-10 官方两页行为变更)
「target36 通知要逐个授权」无此项。通知运行时权限 POST_NOTIFICATIONS 是 Android 13(API 33)内容;16 的通知变化是新增 ProgressStyle 进度通知(特性,非限制)
「target36 后台音频被禁」无此专项。后台媒体限制主要挂在 Android 14(API 34)前台服务类型体系
「APK 签名 v4 是 16 新规」不属实。v4 签名方案是 Android 11(API 30)的增量安装配套;16 官方页无 APK 签名新版本
「闹钟权限收紧」无新增权限;本页 §五 的 scheduleAtFixedRate 补跑收敛才是 16 的闹钟类变更

本页小结 ​

本页小结:targetSdk 36 的四座山:edge-to-edge 不可退出(删开关 + 双 toolkit insets 回归)、预测性返回默认化(onBackPressed 断供,迁移或临时关阀)、sw600dp+ 忽略方向/比例限制(桌面窗口化时代的自适应要求,临时退出属性到 target37 作废)、隐私重构(健康细粒度权限 + LNP 局域网访问收口 + 应用自有照片回访)。安全线新增 Safer Intents(选择启用,迟早变默认)与 Mali GPU IOCTL 过滤。升级前把 §二/§三/§六 三节当冒烟测试项跑完,再动其余。

参考资料 ​

基于 Android 16 / API 36 · 内容为原创整理,转载请注明出处