小米MIUI短信权限遇到的坑

最近公司开发一个项目,需要用到短信的功能,适配华为手机一切都正常,适配小米手机,遇到了两个棘手问题:

1.小米MIUI有个通知类短信权限,这个权限不知道如何申请,不知道如何判断是否具有该权限;

2.业务要求在引导页弹短信读取权限的弹窗让用户授权(这个是其他手机正常的流程),小米MIUI读取短信权限READ_SMS,动态申请后不弹窗,但是会走onRequestPermissionsResult的回调,而且回调值是PERMISSION_GRANTED,去权限设置页面查看该权限其实是询问状态;

第一个问题:解决办法是手动引导用户去设置页面开启,一般引导页只会走一次,这个权限是否开启目前没法判断,看过其他的例如来电类app, 有些权限也无法判断是否开启了,做法是弹窗让用户选择是否已开启。

小米跳权限设置页代码如下:

 public static void goPermissionSettings(Activity activity) {
        if (isMIUI()) {
            Intent intent;
            intent = new Intent("miui.intent.action.APP_PERM_EDITOR");
            intent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.PermissionsEditorActivity");
            intent.putExtra("extra_pkgname", activity.getPackageName());
            if (PhoneUtil.isIntentAvailable(intent, activity)) {
                activity.startActivityForResult(intent, REQUEST_CODE_SERVICE_SMS);
            } else {
                intent = new Intent("miui.intent.action.APP_PERM_EDITOR");
                intent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.AppPermissionsEditorActivity");
                intent.putExtra("extra_pkgname", activity.getPackageName());
                if (PhoneUtil.isIntentAvailable(intent, activity)) {
                    activity.startActivityForResult(intent, REQUEST_CODE_SERVICE_SMS);
                } else {
                    intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                    Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
                    intent.setData(uri);
                    activity.startActivityForResult(intent, REQUEST_CODE_SERVICE_SMS);
                }
            }
        }
    }

    /**
     * 判断是否是小米机型
     * @return
     */
    public static boolean isMIUI() {
        if (isMiui == null) {
            isMiui = !TextUtils.isEmpty(getSystemProperty("ro.miui.ui.version.name"));
        }
        return isMiui;
    }


    public static String getSystemProperty(String propName) {
        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) {
            Log.e(TAG, "Unable to read sysprop " + propName, ex);
            return null;
        } finally {
            if (input != null) {
                try {
                    input.close();
                } catch (IOException e) {
                    Log.e(TAG, "Exception while closing InputStream", e);
                }
            }
        }
        return line;
    }

    /**
     * 判断是否存在可用的跳转意图
     */
    public static boolean isIntentAvailable(Intent intent, Context context) {
        if (intent == null || context == null || context.getPackageManager() == null) {
            return false;
        }
        return context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY).size() > 0;
    }

第二个问题:小米MIUI其实有一套自己的权限管理,叫AppOpsManager,Google把它隐藏了没有开放出来,这个权限管理比现有的权限优先级更高。AppOpsManager可以跳过一些流氓软件的限制。比如应用需要开启某一个敏感权限,如果你拒绝了,应用就会不让你进去或者一直弹窗提醒。  利用AppOpsManager可以判断读取短信的权限是开启还是拒绝还是询问。不过最坑的是就是虽然你判断出它是具体是什么状态了,你还是没法让它弹窗授权。

不过我发现了一个问题,小米MIUI弹出短信读读取的时机是当应用真正去读短信的时候触发。Ps:前提是你申请了读取短信权限。 所以我们可以这样做:在第一次申请读取短信权限的回调里去真正读一次短信操作,这个时候你会发现读取短信的弹窗弹起来了,后面就是正常流程了。补充一点,小米的读取短信权限如果手动拒绝了,下次再用这种方式也是不弹窗的,只能手动引导用户打开读取短信的权限了。

总结:小米MIUI真是太坑了!

你可能感兴趣的:(Android,动态权限)