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

Flutter集成华为定位 位置权限被拒时应用崩溃如何修复

问题描述

在华为设备上实现设备位置获取功能时,位置权限授予场景下功能运行正常,但用户拒绝位置权限后应用直接崩溃,相同逻辑使用谷歌定位服务时从未出现该问题。拒绝位置权限时控制台输出了QR扫码插件相关的报错,和位置功能逻辑无直接关联。

现有实现代码
Future<Location?> getAccuratePositionH() async {
  PermissionHandler permissionHandler = PermissionHandler();
  bool status = await permissionHandler.requestLocationPermission();
  if (status) {
    FusedLocationProviderClient locationService = FusedLocationProviderClient();
    Location location = await locationService.getLastLocation();
    return location;
  }
  else {
    return null;
  }
}
报错信息

控制台日志

I/cgr.qrmv.QrMobVisPlugin( 5178): Permissions request denied.
W/cgr.qrmv.QrMobVisPlugin( 5178): Starting QR Mobile Vision failed
W/cgr.qrmv.QrMobVisPlugin( 5178): com.github.rmtmckenzie.qrmobilevision.QrReader$Exception: QR reader failed because noPermissions

异常堆栈

java.lang.RuntimeException: Failure delivering result ResultInfo{who=@android:requestPermissions:, request=1, result=-1, data=Intent { act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }} to activity {com.lea24.partyfinder/com.lea24.partyfinder.MainActivity}: java.lang.NullPointerException: Attempt to read from field 'io.flutter.plugin.common.MethodChannel$Result com.github.rmtmckenzie.qrmobilevision.QrMobileVisionPlugin$ReadingInstance.startResult' on a null object reference
问题根因
  • 核心原因是权限请求码冲突:项目引入的qrmobilevision扫码插件内部默认使用1作为权限请求码,你当前实现的位置权限申请逻辑也默认使用了1作为请求码。华为系统返回权限申请结果时,会把结果派发给所有监听权限回调的插件,扫码插件收到和自己请求码一致的回调后,误以为是自己发起的相机权限申请被拒绝,此时扫码插件并未启动、内部ReadingInstance实例为空,直接读取实例字段就触发了空指针崩溃。
  • 谷歌定位服务未触发该问题,是因为GMS定位服务的权限请求逻辑使用了独立的专属请求码,不会和扫码插件的默认请求码重合,不会触发跨插件的回调误处理。
修复方案
  • 修改位置权限请求的自定义请求码,不要使用默认值1,替换为不与其他插件冲突的数值(比如20240901),从根源避免请求码撞车。
  • 给定位逻辑补充异常捕获,就算定位服务本身调用出错,也不会抛出未捕获异常导致应用崩溃。
  • 可选操作:升级qrmobilevision插件到最新版本,新版本已经对权限回调时实例为空的场景做了空安全防护,就算出现请求码冲突也不会直接崩溃。

修复后的参考代码:

Future<Location?> getAccuratePositionH() async {
  PermissionHandler permissionHandler = PermissionHandler();
  // 指定独立的权限请求码,避开其他插件使用的默认值1
  bool status = await permissionHandler.requestLocationPermission(requestCode: 20240901);
  if (status) {
    try {
      FusedLocationProviderClient locationService = FusedLocationProviderClient();
      Location location = await locationService.getLastLocation();
      return location;
    } catch (e) {
      // 定位获取失败时统一返回null,不向外抛出异常
      return null;
    }
  } else {
    return null;
  }
}

内容的提问来源于stack exchange,提问作者Karol Wiśniewski

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 00:09:13