Search code examples
androidandroid-permissionsandroid-bluetooth

How to re-request BLUETOOTH_SCAN and BLUETOOTH_CONNECT permissions for Android 12 after a user denial?


I have a problem re-requesting the permissions required to scan and connect to bluetooth devices when targeting SDK 31 (Android 12).

I call this method inside my main activity's onCreate():

public void requestBluetoothPermissions() {

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {

        if ((this.checkSelfPermission(Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED)
            || (this.checkSelfPermission(Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED)) {

            Log.w(getClass().getName(), "requestBluetoothPermissions() BLUETOOTH_SCAN AND BLUETOOTH_CONNECT permissions needed => requesting them...");

            this.requestPermissions(new String[]{
                    Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT
            }, MyActivity.REQUEST_BLUETOOTH_PERMISSIONS);

        }
    }
}

It's works fine the first time it is called i.e. an Android pop-up is displayed to the user, prompting him to grant the permissions.

But if he refuses to grant the permissions, next time onCreate() is called, the pop-up will not be displayed, which means the user remains unable to grant the permissions.

Any idea why and how to fix this ?


Solution

  • It appears Android 12 blocks requesting the same permission after user denied it once only.

    Therefore, I ended up using ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.BLUETOOTH_SCAN) to determine wether the permission can be requested or not, in which case a snackbar message is displayed explaining why is the permission needed, with a button opening the app settings where permission can be granted.

    Here is a sample of the code:

    public void requestBluetoothPermissions() {
    
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
    
            if ((this.checkSelfPermission(Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED)
                || (this.checkSelfPermission(Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED)) {
    
                if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
                        Manifest.permission.BLUETOOTH_SCAN)) {
    
                     // display permission rationale in snackbar message
                } else {
                    Log.w(getClass().getName(), "requestBluetoothPermissions() BLUETOOTH_SCAN AND BLUETOOTH_CONNECT permissions needed => requesting them...");
    
                    this.requestPermissions(new String[]{
                        Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT
                        }, MyActivity.REQUEST_BLUETOOTH_PERMISSIONS);
                }
            }
        }
    }