Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ActivityResultLauncher with RequestMultiplePermissions contract doesn't show permissions UI on launch

I am trying to request permissions using ActivityResultLauncher with ActivityResultsContract.RequestMultiplePermissions.

public class MainActivity extends AppCompatActivity {

    final String[] PERMISSIONS = {
            Manifest.permission.FOREGROUND_SERVICE,
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_BACKGROUND_LOCATION,
            Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
    };

    private ActivityResultContracts.RequestMultiplePermissions multiplePermissionsContract;
    private ActivityResultLauncher<String[]> multiplePermissionLauncher;    

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        multiplePermissionsContract = new ActivityResultContracts.RequestMultiplePermissions();
        multiplePermissionLauncher = registerForActivityResult(multiplePermissionsContract, isGranted -> {
            Log.d("PERMISSIONS", "Launcher result: " + isGranted.toString());
            if (isGranted.containsValue(false)) {
                Log.d("PERMISSIONS", "At least one of the permissions was not granted, launching again...");
                multiplePermissionLauncher.launch(PERMISSIONS);
            }
        });

        askPermissions(multiplePermissionLauncher);
    }

    private void askPermissions(ActivityResultLauncher<String[]> multiplePermissionLauncher) {
        if (!hasPermissions(PERMISSIONS)) {
            Log.d("PERMISSIONS", "Launching multiple contract permission launcher for ALL required permissions");
            multiplePermissionLauncher.launch(PERMISSIONS);
        } else {
            Log.d("PERMISSIONS", "All permissions are already granted");
        }
    }

    private boolean hasPermissions(String[] permissions) {
        if (permissions != null) {
            for (String permission : permissions) {
                if (ActivityCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
                    Log.d("PERMISSIONS", "Permission is not granted: " + permission);
                    return false;
                }
                Log.d("PERMISSIONS", "Permission already granted: " + permission);
            }
            return true;
        }
        return false;
    }
}

I also included the necessary dependencies in build.gradle:

implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.activity:activity:1.2.0'
implementation 'androidx.fragment:fragment:1.3.0'

When I launch the app on the device, the UI for allowing permissions is not shown. I cleared cache and removed the app from the device prior to launching. The logs:

15:02:43.584 D/PERMISSIONS: Permission already granted: android.permission.FOREGROUND_SERVICE
15:02:43.586 D/PERMISSIONS: Permission is not granted: android.permission.ACCESS_FINE_LOCATION
15:02:43.586 D/PERMISSIONS: Launching multiple contract permission launcher for ALL required permissions
15:02:43.753 D/PERMISSIONS: Launcher result: {android.permission.ACCESS_FINE_LOCATION=false, android.permission.ACCESS_BACKGROUND_LOCATION=false}
15:02:43.753 D/PERMISSIONS: At least one of the permissions was not granted, launching again...
15:02:43.857 D/PERMISSIONS: Launcher result: {android.permission.ACCESS_FINE_LOCATION=false, android.permission.ACCESS_BACKGROUND_LOCATION=false}
15:02:43.857 D/PERMISSIONS: At least one of the permissions was not granted, launching again...
15:02:43.939 D/PERMISSIONS: Launcher result: {android.permission.ACCESS_FINE_LOCATION=false, android.permission.ACCESS_BACKGROUND_LOCATION=false}

The last two lines repeat infinitely until I close the app. However, when I use ActivityResultContracts.RequestPermission and request each permission separately, it works as expected, showing all the necessary UI.

Why ActivityResultsContract.RequestMultiplePermissions is not working in my case?

like image 357
Vladimir Kattsyn Avatar asked Mar 04 '21 12:03

Vladimir Kattsyn


People also ask

How do I check if permission is granted Android?

To check if the user has already granted your app a particular permission, pass that permission into the ContextCompat. checkSelfPermission() method. This method returns either PERMISSION_GRANTED or PERMISSION_DENIED , depending on whether your app has the permission.

How do you request multiple permissions using RequestMultiplePermissions contract?

How to request multiple permission using RequestMultiplePermissions contract: Process is same for requesting multiple permissions at once. You need to pass array of permission to launch(). ActivityResultCallback will return map with permission as key and its grant status as value e.g. below example prints android.


1 Answers

I found an answer to my question. It turned out that in Android 11 ACCESS_BACKGROUND_LOCATION permission shouldn't be requested alongside with other permissions. If it is, the system will just ignore the request. This permission should be requested separately.

Also, if at first request user decided not to give this permission, all the following requests for this permission will be ignored, so the settings page for it won't be shown (in this case you should probably prompt user to allow the permission manually).

like image 181
Vladimir Kattsyn Avatar answered Oct 23 '22 14:10

Vladimir Kattsyn