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

Android中BLUETOOTH_SCAN等蓝牙权限请求失败,求解答

问题原因及解决方案

你的蓝牙权限请求失败、不弹出对话框的核心原因是Android 12+(API 31)对蓝牙权限的特殊要求未满足,具体问题点和修复步骤如下:

1. 权限声明缺失关键属性

Android 12及以上新增的BLUETOOTH_SCAN、BLUETOOTH_CONNECT、BLUETOOTH_ADVERTISE权限需要额外配置:

  • 若BLUETOOTH_SCAN仅用于扫描蓝牙设备不需要获取位置信息,必须添加android:usesPermissionFlags="neverForLocation"属性,否则系统会判定你需定位权限,导致请求异常。
  • 旧版本(API 30及以下)的蓝牙权限需添加android:maxSdkVersion="30"做兼容,避免权限冲突。

修改后的Manifest权限声明:

<!-- Android 12+ 新蓝牙权限 -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
    android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />

<!-- Android 11及以下 旧蓝牙权限(仅兼容用) -->
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />

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

<!-- 若需通过蓝牙扫描获取位置,需添加定位权限 -->
<!-- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> -->

2. TargetSdkVersion 未达标

只有当App的targetSdkVersion设置为31或更高时,Android系统才会识别新的蓝牙权限并允许动态请求。若targetSdkVersion低于31,系统会将新蓝牙权限映射为旧的正常权限(无需动态申请),导致调用requestPermissions时直接返回拒绝,且不弹出请求框。

修改Module级build.gradle(或build.gradle.kts):

android {
    defaultConfig {
        targetSdkVersion 33 // 至少设置为31
        // 其他配置...
    }
}

3. 权限请求逻辑优化

你的代码中方法名requestStoragePermission属于命名错误(实际请求蓝牙权限),虽不影响功能,但建议修正以提升可读性。同时需兼容旧版本设备的权限逻辑:

// 修正方法名
@RequiresApi(api = Build.VERSION_CODES.S)
private void requestBluetoothScanPermission() {
    if (ActivityCompat.shouldShowRequestPermissionRationale(this,
            Manifest.permission.BLUETOOTH_SCAN)) {

        new AlertDialog.Builder(this)
                .setTitle("需要权限")
                .setMessage("此权限用于扫描蓝牙设备")
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        ActivityCompat.requestPermissions(MainActivity.this,
                                new String[]{Manifest.permission.BLUETOOTH_SCAN}, BLUETOOTH_PERMISSION_CODE);
                    }
                })
                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                })
                .create().show();

    } else {
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.BLUETOOTH_SCAN}, BLUETOOTH_PERMISSION_CODE);
    }
}

同时在点击事件中添加版本判断,兼容旧设备:

buttonRequest.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            // Android 12+ 处理新权限
            if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.BLUETOOTH_SCAN) == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(MainActivity.this, "你已拥有此权限!",
                        Toast.LENGTH_SHORT).show();
            } else {
                requestBluetoothScanPermission();
            }
        } else {
            // Android 11及以下 处理旧权限
            if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.BLUETOOTH) == PackageManager.PERMISSION_GRANTED &&
                    ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.BLUETOOTH_ADMIN) == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(MainActivity.this, "你已拥有此权限!",
                        Toast.LENGTH_SHORT).show();
            } else {
                ActivityCompat.requestPermissions(MainActivity.this,
                        new String[]{Manifest.permission.BLUETOOTH, Manifest.permission.BLUETOOTH_ADMIN}, BLUETOOTH_PERMISSION_CODE);
            }
        }
    }
});

完成以上修改后,重新打包安装App,即可正常触发蓝牙权限请求对话框。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 23:11:00