Change from timers to threads and runnables.
This commit is contained in:
		| @@ -6,6 +6,7 @@ import android.app.PendingIntent; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.os.Bundle; | ||||
| import android.os.Handler; | ||||
| import android.os.Vibrator; | ||||
| import android.util.Log; | ||||
| import android.view.View; | ||||
| @@ -25,47 +26,51 @@ import java.util.TimerTask; | ||||
| public class AlarmAlertActivity extends Activity { | ||||
|     // TODO correct alert lifetime | ||||
|     private static final int ALERT_LIFE = 1000*10;//1000*60*2; // 2 minutes | ||||
|     private static final Timer timer = new Timer("AlarmAlertActivity"); | ||||
|     private static final long[] vPattern = {500, 500}; | ||||
|     private static final Handler handler = new Handler(); | ||||
|     private static Runnable r; | ||||
|     private static AlarmManager graceManager; | ||||
|     private static PendingIntent gracePendingIntent; | ||||
|     private static Intent notifyIntent; | ||||
|     private static Vibrator vibrator; | ||||
|     private static Boolean userCancelled; | ||||
|  | ||||
|     @Override | ||||
|     protected void onCreate(Bundle savedInstanceState) { | ||||
|         super.onCreate(savedInstanceState); | ||||
|         requestWindowFeature(Window.FEATURE_NO_TITLE); | ||||
|         Window window = getWindow(); | ||||
|         // Set to use the full screen | ||||
|         int fullScreen = WindowManager.LayoutParams.FLAG_FULLSCREEN; | ||||
|         // if KitKat, mimic the main alarm | ||||
|         fullScreen = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS; | ||||
|         window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | ||||
|                 | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | ||||
|                 | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | ||||
|                 | WindowManager.LayoutParams.FLAG_FULLSCREEN | ||||
|                 | fullScreen | ||||
|         ); | ||||
|         setContentView(R.layout.alarm_alert); | ||||
|  | ||||
|         // Disable any current notifications | ||||
|         stopService(new Intent(getApplicationContext(), AlarmNotify.class)); | ||||
|         notifyIntent = new Intent(getApplicationContext(), AlarmNotify.class); | ||||
|  | ||||
|         // Disable any current notifications | ||||
|         stopService(notifyIntent); | ||||
|  | ||||
|         // Turn off the alert activity, and switch to a notification | ||||
|         timer.schedule(new TimerTask() { | ||||
|         r = new Runnable() { | ||||
|             public void run() { | ||||
|                 // Close the dialogue | ||||
|                 finish(); | ||||
|                 // Switch to notification if the Activity has not been closed by the user | ||||
|                 if (!userCancelled) { | ||||
|                     startService(new Intent(getApplicationContext(), AlarmNotify.class)); | ||||
|                     Log.d("AlarmAlertActivity", "Started notification"); | ||||
|                 } | ||||
|                 startService(notifyIntent); | ||||
|                 Log.d("AlarmAlertActivity", "Started notification"); | ||||
|             } | ||||
|         }, ALERT_LIFE); | ||||
|         }; | ||||
|         handler.postDelayed(r, ALERT_LIFE); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onStart() { | ||||
|         super.onStart(); | ||||
|         userCancelled = false; | ||||
|  | ||||
|         vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); | ||||
|         vibrator.vibrate(vPattern, 0); | ||||
| @@ -81,18 +86,16 @@ public class AlarmAlertActivity extends Activity { | ||||
|                 gracePendingIntent = PendingIntent.getBroadcast(getApplicationContext(), MainActivity.GRACE_REQUEST, graceIntent, 0); | ||||
|                 graceManager.cancel(gracePendingIntent); | ||||
|                 Log.d("AlarmAlertActivity", "Cancelled grace alarm."); | ||||
|                 // Ensure we don't load a notification later on | ||||
|                 userCancelled = true; | ||||
|                 // Close the dialogue (stop vibration &c) | ||||
|                 finish(); | ||||
|             } | ||||
|  | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     public void onStop() { | ||||
|         // Ensure we don't load a notification now | ||||
|         handler.removeCallbacks(r); | ||||
|         vibrator.cancel(); | ||||
|         super.onStop(); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -17,8 +17,8 @@ import java.util.Timer; | ||||
| import java.util.TimerTask; | ||||
|  | ||||
| public class AlarmNotify extends Service { | ||||
|     private static final Timer timer = new Timer("AlarmNotify"); | ||||
|     public  static final int notifyID = 1; | ||||
|     private volatile boolean threadRunning = false; | ||||
|  | ||||
|     @Override | ||||
|     public IBinder onBind(Intent intent) { | ||||
| @@ -27,10 +27,11 @@ public class AlarmNotify extends Service { | ||||
|  | ||||
|     @Override | ||||
|     public void onDestroy() { | ||||
|         // If the notification is cancelled, stop updating. | ||||
|         threadRunning = false; | ||||
|         // Remove the notification in the notification bar | ||||
|         NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); | ||||
|         nm.cancel(notifyID); | ||||
|         timer.cancel(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -76,30 +77,43 @@ public class AlarmNotify extends Service { | ||||
|         nm.cancel(notifyID); | ||||
|         nm.notify(notifyID, notification.build()); | ||||
|  | ||||
|         timer.scheduleAtFixedRate(new TimerTask() { | ||||
|             // this is called at every UPDATE_INTERVAL | ||||
|         new Thread(new Runnable() { | ||||
|             @Override | ||||
|             public void run() { | ||||
|                 threadRunning = true; | ||||
|                 int max = 1000; | ||||
|                 // Convert endTime from milliseconds to seconds, and translate to time remaining | ||||
|                 int secondsLeft = (int) ((endTime - System.currentTimeMillis()))/(1000); | ||||
|                 int secondsLeft = (int) ((endTime - System.currentTimeMillis())) / (1000); | ||||
|                 int gracePeriodSeconds = gracePeriod * 60; | ||||
|                 // Multiply each int by 1000 for greater progress resolution | ||||
|                 int progress = ((((gracePeriodSeconds * 1000) - (secondsLeft * 1000)) * max) / (gracePeriodSeconds * 1000) ); | ||||
|                 //Log.d("AlarmNotify", "secondsLeft is "+secondsLeft+" and progress is "+progress+" (gracePeriodSeconds is "+gracePeriodSeconds+")"); | ||||
|                 if (secondsLeft >= 0) { | ||||
|                     int minutesLeft = secondsLeft/60; | ||||
|                 int progress = ((((gracePeriodSeconds * 1000) - (secondsLeft * 1000)) * max) / (gracePeriodSeconds * 1000)); | ||||
|  | ||||
|                 while (progress < max) { | ||||
|                     // Stop the thread if cancelled elsewhere | ||||
|                     if (!threadRunning) { | ||||
|                         return; | ||||
|                     } | ||||
|                     //Log.d("AlarmNotify", "secondsLeft is "+secondsLeft+" and progress is "+progress+" (gracePeriodSeconds is "+gracePeriodSeconds+")"); | ||||
|                     int minutesLeft = secondsLeft / 60; | ||||
|                     notification.setContentText(String.format(getString(R.string.notificationText), MainActivity.MinutesToGracePeriodStr(minutesLeft))); | ||||
|                     notification.setProgress(max, progress, false); | ||||
|                     // Update the notification | ||||
|                     nm.notify(notifyID, notification.build()); | ||||
|                 } else { | ||||
|                     nm.cancel(notifyID); | ||||
|                     this.cancel(); // Cancel timer | ||||
|                     stopSelf();    // stop service | ||||
|                     // Prepare secondsLeft and progress for the next loop | ||||
|                     secondsLeft = secondsLeft - (UPDATE_INTERVAL / 1000); | ||||
|                     // Multiply each int by 1000 for greater progress resolution | ||||
|                     progress = ((((gracePeriodSeconds * 1000) - (secondsLeft * 1000)) * max) / (gracePeriodSeconds * 1000)); | ||||
|                     // Sleeps the thread, simulating an operation | ||||
|                     // that takes time | ||||
|                     try { | ||||
|                         Thread.sleep(UPDATE_INTERVAL); | ||||
|                     } catch (InterruptedException e) { | ||||
|                         Log.d("AlarmNotify", "sleep failure"); | ||||
|                     } | ||||
|                 } | ||||
|                 stopSelf(); // stop notification service | ||||
|             } | ||||
|         }, 0, UPDATE_INTERVAL); | ||||
|         }).start(); | ||||
|  | ||||
| 		return super.onStartCommand(intent, flags, startId); | ||||
|     } | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  | ||||
|     <string name="alarm_alert">Alarm Alert</string> | ||||
|  | ||||
|     <string name="alarm_notification">SMS pending</string> | ||||
|     <string name="alarm_notification">Text message pending</string> | ||||
|  | ||||
|     <string-array name="grace_period_array"> | ||||
|         <item>10 minutes</item> | ||||
| @@ -47,11 +47,11 @@ | ||||
|  | ||||
|     <string name="alarmSetToast">HypoAlarm set to </string> | ||||
|  | ||||
|     <string name="alarmCancelToast">HypoAlarm SMS cancelled</string> | ||||
|     <string name="alarmCancelToast">HypoAlarm text message cancelled</string> | ||||
|  | ||||
|     <string name="defaultMessage">Hi, I haven\'t responded to my alarm today. Please contact me to make sure I\'m awake.</string> | ||||
|  | ||||
|     <string name="notificationText">An SMS will be sent in %1$s</string> | ||||
|     <string name="notificationText">A text message will be sent in %1$s</string> | ||||
|  | ||||
|     <string name="notificationCancellation">Cancel</string> | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user