美文网首页权限适配Android 开发相关文章收集
Android 跳转权限设置界面的终极适配(适配各大定制 ROM

Android 跳转权限设置界面的终极适配(适配各大定制 ROM

作者: 渊祥 | 来源:发表于2017-09-25 11:26 被阅读2278次

    前言

    在我们请求用户权限时,很有可能会被用户有意无意地点了拒绝,而这个权限恰恰又是当前操作所以必须的,所以一般我们都会希望用户能手动去打开权限,以便我们能顺利的执行业务逻辑。

    那么问题来了,我们要怎么快速地引导用户打开我们需要的权限呢。直接跟用户说我们需要这个权限,你给我去打开?别开玩笑了,有太多的用户根本找不到权限的开关,折腾了半天一无所获,然后放弃了这个操作,甚至放弃了这个应用。

    还有没有更好的办法?目前很多一些应用都是采用提示法,告诉用户应该去『设置 - 应用列表 - 本应用 - 权限管理』中打开某某权限,还有一些会辅助跳转『应用信息』或者『应用列表』,再让用户自己找。

    这些方法确实在一定程度上帮助了用户找到相应的权限开关,但是我觉得这还不够。为什么呢?因为在目前国内一些 ROM 中,权限开关根本不在『应用信息』或者『应用列表』里,他们另起炉灶,把权限管理放在了『安全中心』、『手机管家』、『权限管理』等一些系统应用入口中管理。虽然这样的定制方便了用户对权限的管理,却让开发者深感头疼,它们的权限管理界面既没有统一的名称,也没有统一的 API 来跳转。所以必须根据不同的国产 ROM (甚至是同一种 ROM 的不同版本)来定制不同的权限跳转或者提示方案。

    关于识别 ROM 并获取其版本号的方案,可见 国产定制 ROM 的终极适配,识别 ROM 并获取版本号

    权限界面的跳转

    关于权限的界面跳转方面,我一开始的思路是参考了 『Android各大手机品牌手机跳转到权限管理界面』这篇文章。

    通过 『ActivityTracker』来获取不同 ROM (甚至需要适配 ROM 版本)的权限界面组件名并进行跳转。部分 ROM 无法进行跳转的,和根据情况跳转到最方便用户操作的界面,比如可以通过『应用信息』界面进去的,可以跳转至『应用信息』在做进一步的提示即可。

    public static boolean gotoPermissionSetting() {
        boolean success = true;
        Intent intent = new Intent();
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        String packageName = LshAppUtils.getPackageName();
    
        LshOSUtils.ROM romType = LshOSUtils.getRomType();
        switch (romType) {
            case EMUI: // 华为
                intent.putExtra("packageName", packageName);
                intent.setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.permissionmanager.ui.MainActivity"));
                break;
            case Flyme: // 魅族
                intent.setAction("com.meizu.safe.security.SHOW_APPSEC");
                intent.addCategory(Intent.CATEGORY_DEFAULT);
                intent.putExtra("packageName", packageName);
                break;
            case MIUI: // 小米
                String rom = getMiuiVersion();
                if ("V6".equals(rom) || "V7".equals(rom)) {
                    intent.setAction("miui.intent.action.APP_PERM_EDITOR");
                    intent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.AppPermissionsEditorActivity");
                    intent.putExtra("extra_pkgname", packageName);
                } else if ("V8".equals(rom) || "V9".equals(rom)) {
                    intent.setAction("miui.intent.action.APP_PERM_EDITOR");
                    intent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.PermissionsEditorActivity");
                    intent.putExtra("extra_pkgname", packageName);
                } else {
                    intent = getAppDetailsSettingsIntent(packageName);
                }
                break;
            case Sony: // 索尼
                intent.putExtra("packageName", packageName);
                intent.setComponent(new ComponentName("com.sonymobile.cta", "com.sonymobile.cta.SomcCTAMainActivity"));
                break;
            case ColorOS: // OPPO
                intent.putExtra("packageName", packageName);
                intent.setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.permission.PermissionManagerActivity"));
                break;
            case EUI: // 乐视
                intent.putExtra("packageName", packageName);
                intent.setComponent(new ComponentName("com.letv.android.letvsafe", "com.letv.android.letvsafe.PermissionAndApps"));
                break;
            case LG: // LG
                intent.setAction("android.intent.action.MAIN");
                intent.putExtra("packageName", packageName);
                ComponentName comp = new ComponentName("com.android.settings", "com.android.settings.Settings$AccessLockSummaryActivity");
                intent.setComponent(comp);
                break;
            case SamSung: // 三星
            case SmartisanOS: // 锤子
                gotoAppDetailSetting(packageName);
                break;
            default:
                intent.setAction(Settings.ACTION_SETTINGS);
                LshLogUtils.i("没有适配该机型, 跳转普通设置界面");
                success = false;
                break;
        }
        try {
            LshContextUtils.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
            // 跳转失败, 前往普通设置界面
            LshIntentUtils.gotoSetting();
            success = false;
            LshLogUtils.i("无法跳转权限界面, 开始跳转普通设置界面");
        }
        return success;
    }
    
    private static String getMiuiVersion() {
        String propName = "ro.miui.ui.version.name";
        String line;
        BufferedReader input = null;
        try {
            Process p = Runtime.getRuntime().exec("getprop " + propName);
            input = new BufferedReader(
                    new InputStreamReader(p.getInputStream()), 1024);
            line = input.readLine();
            input.close();
        } catch (IOException ex) {
            ex.printStackTrace();
            return null;
        } finally {
            LshIOUtils.close(input);
        }
        LshLogUtils.i("MiuiVersion = " + line);
        return line;
    }
    

    致歉

    由于公司测试设备和个人时间问题,在权限跳转方面目前只测试成功了小米(V7 V8 V9)、华为、三星、锤子、魅族等机型,OPPO 机型目前没有成功跳转。所以在代码和适配方面仍需要继续进行开发和维护。由于目前的公司业务在适配方面的要求并不严格,所以近期内可能没有继续研究适配下去的希望。希望小伙伴们能给一些点赞和支持,如果发现自己的研究能被人所有还是很有动力的。

    目前暂定喜欢数超过 10 算是得到大家肯定,继续把跳转步骤进行完整的封装,并适配主流 ROM 系统。希望觉得这篇文章有用的朋友不要吝啬点个喜欢就行,这也算是自己在开源项目的开发上得到的巨大鼓舞了吧。

    关于权限跳转的详细代码已经抽取到个人工具类并上传到 GitHub,如有建议或问题,欢迎提 Issues 或 Pull requests。

    本篇文章代码所在工具类:IntentUtils

    随便提一下自己花了大量心血收集整理的工具类,本篇文章提到的 LshOSUtils 已经收集到该工具类,其中还包括许多其他日常经常使用到的工具类。在此不多赘述,感兴趣的可以点击下面链接查看。

    个人收集的常用工具类:Utils-Everywhere

    相关文章

      网友评论

      • xwp:java.io.FileNotFoundException: /system/build.prop (Permission denied)
        获取ROM类型本身就需要权限,所以直接GG
        渊祥:@四季树 已经解决了,目前 ROM 的识别功能已经抽离到独立的项目里了,欢迎拍砖~
        xwp:/system/build.prop (Permission denied) 在8.0是不可读的。弄bugly死活不上报ANR,查出来是这个原因
        xwp:如果没有权限拿build.prop,根据Build.MANUFACTURER判断,进行跳转,再失败的话就直接跳set页。
      • ZZZ_Hero:您好,魅族7.0通过以上方式跳转不能成功,应该是intent.setClassName("com.meizu.safe", "com.meizu.safe.security.AppSecActivity"),但是这个Activity的位置或者名字变了,作者的方式不能跳转到权限设置界面
        渊祥:没办法哈,之前由于换工作太忙,没有时间理这块了,现在正在逐步完善并适配,欢迎交流~
      • 风舞尘起:集成的太臃肿了,很多工程都有自己的utils,现在再改用你的,改动太大了。
        能分离出 跳转权限设置界面这个部分吗?
        耦合太高。。没法用
        渊祥:嗯,我知道的,因为这一块我还没有整理完整,所以还没有单拎出来。近期在忙着一些其他事情,后期我一定会把这些事情弄好的。不过呢,多谢你的好心提醒呢,让我突然又有动力了,哈哈哈~
      • b9629ca48312:支持博主
        渊祥:哈哈 谢谢~ :heart: 正好你是第10个给喜欢的哎,谢谢你们的肯定:pray: 看来我要继续把未完成的工作做完了:stuck_out_tongue:
      • 360a88b0e4cf:万分感谢呀,手边只得3,4个手机呀,网上旧的资料又怕过期了,苦恼。我根据你的资料把自己写的有关代码注释掉了。看到这么全这么新的资料写起代码来都带劲了
        渊祥:哈哈,互勉~
      • fa64524ceec2:我之前找的跳转有些问题,刚好跟你的融合一下
      • 751d6bed8557:楼主写的不错,刚好需要这些资料.:+1:
        渊祥:谢谢支持,因为测试机型有限,还有一些机型没有进行适配是有点可惜的

      本文标题:Android 跳转权限设置界面的终极适配(适配各大定制 ROM

      本文链接:https://www.haomeiwen.com/subject/cecwlxtx.html