Add some SDK checks.

This commit is contained in:
Timothy Allen 2014-03-26 16:43:24 +02:00
parent c32aef7c86
commit c2806f2231
4 changed files with 91 additions and 72 deletions

View File

@ -5,6 +5,7 @@ import android.app.AlarmManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Vibrator; import android.os.Vibrator;
@ -35,8 +36,9 @@ public class AlarmAlertActivity extends Activity {
Window window = getWindow(); Window window = getWindow();
// Set to use the full screen // Set to use the full screen
int fullScreen = WindowManager.LayoutParams.FLAG_FULLSCREEN; int fullScreen = WindowManager.LayoutParams.FLAG_FULLSCREEN;
// TODO if KitKat, mimic the main alarm if (Build.VERSION.SDK_INT >= 19) {
fullScreen = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS; 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

View File

@ -9,6 +9,7 @@ import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.IBinder; import android.os.IBinder;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
@ -44,78 +45,81 @@ public class AlarmNotify extends Service {
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_grey); Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_grey);
final NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); final NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
final Notification.Builder notification = new Notification.Builder(this) if (Build.VERSION.SDK_INT >= 11) {
.setContentTitle(getString(R.string.app_name)) final Notification.Builder notification = new Notification.Builder(this)
.setContentText(String.format(getString(R.string.notificationText), MainActivity.MinutesToGracePeriodStr(gracePeriod))) .setContentTitle(getString(R.string.app_name))
.setSmallIcon(R.drawable.alarm_notification) .setContentText(String.format(getString(R.string.notificationText), MainActivity.MinutesToGracePeriodStr(gracePeriod)))
.setLargeIcon(bm) .setSmallIcon(R.drawable.alarm_notification)
.setOnlyAlertOnce(true) .setLargeIcon(bm)
.setAutoCancel(false) .setOnlyAlertOnce(true)
.setPriority(Notification.PRIORITY_HIGH); .setAutoCancel(false)
.setPriority(Notification.PRIORITY_HIGH);
// Set up dismiss action // Set up dismiss action
Intent cancellerIntent = new Intent(getBaseContext(), CancelGraceReceiver.class); Intent cancellerIntent = new Intent(getBaseContext(), CancelGraceReceiver.class);
PendingIntent cancellerPendingIntent = PendingIntent.getBroadcast(getBaseContext(), MainActivity.CANCEL_GRACE_REQUEST, cancellerIntent, PendingIntent.FLAG_CANCEL_CURRENT); PendingIntent cancellerPendingIntent = PendingIntent.getBroadcast(getBaseContext(), MainActivity.CANCEL_GRACE_REQUEST, cancellerIntent, PendingIntent.FLAG_CANCEL_CURRENT);
// Cancel the grace period if the user clears the notification // Cancel the grace period if the user clears the notification
notification.setDeleteIntent(cancellerPendingIntent); notification.setDeleteIntent(cancellerPendingIntent);
// Allow the user to cancel by clicking a "Cancel" button // Allow the user to cancel by clicking a "Cancel" button
notification.addAction(android.R.drawable.ic_menu_close_clear_cancel, getString(R.string.notificationCancellation), cancellerPendingIntent); notification.addAction(android.R.drawable.ic_menu_close_clear_cancel, getString(R.string.notificationCancellation), cancellerPendingIntent);
// Allow the user to cancel by selecting the ContentText or ContentTitle // Allow the user to cancel by selecting the ContentText or ContentTitle
notification.setContentIntent(cancellerPendingIntent); notification.setContentIntent(cancellerPendingIntent);
/** /**
* TODO load alert activity (without sound or vibration) on select? * TODO load alert activity (without sound or vibration) on select?
* TODO This would allow the user to test competence * TODO This would allow the user to test competence
Intent alertActivityIntent = new Intent(this, AlarmAlertActivity.class); Intent alertActivityIntent = new Intent(this, AlarmAlertActivity.class);
alertActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | alertActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
notification.setContentIntent(alertActivityIntent); notification.setContentIntent(alertActivityIntent);
*/ */
nm.cancel(notifyID); nm.cancel(notifyID);
nm.notify(notifyID, notification.build()); nm.notify(notifyID, notification.build());
new Thread(new Runnable() { new Thread(new Runnable() {
@Override @Override
public void run() { public void run() {
notificationRunning = true; notificationRunning = true;
Log.d("AlarmNotify", "2: Setting notificationRunning to true"); Log.d("AlarmNotify", "2: Setting notificationRunning to 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
int progress = (((gracePeriodSeconds * 1000) - (secondsLeft * 1000)) * max) / (gracePeriodSeconds * 1000);
while (progress < max) {
// Stop the thread if cancelled elsewhere
Log.d("AlarmNotify", "notificationRunning is "+notificationRunning);
if (!notificationRunning) {
return;
}
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());
// Prepare secondsLeft and progress for the next loop
secondsLeft = secondsLeft - (UPDATE_INTERVAL / 1000);
// Multiply each int by 1000 for greater progress resolution // Multiply each int by 1000 for greater progress resolution
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+")");
// 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
}
}).start();
while (progress < max) {
// Stop the thread if cancelled elsewhere
Log.d("AlarmNotify", "notificationRunning is " + notificationRunning);
if (!notificationRunning) {
return;
}
int minutesLeft = secondsLeft / 60;
if (Build.VERSION.SDK_INT >= 11) {
notification.setContentText(String.format(getString(R.string.notificationText), MainActivity.MinutesToGracePeriodStr(minutesLeft)));
notification.setProgress(max, progress, false);
// Update the notification
nm.notify(notifyID, notification.build());
}
// 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);
Log.d("AlarmNotify", "secondsLeft is " + secondsLeft + " and progress is " + progress + " (gracePeriodSeconds is " + gracePeriodSeconds + ")");
// 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
}
}).start();
}
return super.onStartCommand(intent, flags, startId); return super.onStartCommand(intent, flags, startId);
} }
} }

View File

@ -7,8 +7,10 @@ import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Build;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import android.view.WindowManager;
import java.util.Calendar; import java.util.Calendar;
@ -34,7 +36,11 @@ public class AlarmReceiver extends BroadcastReceiver {
Intent graceIntent = new Intent(context, GraceReceiver.class); Intent graceIntent = new Intent(context, GraceReceiver.class);
gracePendingIntent = PendingIntent.getBroadcast(context, MainActivity.GRACE_REQUEST, graceIntent, 0); gracePendingIntent = PendingIntent.getBroadcast(context, MainActivity.GRACE_REQUEST, graceIntent, 0);
graceManager.cancel(gracePendingIntent); graceManager.cancel(gracePendingIntent);
graceManager.setExact(AlarmManager.RTC_WAKEUP, graceCal.getTimeInMillis(), gracePendingIntent); if (Build.VERSION.SDK_INT >= 19) {
graceManager.setExact(AlarmManager.RTC_WAKEUP, graceCal.getTimeInMillis(), gracePendingIntent);
} else {
graceManager.set(AlarmManager.RTC_WAKEUP, graceCal.getTimeInMillis(), gracePendingIntent);
}
Log.d("AlarmReceiver", "Setting grace alarm for " + MainActivity.debugDate(graceCal)); Log.d("AlarmReceiver", "Setting grace alarm for " + MainActivity.debugDate(graceCal));
// Allow user to acknowledge alarm and cancel grace alarm // Allow user to acknowledge alarm and cancel grace alarm
@ -51,8 +57,11 @@ public class AlarmReceiver extends BroadcastReceiver {
alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmPendingIntent = PendingIntent.getBroadcast(context, MainActivity.ALARM_REQUEST, intent, 0); alarmPendingIntent = PendingIntent.getBroadcast(context, MainActivity.ALARM_REQUEST, intent, 0);
alarmManager.cancel(alarmPendingIntent); alarmManager.cancel(alarmPendingIntent);
// TODO use set() for older APIs if (Build.VERSION.SDK_INT >= 19) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), alarmPendingIntent); alarmManager.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), alarmPendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), alarmPendingIntent);
}
Log.d("AlarmReceiver", "Resetting alarm for " + MainActivity.debugDate(cal)); Log.d("AlarmReceiver", "Resetting alarm for " + MainActivity.debugDate(cal));
} }
} }

View File

@ -13,6 +13,7 @@ import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.database.Cursor; import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.provider.ContactsContract; import android.provider.ContactsContract;
@ -308,8 +309,11 @@ public class MainActivity extends ActionBarActivity {
// Cancel any existing alarms // Cancel any existing alarms
alarmManager.cancel(alarmPendingIntent); alarmManager.cancel(alarmPendingIntent);
// Set or reset alarm // Set or reset alarm
// TODO use set() for older APIs if (Build.VERSION.SDK_INT >= 19) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), alarmPendingIntent); alarmManager.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), alarmPendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), alarmPendingIntent);
}
Log.d("MainActivity", "Setting alarm for " + MainActivity.debugDate(cal)); Log.d("MainActivity", "Setting alarm for " + MainActivity.debugDate(cal));
// Set boot receiver, so alarm restarts on boot // Set boot receiver, so alarm restarts on boot