How to check MIUI autostart permission programmatically? How to check MIUI autostart permission programmatically? android android

How to check MIUI autostart permission programmatically?


For now it's not possible.

As it's completely depend on their operating system API's and customisation. Even developers have requested for this on XIOMI's official forums but there is no response from there side.

Till now even i am finding an answer to this question but nothing helped me.

For the time being it will be only possible for rooted phones. i.e. making customisation in their firmware by becoming super user. But this is not at all advisable as it may damage user's phone.

EDIT 1

You can redirect user to autostart permission's settings page for enabling your app using following code

String manufacturer = "xiaomi";if (manufacturer.equalsIgnoreCase(android.os.Build.MANUFACTURER)) {    //this will open auto start screen where user can enable permission for your app    Intent intent1 = new Intent();    intent1.setComponent(new ComponentName("com.miui.securitycenter", "com.miui.permcenter.autostart.AutoStartManagementActivity"));    startActivity(intent1);}

EDIT 2I have recently used Mi A1 from XIOMI which have stock android (not miui) so this phone does not have autostart permission settings from miui. So take care while navigating user to the settings in such devices because it will not work here.


100% working for oppo, vivo, xiomi, letv huawei, and honor

just call this function

private void addAutoStartup() {    try {        Intent intent = new Intent();        String manufacturer = android.os.Build.MANUFACTURER;        if ("xiaomi".equalsIgnoreCase(manufacturer)) {            intent.setComponent(new ComponentName("com.miui.securitycenter", "com.miui.permcenter.autostart.AutoStartManagementActivity"));        } else if ("oppo".equalsIgnoreCase(manufacturer)) {            intent.setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.permission.startup.StartupAppListActivity"));        } else if ("vivo".equalsIgnoreCase(manufacturer)) {            intent.setComponent(new ComponentName("com.vivo.permissionmanager", "com.vivo.permissionmanager.activity.BgStartUpManagerActivity"));        } else if ("Letv".equalsIgnoreCase(manufacturer)) {            intent.setComponent(new ComponentName("com.letv.android.letvsafe", "com.letv.android.letvsafe.AutobootManageActivity"));        } else if ("Honor".equalsIgnoreCase(manufacturer)) {            intent.setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.optimize.process.ProtectActivity"));        }        List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);        if  (list.size() > 0) {            startActivity(intent);        }    } catch (Exception e) {        Log.e("exc" , String.valueOf(e));    }}


This is not a perfect solution by any means and it requires some testing, but I've been able to detect the autostart permission on my Xiaomi device with it.

The autostart permission allows apps to be started by receiving an implicit broadcast intent. This method consists of scheduling an implicit broadcast with AlarmManager, killing the app and checking if the broadcast caused it to respawn. A second explicit intent is also scheduled just to make sure that the app is started eventually.

public class AutostartDetector extends BroadcastReceiver {// I've omitted all the constant declaration to keep this snippet concise// they should match the values used in the Manifestpublic static void testAutoStart(Context context) {    long now = System.currentTimeMillis();    // this ID is for matching the implicit and explicit intents    // it might be unnecessary    String testId = Long.toHexString(now);    Intent implicitIntent = new Intent(ACTION_IMPLICIT_BROADCAST);    // the category is set just to make sure that no other receivers handle the broadcast    implicitIntent.addCategory(CATEGORY_AUTOSTART);    implicitIntent.putExtra(EXTRA_TEST_ID, testId);    PendingIntent implicitPendingIntent =            PendingIntent.getBroadcast(context, REQUEST_CODE_IMPLICIT_BROADCAST, implicitIntent, PendingIntent.FLAG_UPDATE_CURRENT);    Intent explicitIntent = new Intent(ACTION_EXPLICIT_BROADCAST);    explicitIntent.addCategory(CATEGORY_AUTOSTART);    explicitIntent.setComponent(new ComponentName(context, AutostartDetector.class));    explicitIntent.putExtra(EXTRA_TEST_ID, testId);    PendingIntent explicitPendingIntent =            PendingIntent.getBroadcast(context, REQUEST_CODE_EXPLICIT_BROADCAST, explicitIntent, PendingIntent.FLAG_UPDATE_CURRENT);    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);    // calling commit() makes sure that the data is written before we kill the app    // again, this might be unnecessary    getSharedPreferences(context).edit().putInt(testId, TestStatus.STARTED).commit();    // the explicit intent is set with an additional delay to let the implicit one be received first; might require some fine tuning    alarmManager.set(AlarmManager.RTC_WAKEUP, now + BASE_DELAY, implicitPendingIntent);    alarmManager.set(AlarmManager.RTC_WAKEUP, now + BASE_DELAY + EXPLICIT_INTENT_DELAY, explicitPendingIntent);    // kill the app - actually kind of tricky, see below    SelfKiller.killSelf(context);}@Overridepublic void onReceive(Context context, Intent intent) {    SharedPreferences sharedPreferences = getSharedPreferences(context);    String testId = intent.getStringExtra(EXTRA_TEST_ID);    if (testId == null) {        Log.w(TAG, "Null test ID");        return;    }    if (!sharedPreferences.contains(testId)) {        Log.w(TAG, "Unknown test ID: " + testId);        return;    }    String action = intent.getAction();    if (ACTION_IMPLICIT_BROADCAST.equals(action)) {        // we could assume right here that the autostart permission has been granted,        // but we should receive the explicit intent anyway, so let's use it        // as a test sanity check        Log.v(TAG, "Received implicit broadcast");        sharedPreferences.edit().putInt(testId, TestStatus.IMPLICIT_INTENT_RECEIVED).apply();    } else if (ACTION_EXPLICIT_BROADCAST.equals(action)) {        Log.v(TAG, "Received explicit broadcast");        int testStatus = sharedPreferences.getInt(testId, -1);        switch (testStatus) {            case TestStatus.STARTED:                // the implicit broadcast has NOT been received - autostart permission denied                Log.d(TAG, "Autostart disabled");                sharedPreferences.edit().putBoolean(PREF_AUTOSTART_ENABLED, false).apply();                notifyListener(false);                break;            case TestStatus.IMPLICIT_INTENT_RECEIVED:                // the implicit broadcast has been received - autostart permission granted                Log.d(TAG, "Autostart enabled");                sharedPreferences.edit().putBoolean(PREF_AUTOSTART_ENABLED, true).apply();                notifyListener(true);                break;            default:                Log.w(TAG, "Invalid test status: " + testId + ' ' + testStatus);                break;        }    }}private interface TestStatus {    int STARTED = 1;    int IMPLICIT_INTENT_RECEIVED = 2;}

Receiver declaration in the manifest:

<receiver android:name=".autostart.AutostartDetector">    <intent-filter>        <category android:name="com.example.autostart.CATEGORY_AUTOSTART"/>        <action android:name="com.example.autostart.ACTION_IMPLICIT_BROADCAST"/>        <action android:name="com.example.autostart.ACTION_EXPLICIT_BROADCAST"/>    </intent-filter></receiver>

Killing the app reliably is another problem. I've been using this helper method:

public static void killSelf(Context context) {    ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);    activityManager.killBackgroundProcesses(context.getPackageName());    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {        // this is all we can do before ICS. luckily Xiaomi phones have newer system versions :)        System.exit(1);        return;    }    // set up a callback so System.exit() is called as soon as all    // the activities are finished    context.registerComponentCallbacks(new ComponentCallbacks2() {        @Override        public void onTrimMemory(int i) {            if (i == TRIM_MEMORY_UI_HIDDEN) {                Log.v(TAG, "UI Hidden");                System.exit(1);            }        }        /* ... */    });    // see below    ActivityTracker.getInstance().finishAllActivities();}

ActivityTracker is another utility that keeps track of activity lifecycles. Make sure to register it in the Application subclass.

@RequiresApi(api = Build.VERSION_CODES.ICE_CREAM_SANDWICH)public final class ActivityTracker implements Application.ActivityLifecycleCallbacks {    private final ArraySet<Activity> mCreatedActivities = new ArraySet<>();    public static ActivityTracker getInstance() {        return Holder.INSTANCE;    }    public static void init(Application application) {        application.registerActivityLifecycleCallbacks(getInstance());    }    public static void release(Application application) {        ActivityTracker activityTracker = getInstance();        application.unregisterActivityLifecycleCallbacks(activityTracker);        activityTracker.mCreatedActivities.clear();    }    public void finishAllActivities() {        // iterate over active activities and finish them all        for (Activity activity : mCreatedActivities) {            Log.v(TAG, "Finishing " + activity);            activity.finish();        }    }    public Set<Activity> getCreatedActivities() {        return Collections.unmodifiableSet(mCreatedActivities);    }    @Override    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {        mCreatedActivities.add(activity);    }        @Override    public void onActivityDestroyed(Activity activity) {        mCreatedActivities.remove(activity);    }    private static final class Holder {        private static final ActivityTracker INSTANCE = new ActivityTracker();    }    /* ... */}

You might also want to stop all the services just to be sure.