You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

相同代码下蓝牙模块在Android 11正常,Android 11+扫描丢失设备

Android 11+ 蓝牙扫描丢失设备的解决方案

1. 修正权限配置

Android 12(API 31)及以上对蓝牙权限的管控更严格,需调整权限声明并确保运行时权限申请逻辑正确:

调整Manifest权限

为BLUETOOTH_SCAN添加权限标志,明确是否依赖位置信息扫描:

<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
    android:usesPermissionFlags="neverForLocation" />

如果你的BLE设备未广播服务UUID,必须依赖位置信息才能被发现,则移除android:usesPermissionFlags属性,但需确保已正确申请ACCESS_FINE_LOCATION权限。

动态申请运行时权限

启动扫描前,必须主动申请以下权限:

import 'package:permission_handler/permission_handler.dart';

Future<void> requestBlePermissions() async {
  final statuses = await [
    Permission.bluetoothScan,
    Permission.bluetoothConnect,
    Permission.locationWhenInUse,
  ].request();

  if (statuses.values.any((status) => status != PermissionStatus.granted)) {
    // 处理权限拒绝逻辑,比如弹窗提示用户开启权限
  }
}

2. 优化扫描参数

Android 12+对无过滤的蓝牙扫描(空UUID列表)有严格的频率限制,易导致设备丢失,可通过以下方式优化:

指定目标服务UUID扫描

如果你的BLE设备有固定服务UUID,启动扫描时传入该UUID,缩小扫描范围:

// 替换为你的设备实际服务UUID
final targetUuid = Uuid.parse("0000FFE0-0000-1000-8000-00805F9B34FB");
bleScanner.startScan([targetUuid]);

调整扫描模式

使用低延迟扫描模式提升前台扫描效率:

bleScanner.startScan(
  [],
  scanMode: ScanMode.lowLatency,
);

3. 适配Android 12+后台扫描限制

如果需要在后台持续扫描,需:

  • 动态申请ACCESS_BACKGROUND_LOCATION权限
  • 使用前台服务承载扫描逻辑,避免系统限制扫描频率

4. 代码逻辑优化

管理扫描生命周期

页面销毁时停止扫描,避免资源泄漏:

@override
void dispose() {
  bleScanner.stopScan();
  super.dispose();
}

复用扫描器实例

当前代码每次创建页面都初始化新的BleScanner,易导致扫描冲突,建议改为全局单例或通过状态管理工具(如Riverpod)共享实例:

// Riverpod单例示例
final bleScannerProvider = Provider<BleScanner>((ref) {
  return BleScanner(
    ble: FlutterReactiveBle(),
    logMessage: (message) {},
  );
});

内容的提问来源于stack exchange,提问作者Abdullah Saeed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 14:05:58