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});
Thank you for the post