web-dev-qa-db-ja.com

ブロードキャストインテント/ブロードキャストレシーバーを使用して、サービスからアクティビティにメッセージを送信する

だから私は、放送の意図とそれらへのメッセージの受信について理解しています(私は思う)。

だから今、私の問題/私が解決できないのは、レシーバのonReceiveメソッドからアクティビティにメッセージを送信する方法です。私はそのような受信機を持っているとしましょう:

public class ReceiveMessages extends BroadcastReceiver 
{
@Override
   public void onReceive(Context context, Intent intent) 
   {    
       String action = intent.getAction();
       if(action.equalsIgnoreCase(TheService.DOWNLOADED)){    
           // send message to activity
       }
   }
}

アクティビティにメッセージを送信するにはどうすればよいですか?

メッセージを送信し、何らかの方法で監視したいアクティビティでレシーバーをインスタンス化する必要がありますか?または何?私は概念を理解していますが、実際にはアプリケーションを理解していません。

どんな助けでも絶対に素晴らしいでしょう、ありがとう。

トム

47
Thomas Clayson

[〜#〜] edited [〜#〜]BroadcastReceiverの登録/登録解除のコード例を修正し、マニフェスト宣言も削除しました。

ReceiveMessagesからのメッセージをリッスンする必要があるActivity内の内部クラスとしてServiceを定義します。

次に、次のようなクラス変数を宣言します...

_ReceiveMessages myReceiver = null;
Boolean myReceiverIsRegistered = false;
_

onCreate()myReceiver = new ReceiveMessages();を使用します

次に、onResume()...

_if (!myReceiverIsRegistered) {
    registerReceiver(myReceiver, new IntentFilter("com.mycompany.myapp.SOME_MESSAGE"));
    myReceiverIsRegistered = true;
}
_

...およびonPause()...

_if (myReceiverIsRegistered) {
    unregisterReceiver(myReceiver);
    myReceiverIsRegistered = false;
}
_

ServiceIntentを作成してブロードキャストします...

_Intent i = new Intent("com.mycompany.myapp.SOME_MESSAGE");
sendBroadcast(i);
_

そしてそれはそれについてです。私の例のように、パッケージ/アプリに固有の「アクション」、つまり_com.mycompany..._を作成します。これにより、他のアプリやシステムコンポーネントが処理しようとする状況を回避できます。

70
Squonk

違反はありませんが、あなたの質問はまだあいまいです。それで、私はシナリオの全体の混乱を概説し、あなたが持っていると思うどんな問題でもそれらの1つが実際にヒットすることを望みます。

シナリオA:アクティビティのみ

フォアグラウンドでアクティビティがあるときにのみブロードキャストを受信する必要がある場合は、registerReceiver()を使用してアクティビティにBroadcastReceiverを登録させます。 @MisterSquonkが示したように、onResume()でレシーバーを登録し、onPause()でレシーバーの登録を解除します。

シナリオB:フォアグラウンドの場合、その他の場合のアクティビティ。注文放送

フォアグラウンドアクティビティでブロードキャストを処理したいが、そのアクティビティがフォアグラウンドにない場合(たとえば、Notificationを上げる)、ブロードキャストが順序付けされたブロードキャスト(たとえば、着信SMS)、シナリオAソリューションを引き続き使用しますが、優先度の高いIntentFilterを使用します(setPriority()を参照)。さらに、マニフェストの_<receiver>_要素を介してBroadcastReceiverを登録し、同じブロードキャストに対して優先度の低い_<intent-filter>_を使用します。アクティビティのBroadcastReceiverで、abortBroadcast()を呼び出してイベントを消費し、マニフェストに登録されたBroadcastReceiverに到達しないようにします。

シナリオC:フォアグラウンドの場合はアクティビティ、その他の場合はアクティビティ。定期放送

シナリオBがほぼ適合しているが、聴いているブロードキャストが順序付けされたブロードキャストではない場合、シナリオBから開始する必要があります。ただし、両方の受信者がそれぞれのフィルターに持つブロードキャストは、 @MisterSquonkが提案したアクション文字列。さらに、マニフェストにanotherBroadcastReceiverを登録します。_<intent-filter>_は、聴いている実際のブロードキャスト用です。そのレシーバーは、単にsendOrderedBroadcast()を呼び出して、他のレシーバーがリッスンしている順序付けられたブロードキャストを送信します。

シナリオD:前景に関係なくアクティビティ

自分のアクティビティの一部がブロードキャストについて知る必要があり、それがフォアグラウンドにあるかどうかは関係ない場合、それが意味することを再考する必要があります。通常、これは実際にブロードキャストが何らかの形でデータモデルに影響を与えることを意味します。その場合、懸念はnotアクティビティを知らせることではなく、データモデルを更新し、既存の「アクティビティにデータモデルの変更について知らせる」ロジックが残りを処理します。

ただし、これがデータモデルの一部ではないと確信している場合は、シナリオBまたはシナリオCを実装し、静的データメンバーにいくつかの情報を貼り付けることができます。アクティビティは、onResume()の静的データメンバーを調べて、フォアグラウンドに戻ったときにブロードキャストに関する情報を取得できます。

「しかし、もし私のプロセスがブロードキャストとフォアグラウンドに来る他のアクティビティとの間で終了したらどうなるでしょうか?」と考えているなら、あなたのブロードキャストは本当にisこのシナリオ。

「しかし、バックグラウンドで作業を行っているアクティビティを更新したい」と考えている場合、問題のアクティビティは壊れています。アクティビティがバックグラウンドで作業を行うことはありません。その作業は何らかの形式のサービスに委任する必要があり、サービスへのブロードキャストを取得するための関連する一連のシナリオがあります。

68
CommonsWare

インテントをブロードキャストするには:

Intent intent = new Intent("com.yourcompany.testIntent");
intent.putExtra("value","test");
sendBroadcast(intent);

同じ意図を受け取るには:

IntentFilter filter = new IntentFilter("com.yourcompany.testIntent");
        BroadcastReceiver receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
              String value =  intent.getExtras().getString("value");
            }
        };
registerReceiver(receiver, filter);
17
AlexA

質問の時点ではおそらく関係ありませんが、Androidサポートパッケージに LocalBroadcastManager があります。

通常のブロードキャストとほとんど同じように機能しますが、すべての「チャタリング」は実行中のアプリに対してローカルです。

利点:

  • ブロードキャストしているデータがアプリを離れることはないので、プライベートデータの漏洩について心配する必要はありません。
  • 他のアプリケーションがこれらのブロードキャストをアプリに送信することはできないため、セキュリティホールが悪用される可能性を心配する必要はありません。
  • システムを介してグローバルブロードキャストを送信するよりも効率的です。

例:

Intent i = new Intent("my.local.intent");
LocalBroadcastManager.getInstance(context).sendBroadcast(i);

そして受け取る

receiver = new MyBroadcastReceiverToHandleLocalBroadcast();

IntentFilter i = new IntentFilter();
i.addAction("my.local.intent");
LocalBroadcastManager.getInstance(context).registerReceiver(receiver, i);
8
Kuffs