繁体   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