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

已声明BLUETOOTH_CONNECT与BLUETOOTH_SCAN仍提示权限缺失求助

Android BLUETOOTH_CONNECT和BLUETOOTH_SCAN权限缺失问题排查

我遇到了BLUETOOTH_CONNECT和BLUETOOTH_SCAN权限的问题,但我已经在清单文件中进行了声明。

以下是完整的AndroidManifest.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" >
    <!-- Request legacy Bluetooth permissions on older devices. -->
    <uses-permission android:name="android.permission.BLUETOOTH"
                     android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
                     android:maxSdkVersion="30" />
    <!-- Needed only if your app looks for Bluetooth devices.
         If your app doesn't use Bluetooth scan results to derive physical
         location information, you can strongly assert that your app
         doesn't derive physical location. -->
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
    <!-- Needed only if your app makes the device discoverable to Bluetooth
         devices. -->
    <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
    <!-- Needed only if your app communicates with already-paired Bluetooth
         devices. -->
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    <!-- Needed only if your app uses Bluetooth scan results to derive physical location. -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <!-- Include "neverForLocation" only if you can strongly assert that
             your app never derives physical location from Bluetooth scan results. -->
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN"
                     android:usesPermissionFlags="neverForLocation" />
    <!-- Not needed if you can strongly assert that your app never derives
         physical location from Bluetooth scan results and doesn't need location
         access for any other purpose. -->
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
    <uses-feature android:name="android.hardware.bluetooth" android:required="true"/>
    <uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
</manifest>

问题原因分析

  1. 重复权限声明冲突
    你重复声明了BLUETOOTH_SCAN和BLUETOOTH_ADMIN:

    • BLUETOOTH_SCAN一次无flag,一次带neverForLocation,系统无法识别正确配置;
    • BLUETOOTH_ADMIN第二次声明未加maxSdkVersion="30",在高版本设备上造成冗余。
  2. 未处理动态权限申请
    Android 12(API 31)及以上版本中,BLUETOOTH_SCAN、BLUETOOTH_CONNECT属于危险权限,仅在Manifest声明完全不够,必须在运行时主动请求用户授权。

  3. 位置权限逻辑矛盾
    你同时声明了ACCESS_FINE_LOCATION和BLUETOOTH_SCAN的neverForLocation flag,二者互斥:

    • 若App不需要通过蓝牙扫描获取位置,就不需要位置权限,只保留带neverForLocation的BLUETOOTH_SCAN;
    • 若需要位置信息,就去掉neverForLocation flag,并确保动态申请位置权限。

修正后的Manifest示例

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" >

    <!-- 适配API 30及以下的旧蓝牙权限 -->
    <uses-permission android:name="android.permission.BLUETOOTH"
                     android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
                     android:maxSdkVersion="30" />

    <!-- Android 12+ 蓝牙权限 -->
    <!-- 不需要蓝牙定位的情况,添加neverForLocation flag -->
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN"
                     android:usesPermissionFlags="neverForLocation" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

    <!-- 仅当需要通过蓝牙获取位置时,才启用以下权限 -->
    <!-- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> -->
    <!-- <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"
                       android:maxSdkVersion="32" /> -->

    <uses-feature android:name="android.hardware.bluetooth" android:required="true"/>
    <uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
</manifest>

运行时权限申请代码示例(Kotlin)

private fun requestBluetoothPermissions() {
    val permissionsToRequest = mutableListOf<String>()
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        // 检查BLUETOOTH_SCAN权限
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {
            permissionsToRequest.add(Manifest.permission.BLUETOOTH_SCAN)
        }
        // 检查BLUETOOTH_CONNECT权限
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
            permissionsToRequest.add(Manifest.permission.BLUETOOTH_CONNECT)
        }
        // 如果需要位置权限,取消注释下面代码
        // if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        //     permissionsToRequest.add(Manifest.permission.ACCESS_FINE_LOCATION)
        // }
    }

    if (permissionsToRequest.isNotEmpty()) {
        ActivityCompat.requestPermissions(this, permissionsToRequest.toTypedArray(), 1001)
    }
}

// 权限申请结果回调
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    if (requestCode == 1001) {
        val allGranted = grantResults.all { it == PackageManager.PERMISSION_GRANTED }
        if (allGranted) {
            // 权限全部授予,执行蓝牙相关操作
        } else {
            // 权限被拒绝,提示用户前往设置开启
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 01:10:32