这应该算是一个比较老的东西了,但还是想写一写。
Android6.0 动态权限,顾名思义,是在6.0及以上的Android生效的,6.0以下,及小米,魅族等自定义的权限获取,相对来说比较复杂,网上看了很多文章,有很多种不同的实现方法,但个人感觉都不太可靠,主要还是Android碎片化太严重。下面先附上几个解决6.0一下及国内相关厂商自定义权限获取的方案:
AppOpsManager权限检测适配:https://www.jianshu.com/p/352c4b9d320d
Android AppOpsManager权限判断:https://www.jianshu.com/p/5fa0a149926d?utm_campaign=maleskine&utm_content=note&utm_medium=pc_all_hots&utm_source=recommendation
Android 5.1 AppOps总结:https://blog.csdn.net/lewif/article/details/49124757
小米魅族系统遇到的6.0权限不弹窗问题:https://blog.csdn.net/hey_xiaoge/article/details/56017363
小米6.0动态权限特殊处理:https://blog.csdn.net/jsqfengbao/article/details/77185983
以上几个大概都是使用AppOpsManager来解决问题,后面还看到过一个说申请权限后通过判断是否跳转其他界面的方法,来确定是否有权限的方法,大家可以参考一下。下面还是介绍一下Google官方支持的6.0权限获取步骤吧。
在6.0以后的系统中,并不是所有权限都需要动态获取,只有在以下表中的危险权限才需要动态获取:
group:android.permission-group.CONTACTS
permission:android.permission.WRITE_CONTACTS
permission:android.permission.GET_ACCOUNTS
permission:android.permission.READ_CONTACTS
group:android.permission-group.PHONE
permission:android.permission.READ_CALL_LOG
permission:android.permission.READ_PHONE_STATE
permission:android.permission.CALL_PHONE
permission:android.permission.WRITE_CALL_LOG
permission:android.permission.USE_SIP
permission:android.permission.PROCESS_OUTGOING_CALLS
permission:com.android.voicemail.permission.ADD_VOICEMAIL
group:android.permission-group.CALENDAR
permission:android.permission.READ_CALENDAR
permission:android.permission.WRITE_CALENDAR
group:android.permission-group.CAMERA
permission:android.permission.CAMERA
group:android.permission-group.SENSORS
permission:android.permission.BODY_SENSORS
group:android.permission-group.LOCATION
permission:android.permission.ACCESS_FINE_LOCATION
permission:android.permission.ACCESS_COARSE_LOCATION
group:android.permission-group.STORAGE
permission:android.permission.READ_EXTERNAL_STORAGE
permission:android.permission.WRITE_EXTERNAL_STORAGE
group:android.permission-group.MICROPHONE
permission:android.permission.RECORD_AUDIO
group:android.permission-group.SMS
permission:android.permission.READ_SMS
permission:android.permission.RECEIVE_WAP_PUSH
permission:android.permission.RECEIVE_MMS
permission:android.permission.RECEIVE_SMS
permission:android.permission.SEND_SMS
permission:android.permission.READ_CELL_BROADCASTS
然后确保你的targetSdkVersion >= 23,然后在清单文件中如往常开发申请权限一样,申明你所需要的权限,包括危险权限和普通权限:
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.CAMERA" />
申请权限的代码,大致可以分为3步:
1、检查你需要的权限是否已经授权 ContextCompat.checkSelfPermission() :
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
...
} else {
...
}
}
2、动态申请权限 ActivityCompat.requestPermissions():
if(Build.VERSION.SDK_INT>=23){
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, 1);
} else {
...
}
}
requestPermissions()方法接收三个参数,分别是Activity的实例、需要申请权限的String数组、请求码,请求码在第三步会用到。
3、重写权限申请之后的回调方法 onRequestPermissionsResult() :
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
//grantResults数组与权限字符串数组对应,里面存放权限申请结果
if(grantResults[0]== PackageManager.PERMISSION_GRANTED){
Toast.makeText(MainActivity.this,"已授权",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(MainActivity.this,"拒绝授权",Toast.LENGTH_SHORT).show();
}
}
好了,到此基本的Android6.0 动态权限获取已经完成了,不算麻烦,最主要的还是看能不能解决碎片化导致的各个厂商不同的动态权限获取问题。