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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 09:37:28