版权声明:本文为博主原创文章,转载请注明出处http://blog.csdn.net/u013132758。 https://blog.csdn.net/u013132758/article/details/53585894
前言
最近项目发现比较多的问题是关于Android 6.0的问题,APP安装之后,在Android 6.0之后的系统,点击直接奔溃打不开,这是为什么昵?这就是Android 6.0以上的系统引入运行时权限--默认所有涉及用户隐私的权限都被关闭,我们在AndroidManifest.xml中申请了,之后我们还得动态申请权限,不然我们每次安装完APP后,就得在“设置=》应用=》安装的APP”打开我们所需权限。
Android 6.0 需要动态申请的权限
Android M引入了运行时权限。所有权限仍然需要在AndroidManifest中声明。但是,当访问需要权限的API时,活动或片段必须验证权限已被授予或使用通过支持库的调用请求缺少的权限。Android 6.0需要单独申请的权限,共分为9组,每组只要有一个权限申请成功了,就默认整组权限都可以使用了。如下所示:
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
Android 6.0动态权限申请主要方法
Android6.0动态权限申请主要用到v4包中的下面三个函数:
- 权限通过ActivityCompat类中的checkselfpermission 方法。
- 权限请求是通过Activitycompat 类中的requestpermissions方法,在回调activitycompat收到响应。onrequestpermissionsresultcallback # onrequestpermissionsresult方法。
- 应用程序可以提供一个额外的合理的使用权限调用Activitycompat # shouldshowrequestpermissionrationale方法。Android原生系统中,如果第二次弹出权限申请的对话框,会出现“以后不再弹出”的提示框,如果用户勾选了,你再申请权限,则shouldShowRequestPermissionRationale返回true,意思是说要给用户一个 解释,告诉用户为什么要这个权限。然而,在实际开发中,需要注意的是,很多手机对原生系统做了修改,比如小米,小米4的6.0的shouldShowRequestPermissionRationale 就一直返回false,而且在申请权限时,如果用户选择了拒绝,则不会再弹出对话框了。。。。 所以说这个地方有坑,我的解决方法是,在回调里面处理,如果用户拒绝了这个权限,则打开本应用信息界面,由用户自己手动开启这个权限。
Android 6.0动态权限申请示例
上面讲了Android6.0动态权限申请的原理,下面我们来看一下如何申请动态权限。
1、首先在AndroidManifest.xml文件中申请所需要的权限。比如我要申请照相机的权限
2、在build.gradle文件中修改targetSdkVersion即APP所支持的sdk版本号大于等于23,我这里设置为23.因为23就是Android 6.0的sdk版本号。
3、开始申请权限,我们通过流程图来看一下
代码示例:
检查权限
//检查权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
//进入到这里代表没有权限.
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CODE);
} else {
showcamera();
}
我们还需要写回掉方法:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode){
case REQUEST_CODE:
if(grantResults.length >0 &&grantResults[0]==PackageManager.PERMISSION_GRANTED){
//用户同意授权
showcamera();
}else{
//用户拒绝授权
}
break;
}
}
如果拒绝提示用户
我们用上面的方法,如果申请时用户拒绝授予权限时,APP会崩溃,所以我们需要在用户拒绝授予权限后,提示用户我们为什么要这个权限。 //检查权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
//进入到这里代表没有权限.
if(ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.CAMERA)){
//已经禁止提示了
Toast.makeText(MainActivity.this, "您已禁止该权限,需要重新开启。", Toast.LENGTH_SHORT).show();
}else{
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CODE);
}