在Android中,申请蓝牙权限需要申请定位权限的原因主要涉及到以下几点:
-
蓝牙扫描能暴露位置信息
当应用进行蓝牙扫描时,特别是低功耗蓝牙(Bluetooth Low Energy, BLE)的扫描,扫描结果中的蓝牙设备列表可以反映出用户的位置信息。例如,在特定的地理位置,某些蓝牙设备(如商店、家庭、办公设备等)会唯一存在,因此通过蓝牙扫描结果可以推断用户的位置。 -
系统安全策略
从Android 6.0(API 23)开始,Google出于隐私和安全的考虑,要求应用在使用蓝牙扫描功能时,需要申请与位置相关的权限。具体来说是ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION权限。这是因为扫描蓝牙设备可以间接地提供用户的位置信息,Google希望通过这种权限申请机制来保护用户的隐私。 -
应用权限管理
通过强制要求蓝牙扫描权限与位置权限绑定,Android系统确保应用在获取蓝牙扫描结果前,明确告知用户应用可能会访问他们的位置信息。这使得用户在授权时可以更清楚地了解应用的行为。
权限申请插件:permission_handler: ^10.4.5
蓝牙权限:
- Permission.bluetooth: 通用蓝牙权限,可能涵盖蓝牙的基本操作。
- Permission.bluetoothConnect: 允许应用连接到蓝牙设备。
- Permission.bluetoothScan: 允许应用扫描蓝牙设备。
- Permission.bluetoothAdvertise: 允许应用广播蓝牙信号。
定位权限:
- Permission.locationWhenInUse: 仅在前台使用应用时请求位置权限。
- Permission.locationAlways: 在任何时候都可以请求位置权限,不论应用是否在前台。
- Permission.location: 一个更通用的权限请求,可能会请求“仅在使用时”或“始终”访问权限,具体情况取决于实际应用需求。
注意:
在同时申请这三个定位权限时,用户授权后,检测授权状态,仍有个别是拒绝状态。但是,再次申请时,是已授权状态。
在Android上,如果你请求了多个权限,系统会按照请求的权限进行授权。如果应用首先请求了Permission.locationWhenInUse,系统可能会要求用户授权该权限,而Permission.locationAlways可能需要在应用已获得“仅在使用时”权限的情况下才能被授予。
所以,才会出现上述情况。于是,我们只申请 Permission.location 权限可以一次通过,不影响蓝牙搜索、连接、匹配及通信。
Future _requestPermission() async {
Map<Permission, PermissionStatus> statuses = await [
Permission.bluetoothAdvertise,
Permission.bluetooth,
Permission.bluetoothConnect,
Permission.bluetoothScan,
Permission.location,/// 有个别定位权限 在定位权限授权时,需要再次请求定位权限才会授权通过,需要再考虑添加
].request();
// Permission.locationAlways,
// Permission.locationWhenInUse, 这两个权限需要Permission.location授权之后再次申请
bool granted = true;
statuses.forEach((key, value) {
if (value != PermissionStatus.granted) {
granted = false;
}
});
if (granted) {
/// 开始搜索蓝牙
Future.delayed(const Duration(seconds: 2), () {
FlutterWear().scanBluetooth();
});
}else{
BotToast.showText(text: '蓝牙权限未开启,请开启蓝牙权限');
}
}
网友评论