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
相关产品推荐
相关产品推荐

