[Help]: ANDROID: scan permission popup appears twice
Closed this issue · 4 comments
hiperioncn commented
Requirements
- I've looked at the README 'Common Problems' section
Have you checked this problem on the example app?
No
FlutterBluePlus Version
1.32.11
Flutter Version
3.22.2
What OS?
Android
OS Version
android14
Bluetooth Module
esp32
What is your problem?
When I run the example app, click "scan" button, show ble request popup twice.
More info from #966
chipweinberger commented
thats not a pairing request. It's a permissions popup.
hiperioncn commented
So why the example show permission popup twice?What can i do for it?
chipweinberger commented
we ask for 2 different permissions when scanning.BLUETOOTH_SCAN & BLUETOOTH_CONNECT
if (Build.VERSION.SDK_INT >= 31) { // Android 12 (October 2021)
permissions.add(Manifest.permission.BLUETOOTH_SCAN);
if (androidUsesFineLocation) {
permissions.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
// it is unclear why this is needed, but some phones throw a
// SecurityException AdapterService getRemoteName, without it
permissions.add(Manifest.permission.BLUETOOTH_CONNECT);
}
but we only ask 1 at a time.
private void askPermission(List<String> permissionsNeeded, OperationOnPermission operation)
{
// finished asking for permission? call callback
if (permissionsNeeded.isEmpty()) {
operation.op(true, null);
return;
}
String nextPermission = permissionsNeeded.remove(0);
operationsOnPermission.put(lastEventId, (granted, perm) -> {
operationsOnPermission.remove(lastEventId);
if (!granted) {
operation.op(false, perm);
return;
}
// recursively ask for next permission
askPermission(permissionsNeeded, operation);
});
ActivityCompat.requestPermissions(
activityBinding.getActivity(),
new String[]{nextPermission},
lastEventId);
lastEventId++;
}
you'll need to submit a PR to fix it, by asking both permissions at the same time.
chipweinberger commented
you can try this code. You'll need to change the FBP code.
@Override
public boolean onRequestPermissionsResult(int requestCode,
String[] permissions,
int[] grantResults) {
OperationOnPermission operation = operationsOnPermission.get(requestCode);
if (operation != null && grantResults.length > 0) {
for (int i = 0; i < permissions.length; i++) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
// If any permission is denied, call the operation with false
operation.op(false, permissions[i]);
return true;
}
}
// All permissions are granted
operation.op(true, null);
return true;
} else {
return false;
}
}
private void ensurePermissions(List<String> permissions, OperationOnPermission operation) {
// only request permission we don't already have
List<String> permissionsNeeded = new ArrayList<>();
for (String permission : permissions) {
if (permission != null && ContextCompat.checkSelfPermission(context, permission)
!= PackageManager.PERMISSION_GRANTED) {
permissionsNeeded.add(permission);
}
}
// no work to do?
if (permissionsNeeded.isEmpty()) {
operation.op(true, null);
return;
}
// Request all permissions at once
askPermission(permissionsNeeded, operation);
}
private void askPermission(List<String> permissionsNeeded, OperationOnPermission operation) {
// finished asking for permission? call callback
if (permissionsNeeded.isEmpty()) {
operation.op(true, null);
return;
}
// Store the operation for later use in onRequestPermissionsResult
operationsOnPermission.put(lastEventId, operation);
// Request all needed permissions at once
ActivityCompat.requestPermissions(
activityBinding.getActivity(),
permissionsNeeded.toArray(new String[0]),
lastEventId);
lastEventId++;
}