web-dev-qa-db-fra.com

Les services d'arrière-plan sont limités dans Xiaomi et Oppo

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.

4
Behrad Ranjbar

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
        }
0
Behrad Ranjbar