我的每日通知被多次触发

时间:2019-12-15 13:09:54

标签: android notifications alarmmanager

我正在开发一个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());
    }
}

0 个答案:

没有答案