Ответ 1
Из вашей деятельности позвоните startService(intent)
и передайте ему некоторые данные, которые будут представлять собой ключ для остановки службы.
Позвоните в сервисную службу stopForeground(true)
, а затем stopSelf()
сразу после нее.
Я пытаюсь остановить службу, которая работает как служба переднего плана.
Текущая проблема заключается в том, что при вызове stopService()
уведомление все еще остается.
Итак, в моем решении я добавил ресивер, который я регистрирую внутри onCreate()
Внутри метода onReceive()
я вызываю stopforeground(true)
и скрывает это уведомление.
И затем stopself()
, чтобы остановить службу.
Внутри onDestroy()
я не зарегистрировал приемник.
Есть ли более правильный способ справиться с этим? потому что stopService() просто не работает.
@Override
public void onDestroy(){
unregisterReceiver(receiver);
super.onDestroy();
}
Из вашей деятельности позвоните startService(intent)
и передайте ему некоторые данные, которые будут представлять собой ключ для остановки службы.
Позвоните в сервисную службу stopForeground(true)
, а затем stopSelf()
сразу после нее.
Чтобы запустить и остановить службу переднего плана от использования активности:
//start
Intent startIntent = new Intent(MainActivity.this, ForegroundService.class);
startIntent.setAction(Constants.ACTION.STARTFOREGROUND_ACTION);
startService(startIntent);
//stop
Intent stopIntent = new Intent(MainActivity.this, ForegroundService.class);
stopIntent.setAction(Constants.ACTION.STOPFOREGROUND_ACTION);
startService(stopIntent);
в службе переднего плана - используйте (как минимум) этот код:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getAction().equals(Constants.ACTION.STARTFOREGROUND_ACTION)) {
Log.i(LOG_TAG, "Received Start Foreground Intent ");
// your start service code
}
else if (intent.getAction().equals( Constants.ACTION.STOPFOREGROUND_ACTION)) {
Log.i(LOG_TAG, "Received Stop Foreground Intent");
//your end servce code
stopForeground(true);
stopSelf();
}
return START_STICKY;
}
Как указано здесь: https://developer.android.com/guide/components/services#Stopping
Запущенный сервис должен управлять своим жизненным циклом. Таким образом, система не останавливает и не уничтожает службу, если она не восстанавливает системную память, а служба продолжает работать после возврата onStartCommand(). Служба должна остановить себя, вызвав stopSelf(), иначе другой компонент может остановить его, вызвав stopService().
Получив запрос на остановку с помощью stopSelf() или stopService(), система уничтожит службу как можно скорее.
Таким образом, вы можете вызвать stopService() из действия, которое вы использовали для вызова startService(). Я сделал это прямо здесь:
start_button.setOnClickListener {
applicationContext.startForegroundService(Intent(this, ServiceTest::class.java))
}
stop_button.setOnClickListener {
applicationContext.stopService(Intent(this, ServiceTest::class.java))
}
Я создал две кнопки для запуска и остановки службы, и она работает.
В дополнение к другим ответам я закончил с этим фрагментом, используя Android Oreo и более поздние версии, чтобы остановить сервисы работы.
Intent intent = new Intent(getApplicationContext(), LocationService.class);
intent.setAction(status);
ContextCompat.startForegroundService(getApplicationContext(), intent);
И в обслуживании
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
startForeground(121, notification);
if (intent.getAction().equals("StopService")) {
stopForeground(true);
stopSelf();
}
startForeground() обязателен, если приложение не завершит работу без вызова
Новый метод Context.startForegroundService() запускает передний план оказание услуг. Система позволяет приложениям звонить Context.startForegroundService(), даже когда приложение находится в фон. Тем не менее, приложение должно вызвать эту услугу Метод startForeground() в течение пяти секунд после создано.
https://developer.android.com/about/versions/oreo/android-8.0-changes.html
Если вы хотите остановить службу, а затем обновить уведомление, вы можете сначала вызвать stopSelf(), а затем notify(). stopForeground (false) делает уведомление отменяемым.
private final BroadcastReceiver myBgWorkCompleteReceiver= new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
stopSelf();
notificationLayoutExpanded.setTextViewText(R.id.file_download_notify_download_percentage, "Background work completed");
manager.notify(mNotificationId, notification);
stopForeground(false);
}
};
public void onDestroy() {
super.onDestroy();
// cancel any running threads here
LocalBroadcastManager.getInstance(this).unregisterReceiver(myBgWorkCompleteReceiver);
}
Я нашел лучший способ остановить службу, чтобы остановить себя. Таким образом, вы уверены, что он действительно остановит и сохранит целостность данных. Если вы хотите сделать это извне (активность), я обычно использую глобальный статический атрибут.
Проверьте мой ответ здесь: fooobar.com/info/394902/...