详解Android权限管理之Android 6.0运行时权限及解决办法

详解Android权限管理之Android 6.0运行时权限及解决办法,第1张

概述前言:今天还是围绕着最近面试的一个热门话题Android6.0权限适配来总结学习,其实Android6.0权限适配我们公司是在今年5月份才开始做,算是比较晚的吧,不过现在Android6.0以上设备越来越多了,所以Android6.0权限适

前言:

今天还是围绕着最近面试的一个热门话题AndroID 6.0权限适配来总结学习,其实AndroID 6.0权限适配我们公司是在今年5月份才开始做,算是比较晚的吧,不过现在AndroID 6.0以上设备越来越多了,所以AndroID 6.0 权限适配是必不可少的工作,这里主要介绍一下我们公司是如何做AndroID 6.0权限适配的。

AndroID 6.0以下非运行时权限:

根据上面博客我们很清楚的知道,AndroID的权限其实就是为了程序之间更加的安全的访问,所以权限有等级之分,比如:normal 低风险权限 、Dangerous  高风险权限等,虽然有这种安全意识,但是这些权限只会在安装的时候被询问一次,一旦安装之后,如果app申请了高风险权限的话,而且大部分用户在安装的时候很少去关注这些权限列表,再加上很多AndroID市场都有静默安装的功能用户更加感知不到任何权限提示,就这样app就有可能会在后台做一些对用户带来伤害的事情。如下图所示:

AndroID6.0运行时权限:

鉴于6.0之前的版本权限管理相对不那么安全,所以AndroID 6.0 采用新的权限模型,只有在需要权限的时候,才告知用户是否授权,是在runtime时候授权,而不是在原来安装的时候 ,同时默认情况下每次在运行时打开页面时候,需要先检查是否有所需要的权限申请。这样的用户的自主性提高很多,比如用户可以给APP赋予摄像的权限,也可以使用权限。

 

AndroID 6.0权限适配:

1.)不进行适配造成的现象

先看下app module的build.gradle配置

 compileSdkVersion 24 buildToolsversion "24.0.2" defaultConfig {  applicationID "com.whoislcj.rxpermissions"  minSdkVersion 15  targetSdkVersion 24  versionCode 1  versionname "1.0" }

由于AndroID 6.0 以上的权限变成了运行时权限,也就是说在需要使用某个权限的时候必须动态去申请使用,直接访问直接导致app崩溃。


2.)早期的解决办法 

其实判断是否是需要运行时权限的标记就是targetSDKVersion,当targetSDKVersion<23的时候,仅在安装时赋予权限,使用时将不被提醒,当targetSDKVersion≥23的时候才会使用新的运行时权限规则。所有在最早遇见因权限未适配的导致的崩溃的时候,我们团队采用的解决办法是将targetSDKVersion人为的降到小于23,这样就变成了还是默认使用权限,但是这种并不是Google所推荐使用的。

 compileSdkVersion 24 buildToolsversion "24.0.2" defaultConfig {  applicationID "com.whoislcj.rxpermissions"  minSdkVersion 15  targetSdkVersion 22  versionCode 1  versionname "1.0" }

3.)判断是否拥有该权限的使用权限

检查是否拥有使用权

 public boolean isGranted(String permission) {  return !isMarshmallow() || isGranted_(permission); }

判断是否是AndroID 6.0以上

 private boolean isMarshmallow() {  return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M; }

是否申请了该使用权限

 private boolean isGranted_(String permission) {  int checkSelfPermission = ActivityCompat.checkSelfPermission(this,permission);  return checkSelfPermission == PackageManager.PERMISSION_GRANTED; }

ContextCompat.checkSelfPermission,主要用于检测某个权限是否已经被授予,方法返回值为PackageManager.PERMISSION_DENIED或者PackageManager.PERMISSION_GRANTED。当返回DENIED就需要进行申请授权了。

4.)申请使用权限

private voID requestPermission(String permission,int requestCode) {  if (!isGranted(permission)) {   if (ActivityCompat.shouldShowRequestPermissionRationale(this,permission)) {   } else {    ActivityCompat.requestPermissions(this,new String[]{permission},requestCode);   }  } else {   //直接执行相应 *** 作了  } }

shouldShowRequestPermissionRationale主要用于给用户一个申请权限的解释,该方法只有在用户在上一次已经拒绝过你的这个权限申请。也就是说,用户已经拒绝一次了,你又d个授权框,你需要给用户一个解释,为什么要授权,则使用该方法。requestCode这个需要在处理的回调的时候 一一对应的。

5.)处理授权回调

@OverrIDe public voID onRequestPermissionsResult(int requestCode,String[] permissions,int[] grantResults) {  if (requestCode == CAMERA) {   if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {    String jpgPath = getCacheDir() + "test.jpg";    takePhotoByPath(jpgPath,2);   } else {    // Permission DenIEd    Toast.makeText(MainActivity.this,"您没有授权该权限,请在设置中打开授权",Toast.LENGTH_SHORT).show();   }   return;  }  super.onRequestPermissionsResult(requestCode,permissions,grantResults); }

6.)完整的Activity示例
 

public class MainActivity extends AppCompatActivity { private static final int CAMERA = 2; @OverrIDe protected voID onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentVIEw(R.layout.activity_main);  findVIEwByID(R.ID.request_permission).setonClickListener(new VIEw.OnClickListener() {   @OverrIDe   public voID onClick(VIEw v) {    requestPermission(Manifest.permission.CAMERA,CAMERA);   }  }); } /**  * 拍照,返回拍照文件的绝对路径  */ private String takePhotoByPath(String filePath,int requestCode) {  file file = new file(filePath);  startActivityForResult(getTakePhotoIntent(file),requestCode);  return file.getPath(); } private Intent getTakePhotoIntent(file file) {  if (file.exists()) {   file.delete();  }  try {   file.createNewfile();  } catch (IOException e) {   e.printstacktrace();  }  Uri uri = Uri.fromfile(file);  Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);  intent.putExtra(MediaStore.EXTRA_OUTPUT,uri);  return intent; } public boolean isGranted(String permission) {  return !isMarshmallow() || isGranted_(permission); } private boolean isGranted_(String permission) {  int checkSelfPermission = ActivityCompat.checkSelfPermission(this,permission);  return checkSelfPermission == PackageManager.PERMISSION_GRANTED; } private boolean isMarshmallow() {  return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M; } //shouldShowRequestPermissionRationale主要用于给用户一个申请权限的解释,该方法只有在用户在上一次已经拒绝过你的这个权限申请。也就是说,用户已经拒绝一次了,你又d个授权框,你需要给用户一个解释,为什么要授权,则使用该方法。 private voID requestPermission(String permission,requestCode);   }  } else {   //直接执行相应 *** 作了  } } @OverrIDe public voID onRequestPermissionsResult(int requestCode,grantResults); }}

总结:

本篇总结学习了AndroID 6.0的运行时权限及如何适配的问题,但是这个并不是我们公司目前最终的解决办法,从上面可以看出实现起来还是蛮麻烦的,申请权限和处理回调在不同的地方代码可读性相对较差,我们最终的解决方案是采用RxJava+RxPermission的方式解决,下一篇将介绍一下如何使用RxPermission解决AndroID 6.0 权限适配问题。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

总结

以上是内存溢出为你收集整理的详解Android权限管理之Android 6.0运行时权限及解决办法全部内容,希望文章能够帮你解决详解Android权限管理之Android 6.0运行时权限及解决办法所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1147615.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存