第2章 Android蓝牙权限适配清单
Android 蓝牙权限体系自 API 级别 23(Android 6.0)起逐步演变为运行时权限模型,并在 Android 12(API 31)中进行了重大拆分。本章梳理 BLUETOOTH、BLUETOOTH_ADMIN、ACCESS_FINE_LOCATION、BLUETOOTH_CONNECT 四种权限的适配要求,并给出完整的运行时请求流程。
2.1 权限清单与说明
| 权限名称 | 用途 | 最低 API | 是否需要运行时请求 | 备注 |
|---|---|---|---|---|
| BLUETOOTH | 发起蓝牙连接、扫描、配对等基础操作 | 1 | 否(Android 12 以下) 是(Android 12+ 用于传统场景) | Android 12 后若 targetSdkVersion≥31,必须声明 BLUETOOTH_CONNECT 替代 |
| BLUETOOTH_ADMIN | 启用/禁用蓝牙、设置扫描模式 | 1 | 否(同上) | 同样在 Android 12+ 被 BLUETOOTH_SCAN 等拆解 |
| ACCESS_FINE_LOCATION | 允许蓝牙扫描获取精确位置(用于 BLE 扫描) | 23 | 是 | Android 10+ 需要;Android 12 后若仅使用 BLE,可改用 BLUETOOTH_SCAN(需配合) |
| BLUETOOTH_CONNECT | 发起蓝牙连接、配对、数据传输(Android 12+) | 31 | 是 | 替代 BLUETOOTH 的连接能力,无需位置权限 |
注意事项:若 targetSdkVersion 为 31 及以上,必须在 AndroidManifest.xml 中声明
BLUETOOTH_CONNECT 和 BLUETOOTH_SCAN(如需扫描),否则编译时会报权限缺失。2.2 Android 12+ 新增 BLUETOOTH_CONNECT 权限
Android 12 将传统 BLUETOOTH 和 BLUETOOTH_ADMIN 拆分为更细粒度的运行时权限:
- BLUETOOTH_CONNECT:用于连接已配对的蓝牙设备、传输数据。
- BLUETOOTH_SCAN:用于扫描蓝牙设备(不涉及位置)。
- BLUETOOTH_ADVERTISE:用于向外广播蓝牙信号。
对于仅需连接已配对设备的场景,只需 BLUETOOTH_CONNECT;若需扫描未配对设备,还需 BLUETOOTH_SCAN 和 ACCESS_FINE_LOCATION(Android 12 以下仍强制位置权限)。
2.3 运行时请求流程
以下步骤适用于 targetSdkVersion ≥ 31 的应用:
- 在 AndroidManifest.xml 中声明
BLUETOOTH_CONNECT(必要时加上BLUETOOTH_SCAN和ACCESS_FINE_LOCATION)。 - 在代码中检查权限是否已授予(
checkSelfPermission)。 - 若未授予,则调用
requestPermissions发起运行时请求。 - 在
onRequestPermissionsResult回调中处理结果。 - 权限授予后,才能执行蓝牙连接操作。
示例代码(Kotlin):
// 检查权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT)
!= PackageManager.PERMISSION_GRANTED) {
// 请求权限
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.BLUETOOTH_CONNECT),
REQUEST_BLUETOOTH_CONNECT
)
} else {
// 权限已授予,执行蓝牙操作
connectBluetooth()
}
// 处理权限请求结果
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray
) {
when (requestCode) {
REQUEST_BLUETOOTH_CONNECT -> {
if (grantResults.isNotEmpty() &&
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
connectBluetooth()
} else {
// 处理拒绝逻辑(提示用户或降级)
}
}
}
}
警告:在 Android 12 以下设备上,若 targetSdkVersion ≥ 31,系统可能会忽略
BLUETOOTH_CONNECT 权限(因为该权限不存在于旧版系统中),导致运行时崩溃。务必通过 Build.VERSION.SDK_INT 做版本判断,并在旧版使用 BLUETOOTH 权限。建议:使用
androidx.activity.result.ActivityResultLauncher 代替旧式 requestPermissions,以获得更简洁的回调方式。代码注意事项:在 Android 12 以下设备上,BLUETOOTH_CONNECT 权限在运行时 API 中不存在,直接请求会导致 Crash。必须通过
Build.VERSION.SDK_INT >= Build.VERSION_CODES.S 分支处理。掌握上述权限适配清单及请求流程后,即可正确获取蓝牙连接权限。下一环节将基于此权限状态,建立安全的 Keystore 加密通道。