Change from timers to threads and runnables.

This commit is contained in:
Timothy Allen 2014-03-26 11:14:22 +02:00
parent c01e340aca
commit 68c2abd06d
3 changed files with 50 additions and 33 deletions

View File

@ -6,6 +6,7 @@ import android.app.PendingIntent;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.os.Vibrator; import android.os.Vibrator;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
@ -25,47 +26,51 @@ import java.util.TimerTask;
public class AlarmAlertActivity extends Activity { public class AlarmAlertActivity extends Activity {
// TODO correct alert lifetime // TODO correct alert lifetime
private static final int ALERT_LIFE = 1000*10;//1000*60*2; // 2 minutes 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 long[] vPattern = {500, 500};
private static final Handler handler = new Handler();
private static Runnable r;
private static AlarmManager graceManager; private static AlarmManager graceManager;
private static PendingIntent gracePendingIntent; private static PendingIntent gracePendingIntent;
private static Intent notifyIntent;
private static Vibrator vibrator; private static Vibrator vibrator;
private static Boolean userCancelled;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); requestWindowFeature(Window.FEATURE_NO_TITLE);
Window window = getWindow(); 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 window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_FULLSCREEN | fullScreen
); );
setContentView(R.layout.alarm_alert); setContentView(R.layout.alarm_alert);
// Disable any current notifications notifyIntent = new Intent(getApplicationContext(), AlarmNotify.class);
stopService(new Intent(getApplicationContext(), AlarmNotify.class));
// Disable any current notifications
stopService(notifyIntent);
// Turn off the alert activity, and switch to a notification // Turn off the alert activity, and switch to a notification
timer.schedule(new TimerTask() { r = new Runnable() {
public void run() { public void run() {
// Close the dialogue // Close the dialogue
finish(); finish();
// Switch to notification if the Activity has not been closed by the user // Switch to notification if the Activity has not been closed by the user
if (!userCancelled) { startService(notifyIntent);
startService(new Intent(getApplicationContext(), AlarmNotify.class)); Log.d("AlarmAlertActivity", "Started notification");
Log.d("AlarmAlertActivity", "Started notification");
}
} }
}, ALERT_LIFE); };
handler.postDelayed(r, ALERT_LIFE);
} }
@Override @Override
public void onStart() { public void onStart() {
super.onStart(); super.onStart();
userCancelled = false;
vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(vPattern, 0); vibrator.vibrate(vPattern, 0);
@ -81,18 +86,16 @@ public class AlarmAlertActivity extends Activity {
gracePendingIntent = PendingIntent.getBroadcast(getApplicationContext(), MainActivity.GRACE_REQUEST, graceIntent, 0); gracePendingIntent = PendingIntent.getBroadcast(getApplicationContext(), MainActivity.GRACE_REQUEST, graceIntent, 0);
graceManager.cancel(gracePendingIntent); graceManager.cancel(gracePendingIntent);
Log.d("AlarmAlertActivity", "Cancelled grace alarm."); Log.d("AlarmAlertActivity", "Cancelled grace alarm.");
// Ensure we don't load a notification later on
userCancelled = true;
// Close the dialogue (stop vibration &c) // Close the dialogue (stop vibration &c)
finish(); finish();
} }
}); });
} }
public void onStop() { public void onStop() {
// Ensure we don't load a notification now
handler.removeCallbacks(r);
vibrator.cancel(); vibrator.cancel();
super.onStop(); super.onStop();
} }
} }

View File

@ -17,8 +17,8 @@ import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
public class AlarmNotify extends Service { public class AlarmNotify extends Service {
private static final Timer timer = new Timer("AlarmNotify");
public static final int notifyID = 1; public static final int notifyID = 1;
private volatile boolean threadRunning = false;
@Override @Override
public IBinder onBind(Intent intent) { public IBinder onBind(Intent intent) {
@ -27,10 +27,11 @@ public class AlarmNotify extends Service {
@Override @Override
public void onDestroy() { public void onDestroy() {
// If the notification is cancelled, stop updating.
threadRunning = false;
// Remove the notification in the notification bar // Remove the notification in the notification bar
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nm.cancel(notifyID); nm.cancel(notifyID);
timer.cancel();
} }
@Override @Override
@ -76,30 +77,43 @@ public class AlarmNotify extends Service {
nm.cancel(notifyID); nm.cancel(notifyID);
nm.notify(notifyID, notification.build()); nm.notify(notifyID, notification.build());
timer.scheduleAtFixedRate(new TimerTask() { new Thread(new Runnable() {
// this is called at every UPDATE_INTERVAL
@Override @Override
public void run() { public void run() {
threadRunning = true;
int max = 1000; int max = 1000;
// Convert endTime from milliseconds to seconds, and translate to time remaining // 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; int gracePeriodSeconds = gracePeriod * 60;
// Multiply each int by 1000 for greater progress resolution // Multiply each int by 1000 for greater progress resolution
int progress = ((((gracePeriodSeconds * 1000) - (secondsLeft * 1000)) * max) / (gracePeriodSeconds * 1000) ); 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) { while (progress < max) {
int minutesLeft = secondsLeft/60; // 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.setContentText(String.format(getString(R.string.notificationText), MainActivity.MinutesToGracePeriodStr(minutesLeft)));
notification.setProgress(max, progress, false); notification.setProgress(max, progress, false);
// Update the notification // Update the notification
nm.notify(notifyID, notification.build()); nm.notify(notifyID, notification.build());
} else { // Prepare secondsLeft and progress for the next loop
nm.cancel(notifyID); secondsLeft = secondsLeft - (UPDATE_INTERVAL / 1000);
this.cancel(); // Cancel timer // Multiply each int by 1000 for greater progress resolution
stopSelf(); // stop service 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); return super.onStartCommand(intent, flags, startId);
} }

View File

@ -5,7 +5,7 @@
<string name="alarm_alert">Alarm Alert</string> <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"> <string-array name="grace_period_array">
<item>10 minutes</item> <item>10 minutes</item>
@ -47,11 +47,11 @@
<string name="alarmSetToast">HypoAlarm set to </string> <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="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> <string name="notificationCancellation">Cancel</string>