背景描述
随着Android系统的不断升级,谷歌对用户的隐私是越来越注重了,给我们开发者带来了更多的繁琐。Android6.0增加了动态权限申请,虽然不难,但是实现起来会很繁琐,代码量会很多,通常都是在需要申请的地方调用ContextCompat.checkSelfPermission(context, permission)
判断是否已经有了需要的权限,如果没有,则需要调用ActivityCompat.requestPermissions(activity, permissions, mRequestCode)
进行申请,最后需要在onRequestPermissionsResult
回调中对requestCode
和每一个权限对应的result
进行int
型的判断,一整个过程下来非常繁琐。这对于永远追求简单简洁的程序员来说是不可忍受的,所有将整个过程封装一下,目标是尽可能的使使用变得更简单。
实现逻辑
- 先看项目结构
-
把申请权限的整个流程都封装到
PermissionHelper
类中,对外只提供一个使用方法runOnPermissionGranted(Activity activity, Runnable actionOnGranted, Runnable actionOnDenied, String... permissions)
-
把需要申请的权限列表、申请成功和失败的回调等传入方法中,先判断是否已经允许了这些权限,如果没有,则申请权限,申请结果将会回调到Activity中的onRequestPermissionsResult方法,所以需要用户手动重写onRequestPermissionsResult方法,写入一行固定的代码即可(看后面的使用方法)。
public static void runOnPermissionGranted(Activity activity, Runnable actionOnGranted, Runnable actionOnDenied, String... permissions) {
if (isPermissionGranted(activity, permissions)) {
new Handler(Looper.getMainLooper()).post(actionOnGranted);
} else {
mRunnableOnPermissionGranted.put(mRequestCode, actionOnGranted);
mRunnableOnPermissionDenied.put(mRequestCode, actionOnDenied);
ActivityCompat.requestPermissions(activity, permissions, mRequestCode);
mRequestCode++;
}
}
- 申请结果就会回调到PermissionHelper类中进行处理,判断用户是否允许了权限,对应的调用之前传入的runnable,这样开发者就不用再重复一整个申请权限的过程了,只需要调用runOnPermissionGranted即可。
public static void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (mRunnableOnPermissionGranted.containsKey(requestCode)) {
// 这里规定全部权限都通过才算通过
boolean grant = true;
// 在A申请权限,然后马上跳转到B,则grantResults.length=0
if (grantResults.length == 0) grant = false;
for (int result : grantResults) {
if (result == PackageManager.PERMISSION_DENIED) {
grant = false;
}
}
if (grant) {
new Handler(Looper.getMainLooper()).post(mRunnableOnPermissionGranted.get(requestCode));
} else {
new Handler(Looper.getMainLooper()).post(mRunnableOnPermissionDenied.get(requestCode));
}
mRunnableOnPermissionGranted.remove(mRequestCode);
mRunnableOnPermissionDenied.remove(mRequestCode);
}
}
使用方法一:
-
直接把DEMO中的
PermissionHelper
类复制到你项目中 -
在
AndroidManifest
中注册权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- 重写
Activity
中的onRequestPermissionsResult
方法
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
PermissionHelper.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
- 在
Activity
中直接调用即可
PermissionHelper.runOnPermissionGranted(this, () -> {
// 权限通过
}, () -> {
// 权限不通过
}, Manifest.permission.WRITE_EXTERNAL_STORAGE);
使用方法二:
-
直接把DEMO中的
PermissionHelper
类和PermissionActivity
类复制到你项目中 -
在
AndroidManifest
中注册权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-
Activity
继承PermissionActivity
-
在
Activity
中直接调用即可
PermissionHelper.runOnPermissionGranted(this, () -> {
// 权限通过
}, () -> {
// 权限不通过
}, Manifest.permission.WRITE_EXTERNAL_STORAGE);
效果图
运行代码可能出现的问题
-
compileSdkVersion 27
,可以改成你电脑中存在的SDK版本。 -
这里用的是
gradle-4.4-all.zip
,如果你用的是其它版本,那么可能会下载超级慢,建议改成你电脑中存在的gradle版本,改文件PermissionHelper/gradle/wrapper/gradle-wrapper.properties
即可。 -
其它问题可以直接联系我。Android 6.0 超级简单的权限申请 (Permission)
注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权