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

Flutter开发iBeacon检测应用运行时崩溃,求助解决

解决华为P30 Pro上Flutter iBeacon扫描终止问题

根据你提供的报错信息和代码,问题主要集中在权限不足、华为EMUI系统权限管控限制以及代码逻辑细节问题,以下是针对性的解决步骤:


1. 补充AndroidManifest.xml权限配置

华为EMUI对蓝牙和位置权限管控严格,除现有权限外,需在android/app/src/main/AndroidManifest.xml中补充以下权限:

<!-- 蓝牙扫描/连接权限(Android 12+) -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!-- 高精度位置权限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- Android 10+ 后台扫描必需的后台位置权限 -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<!-- 前台服务权限(后台扫描必须) -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />

<!-- 声明蓝牙LE功能依赖 -->
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />

2. 修改权限申请逻辑

原代码仅申请了位置权限,需补充蓝牙扫描和后台位置权限的申请,更新requestPermission方法:

void requestPermission() async {
  // 批量申请所需权限
  Map<Permission, PermissionStatus> statuses = await [
    Permission.location,
    Permission.locationAlways, // 后台位置权限
    Permission.bluetoothScan,
    Permission.bluetoothConnect,
  ].request();

  // 检查核心权限是否全部授予
  if (statuses[Permission.location]!.isGranted &&
      statuses[Permission.bluetoothScan]!.isGranted) {
    initBeacon();
  } else {
    showDialog(
      context: context,
      builder: (_) => AlertDialog(
        title: const Text('权限申请失败'),
        content: const Text('请授予位置和蓝牙权限,否则无法扫描iBeacon'),
        actions: [
          TextButton(
            child: const Text('去设置'),
            onPressed: () {
              Navigator.pop(context);
              openAppSettings();
            },
          ),
        ],
      ),
    );
  }
}

3. 修复代码中的逻辑问题

(1)修正dispose方法的调用错误

原代码中flutterBeacon.close是方法,需添加括号执行:

@override
void dispose() {
  super.dispose();
  _streamRanging?.cancel();
  flutterBeacon.close(); // 补充括号
}

(2)优化Beacon扫描结果更新逻辑

原代码在循环内多次调用setState导致UI频繁刷新,将状态更新移到循环外:

_streamRanging = flutterBeacon.ranging(regions).listen((RangingResult result) {
  if (result != null && result.beacons.isNotEmpty) {
    // 过滤目标UUID的Beacon
    List<Beacon> filteredBeacons = result.beacons.where((beacon) => 
      beacon.proximityUUID == 'a86be991-76c7-4fc4-892a-551acf07c77c'
    ).toList();
    
    setState(() {
      _beacons.clear();
      _beacons.addAll(filteredBeacons);
    });
  } else {
    setState(() {
      _beacons.clear();
    });
  }
});

4. 华为设备特殊设置调整

华为EMUI的省电策略会限制后台扫描能力,需手动开启以下设置:

  • 进入设置 > 应用和服务 > 权限管理 > 你的应用,将位置信息设为始终允许,确保蓝牙权限开启。
  • 进入设置 > 电池 > 应用启动管理,找到你的应用,关闭自动管理,手动开启允许自启动、允许关联启动、允许后台活动。
  • 确保手机位置服务已开启,并设置为高精度模式(设置 > 位置信息 > 定位模式)。

5. 完善初始化流程

在initBeacon中添加蓝牙状态检查,避免初始化失败:

initBeacon() async {
  try {
    // 先检查蓝牙是否开启
    bool isBluetoothEnabled = await flutterBeacon.checkAvailability;
    if (!isBluetoothEnabled) {
      print('蓝牙未开启,请先打开蓝牙');
      return;
    }
    
    await flutterBeacon.initializeScanning;
    print('Beacon scanner initialized');
  } on PlatformException catch (e) {
    print('初始化失败:${e.message}');
  }
  // 后续的region配置和ranging逻辑保持不变
}

按照以上步骤修改后重新运行应用,即可解决扫描终止的问题。

内容的提问来源于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 00:03:10