前言
这几天在做一个小工具app,结果在fragment里面动态申请权限提示原有的申请方法已经弃用,还画了很明显的删除线。。。这叫一个强迫症的我怎么受得了。赶紧网上找资料也找不出什么结果,看了官方文档才发现了有registerForActivityResult这么一个神奇好用的函数,可以代替我们现有的startActivityForResult和权限申请函数。
那么下面就分两种情况来讲一下如何使用这个函数动态申请权限。
一、申请单个权限
首先,我们需要定义一个launcher:
ActivityResultLauncher<String> launcher = registerForActivityResult(new ActivityResultContracts.RequestPermission(),
result -> {
if (result.equals(true)) {
//权限获取到之后的动作
} else {
//权限没有获取到的动作
}
});
上面代码里的ActivityResultContracts.RequestPermission()就是告诉系统你要获取权限,result是返回结果
可以看出只要权限获取到了,这里result返回就是true,直接进行判断即可。
当然,只定义了这个launcher系统是不会执行的,因为这只是一个注册函数,还要在你需要执行的地方加入如下的代码:
button.setOnClickListener(view -> {
launcher.launch(Manifest.permission.READ_EXTERNAL_STORAGE);
});
完成后当你点击这个button的时候,就会跳出申请读存储权限的提示。
二、获取多个权限
这里我以同时获取拍照和存储两个权限为例,三个及以上的原理类似。
和获取单个权限一样,获取多个权限也需要定义一个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)) {
//权限全部获取到之后的动作
} else {
//有权限没有获取到的动作
}
}
});
和单个权限不同的是,多个权限传入的方法是ActivityResultContracts.RequestMultiplePermissions()。ActivityResultLauncher里面带的是一个string数组。返回值result的类型是map(样例如下表)。
申请的权限(String) | 权限的申请结果(boolean) |
---|---|
Manifest.permission.CAMERA | true/false |
Manifest.permission.READ_EXTERNAL_STORAGE | true/false |
所以直接使用map里的get方法就可以获取每个权限对应的结果。我以为就这样结束了,结果编译器在我get方法这里画了黄黄的底色,一看提示说可能导致空指针异常。所以我就多加了Objects.requireNonNull,警告马上消失。
最后一步同样不能少,在需要获取权限的地方执行一下launch方法:
launcher.launch(new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE})
三、总结
registerForActivityResult真的是个很好用的函数,要不是提示我之前的被弃用了我可能一直都不知道,不光可以代替获取权限方法,startActivityForResult方法也可以替换为这个函数。