web-dev-qa-db-fra.com

Work Manager ne fonctionne pas lorsque l'application est tuée par l'utilisateur. Pourquoi?

Je veux exécuter une tâche, même après que l'application soit tuée à l'aide de Work Manager. Mais la tâche n'est pas exécutée après que l'application soit tuée.

    workManager = WorkManager.getInstance();
    Constraints constraints = new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build();
    OneTimeWorkRequest saveData = new OneTimeWorkRequest.Builder(SaveDataWorker.class).setConstraints(constraints).setInitialDelay(10,TimeUnit.SECONDS).build();
    workManager.enqueue(saveData);
8
kapsid

Comme je l'ai découvert, le responsable de travail dépend du fabricant de l'appareil. Pour mon cas, c'est un appareil MiUI, qui n'autorise pas le gestionnaire de travail à fonctionner au cas où l'application est tuée ou redémarrée. Le gestionnaire de travail a travaillé lorsque j'ai fourni l'application avec "Autorisation automatique".

3
kapsid

Work Manager dépend complètement du fabricant, certains fabricants ou vous pouvez également dire des périphériques avec Stock ROM permettant à Work Manager de fonctionner comme il se doit, mais il existe certains appareils fabricants ("chinois Rom's" ) Étaient très agressives tout en éliminant les applications de fond, ils tuent même le responsable de travail, cependant, Google essaie de faire fonctionner le gestionnaire de travail normalement sur tous les appareils en discutant avec OEM.

Dès maintenant si vous voulez vraiment courir quelque chose en arrière-plan, vous pouvez activer l'option AutoStart dans Xiaomi et d'autres périphériques, sinon vous pouvez également afficher une notification dans la barre de notification qui fait une application à exécuter au premier plan. Vous pouvez vérifier si l'application fonctionne toujours en arrière-plan ou non, sinon vous pouvez le redémarrer.

if (!isServiceRunning(this, MyService::class.Java)) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            startForegroundService(Intent(this, MyService::class.Java))
        } else {
            startService(Intent(this, MyService::class.Java))
        }

    }


 private fun isServiceRunning(context: Context, serviceClass: Class<*>): Boolean {
    val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
    val services = activityManager.getRunningServices(Integer.MAX_VALUE)

    if (services != null) {
        for (i in services.indices) {
            if (serviceClass.name == services[i].service.className && services[i].pid != 0) {
                return true
            }
        }
    }
    return false
}


 val am = getSystemService(Context.ALARM_SERVICE) as AlarmManager
    val pi = PendingIntent.getBroadcast(
        applicationContext,
        34,
        Intent(this, MyBroadcastReceiver::class.Java),
        PendingIntent.FLAG_UPDATE_CURRENT
    )
    am.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 10000, pi)

Et enfin dans le récepteur de diffusion.

 override fun onReceive(context: Context?, intent: Intent?) {
    Handler(Looper.getMainLooper()).post {
        if (!isServiceRunning(context!!, MyService::class.Java)) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                context.startForegroundService(Intent(context, MyService::class.Java))
            } else {
                context.startService(Intent(context, MyService::class.Java))
            }
        }
        val am = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
        val pi = PendingIntent.getBroadcast(
            context, 34, Intent(context, MyBroadcastReceiver::class.Java),
            PendingIntent.FLAG_UPDATE_CURRENT
        )
        am.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 5000, pi)
    }
}
1