Android6.0动态获取权限 Android系统从6.0开始对用户权限的控制更加严格,系统将权限分为了两个级别,常规权限和危险权限; 1、常规权限:不会涉及用户隐私操作的权限,如读写存储卡; 2、危险权限:涉及用户隐私的权限,如读取电子邮件和通讯录; Android将需要申请的权限依次在manifest中注册, 如<uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission> 当用户执行需要权限的操作时,系统会检查当前应用是否具有相应的操作权限, 在Android6.0之前,会在安装应用的时候申请权限,如果用户不同意, 则无法完成安装,但是在6.0之后,申请限向变成了动态申请的模式,即当用户应用要使用某项权 限才能进行相应操作时,每次都需要去检查是否拥有相应的权限,当申请的是常规权限的时候, 系统会默认同意权限,申请的是危险权限的时候,系统会弹出询问框提示用户是否授权该应用相应的权限。 ------------------------------------------------------------------------------------------------------------------- 方法一: 自己手动请求权限。参考:https://developer.android.google.cn/training/permissions/requesting.html 1,注册权限; <uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission> 2、检查权限: 在Activity/Fragment中相应的方法里调用ContextCompat.checkSelfPermission()方法, 检查是否拥有相依的权限 调用ContextCompat的方法检查权限: int permissionCheck = ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.WRITE_CALENDAR); public void checkPermission(){ int tag= ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS); if(tag== PackageManager.PERMISSION_DENIED){//没有权限 //需要执行申请权限操作 ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_CONTACTS}, MY_PERMISSIONS_REQUEST_READ_CONTACTS); }else if (tag==PackageManager.PERMISSION_GRANTED){//有权限 //执行目标代码 callMyPhone(); } } 3、申请权限: MY_PERMISSIONS_REQUEST_READ_CONTACTS:请求码,申请成功或失败后会在 onRequestPermissionsResult方法中作为某项权限的标识。 ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.READ_CONTACTS}, MY_PERMISSIONS_REQUEST_READ_CONTACTS); 复写Activity/Fragment的onRequestPermissionsResult方法,这里以Activity为例: @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode){ case MY_PERMISSIONS_REQUEST_READ_CONTACTS://申请成功 if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {//申请成功 //成功要执行的方法 callMyPhone(); } else {//申请失败 //失败要执行的方法 } break; } } 4、申请权限成功或者失败,完成相应的操作: 当权限申请成功后,会异步回调onRequestPermissionsResult方法,requestCode就是申请某 项权限是传入的请求码,这里是MY_PERMISSIONS_REQUEST_READ_CONTACTS,通过requestCode 来判断是申请的那项权限,grantResults是权限申请的结果,是一个数组,判断是成功还是 失败,并且执行相应的方法。 全部代码: ================= public class MainActivity extends AppCompatActivity { public static int MY_PERMISSIONS_REQUEST_CALL_PHONE = 100; private static final int MY_PERMISSIONS_REQUEST_READ_CONTACTS=100; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void checkPermission(){ int tag= ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS); if(tag== PackageManager.PERMISSION_DENIED){//没有权限 //需要执行申请权限操作 ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_CONTACTS}, MY_PERMISSIONS_REQUEST_READ_CONTACTS); }else if (tag==PackageManager.PERMISSION_GRANTED){//有权限 //执行目标代码 callMyPhone(); } } //指向访问通讯 public void callMyPhone() { Uri uri =ContactsContract.Contacts.CONTENT_URI; Intent intent = new Intent(Intent.ACTION_PICK, uri); startActivityForResult(intent,0); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode){ case MY_PERMISSIONS_REQUEST_READ_CONTACTS: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {//申请成功 //成功要执行的方法 callMyPhone(); } else {//申请失败 //失败要执行的方法 } break; } } -------------------------------------------------------------------------------------------- 方法二: =============== 使用三方的库; 常用的库有很多,比较好的有easypermissions和PermissionsDispatcher等, 开源地址为: easypermissions:https://github.com/googlesamples/easypermissions PermissionsDispatcher:https://github.com/hotchemi/PermissionsDispatcher 这里以PermissionsDispatcher为例:该库是使用反射机制来做的,但是右一个亮点是将 提前到了编译器,通过反射生成辅助来供相应的类在运行时调用,所以该库基本不因为反射 影响应用的性能。 注意:当gradle版本不一样的时候,引入配置方式有所不同 1)、当Gradle 版本>= 2.2的引入方式; 在当前module的gradle中依赖库: dependencies { compile 'com.github.hotchemi:permissionsdispatcher:2.3.1' annotationProcessor 'com.github.hotchemi:permissionsdispatcher-processor:2.3.1' } 2)、当Gradle 版本< 2.2的引入方式; 《1》中工程的gradle中 buildscript { dependencies { classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' } } repositories { jcenter() // 需要添加的配置 maven { url 'http://oss.jfrog.org/artifactory/oss-snapshot-local/' } } 《2》在module的gradle中配置: 头部添加 apply plugin: 'com.android.application'//你的module配置不用动 apply plugin: 'android-apt'//新添加的配置 依赖库 dependencies { compile 'com.github.hotchemi:permissionsdispatcher:2.3.1' annotationProcessor 'com.github.hotchemi:permissionsdispatcher-processor:2.3.1' } 根据不同gradle的版本配置完成后重新构建工程,接下来就是正式使用了。 在Activity或Fragment中使用 ------------------------------------------------------------------------------------ 注解列表: Annotation Required Description @RuntimePermissions 必须 注解在其内部需要使用运行时权限的Activity或 Fragment上 ------------------------------------------------------------------------------------ @NeedsPermission 必须 注解在需要调用运行时权限的方法上,当用户给予权限时 会执行该方法 ------------------------------------------------------------------------------------ @OnShowRationale 可选 注解在用于向用户解释为什么需要调用该权限的方法上, 只有当第一次请求权限被用户拒绝,下次请求权限之前会 调用 ------------------------------------------------------------------------------------ @OnPermissionDenied 可选 注解在当用户拒绝了权限请求时需要调用的方法上 ------------------------------------------------------------------------------------ @OnNeverAskAgain 可选 注解在当用户选中了授权窗口中的不再询问复选框后并拒 绝了权限请求时需要调用的方法,一般可以向用户解释为 何申请此权限,并根据实际需求决定是否再次弹出权限请 求对话框 ------------------------------------------------------------------------------------ 官网参考地址:http://hotchemi.github.io/PermissionsDispatcher/ 注意:被注解的方法不能是私有方法。 只有@RuntimePermissions和@NeedsPermission是必须的,其余注解均为可选。当使用了 @RuntimePermissions和@NeedsPermission之后,需要点击菜单栏中Build菜单下的Make Project ,或者按快捷键Ctrl+ F9编译整个项目,编译器会在app\build\intermediates\classes\debug 目录下与被注解的Activity同一个包下生成一个辅助类, 名称为被注解的Activity名称+PermissionsDispatcher.class 接下来可以调用辅助类里面的方法完成应用的权限请求了。 在需要调用权限的位置调用辅助类里面的xxxWithCheck方法,xxx是被@NeedsPermission注 解的方法名。如: MainActivityPermissionsDispatcher.showCameraWithCheck(this); 全部代码: ================== 注解Activity为运行时权限 @RuntimePermissions public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } /** * 执行的事件 * @param */ public void app(View v) { MainActivityPermissionsDispatcher.callPhoneWithCheck(this);//检查权限 } /** * 当权限申请成功后被执行的代码 * 注解当某项权限申请成功后被调用的方法 */ @NeedsPermission(Manifest.permission.READ_CONTACTS) public void callPhone() { Uri uri = ContactsContract.Contacts.CONTENT_URI; Intent intent = new Intent(Intent.ACTION_PICK, uri); startActivityForResult(intent, 0); } /** * 复写Activity或者Fragment的处理权限的方法 * 当申请了权限时会被异步调用 */ @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[]permissions,@NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); //调用生成辅助类的方法 MainActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults); } /** * 当权限被拒绝后要调用的方法 */ @OnPermissionDenied(Manifest.permission.READ_CONTACTS) public void onPermissionDenied() { } }
Android6.0动态获取权限
最新推荐文章于 2021-05-25 16:17:52 发布