Android - Probleme mit dem Dienst, der mehrere lokale Benachrichtigungen sendet

Ich habe eine Codebasis für eine Android-App geerbt und habe ein besonderes Problem mit lokalen Benachrichtigungen.

Die Idee ist, für jedes Ereignis, das in der Zukunft geplant ist, eine Benachrichtigung zu senden, wobei auch berücksichtigt wird, wie viele Minuten vor dem Ereignis der Benutzer benachrichtigt werden möchte.

Alles funktioniert einwandfrei, außer dass nach dem ersten Auslösen der Benachrichtigung die Benachrichtigung ein weiteres Mal ausgelöst wird, wenn der Benutzer die App vor dem Start des Ereignisses öffnet. Dies geschieht jedes Mal, wenn die App zwischen (Startdatum des Ereignisses - Erinnerung) und Startdatum des Ereignisses geöffnet wird.

Ich habe schon einen Blick aufDie und auchDie ohne glück. Ich habe gelesen, dass die Verwendung eines Dienstes genau dieses Problem verursachen kann, und einige empfehlen, ihn zu entfernen. Ich denke jedoch, dass dies erforderlich ist, da die Benachrichtigung auch dann ausgelöst werden muss, wenn die App geschlossen wird.

erzeit ist der Code wie folgt aufgebaut:

Edit - aktualisierte Beschreibung von TabBarActivity

Inside TabBarActivity Ich habe die Methode scheduleTravelNotification Damit wird der AlarmManager terminiert. Diese Methode wird jedes Mal ausgeführt, wenn ein neues Ereignis in der lokalen Datenbank hinzugefügt werden soll oder wenn ein vorhandenes Ereignis aktualisiert wurde. Die TabBarActivity führt diese Methode in den Methoden onCreate und onResume aus. TabBarActivity ist auch das Ziel des Notification-On-Click-Ereignisses.

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()));
}

Das ist TravelNotificationReceiver.java (Soll ich LocalBroadcastReceiver anstelle von BroadcastReceiver verwenden?)

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 erweitert NotificationService.java Einstellung als type = "Travel", flags = 0, title = "something" und 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");
    }
}

Edit - Hier ist der Code für 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();
    }

Danke für die Antworten!

Bearbeiten hab ich auch gesehenDie hat aber keine akzeptierten Antworten, währendDiepost schlagen etwas vor, von dem ich denke, dass es bereits mit if (alarmTime <currentTime) {return; } in scheduleTravelNotification.

Antworten auf die Frage(8)

Ihre Antwort auf die Frage