Android Skip Application Permission Settings Page Adaptation Millet System

Keywords: MIUI Android Flyme

Skipping the application settings page to allow users to modify denied permissions is a common requirement, but testing on the MIUI 8 system has found pits. Write an article to record.

Normal jump application setup page method

Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
intent.setData(uri);
activity.startActivityForResult(intent, CODE_REQUEST);

It is the implicit intention of system encapsulation to open the details of the settings page directly, and intent provides package name information to tell the system which application to retrieve.Don't forget to open it by startActivityForResult. After all, you have to go through the permission checks and follow-up methods again after you return from the settings page.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == CODE_REQUEST) {
        //TODO something;
    }
}

Settings encapsulates a number of useful system properties. Take a look at the comment for Settings.ACTION_APPLICATION_DETAILS_SETTINGS:

/**
     * Activity Action: Show screen of details about a particular application.
     * <p>
     * In some cases, a matching Activity may not exist, so ensure you
     * safeguard against this.
     * <p>
     * Input: The Intent's data URI specifies the application package name
     * to be shown, with the "package" scheme.  That is "package:com.my.app".
     * <p>
     * Output: Nothing.
     */
    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
    public static final String ACTION_APPLICATION_DETAILS_SETTINGS =
            "android.settings.APPLICATION_DETAILS_SETTINGS";

Problems encountered on MIUI 8 system

The scenario is like this, what I need to request is the open camera permission, which simulates the situation where the user is detected to disable the permission and prompted to set the page open permission on the system.

The callback can detect that the permission has been acquired after the system permission settings page grants the permission, but the millet MIX test machine turns on the camera with a black screen and prompts me that the permission is disabled and needs to be turned on in the security center.

The original millet system made another set of rights management pages in the Security Center, and directly ignored the results of Android's own rights settings page.Blind overhead.However, the user does not care, so we can only prompt the user to go to the Security Center's Rights Management page to make changes on the MIUI system.

Some special adapting issues on MIUI can be seen in this post: http://www.miui.com/thread-2442999-1-1.html

Top Code:

public static void settingPermissionActivity(Activity activity) {
    //Determine if millet system
    if (TextUtils.equals(BrandUtils.getSystemInfo().getOs(), BrandUtils.SYS_MIUI)) {
        Intent miuiIntent = new Intent("miui.intent.action.APP_PERM_EDITOR");
        miuiIntent.putExtra("extra_pkgname", activity.getPackageName());
        //Detect if Activity accepts this Intent exists
        List<ResolveInfo> resolveInfos = activity.getPackageManager().queryIntentActivities(miuiIntent, PackageManager.MATCH_DEFAULT_ONLY);
        if (resolveInfos.size() > 0) {
            activity.startActivityForResult(miuiIntent, CODE_REQUEST_CAMERA_PERMISSIONS);
            return;
        }
    }
    //Open the App Settings page for Android if it's not a millet system
    Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
    Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
    intent.setData(uri);
    activity.startActivityForResult(intent, CODE_REQUEST_CAMERA_PERMISSIONS);
}

The code to judge the system is as follows:

/**
 * Created by Yomii on 2017/4/12.
 */

public class BrandUtils {

    public static final String SYS_EMUI = "sys_emui";
    public static final String SYS_MIUI = "sys_miui";
    public static final String SYS_FLYME = "sys_flyme";
    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";
    private static final String KEY_EMUI_API_LEVEL = "ro.build.hw_emui_api_level";
    private static final String KEY_EMUI_VERSION = "ro.build.version.emui";
    private static final String KEY_EMUI_CONFIG_HW_SYS_VERSION = "ro.confg.hw_systemversion";

    private static SystemInfo systemInfoInstance;

    public static SystemInfo getSystemInfo() {
        if (systemInfoInstance == null) {
            synchronized (BrandUtils.class) {
                if (systemInfoInstance == null) {
                    systemInfoInstance = new SystemInfo();
                    getSystem(systemInfoInstance);
                }
            }
        }
        return systemInfoInstance;
    }

    private static void getSystem(SystemInfo info) {
        try {
            Properties prop = new Properties();
            prop.load(new FileInputStream(new File(Environment.getRootDirectory(), "build.prop")));
            if (prop.getProperty(KEY_MIUI_VERSION_CODE, null) != null
                    || prop.getProperty(KEY_MIUI_VERSION_NAME, null) != null
                    || prop.getProperty(KEY_MIUI_INTERNAL_STORAGE, null) != null) {
                info.os = SYS_MIUI;//millet
                info.versionCode = Integer.valueOf(prop.getProperty(KEY_MIUI_VERSION_CODE, "0"));
                info.versionName = prop.getProperty(KEY_MIUI_VERSION_NAME, "V0");
            } else if (prop.getProperty(KEY_EMUI_API_LEVEL, null) != null
                    || prop.getProperty(KEY_EMUI_VERSION, null) != null
                    || prop.getProperty(KEY_EMUI_CONFIG_HW_SYS_VERSION, null) != null) {
                info.os = SYS_EMUI;//Huawei
                info.versionCode = Integer.valueOf(prop.getProperty(KEY_EMUI_API_LEVEL, "0"));
                info.versionName = prop.getProperty(KEY_EMUI_VERSION, "unknown");
            } else if (getMeizuFlymeOSFlag().toLowerCase().contains("flyme")) {
                info.os = SYS_FLYME;//Meizu
                info.versionCode = 0;
                info.versionName = "unknown";
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static String getMeizuFlymeOSFlag() {
        return getSystemProperty("ro.build.display.id", "");
    }

    private static String getSystemProperty(String key, String defaultValue) {
        try {
            Class<?> clz = Class.forName("android.os.SystemProperties");
            Method get = clz.getMethod("get", String.class, String.class);
            return (String) get.invoke(clz, key, defaultValue);
        } catch (Exception e) {
        }
        return defaultValue;
    }

    public static class SystemInfo {
        private String os = "android";
        private String versionName = Build.VERSION.RELEASE;
        private int versionCode = Build.VERSION.SDK_INT;

        public String getOs() {
            return os;
        }

        public String getVersionName() {
            return versionName;
        }

        public int getVersionCode() {
            return versionCode;
        }

        @Override
        public String toString() {
            return "SystemInfo{" +
                    "os='" + os + '\'' +
                    ", versionName='" + versionName + '\'' +
                    ", versionCode=" + versionCode +
                    '}';
        }
    }
}

Posted by jimmyborofan on Sat, 22 Jun 2019 09:31:07 -0700