Android 6.0 动态权限申请简单简洁优雅的处理方式

    技术2022-07-11  90

    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<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;     }   } 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需要权限就实现接口,其他用帮助类就全部搞定。

    Processed: 0.011, SQL: 9