在 Android 中创建定时通知(例如事件)
对于一些Android应用程序,我想集成以下功能: 用户可以定义他想要提醒某件事的时间。当时间到了时,即使用户此时没有使用该应用程序,应用程序也应该在通知栏中创建一个通知。
为此,应该查看 AlarmManager、NotificationManager 和 Notification.Builder 类,对吧?
那么如何提前创建定时通知呢?我的代码(到目前为止)是这样的:
将其添加到 AndroidManifest 下以注册广播接收器:
<receiver android:name="AlarmNotificationReceiver"></receiver>
创建一个新的类文件来处理它收到的警报:
public class AlarmNotificationReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
if (extras != null) {
String additionalData = extras.getString("displayText");
// show the notification now
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification mNotification = new Notification(R.drawable.ic_launcher, context.getString(R.string.app_name), System.currentTimeMillis());
PendingIntent pi = PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), 0); // open MainActivity if the user selects this notification
mNotification.setLatestEventInfo(context, context.getString(R.string.app_name), additionalData, pi);
mNotification.flags |= Notification.FLAG_AUTO_CANCEL | Notification.DEFAULT_SOUND;
mNotificationManager.notify(1, mNotification);
}
}
}
使用此代码(例如在 MainActivity 中)将警报设置为 3 秒从现在开始:
Intent i = new Intent(this, AlarmNotificationReceiver.class);
i.putExtra("displayText", "sample text");
PendingIntent pi = PendingIntent.getBroadcast(this.getApplicationContext(), 234324246, i, 0);
AlarmManager mAlarm = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
mAlarm.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+3*1000, pi);
我需要改变什么才能使这项工作正常进行?谢谢你!
两个问题是:
- 当我在代码中更改通知文本时,通知文本不会更改。仅当我更改 PendingIntent.getBroadcast(...) 中的 requestCode 时,它才会更改。这个请求代码是什么意思?可以是随机值还是0?
- 重新启动手机后,“计划”通知或警报消失了。但现在我发现这是正常行为,对吧?我怎样才能规避这个问题?
For some Android applications, I would like to integrate the following feature:
The user can define a time when he wants to be reminded of something. When the time has come then, the application should create a notification in the notification bar even when the user doesn't use the app at this moment.
For this purpose, the classes AlarmManager, NotificationManager und Notification.Builder are the ones to look at, right?
So how do I create a timed notification in advance? My code (so far) is this:
Add this under to the AndroidManifest to register the broadcast receiver:
<receiver android:name="AlarmNotificationReceiver"></receiver>
Create a new class file which handles the alarm that it receives:
public class AlarmNotificationReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
if (extras != null) {
String additionalData = extras.getString("displayText");
// show the notification now
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification mNotification = new Notification(R.drawable.ic_launcher, context.getString(R.string.app_name), System.currentTimeMillis());
PendingIntent pi = PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), 0); // open MainActivity if the user selects this notification
mNotification.setLatestEventInfo(context, context.getString(R.string.app_name), additionalData, pi);
mNotification.flags |= Notification.FLAG_AUTO_CANCEL | Notification.DEFAULT_SOUND;
mNotificationManager.notify(1, mNotification);
}
}
}
Use this code (for example in MainActivity) to set the alarm to 3 seconds from now:
Intent i = new Intent(this, AlarmNotificationReceiver.class);
i.putExtra("displayText", "sample text");
PendingIntent pi = PendingIntent.getBroadcast(this.getApplicationContext(), 234324246, i, 0);
AlarmManager mAlarm = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
mAlarm.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+3*1000, pi);
What do I need to change to make this work? Thank you!
The two problems are:
- The notification's text does not change when I change it in code. It only changes when I change the requestCode in PendingIntent.getBroadcast(...). What is this request code all about? Can it be a random value or 0?
- After rebooting my phone, the "planned" notification, or the alarm, is gone. But now I've seen that this is normal behaviour, right? How can I circumvent this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不确定第 1 部分,但对于第 2 部分,一般方法是拦截 BOOT_COMPLETED 意图并使用它来重新注册所有警报。不幸的是,这意味着对于您在警报管理器中注册的每个警报,您也必须将其存储在应用程序的数据库中。
因此,您需要一个广播接收器来拦截 BOOT_COMPLETED 意图:
要获取 BOOT_COMPLETED 意图,您必须在清单中添加以下权限:
并且 BootReceiver 还需要使用以下意图过滤器在您的清单中注册:
这很重要需要注意的是,如果您的应用程序安装到 SD 卡,它永远无法接收 BOOT_COMPLETED 意图。另外,值得注意的是,这种实现有点幼稚,因为它在启动时立即执行代码,这可能会减慢用户手机在启动时的速度。因此,我建议在拦截启动意图后延迟执行几分钟。
Not sure about part 1, but for part 2 the general approach is to intercept the BOOT_COMPLETED intent and use that to re-register all alarms. This does unfortunately mean that for each alarm you have registered with the alarm manager you have to store it in your app's db as well.
So, you'll need a broadcast receiver to intercept the BOOT_COMPLETED intent:
To get the BOOT_COMPLETED intent, you must put the following permission in your manifest:
And the BootReceiver also needs to be registered in your manifest with the following intent filter:
It's important to note that if your app is installed to the sdcard, it can never receive the BOOT_COMPLETED intent. Also, it's worth noting that this implementation is a bit naive in that it executes code immediately on booting which can slow the user's phone down at startup. So, I recommend delaying your execution for a few minutes after intercepting the boot intent.
我个人会在没有广播接收器的情况下做到这一点。我会让 AlarmManager 触发启动单独活动的意图,而不是接收器。然后这个新的 Activity 就可以为您发出通知。我不确定这是否是更好的方法,但对我来说似乎不那么复杂。
活动更好
编辑:服务可能比您的 MainActivity 中的
:您的服务:
您的清单:
I personally would do it without a Broadcast Receiver. I'd get the AlarmManager to fire the intent to start a seperate Activity, rather than receiver. Then this new Activity could make the notification for you. I'm not sure if this is a better way, but it seems less complicated to me.
Edit: A Service would probably be better still than an Activity
In your MainActivity:
Your Service:
Your Manifest: