2012年11月13日火曜日

BroadcastReceiverからServiceを操作する方法

BroadcastReceiverからServiceを操作には、どうしたらすんなり行くだろうかと考えた。

1. BroadcastReceiverの中にクラス変数を持って、Service側で都度参照する
⇒ポーリングするのは気持ち悪い

2. BroadcastReceiverからServiceにBindして、Service内のメソッドを呼ぶ
⇒BroadcastReceiver内の処理で、Bindしてからメソッド呼ぶまで待機とかしたくない。

てな感じで、別の方法を探していたら普通に公式リファレンスに書いてありました。

Receiver Lifecycle の部分から抜粋

"In particular, you may not show a dialog or bind to a service from within a BroadcastReceiver. For the former, you should instead use the NotificationManager API. For the latter, you can use Context.startService() to send a command to the service."

ざっくり訳すと、
特に、BroadcastReceiver内でダイアログを表示したりServiceにBindするべきじゃない。前者(ダイアログ表示)については代わりに"NotificationManager API"を使うべきだし、後者(サービスにバインド)については"Context.startService()"を使ってサービスにコマンドを送るべきだ。
でしょうか。

すっかり頭の中で、Serviceに何かさせるときはBindって凝り固まっていたので、startServiceで送られてくるのがIntentだって事を忘れていました。

実装例として、スクリーンがオフになった時にSampleServiceを操作する場合、こんな感じ。

BroadcastReceiverをextendsしたクラスで

@Override
public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();

    if (action.equals(Intent.ACTION_SCREEN_OFF)) {

        Intent startServiceIntent = new Intent(context,SampleService.class);
        startServiceIntent.putExtra(SampleService.REQUEST_TYPE, SampleService.REQUEST_PROCESS);
        context.startService(startServiceIntent);
    }
}

SampleService (extends Service) で
public static final String REQUEST_TYPE = "requestType";
public static final int REQUEST_PROCESS = 1;

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    // intentがnullで渡される場合もあるのでチェック
    if (intent != null && intent.getIntExtra(REQUEST_TYPE, 0) == REQUEST_PROCESS) {
        hogehoge(); // 任意のメソッド
    }

    ...

}


こんな感じでうまく動きました。


0 件のコメント:

コメントを投稿