Request Permission with new API

Before June 2020 the request permission at runtime happened through requestPermission() and requestPermissionResult(). After that date the things are become a bit tricky. Requesting a permission has been inglobated in a more general way of “Getting a result from an activity” by “Registering a callback for an activity result”. Here are the documents: Getting a result from an activity.

Generally speaking, the communication between two activities or, an activity and a fragment, is done by registering a callback.

But let’s focus better on the request permissions: we should use now 2 new API package (androidx.activity.result & androidx.activity.result.contract), because the old one APIs are deprecated.

First of all, you must declare in the onCreate() or onAttach() methods of the activity or fragment the ActivityResultContract,

@Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        singlePermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestPermission(), (isGranted) -> {
            if (isGranted)
                ...do something good...
            else 
                ... do something bad...
        });
    }

Otherwise if you make it in other methods the following exception will throw:

Fatal Exception: java.lang.IllegalStateException: Fragment p0{b7ebf55} (b50ece9c-77cd-4948-9135-5a2194f8702f) id=0x7f0a0117} is attempting to registerForActivityResult after being created. Fragments must call registerForActivityResult() before they are created (i.e. initialization, onAttach(), or onCreate()).

And in the declarations of the class:

private ActivityResultLauncher<String> singlePermissionLauncher;

Then, in the moment you will ask the permission (after a click on a button or something else):

myButton.setOnClickListener(v -> singlePermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION));

Job done.

If you have to ask multiple permission, don’t call ActivityResultContracts.RequestPermission() but call ActivityResultContracts.RequestMultiplePermission() as the following code:

multiplePermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), (Map<String, Boolean> isGranted) -> {
            boolean granted = true;
            for (Map.Entry<String, Boolean> x : isGranted.entrySet())
                if (!x.getValue()) granted = false;
            if (granted)
                ...do something good...
            else {
                ... do something bad...
            }
        });

And call with this:

multiplePermissionLauncher.launch(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.<em>ACCESS_BACKGROUND_LOCATION});

One Reply to “Request Permission with new API”

Leave a Reply

Your email address will not be published. Required fields are marked *