Android M发布有一段时间了,AndroidM在API上和代码中有不少改动,并不比AndroidL小。我们只能感谢Google又给android程序员带来的新的研究课题,相比之下Android 6.0 优化做的相对好的一个版本。
比如上表中ACCESS_FINE_LOCATION和ACCESS_COARSE_LOCATION是同属于LOCATION这个权限组,那么只要在申请ACCESS_FINE_LOCATION时,用户同意了,则系统自动会赋与ACCESS_COARSE_LOCATION的权限,不需要重新申请了。
(3)相对应 Android 6.0权限的Code Path :
Packages/apps/packageInstaller/src/com/android/packageInstaller/permisson/ //管理install 是权限
Framework/base/services/core/java/com/android/server/pm
(1)DefaultPermissionGrantPolicy.java 给某些预制的apk,给予权限,也可以撤销
(2)PermissionsState.java 管理权限的状态
(4)谷歌会在第一次开机时,默认打开一些特定的app 运行权限
具体代码在DefaultPermissionGranPolicy.java 中
(1)App Permission 管理对应的类
1.ManagePermissonsActivity
2.Manage_APP_Permission
3.AppPermissionsFragment
(2)ManagePermissionsActivity
Manage_Permission_Apps
PermissionAppsFragment
当你确定你需要申请权限(在检查权限方法返回PERMISSION_DENIED),你就可以调用申请权限的api。这个API支持批量申请,但是不建议一次申请太多,一般都是用到什么权限申请什么权限,因为用户需要对每一个权限做确认。
这个API也是在ActivityCompat中,他的函数签名是这样的。
(1)必须注意:每次访问时 都需要检查权限,用户可以自己撤销权限,而且不会通知app
Context.checkSelfPermission(READ_CONTACTS)==PackageMANAGER.PERMISSION_GRANTED{
//存在
}else{
//不存在 需要去申请
requestPermissions(new String[]{""},int)
}
2.用户响应权限请求后,系统会调用Activity.OnRequestPermissionResult(int requestCode ,String[] args,int [] resulst)
在app里面重写Call Back回调
swich(requestCode){
case READ_CONTACTS : //如果用户取消,permissions可能为null.
if(results[0]==PackageMANAGER.PERMISSION_GRANTED &&grantResults.length > 0){ //有权限
// 可以安全的调用api。
}else{
//拒绝
}
braak;
}
这个方法的参数中requestCode用于对应你之前requestPermission中的值,grantResults中的结果与permissions中的权限按顺序一一对应。grantResults的结果是PackageManager.PERMISSION_GRANTED或PackageManager.PERMISSION_DENIED之一
放在去申请权限前来弹个Toast
if (ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.READ_CONTACTS)) {
//做点什么,弹个Toast
}
(4)简单说下检查权限的流程
App->context.checkSelfPermission-->ContextImpl-->AMS>ActivityManagerNative.getDefault().checkSelfPermission--->
PMS->AppGlobals.getPackageManager().checkUidPermission(permisson,uid)--->PMS通过调用PermissionState.hasPermission判断某个uid是否
拥有某个permission
(5)简单说下请求权限的流程
App-->Activity.requestPermissions-->然后startActivityForResult-->然后调到PackageInstaller里面的GrantPermisslonsActivity,然后show给用户看,你需要不需要申请权限。如果同意->就调用PMS的grantRuntimePermission获取到权限并且调用setResuletAndFinsh函数CallBack返回给
App--app只要需要在Activity中重写OnRequestPermissionResult方法。
(2)Activity Intent的内容Action就是ACTION.Request_permissionS 数据包就是permission.name
6.Apk安装时会判断权限类型,对于dangerous的权限,会判定为runtimePermission,安装时不会对User赋予此权限.
其他类型的权限,则安装时赋予给所有的User
grantPermissionsLpw --获取权限的接口
-writeRuntimePermissionsForUserLpr 写入xml
对应的runtime-permissionos.xml 每个user维护一份
以上分析流程大家可以对照源码继续进行分析更深入,这里只是简单说下笔者的流程,可能还有地方说的不到位,或者错误,请大家留言,分享给大家,谢谢