使用Flutter_blue时蓝牙权限被拒导致应用崩溃该如何解决
解决Flutter_blue蓝牙权限拒绝后应用崩溃的方案
崩溃根本原因是你在权限状态未明确前就调用了FlutterBlue相关API,权限被拒绝后无权限触发原生侧报错崩溃,按照以下步骤处理即可解决:
前置配置
- 先引入依赖包:
permission_handler(权限处理)、device_info_plus(适配安卓不同版本权限),同时在原生侧补全权限声明:安卓端
AndroidManifest.xml添加权限:<!-- 安卓12以下蓝牙权限 --> <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" /> <!-- 安卓12及以上蓝牙权限 --> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <uses-feature android:name="android.hardware.bluetooth_le" android:required="false" />iOS端
Info.plist添加权限说明:<key>NSBluetoothAlwaysUsageDescription</key> <string>需要使用蓝牙来连接设备</string> <key>NSBluetoothPeripheralUsageDescription</key> <string>需要使用蓝牙来连接设备</string>
核心逻辑处理
- 应用启动后禁止先初始化FlutterBlue实例,先走权限校验逻辑,权限完全通过后再执行蓝牙相关操作:
import 'package:flutter/material.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:flutter_blue/flutter_blue.dart'; import 'package:device_info_plus/device_info_plus.dart'; Future<void> checkBluetoothPermission(BuildContext context) async { Map<Permission, PermissionStatus> statuses; // 适配不同安卓版本的权限申请 if (Theme.of(context).platform == TargetPlatform.android) { final androidInfo = await DeviceInfoPlugin().androidInfo; if (androidInfo.version.sdkInt >= 31) { statuses = await [ Permission.bluetooth, Permission.bluetoothScan, Permission.bluetoothConnect, ].request(); } else { statuses = await [ Permission.bluetooth, Permission.location, ].request(); } } else { // iOS端权限申请 statuses = await [Permission.bluetoothAlways].request(); } // 校验所有需要的权限是否都已授予 bool isPermissionGranted = statuses.values.every((status) => status.isGranted); if (isPermissionGranted) { // 权限通过后再初始化FlutterBlue,执行业务逻辑 FlutterBlue.instance.state.listen((state) { // 正常蓝牙扫描、连接等逻辑 }); } else { // 权限未通过,直接跳转提示页,不执行任何蓝牙相关API Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => const BluetoothPermissionTipPage()), ); } }
注意事项
- 所有
FlutterBlue相关API调用前都要加权限状态校验,禁止在权限未确定的场景下调用任何蓝牙方法 - 如果用户勾选了「永久拒绝」权限,再次调用
request()不会弹出系统授权弹窗,可在提示页增加引导用户跳转到系统设置页开启权限的逻辑
内容的提问来源于stack exchange,提问作者helloitsme3
相关产品推荐
相关产品推荐

