1、动态权限获取机制
- Google在Android 6.0中引入了动态权限获取机制(Runtime Permission),使得Android的权限管理更加严格完善。
- 动态权限获取要求开发者在调用涉及相关权限的代码时,使用系统接口来动态得申请相应权限。定位SDK涉及权限即在此范畴中。
- 在未获取到定位权限情况下,定位SDK获取到的定位依据(基站、WiFi)均为空值,因此无法有效定位,定位服务会返回错误码167。
2、动态权限机制的开启
因此需要在项目配置文件中修改您的targetSdkVersion配置。
对于Eclipse环境,请更改AndroidManifest.xml中代码;AndroidStudio环境,请更改build.gradle中的代码。
3、关于android:protectionLevel:权限的等级
normal 低风险权限,只要申请了就可以使用(在AndroidManifest.xml中添加<uses-permission>标签),安装时不需要用户确认;
dangerous 高风险权限,安装时需要用户的确认才可使用;
signature 只有当申请权限的应用程序的数字签名与声明此权限的应用程序的数字签名相同时(如果是申请系统权限,则需要与系统签名相同),才能将权限授给它;
signatureOrSystem 签名相同,或者申请权限的应用为系统应用(在system image中),与signature类似,只是增加了rom中自带的app的声明 ,尽量不要使用该选项,因为signature已经适合绝大部分的情况。
对于普通和危险级别的权限,我们称之为低级权限,应用申请即授予。其他两级权限,我们称之为高级权限或系统权限。当应用试图在没有权限的情况下做受限操作,应用将被系统杀掉以警示。系统应用可以使用任何权限。权限的声明者可无条件使用该权限。
4、动态权限代码样例
在Android 6.0系统中,需要动态获取的权限涉及到:
- 获取手机状态:
Manifest.permission.READ_PHONE_STATE;
- 获取位置信息:
Manifest.permission.ACCESS_COARSE_LOCATION;
Manifest.permission.ACCESS_FINE_LOCATION;
- 读写SD卡:
Manifest.permission.READ_EXTERNAL_STORAGE;
Manifest.permission.WRITE_EXTERNAL_STORAGE;
5、获取权限使用API
- 第一步,利用Context.checkSelfPermission接口,触发系统弹窗
- int android.content.Context.checkSelfPermission(String permission),此接口会触发系统弹窗,用户选择后触发Activity中的回调函数,以READ_PHONE_STATE为例:
private static final int BAIDU_READ_PHONE_STATE =100;
- 第二步,定义权限获取码,申请权限
- 自定义一个权限获取码,用于回调函数中做对应处理,调用checkSelfPermission接口申请权限:
if(mContext.checkSelfPermission(Manifest.permission.READ_PHONE_STATE)!=PackageManager.PERMISSION_GRANTED) {
// 申请一个(或多个)权限,并提供用于回调返回的获取码(用户定义)
requestPermissions( new String[]{ Manifest.permission.READ_PHONE_STATE },BAIDU_READ_PHONE_STATE );
}
- 第三步,处理回调函数
- 在Activity的onRequestPermissionResult回调函数中做处理:
public void onRequestPermissionsResult(int requestCode,String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions,grantResults);
switch(requestCode) {
//requestCode即所声明的权限获取码,在checkSelfPermission时传入
case 1:
BAIDU_READ_PHONE_STATE:
if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//获取到权限,做相应处理
//调用定位SDK应确保相关权限均被授权,否则会引起定位失败
} else{
//没有获取到权限,做特殊处理
}
break;
default:
break;
}
}
6、一个权限获取方式
7、多个权限获取方式
8、一个和多个权限获取唯一不同的地方需要在回调中分别处理
9、动态权限获取的封装
- 把权限的申请放在BaseActivity中,然后各个子Activity去继承BaseActivity。
- 定义权限回调接口
- 申请权限的方法必须传递一个Activity对象,工具类中需要一个Activity管理器获取最上层的Activity.
Demo地址如下:
AndroidPermission Demo 地址链接