I created a test application for installing apk files. PackageInstaller was used for this. The app works well. However, for Xiaomi in BroadcastReceiver I get the "INSTALL_FAILED_INTERNAL_ERROR: Permission Denied" error. But if you enable developer mode and disable MIUI optimization, then the application also successfully installs packages. I can't get users of my application to force them to turn off the optimization mode, how can I deal with this? Tested on MIUI 11 version
PackageInstaller does not work on MIUI optimization mode
902 Views Asked by Serg Sergeevich At
2
There are 2 best solutions below
0
On
It seems as though MIUI 20.2.20 solves this incompatibility. solru's answer checks for this.
In case the GitHub link stops working:
public static boolean isMiui() {
return !TextUtils.isEmpty(Utils.getSystemProperty("ro.miui.ui.version.name"));
}
public static String getMiuiVersionName() {
String versionName = Utils.getSystemProperty("ro.miui.ui.version.name");
return !TextUtils.isEmpty(versionName) ? versionName : "???";
}
public static int getMiuiVersionCode() {
try {
return Integer.parseInt(Objects.requireNonNull(Utils.getSystemProperty("ro.miui.ui.version.code")));
} catch (Exception e) {
return -1;
}
}
public static String getActualMiuiVersion() {
return Build.VERSION.INCREMENTAL;
}
private static int[] parseVersionIntoParts(String version) {
try {
String[] versionParts = version.split("\\.");
int[] intVersionParts = new int[versionParts.length];
for (int i = 0; i < versionParts.length; i++)
intVersionParts[i] = Integer.parseInt(versionParts[i]);
return intVersionParts;
} catch (Exception e) {
return new int[]{-1};
}
}
/**
* @return 0 if versions are equal, values less than 0 if ver1 is lower than ver2, value more than 0 if ver1 is higher than ver2
*/
private static int compareVersions(String version1, String version2) {
if (version1.equals(version2))
return 0;
int[] version1Parts = parseVersionIntoParts(version1);
int[] version2Parts = parseVersionIntoParts(version2);
for (int i = 0; i < version2Parts.length; i++) {
if (i >= version1Parts.length)
return -1;
if (version1Parts[i] < version2Parts[i])
return -1;
if (version1Parts[i] > version2Parts[i])
return 1;
}
return 1;
}
public static boolean isActualMiuiVersionAtLeast(String targetVer) {
return compareVersions(getActualMiuiVersion(), targetVer) >= 0;
}
@SuppressLint("PrivateApi")
public static boolean isMiuiOptimizationDisabled() {
if ("0".equals(Utils.getSystemProperty("persist.sys.miui_optimization")))
return true;
try {
return (boolean) Class.forName("android.miui.AppOpsUtils")
.getDeclaredMethod("isXOptMode")
.invoke(null);
} catch (Exception e) {
return false;
}
}
public static boolean isFixedMiui() {
return isActualMiuiVersionAtLeast("20.2.20") || isMiuiOptimizationDisabled();
}
Ultimately the functions you're looking for are isMiui and isMiuiFixed.
You can detect whether user has MIUI and optimization mode enabled and display a message which will force user to disable it. Use these utility methods (it's a part of Split APKs Installer source code): https://github.com/Aefyr/SAI/blob/master/app/src/main/java/com/aefyr/sai/utils/MiuiUtils.java