このガイドでは、バックグラウンド サービスで実行された作業リクエストのステータスを、そのリクエストを送信したコンポーネントに報告する方法について説明します。これにより、たとえば Activity
オブジェクトの UI 内で、リクエストのステータスを報告できるようになります。ステータスの送受信には、LocalBroadcastManager
を使用することをおすすめします。これは、ブロードキャスト Intent
オブジェクトの対象をアプリ内のコンポーネントに制限します。
JobIntentService からステータスを報告する
JobIntentService
内の作業リクエストのステータスを他のコンポーネントに送信するには、まず、拡張データ内にステータスを格納する Intent
を作成します。必要に応じて、この Intent
にアクションやデータ URI を追加します。
次に、LocalBroadcastManager.sendBroadcast()
を呼び出して Intent
を送信します。Intent
は、それを受信するように登録されているアプリ内のコンポーネントに送信されます。LocalBroadcastManager
のインスタンスを取得するには、getInstance()
を呼び出します。
たとえば、次のようになります。
Kotlin
... // Defines a custom Intent action const val BROADCAST_ACTION = "com.example.android.threadsample.BROADCAST" ... // Defines the key for the status "extra" in an Intent const val EXTENDED_DATA_STATUS = "com.example.android.threadsample.STATUS" ... class RSSPullService : JobIntentService() { ... /* * Creates a new Intent containing a Uri object * BROADCAST_ACTION is a custom Intent action */ val localIntent = Intent(BROADCAST_ACTION).apply { // Puts the status into the Intent putExtra(EXTENDED_DATA_STATUS, status) } // Broadcasts the Intent to receivers in this app. LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent) ... }
Java
public final class Constants { ... // Defines a custom Intent action public static final String BROADCAST_ACTION = "com.example.android.threadsample.BROADCAST"; ... // Defines the key for the status "extra" in an Intent public static final String EXTENDED_DATA_STATUS = "com.example.android.threadsample.STATUS"; ... } public class RSSPullService extends JobIntentService { ... /* * Creates a new Intent containing a Uri object * BROADCAST_ACTION is a custom Intent action */ Intent localIntent = new Intent(Constants.BROADCAST_ACTION) // Puts the status into the Intent .putExtra(Constants.EXTENDED_DATA_STATUS, status); // Broadcasts the Intent to receivers in this app. LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent); ... }
次に、元の作業リクエストを送信したコンポーネント内の受信ブロードキャスト Intent
オブジェクトを処理します。
JobIntentService からステータス ブロードキャストを受信する
ブロードキャスト Intent
オブジェクトを受信するには、BroadcastReceiver
のサブクラスを使用します。このサブクラス内に、BroadcastReceiver.onReceive()
コールバック メソッドを実装します。これは、LocalBroadcastManager
が Intent
を受信したときに呼び出すメソッドです。LocalBroadcastManager
は、受信 Intent
を BroadcastReceiver.onReceive()
に渡します。
たとえば、次のようになります。
Kotlin
// Broadcast receiver for receiving status updates from the IntentService. private class DownloadStateReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { ... /* * Handle Intents here. */ ... } }
Java
// Broadcast receiver for receiving status updates from the IntentService. private class DownloadStateReceiver extends BroadcastReceiver { // Called when the BroadcastReceiver gets an Intent it's registered to receive @Override public void onReceive(Context context, Intent intent) { ... /* * Handle Intents here. */ ... } }
BroadcastReceiver
を定義したら、それに対し、特定のアクションや、カテゴリ、データとの照合を行うフィルタを定義できます。そのためには、IntentFilter
を作成します。フィルタを定義する方法を次のスニペットに示します。
Kotlin
// Class that displays photos class DisplayActivity : FragmentActivity() { ... override fun onCreate(savedInstanceState: Bundle?) { ... super.onCreate(savedInstanceState) ... // The filter's action is BROADCAST_ACTION var statusIntentFilter = IntentFilter(BROADCAST_ACTION).apply { // Adds a data filter for the HTTP scheme addDataScheme("http") } ...
Java
// Class that displays photos public class DisplayActivity extends FragmentActivity { ... public void onCreate(Bundle stateBundle) { ... super.onCreate(stateBundle); ... // The filter's action is BROADCAST_ACTION IntentFilter statusIntentFilter = new IntentFilter( Constants.BROADCAST_ACTION); // Adds a data filter for the HTTP scheme statusIntentFilter.addDataScheme("http"); ...
BroadcastReceiver
と IntentFilter
をシステムに登録するには、LocalBroadcastManager
のインスタンスを取得して、その registerReceiver()
メソッドを呼び出します。BroadcastReceiver
とその IntentFilter
を登録する方法を次のスニペットに示します。
Kotlin
// Instantiates a new DownloadStateReceiver val downloadStateReceiver = DownloadStateReceiver() // Registers the DownloadStateReceiver and its intent filters LocalBroadcastManager.getInstance(this) .registerReceiver(downloadStateReceiver, statusIntentFilter) ...
Java
// Instantiates a new DownloadStateReceiver DownloadStateReceiver downloadStateReceiver = new DownloadStateReceiver(); // Registers the DownloadStateReceiver and its intent filters LocalBroadcastManager.getInstance(this).registerReceiver( downloadStateReceiver, statusIntentFilter); ...
1 つの BroadcastReceiver
で複数のタイプのブロードキャスト Intent
オブジェクトを処理できます。このオブジェクトは、それぞれ独自のアクションを持ちます。この機能により、アクションごとに異なるコードを実行できます。その際、アクションごとに個別の BroadcastReceiver
を定義する必要はありません。同じ BroadcastReceiver
に対して別の IntentFilter
を定義するには、IntentFilter
を作成して、registerReceiver()
の呼び出しを繰り返します。たとえば、次のようになります。
Kotlin
/* * Instantiates a new action filter. * No data filter is needed. */ statusIntentFilter = IntentFilter(ACTION_ZOOM_IMAGE) // Registers the receiver with the new filter LocalBroadcastManager.getInstance(this) .registerReceiver(downloadStateReceiver, statusIntentFilter)
Java
/* * Instantiates a new action filter. * No data filter is needed. */ statusIntentFilter = new IntentFilter(Constants.ACTION_ZOOM_IMAGE); // Registers the receiver with the new filter LocalBroadcastManager.getInstance(this).registerReceiver( downloadStateReceiver, statusIntentFilter);
ブロードキャスト Intent
送信しても、Activity
の起動や再開は行われません。Activity
の BroadcastReceiver
は、アプリがバックグラウンドにある場合でも、Intent
オブジェクトを受信して処理します。アプリをフォアグラウンドに移すことはありません。アプリが表示されていないときにバックグラウンドで発生したイベントをユーザーに通知するには、Notification
を使用します。受信ブロードキャスト Intent
へのレスポンスとして Activity
を起動しないでください。