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

Android 12蓝牙权限自动被拒求助:提示一次仅能请求一组权限

Android 12蓝牙权限自动拒绝及Can request only one set of permissions at a time警告问题排查

适配Android 12蓝牙权限时,遇到权限被自动拒绝,且收到警告提示Can request only one set of permissions at a time,蓝牙功能对应用至关重要,刚接触Android 12蓝牙权限,不清楚哪里操作有误。以下是权限请求代码:

public void requestBluetooth() {
    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.BLUETOOTH_CONNECT)
            != PackageManager.PERMISSION_GRANTED) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            beforeBluetoothGranted = ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.BLUETOOTH_CONNECT);

            if (beforeBluetoothGranted) {
                new AlertDialog.Builder(MainActivity.this)
                        .setTitle("Warning")
                        .setMessage("App must grant Bluetooth permissions in order for BiSym to operate!")
                        .setCancelable(false)
                        .setNeutralButton("OK", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                ActivityCompat.requestPermissions(MainActivity.this,
                                        new String[]{Manifest.permission.BLUETOOTH_CONNECT}, MY_PERMISSIONS_REQUEST_BLUETOOTH);
                            }
                        })
                        .show();

            } else {
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.BLUETOOTH_CONNECT},
                        MY_PERMISSIONS_REQUEST_BLUETOOTH);
            }
        }
    } else {
        requestBluetoothScan();
    }
}

public void requestBluetoothScan() {
    //does the same as requestBluetooth for the scan permissions
}

public void onRequestPermissionsResult(int requestCode,
                                       String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {
        ...
        case MY_PERMISSIONS_REQUEST_BLUETOOTH:
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                        requestBluetoothScan();
                } else {
                    afterBluetoothGranted = ActivityCompat.shouldShowRequestPermissionRationale(this,
                            Manifest.permission.BLUETOOTH_CONNECT);
                }
                if (!(beforeBluetoothGranted || afterBluetoothGranted)) {
                    gotoSettings();
                }
            }
        break;
        case MY_PERMISSIONS_REQUEST_BLUETOOTH_SCAN:
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    if (!mApp.trialShown) {
                        openWhatsNewDialog();
                    }
                } else {
                    afterBluetoothGranted = ActivityCompat.shouldShowRequestPermissionRationale(this,
                            Manifest.permission.BLUETOOTH_SCAN);
                }
                if (!(beforeBluetoothScanGranted || afterBluetoothScanGranted)) {
                    gotoSettings();
                }

            }
            break;
    }
}

问题原因

  • 连续触发权限请求冲突:代码在requestBluetooth中,一旦BLUETOOTH_CONNECT权限已授予,就立刻调用requestBluetoothScan发起新的权限请求;同时在onRequestPermissionsResult的MY_PERMISSIONS_REQUEST_BLUETOOTH分支里,权限授予后也会马上调用requestBluetoothScan。而Android系统不允许同时发起多组权限请求,前一个请求的弹窗还未完全处理完毕,就触发下一个请求,会导致后一个请求被自动拒绝,并抛出Can request only one set of permissions at a time警告。
  • 同组权限分开请求不合理:Android 12中,BLUETOOTH_CONNECT和BLUETOOTH_SCAN属于同一权限组(蓝牙组),分开请求不仅会触发系统限制,还会增加用户操作步骤,影响体验。

解决方案

1. 合并同组权限请求(推荐)

直接一次性请求BLUETOOTH_CONNECT和BLUETOOTH_SCAN两个权限,避免连续请求冲突:

public void requestBluetoothPermissions() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        String[] bluetoothPermissions = {
            Manifest.permission.BLUETOOTH_CONNECT,
            Manifest.permission.BLUETOOTH_SCAN
        };
        boolean connectGranted = ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED;
        boolean scanGranted = ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) == PackageManager.PERMISSION_GRANTED;

        if (!connectGranted || !scanGranted) {
            boolean shouldShowRationale = ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.BLUETOOTH_CONNECT)
                    || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.BLUETOOTH_SCAN);

            if (shouldShowRationale) {
                new AlertDialog.Builder(MainActivity.this)
                        .setTitle("警告")
                        .setMessage("应用必须获取蓝牙权限才能正常运行BiSym功能!")
                        .setCancelable(false)
                        .setNeutralButton("确定", (dialog, which) -> {
                            ActivityCompat.requestPermissions(MainActivity.this, bluetoothPermissions, MY_PERMISSIONS_REQUEST_BLUETOOTH);
                        })
                        .show();
            } else {
                ActivityCompat.requestPermissions(this, bluetoothPermissions, MY_PERMISSIONS_REQUEST_BLUETOOTH);
            }
        } else {
            // 权限已全部授予,执行后续逻辑
            if (!mApp.trialShown) {
                openWhatsNewDialog();
            }
        }
    }
}

2. 修改权限回调逻辑

合并请求后,只需处理一个requestCode,在回调中检查两个权限的授予状态:

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_BLUETOOTH:
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                boolean connectGranted = false;
                boolean scanGranted = false;
                for (int i = 0; i < permissions.length; i++) {
                    if (Manifest.permission.BLUETOOTH_CONNECT.equals(permissions[i])) {
                        connectGranted = grantResults[i] == PackageManager.PERMISSION_GRANTED;
                    } else if (Manifest.permission.BLUETOOTH_SCAN.equals(permissions[i])) {
                        scanGranted = grantResults[i] == PackageManager.PERMISSION_GRANTED;
                    }
                }

                if (connectGranted && scanGranted) {
                    // 所有蓝牙权限已授予
                    if (!mApp.trialShown) {
                        openWhatsNewDialog();
                    }
                } else {
                    // 检查是否需要引导到设置页
                    boolean showRationaleConnect = ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.BLUETOOTH_CONNECT);
                    boolean showRationaleScan = ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.BLUETOOTH_SCAN);
                    if (!showRationaleConnect && !showRationaleScan) {
                        gotoSettings();
                    }
                }
            }
            break;
        // 其他requestCode处理逻辑...
    }
}

3. 若坚持分开请求(不推荐)

必须确保前一个权限请求的回调完全完成后,再发起下一个请求,比如在onRequestPermissionsResult中延迟调用:

// 在MY_PERMISSIONS_REQUEST_BLUETOOTH分支中
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    new Handler(Looper.getMainLooper()).postDelayed(() -> requestBluetoothScan(), 500);
}

但这种方式可能仍存在系统限制风险,且用户体验较差,优先推荐合并请求方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 14:30:58