安卓6.0之后——动态获取权限封装

来源:互联网 发布:网络优化工程师培训费 编辑:程序博客网 时间:2024/06/05 09:56

转自:

今天将项目中需要授权的地方,增加了判断 -----------关于6.0权限的封装。大家知道,在android6.0之后,谷歌为了更进一步保护用户的手机安全及知情权,在权限管理方面做了改变。在6.0之前,我们只需要在Manifest里增加对应的权限标签即可,如:
    <uses-permission android:name="android.permission.INTERNET" />    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />    <uses-permission android:name="android.permission.CAMERA" />
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4
但是现在就不同了,比如调用照相机。用户的系统设置默认不授予你的应用这个权限,而你此时没有进行动态授权,那不同产商就会有不同的问题(轻则不能调用,重则直接崩溃,小编的小米就是直接崩)说了这么多,让我们看看代码。在BaseActivity做好封装,具体的子类只要进行调用,去实现具体的逻辑就好

四部曲:第一步,先判断是否有权限
 /**     * 判断是否拥有权限     *     * @param permissions     * @return     */    public boolean hasPermission(String... permissions) {        for (String permission : permissions) {            if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED)                return false;        }        return true;    }//说明://String... permissions//形参String...的效果其实就和数组一样,这里的实参可以写多个String,也就是权限(下面讲到友盟分享的权限申请时就会理解)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

第二步:如果没有权限,就进行请求

  /**     * 请求权限     */    protected void requestPermission(int code, String... permissions) {        ActivityCompat.requestPermissions(this, permissions, code);        ToastUtil.showMessage(this, "如果拒绝授权,会导致应用无法正常使用", Toast.Length_SHORT);    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

第三步:请求授权后的回调

  /**     * 请求权限的回调     *     * @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) {                    ToastUtil.showMessage(this, "现在您拥有了权限");                    // 这里写你需要的业务逻辑                    doYourNeedDo();                } else {                    ToastUtil.showMessage(this, "您拒绝授权,会导致应用无法正常使用,可以在系统设置中重新开启权限", Toast.Length_SHORT);                }                break;            case Constants.CODE_READ_EXTERNAL_STORAGE:            //另一个权限的回调                break;        }    }//说明://Constants.CODE_CAMERA//这是在外部封装的一个常量类,里面有许多静态的URL以及权限的CODE,可以自定义//但是在调用的时候,记得这个CODE要和你自己定义的CODE一一对应
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

最后,第四步,留一个方法,给子类重写,实现你所需要的业务逻辑(比如 拍照)

 //子类重写后实现具体调用相机的业务逻辑    public void doYourNeedDo() {         //留给子类重写,这里空白就好    }
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

OK,封装完成 
接下来,在需要进行授权的Activity中 extends 这个封装了权限请求的BaseActvity

在需要调用的地方进行判断

  //判断是否有权限 if (hasPermission(Manifest.permission.CAMERA,Manifest.permission.CAMERA)) {      //有权限,则写你的业务逻辑     doYourNeedDo();}else {    //没权限,进行权限请求   requestPermission(Constants.CODE_CAMERA, Manifest.permission.CAMERA);   }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
    //重写调用相机的逻辑    @Override    public void doYourNeedDo() {        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);        //  拍照后保存图片的绝对路径        String cameraPath = LocalImageHelper.getInstance().setCameraImgPath();        File file = new File(cameraPath);        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));        startActivityForResult(intent, ImageUtils.REQUEST_CODE_GETIMAGE_BYCAMERA);    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

OK,这样就搞定了。


写到这里,总结一下上面的思路, 
就是, 
一,判断权限、 
二、有权限,执行 / 没权限,请求权限 
三、请求后的权限回调(这里注意CODE,要匹配) 
四、业务逻辑(有权限则直接从第二步跳到这步,没权限则在第三步的回调中调用)

上面的封装方法,最好在Manifest里还是像原先一样,将需要的权限先添加上,这样就可以兼容6.0以上和6.0以下的版本。 
6.0以下不会有任何影响。


再说一说友盟的实现逻辑

    //如想让你的app在android 6.0系统上也能运行的话,需要动态获取权限,没有权限的话分享sdk会出错,    //参考一下代码做动态获取权限,适配安卓6.0系统    //你需要最新的android.support.v4包,或者v13的包可也以  if(Build.VERSION.SDK_INT>=23){       String[] mPermissionList = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.CALL_PHONE,Manifest.permission.READ_LOGS,Manifest.permission.READ_PHONE_STATE, Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.SET_DEBUG_APP,Manifest.permission.SYSTEM_ALERT_WINDOW,Manifest.permission.GET_ACCOUNTS,Manifest.permission.WRITE_APN_SETTINGS}; ActivityCompat.requestPermissions(this,mPermissionList,123);            }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

其实思路大抵相同,只是友盟是通过判断版本号,是否大于23,。

上面这段代码是直接从友盟分享中拷出来的,mPermissionList 这个数组用在我们第一种封装的方法上也是一样的。

0 0
原创粉丝点击