我已经继承了一个 Android 应用程序的代码库,并且我正面临一个与本地通知有关的特别问题。
这个想法是为将来安排的每个事件发送通知,同时考虑到用户希望在事件前多少分钟收到通知的提醒偏好。
一切正常,除了在第一次引发通知之后,如果用户在事件开始之前打开应用程序,通知会再次引发。每次在(事件开始日期 - 提醒)和事件开始日期之间打开应用程序时,都会发生这种情况。
我已经看过了这个,也没有运气。我读过使用服务可能会导致这个问题,有些人建议删除它,但我认为这是必要的,因为在应用程序关闭时也必须抛出通知。
目前代码结构如下:
编辑 - TabBarActivity 的更新描述
在 TabBarActivity 中,我有调度 AlarmManager 的方法scheduleTravelNotification。每次在本地数据库中添加新事件或更新现有事件时,都会执行此方法。TabBarActivity 在 onCreate 和 onResume 方法中运行此方法。TabBarActivity 也是通知的目标 - onclick 事件。
private static void scheduleTravelNotification(Context context, RouteItem routeItem) {
long currentTime = System.currentTimeMillis();
int alarmTimeBefore = routeItem.getAlarmTimeBefore();
long alarmTime = routeItem.getStartTime() - (alarmTimeBefore * 1000 * 60);
if(alarmTimeBefore < 0){
return;
}
if(alarmTime < currentTime){
return;
}
Intent actionOnClickIntent = new Intent(context, TravelNotificationReceiver.class);
PendingIntent travelServiceIntent = PendingIntent.getBroadcast(context, System.currentTimeMillis(), actionOnClickIntent, PendingIntent.FLAG_ONE_SHOT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(alarmTime);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), travelServiceIntent);
Log.e("NEXT ALARM", "Time: " + String.valueOf(calendar.getTimeInMillis()));
}
这是TravelNotificationReceiver.java(我应该使用 LocalBroadcastReceiver 而不是 BroadcastReceiver 吗?)
public class TravelNotificationReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.e("RECEIVER", "received TravelNotification request");
Intent notificationIntent = new Intent(context, TravelNotificationService.class);
context.startService(notificationIntent);
}
}
TravelNotificationService.java将NotificationService.java设置扩展为 type = "Travel"、flags = 0、title = "something" 和 text = "something else"。
public abstract class NotificationService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
sendNotification();
return super.onStartCommand(intent, flags, startId);
}
public abstract String setNotificationType();
public abstract int setNotificationFlags();
public abstract String setNotificationTitle();
public abstract String setNotificationText();
/**
* Executes all the logic to init the service, prepare and send the notification
*/
private void sendNotification() {
int flags = setNotificationFlags();
String type = setNotificationType();
NotificationHelper.logger(type, "Received request");
// Setup notification manager, intent and pending intent
NotificationManager manager = (NotificationManager) this.getApplicationContext().getSystemService(this.getApplicationContext().NOTIFICATION_SERVICE);
Intent intentAction = new Intent(this.getApplicationContext(), TabBarActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this.getApplicationContext(), 0, intentAction, flags);
// Prepares notification
String title = setNotificationTitle();
String text = setNotificationText();
Notification notification = NotificationHelper.buildNotification(getApplicationContext(), title, text, pendingIntent);
// Effectively send the notification
manager.notify(101, notification);
NotificationHelper.logger(type, "Notified");
}
}
编辑 - 这是 NotificationHelper.buildNotification 的代码
public static Notification buildNotification(Context context, String title, String text, PendingIntent pendingIntent) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setAutoCancel(true);
builder.setContentText(text);
builder.setContentTitle(title);
builder.setContentIntent(pendingIntent);
builder.setSmallIcon(R.mipmap.launcher);
builder.setCategory(Notification.CATEGORY_MESSAGE);
builder.setVisibility(Notification.VISIBILITY_PUBLIC);
return builder.build();
}
谢谢你的回答!
编辑我也看到了这个但没有接受的答案,而这篇文章提出了一些我认为它已经通过 if(alarmTime < currentTime){ return; 进行管理的内容。} 在 scheduleTravelNotification。