关于Android6.0运行时权限网上的教程很多,但大部分都不是很全,就是简单的申请一下,但是这样真的就完了吗?逻辑流程都走的通吗?
比如:
用户要是拒绝权限了呢?
要是拒绝权限了并且选择不再询问了呢?
要是用户选择一个权限后把剩下的就禁止掉了呢?
要是用户去系统选择权限的时候没有选择允许又回到咱们的程序当中了呢?
下面就解决这种问题:先来张图
有稍微的一点点丑,不过能看。
分析一下问题,用户禁止掉权限应该给个弹出框告诉用户没有授权有些功能是无法使用的,让用户去授权,用户禁止掉并且选上了不再提示的选项,那申请权限的时候就不会提示你同意授权了,这时我们就让用户跳转到系统权限页面去授权,这里实现的时候出现一个问题,弹框的时候弹了两下,应为有两个权限,返回了两次,这里只要把弹框的初始化放到外面去就好了,在权限的返回里面只做显示操作,下面是全部代码参考一下:
public class Main2Activity extends AppCompatActivity {
private static final int NOT_NOTICE = 2;//如果勾选了不再询问
private AlertDialog alertDialog;//禁止
private AlertDialog mDialog;//禁止了并且不再提示
//TODO 要申请的权限,这里我只放了读取文件和相机权限
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//禁止当前页面截屏
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
setContentView(R.layout.activity_main2);
initDiaLogs();//初始化弹框
requetPermission();//检测是否授权权限
}
/**
* 检测是否有相关权限没有去授权
* */
private void requetPermission() {
for (String permission : PERMISSIONS_STORAGE) {
if (ContextCompat.checkSelfPermission(this, permission) != PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, 1);
} else {
Toast.makeText(this, "您已经申请了权限!", Toast.LENGTH_SHORT).show();
}
}
}
/**
* 授权返回结果:
* 1.始终允许
* 2.禁止
* 3.禁止后不再提示
* */
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 1) {
for (int i = 0; i < permissions.length; i++) {
if (grantResults[i] == PERMISSION_GRANTED) {//选择了“始终允许”
Toast.makeText(this, "" + "权限" + permissions[i] + "申请成功", Toast.LENGTH_SHORT).show();
} else {
if (!ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i])) {//用户选择了禁止不再询问
//TODO 不要在这里初始化Dialog,会导致弹框弹两遍
if (mDialog != null && mDialog.isShowing()) {
mDialog.show();
}
} else {//选择禁止
if (alertDialog != null && !alertDialog.isShowing()) {
alertDialog.show();
}
}
}
}
}
}
/**
* 初始化弹框
* */
public void initDiaLogs() {
//禁止后不再提示的弹框
AlertDialog.Builder builder1 = new AlertDialog.Builder(Main2Activity.this);
builder1.setTitle("申请权限")
.setMessage("由于您未授权会导致部分功能无法使用")
.setPositiveButton("去授权", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if (mDialog != null && mDialog.isShowing()) {
mDialog.dismiss();
}
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);//注意就是"package",不用改成自己的包名
intent.setData(uri);
startActivityForResult(intent, NOT_NOTICE);
}
});
mDialog = builder1.create();
mDialog.setCanceledOnTouchOutside(false);
//禁止后的弹框
AlertDialog.Builder builder = new AlertDialog.Builder(Main2Activity.this);
builder.setTitle("申请权限")
.setMessage("由于您未授权会导致部分功能无法使用")
.setPositiveButton("去授权", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if (alertDialog != null && alertDialog.isShowing()) {
alertDialog.dismiss();
}
requetPermission();
}
});
alertDialog = builder.create();
alertDialog.setCanceledOnTouchOutside(false);
}
/**
* 从系统权限那里过来如果没有权限需要再次申请
* */
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == NOT_NOTICE) {
requetPermission();//由于不知道是否选择了允许所以需要再次判断
}
}
}
注释很全,这里我是直接放在类里使用了,你可以封装到工具类里面,或者是写到基类里面,都可以,留出权限的接口就行了