Подтвердить что ты не робот

Продолжить службу, даже если приложение очищено от последнего приложения

У меня небольшая проблема.

В моем приложении Служба запускается после успешного входа пользователя в систему. Раньше служба должна была прекратиться, если приложение было убито. (скажем, удалены из списка последних приложений путем прокрутки.) Таким образом, мы использовали android:stopWithTask="true". Теперь нам нужно, чтобы Служба запускалась так, как она есть, даже если запущенная Задание была удалена из списка последних приложений. Поэтому я изменил Сервис, включив android:stopWithTask="false". Но это не работает.

Связанный код:

Вот часть, относящаяся к Сервису:

<service
    android:enabled="true"
    android:name=".MyService"
    android:exported="false"
    android:stopWithTask="false" />

В MyService.java:

public class MyService extends AbstractService {

    @Override
    public void onStartService() {
        Intent intent = new Intent(this, MyActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
        Notification notification = new Notification(R.drawable.ic_launcher, "My network services", System.currentTimeMillis());
        notification.setLatestEventInfo(this, "AppName", "Message", pendingIntent);
        startForeground(MY_NOTIFICATION_ID, notification);  
    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        Toast.makeText(getApplicationContext(), "onTaskRemoved called", Toast.LENGTH_LONG).show();
        System.out.println("onTaskRemoved called");
        super.onTaskRemoved(rootIntent);
    }
}

AbstractService.java - это пользовательский класс, который расширяет Sevrice:

public abstract class AbstractService extends Service {

    protected final String TAG = this.getClass().getName();

    @Override
    public void onCreate() {
        super.onCreate();
        onStartService();
        Log.i(TAG, "onCreate(): Service Started.");
    }

    @Override
    public final int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG, "onStarCommand(): Received id " + startId + ": " + intent);
        return START_STICKY; // run until explicitly stopped.
    }

    @Override
    public final IBinder onBind(Intent intent) {
        return m_messenger.getBinder();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        onStopService();
        Log.i(TAG, "Service Stopped.");
    }    

    public abstract void onStartService();
    public abstract void onStopService();
    public abstract void onReceiveMessage(Message msg);

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        Toast.makeText(getApplicationContext(), "AS onTaskRemoved called", Toast.LENGTH_LONG).show();
        super.onTaskRemoved(rootIntent);
    }
}

Теперь, если я вхожу в приложение, запускается MyService. После этого я нажимаю кнопку "Домой", поэтому приложение перемещается в фоновый режим. Теперь я удаляю приложение из списка недавних приложений. В это время я должен увидеть сообщение Toast и консоль, как описано в этом методе:

public void onTaskRemoved (Intent rootIntent)

Добавлен в уровень API 14

Это вызывается, если служба в настоящее время запущена, и пользователь имеет удалена задача, которая поступает из приложения-службы. Если у вас есть установите ServiceInfo.FLAG_STOP_WITH_TASK, тогда вы не получите этого Перезвони; вместо этого служба будет просто остановлена.

Параметры rootIntent Исходный корень, который использовался для запустите задачу, которая удаляется.

Но я не вижу ничего подобного. Служба возвращает START_STICKY в onStartCommand, поэтому я думаю, что onTaskRemoved должен быть запущен вместе с флагом android:stopWithTask="false".

Я что-то пропустил?

Сообщите мне, если мне нужно добавить код, который может быть важным для выяснения того, что неправильно.

P.S.: Я тестировал это на 4.2.2 до сих пор.

P.S.: Я только что протестировал тот же код в 4.1.2, на котором Служба продолжает работать, и я получаю сообщение "onTaskRemoved called" в журнале тоже.

Что делать, чтобы сделать эту работу во всех версиях?

4b9b3361

Ответ 1

Просто следуйте этим сценариям, ваш сервис и процессы (потоки внутри вашего сервиса) будут оставаться непрерывными.

  1. Создайте сервис и используйте START_STICKY в качестве возвращаемого значения в методе onStartCommand, как показано ниже:

    @Override
    public int onStartCommand(final Intent intent, 
                              final int flags,
                              final int startId) {
    
        //your code
        return START_STICKY;
    }  
    
  2. Приведенный выше код перезапустит службу, если она будет уничтожена и всегда будет работать, но процесс (потоки), запущенный из службы, перестанет работать, если ваше приложение будет удалено из последних приложений. Чтобы ваши процессы (потоки) всегда оставались в рабочем состоянии, вы должны переопределить метод onTaskRemoved() и добавить код для перезапуска задач, как показано ниже.

    @Override
    public void onTaskRemoved(Intent rootIntent){
        Intent restartServiceTask = new Intent(getApplicationContext(),this.getClass());
        restartServiceTask.setPackage(getPackageName());    
        PendingIntent restartPendingIntent =PendingIntent.getService(getApplicationContext(), 1,restartServiceTask, PendingIntent.FLAG_ONE_SHOT);
        AlarmManager myAlarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
        myAlarmService.set(
                AlarmManager.ELAPSED_REALTIME,
                SystemClock.elapsedRealtime() + 1000,
                restartPendingIntent);
    
        super.onTaskRemoved(rootIntent);
    }
    
  3. Запустите сервис, как показано ниже

startService (новый Intent (это, YourService.class));

Ответ 2

В свою службу добавьте следующий код. Это прекрасная работа для меня в 4.4.2

Вот обходной путь, с которым я столкнулся, и хорошо работает для повторного запуска службы, если его процесс был убит при закрытии приложения.

 @Override public void onTaskRemoved(Intent rootIntent){
     Intent restartServiceIntent = new Intent(getApplicationContext(), this.getClass());

     PendingIntent restartServicePendingIntent = PendingIntent.getService(
         getApplicationContext(), 1, restartServiceIntent, PendingIntent.FLAG_ONE_SHOT);
     AlarmManager alarmService = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
     alarmService.set(ELAPSED_REALTIME, elapsedRealtime() + 1000,
         restartServicePendingIntent);

     super.onTaskRemoved(rootIntent); 
}

Ответ 3

Если вы привязываетесь к своей службе из подкласса класса Application и поддерживаете соединение с IBinder, служба останется в живых даже после удаления приложения из последних приложений.

Ответ 4

Напишите 5 строк, которые я добавил в oncreate() класса обслуживания

Вот так:

public class AlarmService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Intent iHeartBeatService = new Intent(AlarmService.this,
                AlarmService.class);
        PendingIntent piHeartBeatService = PendingIntent.getService(this, 0,
                iHeartBeatService, PendingIntent.FLAG_UPDATE_CURRENT);
        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        alarmManager.cancel(piHeartBeatService);
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
                System.currentTimeMillis(), 1000, piHeartBeatService);

    }
}

или

попробуйте этот

public class MyService extends Service{


    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        super.onCreate();
        System.out.println("service created");
    }

    @SuppressLint("NewApi")
    @Override
    public void onTaskRemoved(Intent rootIntent) {
        // TODO Auto-generated method stub
        System.out.println("onTaskRemoved");
        super.onTaskRemoved(rootIntent);

    }

    @Override
    @Deprecated
    public void onStart(Intent intent, int startId) {
        // TODO Auto-generated method stub
        super.onStart(intent, startId);
        System.out.println("Service started");
        new Handler().postDelayed(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                System.out.println("Service is running");
            }
        }, 5000);
    }

}

Ответ 5

Похоже, что выключение приложения из "недавних задач" убивает все, что связано.

Возможно, вам стоит взглянуть туда, чтобы найти способ перезапуска вашего сервиса, если он остановится: fooobar.com/info/99450/...