How to open Draw Overlay permission popup in MIUI?
Call This method directly onDisplayPopupPermission()
where you want to use this permission
.
To check permission is granted
or not
I have added one more answer above, please check.
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;}
It will redirect to display popup window permission screen you can manually change it to on off
This below code is working for me. You need these two class MIUIUtils.java and BuildProperties.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(); }}
Call in your code like this:
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"); }
To check if Display popup window
permission is Granted or not, using onDisplayPopupPermission()
this method is from my above answer.
I am using canDrawOverlayViews
and reflection
to check permission is granted
or not this may be removed/changed in the latest releases
.
This solution I have tried up to
MIUI8
it's working, not sure about the latest updates. Please give an update on the comment so others can have updates.
1.Step
if (!canDrawOverlayViews() && isXiaomi()) { //permission not granted Log.e("canDrawOverlayViews", "-No-"); onDisplayPopupPermission(); //write above answered permission code for MIUI here }else { }
2.StepCheck if permission granted or not
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() I have found this solution here 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; }
}