漫聊android适配动态权限机制

	近期利用工作空闲之际,学习了些新的知识,为了更好的消化他们,我觉得把他们写出来能更好的帮我理解知识,也希望我的知识总结能方便大家学习,共同探讨和交流

   我先谈点儿题外话,要说做android开发遇到最麻烦无语的事儿,我个人认为是“给手机做适配”。由于android的开源性的特点,还有近年来非常火热的“互联网思维之个性化私人定制”。现在的android手机系统越来越多样化,比方说我最喜欢的小米的MIUI,还有魅族、华为、三星以及乐视等手机厂商都有自己的深度定制android系统。这样做有很多好处,例如可以快速占领市场,有优点就一定有缺点,这是万物的规律,android也不例外,例如系统碎片化严重导致手机越用越用越卡(由于本文是技术类文章,这方面内容在本片文章不是重点,我这里简略)。我这里顺带提一下开发上的坑吧,由于现在手机系统定制化严重,有些android原有的功能直接就被手机厂商修改了,这就会出现同一段代码在AB手机上运行正常,但在C手机上直接运行崩溃。遇到这个情况开发人员内心有一万头羊驼飘过。导致开发一个APP不得不在各大手机上调试适配,工作任务量一下涨了很多(真羡慕IOS没这个问题啊)适配上的坑很多,由于我开发阅历有限,看到的坑不多,等以后阅历多后,会考虑写篇文章好好聊聊那些坑的事儿。

为了能改善这一糟糕的局面,Google决定开始优化Android系统,于是在2015年的Google I/O大会上,Google公司推出了Android 6.0系统。这个6.0系统特点有很多,其中有一点很值得用户关注,那就是“更加安全”,手机系统的敏感权限(例如读写SD卡、短信、拍照等)由之前的自动打开权限变成由用户自己手动决定是否需要打开。

好了,现在先问各位三个问题。1android为什么要改变老的权限管理机制?2、可以不适配吗?3、可以不借助第三方库吗?

先来回答第一个问题。因为为了保护用户的隐私安全!之前我听同事告诉我说,在这一特性没出来之前,有些软件公司为了谋取金钱利益,在用户不知情的情况下打开摄像头偷拍用户,然后进行敲诈勒索。呵,这流氓软件想想都觉的可怕,可真会钻谷歌的空子,好还谷歌及时发现把这个漏洞补上了。回答第二个问题,我以亲身经历告诉你,不能!如果不适配android动态权限,其结果就是若用户要使用功能的相关权限没有打开,你直接就使用的话,APP一定会直接崩溃!!!回答第三个问题,可以。其实动态权限适配实现起来并不困难,完全没必要去用第三方库去做。因此接下来我就来实现android动态权限的适配。

在编写代码之前,我们要明白哪些权限需要动态申请,哪些不需要。Google将权限分为两类,一类是Normal Permissions,这类权限一般不涉及用户隐私,是不需要用户进行授权的,比如手机震动、访问网络等;另一类是Dangerous Permission,一般是涉及到用户隐私的,需要用户进行授权,比如读取sdcard、访问通讯录等。

Normal Permissions如下

Dangerous Permissions:



就这些内容吧。由于使用申请权限这些事儿基本都在Activity和Fragment里。为了使用方便,减少代码冗余。我们可以把这块逻辑封装放到我们自定义的BaseActivity和BaseFragment中,这样只要我们只需要继承他们就可以直接使用了。当然也可将这些逻辑放到自己封装的Utils工具类中,两种方案都可以的。这里我使用的是第一种方案。

使用之前,1、先要判断是否有指定的权限

public boolean hasPermission(String... permissions) {

        for (String permisson : permissions) {
            if (ContextCompat.checkSelfPermission(getActivity(), permisson)
                != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
        return true;
    }
使用String... permissions方便多个权限的判断,检查权限可以使用ContextCompat.checkSelfPermission(),ContextCompat类是Context下属的一个类,里面有很多和文件相关的方法。PERMISSION_GRANTED表示允许授权。
接下来如果用户没有打开相关权限.2、那就要申请权限了

public void requestPermission(int code, String... permissions) {

        if (Build.VERSION.SDK_INT >= 23) {
            requestPermissions(permissions, code);
        }
    }
权限动态申请是在android6.0以后的事,所以这里要判断一下。
既然申请了权限,3、接下来要处理权限申请回调了

 @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case Constant.HARDWEAR_CAMERA_CODE: // 打开相机权限
                if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    doOpenCamera();
                }
                break;
            case Constant.WRITE_READ_EXTERNAL_CODE: // 读写SD卡权限
                if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    doWriteSDCard();
                }
                break;
        }
    }

这里我们在申请权限时,要填写一个请求码,方便后面回调时识别是申请的哪个权限,而这些请求码可以放在自定义的Constant类中,例如

/**
     * 权限常量相关
     */
    public static final int WRITE_READ_EXTERNAL_CODE = 0x01;
    public static final String[] WRITE_READ_EXTERNAL_PERMISSION = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE};

    public static final int HARDWEAR_CAMERA_CODE = 0x02;
    public static final String[] HARDWEAR_CAMERA_PERMISSION = new String[]{Manifest.permission.CAMERA};
最后就是使用。使用也很方便,例如在使用相机时。
case R.id.card_view:
                if (hasPermission(Constant.HARDWEAR_CAMERA_PERMISSION)) {
                    doOpenCamera();
                } else {
                    requestPermission(Constant.HARDWEAR_CAMERA_CODE, Constant.HARDWEAR_CAMERA_PERMISSION);
                }
                break;

doOpenCamera()方法可以在BaseFragment中,至于里面的方法实现,可以在自己的Activity去做。例如
 @Override
    public void doOpenCamera() {
        Intent intent = new Intent(mContext, CaptureActivity.class);
        startActivityForResult(intent, REQUEST_QRCODE);
    }

或许有人会说在BaseFragment中写这么多空方法不好,太冗余了。其实也不算太严重,因为危险权限就9个,平时用的话连一半都不到,所以不用担心。

以上就是我的个人实现。如有不对,请各位大神指正,谢谢




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章