Nous développons une application avec MQTT fonctionnant dans un service de premier plan. Le problème est sur Xiaomi Redmi Note 7, le service est tué après avoir tué l'application, mais sur d'autres marques, cela fonctionne bien. Je n'ai pas testé l'application sur Oppo et Vivo, mais lors de la recherche, ils ont également des problèmes. Dans la méthode onCreate
du service, j'ai appelé startForeground(NOTIFICATION_ID, notification)
et ma déclaration de service dans le manifeste est comme ceci
<service
Android:name=".service.mqtt.MqttService"
Android:enabled="true"
Android:exported="false"
Android:foregroundServiceType="location" />
J'ai également changé foregroundServiceType
en connectedDevice|dataSync|mediaPlayback
et ajouté Android:stopWithTask="false"
et renvoyé START_STICKY
dans onStartCommand
méthode de service mais ne fonctionne toujours pas.
Enfin j'ai trouvé la réponse ici
private static final Intent[] POWERMANAGER_INTENTS = {
new Intent().setComponent(new ComponentName("com.miui.securitycenter", "com.miui.permcenter.autostart.AutoStartManagementActivity")),
new Intent().setComponent(new ComponentName("com.letv.Android.letvsafe", "com.letv.Android.letvsafe.AutobootManageActivity")),
new Intent().setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.startupmgr.ui.StartupNormalAppListActivity")),
new Intent().setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.optimize.process.ProtectActivity")),
new Intent().setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.appcontrol.activity.StartupAppControlActivity")),
new Intent().setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.permission.startup.StartupAppListActivity")),
new Intent().setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.startupapp.StartupAppListActivity")),
new Intent().setComponent(new ComponentName("com.oppo.safe", "com.oppo.safe.permission.startup.StartupAppListActivity")),
new Intent().setComponent(new ComponentName("com.iqoo.secure", "com.iqoo.secure.ui.phoneoptimize.AddWhiteListActivity")),
new Intent().setComponent(new ComponentName("com.iqoo.secure", "com.iqoo.secure.ui.phoneoptimize.BgStartUpManager")),
new Intent().setComponent(new ComponentName("com.vivo.permissionmanager", "com.vivo.permissionmanager.activity.BgStartUpManagerActivity")),
new Intent().setComponent(new ComponentName("com.samsung.Android.lool", "com.samsung.Android.sm.ui.battery.BatteryActivity")),
new Intent().setComponent(new ComponentName("com.htc.pitroad", "com.htc.pitroad.landingpage.activity.LandingPageActivity")),
new Intent().setComponent(new ComponentName("com.asus.mobilemanager", "com.asus.mobilemanager.MainActivity"))
};
for (Intent intent : POWERMANAGER_INTENTS)
if (getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
// show dialog to ask user action
break;
}
edit: Il y a également un problème pour vérifier si l'utilisateur a activé le démarrage automatique ou non. Au fur et à mesure de mes recherches, aucune solution n'est actuellement disponible. J'ai donc conçu une solution moi-même. J'ai créé un ouvrier qui fera gagner du temps au système dans les préférences toutes les 25 minutes. Chaque fois que l'application est ouverte, je vérifie les préférences, et si plus de 30 minutes se sont écoulées depuis le temps enregistré, cela signifie que le travailleur n'a pas pu faire le travail, donc peut-être que l'utilisateur n'a pas activé le démarrage automatique la dernière fois et doit Invite à nouveau.
class BackgroundCheckWorker(val appContext: Context, val workerParams: WorkerParameters) :
Worker(appContext, workerParams), KoinComponent {
override fun doWork(): Result {
val pref = appContext.getSharedPreferences(PermissionHandler.AUTO_START_PREF, Context.MODE_PRIVATE)
val editor = pref.edit()
editor.putString(AUTO_START_PREF_KEY, Calendar.getInstance().time.toString())
editor.apply()
return Result.success()
}
}
Et dans splash, j'appelle cette fonction:
fun requestUnrestrictedBackgroundService(context: Activity): Boolean {
val pref = context.getSharedPreferences(AUTO_START_PREF, Context.MODE_PRIVATE)
var updated = false
val lastUpdate = pref.getString(AUTO_START_PREF_KEY, "")
updated = if (lastUpdate == null || lastUpdate == "") {
val editor = pref.edit()
editor.putString(AUTO_START_PREF_KEY, Calendar.getInstance().time.toString())
editor.apply()
false
} else lastUpdate != "" &&
DateUtil.minAgo(lastUpdate) <= 30
if (!updated) {
for (intent in POWERMANAGER_INTENTS)
if (context.packageManager.resolveActivity(
intent,
PackageManager.MATCH_DEFAULT_ONLY
) != null
) {
val dialog = AlertDialog.Builder(context)
dialog.setMessage("On this device you must allow us to run services in background")
.setPositiveButton("Yes") { paramDialogInterface, paramInt ->
val editor = pref.edit()
editor.putString(AUTO_START_PREF_KEY, Calendar.getInstance().time.toString())
editor.apply()
context.startActivityForResult(intent, 1234)
}
.setNegativeButton("Cancel") { paramDialogInterface, paramInt -> context.finish() }
dialog.show()
return false
}
}
return true
}