Android权限篇 Android 6.0动态权限申请
Posted 彭老希
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android权限篇 Android 6.0动态权限申请相关的知识,希望对你有一定的参考价值。
一、前言
android6.0之前只需在AndroidManifest.xml文件写明权限即可
Android 6.0 版本之后【SDK >= 23】,一些隐私权限需要动态申请,而且在用户同意授权之后App才能拥有该权限。
二、处理思路
在每个Activity界面显示前把该界面所需的权限全部申请允许了,再进入正常的流程。如果有权限未被允许,开发者可以在接口中自己处理,可以直接提示并退出,或者提示权限的作用后重新发起权限申请。或者提供浏览的界面,Android10之后,谷歌官方不允许用户拒绝权限后,应用被退出
三、官方API - 监测权限是否被授予
1、checkSelfPermission检查是否已被授予
2、requestPermissions申请权限
3、自动回调onRequestPermissionsResult 根据请求权限结果
4、shouldShowRequestPermissionRationale 应该显示请求许可理由
ContextCompat.checkSelfPermission(): 检查权限是否已经授权
ActivityCompat.requestPermissions():动态申请权限,并弹出对话框
onRequestPermissionsResult():在activity里面重写该方法该方法是权限申请之后的回调方法。
shouldShowRequestPermissionRationale() :当应用首次
申请权限时,如果用户点击拒绝
,下次再申请权限
,Android允许你提示用户,你为什么需要这个权限,更好引导用户是否授权,其中在Android原生系统中:
如果应用之前请求
过此权限但用户拒绝
了请求,此方法将返回true
;
如果用户在过去拒绝
了权限请求且在权限请求系统对话框中选择了 Don't ask again
选项将返回 false
;
如果第一次申请
权限也返回false
;
如果设备规范禁止应用具有该权限
,此方法也会返回 false
,返回false则不在显示提示对话框
,返回true则会显示对话框
。
四、运行效果图
(1) 初次进入界面,申请所需的全部权限
(2)申请单个权限
(3)拒绝授予权限,且勾选了不再提示
(4)拒绝权限并不再提示,告知用户该权限的作用
(5)提示用户开启权限
(6)点击“立即开启”跳到权限设置页面
五、实战使用
public class MainActivity extends AppCompatActivity implements View.OnClickListener, PermissionInterface {
private int requestCode = 10000;
private Button btn_phone;//打电话
private Button btn_camera;//打开相机
private PermissionHelper mPermissionHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_phone = findViewById(R.id.btn_phone);
btn_camera = findViewById(R.id.btn_camera);
btn_phone.setOnClickListener(this);
btn_camera.setOnClickListener(this);
//初始化
mPermissionHelper = new PermissionHelper(this, this);
//发起权限申请
mPermissionHelper.requestPermissions(new String[]{Manifest.permission.CALL_PHONE,
Manifest.permission.CAMERA});
}
//点击监听
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_phone://打电话
requestCode = 0;
mPermissionHelper.requestPermissions(new String[]{Manifest.permission.CALL_PHONE});
break;
case R.id.btn_camera://打开相机
requestCode = 1;
mPermissionHelper.requestPermissions(new String[]{Manifest.permission.CAMERA});
break;
}
}
/**
* 可设置请求权限请求码
*/
@Override
public int getPermissionsRequestCode() {
//设置权限请求requestCode,只有不跟onRequestPermissionsResult方法中的其他请求码冲突即可。
return requestCode;
}
/**
* 请求权限成功回调
*/
@Override
public void requestPermissionsSuccess() {
//权限请求用户已经全部允许
if (requestCode == 10000) {
} else if (requestCode == 0) {
Intent intent = new Intent(Intent.ACTION_DIAL);
Uri data = Uri.parse("tel:" + 10086);
intent.setData(data);
startActivity(intent);
} else if (requestCode == 1) {
Intent intent1 = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent1, 0);
}
}
/**
* 请求权限失败回调
*/
@TargetApi(Build.VERSION_CODES.M)
@Override
public void requestPermissionsFail() {
//权限请求不被用户允许。可以提示并退出或者提示权限的用途并重新发起权限申请。
if (requestCode==10000){
}else if (requestCode == 0) {
//如果拒绝授予权限,且勾选了再也不提醒
if (!shouldShowRequestPermissionRationale(Manifest.permission.CALL_PHONE)) {
DialogUtil.showSelectDialog(this, "说明", "需要使用电话权限,进行电话测试", "取消", "确定", new DialogUtil.DialogClickListener() {
@Override
public void confirm() {
//用于在用户勾选“不再提示”并且拒绝时,再次提示用户
DialogUtil.showSelectDialog(MainActivity.this, "电话权限不可用", "请在-应用设置-权限中,允许APP使用电话权限来测试", "取消", "立即开启", new DialogUtil.DialogClickListener() {
@Override
public void confirm() {
goToAppSetting();
}
@Override
public void cancel() {
}
}).show();
}
@Override
public void cancel() {
}
}).show();
} else {
DialogUtil.showSelectDialog(MainActivity.this, "电话权限不可用", "请在-应用设置-权限中,允许APP使用电话权限来测试", "取消", "立即开启", new DialogUtil.DialogClickListener() {
@Override
public void confirm() {
goToAppSetting();
}
@Override
public void cancel() {
}
}).show();
}
}else if (requestCode==1){
//如果拒绝授予权限,且勾选了再也不提醒
if (!shouldShowRequestPermissionRationale(Manifest.permission.CALL_PHONE)) {
DialogUtil.showSelectDialog(this, "说明", "需要使用相机权限,进行相机测试", "取消", "确定", new DialogUtil.DialogClickListener() {
@Override
public void confirm() {
//用于在用户勾选“不再提示”并且拒绝时,再次提示用户
DialogUtil.showSelectDialog(MainActivity.this, "相机权限不可用", "请在-应用设置-权限中,允许APP使用相机权限来测试", "取消", "立即开启", new DialogUtil.DialogClickListener() {
@Override
public void confirm() {
goToAppSetting();
}
@Override
public void cancel() {
}
}).show();
}
@Override
public void cancel() {
}
}).show();
} else {
DialogUtil.showSelectDialog(MainActivity.this, "相机权限不可用", "请在-应用设置-权限中,允许APP使用相机权限来测试", "取消", "立即开启", new DialogUtil.DialogClickListener() {
@Override
public void confirm() {
goToAppSetting();
}
@Override
public void cancel() {
}
}).show();
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (mPermissionHelper.requestPermissionsResult(requestCode, permissions, grantResults)) {
//权限请求结果,并已经处理了该回调
return;
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
/**
* 打开Setting
*/
private void goToAppSetting() {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, 123);
}
}
六、Dialog工具类
public class DialogUtil {
/**
* 创建一个选择对话框
*
* @param context
* @param pContent 提示消息
* @param dialogClickListener 点击监听
* @return
*/
public static Dialog showSelectDialog(Context context, String title, String pContent, String pLeftBtnStr,
String pRightBtnStr,
final DialogClickListener dialogClickListener) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
AlertDialog dialog = builder.setTitle(title)
.setMessage(pContent)
.setPositiveButton(pRightBtnStr, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialogClickListener.confirm();
dialog.dismiss();
}
})
.setNegativeButton(pLeftBtnStr, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialogClickListener.cancel();
dialog.dismiss();
// return;
}
})
.create();
return dialog;
}
public interface DialogClickListener {
public abstract void confirm();
public abstract void cancel();
}
}
七、权限的接口类
/**
* 权限请求接口
*/
public interface PermissionInterface {
/**
* 可得到请求权限请求码
*/
int getPermissionsRequestCode();
/**
* 请求权限成功回调
*/
void requestPermissionsSuccess();
/**
* 请求权限失败回调
*/
void requestPermissionsFail();
}
八、权限的帮助类
/**
* 动态权限帮助类
*/
public class PermissionHelper {
private Activity mActivity;
private PermissionInterface mPermissionInterface;
public PermissionHelper(@NonNull Activity activity, @NonNull PermissionInterface permissionInterface) {
mActivity = activity;
mPermissionInterface = permissionInterface;
}
/**
* 开始请求权限。
* 方法内部已经对Android M 或以上版本进行了判断,外部使用不再需要重复判断。
* 如果设备还不是M或以上版本,则也会回调到requestPermissionsSuccess方法。
*/
public void requestPermissions(String[] permissions) {
String[] deniedPermissions = PermissionUtil.getDeniedPermissions(mActivity, permissions);
if (deniedPermissions != null && deniedPermissions.length > 0) {
PermissionUtil.requestPermissions(mActivity, deniedPermissions, mPermissionInterface.getPermissionsRequestCode());
} else {
mPermissionInterface.requestPermissionsSuccess();
}
}
/**
* 在Activity中的onRequestPermissionsResult中调用
* @param requestCode
* @param permissions
* @param grantResults
* @return true 代表对该requestCode感兴趣,并已经处理掉了。false 对该requestCode不感兴趣,不处理。
*/
public boolean requestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == mPermissionInterface.getPermissionsRequestCode()) {
boolean isAllGranted = true;//是否全部权限已授权
for(int result : grantResults){
if(result == PackageManager.PERMISSION_DENIED){
isAllGranted = false;
break;
}
}
if(isAllGranted){
//已全部授权
mPermissionInterface.requestPermissionsSuccess();
}else{
//权限有缺失
mPermissionInterface.requestPermissionsFail();
}
return true;
}
return false;
}
}
九、权限的工具类
/**
* 动态权限工具类
*/
public class PermissionUtil {
/**
* 弹出对话框请求权限
* @param activity
* @param permissions
* @param requestCode
*/
public static void requestPermissions(Activity activity, String[] permissions, int requestCode) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
activity.requestPermissions(permissions, requestCode);
}
}
/**
* 返回缺失的权限
* @param context
* @param permissions
* @return 返回缺少的权限,null 意味着没有缺少权限
*/
public static String[] getDeniedPermissions(Context context, String[] permissions) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
ArrayList<String> deniedPermissionList = new ArrayList<>();
for (String permission : permissions) {
if (context.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
deniedPermissionList.add(permission);
}
}
int size = deniedPermissionList.size();
if (size > 0) {
return deniedPermissionList.toArray(new String[deniedPermissionList.size()]);
}
}
return null;
}
}
以上是关于Android权限篇 Android 6.0动态权限申请的主要内容,如果未能解决你的问题,请参考以下文章