我正在开发一个Android应用程序,该应用程序会提醒人们服用药物。我的应用正在运行,但通知在正确的时间和日期触发,但过去的通知与当前的通知同时触发,所以我无法弄清原因。
例如: 我今天有两则通知,一个是早上7点,另一个是晚上10点,在晚上10点,当我打开应用程序时,也会在7am发出通知。有时候,即使是过去的那些老朋友,也会感到烦恼。
一点帮助将不胜感激。谢谢。
NotificationService.Java 每天调用的服务,它管理每日警报
package com.alyamaniy.medicationreminder.service;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.IBinder;
import androidx.annotation.Nullable;
import com.alyamaniy.medicationreminder.R;
import com.alyamaniy.medicationreminder.helpers.AlarmHelper;
import com.alyamaniy.medicationreminder.helpers.CalendarHelper;
import com.alyamaniy.medicationreminder.helpers.DoseHelper;
import com.alyamaniy.medicationreminder.helpers.Helpers;
import com.alyamaniy.medicationreminder.helpers.NotificationHelper;
import java.util.Calendar;
public class NotificationService extends Service {
private static long MILLISECS_PER_DAY = 86400000L;
private static boolean isStarted = false;
private SharedPreferences sharedPreferences;
@Override
public void onCreate() {
super.onCreate();
NotificationHelper notificationHelper = new NotificationHelper(getApplicationContext());
startForeground(1, notificationHelper.getChannelNotification(getResources().getString(R.string.notif_service_text)).build());
sharedPreferences = getSharedPreferences(Helpers.pref_name, MODE_PRIVATE);
long lastTimeDone = Helpers.getLastDayAction(sharedPreferences);
if ((System.currentTimeMillis() - lastTimeDone) >= MILLISECS_PER_DAY || !isStarted) {
isStarted = true;
//set alarm for the medications
new AlarmHelper(getApplicationContext()).setAlarms(new DoseHelper(getApplicationContext()).getAllDose(),
new CalendarHelper(getApplicationContext()), false);
setAlarm();
}
stopForeground(true);
stopSelf();
}
//setalarm for the next day
public void setAlarm() {
Intent serviceIntent = new Intent(this, NotificationService.class);
PendingIntent pendingIntent = PendingIntent.getService(this, -100, serviceIntent,
PendingIntent.FLAG_CANCEL_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR_OF_DAY, 1);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Helpers.setLastDayAction(sharedPreferences, System.currentTimeMillis());
if (am != null) {
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
AlarmHelper.java 一个帮助器类,它检查每日警报
package com.alyamaniy.medicationreminder.helpers;
import android.content.Context;
import com.alyamaniy.medicationreminder.prescription.model.Dose;
import com.alyamaniy.medicationreminder.prescription.model.DoseDuration;
import java.util.ArrayList;
public class AlarmHelper {
private DoseHelper doseHelper;
public AlarmHelper(Context context) {
this.doseHelper = new DoseHelper(context);
}
public void setAlarms(ArrayList<DoseDuration> doseDurations, CalendarHelper calendarHelper, boolean isInitAlarm) {
for (DoseDuration doseDuration : doseDurations) {
setAlarm(doseDuration, calendarHelper, isInitAlarm);
}
}
private void setAlarm(DoseDuration doseDuration, CalendarHelper calendarHelper, boolean isInitAlarm) {
boolean isNotFinished = Helpers.checkDate(doseDuration.getMedic_B(), doseDuration.getMedic_E());
for (Dose dose : doseDuration.getDoses()) {
boolean isPastTime = (!isInitAlarm) || Helpers.checkTime(dose);
//set notification for the medication
if (isNotFinished && isPastTime) calendarHelper.setNotificationAlarm(dose);
else {
calendarHelper.cancelNotificationAlarm(dose);
isPrescriptionFinished(doseDuration.getId());
}
}
}
private void isPrescriptionFinished(int doseDurationId) {
doseHelper.checkIfprescIsFinished(doseDurationId);
}
public void deleteAlarm(CalendarHelper calendarHelper, Dose dose) {
calendarHelper.cancelNotificationAlarm(dose);
}
}
CalendarHelper.java 用于设置每日警报的帮助程序类,它会调用broadcastReceiver
package com.alyamaniy.medicationreminder.helpers;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import com.alyamaniy.medicationreminder.prescription.model.Dose;
import com.alyamaniy.medicationreminder.receiver.NotificationReceiver;
import java.util.Calendar;
public class CalendarHelper {
private Context context;
public CalendarHelper(Context context) {
this.context = context;
}
public void setNotificationAlarm(Dose dose) {
int[] time = Helpers.getDoseTime(dose.getDose());
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, time[0]);
calendar.set(Calendar.MINUTE, time[1]);
calendar.set(Calendar.SECOND, 0);
Intent intent = new Intent(context, NotificationReceiver.class);
intent.putExtra("id", dose.getId());
intent.putExtra("time", dose.getDose());
//set notification in the future
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, dose.getId(), intent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if (alarmManager != null)
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
public void cancelNotificationAlarm(Dose dose) {
int[] time = Helpers.getDoseTime(dose.getDose());
Intent intent = new Intent(context, NotificationReceiver.class);
intent.putExtra("id", dose.getId());
intent.putExtra("time", time);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, dose.getId(), intent, PendingIntent.FLAG_ONE_SHOT);
if (alarmManager != null) alarmManager.cancel(pendingIntent);
}
}
NotificationReceiver 广播接收者调用,它触发通知
package com.alyamaniy.medicationreminder.receiver;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import androidx.core.app.NotificationCompat;
import com.alyamaniy.medicationreminder.R;
import com.alyamaniy.medicationreminder.helpers.NotificationHelper;
import com.alyamaniy.medicationreminder.prescription.activities.TakeMedicActivity;
//Receiver to fire notification
public class NotificationReceiver extends BroadcastReceiver {
static int requestCode = 0;
static String time_saved = "";
@Override
public void onReceive(Context context, Intent intent) {
String time = intent.getStringExtra("time");
Intent i = new Intent(context, TakeMedicActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("time", time);
if (!time_saved.equals(time)) {
requestCode++;
time_saved = time;
}
//on notification click open an activity
PendingIntent pendingIntent = PendingIntent.getActivity(context, requestCode, i, PendingIntent.FLAG_ONE_SHOT);
NotificationHelper notificationHelper = new NotificationHelper(context);
NotificationCompat.Builder builder = notificationHelper.getChannelNotification(pendingIntent, context.getResources().getString(R.string.medi_notif_title), context.getResources().getString(R.string.time_to_take_meds));
notificationHelper.getManager().notify(requestCode, builder.build());
}
}