1 原理
在安卓6.0以后单纯的再Manifest中申请权限不再有效,系统要求必须动态申请,并获取用户确认
2 效果
3 Demo
DynamicPermissionRequestActivity
4 代码实现
- Manifest中配置权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.SEND_SMS" />
- 进入应用时查询,如果没有动态申请,弹出申请框;
用户如果禁止了,必须要这个权限的,弹出提示框,让用户在系统设置中去设置
Utils工具类PermissionUtils:
public class PermissionUtils {
public final static int CODE_PERMISSION_REQUEST = 99;
public final static int CODE_PERMISSION_SETTING = 100;
public final static int PERMISSION_DENIED = -1;
public final static int PERMISSION_GRANTED = 0;
public final static int PERMISSION_SHOW_REQUEST = 1;
/**
* 弹出对话框请求权限
*/
public static void requestPermissions(Activity activity, String[] permissions, int requestCode){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
ActivityCompat.requestPermissions(activity, permissions, requestCode);
}
}
/**
* 返回缺失的权限
* @return 返回缺少的权限,null 意味着没有缺少权限
*/
public static String[] getDeniedPermissions(Context context, String[] permissions){
if (Build.VERSION.SDK_INT >= 23) {
ArrayList<String> deniedPermissionList = new ArrayList<>();
for(String permission : permissions){
if(ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED){
deniedPermissionList.add(permission);
}
}
int size = deniedPermissionList.size();
if(size > 0){
return deniedPermissionList.toArray(new String[deniedPermissionList.size()]);
}
}
return null;
}
public static String getPermissionDes(String[] permissions){
Set<String> set = new LinkedHashSet<>();
for(int i = 0; i < permissions.length; i++){
if(!TextUtils.isEmpty(permissions[i])){
if(permissions[i].equals(Manifest.permission.READ_PHONE_STATE)){
set.add("读取手机状态");
}if(permissions[i].equals(Manifest.permission.SEND_SMS)){
set.add("发送短信");
}else if(permissions[i].equals(Manifest.permission.RECORD_AUDIO)) {
set.add("录音");
}else if(permissions[i].equals(Manifest.permission.MODIFY_AUDIO_SETTINGS)) {
set.add("录音");
} else if(permissions[i].equals(Manifest.permission.CAMERA)) {
set.add("拍照");
}else if(permissions[i].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
set.add("访问照片");
}else if(permissions[i].equals(Manifest.permission.READ_EXTERNAL_STORAGE)) {
set.add("访问照片");
}else if(permissions[i].equals(Manifest.permission.ACCESS_COARSE_LOCATION)) {
set.add("读取位置信息");
}else if(permissions[i].equals(Manifest.permission.ACCESS_FINE_LOCATION)) {
set.add("读取位置信息");
}
}
}
if(set != null && !set.isEmpty()){
StringBuilder res = new StringBuilder();
Iterator<String> it = set.iterator();
while(it.hasNext())
res.append(it.next()).append("、");
return res.substring(0, res.length() - 1).toString();
}
return "";
}
}
Activity中查询并申请,弹出确认框(MyDialog就是个普通封装)
public class DynamicPermissionRequestActivity extends AppCompatActivity {
private String[] permissions = new String[]{Manifest.permission.READ_PHONE_STATE, Manifest.permission.SEND_SMS, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dynamic_permission);
if(checkPermission()){
init();
}
}
private void init() {
//请求权限成功后进行应用的初始化操作
}
private boolean checkPermission(){
String[] perms = PermissionUtils.getDeniedPermissions(this, permissions);
if(perms == null || perms.length == 0){
return true;
}else {
PermissionUtils.requestPermissions(this, permissions, PermissionUtils.CODE_PERMISSION_REQUEST);
return false;
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case PermissionUtils.CODE_PERMISSION_REQUEST:
int permissionVal = PermissionUtils.PERMISSION_GRANTED;
for(int i = 0; i < grantResults.length; i++){
if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
permissionVal = PermissionUtils.PERMISSION_DENIED;
if(!ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i])){
permissionVal = PermissionUtils.PERMISSION_SHOW_REQUEST;
break;
}
}
}
if(permissionVal == PermissionUtils.PERMISSION_SHOW_REQUEST){
new MyDialog.Builder(this)
.setTitle("提示")
.setMessage("为了确保功能服务的正常使用,我们需要您开启"+
PermissionUtils.getPermissionDes(permissions) + "权限,请在设置后重试。", Gravity.LEFT)
.setPositiveButton("去设置", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, PermissionUtils.CODE_PERMISSION_SETTING);
dialog.dismiss();
}
})
.setCancelable(false)
.setCanceledOnTouchOutside(false)
.create().show();
}else if(permissionVal == PermissionUtils.PERMISSION_DENIED){
PermissionUtils.requestPermissions(this, permissions, PermissionUtils.CODE_PERMISSION_REQUEST);
}else {
init();
}
break;
case RESULT_CANCELED:
break;
default:
break;
}
}
}