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

Flutter使用permission_handler时附近设备权限不生效如何解决

问题根因

当前配置存在两处核心错误,导致蓝牙相关权限无法正常弹出申请、扫描功能失效:

  • AndroidManifest.xml 未声明蓝牙扫描/连接所需的对应权限,系统根本不会向用户弹出蓝牙相关权限申请弹窗
  • 权限校验逻辑仅申请了定位权限,完全没有覆盖Android 12及以上版本要求的专属蓝牙权限,手动进设置开权限后能用就是这个原因

修复步骤

1. 补全AndroidManifest.xml权限声明

在清单文件的<manifest>节点下,和现有通讯录、存储权限同级的位置,添加以下蓝牙相关权限配置:

<!-- Android 12+ 蓝牙扫描权限 -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />
<!-- Android 12+ 蓝牙连接权限 -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!-- Android 11及以下版本兼容的旧版蓝牙权限 -->
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
<!-- Android 11及以下版本蓝牙扫描所需的精确定位权限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

注意:如果你的应用需要通过蓝牙扫描获取位置信息(如室内定位场景),请删除BLUETOOTH_SCAN权限下的android:usesPermissionFlags="neverForLocation"配置,否则扫描功能会抛出异常。

2. 替换原有权限校验逻辑

不要只校验定位权限,需要根据系统版本区分申请对应权限,替换原有权限判断代码即可:

bool permGranted = true;

// 判断当前设备Android版本
final androidInfo = await DeviceInfoPlugin().androidInfo;
final sdkInt = androidInfo.version.sdkInt;

if (sdkInt >= 31) {
  // Android 12及以上校验蓝牙专属权限
  // 校验扫描权限
  final scanStatus = await Permission.bluetoothScan.status;
  if (scanStatus.isDenied) {
    permGranted = false;
    if (await Permission.bluetoothScan.request().isGranted) {
      permGranted = true;
    }
  }
  // 校验连接权限
  final connectStatus = await Permission.bluetoothConnect.status;
  if (connectStatus.isDenied) {
    permGranted = false;
    if (await Permission.bluetoothConnect.request().isGranted) {
      permGranted = true;
    }
  }
} else {
  // Android 11及以下校验定位权限
  final locationStatus = await Permission.location.status;
  if (locationStatus.isDenied) {
    permGranted = false;
    if (await Permission.location.request().isGranted) {
      permGranted = true;
    }
  }
}

// 处理权限永久拒绝的场景
if (!permGranted) {
  if (sdkInt >=31) {
    if (await Permission.bluetoothScan.isPermanentlyDenied || await Permission.bluetoothConnect.isPermanentlyDenied) {
      // 弹窗提示用户需要到设置页开启权限,之后调用openAppSettings()跳转
    }
  } else {
    if (await Permission.location.isPermanentlyDenied) {
      // 同上,引导用户手动开权限
    }
  }
}

// 所有权限校验通过后再启动蓝牙扫描
if (permGranted) {
  _logMessage('Start ble discovery');
  // 原有蓝牙扫描业务逻辑
}

补充:代码中用到的DeviceInfoPlugin来自device_info_plus插件,用于获取设备系统版本,在pubspec.yaml中添加对应依赖即可使用;openAppSettings()方法是permission_handler自带的方法,可直接调用跳转应用设置页。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 10:48:11