在Android中,申請藍(lán)牙權(quán)限需要申請定位權(quán)限的原因主要涉及到以下幾點(diǎn):
藍(lán)牙掃描能暴露位置信息
當(dāng)應(yīng)用進(jìn)行藍(lán)牙掃描時(shí),特別是低功耗藍(lán)牙(Bluetooth Low Energy, BLE)的掃描,掃描結(jié)果中的藍(lán)牙設(shè)備列表可以反映出用戶的位置信息。例如,在特定的地理位置,某些藍(lán)牙設(shè)備(如商店、家庭、辦公設(shè)備等)會(huì)唯一存在,因此通過藍(lán)牙掃描結(jié)果可以推斷用戶的位置。系統(tǒng)安全策略
從Android 6.0(API 23)開始,Google出于隱私和安全的考慮,要求應(yīng)用在使用藍(lán)牙掃描功能時(shí),需要申請與位置相關(guān)的權(quán)限。具體來說是ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION權(quán)限。這是因?yàn)閽呙杷{(lán)牙設(shè)備可以間接地提供用戶的位置信息,Google希望通過這種權(quán)限申請機(jī)制來保護(hù)用戶的隱私。應(yīng)用權(quán)限管理
通過強(qiáng)制要求藍(lán)牙掃描權(quán)限與位置權(quán)限綁定,Android系統(tǒng)確保應(yīng)用在獲取藍(lán)牙掃描結(jié)果前,明確告知用戶應(yīng)用可能會(huì)訪問他們的位置信息。這使得用戶在授權(quán)時(shí)可以更清楚地了解應(yīng)用的行為。
權(quán)限申請插件:permission_handler: ^10.4.5
藍(lán)牙權(quán)限:
- Permission.bluetooth: 通用藍(lán)牙權(quán)限,可能涵蓋藍(lán)牙的基本操作。
- Permission.bluetoothConnect: 允許應(yīng)用連接到藍(lán)牙設(shè)備。
- Permission.bluetoothScan: 允許應(yīng)用掃描藍(lán)牙設(shè)備。
- Permission.bluetoothAdvertise: 允許應(yīng)用廣播藍(lán)牙信號。
定位權(quán)限:
- Permission.locationWhenInUse: 僅在前臺使用應(yīng)用時(shí)請求位置權(quán)限。
- Permission.locationAlways: 在任何時(shí)候都可以請求位置權(quán)限,不論應(yīng)用是否在前臺。
- Permission.location: 一個(gè)更通用的權(quán)限請求,可能會(huì)請求“僅在使用時(shí)”或“始終”訪問權(quán)限,具體情況取決于實(shí)際應(yīng)用需求。
注意:
在同時(shí)申請這三個(gè)定位權(quán)限時(shí),用戶授權(quán)后,檢測授權(quán)狀態(tài),仍有個(gè)別是拒絕狀態(tài)。但是,再次申請時(shí),是已授權(quán)狀態(tài)。
在Android上,如果你請求了多個(gè)權(quán)限,系統(tǒng)會(huì)按照請求的權(quán)限進(jìn)行授權(quán)。如果應(yīng)用首先請求了Permission.locationWhenInUse,系統(tǒng)可能會(huì)要求用戶授權(quán)該權(quán)限,而Permission.locationAlways可能需要在應(yīng)用已獲得“僅在使用時(shí)”權(quán)限的情況下才能被授予。
所以,才會(huì)出現(xiàn)上述情況。于是,我們只申請 Permission.location 權(quán)限可以一次通過,不影響藍(lán)牙搜索、連接、匹配及通信。
Future _requestPermission() async {
Map<Permission, PermissionStatus> statuses = await [
Permission.bluetoothAdvertise,
Permission.bluetooth,
Permission.bluetoothConnect,
Permission.bluetoothScan,
Permission.location,/// 有個(gè)別定位權(quán)限 在定位權(quán)限授權(quán)時(shí),需要再次請求定位權(quán)限才會(huì)授權(quán)通過,需要再考慮添加
].request();
// Permission.locationAlways,
// Permission.locationWhenInUse, 這兩個(gè)權(quán)限需要Permission.location授權(quán)之后再次申請
bool granted = true;
statuses.forEach((key, value) {
if (value != PermissionStatus.granted) {
granted = false;
}
});
if (granted) {
/// 開始搜索藍(lán)牙
Future.delayed(const Duration(seconds: 2), () {
FlutterWear().scanBluetooth();
});
}else{
BotToast.showText(text: '藍(lán)牙權(quán)限未開啟,請開啟藍(lán)牙權(quán)限');
}
}