LoginSignup
50
48

More than 5 years have passed since last update.

BroadcastReceiverの処理結果を受け取る方法

Last updated at Posted at 2014-08-11

BroadcastReceiverの処理結果が取れる?

ある日、BroadcastReceiver.setResult()があることに気がついた。
ずっとBroadcastの結果は取れないものだと思っていたが、Context.sendOrderedBroadcast()を使用することでその結果を受け取ることができるようだ。

概要

大まかな処理手順はこうだ。
まず、sendOrderedBroadcast()ではBroadcastReceiverがその優先順位にしたがって呼び出される。
それぞれのBroadcastReceiveronReceive()の最後にsetResult()によって処理結果を追記する。
sendOrderedBroadcast()では一番最後に処理を行うBroadcastReceiverを直接指定することができるため、そのonReceive()の中でgetResultCode(),getResultData(),getResultExtras()を参照することですべてのBroadcastの最終的な処理結果を受け取ることができる。

優先順位設定

Broadcastの優先順位はIntentFilter.setPriority()で行う。
数字の大きいものが優先度が高く、デフォルトは0。
おそらくIntentFilter.SYSTEM_HIGH_PRIORITYからIntentFilter.SYSTEM_LOW_PRIORITYの間で設定したほうが良いと思う。

BroadcastReceiver receiver = new MyBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(MY_ACTION);
// 優先度を高めに設定
intentFilter.setPriority(100);
registerReceiver(receiver, intentFilter);

BroadcastReceiverの実装

BroadcastReceiver側の処理はsetResult系の処理をする事以外は何もしなくて良い。
先に実行されたBroadcastReceiverの処理結果はgetResultCode(),getResultData(),getResultExtras()で取得できる。
setResult()した場合、値はすべて上書きされることに注意

    @Override
    public void onReceive(Context context, Intent intent) 
    {
        // onReceive処理

        // 前のBroadcastReceiverの判定を引き継ぐ
        setResultCode(getResultCode());

        // Extrasに何か入れてみる
        // 引数をtrueにするとnullの場合自動生成してくれる
        Bundle extras = getResultExtras(true);
        extras.putString("key", "value");
        setResultExtras(extras);
    }

何らかの理由で以降のBroadcastReceiverを実行しないようにするにはabortBroadcast()で以降のBroadcastに処理が伝達されないようにすれば良い。
ただし、確実に止められるのは自分より優先度が低いBroadcastReceiverのみとなる。
優先度が等しいBroadcastReceiverは自分より前に実行されている可能性があるため。

    @Override
    public void onReceive(Context context, Intent intent) 
    {
        // onReceive処理

        if(FAILED){
            // 失敗したのでこのReceiverで処理を終了したい

            // RESULT_CANCELEDにするのが良いかも?
            setResultCode(Activity.RESULT_CANCELED);

            // これより優先順位が低いBroadcastReceiverは実行されない
            abortBroadcast();
        }
    }

Broadcastの送信

Context.sendOrderedBroadcast()は2種類あるが、処理結果を扱えるのは1種類だけだ。
引数が多いが、第3引数のresultReceiverが最後に実行されるBroadcastReceiverになる。initial〜系の引数は処理結果のデフォルト値を格納する。

public abstract void sendOrderedBroadcast (Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)

結果は当然、resultReceiverに指定したBroadcastReceiverで受け取る。
abortBroadcast()された場合でもresultReceiverは実行されるようだ。
(IntentFilterでBroadcastを受信しているわけではないので当然か)

    @Override
    public void onReceive(Context context, Intent intent) 
    {
        // 処理結果
        getResultCode();
        getResultData();
        getResultExtras(false);
    }

まとめ

便利そうだけど使い道が思いつかない。
システムならともかく、アプリでどう使うべきなんだろう。

50
48
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
50
48