- Add a pre-alarm notification
- Initial location stuff.
This commit is contained in:
		| @@ -21,9 +21,12 @@ | ||||
|                     android:launchMode="singleInstance" | ||||
|                     android:noHistory="true"> | ||||
|         </activity> | ||||
|         <receiver android:name=".PreAlarmReceiver"/> | ||||
|         <receiver android:name=".CancelAlarmReceiver"/> | ||||
|         <receiver android:name=".AlarmReceiver"/> | ||||
|         <receiver android:name=".GraceReceiver"/> | ||||
|         <receiver android:name=".CancelGraceReceiver"/> | ||||
|  | ||||
|         <receiver android:name=".BootReceiver" | ||||
|             android:enabled="false" > | ||||
|             <intent-filter> | ||||
| @@ -35,6 +38,11 @@ | ||||
|             android:name=".AlarmNotify" | ||||
|             android:label="@string/alarm_notification" > | ||||
|         </service> | ||||
|  | ||||
|         <service | ||||
|             android:name=".PreAlarmNotify" | ||||
|             android:label="@string/alarm_notification" > | ||||
|         </service> | ||||
|     </application> | ||||
|  | ||||
|     <!-- permission required to read contacts --> | ||||
|   | ||||
| @@ -23,8 +23,8 @@ import java.util.Calendar; | ||||
|  */ | ||||
|  | ||||
| public class AlarmReceiver extends BroadcastReceiver { | ||||
|     private static final int SNOOZE_TIME = 1000*20; //TODO 1000*60*5; // Snooze for 5 minutes if need be | ||||
|     private static final int ALERT_LIFE = 1000*60;  //TODO 1000*60*2; // 2 minutes | ||||
|     private static final int SNOOZE_TIME = 0; //1000*60*5; // Snooze for 5 minutes if need be | ||||
|     private static final int ALERT_LIFE = 1000*10;  //TODO 1000*60*2; // 2 minutes | ||||
|     private static SharedPreferences sharedPref; | ||||
|     private static AlarmManager alarmManager, graceManager; | ||||
|     private static PendingIntent alarmPendingIntent, gracePendingIntent; | ||||
| @@ -44,10 +44,18 @@ public class AlarmReceiver extends BroadcastReceiver { | ||||
|         int gracePeriod = sharedPref.getInt(context.getString(R.string.GracePeriodPref), 60); | ||||
|         String alarmTimeStr = sharedPref.getString(context.getString(R.string.AlarmTimePref), null); | ||||
|  | ||||
|         // TODO remove | ||||
|         if (MainActivity.HYPOALARM_DEBUG) { | ||||
|             gracePeriod = 1; | ||||
|         } | ||||
|  | ||||
|         if (alarmActive) { | ||||
|             // if nothing else happens, assume the alert was ignored. | ||||
|             alarmStatus = ALARM_RUNNING; | ||||
|  | ||||
|             // Cancel the pre-alarm notification, if it exists | ||||
|             context.stopService(new Intent(context, PreAlarmNotify.class)); | ||||
|  | ||||
|             // Set a grace period alarm to send SMS | ||||
|             Calendar graceCal = Calendar.getInstance(); | ||||
|             graceCal.set(Calendar.SECOND, 0); | ||||
| @@ -76,8 +84,9 @@ public class AlarmReceiver extends BroadcastReceiver { | ||||
|             startAlert(context); | ||||
|  | ||||
|             // Reset for tomorrow; as of API 19, setRepeating() is inexact, so we use setExact() | ||||
|             // (Calendar will automatically advance the day since today's alarmTimeStr is now in the past.) | ||||
|             Calendar cal = MainActivity.TimeStringToCalendar(alarmTimeStr); | ||||
|             // Advance the calendar to tomorrow | ||||
|             cal.add(Calendar.DAY_OF_MONTH, 1); | ||||
|             alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); | ||||
|             alarmPendingIntent = PendingIntent.getBroadcast(context, MainActivity.ALARM_REQUEST, intent, 0); | ||||
|             alarmManager.cancel(alarmPendingIntent); | ||||
| @@ -108,8 +117,8 @@ public class AlarmReceiver extends BroadcastReceiver { | ||||
|                     alarmStatus.contentEquals(ALARM_SNOOZED)) { | ||||
|                     return; | ||||
|                 } | ||||
|                 // Stop if we're running the snooze alert | ||||
|                 if (alarmStatus.contentEquals(ALARM_SNOOZE_RUNNING)) { | ||||
|                 // Stop if we're running the snooze alert, or the snooze time is less than 10 seconds | ||||
|                 if (alarmStatus.contentEquals(ALARM_SNOOZE_RUNNING) || SNOOZE_TIME < 10000) { | ||||
|                     stopAlert(context); | ||||
|                 } else { | ||||
|                     alarmStatus = ALARM_IGNORED; // This is true, although we are about to switch to ALARM_SNOOZED | ||||
|   | ||||
| @@ -0,0 +1,48 @@ | ||||
| package za.org.treehouse.hypoalarm; | ||||
|  | ||||
| import android.app.AlarmManager; | ||||
| import android.app.PendingIntent; | ||||
| import android.content.BroadcastReceiver; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
| import android.os.Build; | ||||
| import android.preference.PreferenceManager; | ||||
| import android.util.Log; | ||||
| import android.widget.Toast; | ||||
|  | ||||
| import java.util.Calendar; | ||||
|  | ||||
| public class CancelAlarmReceiver extends BroadcastReceiver { | ||||
|     @Override | ||||
|     public void onReceive(Context context, Intent intent) { | ||||
|         SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context); | ||||
|         String alarmTimeStr = sharedPref.getString(context.getString(R.string.AlarmTimePref), null); | ||||
|  | ||||
|         AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); | ||||
|         Intent alarmIntent = new Intent(context, AlarmReceiver.class); | ||||
|         PendingIntent alarmPendingIntent = PendingIntent.getBroadcast(context, MainActivity.ALARM_REQUEST, alarmIntent, 0); | ||||
|         alarmManager.cancel(alarmPendingIntent); | ||||
|         Log.d("CancelAlarmReceiver", "Cancelled grace alarm"); | ||||
|  | ||||
|         // Reset alarm for tomorrow | ||||
|  | ||||
|         // Reset for tomorrow; as of API 19, setRepeating() is inexact, so we use setExact() | ||||
|         Calendar cal = MainActivity.TimeStringToCalendar(alarmTimeStr); | ||||
|         // Set for tomorrow | ||||
|         cal.add(Calendar.DAY_OF_MONTH, 1); | ||||
|         if (Build.VERSION.SDK_INT >= 19) { | ||||
|             alarmManager.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), alarmPendingIntent); | ||||
|         } else { | ||||
|             alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), alarmPendingIntent); | ||||
|         } | ||||
|         Log.d("CancelAlarmReceiver", "Resetting alarm for " + MainActivity.debugDate(cal)); | ||||
|  | ||||
|         // Display toast | ||||
|         Toast.makeText(context, context.getString(R.string.alarmCancelToast), Toast.LENGTH_LONG).show(); | ||||
|  | ||||
|         // Remove notification | ||||
|         context.stopService(new Intent(context, PreAlarmNotify.class)); | ||||
|  | ||||
|     } | ||||
| } | ||||
| @@ -4,29 +4,64 @@ import android.content.BroadcastReceiver; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
| import android.location.Location; | ||||
| import android.location.LocationListener; | ||||
| import android.location.LocationManager; | ||||
| import android.os.Bundle; | ||||
| import android.os.PowerManager; | ||||
| import android.preference.PreferenceManager; | ||||
| import android.telephony.SmsManager; | ||||
| import android.util.Log; | ||||
| import android.widget.Toast; | ||||
|  | ||||
| public class GraceReceiver extends BroadcastReceiver { | ||||
|     private static SharedPreferences sharedPref; | ||||
|     private static String uri; | ||||
|  | ||||
|     @Override | ||||
|     public void onReceive(Context context, Intent intent) { | ||||
|         sharedPref = PreferenceManager.getDefaultSharedPreferences(context); | ||||
|         Boolean alarmActive = sharedPref.getBoolean(context.getString(R.string.AlarmActivePref), true); | ||||
|  | ||||
|         // TODO get location of phone and send in the message | ||||
|  | ||||
|         if (alarmActive) { | ||||
|             String phoneNumber = sharedPref.getString(context.getString(R.string.PhoneNumberPref), null); | ||||
|             String message = sharedPref.getString(context.getString(R.string.MessagePref), null); | ||||
|  | ||||
|             // TODO get location of phone and send in the message | ||||
|             LocationManager  locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); | ||||
|             LocationListener locationListener = new LocationListener() { | ||||
|                 public void onLocationChanged(Location location) { | ||||
|                     // Called when a new location is found by the network location provider. | ||||
|                     if (location != null) { | ||||
|                         double latitude = location.getLatitude(); | ||||
|                         double longitude = location.getLongitude(); | ||||
|  | ||||
|                         uri = " http://maps.google.com?q=" + location.getLatitude() + "," + location.getLongitude(); | ||||
|                     } | ||||
|                 } | ||||
|                 public void onStatusChanged(String provider, int status, Bundle extras) { | ||||
|                 } | ||||
|                 public void onProviderEnabled(String provider) { | ||||
|                 } | ||||
|                 public void onProviderDisabled(String provider) { | ||||
|                 } | ||||
|             }; | ||||
|  | ||||
|             if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { | ||||
|                 locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener); | ||||
|             } else if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) { | ||||
|                 locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener); | ||||
|             } | ||||
|  | ||||
|             message += uri; | ||||
|  | ||||
|             SmsManager sms = SmsManager.getDefault(); | ||||
|             // TODO uncomment this: | ||||
|             //sms.sendTextMessage(phoneNumber, null, message, null, null); | ||||
|             Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); | ||||
|             Log.d("GraceReceiver", "Sending sms to " + phoneNumber); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -62,7 +62,9 @@ import java.util.regex.Pattern; | ||||
| public class MainActivity extends ActionBarActivity { | ||||
|     public  static int ALARM_REQUEST = 1; | ||||
|     public  static int GRACE_REQUEST = 2; | ||||
|     public  static int CANCEL_GRACE_REQUEST = 3; | ||||
|     public  static int PRENOTIFY_REQUEST = 3; | ||||
|     public  static int CANCEL_GRACE_REQUEST = 4; | ||||
|     public  static int CANCEL_ALARM_REQUEST = 5; | ||||
|     private static Switch alarmActiveSwitch; | ||||
|     private static Button alarmTimeButton; | ||||
|     private static Spinner gracePeriodSpinner; | ||||
| @@ -268,7 +270,7 @@ public class MainActivity extends ActionBarActivity { | ||||
|     public static class TimePickerFragment extends DialogFragment implements TimePickerDialog.OnTimeSetListener { | ||||
|         SharedPreferences sharedPref; | ||||
|         private AlarmManager alarmManager; | ||||
|         private PendingIntent alarmPendingIntent; | ||||
|         private PendingIntent alarmPendingIntent, preNotifyPendingIntent; | ||||
|  | ||||
|         @Override | ||||
|         public Dialog onCreateDialog(Bundle savedInstanceState) { | ||||
| @@ -319,6 +321,21 @@ public class MainActivity extends ActionBarActivity { | ||||
|                 } | ||||
|                 Log.d("MainActivity", "Setting alarm for " + MainActivity.debugDate(cal)); | ||||
|  | ||||
|                 // Set an alarm for the pre-alarm notification, half an hour before the alarm | ||||
|                 Calendar preNotifyCal = cal; | ||||
|                 preNotifyCal.add(Calendar.MINUTE, -30); | ||||
|                 Intent preNotifyIntent = new Intent(getActivity(), PreAlarmReceiver.class); | ||||
|                 preNotifyPendingIntent = PendingIntent.getBroadcast(getActivity(), PRENOTIFY_REQUEST, preNotifyIntent, 0); | ||||
|                 // Cancel any existing alarms | ||||
|                 alarmManager.cancel(preNotifyPendingIntent); | ||||
|                 // Set or reset alarm | ||||
|                 if (Build.VERSION.SDK_INT >= 19) { | ||||
|                     alarmManager.setExact(AlarmManager.RTC_WAKEUP, preNotifyCal.getTimeInMillis(), preNotifyPendingIntent); | ||||
|                 } else { | ||||
|                     alarmManager.set(AlarmManager.RTC_WAKEUP, preNotifyCal.getTimeInMillis(), preNotifyPendingIntent); | ||||
|                 } | ||||
|                 Log.d("MainActivity", "Setting pre-alarm for " + MainActivity.debugDate(preNotifyCal)); | ||||
|  | ||||
|                 // Set boot receiver, so alarm restarts on boot | ||||
|                 ComponentName receiver = new ComponentName(getActivity(), BootReceiver.class); | ||||
|                 PackageManager pm = getActivity().getPackageManager(); | ||||
| @@ -435,10 +452,6 @@ public class MainActivity extends ActionBarActivity { | ||||
|             cal.set(Calendar.HOUR, dateCal.get(Calendar.HOUR)); | ||||
|             cal.set(Calendar.MINUTE, dateCal.get(Calendar.MINUTE)); | ||||
|             cal.set(Calendar.SECOND, 0); | ||||
|             // Ensure that this date is in the future | ||||
|             if (date.before(new Date())) { | ||||
|                 cal.add(Calendar.DAY_OF_MONTH, 1); | ||||
|             } | ||||
|             return cal; | ||||
|         } catch (ParseException e) { | ||||
|             e.printStackTrace(); | ||||
| @@ -495,6 +508,4 @@ public class MainActivity extends ActionBarActivity { | ||||
|         } | ||||
|         return remMinutes + minStr; | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,69 @@ | ||||
| package za.org.treehouse.hypoalarm; | ||||
|  | ||||
| import android.app.Notification; | ||||
| import android.app.NotificationManager; | ||||
| import android.app.PendingIntent; | ||||
| import android.app.Service; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
| import android.graphics.Bitmap; | ||||
| import android.graphics.BitmapFactory; | ||||
| import android.os.Build; | ||||
| import android.os.IBinder; | ||||
| import android.preference.PreferenceManager; | ||||
| import android.util.Log; | ||||
|  | ||||
| public class PreAlarmNotify extends Service { | ||||
|     public  static final int preNotifyID = 2; | ||||
|  | ||||
|     @Override | ||||
|     public IBinder onBind(Intent intent) { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onDestroy() { | ||||
|         // Remove the notification in the notification bar | ||||
|         NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); | ||||
|         nm.cancel(preNotifyID); | ||||
|         Log.d("AlarmNotify", "Pre-notification stopped."); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public int onStartCommand(Intent intent, int flags, int startId) { | ||||
|         SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); | ||||
|  | ||||
|         Log.d("PreAlarmNotify", "Pre-notification started."); | ||||
|  | ||||
|         String alarmTimeStr = sharedPref.getString(getString(R.string.AlarmTimePref), null); | ||||
|  | ||||
|         Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_grey); | ||||
|         final NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); | ||||
|         if (Build.VERSION.SDK_INT >= 11) { | ||||
|             final Notification.Builder notification = new Notification.Builder(this) | ||||
|                     .setContentTitle(getString(R.string.app_name)) | ||||
|                     .setContentText(getString(R.string.preNotificationText)) | ||||
|                     .setSmallIcon(R.drawable.alarm_notification) | ||||
|                     .setLargeIcon(bm) | ||||
|                     .setOnlyAlertOnce(true) | ||||
|                     .setAutoCancel(false) | ||||
|                     .setPriority(Notification.PRIORITY_HIGH); | ||||
|  | ||||
|             // Set up dismiss action | ||||
|             Intent cancelAlarmIntent = new Intent(getBaseContext(), CancelAlarmReceiver.class); | ||||
|             PendingIntent cancelAlarmPendingIntent = PendingIntent.getBroadcast(getBaseContext(), MainActivity.CANCEL_ALARM_REQUEST, cancelAlarmIntent, PendingIntent.FLAG_CANCEL_CURRENT); | ||||
|  | ||||
|             // Cancel the grace period if the user clears the notification | ||||
|             notification.setDeleteIntent(cancelAlarmPendingIntent); | ||||
|             // Allow the user to cancel by clicking a "Cancel" button | ||||
|             notification.addAction(android.R.drawable.ic_menu_close_clear_cancel, getString(R.string.preNotificationCancellation), cancelAlarmPendingIntent); | ||||
|             // Allow the user to cancel by selecting the ContentText or ContentTitle | ||||
|             notification.setContentIntent(cancelAlarmPendingIntent); | ||||
|  | ||||
|             nm.cancel(this.preNotifyID); | ||||
|             nm.notify(this.preNotifyID, notification.build()); | ||||
|         } | ||||
|         return super.onStartCommand(intent, flags, startId); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,23 @@ | ||||
| package za.org.treehouse.hypoalarm; | ||||
|  | ||||
| import android.content.BroadcastReceiver; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
| import android.preference.PreferenceManager; | ||||
|  | ||||
| public class PreAlarmReceiver extends BroadcastReceiver { | ||||
|     @Override | ||||
|     public void onReceive(final Context context, Intent intent) { | ||||
|         SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context); | ||||
|         Boolean alarmActive = sharedPref.getBoolean(context.getString(R.string.AlarmActivePref), true); | ||||
|         String alarmTimeStr = sharedPref.getString(context.getString(R.string.AlarmTimePref), null); | ||||
|  | ||||
|         if (alarmActive) { | ||||
|             // Create notification | ||||
|             Intent preNotifyIntent = new Intent(context, PreAlarmNotify.class); | ||||
|             // The PreAlarmNotify service can either be stopped by calling CancelAlarmReceiver, or by waiting for AlarmReceiver to run | ||||
|             context.startService(preNotifyIntent); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -55,6 +55,10 @@ | ||||
|  | ||||
|     <string name="notificationCancellation">Cancel</string> | ||||
|  | ||||
|     <string name="preNotificationText">Upcoming alarm</string> | ||||
|  | ||||
|     <string name="preNotificationCancellation">Dismiss Now</string> | ||||
|  | ||||
|     <string name="alarmCancelled">All HypoAlarms cancelled</string> | ||||
|  | ||||
|     <array name="glowpad_target"> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user