如何在MIUI中打开“绘图叠加”权限弹出窗口?

问题描述 投票:17回答:3

我想在MIUI中打开此权限弹出窗口。我已经尝试过此代码,但是无法打开特定应用程序的权限管理器弹出窗口。

public static Intent toPermissionManager(Context context, String packageName) {
    Intent intent = new Intent("miui.intent.action.APP_PERM_EDITOR");
    String version = getVersionName();
    if (MIUI_V5.equals(version)) {
        PackageInfo pInfo;
        try {
            pInfo = context.getPackageManager().getPackageInfo(packageName, 0);
        } catch (PackageManager.NameNotFoundException ignored) {
            return null;
        }
        intent.setClassName("com.android.settings", "com.miui.securitycenter.permission.AppPermissionsEditor");
        intent.putExtra("extra_package_uid", pInfo.applicationInfo.uid);
    } else { // MIUI_V6 and above
        final String PKG_SECURITY_CENTER = "com.miui.securitycenter";
        try {
            context.getPackageManager().getPackageInfo(PKG_SECURITY_CENTER, PackageManager.GET_ACTIVITIES);
        } catch (PackageManager.NameNotFoundException ignored) {
            return null;
        }
        intent.setClassName(PKG_SECURITY_CENTER, "com.miui.permcenter.permissions.AppPermissionsEditorActivity");
        intent.putExtra("extra_pkgname", packageName);
    }
    return intent;
}
android android-permissions android-popupwindow
3个回答
13
投票

直接在您要使用此onDisplayPopupPermission()的位置直接permission调用此方法。

要检查许可权是granted还是not,我在上面又添加了一个答案,请检查。

private void onDisplayPopupPermission() {
    if (!isMIUI()) {
        return;
    }
    try {
        // MIUI 8
        Intent localIntent = new Intent("miui.intent.action.APP_PERM_EDITOR");
        localIntent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.PermissionsEditorActivity");
        localIntent.putExtra("extra_pkgname", getPackageName());
        startActivity(localIntent);
        return;
    } catch (Exception ignore) {
    }
    try {
        // MIUI 5/6/7
        Intent localIntent = new Intent("miui.intent.action.APP_PERM_EDITOR");
        localIntent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.AppPermissionsEditorActivity");
        localIntent.putExtra("extra_pkgname", getPackageName());
        startActivity(localIntent);
        return;
    } catch (Exception ignore) {
    }
    // Otherwise jump to application details
    Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
    Uri uri = Uri.fromParts("package", getPackageName(), null);
    intent.setData(uri);
    startActivity(intent);
 }


private static boolean isMIUI() {
    String device = Build.MANUFACTURER;
    if (device.equals("Xiaomi")) {
        try {
            Properties prop = new Properties();
            prop.load(new FileInputStream(new File(Environment.getRootDirectory(), "build.prop")));
            return prop.getProperty("ro.miui.ui.version.code", null) != null
                    || prop.getProperty("ro.miui.ui.version.name", null) != null
                    || prop.getProperty("ro.miui.internal.storage", null) != null;
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    return false;
}

它将重定向到显示弹出窗口权限屏幕,您可以手动将其更改为开/关


5
投票

下面的这段代码对我有用。您需要这两个类MIUIUtils.javaBuildProperties.java

MIUIUtils.java

public class MIUIUtils {
    private static final String MIUI_V5 = "V5";
    private static final String MIUI_V6 = "V6";

    private static final String KEY_MIUI_VERSION_CODE = "ro.miui.ui.version.code";
    private static final String KEY_MIUI_VERSION_NAME = "ro.miui.ui.version.name";
    private static final String KEY_MIUI_INTERNAL_STORAGE = "ro.miui.internal.storage";

    public static boolean isMIUI() {
        try {
            final BuildProperties prop = BuildProperties.newInstance();
            return prop.getProperty(KEY_MIUI_VERSION_CODE, null) != null
                || prop.getProperty(KEY_MIUI_VERSION_NAME, null) != null
                || prop.getProperty(KEY_MIUI_INTERNAL_STORAGE, null) != null;
        } catch (IOException e) {
            return false;
        }
    }

    public static boolean isMIUIV5() {
        return getVersionName().equals(MIUI_V5);
    }

    public static boolean isMIUIV6() {
        return getVersionName().equals(MIUI_V6);
    }

    public static String getVersionName() {
        try {
            final BuildProperties prop = BuildProperties.newInstance();
            return prop.getProperty(KEY_MIUI_VERSION_NAME);
        } catch (IOException e) {
            return "";
        }
    }

    public static boolean isFloatWindowOptionAllowed(Context context) {
        AppOpsManager manager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        Class localClass = manager.getClass();
        Class[] arrayOfClass = new Class[3];
        arrayOfClass[0] = Integer.TYPE;
        arrayOfClass[1] = Integer.TYPE;
        arrayOfClass[2] = String.class;
        try {
            Method method = localClass.getMethod("checkOp", arrayOfClass);
            if (method == null) {
                return false;
            }
            Object[] arrayOfObjects = new Object[3];
            arrayOfObjects[0] = Integer.valueOf(24);
            arrayOfObjects[1] = Integer.valueOf(Binder.getCallingUid());
            arrayOfObjects[2] = context.getPackageName();
            int m = ((Integer) method.invoke((Object) manager, arrayOfObjects)).intValue();
            return m == AppOpsManager.MODE_ALLOWED;
        } catch (Exception e) {
            return false;
        }
    }

    public static Intent toPermissionManager(Context context, String packageName) {
        Intent intent = new Intent("miui.intent.action.APP_PERM_EDITOR");
        String version = getVersionName();
        if (MIUI_V5.equals(version)) {
            PackageInfo pInfo;
            try {
                pInfo = context.getPackageManager().getPackageInfo(packageName, 0);
            } catch (PackageManager.NameNotFoundException ignored) {
                return null;
            }
            intent.setClassName("com.android.settings", "com.miui.securitycenter.permission.AppPermissionsEditor");
            intent.putExtra("extra_package_uid", pInfo.applicationInfo.uid);
        } else { // MIUI_V6 and above
            final String PKG_SECURITY_CENTER = "com.miui.securitycenter";
            try {
           context.getPackageManager().getPackageInfo(PKG_SECURITY_CENTER, PackageManager.GET_ACTIVITIES);
            } catch (PackageManager.NameNotFoundException ignored) {
                return null;
            }
            intent.setClassName(PKG_SECURITY_CENTER, "com.miui.permcenter.permissions.AppPermissionsEditorActivity");
            intent.putExtra("extra_pkgname", packageName);
        }
        return intent;
    }


    public static Intent toFloatWindowPermission(Context context, String packageName) {
        Uri packageUri = Uri.parse("package:" + packageName);
        Intent detailsIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, packageUri);
        detailsIntent.addCategory(Intent.CATEGORY_DEFAULT);
        if (isMIUIV5()) {
            return detailsIntent;
        } else {
            Intent permIntent = toPermissionManager(context, packageName);
            return permIntent == null ? detailsIntent : permIntent;
        }
    }
}

BuildProperties.java

public class BuildProperties {

    private final Properties properties;

    private BuildProperties() throws IOException {
        InputStream in = new FileInputStream(new File(Environment.getRootDirectory(), "build.prop"));
        properties = new Properties();
        properties.load(in);
        in.close();
    }

    public static BuildProperties newInstance() throws IOException {
        return new BuildProperties();
    }

    public boolean containsKey(final Object key) {
        return properties.containsKey(key);
    }

    public boolean containsValue(final Object value) {
        return properties.containsValue(value);
    }

    public Set<Map.Entry<Object, Object>> entrySet() {
        return properties.entrySet();
    }

    public String getProperty(final String name) {
        return properties.getProperty(name);
    }

    public String getProperty(final String name, final String defaultValue) {
        return properties.getProperty(name, defaultValue);
    }

    public boolean isEmpty() {
        return properties.isEmpty();
    }

    public Enumeration<Object> keys() {
        return properties.keys();
    }

    public Set<Object> keySet() {
        return properties.keySet();
    }

    public int size() {
        return properties.size();
    }

    public Collection<Object> values() {
        return properties.values();
    }
}

以这种方式调用您的代码:

     if (Build.VERSION.SDK_INT >= 19 && MIUIUtils.isMIUI() && !MIUIUtils.isFloatWindowOptionAllowed(context)) {
            Log.i(TAG, "MIUI DEVICE: Screen Overlay Not allowed");
            startActivityForResult(MIUIUtils.toFloatWindowPermission(context, getPackageName()), REQUEST_OVERLAY_PERMISSION);
        } else if (Build.VERSION.SDK_INT >= 23 && !Settings.canDrawOverlays(context)) {
            Log.i(TAG, "SDK_INT > 23: Screen Overlay Not allowed");
            startActivityForResult(new Intent(
                            "android.settings.action.MANAGE_OVERLAY_PERMISSION", 
                            Uri.parse("package:" +getPackageName()))
                    , REQUEST_OVERLAY_PERMISSION
            );
        } else {
            Log.i(TAG, "SKK_INT < 19 or Have overlay permission");

        }

1
投票

要检查是否授予Display popup window权限,使用onDisplayPopupPermission()此方法来自于我上面的答案。

我正在使用canDrawOverlayViewsreflection检查permission is granted,这可能是removed/changed in the latest releases

我已经尝试过此解决方案,直到MIUI8都有效,不确定最新更新。请更新评论,以便其他人可以更新。

1.Step

if (!canDrawOverlayViews() && isXiaomi()) {
        //permission not granted
        Log.e("canDrawOverlayViews", "-No-");
       onDisplayPopupPermission(); 
        //write above answered permission code for MIUI here
    }else {

    }

2.Step检查是否授予权限

public boolean canDrawOverlayViews() {
    if (Build.VERSION.SDK_INT < 21) {
        return true;
    }
    Context con = this;
    try {
        return Settings.canDrawOverlays(con);
    } catch (NoSuchMethodError e) {
        return canDrawOverlaysUsingReflection(con);
    }
}

public static boolean isXiaomi() {
    return "xiaomi".equalsIgnoreCase(Build.MANUFACTURER);
}

canDrawOverlaysUsingReflection()我在这里here translate this page]找到了此解决方案

public static boolean canDrawOverlaysUsingReflection(Context context) {

try {

    AppOpsManager manager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
    Class clazz = AppOpsManager.class;
    Method dispatchMethod = clazz.getMethod("checkOp", new Class[] { int.class, int.class, String.class });
    //AppOpsManager.OP_SYSTEM_ALERT_WINDOW = 24
    int mode = (Integer) dispatchMethod.invoke(manager, new Object[] { 24, Binder.getCallingUid(), context.getApplicationContext().getPackageName() });

    return AppOpsManager.MODE_ALLOWED == mode;

} catch (Exception e) {  return false;  }

}

© www.soinside.com 2019 - 2024. All rights reserved.