基本思路: 将 常用的权限的申请,封装到 基类中,baseactivity 和 basefragment 中 ,根据自己项目的情况 而定
第一步:定义几个常量 用于调用 ,权限请求码的对比:
以我的项目为例:
/** * 权限的请求相关 宏观定义值 */ public static final int CODE_CAMERA = 1100;//相机 public static final int CODE_READ_EXTERNAL_STORAGE = Constants.CODE_CAMERA + 1;//读写 public static final int CODE_GET_LOCATION = Constants.CODE_READ_EXTERNAL_STORAGE + 1;//定位
第二步:在配置文件中 ,添加我们所需要获取的权限 根据自己所需的权限进行添加
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
第三步: 在封装的基类中操作: 此处以activity的基类 为例子
1).创建可以被子类activity调用的 方法 用于判断 是否有某种权限
/** * 判断是否拥有权限 * * @param permissions * @return */ public boolean hasPermission(String... permissions) { for (String permission : permissions) { if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) return false; } return true; }
2). 在基类中定义 可以被子类调用的 请求权限的方法
/** * 请求权限 */ protected void requestPermission(int code, String... permissions) { ActivityCompat.requestPermissions(this, permissions, code); App.showToast("如果拒绝授权,会导致应用无法正常使用"); }
3).请求权限的回调 ,可以根据自己的项目需要 ,设置 权限请求 返回码 的判断 ,比如 常见的 定位,相机 ,读写等
此处 需要注意的点,就是 返回码 对比的值 要用 我们刚才 第一步 ,宏定义的常量
/** * 请求权限的回调 * * @param requestCode * @param permissions * @param grantResults */ @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode) { case Constants.CODE_CAMERA: //例子:请求相机的回调 if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 这里写你需要的业务逻辑 doYourNeedDoCarme(); } else { /*App.showToast("您拒绝授权,会导致应用无法正常使用,可以在系统设置中重新开启权限");*/ setPerssion("相机"); } break; case Constants.CODE_READ_EXTERNAL_STORAGE://读写权限的回调 //另一个权限的回调 if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 这里写你需要的业务逻辑 doYourNeedDoWriteAndRead(); } else { /*App.showToast("您拒绝授权,会导致应用无法正常使用,可以在系统设置中重新开启权限");*/ setPerssion("读写"); } break; case Constants.CODE_GET_LOCATION://定位权限的回调 //另一个权限的回调 if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 这里写你需要的业务逻辑 doYourNeedDoGetLocation(); } else { /*App.showToast("您拒绝授权,会导致应用无法正常使用,可以在系统设置中重新开启权限");*/ setPerssion("定位"); } break; } }
4). 获取权限之后的逻辑操作 ,既然封装在基类里面 ,因为针对不同的页面,所进行的逻辑操作 肯定不一样,所以 ,就写一个方法 ,在每个需要进行权限请求的页面,按照自己的业务需求 ,业务逻辑 去实现 ,去重写这个方法 就可以了
//子类重写后实现具体调用相机的业务逻辑 public void doYourNeedDoCarme() { //留给子类重写,这里空白就好 } //子类重写后实现获取读写权限之后业务逻辑 public void doYourNeedDoWriteAndRead() { //留给子类重写,这里空白就好 } //子类重写后实现具体获取定位之后的业务逻辑 public void doYourNeedDoGetLocation() { //留给子类重写,这里空白就好 }
5).这一步 ,可以按照自己的需求 ,可写可不写 ,此处是一个弹框 ,在拒绝的时候 ,提示用户 去设置 权限
/** * 开启权限的弹框 */ public void setPerssion(final String string) { final MyPerssionDialog myDialog = new MyPerssionDialog(this, "该功能需要开启" + string + "权限"); myDialog.show();//展示 myDialog.positive.setOnClickListener(new View.OnClickListener() {//设置 @Override public void onClick(View view) { Intent intent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS); intent.setData(Uri.parse("package:" + getPackageName())); startActivity(intent); myDialog.dismiss(); } }); myDialog.negative.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { App.showToast("请开启" + string + "权限,否则影响该功能的使用"); } }); }
到此为止 ,我们的 基类 已经封装好了 ,下面就是一个在子类中调用的过程
此处已拍照上传为例: 需要的权限为 拍照权限 ,读写权限
1. 权限请求的位置 ,在点击拍照按钮的时候 ,进行 权限的判断,如果 没有权限 ,就调用基类的 请求权限的方法 ,此处 针对不同的权限,请求的参数,参照自己在第一步 ,宏定义的常量
/**拍照点击事件*/ textViewTakePhoto.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { sfPopupWindowOk.dismiss(); backgroundAlpha(1f); //判断是否有权限 相机权限 if (hasPermission(Manifest.permission.CAMERA,Manifest.permission.CAMERA)) { //有权限,则写你的业务逻辑 doYourNeedDoCarme(); }else { //没权限,进行权限请求 requestPermission(Constants.CODE_CAMERA, Manifest.permission.CAMERA); } } });
2.有权限的话 ,需要做的操作 ,如上图所示
重写父类的 获取相机权限后 的方法 ,写上自己的逻辑操作 即可 ,此处为 调用相机拍照
/** * 获取相机权限后的一些逻辑操作 */ @Override public void doYourNeedDoCarme() { super.doYourNeedDoCarme(); startCamera();//开启相机 } /** * 获取读写权限后的一些逻辑操作 */ @Override public void doYourNeedDoWriteAndRead() { super.doYourNeedDoWriteAndRead(); }
综上所述 :
所有的 在基类 中,在子类 中 的操作 按以上步骤 即可