从 Android 6.0(API 级别 23)开始,用户开始在应用运行时向其授予权限,而不是在应用安装时授予。html
系统权限分为两类:android
如需了解更多关于正常权限与危险权限能够参阅这里。git
运行时权限的加入增长了用户隐私的安全,但同时也给开发者带来了一些负担,由于多了检查权限,请求权限,处理权限请求响应的步骤。api
因而就出现了一些框架,用于简化运行时权限的处理,如 PermissionsDispatcher,Dexter,RxPermissions,easypermissions 等。安全
这里只用过 easypermissions 和 PermissionsDispatcher,最终选择了 PermissionsDispatcher,缘由是使用人数最多,api 设计简单易用,兼容性较好,easypermissions 使用起来相对麻烦一些。app
PermissionsDispatcher 提供简单的基于注解的 api 处理 Android Marshmallow 下的运行时权限(非反射方式)。框架
注意把 ${latest.version}
改成最新版本。ide
打开命令行,cd 到工程根目录,执行 gradlew -version
或者 gradlew -v
命令查看当前工程 gradle 版本。
根据 gradle 版本进行以下配置:
在 app 模块下的 build.gradle
添加下面的配置:
dependencies { compile 'com.github.hotchemi:permissionsdispatcher:${latest.version}' annotationProcessor 'com.github.hotchemi:permissionsdispatcher-processor:${latest.version}' }
在 project-level 下的 build.gradle
添加下面配置:
buildscript { dependencies { classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' } }
而后,在 app 模块下的 build.gradle
添加下面配置:
apply plugin: 'android-apt' dependencies { compile 'com.github.hotchemi:permissionsdispatcher:${latest.version}' apt 'com.github.hotchemi:permissionsdispatcher-processor:${latest.version}' }
注意:注解的方法不能是 private 的。
注解 | 是否必须 | 描述 |
---|---|---|
@RuntimePermissions |
✓ | 注册一个 Activity 或 Fragment 用于处理权限 |
@NeedsPermission |
✓ | 注解一个方法,说明须要什么权限(一个或多个) |
@OnShowRationale |
注解一个方法,解释为何须要这些权限 | |
@OnPermissionDenied |
注解一个方法,当用户拒绝受权时将调用该方法 | |
@OnNeverAskAgain |
注解一个方法,当用户选择了 "再也不提醒" 将调用该方法 |
@RuntimePermissions public class MainActivity extends AppCompatActivity { // 单个权限 // @NeedsPermission(Manifest.permission.CAMERA) // 多个权限 @NeedsPermission({ Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO }) void showCamera() { getSupportFragmentManager().beginTransaction() .replace(R.id.sample_content_fragment, CameraPreviewFragment.newInstance()) .addToBackStack("camera") .commitAllowingStateLoss(); } // 向用户说明为何须要这些权限(可选) @OnShowRationale(Manifest.permission.CAMERA) void showRationaleForCamera(final PermissionRequest request) { new AlertDialog.Builder(this) .setMessage(R.string.permission_camera_rationale) .setPositiveButton(R.string.button_allow, (dialog, button) -> request.proceed()) .setNegativeButton(R.string.button_deny, (dialog, button) -> request.cancel()) .show(); } // 用户拒绝受权回调(可选) @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(); } }
注解写好后,Build ——> Make Module ***
,PermissionsDispatcher
会生成一个 MainActivityPermissionsDispatcher
(Activity Name + PermissionsDispatcher
),你可使用它来安全地访问这些授权限保护的方法。
你惟一须要作的一件事是将工做委托给这个辅助类:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.button_camera).setOnClickListener(v -> { // 调用带权限检查的 showCamera 方法 MainActivityPermissionsDispatcher.showCameraWithCheck(this); }); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); // 代理权限处理到自动生成的方法 MainActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults); }
*PermissionDispatcher.*WithCheck
方法对你原来的方法进行了包装,包了一层权限检查的代码,你须要作的就是把原来的方法调用改成 *PermissionDispatcher.*WithCheck
。另外,在 onRequestPermissionsResult
中回调 *PermissionsDispatcher.onRequestPermissionsResult
方法。
两个特殊权限:
Manifest.permission.SYSTEM_ALERT_WINDOW
:显示悬浮窗Manifest.permission.WRITE_SETTINGS
:读写系统设置对于这两个权限,在 Android 下默认是须要到 Settings -> Apps
中手动受权的。因为不一样 ROM 状况可能还有点不同。
PermissionsDispatcher
对于两个特殊权限也作了兼容处理(Android6.0+),使用方法如上同样。
若是须要兼容低版本的 Android 系统或者不一样 ROM 能够参考这个开源项目。
<uses-permission>
有一个 maxSdkVersion
属性,PermissionsDispatcher
对它也作了支持。
好比,在 Androidmanifest.xml 中定义了以下权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18" />
注解中添加 maxSdkVersion
:
@RuntimePermissions public class MainActivity extends AppCompatActivity { @NeedsPermission(value = Manifest.permission.WRITE_EXTERNAL_STORAGE, maxSdkVersion = 18) void getStorage() { // ... } }
PermissionsDispatcher Plugin 是 PermissionsDispatcher 的辅助插件,支持自动生成权限检查相关代码。
项目地址:https://github.com/shiraji/permissions-dispatcher-plugin
安装说明:Android Studio 中打开 Setting,
Plugins ——> Browse repositories...
搜索PermissionsDispatcher plugin
,点 Install 下载安装,安装完成后重启生效。
image
使用说明:
使用过程当中发现有两个小问题须要注意一下:
onRequestPermissionsResult
方法也会被自动添加屡次Build ——> Make Module ***
相对快些做者:linchaolong 连接:https://www.jianshu.com/p/64e7334cde11 來源:简书 简书著做权归做者全部,任何形式的转载都请联系做者得到受权并注明出处。