Flutter Beacon检测代码报错求助:Android模拟器无法识别Beacon
Flutter iBeacon检测在Android模拟器上失败的解决方法
问题背景
作为Flutter新手,编写了检测4个Beacon的代码,已在AndroidManifest.xml中添加相关权限,但两款Android模拟器运行均报错,无法检测Beacon。代码如下:
import 'dart:async'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_beacon/flutter_beacon.dart'; import 'package:permission_handler/permission_handler.dart'; void main() => runApp(MyApp()); class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { StreamSubscription<RangingResult>? _streamRanging; final _regionBeacons = <Region, List<Beacon>>{}; final _beacons = <Beacon>[]; @override void initState() { super.initState(); requestPermission(); } void requestPermission() async { if (await Permission.location.request().isGranted) { initBeacon(); } else { showDialog( context: context, builder: (_) => AlertDialog( title: Text('Location Permission Required'), content: Text( 'Please grant location permission to enable beacon scanning.'), actions: [ TextButton( child: Text('OK'), onPressed: () { Navigator.pop(context); openAppSettings(); }, ), ], ), ); } } initBeacon() async { try { await flutterBeacon.initializeScanning; print('Beacon scanner initialized'); } on PlatformException catch (e) { print(e); } final regions = <Region>[]; if (Platform.isIOS) { regions.add(Region( identifier: 'MyBeacon', proximityUUID: 'a86be991-76c7-4fc4-892a-551acf07c77c', major: null, minor: null)); } else { regions.add(Region(identifier: 'com.beacon')); } flutterBeacon.monitoring(regions).listen((MonitoringResult result) {}); _streamRanging = flutterBeacon.ranging(regions).listen((RangingResult result) { if (result != null && result.beacons.isNotEmpty) { List<Beacon> beacons = result.beacons; for (var beacon in beacons) { String uuid = beacon.proximityUUID; int major = beacon.major; int minor = beacon.minor; int rssi = beacon.rssi; print( 'Beacon detected: UUID=$uuid, major=$major, minor=$minor, rssi=$rssi'); } } }); } @override void dispose() { super.dispose(); _streamRanging?.cancel(); flutterBeacon.close; } @override Widget build(BuildContext context) { return MaterialApp( title: 'iBeacon Detection', home: Scaffold( appBar: AppBar( title: Text('iBeacon Detection'), ), body: Center( child: Text('Searching for iBeacons...'), ), ), ); } }
解决方案
1. 放弃模拟器,使用物理Android设备测试
绝大多数Android模拟器不支持BLE(蓝牙低功耗)功能,这是无法检测Beacon的核心原因。即使部分模拟器声称支持,其BLE模拟稳定性极差,无法替代真实设备。直接使用带BLE模块的物理Android设备测试是最可靠的方案。
2. 完善Android权限配置
确保AndroidManifest.xml中添加所有必要权限:
<!-- 基础位置权限 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- BLE基础权限 --> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <!-- Android 12+ 专属蓝牙权限 --> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <!-- 声明应用依赖BLE硬件 --> <uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />
3. 修正Android端Region配置
原代码中Android的Region未指定Proximity UUID,导致无法识别目标Beacon区域,修改为与iOS一致的配置:
// 替换原Android Region代码 regions.add(Region( identifier: 'MyBeacon', proximityUUID: 'a86be991-76c7-4fc4-892a-551acf07c77c', major: null, minor: null ));
4. 补充Android 12+权限检查
Android 12及以上需要单独申请蓝牙扫描权限,更新requestPermission方法:
void requestPermission() async { Map<Permission, PermissionStatus> statuses = await [ Permission.location, Permission.bluetoothScan, Permission.bluetoothConnect, ].request(); if (statuses[Permission.location]!.isGranted && statuses[Permission.bluetoothScan]!.isGranted) { initBeacon(); } else { showDialog( context: context, builder: (_) => AlertDialog( title: Text('权限要求'), content: Text('需要位置和蓝牙扫描权限才能检测Beacon,请在设置中开启。'), actions: [ TextButton( child: Text('确定'), onPressed: () { Navigator.pop(context); openAppSettings(); }, ), ], ), ); } }
5. 修复资源释放代码
原代码中flutterBeacon.close是属性访问,需改为调用方法:
@override void dispose() { super.dispose(); _streamRanging?.cancel(); // 修正:调用close方法释放资源 flutterBeacon.close(); }
6. 测试前准备
- 确保物理设备的蓝牙、位置服务已开启。
- 确认Beacon设备处于正常广播状态,且UUID、Major/Minor值与代码配置一致。
内容的提问来源于stack exchange,提问作者alaa alshiekheh
相关产品推荐
相关产品推荐

