Каков правильный способ остановить работу службы на переднем плане

Я пытаюсь остановить службу, которая работает как служба переднего плана.

Текущая проблема заключается в том, что при вызове stopService() уведомление все еще остается.

Итак, в моем решении я добавил ресивер, который я регистрирую внутри onCreate()

Внутри метода onReceive() я вызываю stopforeground(true) и скрывает это уведомление. И затем stopself(), чтобы остановить службу.

Внутри onDestroy() я не зарегистрировал приемник.

Есть ли более правильный способ справиться с этим? потому что stopService() просто не работает.

@Override
public void onDestroy(){
  unregisterReceiver(receiver);
  super.onDestroy();
}

Ответ 1

Из вашей деятельности позвоните startService(intent) и передайте ему некоторые данные, которые будут представлять собой ключ для остановки службы.

Позвоните в сервисную службу stopForeground(true), а затем stopSelf() сразу после нее.

Ответ 2

Чтобы запустить и остановить службу переднего плана от использования активности:

//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;
}

Ответ 3

Как указано здесь: 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))
    }

Я создал две кнопки для запуска и остановки службы, и она работает.

Ответ 4

В дополнение к другим ответам я закончил с этим фрагментом, используя 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

Ответ 5

Если вы хотите остановить службу, а затем обновить уведомление, вы можете сначала вызвать 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);
    }

Ответ 6

Я нашел лучший способ остановить службу, чтобы остановить себя. Таким образом, вы уверены, что он действительно остановит и сохранит целостность данных. Если вы хотите сделать это извне (активность), я обычно использую глобальный статический атрибут.

Проверьте мой ответ здесь: fooobar.com/info/394902/...