这是正确的行为actully。每当您收到消息时,系统都会发送短信广播。由于您的应用程序在声明中声明了它想要接收此类广播,因此每次都会创建并执行BroadcastReceiver的新实例。
如果你想只在特定的时间执行接收器(在这种情况下,当你的应用程序是在前台),你必须注册,并通过使用Context.registerReceiver()
和Context.unregisterReceiver()
动态注销它的代码,而不是表现。
如何准确地做到这一点?
下面是一个简短的例子。我假设你已经编写了自己的类来扩展BroadcastReceiver并处理onReceive()
中的内容。在这个例子中,这个类的名字是SmsReceiver
,就像在链接教程中一样。
我们的目标是只在一个活动处于前台时接收广播,这意味着您还应该拥有一个扩展活动并像普通应用程序一样显示UI的类。
首先,我们需要一个接收器的实际实例作为类成员。加入这样的事情您的活动类:
private SmsReceiver smsReceiver = new SmsReceiver();
旁注:这实际上的主要区别之一在清单中,并在代码登记之间:
- 在代码中创建一个接收器实例自己
- 当在清单中注册,系统会生成实例为你在后台
好,很好。现在,当活动进入前台并退出时,我们只需注册并取消注册该接收器。看看Activity class doc中的图表,这些事件中调用的框架方法是onResume()
和onPause()
。
添加以下行到你的onResume()
方法:
@Override
public void onResume() {
IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
registerReceiver(smsReceiver, filter);
}
我们在这里所做的其实很简单。它是清单<receiver />
标记的代码等效物。我们用我们喜欢接收的广播创建了一个intent过滤器,并使用它注册我们的接收器。
下一步是取消注册onPause()
。再次,如果您尚未添加此行或创建onPause()
。
@Override
public void onPause() {
unregisterReceiver(smsReceiver);
}
非常简单 - 带上我们的接收器实例,并在应用即将进入背景时取消注册。这就是所有的魔法,一切都应该按照预期工作。 不要忘记删除清单中的整个<receiver />
标记,但是当您使用现有代码时。否则,您会以两种方式注册您的接收器。
所以我试图实现你的建议,但我有点困惑。我在哪里把registerReceiver,我如何正确使用它,即什么是代码示例。有没有可以链接到我的例子?我有这个,但它会导致崩溃BroadcastReceiver BR = null; IntentFilter filter = null; registerReceiver(BR,filter); – 2011-12-21 03:12:56
@ChrisSippel你不能用这样的'null'对象注册。我为我的答案添加了一个简短的指南。 – 2011-12-21 10:58:05
所以我终于到处去做正确的事情,假期和学校,我一直很忙。所以我很高兴地说它很有用,我非常感谢你! – 2012-01-14 21:12:45