web-dev-qa-db-ja.com

フォアグラウンドとして実行されているサービスを停止する適切な方法は何ですか

フォアグラウンドサービスとして実行されているサービスを停止しようとしています。

現在の問題は、stopService()を呼び出したときに通知がまだ残っていることです。

したがって、私のソリューションでは、onCreate()内に登録するレシーバーを追加しました。

onReceive()メソッド内でstopforeground(true)を呼び出し、通知を非表示にします。そして、stopself()でサービスを停止します。

onDestroy()内で、レシーバーの登録を解除しました。

これを処理するより適切な方法はありますか? stopService()が機能しないためです。

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

アクティビティからstartService(intent)を呼び出して、キーを表すデータをサービスの停止に渡します。

サービスからstopForeground(true)を呼び出し、その直後にstopSelf()を呼び出します。

51
Ilya Gazman

アクティビティからフォアグラウンドサービスを開始および停止するには:

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

他の回答に加えて、私は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()を呼び出すことを許可します。ただし、アプリは、サービスの作成後5秒以内にそのサービスのstartForeground()メソッドを呼び出す必要があります。

https://developer.Android.com/about/versions/oreo/Android-8.0-changes.html

1
Nerius Jok

ここに記載されているとおり: https://developer.Android.com/guide/components/services#Stopping

開始されたサービスは、独自のライフサイクルを管理する必要があります。つまり、システムはシステムメモリを回復する必要があり、onStartCommand()が戻った後もサービスの実行を継続しない限り、サービスを停止または破棄しません。サービスは、stopSelf()を呼び出すことによって自身を停止する必要があります。または、別のコンポーネントがstopService()

stopSelf()またはstopService()で停止するように要求されると、システムはできるだけ早くサービスを破棄します。

したがって、startService()の呼び出しに使用したアクティビティからstopService()を呼び出すことができます。私はここでそれをやった:

start_button.setOnClickListener {
        applicationContext.startForegroundService(Intent(this, ServiceTest::class.Java))
    }
    stop_button.setOnClickListener {
        applicationContext.stopService(Intent(this, ServiceTest::class.Java))
    }

サービスを開始および停止する2つのボタンを作成しましたが、機能します。

1
Ahmed Shahid

サービスを停止してから通知を更新する場合は、最初に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);
    }
0
LincyTonita

サービスを停止する最良の方法は、サービス自体を停止することです。これにより、実際に停止し、データの整合性が維持されることが確実になります。あなたが外部(アクティビティ)からそれをしたい場合、私は通常グローバルな静的属性を使用します。

ここで私の答えを確認してください: https://stackoverflow.com/a/57833370/7795547

0
D Dimitrov