当前对于大部分手机来说,Android6.0及以上的版本已经是基本配置了,我们在开发的时候,需要对6.0的新特性进行适配,最让我们熟悉的就是6.0以上权限的动态申请,今天我们来学习一下权限动态申请相关的知识。
对于动态权限的申请,Google为我们提供了EasyPermissions这个框架,该框架可以帮我们更加简单的完成权限申请的操作。本篇文章我们来学习如何使用这个框架及该框架是怎么封装的。
先贴上gitHub上google示例的地址 EasyPermissions的GitHub地址
我们学习一个框架的时候,肯定是想先知道怎么使用这个框架,所以我们先来看EasyPermissions如何使用!
一、如何使用EasyPermissions?
此处,我们根据上面Google在gitHub中的示例代码进行使用的介绍。示例非常简单,只有两个类,一个Activity,一个Fragment,显示了如何在这两种场景下使用EasyPermissions。
首先,在我们的build.gradle文件中先添加EasyPermissions
implementation 'pub.devrel:easypermissions:1.2.0'
我们先看Activity中的代码是如何写的。
先在Activity的回调onRequestPermissionsResult(此为我们申请权限的回调)方法中,将回调的数据透传给EasyPermissions,让EasyPermissions帮我们管理权限回调。
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// EasyPermissions handles the request result.
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
我们的准备工作,将权限回调给EasyPermissions帮我们管理之后,就可以进行我们的权限申请了,我们知道,在请求权限的时候,需要先判断是否有这个权限,那么我们来看该如何用EasyPermissions判断是否拥有某个权限。
private boolean hasCameraPermission() {
return EasyPermissions.hasPermissions(this, Manifest.permission.CAMERA);
}
非常简单,Google给的示例代码中,只需要调用EasyPermissions的hasPermissions方法就行了
/**
* Check if the calling context has a set of permissions.
*
* @param context the calling context.
* @param perms one ore more permissions, such as {@link Manifest.permission#CAMERA}.
* @return true if all permissions are already granted, false if at least one permission is not
* yet granted.
* @see Manifest.permission
*/
public static boolean hasPermissions(@NonNull Context context,@Size(min = 1) @NonNull String... perms)
这个方法的源码介绍是这样的,其是一个可变长参数,当所有权限都满足的时候,返回true,否则返回false。
当判定有权限的时候,我们去做该做的事就行了,那没有权限怎么办呢?
当然是用EasyPermissions请求权限啦!
public void cameraTask() {
if (hasCameraPermission()) {
// Have permission, do the thing!
Toast.makeText(this, "TODO: Camera things", Toast.LENGTH_LONG).show();
} else {
// Ask for one permission
EasyPermissions.requestPermissions(
this,
getString(R.string.rationale_camera),
RC_CAMERA_PERM,
Manifest.permission.CAMERA);
}
}
请求权限只需要调用EasyPermissions的requestPermissions方法即可,让我们看一下这个方法的各个参数都是什么作用,先看一下源码中的注释。
/**
* Request a set of permissions, showing a rationale if the system requests it.
*
* @param host requesting context.
* @param rationale a message explaining why the application needs this set of permissions;
* will be displayed if the user rejects the request the first time.
* @param requestCode request code to track this request, must be < 256.
* @param perms a set of permissions to be requested.
* @see Manifest.permission
*/
public static void requestPermissions(
@NonNull Activity host, @NonNull String rationale,
int requestCode, @Size(min = 1) @NonNull String... perms)
第一个为Activity对象,第二个是一个字符串,其展示的场景是
当用户第一次拒绝这个权限时,将展示这个信息(
个人手机实际测试,第一次弹出权限请求,点击拒绝并且不再提醒的时候,将没有这个信息展示的场景
)。第三个是requestCode,是做校验用的,需要注意的是,必须小于256。第四个参数就是我们需要请求的权限,同样是一个可变长参数。
接下来我们看四个回调,分别是在我们请求权限时对应的回调信息,EasyPermissions类内部的两个接口。
/**
* Callback interface to receive the results of {@code EasyPermissions.requestPermissions()}
* calls.
*/
public interface PermissionCallbacks extends ActivityCompat.OnRequestPermissionsResultCallback {
void onPermissionsGranted(int requestCode, @NonNull List<String> perms);
void onPermissionsDenied(int requestCode, @NonNull List<String> perms);
}
/**
* Callback interface to receive button clicked events of the rationale dialog
*/
public interface RationaleCallbacks {
void onRationaleAccepted(int requestCode);
void onRationaleDenied(int requestCode);
}
我们的Activity实现这两个接口之后,其对应的回调将传递回来。PermissminCallbacks是权限的回调,当权限被拒绝的时候,会执行onPermissionsDenied方法,当权限通过的时候会执行onPermissionsGranted方法。而RationaleCallbacks就是信息提示框对应的回调,也就是我们上面请求权限第二个参数展示的那个提示框对应的回调,当用户同意的时候,执行onRationaleAccepted方法,取消的时候执行onRationaleDenied方法,也是考虑的很全面了,能满足我们实际使用的场景需求。上面四个方法的参数均是对应权限的requestCode和权限信息,此处不做过多解释。
当我们不再提示并拒绝权限申请的时候,再次使用EasyPermissions的requestPermissions申请权限,将弹出提示信息,确认后跳转到系统对该应用的设置界面,提醒用户手动打开权限。
上面这个界面在示例中是这样调用的:
@Override
public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
Log.d(TAG, "onPermissionsDenied:" + requestCode + ":" + perms.size());
// (Optional) Check whether the user denied any permissions and checked "NEVER ASK AGAIN."
// This will display a dialog directing them to enable the permission in app settings.
if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
Log.d(TAG, "AppSettingsDialog show" );
new AppSettingsDialog.Builder(this).build().show();
}
}
Google自定义了一个AppSettingsDialog(其实是一个Activity),我们可以通过传参来修改显示的样式,跳转相关的信息已经帮我们封装好了,使用起来很便捷。
另外,在启动这个的时候,实际的启动方式是startActivityForResult的,所以我们应该重写Activity的onActivityResult方法,接收权限设置之后的结果,示例中的参考代码如下:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE) {
String yes = getString(R.string.yes);
String no = getString(R.string.no);
// Do something after user returned from app settings screen, like showing a Toast.
Toast.makeText(
this,
getString(R.string.returned_from_app_settings_to_acti