目标版本为Android 12时能否移除清单中蓝牙相关的所有位置权限条目
结论:你当前的权限配置和申请逻辑无法在Android 11及更低版本正常运行,核心是对低版本系统的蓝牙权限规则存在误解。
规则说明:
- Android 12(API 31)及以上:谷歌新增了
BLUETOOTH_SCAN、BLUETOOTH_CONNECT等专用蓝牙运行时权限,只要你声明权限时加了neverForLocation标记,确实不需要再申请任何位置相关权限。 - Android 10~11(API 29~30):蓝牙扫描功能强制要求申请
ACCESS_FINE_LOCATION运行时权限,否则扫描结果为空。 - Android 6.0~9.0(API 23~28):蓝牙扫描功能强制要求申请
ACCESS_COARSE_LOCATION或ACCESS_FINE_LOCATION运行时权限,否则无法正常使用蓝牙功能。
官方提到的「Android12以上可移除位置权限」仅针对12及更高版本,旧系统的权限规则仍然生效,不是低版本不需要运行时权限。
你当前的两个问题:
- 清单文件未声明低版本需要的位置权限,系统会直接拒绝蓝牙扫描请求
- 代码逻辑中Android12以下直接调用
startScanning(),没有做位置权限的判断和申请逻辑,必然无法正常运行
修正方案:
- 补充清单权限声明,给位置权限加
maxSdkVersion=30限定,不会影响Android12及以上版本:
<!-- 补充低版本需要的位置权限 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" /> <!-- 原有权限可以保留,逻辑没问题 --> <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" /> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" tools:targetApi="s" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
- 补充低版本位置权限的申请逻辑:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { when { hasBluetoothPermissions() -> startScanning() shouldShowRequestPermissionRationale(Manifest.permission.BLUETOOTH_SCAN) || shouldShowRequestPermissionRationale(Manifest.permission.BLUETOOTH_CONNECT) -> { showDialog() } else -> requestPermissionLauncher.launch( arrayOf( Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT ) ) } } else { // 补充低版本位置权限判断逻辑 when { hasLocationPermission() -> startScanning() shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION) -> { showLocationRationaleDialog() } else -> requestLocationPermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION) } }
内容的提问来源于stack exchange,提问作者Donny Rozendal
相关产品推荐
相关产品推荐

