Продолжить службу, даже если приложение очищено от последнего приложения
У меня небольшая проблема.
В моем приложении Служба запускается после успешного входа пользователя в систему. Раньше служба должна была прекратиться, если приложение было убито. (скажем, удалены из списка последних приложений путем прокрутки.) Таким образом, мы использовали 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" в журнале тоже.
Что делать, чтобы сделать эту работу во всех версиях?
Ответы
Ответ 1
Просто следуйте этим сценариям, ваш сервис и процессы (потоки внутри вашего сервиса) будут оставаться непрерывными.
-
Создайте сервис и используйте START_STICKY в качестве возвращаемого значения в методе onStartCommand, как показано ниже:
@Override
public int onStartCommand(final Intent intent,
final int flags,
final int startId) {
//your code
return START_STICKY;
}
-
Приведенный выше код перезапустит службу, если она будет уничтожена и всегда будет работать, но процесс (потоки), запущенный из службы, перестанет работать, если ваше приложение будет удалено из последних приложений. Чтобы ваши процессы (потоки) всегда оставались в рабочем состоянии, вы должны переопределить метод 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);
}
- Запустите сервис, как показано ниже
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/...