标签:man 管理机 定义 权限管理 访问 trace 文件中 界面 厂商
在Android 6.0之前,所申请的权限只需要在AndroidManifest.xml列举就可以了,从而容易导致一些安全隐患,因此,在Android 6.0时,Google为了更好的保护用户隐私提出了新的权限管理机制,同时将其分为两大类:
(1)Normal Permissions
Normal Permission一般不涉及用户隐私,是不需要用户进行授权的,比如手机震动,访问网络等。
(2)Dangerous Permission
Dangerous Permission一般是涉及到用户隐私的,需要用户进行授权(动态申请),比如读取SIM卡状态、访问通讯录、SD卡读写等。
通过adb shell pm list permission -d -g可以查看Dangerous Permission。
Dangerous Permission一般以Permission group形式存在,只要Permission Group中某一个permission被Granted(授予),则整个Permission group下的权限均被Granted。
安装的时候不会获得权限,在运行时向用户申请对应权限。这部分权限检查比较简单,不涉及权限兼容,使用官方方案就可以,使用Context:checkSelfPermission,建议使用ContextCompat:checkSelfPermission检查权限即可,一般检查流程如下:
(1)判断是否有对应权限
(ContextCompat::checkSelfPermision)
(2)判断是否需要解释对应权限用途(ActivityCompat::shouldShowRequestPermissionRationale)
如果需要解释,则显示自定义权限界面即可
(3)不需要解释的话,直接请求对应权限
(ActivityCompat::requestPermission)
使用的是老的权限机制,在app安装时会询问AndroidManifest.xml文件中的权限,但是用户可以在设置列表中关闭相关权限,这种情况可能会对app正常运行造成一定影响。
老的权限管理机制是,在app安装时会询问AndroidManifest.xml文件中的权限,用户关闭不了,但是目前有不少国产Rom手机在6.0之间就有关闭权限的开关。
适配过程:
1.使用try-catch来检查权限是否关闭
使用READ_PHONE_STATE权限的方法内部已经try-catch,外面无法捕获,所以如果该权限被用户禁止了,报异常时,在catch中做文章的方法根本没有用。
2.ContextCompat::checkSelfPermission
在6.0可以使用Context::checkSelfPermission进行权限检查,在api 23那使用support v4中的ContextCompat::checkSelfPermission方法失效,只要权限在AndroidManifest.xml中注册过,均会认为该权限granted,因此方法在api 23以下失效。
3.PermissionChecker
PermissionChecker内部实际上使用的是AppOpsManagerCompat,而AppOpsManager是在api 19加入进去的。
在api 23以下,AppOpsManagerImpl::permissionToOp直接返回为null,这直接导致api 23以下权限检查将会返回granted,因此,该方法在api 23下,权限检查方法也会失效。
4.AppOpsManager
API 19以上,Google官方提供了AppOpsManager类来检查权限,里面有两个比较重要的方法: AppOpsManager::checkOp(int op,int uid,String packageName)(hide方法,需要反射)和AppOpsManager::checkOp(String op,int uid,String packageName)(public方法,api 23以上可用)。
但是,当api低于23时,OP_READ_PHONE_STATE=51找不到,导致AppOpsManager::checkOp方法反射失败,导致的原因是每个版本的_NUM_OP不同,OP_READ_PHONE_STATE = 51在6.0(API 23)以下,通过反射是找不到的,因此对于READ_PHONE_STATE权限检查仅限于6.0及6.0以上。
Intent intent = new Intent(); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); intent.setData(Uri.fromParts("package",getPackageName(), null)); try { startActivity(intent); }catch (Exception e){ e.printStackTrace(); }
记得要添加try-catch,不加可能会crash(崩溃)。这种方式就不需要适配各个厂商的不同版本rom,缺点是,用户只能跳转到系统设置页,然后去找对应app的权限管理。
对于不同的手机或手机系统,跳转权限管理页面的activity或者有所不同,如果没有加上try-catch,就会直接crash。
对于这种变化,作为开发者一般都是不知道的,即便通过反馈发现了这个问题,也有可能不知道actiivty是什么,此刻要么搜索网上有没有类似解决方案,要么求助于对应rom开发厂商的开发者论坛。
(1)通过设置找到对应app的权限管理页面
(2)找到对应页面的activity
方法一:通过add工具查看栈顶Activity
adb shell dumpsys activity | grep "mFocusedActivity"
方法二:使用Activity Tracer工具
本文只是将看到的文章进行了学习整理记录,详细的还请查看原文。
原文:http://mp.weixin.qq.com/s/OQRHEufCUXBA3d3DMZXMKQ
标签:man 管理机 定义 权限管理 访问 trace 文件中 界面 厂商
原文地址:http://www.cnblogs.com/zhangmiao14/p/7427855.html