Android 6.0 全网最简单粗暴解决动态权限申请

Android 6.0 全网最简单粗暴解决动态权限申请_第1张图片
i----

前言

Android M 或以上的设备,在使用涉及隐私的安全权限时,需要动态申请,虽然不难,但写下来代码工作量也不少,而且几乎每个应用都需要用到。所以一直在探索一个要足够简单简洁优雅的处理方式,强迫症的精神指导我要拒绝一切繁琐。至于完不完美那就仁者见仁了。

一、思路:

如果在每个用到权限的地方去申请,有点繁琐,所以做法是直接在每个Activity界面显示前就把该界面所需的权限全部申请允许了,再进入正常的流程。如果有权限未被允许,开发者可以在接口中自己处理,可以直接提示并退出,或者提示权限的作用后重新发起权限申请。

二、危险权限列表:Dangerous Permissions

在Android M 或以上,以下权限需要动态申请的意思。

 group:android.permission-group.CONTACTS
 permission:android.permission.WRITE_CONTACTS
 permission:android.permission.GET_ACCOUNTS
 permission:android.permission.READ_CONTACTS

 group:android.permission-group.PHONE
 permission:android.permission.READ_CALL_LOG
 permission:android.permission.READ_PHONE_STATE
 permission:android.permission.CALL_PHONE
 permission:android.permission.WRITE_CALL_LOG
 permission:android.permission.USE_SIP
 permission:android.permission.PROCESS_OUTGOING_CALLS
 permission:com.android.voicemail.permission.ADD_VOICEMAIL

group:android.permission-group.CALENDAR
permission:android.permission.READ_CALENDAR
permission:android.permission.WRITE_CALENDAR

group:android.permission-group.CAMERA
permission:android.permission.CAMERA

group:android.permission-group.SENSORS
permission:android.permission.BODY_SENSORS

 group:android.permission-group.LOCATION
permission:android.permission.ACCESS_FINE_LOCATION
permission:android.permission.ACCESS_COARSE_LOCATION

group:android.permission-group.STORAGE
permission:android.permission.READ_EXTERNAL_STORAGE
permission:android.permission.WRITE_EXTERNAL_STORAGE

group:android.permission-group.MICROPHONE
permission:android.permission.RECORD_AUDIO

group:android.permission-group.SMS
permission:android.permission.READ_SMS
permission:android.permission.RECEIVE_WAP_PUSH
permission:android.permission.RECEIVE_MMS
permission:android.permission.RECEIVE_SMS
permission:android.permission.SEND_SMS
permission:android.permission.READ_CELL_BROADCASTS

三、使用方式:

先从Activity的使用开始。

public class MainActivity extends AppCompatActivity implements PermissionInterface {

private PermissionHelper mPermissionHelper;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //初始化并发起权限申请
    mPermissionHelper = new PermissionHelper(this, this);
    mPermissionHelper.requestPermissions();
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if(mPermissionHelper.requestPermissionsResult(requestCode, permissions, grantResults)){
        //权限请求结果,并已经处理了该回调
        return;
    }
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

@Override
public int getPermissionsRequestCode() {
    //设置权限请求requestCode,只有不跟onRequestPermissionsResult方法中的其他请求码冲突即可。
    return 10000;
}

@Override
public String[] getPermissions() {
    //设置该界面所需的全部权限
    return new String[]{
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_PHONE_STATE
    };
}

@Override
public void requestPermissionsSuccess() {
    //权限请求用户已经全部允许
    initViews();
}

@Override
public void requestPermissionsFail() {
    //权限请求不被用户允许。可以提示并退出或者提示权限的用途并重新发起权限申请。
    finish();
}

private void initViews(){
    //已经拥有所需权限,可以放心操作任何东西了
    
}

}

四、其中使用到的两个类和一个接口实现:

1、Activity需要实现的接口PermissionInterface.java

  /**
    * 权限请求接口
  * Created by dway on 2018/1/10.
  */
  public interface PermissionInterface {

/**
 * 可设置请求权限请求码
 */
int getPermissionsRequestCode();

/**
 * 设置需要请求的权限
 */
String[] getPermissions();

/**
 * 请求权限成功回调
 */
void requestPermissionsSuccess();

/**
 * 请求权限失败回调
 */
void requestPermissionsFail();

 }

2、工具类PermissionUtil.java

  /**
 * 动态权限工具类
 * Created by dway on 2017/1/13.
  */
 public class PermissionUtil {

/**
 * 判断是否有某个权限
 * @param context
 * @param permission
 * @return
 */
public static boolean hasPermission(Context context, String permission){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if(context.checkSelfPermission(permission)  != PackageManager.PERMISSION_GRANTED){
            return false;
        }
    }
    return true;
}

/**
 * 弹出对话框请求权限
 * @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 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;
}

  }

3、权限操作帮助类PermissionHelper.java

package com.dway.permission;

import android.app.Activity;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;

/**
 * 动态权限帮助类
  * Created by dway on 2018/1/10.
  */
 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[] deniedPermissions = PermissionUtil.getDeniedPermissions(mActivity, mPermissionInterface.getPermissions());
    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;
}

}

OK,完成。哪个Activity需要权限就实现接口,其他用帮助类就全部搞定。

你可能感兴趣的:(Android 6.0 全网最简单粗暴解决动态权限申请)