基本资料
最近国外版本需要升级到6.0系统,因此游戏使用到的敏感权限必须要申请用户确认,才可以正常使用,相关的需求很简单,用户启动游戏,有敏感权限未获得授权,先请求用户授权,授权成功,继续游戏,授权失败,关闭游戏(暂时不考虑再未获得敏感权限授权的情况下,继续游戏的情况)。
这里有个误会,由于google给出的接口叫requestPermissions,所以被顺便翻译成了“请求权限”,其实应该翻译成“确认授予权限”比较合适,应用需要的权限还是在应用启动的时候已经列给系统了,只是对于敏感权限,6.0系统多了一步要求用户确认的步骤,仅此而已。
研究了安卓的动态相关的文档,总结下来有以下几点内容:
1.动态权限获取是从android-23版本出现的,之前的版本不支持动态权限。
2.因为android的版本升级向下兼容,所以只是在6.0的系统上多加了一步用户权限确认。
3.如果当前编译系统的SDK版本低于android-23,可以使用android-support-v4.jar来调用权限申请接口。
调用接口
检查权限接口:
android.content.ContextWrapper.checkSelfPermission(String permission)
权限请求接口:
void android.app.Activity.requestPermissions(String[] permissions, int requestCode)
权限回调接口:
void android.app.Activity.onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
对应的android-support-v4接口:
ContextCompat.checkSelfPermission()
ActivityCompat.requestPermissions()
...
此外,还有一个接口,用于检查权限是否被系统关闭,或者已经勾选默认不授权,暂时用不上,接口如下:
shouldShowRequestPermissionRationale()
具体步骤
启动应用先检查是否已经全部授权(安装应用授权确认)
public List<String> getRequestAuthorityList() {
List<String> list = getDynamicAppAuthorityList();
List<String> permissionsNeeded = new ArrayList<String>();
for (int i = 0; i < list.size(); i++) {
String permission = list.get(i);
if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
permissionsNeeded.add(permission);
}
}
return permissionsNeeded;
}
对于需要请求的权限,调用请求权限的接口,会自动弹出权限授予框
List<String> permissionsNeeded = getRequestAuthorityList();
if (permissionsNeeded.size() <= 0) {
} else {
requestPermissions(permissionsNeeded.toArray(new String[permissionsNeeded.size()]) , REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
}
基本流程很简单,关键点注意:
1.编译的工程sdk的版本。
2.因为仅是权限授予的确认,所以在AndroidMainfest下所有需要用到的权限都要添加,并不是动态确认的权限就不用在Mainfest列出来。
比如相机权限是敏感权限,所以对于6.0系统,既需要再Mainfest里边添加,又需要动态确认,而对于低于6.0的系统,因为一起动应用,权限许可就给予了应用,所以也就不需要权限授予了,这个也是google为了向下兼容的一种设计。
特别注意
整套流程处理下来,感觉比较坑爹的就是这个名词翻译,很多人自然理解,既然动态授予了,就不需要在mainfest添加权限了,因此会报各种异常退出的问题,当调用requestPermissions请求授予一个没有在AndroidMainfest列出的权限,应用就会判定非法,自动关闭,而且没有任何日志!!!
╮(╯_╰)╭