React Native中Android11及以下版本Bluetooth权限不生效问题求助
问题相关环境配置
- Build Tool版本:30.0.2
- Android SDK版本:7.0.4
- React Native版本:68.0
问题现象
蓝牙权限在Android 12设备上可正常弹出授权弹窗,完成权限申请流程;但在Android 11及更低版本设备上始终无法触发权限申请弹窗,蓝牙相关功能无法正常使用。
排查解决步骤
- 优先检查AndroidManifest.xml的权限声明适配
90%的这类问题都是权限声明只适配了Android 12,漏了低版本要求的权限项,或是版本阈值配置错误,导致低版本系统识别不到需要申请的权限,自然不会弹出授权窗。
直接替换Manifest中<manifest>节点下的所有蓝牙相关权限配置为以下分层声明:
注意:Android 11及更低版本下,蓝牙扫描能力强依赖位置权限,缺了位置权限哪怕声明了蓝牙相关权限,系统也不会触发授权流程。<!-- Android 12(API 31)及以上版本专属蓝牙权限 --> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" /> <!-- Android 11(API 30)及以下版本所需权限,必须加maxSdkVersion限制避免高版本重复申请 --> <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.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" /> - 校验权限申请逻辑的版本分支
Android 12能正常弹框仅说明高版本权限申请逻辑正常,需要确认代码里的版本判断分支是否覆盖低版本场景:- 系统版本≥API 31时,申请
BLUETOOTH_SCAN、BLUETOOTH_CONNECT、BLUETOOTH_ADVERTISE三个权限 - 系统版本≤API 30时,申请
BLUETOOTH、BLUETOOTH_ADMIN、ACCESS_FINE_LOCATION三个权限
调试时直接在权限申请触发点打日志,打印当前系统版本号、待申请的权限列表,确认低版本下传入权限申请接口的列表没有错传成Android 12的专属权限。如果使用第三方蓝牙库、权限申请库,先确认库版本没有低版本权限分支遗漏的问题,不少库的早期适配版本只加了Android 12的新权限逻辑,完全没处理低版本分支。
- 系统版本≥API 31时,申请
- 核对build.gradle配置项
打开app模块下的build.gradle文件,确认两个配置:targetSdkVersion和你用的build tool版本匹配即可,不要给低版本的BLUETOOTH、BLUETOOTH_ADMIN、ACCESS_FINE_LOCATION权限配置小于30的maxSdkVersion,否则低版本系统会直接忽略这些权限声明- 不要把位置权限的申请逻辑误套上「仅API 31以上执行」的版本判断,否则低版本下根本不会触发位置权限申请,连带蓝牙权限也无法正常弹窗
- 排查系统层面的权限拦截
完成前面配置后如果仍不弹框,先到测试机的应用信息-权限管理页手动查看权限状态:- 如果对应权限已经被设置为「拒绝且不再询问」,系统会直接拦截权限申请弹窗,不会有任何提示,这种情况需要引导用户跳转到应用设置页手动开启权限
- 老版本MIUI、ColorOS等定制ROM会强制绑定蓝牙和位置权限,哪怕代码里声明了蓝牙权限,没有同时申请位置权限的话,系统会直接拦截蓝牙权限弹窗,这种情况可以先手动给应用授予位置权限,再测试弹窗是否正常触发
- 检查RN端桥接逻辑
RN 0.68本身不会自动做蓝牙权限的版本适配,如果是自研原生模块桥接权限申请,要确认原生端的requestPermissions方法能正确接收到JS端传的低版本权限列表,不要在原生端写死只申请Android 12的新蓝牙权限。如果使用第三方权限库,要确认低版本下的权限常量配置正确,没有只配置Android 12的权限项。
内容的提问来源于stack exchange,提问作者R.mane
相关产品推荐
相关产品推荐

