Android 17 新适配要求,各大权限进一步收紧,适配难度提升

0 阅读6分钟

在之前的《Android 17 有什么需要适配的?》我们已经聊过了部分更新场景,而最近 Android 又进一步增加了权限部分的调整。

目前 Android 17 已经进入 Beta 后期阶段,而官方这波更新也进一步收紧权限,甚至可以说是系统级控制模型重构阶段

位置权限

从 Android 17 开始,Android 引入了单次授权与动态粗略定位算法,新增了 “位置按键”(system-provided location button),用于单次精确位置授权,也就是,对于许多常见场景,例如在社交 App 中发帖时添加位置标签,App 并不需要永久或持续在后台访问用户的精确定位。

也就是以后的位置权限,用户可以只在“这一刻”提供精准位置,会需要用到 USE_LOCATION_BUTTON 权限:

当然,这里有个特殊在于,“位置按键”这次 Android 提供相对丰富的自定义选项,支持开发者在保持系统级可识别性的前提下,自定义对应风格

也就是开发者可以修改按键的背景与图标配色方案、轮廓样式以及尺寸形状,不过为了确保安全与信任,位置图标本身为强制显示且无法自定义,同时字体大小则由系统管理。

而在适配实现上,“位置按键” 会通过 Jetpack 库的形式提供,从而简化位置权限的请求流程,使用对应 Jetpack 库实现位置按键,系统会自动处理向后兼容,比如用户在Android 16 或更低版本上点击按键,会默认回退至现有的位置权限提示,

这个功能会在 Android 17 Beta 3 开放测试,从 Android 17 开始,位置访问透明度就基本和麦克风/摄像头一个水平,系统会新增一个状态指示器,每当非系统应用访问位置时,指示器将持续显示,而用户可以通过指示器,查看近期访问过位置的具体应用,并通过“近期应用使用”对话框即时管理相关权限。

同时这次 Android 还增强了粗略定位算法(Approximate Location)的精度,不过「大致位置」功能场景对于很多 App 一般使用场景很有效。

联系人权限变化

Android 17 开始增加了全新的 ACTION_PICK_CONTACTS ,用来收紧目前应用过度读取通讯录的隐私问题,因为 ACTION_PICK_CONTACTS API 类似现有的系统图片选择器,不再全面授权 READ_CONTACTS权限,而是采用 Intent.ACTION_PICK_CONTACTS 机制:

通过 picker ,app 只能看到用户勾选的具体联系人,而应用只能请求所需的特定数据字段,最重要的是,这个功能可能支持打破了系统分身限制,支持从设备上的其他系统分身里读取联系人。

官方说的是支持 profile switching ,也就是选择器支持在不同 profile 间切换。

APM 和无障碍权限

Android 17 正式加入了一种新的系统级安全模式 Advanced Protection Mode( APM 高级保护模式) ,用户打开后会启用一组更激进的安全策略,在 APM 模式下,会限制侧载、限制 USB 传输数据、强制进行 Google Play Protect 扫描、同时限制高风险权限行为和强化日志与检测。

这个场景下,首当其冲的就是大概率就是 AccessibilityService ,这个模式 Android 16 就介绍过,Android 的 APM 模式会针对使用辅助功能服务 API ,但没有被归类为辅助功能工具的应用(Google Play 上 isAccessibilityTool 属性),会禁用它们对辅助功能服务 API 的使用。

开启高级保护模式后,Android 系统不仅会阻止用户向非辅助功能工具授予辅助功能服务权限,还会撤销已授予的权限,而开发者可以通过 AdvancedProtectionManagerQUERY_ADVANCED_PROTECTION_MODE 去感知其状态。

其他

后台启动 Activity(BAL)进一步限制

Android 17 开始 BAL(background activity launcher) 限制扩展到了 IntentSender ,旧的 MODE_BACKGROUND_ACTIVITY_START_ALLOWED 需要迁移,推荐改用更细粒度的模式,比如 MODE_BACKGROUND_ACTIVITY_START_ALLOW_IF_VISIBLE

本地网络权限

Android 17 开始,对 target 37 ACCESS_LOCAL_NETWORK 开始强制化,新增权限:

<uses-permission android:name="android.permission.ACCESS_LOCAL_NETWORK"/>

也就是没有声明权限会无法访问局域网,内网访问从“默认开放” 变为 “权限保护” 机制,这在物联网和智能家居场景而已可能变化比较大。

访问 LAN(如设备发现)需要:

  • 显式声明并在运行时请求 ACCESS_LOCAL_NETWORK
  • 用系统提供的 privacy-preserving picker

它属于 NEARBY_DEVICES 权限组,如果你的应用涉及投屏、打印或智能家居,就需要额外检查 NEARBY_DEVICES 权限组的集成,因为 ACCESS_LOCAL_NETWORK 在该组下。

短信验证码(OTP)读取延迟

Android 17 开始App 无法立即读取 OTP 短信,默认延迟3 小时后才允许访问,官方建议使用:

  • SMS Retriever API
  • SMS User Consent API

动态代码加载(DCL)进一步加强

Android 17 开始所有 native 库 System.load() 必须只读(read-only),否则直接崩溃,这对于热更新的影响会比较大:

  • Android 14 已经把 DCL 的只读要求施加到 DEX/JAR。

  • Android 17 把这个保护进一步扩展到 native libraries。

所以 System.load() 加载的 native 文件必须是只读,否则就回 UnsatisfiedLinkError

val libraryFile = File(context.filesDir, "my_native_lib.so")
// Mark the file as read-only before loading to comply with Android 17+ security requirements
libraryFile.setReadOnly()

System.load(libraryFile.absolutePath)

对于有热更新需求的应用,必须在 System.load() 之前显式调用 file.setReadOnly()。

证书透明度(CT)默认开启

Android 17 开始,对于 target sdk 37 的会自动启用 CT(Certificate Transparency),也就是HTTPS 证书必须在 CT 日志中可验证。

静态 final 字段不可修改

在 target 37+ 并且运行在 Android 17+ 上时,不能再通过反射修改 static final 字段,如果使用反射会出现 IllegalAccessException

也就是 Android 17 进一步收紧了运行时篡改能力,这也会影响部分依赖运行时 hook、魔改常量或底层注入的框架和工具链。

密码显示策略拆分

密码可见策略在 Android 17 被拆成 touch 和 physical keyboard 两套,物理键盘默认直接隐藏字符。

也就是 Android 17 调整了密码回显策略,将“Show passwords”拆分成触屏输入与物理键盘输入两套设置,对物理键盘,默认不再短暂回显最后一个字符。

val isPhysical = event.source and InputDevice.SOURCE_KEYBOARD == InputDevice.SOURCE_KEYBOARD
val shouldShow = android.text.ShowSecretsSetting.shouldShowPassword(context, isPhysical)

链接

developer.android.com/about/versi…

developer.android.com/about/versi…

developer.android.com/about/versi…

developer.android.com/privacy-and…

android-developers.googleblog.com/2026/03/loc…

support.google.com/googleplay/…

www.androidauthority.com/android-adv…

android-developers.googleblog.com/2026/03/the…