第二章:Android蓝牙权限体系演化全景

2.1 概念解释:权限分层的三个时代

Android蓝牙权限体系并不是一夜之间变成“Android 12精细权限”的,它经历了三次结构性跃迁:

  • Android 6.0(API 23) —— 运行时权限时代:用户可以在应用运行时授予/撤销单个权限,蓝牙扫描首次从AndroidManifest.xml静态声明变为对话框授权。
  • Android 10(API 29) —— 位置关联时代:蓝牙扫描被强制关联ACCESS_FINE_LOCATION,因为扫描结果可以推算用户位置。
  • Android 12(API 31) —— 精细权限时代:新增BLUETOOTH_SCAN、BLUETOOTH_ADVERTISE、BLUETOOTH_CONNECT三个独立权限,切断与位置权限的硬绑定。
核心认知: 每一次权限拆分,都是为了“最小必要原则”更精准——让应用只为它真正需要的蓝牙能力请求授权,而不是“扫个蓝牙也要定位权限”。

2.2 原理图解:权限盒子 vs 能力盒子

下图为三个时代下,应用“需要蓝牙扫描”时实际被要求打开的权限盒子对比:

Android蓝牙权限体系演化:6→10→12 Android 6 BLUETOOTH BLUETOOTH_ADMIN 运行时弹窗授权 Android 10 BLUETOOTH ACCESS_FINE_LOCATION 位置+蓝牙 双重授权 Android 12+ BLUETOOTH_SCAN BLUETOOTH_ADVERTISE BLUETOOTH_CONNECT (若需位置推算) 按需精细授权 📌 变化本质 Android 6: 蓝牙权限是“开关型” → Android 10: 蓝牙被捆绑“位置” → Android 12: 蓝牙权限拆分为“功能型”, 扫描、广播、连接各自独立,位置权限仅在“需推算物理位置”时才要求。

上图清晰展示了:从Android 6到10,权限盒子数量未变但内容变重(加入位置);Android 12则把蓝牙盒子本身拆成了三个独立“小盒子”,开发者只需申请与功能对应的权限。

2.3 类比:从“包月健身房卡”到“按次计费”

  1. Android 6 时代: 你办了一张“蓝牙月卡”,可以进健身房(使用蓝牙),但必须前台签字(运行时弹窗)。
  2. Android 10 时代: 健身房要求你必须同时办一张“定位套餐”,因为健身轨迹能暴露你的活动范围——即使你只想用跑步机。
  3. Android 12 时代: 健身房把月卡拆成了“跑步卡”“游泳池卡”“wifi卡”,你只需买你真正需要的服务。只有在测量跑步里程(需要地理定位)时才额外购买位置体验。
💡 迁移思维: 如果你当前应用只做蓝牙扫描(不广播、不连接),在Android 12上只需申请BLUETOOTH_SCAN,不要顺手申请BLUETOOTH_CONNECT,避免用户感知“过度授权”。

2.4 常见误区

误区事实
“Android 12只需要BLUETOOTH_SCAN就能扫描蓝牙”错。因扫描结果可推测粗略位置,仍可能需要ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION(取决于是否用于位置推算)。
“我的应用targetSdk=30,不需要适配Android12权限”错。Google Play从2022年8月起要求新版本targetSdk≥31;即使暂时不更新,老旧API会触发系统兼容性警告,最终会被拒更。
“BLUETOOTH和BLUETOOTH_ADMIN在Android12已废弃”半正确。这两个旧权限仍然存在,但只用于“传统配对”场景,扫描必须改用新权限。混用可能导致系统拦截。
“声明了新权限就不需要旧权限”需要同时声明。Android12要求运行时声明旧权限(用于向后兼容)和新权限(用于真实能力),否则低版本设备会闪退。

2.5 应用边界:何时该用哪个权限组合?

根据蓝牙行为,推荐的最小权限集如下:

  • 仅扫描(不连接、不广播):
    • Android 12+:BLUETOOTH_SCAN + (若用于位置推算)ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION
    • Android 6~11:BLUETOOTH + ACCESS_FINE_LOCATION
  • 扫描 + 连接(如蓝牙耳机、打印机):
    • Android 12+:BLUETOOTH_SCAN + BLUETOOTH_CONNECT + (若需位置)ACCESS_FINE_LOCATION
    • Android 6~11:BLUETOOTH + BLUETOOTH_ADMIN + ACCESS_FINE_LOCATION
  • 广播(如Beacon发射器):
    • Android 12+:BLUETOOTH_ADVERTISE + BLUETOOTH_CONNECT(部分设备需要)
    • Android 6~11:BLUETOOTH + BLUETOOTH_ADMIN
⚠️ 边界陷阱: 如果你的应用在后台持续扫描蓝牙,即使Android 12也仍需要ACCESS_BACKGROUND_LOCATION(Android 10+引入)。精细权限并没有消除“后台位置”要求,只是剥离了前台扫描的强制位置捆绑。

2.6 练习题(随堂自测)

  1. 选择题:Android 12新增的三个精细权限中,哪个权限用于“使设备可被其他设备发现”?
    A. BLUETOOTH_SCAN B. BLUETOOTH_ADVERTISE C. BLUETOOTH_CONNECT D. BLUETOOTH_ADMIN
  2. 判断题:Android 12上,只要声明了BLUETOOTH_SCAN,就不需要再声明BLUETOOTH。( )
  3. 场景题:一款运动App需要在室内扫描用户的蓝牙手环(仅连接),不需要获取设备GPS位置。在Android 12上,最小权限声明应包含哪些?

参考答案: 1. B;2. ×(必须同时声明旧权限用于低版本兼容);3. BLUETOOTH_SCAN + BLUETOOTH_CONNECT(若不需要位置推算,可不加位置权限)。