使用广播意图/广播接收机将消息从服​​务发送到活动

所以我理解(我认为)广播意图和接收消息给他们。

所以现在,我的问题/我无法解决的是如何从接收器的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消息的内部类。

然后,声明类variables如…

 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创build和广播的Intent

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

这就是它。 使“行动”独特的包/应用程序,即com.mycompany...如我的例子。 这有助于避免其他应用程序或系统组件可能尝试处理它的情况。

没有冒犯,但你的问题仍然是模糊的。 所以,我要概括一些场景,并希望其中一个实际上碰到你认为你有的任何问题。

情景A:只有活动

如果您只需在前台进行活动时收到广播,请使用registerReceiver()注册BroadcastReceiver 。 正如@MisterSquonk所指出的,你可以在onResume()注册接收者,并在onPause()注销它。

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

如果您希望前台活动处理广播,但是如果该活动不在前台(例如,发出Notification ),并且广播是有序广播(例如,收到的SMS),您希望发生其他事情,那么您仍然会使用schemeA解决scheme,但使用更高优先级的IntentFilter (请参阅setPriority() )。 另外,通过清单中的<receiver>元素注册一个BroadcastReceiver ,对于同一个广播,使用一个优先级较低的<intent-filter> 。 在该活动的BroadcastReceiver ,调用abortBroadcast()来消费该事件并阻止它到达您的清单注册的BroadcastReceiver

情景C:活动如果在前景,否则其他; 定期播放

如果schemeB几乎适合,但是您正在监听的广播不是有序的广播,则需要从schemeB开始。但是,要让两个接收器在其各自的filter中具有的广播是您自己的filter,请使用专用动作string@MisterSquonkbuild议。 此外,在清单中注册另一个 BroadcastReceiver ,其<intent-filter>用于您正在监听的实际广播。 该接收器只需调用sendOrderedBroadcast()发送其他接收者正在监听的有序广播。

情景D:活动无论前景如何

如果你的某些活动需要了解广播,无论它是否在前台,都需要重新思考你的意思。 通常,这意味着广播会以某种方式影响您的数据模型,在这种情况下,您的担心应该让活动知道,而是更新您的数据模型,并使用您已有的“让活动知道数据模型改变了“其余的逻辑处理。

但是,如果您确信这不是数据模型的一部分,则可以实施schemeB或schemeC,并在静态数据成员中粘贴一些信息。 您的活动可以检查onResume()中的静态数据成员,以便在返回到前台时获取有关广播的信息。

如果你想“但是,如果我的过程在广播和其他活动到达前台之间被终止?”,那么你的广播确实更新你的数据模型,按照这个场景的开头段落。

如果你想“但是,我想更新一个在后台工作的活动”,那么这个活动就会被打破。 活动不应该在后台工作。 这项工作应该委托给某种forms的服务,并且有一整套相关的场景来获得广播服务。

要播放一个意图:

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