chipweinberger/flutter_blue_plus

[Help]: ANDROID: scan permission popup appears twice

Closed this issue · 4 comments

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

thats not a pairing request. It's a permissions popup.

So why the example show permission popup twice?What can i do for it?

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.

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++;
}