From fae89f4c45a32e53442caa192b2c82d8b902ea64 Mon Sep 17 00:00:00 2001 From: Doug Keen Date: Wed, 19 Sep 2012 14:12:18 -0700 Subject: [PATCH] Implemented alarm canceling --- cancelAlarm.svg | 438 ++++++++++++++++++ res/drawable-hdpi/ic_action_cancel_alarm.png | Bin 0 -> 1440 bytes res/drawable-ldpi/ic_action_cancel_alarm.png | Bin 0 -> 595 bytes res/drawable-mdpi/ic_action_cancel_alarm.png | Bin 0 -> 856 bytes res/drawable-xhdpi/ic_action_cancel_alarm.png | Bin 0 -> 2234 bytes res/layout/departures.xml | 3 +- res/menu/route_menu.xml | 10 +- .../dougkeen/bart/AlarmBroadcastReceiver.java | 2 + .../dougkeen/bart/BartRunnerApplication.java | 15 + src/com/dougkeen/bart/EtdService.java | 28 +- .../dougkeen/bart/NotificationService.java | 56 ++- .../bart/TrainAlertDialogFragment.java | 3 +- .../dougkeen/bart/ViewDeparturesActivity.java | 33 +- src/com/dougkeen/util/Observable.java | 46 ++ src/com/dougkeen/util/Observer.java | 5 + 15 files changed, 606 insertions(+), 33 deletions(-) create mode 100644 cancelAlarm.svg create mode 100644 res/drawable-hdpi/ic_action_cancel_alarm.png create mode 100644 res/drawable-ldpi/ic_action_cancel_alarm.png create mode 100644 res/drawable-mdpi/ic_action_cancel_alarm.png create mode 100644 res/drawable-xhdpi/ic_action_cancel_alarm.png create mode 100644 src/com/dougkeen/util/Observable.java create mode 100644 src/com/dougkeen/util/Observer.java diff --git a/cancelAlarm.svg b/cancelAlarm.svg new file mode 100644 index 0000000..56c465f --- /dev/null +++ b/cancelAlarm.svg @@ -0,0 +1,438 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/res/drawable-hdpi/ic_action_cancel_alarm.png b/res/drawable-hdpi/ic_action_cancel_alarm.png new file mode 100644 index 0000000000000000000000000000000000000000..bd87e8566ea87ca7a8b3ad093072fc986f4d93d3 GIT binary patch literal 1440 zcmV;R1z-A!P)+9PbgHM2cp|?`0EKLzWyDsXT1oL1a?UtvsOR1B*gfL=1Iy?`K zfIpxILl&eALfdnxcNu8-i!hV6U#GM!t5Yg~!L4&7Tn@X!2k->E4!^_Jum@}hgTsJ- z^7}n3!_Z~)u_b@&xzk`rcoXj7-KS*+mc36Aa5$Y@3mWkPJPgj>UT_>70=vL^HG}=d z|6jozcp1I}y?8MUg?C{hB9@dHS@gb805i8YjmN+cm<=_L67vpQ{Ym(9`=OkFoQO>Z@3f*IF;U9IvUpv&eEme%sZnGz&i~5 zkE3GnCj49iZ}4n>W(m(-TF1lr;G|4}XW%fGo(4q%?&bY~FcDnGXTlZW zn!UYt17hgTJiiT|C5-^sY)`Yvk^Zypu z$X^CpR67brx{)WqbG+}(d2e55fnN0Zy%pRir^9fjb_)sW279T8&YpPxba3an6p(^Fzz58Dqs$ETzXzBPPJTpn!c~Bz-RazXf>u+yM8-*0u)V0aFDx=Ev5jt}`4H;c0bn z5MV@Zy0p>*yJ5vmVDvV?P0ow32sIcgplu#Fiox8(FTu?iWhxPySyP8A;Q%mtdt&`u zT^RwU5(-#5cwn`%(i9J5=esGiYt}3?S}@SO$<*0|&7fuqva0aj9LSjR78rq76!lm3 zE=7PdH44m$OuU{g>l7omq0U9n1tYSJ%5yic9y%K)@!YtwTBTHgy)&>UjO+Uo=wV<} zF@Mc2=ER#OHFOUjFk6YwhBLEE2F+LqNx77#?30$&5( z&b**|$yrizGCAXBoZj3_LnedK_nR^gAl!UR&qeDtD!}>%AoG5ghHH2sm>Pc>3{$Ij z0Po12^=6=EvEIJCmD%14j<>r7F%iLdgXn*CspoC3t~4YdYfa}aqf@{;@%G>m>&DLV z8U=V8+Z0R{3~YMLAlD7fs#j2t*g6qa#%GtH#RwSQG67XWoPe#sd#^L@jmzTa6XV5F z2L7z3zJYNB>;x-=xT#sx#(4MIRp64dybWGXW*SxyYZUKHf@(YJiIC@m(h**RGKSOq0fD>jEJ{o4l(gUrm5>Z&UtsW>n u)SIX zCE!=U7-NTD?ZAf)D3GIyPx8HmREPqZdksqv3wbb#$kt~f?*u5G#N--TIY<}cufqkr zfDN)>0dAlQIuJQ^C1MpAX5t(~Kn(Pee2;KG_6hb8b|iKqtU`e5rkydnGZCvmrdpYF z(L~anBvG`Q&mR7^@T(MXgvGwp`5t;s>hJV!lE6qwWe6kq}PefS$-U zCF4ucPR1VayRp}>m)#WzBSDho1|3^O;_&^!7fPXlIgf4$sP;4X7QhGv_ADal_~kIp z*rsL7N5qLgnQ@nI5nCXIN;V|KbzfqB*5yW zcr(bh$W_f&+cl(%{HOzp2U4s>6?g2pwp}y$z281$yVO hqYj*jx{CdOfj7?V&>8hG6AAzT002ovPDHLkV1h{j3)KJs literal 0 HcmV?d00001 diff --git a/res/drawable-mdpi/ic_action_cancel_alarm.png b/res/drawable-mdpi/ic_action_cancel_alarm.png new file mode 100644 index 0000000000000000000000000000000000000000..5d1ebba98e36d16e8cdc2cc7a80a0afa647d7166 GIT binary patch literal 856 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 IM6N<$g2A9FhX4Qo literal 0 HcmV?d00001 diff --git a/res/layout/departures.xml b/res/layout/departures.xml index baa2a05..ac8598f 100644 --- a/res/layout/departures.xml +++ b/res/layout/departures.xml @@ -97,7 +97,8 @@ android:layout_height="wrap_content" android:indeterminate="true" android:visibility="invisible" /> - + diff --git a/src/com/dougkeen/bart/AlarmBroadcastReceiver.java b/src/com/dougkeen/bart/AlarmBroadcastReceiver.java index b1b369f..85bbb58 100644 --- a/src/com/dougkeen/bart/AlarmBroadcastReceiver.java +++ b/src/com/dougkeen/bart/AlarmBroadcastReceiver.java @@ -19,6 +19,8 @@ public class AlarmBroadcastReceiver extends BroadcastReceiver { targetIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(targetIntent); + + application.setAlarmPending(false); } } diff --git a/src/com/dougkeen/bart/BartRunnerApplication.java b/src/com/dougkeen/bart/BartRunnerApplication.java index 175d81e..e7d795b 100644 --- a/src/com/dougkeen/bart/BartRunnerApplication.java +++ b/src/com/dougkeen/bart/BartRunnerApplication.java @@ -4,10 +4,13 @@ import android.app.Application; import android.media.MediaPlayer; import com.dougkeen.bart.model.Departure; +import com.dougkeen.util.Observable; public class BartRunnerApplication extends Application { private Departure mBoardedDeparture; + private Observable mAlarmPending = new Observable(false); + private boolean mPlayAlarmRingtone; private boolean mAlarmSounding; @@ -46,4 +49,16 @@ public class BartRunnerApplication extends Application { this.mAlarmMediaPlayer = alarmMediaPlayer; } + public boolean isAlarmPending() { + return mAlarmPending.getValue(); + } + + public Observable getAlarmPendingObservable() { + return mAlarmPending; + } + + public void setAlarmPending(boolean alarmPending) { + this.mAlarmPending.setValue(alarmPending); + } + } \ No newline at end of file diff --git a/src/com/dougkeen/bart/EtdService.java b/src/com/dougkeen/bart/EtdService.java index fea62d7..14b131f 100644 --- a/src/com/dougkeen/bart/EtdService.java +++ b/src/com/dougkeen/bart/EtdService.java @@ -67,10 +67,11 @@ public class EtdService extends Service { public void unregisterListener(EtdServiceListener listener) { StationPair stationPair = getStationPairFromListener(listener); - if (stationPair == null) - return; - - if (mServiceEngineMap.containsKey(stationPair)) { + if (stationPair == null) { + for (EtdServiceEngine engine : mServiceEngineMap.values()) { + engine.unregisterListener(listener); + } + } else if (mServiceEngineMap.containsKey(stationPair)) { mServiceEngineMap.get(stationPair).unregisterListener(listener); } } @@ -93,7 +94,6 @@ public class EtdService extends Service { } public class EtdServiceBinder extends Binder { - public EtdService getService() { return EtdService.this; } @@ -210,9 +210,9 @@ public class EtdService extends Service { mIgnoreDepartureDirection) { @Override public void onResult(RealTimeDepartures result) { - Log.d(Constants.TAG, "Processing data from server"); + Log.v(Constants.TAG, "Processing data from server"); processLatestDepartures(result); - Log.d(Constants.TAG, "Done processing data from server"); + Log.v(Constants.TAG, "Done processing data from server"); notifyListenersOfRequestEnd(); mPendingEtdRequest = false; } @@ -227,7 +227,7 @@ public class EtdService extends Service { } }; mGetDeparturesTask = task; - Log.d(Constants.TAG, "Fetching data from server"); + Log.v(Constants.TAG, "Fetching data from server"); task.execute(new StationPair(mStationPair.getOrigin(), mStationPair .getDestination())); notifyListenersOfRequestStart(); @@ -244,10 +244,10 @@ public class EtdService extends Service { GetScheduleInformationTask task = new GetScheduleInformationTask() { @Override public void onResult(ScheduleInformation result) { - Log.d(Constants.TAG, "Processing data from server"); + Log.v(Constants.TAG, "Processing data from server"); mLatestScheduleInfo = result; applyScheduleInformation(result); - Log.d(Constants.TAG, "Done processing data from server"); + Log.v(Constants.TAG, "Done processing data from server"); } @Override @@ -299,8 +299,8 @@ public class EtdService extends Service { ScheduleItem trip = mLatestScheduleInfo.getTrips().get(i); // Definitely not a match if they have different // destinations - if (!departure.getTrainDestination().abbreviation.equals(trip - .getTrainHeadStation())) { + if (!departure.getTrainDestination().abbreviation + .equals(trip.getTrainHeadStation())) { continue; } @@ -582,7 +582,7 @@ public class EtdService extends Service { } }, millisUntilExecute); mNextFetchClockTime = requestedFetchTime; - Log.d(Constants.TAG, "Scheduled another departure fetch in " + Log.i(Constants.TAG, "Scheduled another departure fetch in " + millisUntilExecute / 1000 + "s"); } } @@ -593,7 +593,7 @@ public class EtdService extends Service { fetchLatestSchedule(); } }, millisUntilExecute); - Log.d(Constants.TAG, "Scheduled another schedule fetch in " + Log.i(Constants.TAG, "Scheduled another schedule fetch in " + millisUntilExecute / 1000 + "s"); } diff --git a/src/com/dougkeen/bart/NotificationService.java b/src/com/dougkeen/bart/NotificationService.java index 530c757..17840f3 100644 --- a/src/com/dougkeen/bart/NotificationService.java +++ b/src/com/dougkeen/bart/NotificationService.java @@ -2,6 +2,8 @@ package com.dougkeen.bart; import java.util.List; +import org.apache.commons.lang3.time.DateFormatUtils; + import android.app.AlarmManager; import android.app.NotificationManager; import android.app.PendingIntent; @@ -19,6 +21,8 @@ import android.os.Message; import android.os.SystemClock; import android.support.v4.app.NotificationCompat; import android.support.v4.app.NotificationCompat.Builder; +import android.util.Log; +import android.util.TimeFormatException; import com.dougkeen.bart.EtdService.EtdServiceBinder; import com.dougkeen.bart.EtdService.EtdServiceListener; @@ -103,6 +107,7 @@ public class NotificationService extends Service implements EtdServiceListener { @Override public int onStartCommand(Intent intent, int flags, int startId) { + mHasShutDown = false; onStart(intent, startId); return START_STICKY; } @@ -119,8 +124,9 @@ public class NotificationService extends Service implements EtdServiceListener { protected void onHandleIntent(Intent intent) { final Departure boardedDeparture = ((BartRunnerApplication) getApplication()) .getBoardedDeparture(); - if (boardedDeparture == null) { - // Nothing to notify about + if (boardedDeparture == null + || intent.getBooleanExtra("cancelAlarm", false)) { + // Nothing to notify about, or we want to cancel the alarm shutDown(false); return; } @@ -139,14 +145,14 @@ public class NotificationService extends Service implements EtdServiceListener { mEtdService.registerListener(this); } - updateNotification(); - Intent targetIntent = new Intent(Intent.ACTION_VIEW, mStationPair.getUri()); targetIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); mNotificationIntent = PendingIntent.getActivity(this, 0, targetIntent, PendingIntent.FLAG_UPDATE_CURRENT); + updateNotification(); + setAlarm(); pollDepartureStatus(); @@ -168,14 +174,20 @@ public class NotificationService extends Service implements EtdServiceListener { if (mAlertLeadTime > 0) { long alertTime = getAlarmClockTime(); if (alertTime > System.currentTimeMillis()) { + if (Log.isLoggable(Constants.TAG, Log.VERBOSE)) + Log.v(Constants.TAG, "Scheduling alarm for " + + DateFormatUtils.format(alertTime, "h:mm:ss")); refreshAlarmPendingIntent(); mAlarmManager.set(AlarmManager.RTC_WAKEUP, alertTime, mAlarmPendingIntent); + ((BartRunnerApplication) getApplication()) + .setAlarmPending(true); } } } private void triggerAlarmImmediately() { + Log.v(Constants.TAG, "Setting off alarm immediately"); cancelAlarm(); refreshAlarmPendingIntent(); mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, @@ -189,6 +201,7 @@ public class NotificationService extends Service implements EtdServiceListener { } private void cancelAlarm() { + ((BartRunnerApplication) getApplication()).setAlarmPending(false); mAlarmManager.cancel(mAlarmPendingIntent); } @@ -280,7 +293,9 @@ public class NotificationService extends Service implements EtdServiceListener { private void updateNotification() { if (mHasShutDown) { - mNotificationManager.cancel(DEPARTURE_NOTIFICATION_ID); + if (mEtdService != null) { + mEtdService.unregisterListener(this); + } return; } @@ -292,16 +307,35 @@ public class NotificationService extends Service implements EtdServiceListener { : (String.format("~%.1f minute", minutes) + ((minutes != 1.0) ? "s" : "")); + final Intent cancelAlarmIntent = new Intent(getApplicationContext(), + NotificationService.class); + cancelAlarmIntent.putExtra("cancelAlarm", true); Builder notificationBuilder = new NotificationCompat.Builder(this) .setOngoing(true) .setSmallIcon(R.drawable.ic_stat_notification) .setContentTitle( mStationPair.getOrigin().shortName + " to " + mStationPair.getDestination().shortName) - .setContentText(minutesText + " until departure") - .setSubText( - "Alert " + mAlertLeadTime + " minutes before departure") .setContentIntent(mNotificationIntent).setWhen(0); + if (android.os.Build.VERSION.SDK_INT > 16) { + notificationBuilder + .setPriority(NotificationCompat.PRIORITY_HIGH) + .addAction( + R.drawable.ic_action_cancel_alarm, + "Cancel alarm", + PendingIntent.getService(getApplicationContext(), + 0, cancelAlarmIntent, + PendingIntent.FLAG_UPDATE_CURRENT)) + .setContentText(minutesText + " until departure") + .setSubText( + "Alert " + mAlertLeadTime + + " minutes before departure"); + } else { + notificationBuilder.setContentText(minutesText + + " to departure (alarm at " + mAlertLeadTime + " min" + + ((mAlertLeadTime == 1) ? "" : "s") + ")"); + } + mNotificationManager.notify(DEPARTURE_NOTIFICATION_ID, notificationBuilder.build()); } @@ -318,11 +352,7 @@ public class NotificationService extends Service implements EtdServiceListener { return 10000000; // Arbitrarily large number } - if (secondsToAlarm > 10 * 60) { - return 60 * 1000; - } else if (secondsToAlarm > 5 * 60) { - return 60 * 1000; - } else if (secondsToAlarm > 3 * 60) { + if (secondsToAlarm > 3 * 60) { return 30 * 1000; } else { return 10 * 1000; diff --git a/src/com/dougkeen/bart/TrainAlertDialogFragment.java b/src/com/dougkeen/bart/TrainAlertDialogFragment.java index 5b9c353..644478d 100644 --- a/src/com/dougkeen/bart/TrainAlertDialogFragment.java +++ b/src/com/dougkeen/bart/TrainAlertDialogFragment.java @@ -82,8 +82,7 @@ public class TrainAlertDialogFragment extends DialogFragment { alertLeadTime); editor.commit(); - Intent intent = new Intent(getActivity() - .getApplicationContext(), + Intent intent = new Intent(getActivity(), NotificationService.class); intent.putExtra("alertLeadTime", alertLeadTime); getActivity().startService(intent); diff --git a/src/com/dougkeen/bart/ViewDeparturesActivity.java b/src/com/dougkeen/bart/ViewDeparturesActivity.java index 2920b80..c9818f3 100644 --- a/src/com/dougkeen/bart/ViewDeparturesActivity.java +++ b/src/com/dougkeen/bart/ViewDeparturesActivity.java @@ -49,6 +49,7 @@ import com.dougkeen.bart.model.Departure; import com.dougkeen.bart.model.Station; import com.dougkeen.bart.model.StationPair; import com.dougkeen.bart.model.TextProvider; +import com.dougkeen.util.Observer; public class ViewDeparturesActivity extends SherlockFragmentActivity implements EtdServiceListener { @@ -291,6 +292,8 @@ public class ViewDeparturesActivity extends SherlockFragmentActivity implements } }; + private Observer mAlarmPendingObserver; + protected DepartureArrayAdapter getListAdapter() { return mDeparturesAdapter; } @@ -305,6 +308,10 @@ public class ViewDeparturesActivity extends SherlockFragmentActivity implements super.onStop(); if (mEtdService != null) mEtdService.unregisterListener(this); + if (mAlarmPendingObserver != null) + ((BartRunnerApplication) getApplication()) + .getAlarmPendingObservable().unregisterObserver( + mAlarmPendingObserver); if (mBound) unbindService(mConnection); Ticker.getInstance().stopTicking(); @@ -355,6 +362,25 @@ public class ViewDeparturesActivity extends SherlockFragmentActivity implements public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getSupportMenuInflater(); inflater.inflate(R.menu.route_menu, menu); + final MenuItem cancelAlarmButton = menu + .findItem(R.id.cancel_alarm_button); + final BartRunnerApplication application = (BartRunnerApplication) getApplication(); + if (application.isAlarmPending()) { + cancelAlarmButton.setVisible(true); + } + mAlarmPendingObserver = new Observer() { + @Override + public void onUpdate(final Boolean newValue) { + runOnUiThread(new Runnable() { + @Override + public void run() { + cancelAlarmButton.setVisible(newValue); + } + }); + } + }; + application.getAlarmPendingObservable().registerObserver( + mAlarmPendingObserver); return true; } @@ -367,6 +393,11 @@ public class ViewDeparturesActivity extends SherlockFragmentActivity implements intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); return true; + } else if (itemId == R.id.cancel_alarm_button) { + Intent intent = new Intent(this, NotificationService.class); + intent.putExtra("cancelAlarm", true); + startService(intent); + return true; } else if (itemId == R.id.view_on_bart_site_button) { startActivity(new Intent( Intent.ACTION_VIEW, @@ -477,7 +508,7 @@ public class ViewDeparturesActivity extends SherlockFragmentActivity implements refreshBoardedDeparture(); // Stop the notification service - stopService(new Intent(getApplicationContext(), + stopService(new Intent(ViewDeparturesActivity.this, NotificationService.class)); // Don't prompt for alert if train is about to leave diff --git a/src/com/dougkeen/util/Observable.java b/src/com/dougkeen/util/Observable.java new file mode 100644 index 0000000..4dd97bd --- /dev/null +++ b/src/com/dougkeen/util/Observable.java @@ -0,0 +1,46 @@ +package com.dougkeen.util; + +import java.util.WeakHashMap; + +import org.apache.commons.lang3.ObjectUtils; + +public class Observable { + private T value; + private WeakHashMap, Boolean> listeners = new WeakHashMap, Boolean>(); + + public Observable() { + super(); + } + + public Observable(T value) { + super(); + this.value = value; + } + + public T getValue() { + return value; + } + + public void setValue(T value) { + if (!ObjectUtils.equals(this.value, value)) { + this.value = value; + notifyOfChange(value); + } + } + + public void registerObserver(Observer observer) { + listeners.put(observer, true); + } + + public void unregisterObserver(Observer observer) { + listeners.remove(observer); + } + + protected void notifyOfChange(T value) { + for (Observer listener : listeners.keySet()) { + if (listener != null) { + listener.onUpdate(value); + } + } + } +} diff --git a/src/com/dougkeen/util/Observer.java b/src/com/dougkeen/util/Observer.java new file mode 100644 index 0000000..0645024 --- /dev/null +++ b/src/com/dougkeen/util/Observer.java @@ -0,0 +1,5 @@ +package com.dougkeen.util; + +public interface Observer { + void onUpdate(final T newValue); +}