我正在调试一个绝对需要蓝牙权限的React Native应用程序,但是目前在Android中蓝牙权限正在返回
unavailable
。 <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
我正在检查蓝牙权限的状态,如下所示:
const checkBluetoothPermissions = () => {
requestMultiple(
Platform.OS === 'android'
? [
PERMISSIONS.ANDROID.BLUETOOTH_SCAN,
PERMISSIONS.ANDROID.BLUETOOTH_CONNECT,
PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION,
]
: [PERMISSIONS.IOS.BLUETOOTH_PERIPHERAL],
).then(_ => {
console.log('permission results', _);
});
};
从此函数记录的内容是
permission results {"android.permission.ACCESS_FINE_LOCATION": "granted", "android.permission.BLUETOOTH_CONNECT": "unavailable", "android.permission.BLUETOOTH_SCAN": "unavailable"}
安装应用程序时,唯一要求的权限是location
,我不知道为什么。
我按照此处的说明操作:react-native-permissions。
同一代码库的 IOS 上没有问题。
这样做
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
并调用这个函数
import {
requestMultiple,
PERMISSIONS,
RESULTS,
} from "react-native-permissions";
const getStatusPermissions = async () => {
const androidOsVer =
Platform.os === "android" && Platform.constants["Release"];
let androidPermissions = [PERMISSIONS.ANDROID.BLUETOOTH_SCAN];
if (androidOsVer > 11) {
androidPermissions.push(PERMISSIONS.ANDROID.BLUETOOTH_SCAN);
}
const statusesList = await requestMultiple(androidPermissions);
return Object.values(statusesList).some((el) => el === RESULTS.GRANTED);
};
它应该通过请求BLUETOOTH权限隐式包含BLUETOOTH_SCAN和BLUETOOTH_CONNECT。由于蓝牙功能经常需要位置权限,因此请确保也请求它。
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
const checkBluetoothPermissions = () => {
requestMultiple(
Platform.OS === 'android'
? [
PERMISSIONS.ANDROID.BLUETOOTH,
PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION,
]
: [PERMISSIONS.IOS.BLUETOOTH_PERIPHERAL],
).then((results) => {
console.log('permission results', results);
});
};
如果您的应用面向 Android 11(API 级别 30)或更低版本,请在应用的清单文件中声明以下权限 这里必须打开位置才能扫描。
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
如果您的应用面向 Android 12(API 级别 31)或更高版本,请在应用的清单文件中声明以下权限:
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />
neverForLocation 标志是必要的,否则扫描将无法正常工作。
注意:如果您的应用程序面向 Android 12(API 级别 31)或更高版本,并且您正在扫描 BLE 信标设备, 不要添加标记 neverForLocation 并且 必须打开位置才能扫描。
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
您可能使用的是 Android 11(API 级别 30)或更低版本的设备,这些设备未定义 BLUETOOTH_SCAN 和 BLUETOOTH_CONNECT(蓝牙权限包含在位置权限中,您只需请求位置权限即可)