我正在尝试创建一个读取文本消息的应用程序。应用程序工作正常,当我收到短信时,该消息与电话号码一起显示在祝酒词中。问题是,即使应用程序关闭,即不在前台,它仍然会在我收到短信时显示吐司。我使用了一个任务杀手应用程序,它仍然显示吐司。不显示吐司的唯一方法是取消应用程序。我正在使用这个网站作为教程
http://www.apriorit.com/our-company/dev-blog/227-handle-sms-on-android
除了加密之外,我已经完成了教程中的所有内容。
感谢任何帮助!
谢谢, 克里斯
答案 0 :(得分:3)
这是正确的行为。每次收到消息时,系统都会发送短信广播。由于您的应用程序在其清单中声明它希望接收此类广播,因此每次都会创建并执行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 />
标记。否则你会以两种方式注册你的接收器。
答案 1 :(得分:0)
您可以将toast
视为一种系统通知。因此,无论前景中是否有Activity
,它都会显示。此外,当您扩展BroadcastReceiver
时,只要您的进程处于活动状态,您的类仍会收到意图。 BroadcastReceiver
与任何前景Activity
无关。