package com.tfltravelalerts.notification; import android.app.Notification; import android.app.NotificationManager; import android.content.Context; import android.util.Log; import android.util.SparseArray; import com.tfltravelalerts.TflApplication; import com.tfltravelalerts.alerts.events.AddOrUpdateAlertRequest; import com.tfltravelalerts.alerts.events.AlertsUpdatedEvent; import com.tfltravelalerts.model.DayTime; import com.tfltravelalerts.model.LineStatusAlert; import com.tfltravelalerts.model.LineStatusAlertSet; import com.tfltravelalerts.model.LineStatusUpdateSet; import com.tfltravelalerts.statusviewer.events.LineStatusUpdateSuccess; import de.greenrobot.event.EventBus; /** * TODO: write doc */ public class TfLNotificationManager { private static final String LOG_TAG = "TfLNotificationManager"; private static final String NOTIFICATION_TAG = "TfLNotificationManager"; private final TfLNotificationManagerStore mNotificationManagerStore = new TfLNotificationManagerStore(); private Context mContext; private LineStatusAlertSet mAlerts; private LineStatusUpdateSet mLineStatus; private SparseArray<LineStatusUpdateSet> mNotifiedUpdates; public TfLNotificationManager() { EventBus.getDefault().registerSticky(this); mContext = TflApplication.getLastInstance(); SparseArray<LineStatusUpdateSet> notifiedUptates = mNotificationManagerStore.load(); if (notifiedUptates == null) { Log.d(LOG_TAG, "contructor: found no notified updates"); mNotifiedUpdates = new SparseArray<LineStatusUpdateSet>(); } else { Log.d(LOG_TAG, "contructor: loading notified updates with a size of " + notifiedUptates.size()); mNotifiedUpdates = notifiedUptates; } } public void onEvent(LineStatusUpdateSuccess update) { Log.d(LOG_TAG, "on LineStatusUpdateSuccess"); mLineStatus = update.getData(); checkNotifications(); } public void onEvent(AlertsUpdatedEvent update) { Log.d(LOG_TAG, "on AlertsUpdatedEvent"); mAlerts = update.getData(); checkNotifications(); } public void onEvent(AddOrUpdateAlertRequest update) { int alertId = update.getData().getId(); Log.d(LOG_TAG, "on AddOrUpdateAlertRequest - removing information about alert " + alertId); mNotifiedUpdates.remove(alertId); mNotificationManagerStore.save(mNotifiedUpdates); } private void checkNotifications() { DayTime now = DayTime.now(); if(mAlerts != null) { for (LineStatusAlert alert : mAlerts.getActiveAlerts(now)) { showOrUpdateNotification(alert); } } } private void showOrUpdateNotification(LineStatusAlert alert) { if (mLineStatus == null) { Log.d(LOG_TAG, "showOrUpdateNotification: mLineStatus is null. Not processing alert " + alert.getId()); return; } if (shouldShowNotification(alert)) { Log.i(LOG_TAG, "showOrUpdateNotification: creating notification"); NotificationManager nm = (NotificationManager) mContext .getSystemService(Context.NOTIFICATION_SERVICE); Notification notification = buildNotification(alert, mLineStatus); nm.notify(NOTIFICATION_TAG, alert.getId(), notification); mNotifiedUpdates.put(alert.getId(), mLineStatus); mNotificationManagerStore.save(mNotifiedUpdates); } else { Log.i(LOG_TAG, "showOrUpdateNotification: not showing notification due to no new data"); } } private boolean shouldShowNotification(LineStatusAlert alert) { LineStatusUpdateSet currentUpdateSet = mLineStatus.getUpdatesForAlert(alert); if(alert.onlyNotifyForDisruptions() && !currentUpdateSet.isDisrupted()) { // TODO there might be a problem here: if there were problems but they // now got solved, we won't tell the user these problems are gone! Log.d(LOG_TAG, "shouldShowNotification for alert " + alert.getId() + "; service is good - surpress notification"); return false; } LineStatusUpdateSet notifiedUpdateSet = mNotifiedUpdates.get(alert.getId()); if (notifiedUpdateSet == null) { Log.d(LOG_TAG, "shouldShowNotification for alert " + alert.getId() + "; no previous notification detected!"); return true; } if(notifiedUpdateSet.isExpiredResult()) { Log.d(LOG_TAG, "shouldShowNotification for alert " + alert.getId() + "; last result has expired"); return true; } LineStatusUpdateSet oldUpdateSet = notifiedUpdateSet.getUpdatesForAlert(alert); Log.d(LOG_TAG, "shouldShowNotification for alert " + alert.getId() + "; checking for changes since last time..."); return oldUpdateSet.lineStatusChanged(currentUpdateSet); } private Notification buildNotification(LineStatusAlert alert, LineStatusUpdateSet lineStatusUpdateSet) { return new TflNotificationBuilder(alert, mLineStatus).buildNotification(); } }