flutter 完美处理iOS Android两端蓝牙权限,解决Android12蓝牙扫描崩溃

前言

最近在做一个配置工具,给Zigbee网关配置网络的工具,其中有一个环节,是用蓝牙配置,过程遇到权限各种坑,故有此篇文章,其中我们使用了第三方库permission_handler,而且permission_handler版本要大于8.2.0才行。

image.png

Android端

第一步:工程名称/android/app/src/main/AndroidManifest.xml,下添加以下权限
image.png

代码如下:

    
    
    
    

    
    

    
    

    
    

在Android12之前的版本,只需要授权位置权限,下面这些都是PermissionStatus.granted

    var isLocationGranted = await Permission.locationWhenInUse.request();
    print('checkBlePermissions, isLocationGranted=$isLocationGranted');


    var isBleGranted = await Permission.bluetooth.request();
    print('checkBlePermissions, isBleGranted=$isBleGranted');

    var isBleScanGranted = await Permission.bluetoothScan.request();
    print('checkBlePermissions, isBleScanGranted=$isBleScanGranted');
    //
    var isBleConnectGranted = await Permission.bluetoothConnect.request();
    print('checkBlePermissions, isBleConnectGranted=$isBleConnectGranted');
    //
    var isBleAdvertiseGranted = await Permission.bluetoothAdvertise.request();
    print('checkBlePermissions, isBleAdvertiseGranted=$isBleAdvertiseGranted');

在>=Android12的版本,除了需要授权“位置权限”,还需要授权“使用附近的设备权限” ,下面这些才会都是PermissionStatus.granted,蓝牙才能正常使用起来

    var isBleScanGranted = await Permission.bluetoothScan.request();
    print('checkBlePermissions, isBleScanGranted=$isBleScanGranted');
    //
    var isBleConnectGranted = await Permission.bluetoothConnect.request();
    print('checkBlePermissions, isBleConnectGranted=$isBleConnectGranted');
    //
    var isBleAdvertiseGranted = await Permission.bluetoothAdvertise.request();
    print('checkBlePermissions, isBleAdvertiseGranted=$isBleAdvertiseGranted');

需要注意的是:在>=Android12的版本, var isBleGranted = await Permission.bluetooth.request();默认为PermissionStatus.denied,应该是因为使用了上面3个权限代替了

第二步,动态申请权限最终代码

其中投机取巧了一下

  Future requestBlePermissions() async {
    location.Location _location = new location.Location();
    bool _serviceEnabled;

    _serviceEnabled = await _location.serviceEnabled();
    if (!_serviceEnabled) {
      _serviceEnabled = await _location.requestService();
      if (!_serviceEnabled) {
        return false;
      }
    }
    var isLocationGranted = await Permission.locationWhenInUse.request();
    print('checkBlePermissions, isLocationGranted=$isLocationGranted');


    var isBleGranted = await Permission.bluetooth.request();
    print('checkBlePermissions, isBleGranted=$isBleGranted');

    var isBleScanGranted = await Permission.bluetoothScan.request();
    print('checkBlePermissions, isBleScanGranted=$isBleScanGranted');
    //
    var isBleConnectGranted = await Permission.bluetoothConnect.request();
    print('checkBlePermissions, isBleConnectGranted=$isBleConnectGranted');
    //
    var isBleAdvertiseGranted = await Permission.bluetoothAdvertise.request();
    print('checkBlePermissions, isBleAdvertiseGranted=$isBleAdvertiseGranted');

    if(Platform.isIOS) {
      return isBleGranted == PermissionStatus.granted;

    }else {
      return isLocationGranted == PermissionStatus.granted &&
           // isBleGranted == PermissionStatus.granted  &&
          isBleScanGranted == PermissionStatus.granted &&
          isBleConnectGranted == PermissionStatus.granted &&
          isBleAdvertiseGranted == PermissionStatus.granted;
    }
  }

iOS端

第一步:info.plist文件申请
image.png
第二步:增加后台模式权限
image.png

如下图所示,选中


image.png
第三步:Podfile文件里面添加代码
image.png

代码如下:

    target.build_configurations.each do |config|
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',
        # dart: [PermissionGroup. location, PermissionGroup. locationAlways, PermissionGroup. locationWhenInUse]
        'PERMISSION_LOCATION=1',
        ## dart: PermissionGroup.bluetooth
        'PERMISSION_BLUETOOTH=1',
      ]
    end
第四步:Podfile文件里面添加代码后,需要重新pod install,安装一下,才会产生效果
第五步:在代码里面调用蓝牙权限
image.png
  Future requestBlePermissions() async {
    location.Location _location = new location.Location();
    bool _serviceEnabled;

    _serviceEnabled = await _location.serviceEnabled();
    if (!_serviceEnabled) {
      _serviceEnabled = await _location.requestService();
      if (!_serviceEnabled) {
        return false;
      }
    }
    var isLocationGranted = await Permission.locationWhenInUse.request();
    print('checkBlePermissions, isLocationGranted=$isLocationGranted');


    var isBleGranted = await Permission.bluetooth.request();
    print('checkBlePermissions, isBleGranted=$isBleGranted');

    var isBleScanGranted = await Permission.bluetoothScan.request();
    print('checkBlePermissions, isBleScanGranted=$isBleScanGranted');
    //
    var isBleConnectGranted = await Permission.bluetoothConnect.request();
    print('checkBlePermissions, isBleConnectGranted=$isBleConnectGranted');
    //
    var isBleAdvertiseGranted = await Permission.bluetoothAdvertise.request();
    print('checkBlePermissions, isBleAdvertiseGranted=$isBleAdvertiseGranted');

    if(Platform.isIOS) {
      return isBleGranted == PermissionStatus.granted;

    }else {
      return isLocationGranted == PermissionStatus.granted &&
           // isBleGranted == PermissionStatus.granted  &&
          isBleScanGranted == PermissionStatus.granted &&
          isBleConnectGranted == PermissionStatus.granted &&
          isBleAdvertiseGranted == PermissionStatus.granted;
    }
  }
最终效果

两端都可以弹框出来申请权限,授受后,可以正常使用起来,还适配了Android12,
如果没有适配Android12的代码,一开始蓝牙扫描,app就会崩溃

结尾

今天flutter 相关技术的分享就到这里喽,小伴们,觉得有点用的话,或者已经看到这里面来的请点赞加关注吧~~ 后续分享更多有关flutter及移动端原生相关文章。如果有疑问的话,请在下方留言~

你可能感兴趣的:(flutter 完美处理iOS Android两端蓝牙权限,解决Android12蓝牙扫描崩溃)