簡體   English   中英

使用廣播意圖/廣播接收器將消息從服​​務發送到活動

[英]Using a broadcast intent/broadcast receiver to send messages from a service to an activity

所以我理解(我認為)關於廣播意圖和接收消息給他們。

所以現在,我的問題/我無法解決的問題是如何從接收器的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
       }
   }
}

我如何向活動發送消息?

我是否必須在我想要發送消息的活動中實例化接收器並以某種方式監視它? 或者是什么? 我理解這個概念,但不是真正的應用程序。

任何幫助都會非常棒,謝謝。

湯姆

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;
}

Service創建並廣播Intent ...

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

這就是它。 讓'action'對你的包/ app來說是唯一的,就像我的例子中的com.mycompany...一樣。 這有助於避免其他應用程序或系統組件可能嘗試處理它的情況。

沒有冒犯,但你的問題仍然模糊不清。 所以,我將概述一堆亂七八糟的場景,希望其中一個實際上能夠解決你認為的任何問題。

場景A:僅活動

如果您只需要在前台有活動時接收廣播,請讓活動使用registerReceiver()注冊BroadcastReceiver 正如@MisterSquonk所指出的那樣,你將在onResume()注冊接收器並在onPause()注銷它。

情景B:活動如果在前景,其他; 有序廣播

如果您希望前台活動處理廣播,但如果該活動不在前台(例如,提出Notification ),並且廣播是有序廣播(例如,傳入SMS),則您希望發生其他事情,那么您仍將使用Scenario A解決方案,但具有更高優先級的IntentFilter (請參閱setPriority() )。 此外,您將通過清單中的<receiver>元素注冊BroadcastReceiver ,並為同一廣播使用較低優先級的<intent-filter> 在活動的BroadcastReceiver ,調用abortBroadcast()來使用該事件並阻止它到達清單注冊的BroadcastReceiver

情景C:活動如果在前景,其他; 定期廣播

如果場景B幾乎適合,但您正在收聽的廣播不是有序廣播,則需要從場景B開始。但是,讓兩個接收者在其各自的過濾器中擁有的廣播是您自己的廣播,使用私有@MisterSquonk建議的動作字符串。 此外,在清單中注冊了另一個 BroadcastReceiver ,其<intent-filter>用於您正在偵聽的真實廣播。 該接收器將簡單地調用sendOrderedBroadcast()來發送其他接收器正在偵聽的有序廣播。

情景D:活動無論前景如何

如果您的某些活動需要了解廣播,並且它是否在前台並不重要,您需要重新考慮您的意思。 通常情況下,這實際上意味着廣播影響某種方式對你的數據模型,在這種情況下,你的關注應該是讓活動的認識,而是更新數據模型,並使用已經存在的“讓活動的了解數據模型改變“邏輯處理其余部分。

但是,如果您確信這不是數據模型的一部分,則可以實現方案B或方案C,並在靜態數據成員中添加一些信息。 您的活動可以檢查onResume()中的靜態數據成員,以便在返回到前台時獲取有關廣播的信息。

如果您正在考慮“但是,如果我的進程在廣播和其他活動到達前台之間終止怎么辦?”,那么根據此場景的開頭段落,您的廣播確實正在更新您的數據模型。

如果您正在考慮“但是,我想要更新正在后台工作的活動”,那么相關的活動就會被破壞。 活動永遠不應該在后台工作。 這項工作應該委托給某種形式的服務,並且有一整套相關的場景來獲得廣播服務。

廣播意圖:

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);

在詢問問題時可能不相關,但現在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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM