在Android 6.0以前的系统中,如果使用的功能用到相关权限,需要在AndroidManifest.xml文件中声明,在用户要安装程序的时候将其展现出来。但是,用户一般不会在意要使用的应用都需要哪些权限,也不会因为需要这些权限而不安装应用。所以一般在安装的时候,就将所有权限都一并申请了。
Android 6.0系统在权限管理上增加了动态权限的控制。它将权限分为两种,一种是静态权限,一种是动态权限。对于一般权限,和以前一样,在AndroidManifest.xml中申请即可,这种是静态权限。对于重要的权限,不仅要在AndroidManifest.xml文件中声明,还需要通过代码让用户在使用的时候动态申请,这种是动态权限。
Android 6.0系统对动态权限进行了定义,说明哪些权限是动态的,必须动态申请才能使用。并且有权限组的概念,也就是说,在一个组内的权限,只要申请了一个,其他的组内权限就被全部申请了。
动态权限组表:
Android 6.0给申请动态权限开放的api,使用起来相当麻烦,包括请求权限,权限处理回调,开发者需要根据用户对系统弹出的动态权限框的各种处理进行相关操作。
因此,有许多第三方库专门来处理这个问题,其中,个人认为PermissionDispatcher这个库非常方便、好用。
下面就来说说如何使用PermissionDispatcher库来为应用处理动态权限。
1、配置
For Android Gradle Plugin >= 2.2 users,需要在app module的build.gradle文件中配置以下内容:
dependencies { compile 'com.github.hotchemi:permissionsdispatcher:${latest.version}' annotationProcessor 'com.github.hotchemi:permissionsdispatcher-processor:${latest.version}' }
其中,${latest.version}
is 。
For Android Gradle Plugin < 2.2 users,需要在project的build.gradle文件中配置以下内容:
buildscript { dependencies { classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' } }
2、PermissionDispatcher是通过注解的方式来使用的。
其中,
@RuntimePermission用来标注需要申请动态权限的Activity和Fragment。
@NeedsPermission指明需要申请权限的方法。需将申请权限成功后的执行内容放到一个方法中,然后将该注解放到该方法上,权限申请成功后,就会自动执行这个方法。
@OnShowRationale可以弹对话框向用户解释权限。
@OnPermissionDenied放在用户在授权对话框选择拒绝授权后,执行的方法上面。
@OnNverAskAgain放在用户在授权对话框选择拒绝授权,并且勾选了“不在提示”选择框后,执行的方法上面。
示例如下:
@RuntimePermissions public class MainActivity extends AppCompatActivity { @NeedsPermission(Manifest.permission.CAMERA) void showCamera() { getSupportFragmentManager().beginTransaction() .replace(R.id.sample_content_fragment, CameraPreviewFragment.newInstance()) .addToBackStack("camera") .commitAllowingStateLoss(); } @OnShowRationale(Manifest.permission.CAMERA) void showRationaleForCamera(final PermissionRequest request) { request.proceed(); } @OnPermissionDenied(Manifest.permission.CAMERA) void showDeniedForCamera() { Toast.makeText(this, R.string.permission_camera_denied, Toast.LENGTH_SHORT).show(); } @OnNeverAskAgain(Manifest.permission.CAMERA) void showNeverAskForCamera() { Toast.makeText(this, R.string.permission_camera_neverask, Toast.LENGTH_SHORT).show(); } }
2、使用PermissionDispatcher库产生的类
在编写完上面示例程序后,编译运行,会产生一些类,我们需要使用这些类进行权限申请。产生的类在app/build/intermediates/classes/debug/包名 目录下。
其中,XXXPermissionDispatcher.XXXWithCheck(this, args...)这条语句就是申请权限。args是@NeedPermission标注的方法的参数。
并且,需要在onRequestPermissionsResult回调方法中执行
XXXPermissionDispatcher.onRequestPermissionsResult方法。
示例如下:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.button_camera).setOnClickListener(v -> { // NOTE: delegate the permission handling to generated method MainActivityPermissionsDispatcher.showCameraWithCheck(this); }); findViewById(R.id.button_contacts).setOnClickListener(v -> { // NOTE: delegate the permission handling to generated method MainActivityPermissionsDispatcher.showContactsWithCheck(this); }); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); // NOTE: delegate the permission handling to generated method MainActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults); }
本文出自 亭子happy,转载时请注明出处及相应链接
https://my.oschina.net/tingzi/blog/828806
习惯使用手机的朋友们可以关注我的微信公众号看文章。