作業ステータスを報告する

このガイドでは、バックグラウンド サービスで実行された処理リクエストのステータスを、リクエストを送信したコンポーネントに報告する方法について説明します。これにより、たとえば、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 のサブクラスを使用します。サブクラスで、LocalBroadcastManagerIntent を受け取ったときに呼び出す BroadcastReceiver.onReceive() コールバック メソッドを実装します。LocalBroadcastManager は、受信した IntentBroadcastReceiver.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");
        ...

BroadcastReceiverIntentFilter をシステムに登録するには、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 は開始または再開されません。ActivityBroadcastReceiver は、アプリがバックグラウンドで実行されている場合でも Intent オブジェクトを受け取って処理しますが、強制的にフォアグラウンドにすることはありません。アプリが表示されていない間にバックグラウンドで発生したイベントをユーザーに通知する場合は、Notification を使用します。受信ブロードキャスト Intent に応じて、Activity を開始しないでください