Android 13下Flutter蓝牙扫描权限异常问题求助
Android 13下Flutter蓝牙扫描权限异常解决方案
问题原因
Android 13(API 33)对蓝牙权限体系做了重大调整:
- 废弃了旧的
BLUETOOTH和BLUETOOTH_ADMIN权限,拆分出BLUETOOTH_SCAN、BLUETOOTH_CONNECT、BLUETOOTH_ADVERTISE三个细分权限 - 你使用的
flutter_blue版本(0.8.0)过于老旧,未适配Android 13的新权限模型,即使手动添加权限,插件内部的权限检查逻辑仍会失效 - 你的
AndroidManifest.xml中缺少Android 13要求的BLUETOOTH_SCAN权限
解决步骤
1. 更新AndroidManifest.xml权限配置
替换原有蓝牙权限,添加Android 13所需的新权限,同时兼容旧版本Android:
<!-- Android 13+ 蓝牙扫描/连接权限 --> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <!-- 旧版本Android(API <=30)蓝牙权限 --> <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" /> <!-- 位置权限(仅旧版本Android需要,用于蓝牙扫描) --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" />
注:如果你的扫描需要基于位置信息(比如过滤附近设备),可以移除
android:usesPermissionFlags="neverForLocation",并保留位置权限请求。
2. 调整Flutter端权限请求逻辑
根据Android版本区分权限请求,适配新的权限模型:
import 'package:flutter/services.dart'; import 'package:permission_handler/permission_handler.dart'; @override void initState() { super.initState(); requestBluetoothPermissions(); } Future<void> requestBluetoothPermissions() async { final androidVersion = await _getAndroidSdkVersion(); if (androidVersion >= 33) { // Android 13+ 请求蓝牙扫描和连接权限 final scanStatus = await Permission.bluetoothScan.request(); final connectStatus = await Permission.bluetoothConnect.request(); if (scanStatus.isGranted && connectStatus.isGranted) { scanDevices(); } } else { // 旧版本Android 请求蓝牙和位置权限 final bluetoothStatus = await Permission.bluetooth.request(); final locationStatus = await Permission.location.request(); if (bluetoothStatus.isGranted && locationStatus.isGranted) { scanDevices(); } } } // 获取Android SDK版本号 Future<int> _getAndroidSdkVersion() async { try { return await MethodChannel('flutter.platform').invokeMethod<int>('getAndroidSdkVersion') ?? 0; } on PlatformException { return 0; } } void scanDevices() { try { flutterBlue.startScan(); flutterBlue.scanResults.listen((results) { setState(() { _scannedDevices = results; print("Bluetooth scan results: ${results.toString()}"); }); }); } catch(e) { print("Error during Bluetooth scanning: $e"); } }
3. 替换为维护活跃的蓝牙插件(推荐)
flutter_blue已停止维护,0.8.0版本存在诸多兼容性问题。建议替换为社区维护的flutter_blue_plus,它完全兼容flutter_blue的API,同时适配了Android 13和iOS 16+的新权限:
- 修改
pubspec.yaml依赖:
dependencies: flutter_blue_plus: ^1.13.18 # 使用最新版本
- 代码无需大幅修改,仅需替换导入语句:
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
验证步骤
- 清理项目缓存:执行
flutter clean - 重新构建项目:
flutter run - 启动应用后,确认权限弹窗正常弹出并授予权限
- 检查日志是否再出现权限相关的SecurityException
内容的提问来源于stack exchange,提问作者MohammadBaqer
相关产品推荐
相关产品推荐

