转载请注明出处,感谢您的支持
文章来源:【chenyk的博客】http://blog.csdn.net/chenyk_kevin_1/article/details/52344876

简单介绍

关于运行时权限的说法,早在Google发布android 6.0的时候,大家也听得蛮多的。从用户的角度来讲,用户是受益方,更好的保护用户的意思,而对于开发者来说,无疑增加了工作量。

对于6.0以下的权限在安装时,会根据权限声明产生一个权限列表,用户只有同意才能完成app的安装。而在6.0以后,不需要先对权限授权就可以安装app,对于权限的授权我们可以选择禁止。

在新的权限机制中,Google将权限分为两类:

Normal Permissions(普通权限):不涉及用户隐私,不需要用户进行授权,比如访问网络等;
Dangerous Permission(危险权限):涉及到用户隐私,需要用户进行授权,比如相机访问、读取SD卡等。

PS:运行时权限只适合APP运行在Android 6.x以上的机器,对于危险权限Google官方也对其进行了分组,只要一组中的某一权限被授权,同组的权限也同样会被授权。

操作步骤

在这之前,前面的一篇文章id=gralloc的问题">Android 异常处理 - 关于E/HAL: load: id=gralloc != hmi->id=gralloc的问题也简单的介绍了关于运行时权限的使用方法,操作步骤如下
1. 在Androidmanifest.xml文件声明相关权限
2. 通过ContextCompat.checkSelfPermission方法检查某项权限被授予情况
3. 申请授权
4. 权限回调处理

封装调用

权限的申请我们一般的做法都在Activity被创建的时候,才开始申请危险权限。而每次都得重复上述的操作,想想都觉得烦。为此,笔者将运行时权限的使用进行了进一步的归纳总结。将权限的检查统一封装在基类中,子类继承并实现抽象方法,传入权限数组等即可。

1)通过抽象方法getNeedPermissions( )获取需要进行检测的权限数组,检查相关权限是否授权,如果未授权则开始申请权限

    /**     * 检查所有权限,无权限则开始申请相关权限     */    protected void checkAllNeedPermissions() {        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return;        List needRequestPermissonList = getDeniedPermissions(getNeedPermissions());        if (null != needRequestPermissonList && needRequestPermissonList.size() > 0) {            ActivityCompat.requestPermissions(this, needRequestPermissonList.toArray(                    new String[needRequestPermissonList.size()]), REQUEST_CODE_PERMISSON);        }    }

2)权限授权情况回调处理,这里授权失败默认弹框是否前往设置页面授权

 /**     * 权限授权结果回调     *     * @param requestCode     * @param permissions     * @param paramArrayOfInt     */    @Override    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,                                           @NonNull int[] paramArrayOfInt) {        if (requestCode == REQUEST_CODE_PERMISSON) {            if (!verifyPermissions(paramArrayOfInt)) {                permissionGrantedFail();                showTipsDialog();                isNeedCheckPermission = false;            } else permissionGrantedSuccess();        }    }

PS:其中permissionGrantedSuccess()和permissionGrantedSuccess()为抽象方法,由子类实现。

3)简单调用,子类继承该基类,实现以下抽象方法即可

    @Override    public String[] getNeedPermissions() {        return new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};    }    @Override    protected void permissionGrantedSuccess() {    }    @Override    protected void permissionGrantedFail() {    }

有没有觉得酱紫操作清晰了很多,也方便了不少。依然如此,就赶紧mark吧。

封装类的完整代码如下:

/** * Created by chenyk on 2016/9/28. * 检查相关权限基类,适用于android 6.0 运行时权限 * 使用方法:需要运行时权限的activity继承此类 */public abstract class BaseCheckPermissionActivity extends Activity        implements OnRequestPermissionsResultCallback {    private static final int REQUEST_CODE_PERMISSON = 2020; //权限请求码    private boolean isNeedCheckPermission = true; //判断是否需要检测,防止无限弹框申请权限    @Override    protected void onResume() {        super.onResume();        if (isNeedCheckPermission) {            checkAllNeedPermissions();        }    }    /**     * 检查所有权限,无权限则开始申请相关权限     */    protected void checkAllNeedPermissions() {        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return;        List needRequestPermissonList = getDeniedPermissions(getNeedPermissions());        if (null != needRequestPermissonList && needRequestPermissonList.size() > 0) {            ActivityCompat.requestPermissions(this, needRequestPermissonList.toArray(                    new String[needRequestPermissonList.size()]), REQUEST_CODE_PERMISSON);        }    }    /**     * 获取权限集中需要申请权限的列表     *     * @param permissions     * @return     */    private List getDeniedPermissions(String[] permissions) {        List needRequestPermissonList = new ArrayList<>();        for (String permission : permissions) {            if (ContextCompat.checkSelfPermission(this, permission) !=                    PackageManager.PERMISSION_GRANTED ||                    ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {                needRequestPermissonList.add(permission);            }        }        return needRequestPermissonList;    }    /**     * 所有权限是否都已授权     *     * @return     */    protected boolean isGrantedAllPermission() {        List needRequestPermissonList = getDeniedPermissions(getNeedPermissions());        return needRequestPermissonList.size() == 0;    }    /**     * 权限授权结果回调     *     * @param requestCode     * @param permissions     * @param paramArrayOfInt     */    @Override    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,                                           @NonNull int[] paramArrayOfInt) {        if (requestCode == REQUEST_CODE_PERMISSON) {            if (!verifyPermissions(paramArrayOfInt)) {                permissionGrantedFail();                showTipsDialog();                isNeedCheckPermission = false;            } else permissionGrantedSuccess();        }    }    /**     * 检测所有的权限是否都已授权     *     * @param grantResults     * @return     */    private boolean verifyPermissions(int[] grantResults) {        for (int grantResult : grantResults) {            if (grantResult != PackageManager.PERMISSION_GRANTED) {                return false;            }        }        return true;    }    /**     * 显示提示对话框     */    protected void showTipsDialog() {        new AlertDialog.Builder(this).setTitle("提示信息").setMessage("当前应用缺少" + getDialogTipsPart()                + "权限,该功能暂时无法使用。如若需要,请单击【确定】按钮前往设置中心进行权限授权。")                .setNegativeButton("取消", new DialogInterface.OnClickListener() {                    @Override                    public void onClick(DialogInterface dialog, int which) {                        finish();                    }                })                .setPositiveButton("确定", new DialogInterface.OnClickListener() {                    @Override                    public void onClick(DialogInterface dialog, int which) {                        startAppSettings();                    }                }).show();    }    /**     * 启动当前应用设置页面     */    private void startAppSettings() {        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);        intent.setData(Uri.parse("package:" + getPackageName()));        startActivity(intent);    }    /**     * 获取弹框提示部分内容     *     * @return     */    protected String getDialogTipsPart() {        return "必要";    }    /**     * 获取需要进行检测的权限数组     */    protected abstract String[] getNeedPermissions();    /**     * 权限授权成功     */    protected abstract void permissionGrantedSuccess();    /**     * 权限授权失败     */    protected abstract void permissionGrantedFail();

版权声明:本文为博主原创文章,未经博主允许不得转载。

写在最后,希望以上内容能帮到您,不定时总结和记录个人的经验。您的支持是我前进的动力,经验分享是美德,加油!

更多相关文章

  1. Android(安卓)动态权限申请之 shouldShowRequestPermissionRatio
  2. Android(安卓)版本适配6.0到9.0
  3. Android(安卓)root 原理
  4. Android中文件读写错误 open failed: ENOENT (No such file or d
  5. Android通过代码获取ROOT权限
  6. 【Android(安卓)百度地图实战】1.构建一个基础的地图页面
  7. ubuntu下运行android emulator权限不够解决方法
  8. android 模拟器 sdcard权限修改
  9. Android系统权限和root权限的获取以及应用权限列表

随机推荐

  1. 如何唯一确定一台 Android(安卓)设备?
  2. Android中SharedPreference实例
  3. MAC下安装android studio问题汇总(持续更
  4. Android Jetpack简介
  5. Tips for Android Tabs
  6. Android 小項目之---Iphone拖动图片特效
  7. Android mvp 详解(下)
  8. HierarchyView的实现原理和Android设备无
  9. app目录下的build.gradle详解
  10. Android LayoutInflater加载.xml文件原理