如何在React Native 0.62中适配Android 12的蓝牙权限?
Android 12蓝牙权限适配React Native 0.62方案
针对React Native 0.62不支持Android 12新增的BLUETOOTH_SCAN、BLUETOOTH_CONNECT权限,导致permission is null错误的问题,提供以下三种适配方案:
方案一:通过原生Module桥接申请权限
直接利用Android原生代码实现权限申请,绕过RN的PermissionsAndroid限制:
创建Android原生模块
在Android项目中新建BluetoothPermissionModule.java,实现权限申请逻辑:package com.yourappname; import android.Manifest; import android.app.Activity; import android.content.pm.PackageManager; import androidx.core.app.ActivityCompat; import com.facebook.react.bridge.Promise; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; public class BluetoothPermissionModule extends ReactContextBaseJavaModule { private static final int REQUEST_BLUETOOTH_PERMISSIONS = 1001; private Promise permissionPromise; public BluetoothPermissionModule(ReactApplicationContext reactContext) { super(reactContext); } @Override public String getName() { return "BluetoothPermissionModule"; } @ReactMethod public void requestBluetoothPermissions(Promise promise) { permissionPromise = promise; Activity currentActivity = getCurrentActivity(); if (currentActivity == null) { promise.reject("ACTIVITY_NULL", "Current activity is null"); return; } String[] permissions = { Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT }; ActivityCompat.requestPermissions(currentActivity, permissions, REQUEST_BLUETOOTH_PERMISSIONS); } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if (requestCode == REQUEST_BLUETOOTH_PERMISSIONS && permissionPromise != null) { boolean allGranted = true; for (int result : grantResults) { if (result != PackageManager.PERMISSION_GRANTED) { allGranted = false; break; } } if (allGranted) { permissionPromise.resolve(true); } else { permissionPromise.reject("PERMISSION_DENIED", "Bluetooth permissions denied"); } permissionPromise = null; } } }同时在
MainApplication.java中注册该模块。RN中调用原生模块
import { NativeModules } from 'react-native'; const { BluetoothPermissionModule } = NativeModules; const requestBluetoothPermissions = async () => { try { const isGranted = await BluetoothPermissionModule.requestBluetoothPermissions(); return isGranted; } catch (error) { console.error('权限申请失败:', error); return false; } };
方案二:直接传递权限字符串申请
RN的PermissionsAndroid支持直接传入权限字符串,无需依赖枚举值:
import { PermissionsAndroid } from 'react-native'; const requestBluetoothPermissions = async () => { const requiredPermissions = [ 'android.permission.BLUETOOTH_SCAN', 'android.permission.BLUETOOTH_CONNECT', ]; try { const grantResults = await PermissionsAndroid.requestMultiple(requiredPermissions); return ( grantResults['android.permission.BLUETOOTH_SCAN'] === PermissionsAndroid.RESULTS.GRANTED && grantResults['android.permission.BLUETOOTH_CONNECT'] === PermissionsAndroid.RESULTS.GRANTED ); } catch (error) { console.error('权限申请出错:', error); return false; } };
方案三:升级React Native版本到0.66+
如果项目允许,升级RN到0.66及以上版本,官方已内置这两个权限的枚举值,可直接使用:
import { PermissionsAndroid } from 'react-native'; const requestBluetoothPermissions = async () => { const granted = await PermissionsAndroid.requestMultiple([ PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN, PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT, ]); return granted[PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN] === PermissionsAndroid.RESULTS.GRANTED && granted[PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT] === PermissionsAndroid.RESULTS.GRANTED; };
通用配置:AndroidManifest.xml权限添加
无论采用哪种方案,都需要在AndroidManifest.xml中添加以下权限配置:
<!-- Android 12+ 蓝牙权限 --> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <!-- 若无需通过蓝牙获取位置信息,添加此flag避免申请位置权限 --> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" /> <!-- 兼容Android 11及以下版本 --> <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
内容的提问来源于stack exchange,提问作者Septatrivanto Wandy
相关产品推荐
相关产品推荐

