序言:
Android6.0已经出来很久了,为什么还要写这么一篇文章呢。主要是网上很少能看到符合项目要求的供初学者使用的例子。另一方面,也是作为个人学习的一个记录吧。
正文:
首先,我将整个权限申请的流程做个简单的梳理:
第一步:判断是否需要申请该权限
第二步:在申请之前,判断是否需要进行弹窗说明
第三步:申请权限
第四步:处理权限申请的结果
判断是否需要申请该权限
(1):判断是否6.0以上
//低于6.0 不需要申请权限
if (Build.VERSION.SDK_INT < 23
|| this.getApplicationInfo().targetSdkVersion < 23) {
//低于6.0,不需要申请,做自己的逻辑处理
}
(2)调用Android api判断 ,可以自己写成一个方法
/**
* 判断是否具备该权限
* @param p:需要判断的权限
* @return boolean:true 表示具备该权限 false:不具备该权限
*
* */
public boolean hasPermission(String p) {
return ActivityCompat.checkSelfPermission(this, p) == PackageManager.PERMISSION_GRANTED;
}
判断是否需要进行弹窗说明
这里可以写成一个方法
/**
* 判断是否需要弹窗说明
* @param p:需要判断的权限
* @return boolean:true 表示需要弹窗 false:不需要弹窗 *
* */
public boolean isNeedNotice(String p) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,p)) {
//需要提示
return true;
}
//不用提示
return false;
}
申请权限
调用系统方法,进行权限申请
//p:需要申请的权限
ActivityCompat.requestPermissions(this, new String[]{p}, requestCode);
处理权限申请的结果
实现onRequestPermissionsResult方法,判断权限申请的结果
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults){
if(REQUEST_PHONE_PERMISSION_CODE == requestCode){
//判断是我们设置的code,再判断是否申请成功
if(grantResults.length >0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
//申请成功,做自己的逻辑处理
}else{
//用户拒绝了权限,判断是否点了 ”不在提示“
if(!isNeedNotice(permissions[0])){
//点了 ”不再提示“ 做自己的逻辑处理,
//可以让用户到应用界面打开,也可以做其他逻辑处理
}else{
//没有点不再提示,重新申请
}
}
}
}
普通的逻辑到这里就结束了,如果代码里面写了 让用户到设置界面去打开权限,还有两个地方需要注意
1:需要处理onActivityResult方法
2:需要处理Activity被系统回收的情况
跳转出去后,当前Activity被系统回收,在用户操作完 ,系统会自动重启当前Activity,我们需要记录申请的权限以及是否是被回收的状态
private boolean isSavedInstanceState = false; //判断是否被重启
@Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
//p:我们正在申请的权限
//系统回收Activity会触发这个方法,因此,在这个方法保存状态
outState.putString("permission", p);
}
然后 :在onCreate方法,去判断是否是被回收过的状态
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
if(savedInstanceState != null) {
String cp = savedInstanceState.getString("permission",null);
if(!TextUtils.isEmpty(currentRequestPermission)) {
// cp不为空 说明是被回收过了
isSavedInstanceState = true;
//判断是否需要重新申请权限,
if(hasPermission(cp)) {
// 不需要再申请了 做自己的逻辑处理
}else{
//重新申请
}
}
}else{
//没有被意外回收,走正常逻辑
}
}
最后:处理onActivityReslut方法
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
if(isSavedInstanceState) {
//被回收 不再执行这个方法
isSavedInstanceState = false;
return ;
}
if(requestCode == REQUEST_PHONE_PERMISSION_CODE){
//确认是我们指定的跳转 判断是否授权
if (hasPermission(currentRequestPermission)) {
//已经授权,走自己的逻辑
}else{
// 仍然没有授权,可以重新发起权限申请或者做其他逻辑
}
}
}
到这里 ,整个权限申请就算是完成了,再附上一个跳转到应用设置界面的方法,给又需要的同学
/**
*
* 跳转到应用详情页面
*
* */
public void detailSetting(int rqCode) {
Intent intent = new Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, rqCode);
}
附上demo链接,因为最近vpn出了点问题,就传的百度网盘。
链接: https://pan.baidu.com/s/1atcDO4uml_egp-v18XLx6w
提取码: ydwv