From d8e56147d2b000d460a26ad61a1cc0168d7bcb42 Mon Sep 17 00:00:00 2001 From: Christophe Beyls Date: Fri, 10 Feb 2017 16:52:34 +0100 Subject: [PATCH] - Disable the AlarmReceiver on boot when not necessary to speed up the boot process - Properly cancel alarms rescheduled in the past after a DB update. --- .../fragments/BookmarksListFragment.java | 2 +- .../fosdem/receivers/AlarmReceiver.java | 19 +++++----- .../fosdem/services/AlarmIntentService.java | 36 +++++++++++++------ 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/be/digitalia/fosdem/fragments/BookmarksListFragment.java b/app/src/main/java/be/digitalia/fosdem/fragments/BookmarksListFragment.java index be3021d..41996da 100644 --- a/app/src/main/java/be/digitalia/fosdem/fragments/BookmarksListFragment.java +++ b/app/src/main/java/be/digitalia/fosdem/fragments/BookmarksListFragment.java @@ -180,7 +180,7 @@ public class BookmarksListFragment extends RecyclerViewFragment implements Loade @Override protected Cursor getCursor() { - return DatabaseManager.getInstance().getBookmarks(upcomingOnly ? System.currentTimeMillis() - TIME_OFFSET : -1L); + return DatabaseManager.getInstance().getBookmarks(upcomingOnly ? System.currentTimeMillis() - TIME_OFFSET : 0L); } } diff --git a/app/src/main/java/be/digitalia/fosdem/receivers/AlarmReceiver.java b/app/src/main/java/be/digitalia/fosdem/receivers/AlarmReceiver.java index 340cb8c..8e08a6f 100644 --- a/app/src/main/java/be/digitalia/fosdem/receivers/AlarmReceiver.java +++ b/app/src/main/java/be/digitalia/fosdem/receivers/AlarmReceiver.java @@ -24,19 +24,20 @@ public class AlarmReceiver extends WakefulBroadcastReceiver { if (ACTION_NOTIFY_EVENT.equals(action)) { // Forward the intent to the AlarmIntentService for background processing of the notification - Intent serviceIntent = new Intent(context, AlarmIntentService.class); - serviceIntent.setAction(ACTION_NOTIFY_EVENT); - serviceIntent.setData(intent.getData()); + Intent serviceIntent = new Intent(context, AlarmIntentService.class) + .setAction(ACTION_NOTIFY_EVENT) + .setData(intent.getData()) + .putExtra(AlarmIntentService.EXTRA_WITH_WAKE_LOCK, true); startWakefulService(context, serviceIntent); } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) { - if (FosdemAlarmManager.getInstance().isEnabled()) { - Intent serviceIntent = new Intent(context, AlarmIntentService.class); - serviceIntent.setAction(AlarmIntentService.ACTION_UPDATE_ALARMS); - serviceIntent.putExtra(AlarmIntentService.EXTRA_WITH_WAKE_LOCK, true); - startWakefulService(context, serviceIntent); - } + String serviceAction = FosdemAlarmManager.getInstance().isEnabled() + ? AlarmIntentService.ACTION_UPDATE_ALARMS : AlarmIntentService.ACTION_DISABLE_ALARMS; + Intent serviceIntent = new Intent(context, AlarmIntentService.class) + .setAction(serviceAction) + .putExtra(AlarmIntentService.EXTRA_WITH_WAKE_LOCK, true); + startWakefulService(context, serviceIntent); } } diff --git a/app/src/main/java/be/digitalia/fosdem/services/AlarmIntentService.java b/app/src/main/java/be/digitalia/fosdem/services/AlarmIntentService.java index 9eb50ca..21e6aa0 100644 --- a/app/src/main/java/be/digitalia/fosdem/services/AlarmIntentService.java +++ b/app/src/main/java/be/digitalia/fosdem/services/AlarmIntentService.java @@ -4,9 +4,11 @@ import android.app.AlarmManager; import android.app.IntentService; import android.app.Notification; import android.app.PendingIntent; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.database.Cursor; import android.graphics.Typeface; import android.net.Uri; @@ -74,29 +76,28 @@ public class AlarmIntentService extends IntentService { case ACTION_UPDATE_ALARMS: { // Create/update all alarms - long delay = getDelay(); - long now = System.currentTimeMillis(); - Cursor cursor = DatabaseManager.getInstance().getBookmarks(now); + final long delay = getDelay(); + final long now = System.currentTimeMillis(); + boolean hasAlarms = false; + Cursor cursor = DatabaseManager.getInstance().getBookmarks(0L); try { while (cursor.moveToNext()) { long eventId = DatabaseManager.toEventId(cursor); long notificationTime = DatabaseManager.toEventStartTimeMillis(cursor) - delay; PendingIntent pi = getAlarmPendingIntent(eventId); if (notificationTime < now) { - // Cancel pending alarms that where scheduled between now and delay, if any + // Cancel pending alarms that are now scheduled in the past, if any alarmManager.cancel(pi); } else { setExactAlarm(alarmManager, AlarmManager.RTC_WAKEUP, notificationTime, pi); + hasAlarms = true; } } + } finally { cursor.close(); } - - // Release the wake lock setup by AlarmReceiver, if any - if (intent.getBooleanExtra(EXTRA_WITH_WAKE_LOCK, false)) { - AlarmReceiver.completeWakefulIntent(intent); - } + setAlarmReceiverEnabled(hasAlarms); break; } @@ -112,6 +113,7 @@ public class AlarmIntentService extends IntentService { } finally { cursor.close(); } + setAlarmReceiverEnabled(false); break; } @@ -124,6 +126,7 @@ public class AlarmIntentService extends IntentService { if ((startTime == -1L) || (startTime < System.currentTimeMillis())) { break; } + setAlarmReceiverEnabled(true); setExactAlarm(alarmManager, AlarmManager.RTC_WAKEUP, startTime - delay, getAlarmPendingIntent(eventId)); break; @@ -228,10 +231,14 @@ public class AlarmIntentService extends IntentService { NotificationManagerCompat.from(this).notify((int) eventId, notificationBuilder.build()); } - AlarmReceiver.completeWakefulIntent(intent); break; } } + + // Release the wake lock setup by AlarmReceiver, if any + if (intent.getBooleanExtra(EXTRA_WITH_WAKE_LOCK, false)) { + AlarmReceiver.completeWakefulIntent(intent); + } } private static void setExactAlarm(AlarmManager manager, int type, long triggerAtMillis, PendingIntent operation) { @@ -248,4 +255,13 @@ public class AlarmIntentService extends IntentService { // Convert from minutes to milliseconds return Long.parseLong(delayString) * DateUtils.MINUTE_IN_MILLIS; } + + /** + * Allows disabling the Alarm Receiver so the app is not loaded at boot when it's not necessary. + */ + private void setAlarmReceiverEnabled(boolean isEnabled) { + ComponentName componentName = new ComponentName(this, AlarmReceiver.class); + int flag = isEnabled ? PackageManager.COMPONENT_ENABLED_STATE_DEFAULT : PackageManager.COMPONENT_ENABLED_STATE_DISABLED; + getPackageManager().setComponentEnabledSetting(componentName, flag, PackageManager.DONT_KILL_APP); + } }