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

Android开发已配置蓝牙权限仍报BLUETOOTH_CONNECT错误崩溃

Android 蓝牙开启报BLUETOOTH_CONNECT权限缺失崩溃修复方案

核心崩溃原因

  • 最直接触发点:权限校验位置错误。Android 12(API 31)及以上版本中,哪怕只是调用BluetoothAdapter.isEnabled()查询蓝牙状态,也要求持有BLUETOOTH_CONNECT权限。你的代码把权限检查写在了if (!adapter.isEnabled())的代码块内部,等于执行isEnabled()时还没做权限校验,直接触发权限拦截崩溃。
  • 未实现运行时权限申请逻辑。BLUETOOTH_CONNECT属于危险运行时权限,仅在AndroidManifest.xml中声明、仅调用checkSelfPermission判断权限状态是不够的,检测到无权限时必须主动调用系统API弹出授权窗口,让用户手动同意。
  • 空指针逻辑漏洞。判断adapter == null时仅弹出了无蓝牙设备的提示,没有加return终止方法执行,在无蓝牙模块的设备上,后续代码调用adapter相关方法会直接触发空指针崩溃。
  • 逻辑笔误。else分支对应蓝牙已经处于开启状态的场景,你打印的日志是"Not enabled",和实际逻辑相反。

分步修复方案

1. 补全运行时权限申请逻辑

首先在代码中添加权限检查、申请的通用逻辑,注意区分系统版本:

// 蓝牙权限请求码
private static final int REQUEST_BT_PERMISSIONS = 1001;
// 蓝牙开启请求码
private static final int REQUEST_ENABLE_BT = 1002;
// 需要申请的蓝牙权限列表,按系统版本适配
private static final String[] BT_PERMISSIONS;
static {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        BT_PERMISSIONS = new String[]{
                Manifest.permission.BLUETOOTH_CONNECT,
                Manifest.permission.BLUETOOTH_SCAN
        };
    } else {
        // Android11及以下不需要新蓝牙权限
        BT_PERMISSIONS = new String[]{};
    }
}

// 检查是否已持有蓝牙权限
private boolean hasBTPermissions() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        for (String permission : BT_PERMISSIONS) {
            if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
    }
    return true;
}

// 发起蓝牙权限申请
private void requestBTPermissions() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        ActivityCompat.requestPermissions(this, BT_PERMISSIONS, REQUEST_BT_PERMISSIONS);
    }
}

// 处理权限申请回调
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == REQUEST_BT_PERMISSIONS) {
        boolean allGranted = true;
        for (int result : grantResults) {
            if (result != PackageManager.PERMISSION_GRANTED) {
                allGranted = false;
                break;
            }
        }
        if (allGranted) {
            // 权限全部通过,再执行蓝牙开启逻辑
            enableBLT();
        } else {
            // 权限被拒绝,可以在这里弹框提示用户需要权限才能使用蓝牙功能
            Log.d("blt-", "蓝牙权限被用户拒绝");
        }
    }
}

2. 修正enableBLT方法的执行顺序

把权限检查、空指针判断移到方法最前面,修正后代码如下:

private void enableBLT(){
    // 先检查权限,无权限直接发起申请,终止后续执行
    if (!hasBTPermissions()) {
        requestBTPermissions();
        return;
    }
    BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
    // 无蓝牙模块时弹提示后直接return,避免空指针
    if (adapter == null) {
        dialogNoBlt();
        return;
    }
    // 此时已持有权限,调用isEnabled不会触发崩溃
    if (!adapter.isEnabled()) {
        Intent enableBltIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableBltIntent, REQUEST_ENABLE_BT);
    } else {
        // 修正原来写反的日志
        Log.d("blt-", "蓝牙已处于开启状态");
    }
}

3. 优化Manifest权限配置,做版本兼容

给旧版蓝牙权限加上版本上限,避免高版本系统出现冗余权限提示,扫描不需要位置时加标记减少权限申请成本:

<!-- Android11及以下版本需要的旧版蓝牙权限 -->
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
<!-- Android12及以上版本需要的新版蓝牙权限 -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!-- 如果蓝牙扫描不需要获取位置结果,加neverForLocation标记,不需要额外申请位置权限 -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />

额外注意事项

  • 所有蓝牙相关API调用(包括查询状态、开启/关闭、扫描、配对、连接),在Android12+上都要先确认持有BLUETOOTH_CONNECT权限,不要抱有“只是查个状态不需要权限”的侥幸。
  • 如果用户拒绝权限并勾选了“不再询问”,需要弹框引导用户跳转到应用设置页手动开启权限,否则功能始终无法使用。
  • 如果你使用的是较新版本的AndroidX,建议废弃startActivityForResult和onRequestPermissionsResult,改用ActivityResultContracts处理权限申请、蓝牙开启的回调,代码更简洁也更符合官方开发规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 13:06:31