版权声明:本文为博主项目中经验总结,著文备份,欢迎补充交流! https://blog.csdn.net/u013806583/article/details/62897431
写在前面:对于新版本的Android,部分权限必须手动向用户发起请求并获得允许后才能使用。关于这一部分的基础知识,这里就不详述。大家可以自行百度去获取。
相关知识:
【举例】Android自定义Dialog——做出“确定/取消”的选择
还是一贯的风格,直接上代码。
1. 与旧版本一样,所有需要的权限需要手动声明
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
在这些权限中,CAMERA 、RECORD_AUDIO 和 WRITE_EXTERNAL_STORAGE 需要动态申请。
2. 动态申请权限
//一个整形常量
public static final int MY_PERMISSIONS_REQUEST = 3000;
//定义一个list,用于存储需要申请的权限
ArrayList<String> permissionList = new ArrayList<String>();
permissionList.add(Manifest.permission.CAMERA);
permissionList.add(Manifest.permission.RECORD_AUDIO);
permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
//调用封装好的申请权限的方法
private void checkAndRequestPermissions(ArrayList<String> permissionList) {
ArrayList<String> list = new ArrayList<>(permissionList);
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String permission = it.next();
//检查权限是否已经申请
int hasPermission = ContextCompat.checkSelfPermission(this, permission);
if (hasPermission == PackageManager.PERMISSION_GRANTED) {
it.remove();
}
}
/**
*补充说明:ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO);
*对于原生Android,如果用户选择了“不再提示”,那么shouldShowRequestPermissionRationale就会为true。
*此时,用户可以弹出一个对话框,向用户解释为什么需要这项权限。
*对于一些深度定制的系统,如果用户选择了“不再提示”,那么shouldShowRequestPermissionRationale永远为false
*
*/
if (list.size() == 0) {
return;
}
String[] permissions = list.toArray(new String[0]);
//正式请求权限
ActivityCompat.requestPermissions(this, permissions, AppConstant.MY_PERMISSIONS_REQUEST);
}
3. 在本Activity中重写 onRequestPermissionsResult() 方法
//不管权限申请成功与否,都会调用该方法
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case AppConstant.MY_PERMISSIONS_REQUEST: {
// If request is cancelled, the result arrays are empty.
int length = grantResults.length;
boolean re_request = false;//标记位:如果需要重新授予权限,true;反之,false。
for (int i = 0; i < length; i++) {
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "权限授予成功:" + permissions[i]);
} else {
Log.e(TAG, "权限授予失败:" + permissions[i]);
re_request = true;
}
}
if (re_request) {
//弹出对话框,提示用户重新授予权限
//关于弹出自定义对话框,可以查看本博文开头的知识扩展
final YesOrNoDialog permissionDialog = new YesOrNoDialog(mContext);
permissionDialog.setCanceledOnTouchOutside(false);
permissionDialog.setMeesage("请授予相关权限,否则程序无法运行。\n\n点击确定,重新授予权限。\n点击取消,立即终止程序。\n");
permissionDialog.setCallback(new YesOrNoDialog.YesOrNoDialogCallback() {
@Override
public void onClickButton(YesOrNoDialog.ClickedButton button, String message) {
if (button == YesOrNoDialog.ClickedButton.POSITIVE) {
permissionDialog.dismiss();
//此处需要弹出手动修改权限的系统界面
checkAndRequestPermissions(permissionList);
} else if (button == YesOrNoDialog.ClickedButton.NEGATIVE) {
permissionDialog.dismiss();
TestActivity.this.finish();
}
}
});
permissionDialog.show();
}
break;
}
default:
break;
}
}
抓住Demo一只:
为了方便以后调用,本人已经将上述方法封装到了.aar文件中。以后调用时,只需要导入第三方包即可。
欢迎大家补充交流。