在用户定义的时间显示多个通知
Displaying multiple notifications at user-defined times
我在 Android 中编程已经一年多了,但之前从未使用过通知,我的一个应用程序需要通知。
在应用程序中,可以设置不同时间的事件。显然,用户可以选择更改这些时间或 add/remove 个事件。
我计划使用通知在活动开始前 5 分钟通知用户。
我已通读 Android 开发人员文档 Building a Notification and Services (which I am also new to). I have decided to use Service
s because I figured that the notification would need to be shown even when the app not running. To help me, I have been referring to one particular SO answer 作为指导。
我首先在 NotificationService
class 中对通知生成器 classes 进行了一些试验,如下所示:
public class NotificationService extends IntentService {
private static final int NOTIFICATION_ID = 1;
public NotificationService() {
super(NotificationService.class.getSimpleName());
}
@Override
protected void onHandleIntent(Intent intent) {
showNotification();
}
private void showNotification() {
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(
this, NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setContentTitle("Test notification")
.setSmallIcon(R.drawable.ic_event_black_24dp)
.setContentText("Test description")
.setContentIntent(pendingIntent);
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.notify(NOTIFICATION_ID, builder.build());
}
}
我还使用以下内容在我的应用程序的初始屏幕中启动此 Service
:
Intent serviceIntent = new Intent(this, NotificationService.class);
startService(serviceIntent);
要在特定时间显示通知,我已经阅读了有关 AlarmManager
的内容,主要是通过 SO questions like this one。我也知道要显示多个通知,我需要不同的通知 ID(比如我的常量 NOTIFICATION_ID
)。
但是,我不确定的是每次添加、删除或更改事件时动态更新通知显示的时间。
有人可以指导我如何实现这一目标吗?
您实现了通知部分。要在特定时间通知用户,您应该设置 AlarmManager。我粘贴您需要的完整代码,然后解释每个部分:
public class AlarmReceiver extends WakefulBroadcastReceiver {
AlarmManager mAlarmManager;
PendingIntent mPendingIntent;
@Override
public void onReceive(Context context, Intent intent) {
int mReceivedID = Integer.parseInt(intent.getStringExtra(AddReminderActivity.EXTRA_REMINDER_ID));
// Get notification title from Reminder Database
ReminderDatabase rb = new ReminderDatabase(context);
ApiReminderModel reminder = rb.getReminder(mReceivedID);
String mTitle = reminder.getName();
// Create intent to open ReminderEditActivity on notification click
// handling when you click on Notification what should happen
Intent editIntent = YourActivity.createActivity(context, reminder.getChannelId(), reminder.getStartTime());
PendingIntent mClick = PendingIntent.getActivity(context, mReceivedID, editIntent, PendingIntent.FLAG_UPDATE_CURRENT);
// Create Notification
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_logo))
.setSmallIcon(R.drawable.ic_logo)
.setContentTitle(context.getResources().getString(R.string.app_name))
.setTicker(mTitle)
.setContentText(mTitle)
.setContentIntent(mClick)
.setSound(ringtoneUri)
.setAutoCancel(true)
.setOnlyAlertOnce(true);
NotificationManager nManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
nManager.notify(mReceivedID, mBuilder.build());
}
public void setAlarm(Context context, Calendar calendar, int ID) {
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
// Put Reminder ID in Intent Extra
Intent intent = new Intent(context, AlarmReceiver.class);
intent.putExtra(AddReminderActivity.EXTRA_REMINDER_ID, Integer.toString(ID));
mPendingIntent = PendingIntent.getBroadcast(context, ID, intent, PendingIntent.FLAG_CANCEL_CURRENT);
// Calculate notification time
Calendar c = Calendar.getInstance();
long currentTime = c.getTimeInMillis();
long diffTime = calendar.getTimeInMillis() - currentTime;
// Start alarm using notification time
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + diffTime, mPendingIntent);
// Restart alarm if device is rebooted
ComponentName receiver = new ComponentName(context, BootReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
}
public void cancelAlarm(Context context, int ID) {
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
// Cancel Alarm using Reminder ID
mPendingIntent = PendingIntent.getBroadcast(context, ID, new Intent(context, AlarmReceiver.class), 0);
mAlarmManager.cancel(mPendingIntent);
// Disable alarm
ComponentName receiver = new ComponentName(context, BootReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
}
}
如您所见,我们有 setAlarm
可以在特定时间通知用户。我还传递了之前启动的日历实例(分配一个应该通知用户的时间)。
Calendar mCalendar = Calendar.getInstance();
mCalendar.add(Calendar.DAY_OF_YEAR, 7);// assume you want send notification 7 days later
new AlarmReceiver().setAlarm(getApplicationContext(), mCalendar, id);
我们还有另一种方法cancelAlarm
。如果你想删除一个 Alaram,只需传递唯一的警报 ID(已用于创建警报)。
另外不要忘记将此Service
添加到您的AndroidManifest.xml
:
<receiver android:name=".service.AlarmReceiver" />
只有剩下的东西 当您重新启动设备时,您应该再次设置 AlarmsManager
,因此您需要 BootRecivier
服务。
我在 Android 中编程已经一年多了,但之前从未使用过通知,我的一个应用程序需要通知。
在应用程序中,可以设置不同时间的事件。显然,用户可以选择更改这些时间或 add/remove 个事件。
我计划使用通知在活动开始前 5 分钟通知用户。
我已通读 Android 开发人员文档 Building a Notification and Services (which I am also new to). I have decided to use Service
s because I figured that the notification would need to be shown even when the app not running. To help me, I have been referring to one particular SO answer 作为指导。
我首先在 NotificationService
class 中对通知生成器 classes 进行了一些试验,如下所示:
public class NotificationService extends IntentService {
private static final int NOTIFICATION_ID = 1;
public NotificationService() {
super(NotificationService.class.getSimpleName());
}
@Override
protected void onHandleIntent(Intent intent) {
showNotification();
}
private void showNotification() {
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(
this, NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setContentTitle("Test notification")
.setSmallIcon(R.drawable.ic_event_black_24dp)
.setContentText("Test description")
.setContentIntent(pendingIntent);
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.notify(NOTIFICATION_ID, builder.build());
}
}
我还使用以下内容在我的应用程序的初始屏幕中启动此 Service
:
Intent serviceIntent = new Intent(this, NotificationService.class);
startService(serviceIntent);
要在特定时间显示通知,我已经阅读了有关 AlarmManager
的内容,主要是通过 SO questions like this one。我也知道要显示多个通知,我需要不同的通知 ID(比如我的常量 NOTIFICATION_ID
)。
但是,我不确定的是每次添加、删除或更改事件时动态更新通知显示的时间。
有人可以指导我如何实现这一目标吗?
您实现了通知部分。要在特定时间通知用户,您应该设置 AlarmManager。我粘贴您需要的完整代码,然后解释每个部分:
public class AlarmReceiver extends WakefulBroadcastReceiver {
AlarmManager mAlarmManager;
PendingIntent mPendingIntent;
@Override
public void onReceive(Context context, Intent intent) {
int mReceivedID = Integer.parseInt(intent.getStringExtra(AddReminderActivity.EXTRA_REMINDER_ID));
// Get notification title from Reminder Database
ReminderDatabase rb = new ReminderDatabase(context);
ApiReminderModel reminder = rb.getReminder(mReceivedID);
String mTitle = reminder.getName();
// Create intent to open ReminderEditActivity on notification click
// handling when you click on Notification what should happen
Intent editIntent = YourActivity.createActivity(context, reminder.getChannelId(), reminder.getStartTime());
PendingIntent mClick = PendingIntent.getActivity(context, mReceivedID, editIntent, PendingIntent.FLAG_UPDATE_CURRENT);
// Create Notification
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_logo))
.setSmallIcon(R.drawable.ic_logo)
.setContentTitle(context.getResources().getString(R.string.app_name))
.setTicker(mTitle)
.setContentText(mTitle)
.setContentIntent(mClick)
.setSound(ringtoneUri)
.setAutoCancel(true)
.setOnlyAlertOnce(true);
NotificationManager nManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
nManager.notify(mReceivedID, mBuilder.build());
}
public void setAlarm(Context context, Calendar calendar, int ID) {
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
// Put Reminder ID in Intent Extra
Intent intent = new Intent(context, AlarmReceiver.class);
intent.putExtra(AddReminderActivity.EXTRA_REMINDER_ID, Integer.toString(ID));
mPendingIntent = PendingIntent.getBroadcast(context, ID, intent, PendingIntent.FLAG_CANCEL_CURRENT);
// Calculate notification time
Calendar c = Calendar.getInstance();
long currentTime = c.getTimeInMillis();
long diffTime = calendar.getTimeInMillis() - currentTime;
// Start alarm using notification time
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + diffTime, mPendingIntent);
// Restart alarm if device is rebooted
ComponentName receiver = new ComponentName(context, BootReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
}
public void cancelAlarm(Context context, int ID) {
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
// Cancel Alarm using Reminder ID
mPendingIntent = PendingIntent.getBroadcast(context, ID, new Intent(context, AlarmReceiver.class), 0);
mAlarmManager.cancel(mPendingIntent);
// Disable alarm
ComponentName receiver = new ComponentName(context, BootReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
}
}
如您所见,我们有 setAlarm
可以在特定时间通知用户。我还传递了之前启动的日历实例(分配一个应该通知用户的时间)。
Calendar mCalendar = Calendar.getInstance();
mCalendar.add(Calendar.DAY_OF_YEAR, 7);// assume you want send notification 7 days later
new AlarmReceiver().setAlarm(getApplicationContext(), mCalendar, id);
我们还有另一种方法cancelAlarm
。如果你想删除一个 Alaram,只需传递唯一的警报 ID(已用于创建警报)。
另外不要忘记将此Service
添加到您的AndroidManifest.xml
:
<receiver android:name=".service.AlarmReceiver" />
只有剩下的东西 当您重新启动设备时,您应该再次设置 AlarmsManager
,因此您需要 BootRecivier
服务。