How to get MIUI Security app auto start permission programmatically?

I am not getting BOOT_COMPLETE broadcast in my Xiaomi Redmi 2 Prime mobile.

My BroadcastReciever is ---

public class OnBootReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    // Setting singleAlarm
    SingleAlarmHandler.getInstance().setAlarm(context);

    try {
        // Sending System Setting broadcast
        String offDate = SharedPrefrencesHandler.getInstance(context).readString(SharedPrefrencesConstants.SWITCH_OFF_DATE);
        int type = SystemSettingsType.PHONE_SWITCH_ON_OFF.getNumericType();

        if (offDate == null)
            offDate = "";

        SystemSettingsHandler.getSystemSettingsHandler().makeSystemSettingsCall(context, type, offDate);
        SharedPrefrencesHandler.getInstance(context).removePrefrence(SharedPrefrencesConstants.SWITCH_OFF_DATE);
        } catch (Exception e) {
            Log.e(ChaseForceApplication.TAG, e.getMessage());
        }
    }
}

and manifest:

    <receiver
        android:name=".broadcastlisteners.OnBootReceiver"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>

with permission:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

Now I am not getting BOOT COMPLETE broadcast in my Xiaomi Redmi 2 Prime mobile as alarm is not set. But in other android mobiles it is working correctly.

I searched and found that it is problem in MIUI firmware. In such mobile they provide an in built security app and until you allow auto start permission in that Security app, you are unable to get broad cast (any notification).

And as soon as you check that permission in that app you start to get the broadcast.

Now my question is:

How to get MIUI Security app auto start permission( Phones like Redmi) programmatically?


Solution 1:

this question already has answer in two Stack Overflow threads:

thread #1 https://stackoverflow.com/a/40932178/1537413

String xiaomi = "Xiaomi";
final String CALC_PACKAGE_NAME = "com.miui.securitycenter";
final String CALC_PACKAGE_ACITIVITY = "com.miui.permcenter.autostart.AutoStartManagementActivity";
if (deviceManufacturer.equalsIgnoreCase(xiaomi)) {
    DisplayUtils.showDialog(activity, "Ask for permission", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialogInterface, int i) {
            try {
                Intent intent = new Intent();
                intent.setComponent(new ComponentName(CALC_PACKAGE_NAME, CALC_PACKAGE_ACITIVITY));
                activity.startActivity(intent);
            } catch (ActivityNotFoundException e) {
                Logger.e(TAG, "Failed to launch AutoStart Screen ", e);
            } catch (Exception e) {
                Logger.e(TAG, "Failed to launch AutoStart Screen ", e);
            }
        }
    }, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialogInterface, int i) {

        }
    });
}

thread #2 https://stackoverflow.com/a/41696993/1537413

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 intent = new Intent();
            intent.setComponent(new ComponentName("com.miui.securitycenter", "com.miui.permcenter.autostart.AutoStartManagementActivity"));
            startActivity(intent);
        }

and for similar problem on huawei devices:

https://stackoverflow.com/a/35220476/1537413

    private void ifHuaweiAlert() {
    final SharedPreferences settings = getSharedPreferences("ProtectedApps", MODE_PRIVATE);
    final String saveIfSkip = "skipProtectedAppsMessage";
    boolean skipMessage = settings.getBoolean(saveIfSkip, false);
    if (!skipMessage) {
        final SharedPreferences.Editor editor = settings.edit();
        Intent intent = new Intent();
        intent.setClassName("com.huawei.systemmanager", "com.huawei.systemmanager.optimize.process.ProtectActivity");
        if (isCallable(intent)) {
            final AppCompatCheckBox dontShowAgain = new AppCompatCheckBox(this);
            dontShowAgain.setText("Do not show again");
            dontShowAgain.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    editor.putBoolean(saveIfSkip, isChecked);
                    editor.apply();
                }
            });

            new AlertDialog.Builder(this)
                    .setIcon(android.R.drawable.ic_dialog_alert)
                    .setTitle("Huawei Protected Apps")
                    .setMessage(String.format("%s requires to be enabled in 'Protected Apps' to function properly.%n", getString(R.string.app_name)))
                    .setView(dontShowAgain)
                    .setPositiveButton("Protected Apps", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            huaweiProtectedApps();
                        }
                    })
                    .setNegativeButton(android.R.string.cancel, null)
                    .show();
        } else {
            editor.putBoolean(saveIfSkip, true);
            editor.apply();
        }
    }
}

private boolean isCallable(Intent intent) {
    List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent,
            PackageManager.MATCH_DEFAULT_ONLY);
    return list.size() > 0;
}

private void huaweiProtectedApps() {
    try {
        String cmd = "am start -n com.huawei.systemmanager/.optimize.process.ProtectActivity";
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            cmd += " --user " + getUserSerial();
        }
        Runtime.getRuntime().exec(cmd);
    } catch (IOException ignored) {
    }
}

private String getUserSerial() {
    //noinspection ResourceType
    Object userManager = getSystemService("user");
    if (null == userManager) return "";

    try {
        Method myUserHandleMethod = android.os.Process.class.getMethod("myUserHandle", (Class<?>[]) null);
        Object myUserHandle = myUserHandleMethod.invoke(android.os.Process.class, (Object[]) null);
        Method getSerialNumberForUser = userManager.getClass().getMethod("getSerialNumberForUser", myUserHandle.getClass());
        Long userSerial = (Long) getSerialNumberForUser.invoke(userManager, myUserHandle);
        if (userSerial != null) {
            return String.valueOf(userSerial);
        } else {
            return "";
        }
    } catch (NoSuchMethodException | IllegalArgumentException | InvocationTargetException | IllegalAccessException ignored) {
    }
    return "";
}

Solution 2:

You need to give permissions in the in build security application for xiaomi.

1. open the security app
2. go to permissions
3. go to auto start
4. enable the applications that you want to keep running in the background!

This worked for me..!