android17系统兼容
Android 官方已经发布了 Android 17 的相关适配文档,其中有不少值得提前关注的内容,另外在去年谷歌也发布过 Android 开发者认证的通告,没认证的应用将无法安装,而时间节点也正好是 2026 。

Android 17 适配
- usesCleartextTraffic 的弃用规划 ,注意,这个变更在这Android 17 这里不是立刻更改,而是会在未来版本计划弃用 usesCleartextTraffic,所以官方建议开发者迁移到 Network Security Config 来按域名白名单方式允许 HTTP。不会还有个需要注意的是,Network Security Config 只支持 API 24+,低于 24 的 app 可能需要两者都配,同时这个变更并不是针对 target 的,也就是就算你不用 target android 17 ,也会在未来受到影响。
- "隐式 URI grant" 的限制" 这个也是未来的变更预警,官方计划在 Android 18 上生效, 在之前当 app 用 Send / SendMultiple / ImageCapture 携带 URI 启动 intent 时,系统当前会"自动"把读写 URI 权限给目标 app,所以 Android 17 开始建议开发者别依赖系统自动授予,而要显式授予 URI 权限。在 Android 17 之前,当你发送一个带有 ACTION_SEND(分享)的 Intent 时,系统看到你带了一个 URI,会自动地帮目标应用开了读写权限现状: 开发者即便忘了写 FLAG_GRANT_READ_URI_PERMISSION,代码通常也能跑通Android 18 : 如果你不显式授权,目标应用(接收方)打开 URI 时会可能会直接报 SecurityException这其实也贴合未来的 Android 将更深度地集成类似 Gemini 的系统级 AI 的场景,这些 AI 能够跨应用读取屏幕内容、处理 Intent,而如果系统允许隐式授权,那么 AI 在处理复杂的链式任务(例如:从 A 应用提取图片 -> B 应用修图 -> C 应用分享)时,权限链路风险会大的提升。❝显式授权建立了一个"权限存根",可以让 AI 介入时,方便系统清晰地追踪到:是用户在 A 应用授权了 AI 读取这个文件。对于开发者来说就是:任何走 intent + content URI 之类,如分享/拍照回传的链路都应该显式 grantUriPermission / flags。(总结起来第一步搜索Intent.ACTION_SEND使用到的位置,然后添加上 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION); - 系统不再"恢复之前的键盘显示状态" 从 Android 17 开始:如果发生配置变化(比如旋转),且你的 app 自己没有处理,那么系统不会恢复之前 IME(软键盘)的状态。如果开发者希望旋转后键盘仍然弹出,需要显式在 windowSoftInputMode 或在 onCreate() / onConfigurationChanged() 里主动请求 。
- Background audio hardening Android 17 上后台音频收紧,如果 app 在没有可见 Activity时还想控制音频(播放/请求焦点/调音量),需要:运行一个 前台服务(FGS),且不是 SHORT_SERVICE;并且这个 FGS 必须带有 while-in-use(WIU)能力:要么因 MediaSessionEvent 启动,要么在 app 可见时由用户触发启动当然,异常情况的反馈也很"阴间"播放与音量相关 API 可能静默失败(不抛异常、也不给失败信息)Audio focus 请求会返回 AUDIOFOCUS_REQUEST_FAILED针对 targetSdk=37
- MessageQueue 无锁"实现 针对 targetSdk 为 Android 17 的场景,官方引入了名为 DeliQueue 的新架构,将传统的基于单一锁(Monitor Lock)的 MessageQueue 替换为无锁数据结构,它使用 Treiber 栈进行无锁消息插入,并结合最小堆进行单线程处理。目的是减少主线程锁竞争、降低掉帧,但可能会破坏那些反射访问 MessageQueue 私有字段/方法的代码,实际上一般正常使用无碍,只会觉得性能变好了,特别是 Flutter 的 MethodChannel , 无锁 MessageQueue 大概率会提升不少性能,但是如果你用过什么黑魔法 hack 过 MessageQueue ,那就很可能异常了。❝比如你通过反射访问私有字段 mMessages ,那么这部分代码都会失效,就算 mMessages 字段为了兼容性依然存在,但它也会永远返回 null。
- BAL进一步收紧,扩展到 IntentSender 官方把 Background Activity Launch 相关保护扩展到 IntentSender,并要求从旧常量迁移到更细粒度的模式,例如 MODE_BACKGROUND_ACTIVITY_START_ALLOW_IF_VISIBLE
- 新增安装时权限 USE_LOOPBACK_INTERFACE 这是一个安装时权限,所以它的限制比较多,它 引入了 USE_LOOPBACK_INTERFACE:在跨 app / 跨 profile 的 127.0.0.1 / ::1 通信默认被阻断,需要通信双方都在 manifest 里声明该权限并获得同意,当然,同一 app 内部 loopback 不受影响。而在 Target 是 17 且缺失权限时,socket 可能直接 EPERM。
- 默认启用 Certificate Transparency(CT) 现在在 Target 是 17 时,证书透明度 (CT) 会默认开启,CT 是一套用于记录和审计数字证书发行情况的系统:要求所有的证书颁发机构(CA)必须将他们签发的每一个证书都公开登记到一个"审计日志"中防止 CA 被黑客攻击或错误地签发了假证书(例如,有人非法给 google.com 签发了一个证书并尝试进行中间人攻击)当你的应用 targetSdkVersion 升级到 37 后,系统会对所有 HTTPS 连接强制执行 CT 检查,如果服务器返回的 SSL 证书没有被记录在公共 CT 日志中(或者没有附带有效的 SCT 签名),Android 系统会直接拒绝连接。而在 Android 17 之前,你需要通过 network_security_config.xml 手动加入 ,而在 Android 17 之后,这个标签默认就是 true。❝虽然 Flutter 引擎使用的是 C++ 的 BoringSSL,但在 Android 平台上,系统可能会在底层(Socket 级别)执行某些安全策略,或者 cronet_http 等场景受到影响。