前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android开发笔记(一百五十八)运行时动态授权管理

Android开发笔记(一百五十八)运行时动态授权管理

作者头像
aqi00
发布2019-01-18 15:53:15
1.1K0
发布2019-01-18 15:53:15
举报
文章被收录于专栏:老欧说安卓老欧说安卓

App开发过程中,涉及到硬件设备的操作,比如拍照、录音、定位等等,都要在AndroidManifest.xml中声明相关的权限。可是Android系统为了防止某些App滥用权限,从而允许用户在系统设置里面对App禁用某些权限。然而这又带来另一个问题,用户打开App之后,App可能因为权限不足导致无法正常运行,甚至直接崩溃闪退。遇到这种情况,只需用户在系统设置中开启相关权限即可恢复正常,但是用户并非专业的开发者,他怎知要去启用哪些权限呢?再说,每次都要用户亲自打开系统设置页面,再琢磨半天精挑细选那些必须开启的权限,不但劳力而且劳神,这种用户体验实在差劲。 有鉴于此,Android从6.0开始引入了运行时权限管理机制,允许App在运行过程中动态检查是否拥有某项权限,一旦发现缺少某种必需的权限,则系统会自动弹出小窗提示用户去开启该权限。如此这般,一方面开发者无需担心App因权限不足而闪退的问题,另一方面用户也不再头痛是哪个权限被禁止导致App用不了的毛病,这个贴心的动态权限授权功能可谓是皆大欢喜。下面就来看看如何在代码中实现运行时权限管理机制。 首先要检查Android系统是否为6.0及以上版本,因为运行时权限管理机制是6.0才开始支持的功能。其次调用ContextCompat.checkSelfPermission方法,检查检查当前App是否开启了指定的权限。倘若检查结果是尚未开启权限,则再调用ActivityCompat.requestPermissions方法,请求系统弹出开启权限的确认对话框。详细的权限校验代码如下所示:

代码语言:javascript
复制
    // 检查某个权限。返回true表示已启用该权限,返回false表示未启用该权限
    public static boolean checkPermission(Activity act, String permission, int requestCode) {
        Log.d(TAG, "checkPermission: "+permission);
        boolean result = true;
        // 只对Android6.0及以上系统进行校验
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // 检查当前App是否开启了名称为permission的权限
            int check = ContextCompat.checkSelfPermission(act, permission);
            if (check != PackageManager.PERMISSION_GRANTED) {
                // 未开启该权限,则请求系统弹窗,好让用户选择是否立即开启权限
                ActivityCompat.requestPermissions(act, new String[]{permission}, requestCode);
                result = false;
            }
        }
        return result;
    }

比如App现在准备拍照,那么需要检查是否开启了相机权限Manifest.permission.CAMERA,如果没有启用相机权限,则系统会弹出下图所示的选择窗口。

再比如App准备获取手机的位置信息,那么需要检查是否开启了定位权限Manifest.permission.ACCESS_FINE_LOCATION,如果没有启用定位,则系统会弹出下图所示的选择窗口。

注意到系统的权限选择弹窗存在“拒绝”和“允许”两个按钮,这便意味着开发者要对两种选项分别进行处理。如果用户点击“拒绝”按钮,自然表示接下来App将会无法正常运行,此时需要提示用户可能产生的问题及其原因;如果用户点击“允许”按钮,系统会立即给App赋予相应的权限,那么App就按照正常的流程走下去,该拍照就拍照、该定位就定位。以上的选项判断逻辑,具体到代码中则需重写Activity的onRequestPermissionsResult函数,重写后的函数代码示例如下:

代码语言:javascript
复制
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if (requestCode == mRequestCode) { // 通过requestCode区分不同的请求
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // 已授权,则进行后续的正常逻辑处理
            } else {
                Toast.makeText(this, "需要允许相机权限才能拍照噢", Toast.LENGTH_SHORT).show();
            }
        }
    }

有时某种业务必须同时开启多项权限,譬如录像就得既开启相机权限、又开启录音权限。那么在校验权限的时候,要多次调用ContextCompat.checkSelfPermission方法,只有待检查的所有权限都已经授权,才无需系统弹窗提示;否则的话,仍需系统逐个弹窗以供用户选择确认。下面是同时校验多个权限的代码例子,其中多个权限以字符串数组的参数形式传入“new String[] {Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA}”:

代码语言:javascript
复制
    public static boolean checkMultiPermission(Activity act, String[] permissions, int requestCode) {
        boolean result = true;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            int check = PackageManager.PERMISSION_GRANTED;
            // 通过权限数组检查是否都开启了这些权限
            for (String permission : permissions) {
                check = ContextCompat.checkSelfPermission(act, permission);
                if (check != PackageManager.PERMISSION_GRANTED) {
                    break;
                }
            }
            if (check != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(act, permissions, requestCode);
                result = false;
            }
        }
        return result;
    }

仍以录像业务为例,假如之前App既无相机权限也无录音权限,则运用了运行时权限管理机制之后,系统会在界面上依次弹出录音权限选择窗、相机权限选择窗。两个权限弹窗的截图如下所示: 录音权限选择窗

相机权限选择窗

点此查看Android开发笔记的完整目录

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年02月11日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档