美文网首页FlutterFlutter学习Flutter
flutter 完美处理iOS Android两端蓝牙权限,解决

flutter 完美处理iOS Android两端蓝牙权限,解决

作者: 微风_10a5 | 来源:发表于2022-11-23 18:45 被阅读0次

    前言

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

    image.png

    Android端

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

    代码如下:

        <uses-permission android:name="android.permission.INTERNET" />
        <!-- Request legacy Bluetooth permissions on older devices. -->
        <uses-permission android:name="android.permission.BLUETOOTH"
            android:maxSdkVersion="30" />
        <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
            android:maxSdkVersion="30" />
    
        <!-- Needed only if your app looks for Bluetooth devices.
             You must add an attribute to this permission, or declare the
             ACCESS_FINE_LOCATION permission, depending on the results when you
             check location usage in your app. -->
        <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
    
        <!-- Needed only if your app makes the device discoverable to Bluetooth
             devices. -->
        <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
    
        <!-- Needed only if your app communicates with already-paired Bluetooth
             devices. -->
        <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    

    在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<bool> 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<bool> 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两端蓝牙权限,解决

        本文链接:https://www.haomeiwen.com/subject/ivqaxdtx.html