Android Permission
2018-11-15 本文已影响0人
Matt_Kill
从 Android 6.0(API 级别 23)开始,用户开始在应用运行时向其授予权限,首先在清单文件中列出我们所需要的权限,如果是正常权限,系统会自动授予,如果是危险权限,则需要在运行时得到用户的批准。
检查权限与请求权限都很容易理解,请自行百度,这里主要要强调的是shouldShowRequestPermissionRationale的用法,以及如何使用它来解决当用户点击了“不再询问”之后要如何处理。
shouldShowRequestPermissionRationale使用:
- 当用户第一次请求权限时,返回false.
- 当用户点击拒绝,之后再次发起权限请求时,返回true.
可用于向用户详细说明使用权限的理由。 - 当用户点击拒绝+不再询问之后,返回false,并在之后发起请求,会一直返回true.
在客户点击了不再询问之后,请求权限的弹出框就不会再出现,所以当监测到用户已经点击了不再询问,可跳转到设置里,让客户在那里打开权限。
直接上代码:
/**
* 检测是否已经打开所需权限,如果是,执行初始化代码,如果否,请求权限。
*/
private void initPermission(){
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestCameraPermission();
return;
}
init();
}
private void init(){
L.logI("*****************init");
}
/**
* 请求权限,这里第一次使用到shouldShowRequestPermissionRationale。
* 用于当用户点击拒绝,之后再次发起权限请求时,向用户详细解释使用该权限的理由
*/
private void requestPermission() {
String neededPermission="";
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)){
neededPermission+="CAMERA";
}
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)){
neededPermission+=",STORAGE";
}
if (!neededPermission.equals("")) {
showPermissionDialog("****************We need "+neededPermission+" permission.****************", new ConfirmCallback() {
@Override
public void confirm(DialogInterface dialog, int which) {
requestCameraStoragePermission();
}
},null);
} else {
requestCameraStoragePermission();
}
}
private void requestCameraStoragePermission(){
ActivityCompat.requestPermissions(PermissionActivity.this,new String[]{Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE}
, REQUEST_CAMERA_PERMISSION);
}
/**
* 请求权限后的返回结果,这里第二次使用到shouldShowRequestPermissionRationale。
* 用于处理当用户点击拒绝+不再询问的情形
* @param requestCode
* @param permissions 请求的所有权限
* @param grantResults 请求的所胡权限相应的结果。
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CAMERA_PERMISSION) {
boolean isGranted=true;
String denyForever="";
for(int i=0;i<permissions.length;i++){
if(grantResults[i]==PackageManager.PERMISSION_DENIED){
isGranted=false;
if(permissions[i].equals(Manifest.permission.CAMERA)){
boolean shouldRequest = ActivityCompat.shouldShowRequestPermissionRationale(PermissionActivity.this, Manifest.permission.CAMERA);
if(!shouldRequest){
//用户将camera权限设置成了不再询问
denyForever+="CAMERA";
}
}
if(permissions[i].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)){
boolean shouldRequest = ActivityCompat.shouldShowRequestPermissionRationale(PermissionActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if(!shouldRequest){
//用户将STORAGE权限设置成了不再询问
denyForever+=",STORAGE";
}
}
}
}
if(!denyForever.equals("")){
//权限请求被设置为"不再询问",引导用户至设置页手动授权
showPermissionDialog("用户选择了不再询问"+denyForever+"权限,如果您想继续使用本功能,请到设置界面设置允许权限。", new ConfirmCallback() {
@Override
public void confirm(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getApplicationContext().getPackageName(), null);
intent.setData(uri);
startActivity(intent);
}
},null);
}
if(isGranted){
//全部权限通过,进行必要的初始化
init();
}
}
}
//------------------------以下是提示框跟相应的回调接口。------------------------------------
private void showPermissionDialog(String msg, final ConfirmCallback confirmCallback, final CancelCallback cancelCallback){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("PERMISSION")
.setMessage(msg)
.setPositiveButton("CONFIRM", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
if(confirmCallback!=null){
confirmCallback.confirm(dialog,which);
}
}
})
.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
if(cancelCallback!=null){
cancelCallback.cancel(dialog,which);
}
}
})
.create()
.show();
}
public interface ConfirmCallback{
public void confirm(DialogInterface dialog, int which);
}
public interface CancelCallback{
public void cancel(DialogInterface dialog, int which);
}