Продолжайте обслуживание, даже если приложение удалено из последних приложений или закрыто на устройстве Red MI.

Я запускаю службу телеметрии в своем приложении. Эта служба проверяет изменения в среде WiFi раз в секунду и, если изменения обнаружены, уведомляет удаленную базу данных. Мне нужно, чтобы эта служба продолжала работать, даже если приложение удалено из последних приложений или закрыто.

Я выполнил Продолжить обслуживание, даже если приложение удалено из недавнего приложения и, кажется, работает на многих устройствах, кроме Xiaomi. Я пробовал много советов для этого устройства:

  1. включить автозапуск.
  2. отключить оптимизацию батареи для этого приложения.
  3. Попытался использовать широковещательный приемник для запуска службы
  4. Пробовал использовать поток таймера и scheduleExecutorservice вместо runnable. не имело значения.

Это мой последний пример кода:

package com.example.csi1;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.view.Gravity;
import android.widget.Toast;

public class MainService extends Service {
    public Context context = this;
    public Handler handler = null;
    public static Runnable runnable = null;
    public static int count = 0;
    public int restart = 0;
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);
        Toast.makeText(this, "MainService onStartCommand", Toast.LENGTH_LONG).show();
        Bundle extras = intent.getExtras();
        count = 0;

        handler = new Handler();
        runnable = new Runnable(){
            public void run() {
                count = count+1;

                WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
                WifiInfo wifiInfo;

                wifiInfo = wifiManager.getConnectionInfo();
                if (wifiInfo.getSupplicantState() == SupplicantState.COMPLETED) {
                    String ssid = wifiInfo.getSSID();
                    Log.i("Service", "SSID:"+ssid);
                    Toast toast = Toast.makeText(context, "Service iter " + String.valueOf(count)+ " " + ssid, Toast.LENGTH_LONG );
                    toast.setGravity(Gravity.TOP|Gravity.RIGHT, 0, 0);
                    toast.show();
                }

                handler.postDelayed(runnable, 1000);

            }
        };

        handler.postDelayed(runnable, 3000);
        return START_STICKY;
    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        super.onTaskRemoved(rootIntent);
        Toast.makeText(this, "onTaskRemoved", Toast.LENGTH_LONG).show();
        if (restart == 0) {
            PendingIntent service = PendingIntent.getService(
                    getApplicationContext(),
                    1001,
                    new Intent(getApplicationContext(), MainService.class),
                    PendingIntent.FLAG_ONE_SHOT);

            AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
            alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 1000, service);
            restart=1;
            Toast.makeText(this, "Service restarted", Toast.LENGTH_LONG).show();
        }
    }
    @Override
    public void onDestroy(){
        Toast.makeText(this, "onDestroy", Toast.LENGTH_SHORT).show();
        if (restart == 0) {
            PendingIntent service = PendingIntent.getService(
                    getApplicationContext(),
                    1001,
                    new Intent(getApplicationContext(), MainService.class),
                    PendingIntent.FLAG_ONE_SHOT);

            AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
            alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 1000, service);
            restart=1;
            Toast.makeText(this, "Service restarted", Toast.LENGTH_LONG).show();
        }
        super.onDestroy();
    }
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
}

он отлично работает на устройстве Samsung и эмуляторе Google Nexus, но всякий раз, когда я запускаю его на Red mi и пролистываю приложение из последних приложений, приложение умирает и обслуживается вместе с ним. Есть ли решение для устройств Red mi или это какое-то общеизвестное ограничение?


person ncormac    schedule 30.06.2019    source источник


Ответы (1)


MIUI от Xiaomi и несколько других очень агрессивно удаляют фоновые службы. Как пользователь, вы можете отключить его, следуя этим шаги (для xiaomi). Но я не знаю решения, чтобы обойти это как разработчик.

Так что вы не делаете ничего плохого, некоторым телефонам просто не нравятся фоновые сервисы, отнимающие заряд батареи. Аналогичное обсуждение можно найти здесь: Настройка защищенных приложений на телефонах Huawei и как с этим справиться. Их решение в основном заключается в том, чтобы пользователь отключил его, вызвав диспетчер оптимизации для каждого из проблемных устройств.

person Software Person    schedule 30.06.2019
comment
Спасибо программисту. Я сделал эти шаги, но служба все еще убивает, так что я понимаю, что ОС просто не позволит мне перезапустить ее? - person ncormac; 01.07.2019
comment
В целом да, но, возможно, посмотрите это: stackoverflow.com/a/35220476/11702000. И посмотрите, поможет ли это. - person Software Person; 01.07.2019