Android如何在不申请位置权限的情况下扫描BLE设备
实现方案
没有通用的全版本无位置权限BLE扫描方案,不同系统版本的权限规则是系统层面强制约束的,按版本适配即可满足需求:
Android 12(API 级别 31)及以上版本(可完全移除位置依赖)
该版本开始系统已将BLE扫描权限从位置权限体系中拆分,按以下配置调整,即可实现无需申请位置权限、无需用户开启位置服务完成BLE扫描:
- 修改
AndroidManifest.xml权限声明,删除原有对ACCESS_COARSE_LOCATION、ACCESS_FINE_LOCATION的无版本限制声明,替换为Android12新增的专属BLE权限,核心是给BLUETOOTH_SCAN加上neverForLocation标记,向系统声明你的应用不会通过BLE扫描结果推导用户位置:
<!-- 旧版本需要的位置权限,仅在API30及以下生效,高版本自动忽略 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" /> <!-- BLE扫描权限,标记不用于位置推导 --> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" /> <!-- 如果需要和扫描到的BLE设备建立配对/连接,需要额外声明这个权限 --> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
- 动态权限申请逻辑做版本判断:当设备系统版本>=Android12时,仅动态申请
BLUETOOTH_SCAN(需要连接时再加BLUETOOTH_CONNECT)即可,不需要检查设备位置开关状态,即使用户全程关闭位置服务,扫描也能正常返回附近BLE设备的广播数据、MAC地址、信号强度等完整信息。
注意:如果漏加
neverForLocation标记,即使你没有声明任何位置权限,系统仍会默认你会通过BLE扫描推导用户位置,强制要求关联位置权限、开启位置服务才能完成扫描,这个配置是高版本移除位置依赖的核心,不能遗漏。
Android 11(API 级别 30)及更低版本(无法绕过位置依赖)
这些版本的系统在底层逻辑上就将BLE扫描能力和位置权限、位置开关强绑定,不存在官方支持的无权限绕过方案:
- 网上流传的反射调用隐藏API、修改系统配置等绕过方案,要么在多数厂商定制ROM上失效,要么会触发系统安全拦截导致应用崩溃,上架应用市场时也会因为违规调用接口被拒,不建议使用。
- 适配时只需做版本判断:在低于Android12的设备上,保留原有位置权限申请、位置开关开启提示逻辑即可,配合Manifest里给位置权限加的
maxSdkVersion="30"配置,高版本系统安装应用时完全不会展示位置权限申请项,符合高版本移除位置依赖的诉求。
内容的提问来源于stack exchange,提问作者Sumit Joshi
相关产品推荐
相关产品推荐

