问题
I am developing an android application in which I want to display the Push notification.
It has displayed well in most of the devices except Xiaomi phones (I am using Redmi Note 4). The problem that I found is, it is because of Autostart option provided by Xiomi which will be disabled by default and the user need to enable it manually.
But I wonder that some of the Android Apps I could see enabling this option without any user interaction Ex: WhatsApp. If I try reinstalling WhatsApp and see the Autostart option , it is enabled!
I am unable to convince our client by telling it is the feature of Xiomi like devices as he is pointing out some apps which is working fine like the example I have mentioned above.
This question has been asked by some other people
Add my app to AutoStart apps list in android programmatically
How to check AutoStart is enabled for our App in Xiaomi manufacturer mobile device Programmatically
But I could not see any answers for them and Posting here with the hope that someone will have an answer for this.
回答1:
The autostart feature will get enabled automatically when you will download the app from playstore if xiaomi OS wants it as apps like amazon ,google IO etc are also not allowed to autostart ,In this case you have to go to Security permissions -> autostart -> then enable autostart from there.You cannot make the app autostart by code all you can do is you can show a dialog to enable auto start and take the user to the autostart activity but this is not a good option as you cannot check whether autostart is enabled or not. This is done by Mi in MIUI8 for saving battery .This issue wasted my 2 days XD
You can refer to this article.
回答2:
For xiaomi, oppo, vivo, etc. devices to Enable Autostart option programmatically
String manufacturer = android.os.Build.MANUFACTURER;
try {
Intent intent = new Intent();
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) {
e.printStackTrace();
}
回答3:
As far as I know, WhatsApp is whitelisted on the Xiaomi device autostart. There is nothing you can do about it. Of course your application will be whitelisted by Xiaomi if it eventually garnered as much as WhatsApp popularity. Until that happens, you can only asking for user to activate it manually by showing the Auto-start feature with something like this:
try {
Intent intent = new Intent();
if ("xiaomi".equalsIgnoreCase(android.os.Build.MANUFACTURER)) {
intent.setComponent(new ComponentName("com.miui.securitycenter",
"com.miui.permcenter.autostart.AutoStartManagementActivity"));
}
// context is your Context
List<ResolveInfo> list = context.getPackageManager()
.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
if (list.size() > 0) {
context.startActivity(intent);
}
} catch (Exception e) {
Log.d("PERMISSION", e.toString());
}
Please note, that I haven't test the code for current Xiaomi device.
回答4:
Few popular apps run in background without being killed during memory cleanup cycle (many of the popular OEMs customize the stack ROM for battery/memory optimization), because they are "White listed" by these manufactures. For your app you can whitelist it either manually (via corresponding "settings" for the devices) or pragmatically by redirecting users to the corresponding settings page to white list the app. Pragmatically you can do like below:
Add below permissions in the App's manifest file:`
<uses-permission android:name="oppo.permission.OPPO_COMPONENT_SAFE"/> <uses-permission android:name="com.huawei.permission.external_app_settings.USE_COMPONENT"/>`
Redirect your to the Auto Start setting:
if (Build.BRAND.equalsIgnoreCase("xiaomi")) { Intent intent = new Intent(); intent.setComponent(new ComponentName("com.miui.securitycenter", "com.miui.permcenter.autostart.AutoStartManagementActivity")); startActivity(intent); } else if (Build.MANUFACTURER.equalsIgnoreCase("oppo")) { try { Intent intent = new Intent(); intent.setClassName("com.coloros.safecenter", "com.coloros.safecenter.permission.startup.StartupAppListActivity"); startActivity(intent); } catch (Exception e) { try { Intent intent = new Intent(); intent.setClassName("com.oppo.safe", "com.oppo.safe.permission.startup.StartupAppListActivity"); startActivity(intent); } catch (Exception ex) { try { Intent intent = new Intent(); intent.setClassName("com.coloros.safecenter", "com.coloros.safecenter.startupapp.StartupAppListActivity"); startActivity(intent); } catch (Exception exx) { } } } }
AutoStart Reference For other OEMs
I have tested this method and it worked but the reliability is still a question as system taking time (approx 2 Min on PoccoF9 & Xiomi devices) to restart the killed service.
But as an user we can prevent the app's background services to get killed all together as below :
- Press Recent apps physical key (left side button).
- Drag down the app once (select, hold & slide it down) tap on the lock icon (if the lock is in open state) to lock the app.
- The app will be put in lock condition (even if you clear the background app processes by clearing, the app will keep on running).
- Same way, if you want to remove it from the lock condition, just drag down again once and the lock symbol will disappear (clearing the background process will clear the app from running too).
But, With this way App's locking status will be reset on reboot on most of the devices.
EDIT: After observing the behavior (on Xiomi's RedmiS3, Android V6.0) of Foreground service here is the analysis:
Even after enabling the "AutoStart" programatically (via user intervention, as explained above) the service didn't restarts always (Service restarted only on few occasions, but most of the time it didn't).
Also, if I search for "AutoStart" in device settings I can't see my app there in the AutoStart list. It seems above method only providing Autostart permission but not enabling it, NOT SURE!. And, if I add my app into "AutoStart" list via device setting, my service gets restarted (though it takes some time).Restarting the killed service in onTaskRemoved() callback could be another option but this callback gets called in surprising way when service gets killed. This callback gets executed only when app is been closed properly by back key press. If we minimized the app (Pause state) this callback never gets called on service kill. (Looking for the reason)
Recently I found another way, the killed service could be restarted via GCM notification event. I doubt that weather the GCM works when App's gets killed on the devices or not (I need to check this and verify the behavior). But one this is for sure "These OEMs has made the programmer life hell!).
来源:https://stackoverflow.com/questions/49473230/android-how-to-enable-autostart-option-programmatically-in-xiaomi-devices