Detailed Explanation of Android registerForActivityResult Dynamic Application Permission Case

  • 2021-12-19 06:44:22
  • OfStack

Preface

These days, I am doing a small tool app. As a result, I dynamically apply for permission in fragment to prompt that the original application method has been abandoned, and I have drawn an obvious strikeout. . . This is called an obsessive-compulsive disorder. How can I stand it? I can't find any results after looking for information on the Internet. After reading the official documents, I found that there is such a magical and easy-to-use function as registerForActivityResult, which can replace our existing startActivityForResult and permission application function.
Then let's talk about how to use this function to apply for permission dynamically in two situations.

1. Apply for a single permission

First, we need to define an launcher:


ActivityResultLauncher<String> launcher = registerForActivityResult(new ActivityResultContracts.RequestPermission(),
			result -> {
				if (result.equals(true)) {
					// Actions after permission is acquired 
				} else {
					// Actions for which permissions are not obtained 
				}
			});

In the above code, ActivityResultContracts. RequestPermission () tells the system that you want to get permission, and result returns the result
It can be seen that as long as the permission is obtained, the return of result is true, which can be judged directly.
Of course, only defining this launcher system will not execute, because this is only a registration function, and you should add the following code where you need to execute it:


button.setOnClickListener(view -> {
	launcher.launch(Manifest.permission.READ_EXTERNAL_STORAGE);
});

When you click on this button, you will be prompted to apply for read storage permission.

2. Get multiple permissions

Here, I take taking pictures and storing at the same time as an example. The principle of three or more permissions is similar.
Just like getting a single permission 1, getting multiple permissions also requires defining an launcher:


ActivityResultLauncher<String[]> launcher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(),
			result -> {
				if (result.get(Manifest.permission.CAMERA) != null
						&& result.get(Manifest.permission.READ_EXTERNAL_STORAGE) != null) {
					if (Objects.requireNonNull(result.get(Manifest.permission.CAMERA)).equals(true)
							&& Objects.requireNonNull(result.get(Manifest.permission.READ_EXTERNAL_STORAGE)).equals(true)) {
						// Actions after all permissions are obtained 
					} else {
						// Actions with permissions that are not obtained 
					}
				}
			});

Unlike a single permission, the way multiple permissions are passed in is ActivityResultContracts. RequestMultiplePermissions (). ActivityResultLauncher contains an string array. The return value result is of type map (as shown in the following table).

申请的权限(String) 权限的申请结果(boolean)
Manifest.permission.CAMERA true/false
Manifest.permission.READ_EXTERNAL_STORAGE true/false

Therefore, the get method in map can be directly used to obtain the corresponding results of each permission. I thought this was the end of it. As a result, the compiler drew a yellow background color here in my get method. 1 Look at the hint that it may cause a null pointer exception. So I added Objects. requireNonNull, and the warning disappeared immediately.
The last step is also indispensable. Execute the launch method 1 where you need to obtain permission:


launcher.launch(new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE})

3. Summary

registerForActivityResult is really a very useful function, if it weren't for prompting me to be abandoned before I may not know, not only can replace access method, startActivityForResult method can also be replaced with this function.


Related articles: