diff options
author | ByteHamster <info@bytehamster.com> | 2019-05-06 23:04:19 +0200 |
---|---|---|
committer | ByteHamster <info@bytehamster.com> | 2019-05-06 23:04:19 +0200 |
commit | dbda4a9aa8efde99dafe82be980ca47413bbb50e (patch) | |
tree | 13083a70e6688f0b3035e573ae66e2cbbfd8977c /core | |
parent | d7768d33e2bf8bfee9bb36979dd5603e3060ec64 (diff) | |
download | AntennaPod-dbda4a9aa8efde99dafe82be980ca47413bbb50e.zip |
Using WorkManager for feed updates
Diffstat (limited to 'core')
8 files changed, 89 insertions, 240 deletions
diff --git a/core/build.gradle b/core/build.gradle index 65dfa1a7b..6f08253b4 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -45,6 +45,8 @@ dependencies { implementation "com.android.support:appcompat-v7:$supportVersion" implementation "com.android.support:preference-v14:$supportVersion" implementation "com.android.support:percent:$supportVersion" + implementation "android.arch.work:work-runtime:$workManagerVersion" + implementation "org.apache.commons:commons-lang3:$commonslangVersion" implementation "org.apache.commons:commons-text:$commonstextVersion" implementation ("org.shredzone.flattr4j:flattr4j-core:$flattr4jVersion") { diff --git a/core/src/main/AndroidManifest.xml b/core/src/main/AndroidManifest.xml index 1146f2a87..3b6edae42 100644 --- a/core/src/main/AndroidManifest.xml +++ b/core/src/main/AndroidManifest.xml @@ -41,29 +41,10 @@ </intent-filter> </receiver> - <receiver android:name=".receiver.AlarmUpdateReceiver"> - <intent-filter> - <action android:name="android.intent.action.BOOT_COMPLETED" /> - </intent-filter> - <intent-filter> - <action android:name="android.intent.action.PACKAGE_REPLACED" /> - <data - android:path="de.danoeh.antennapod" - android:scheme="package" /> - </intent-filter> - </receiver> - <receiver android:name=".receiver.FeedUpdateReceiver" android:label="@string/feed_update_receiver_name" android:exported="true"> <!-- allow feeds update to be triggered by external apps --> </receiver> - - <service - android:name=".service.FeedUpdateJobService" - android:permission="android.permission.BIND_JOB_SERVICE" > - - </service> - </application> </manifest> diff --git a/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java b/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java index 805f0c1b6..7b625d883 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java +++ b/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java @@ -561,7 +561,7 @@ public class UserPreferences { .apply(); // when updating with an interval, we assume the user wants // to update *now* and then every 'hours' interval thereafter. - restartUpdateAlarm(true); + restartUpdateAlarm(); } /** @@ -571,7 +571,7 @@ public class UserPreferences { prefs.edit() .putString(PREF_UPDATE_INTERVAL, hourOfDay + ":" + minute) .apply(); - restartUpdateAlarm(false); + restartUpdateAlarm(); } /** @@ -814,18 +814,23 @@ public class UserPreferences { } } - public static void restartUpdateAlarm(boolean now) { - int[] timeOfDay = getUpdateTimeOfDay(); - Log.d(TAG, "timeOfDay: " + Arrays.toString(timeOfDay)); - if (timeOfDay.length == 2) { - AutoUpdateManager.restartUpdateTimeOfDayAlarm(context, timeOfDay[0], timeOfDay[1]); + /** + * + * @return true if auto update is set to a specific time + * false if auto update is set to interval + */ + public static boolean isAutoUpdateTimeOfDay() { + return getUpdateTimeOfDay().length == 2; + } + + public static void restartUpdateAlarm() { + if (isAutoUpdateTimeOfDay()) { + int[] timeOfDay = getUpdateTimeOfDay(); + Log.d(TAG, "timeOfDay: " + Arrays.toString(timeOfDay)); + AutoUpdateManager.restartUpdateTimeOfDayAlarm(timeOfDay[0], timeOfDay[1]); } else { long milliseconds = getUpdateInterval(); - long startTrigger = milliseconds; - if (now) { - startTrigger = TimeUnit.SECONDS.toMillis(10); - } - AutoUpdateManager.restartUpdateIntervalAlarm(context, startTrigger, milliseconds); + AutoUpdateManager.restartUpdateIntervalAlarm(milliseconds); } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/receiver/AlarmUpdateReceiver.java b/core/src/main/java/de/danoeh/antennapod/core/receiver/AlarmUpdateReceiver.java deleted file mode 100644 index 33c15883b..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/receiver/AlarmUpdateReceiver.java +++ /dev/null @@ -1,29 +0,0 @@ -package de.danoeh.antennapod.core.receiver; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.text.TextUtils; -import android.util.Log; - -import de.danoeh.antennapod.core.ClientConfig; -import de.danoeh.antennapod.core.preferences.UserPreferences; - -/** Listens for events that make it necessary to reset the update alarm. */ -public class AlarmUpdateReceiver extends BroadcastReceiver { - - private static final String TAG = "AlarmUpdateReceiver"; - - @Override - public void onReceive(Context context, Intent intent) { - Log.d(TAG, "Received intent"); - if (TextUtils.equals(intent.getAction(), Intent.ACTION_BOOT_COMPLETED)) { - Log.d(TAG, "Resetting update alarm after reboot"); - } else if (TextUtils.equals(intent.getAction(), Intent.ACTION_PACKAGE_REPLACED)) { - Log.d(TAG, "Resetting update alarm after app upgrade"); - } - ClientConfig.initialize(context); - UserPreferences.restartUpdateAlarm(false); - } - -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/receiver/FeedUpdateReceiver.java b/core/src/main/java/de/danoeh/antennapod/core/receiver/FeedUpdateReceiver.java index 05e12f6df..126f12247 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/receiver/FeedUpdateReceiver.java +++ b/core/src/main/java/de/danoeh/antennapod/core/receiver/FeedUpdateReceiver.java @@ -21,7 +21,6 @@ public class FeedUpdateReceiver extends BroadcastReceiver { Log.d(TAG, "Received intent"); ClientConfig.initialize(context); FeedUpdateUtils.startAutoUpdate(context, null); - UserPreferences.restartUpdateAlarm(false); } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateJobService.java b/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateJobService.java deleted file mode 100644 index 7d80d4e7c..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateJobService.java +++ /dev/null @@ -1,35 +0,0 @@ -package de.danoeh.antennapod.core.service; - -import android.app.job.JobParameters; -import android.app.job.JobService; -import android.os.Build; -import android.support.annotation.RequiresApi; -import android.util.Log; - -import de.danoeh.antennapod.core.ClientConfig; -import de.danoeh.antennapod.core.preferences.UserPreferences; -import de.danoeh.antennapod.core.util.FeedUpdateUtils; - -@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) -public class FeedUpdateJobService extends JobService { - private static final String TAG = "FeedUpdateJobService"; - - @Override - public boolean onStartJob(JobParameters params) { - Log.d(TAG, "Job started"); - ClientConfig.initialize(getApplicationContext()); - - FeedUpdateUtils.startAutoUpdate(getApplicationContext(), () -> { - UserPreferences.restartUpdateAlarm(false); - jobFinished(params, false); // needsReschedule = false - }); - - return true; - } - - @Override - public boolean onStopJob(JobParameters params) { - return true; - } - -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateWorker.java b/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateWorker.java new file mode 100644 index 000000000..efdb96dc1 --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateWorker.java @@ -0,0 +1,37 @@ +package de.danoeh.antennapod.core.service; + +import android.content.Context; +import android.support.annotation.NonNull; +import androidx.work.Worker; +import androidx.work.WorkerParameters; +import de.danoeh.antennapod.core.ClientConfig; +import de.danoeh.antennapod.core.preferences.UserPreferences; +import de.danoeh.antennapod.core.util.FeedUpdateUtils; +import org.awaitility.Awaitility; + +import java.util.concurrent.atomic.AtomicBoolean; + +public class FeedUpdateWorker extends Worker { + + public FeedUpdateWorker(@NonNull Context context, @NonNull WorkerParameters params) { + super(context, params); + } + + @Override + @NonNull + public Result doWork() { + ClientConfig.initialize(getApplicationContext()); + + AtomicBoolean finished = new AtomicBoolean(false); + FeedUpdateUtils.startAutoUpdate(getApplicationContext(), () -> finished.set(true)); + Awaitility.await().until(finished::get); + + if (UserPreferences.isAutoUpdateTimeOfDay()) { + // WorkManager does not allow to set specific time for repeated tasks. + // We repeatedly schedule a OneTimeWorkRequest instead. + UserPreferences.restartUpdateAlarm(); + } + + return Result.success(); + } +} diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/download/AutoUpdateManager.java b/core/src/main/java/de/danoeh/antennapod/core/util/download/AutoUpdateManager.java index 1629f4aaf..d3f25825f 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/download/AutoUpdateManager.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/download/AutoUpdateManager.java @@ -1,29 +1,21 @@ package de.danoeh.antennapod.core.util.download; -import android.app.AlarmManager; -import android.app.PendingIntent; -import android.app.job.JobInfo; -import android.app.job.JobScheduler; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.os.Build; -import android.os.SystemClock; -import android.support.annotation.RequiresApi; import android.util.Log; +import androidx.work.Constraints; +import androidx.work.ExistingPeriodicWorkPolicy; +import androidx.work.ExistingWorkPolicy; +import androidx.work.NetworkType; +import androidx.work.OneTimeWorkRequest; +import androidx.work.PeriodicWorkRequest; +import androidx.work.WorkManager; +import de.danoeh.antennapod.core.preferences.UserPreferences; +import de.danoeh.antennapod.core.service.FeedUpdateWorker; import java.util.Calendar; import java.util.concurrent.TimeUnit; -import de.danoeh.antennapod.core.preferences.UserPreferences; -import de.danoeh.antennapod.core.receiver.FeedUpdateReceiver; -import de.danoeh.antennapod.core.service.FeedUpdateJobService; -import de.danoeh.antennapod.core.storage.DBTasks; -import de.danoeh.antennapod.core.util.Converter; -import de.danoeh.antennapod.core.util.FeedUpdateUtils; - public class AutoUpdateManager { - private static final int JOB_ID_FEED_UPDATE = 42; + private static final String WORK_ID_FEED_UPDATE = FeedUpdateWorker.class.getName(); private static final String TAG = "AutoUpdateManager"; private AutoUpdateManager() { @@ -33,20 +25,22 @@ public class AutoUpdateManager { /** * Sets the interval in which the feeds are refreshed automatically */ - public static void restartUpdateIntervalAlarm(Context context, long triggerAtMillis, long intervalMillis) { + public static void restartUpdateIntervalAlarm(long intervalMillis) { Log.d(TAG, "Restarting update alarm."); - if (Build.VERSION.SDK_INT >= 24) { - restartJobServiceInterval(context, intervalMillis); - } else { - restartAlarmManagerInterval(context, triggerAtMillis, intervalMillis); - } + PeriodicWorkRequest workRequest = new PeriodicWorkRequest.Builder(FeedUpdateWorker.class, + intervalMillis, TimeUnit.MILLISECONDS) + .setConstraints(getConstraints()) + .build(); + + WorkManager.getInstance().enqueueUniquePeriodicWork( + WORK_ID_FEED_UPDATE, ExistingPeriodicWorkPolicy.REPLACE, workRequest); } /** * Sets time of day the feeds are refreshed automatically */ - public static void restartUpdateTimeOfDayAlarm(Context context, int hoursOfDay, int minute) { + public static void restartUpdateTimeOfDayAlarm(int hoursOfDay, int minute) { Log.d(TAG, "Restarting update alarm."); Calendar now = Calendar.getInstance(); @@ -56,130 +50,25 @@ public class AutoUpdateManager { if (alarm.before(now) || alarm.equals(now)) { alarm.add(Calendar.DATE, 1); } + long triggerAtMillis = alarm.getTimeInMillis() - now.getTimeInMillis(); - if (Build.VERSION.SDK_INT >= 24) { - long triggerAtMillis = alarm.getTimeInMillis() - now.getTimeInMillis(); - restartJobServiceTriggerAt(context, triggerAtMillis); - } else { - restartAlarmManagerTimeOfDay(context, alarm); - } - } - - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) - private static JobInfo.Builder getFeedUpdateJobBuilder(Context context) { - ComponentName serviceComponent = new ComponentName(context, FeedUpdateJobService.class); - JobInfo.Builder builder = new JobInfo.Builder(JOB_ID_FEED_UPDATE, serviceComponent); - builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); - builder.setPersisted(true); - return builder; - } - - @RequiresApi(api = Build.VERSION_CODES.N) - private static void restartJobServiceInterval(Context context, long intervalMillis) { - JobScheduler jobScheduler = context.getSystemService(JobScheduler.class); - if (jobScheduler == null) { - Log.d(TAG, "JobScheduler was null."); - return; - } - - JobInfo oldJob = jobScheduler.getPendingJob(JOB_ID_FEED_UPDATE); - if (oldJob != null && oldJob.getIntervalMillis() == intervalMillis) { - Log.d(TAG, "JobScheduler was already set at interval " + intervalMillis + ", ignoring."); - return; - } - - JobInfo.Builder builder = getFeedUpdateJobBuilder(context); - builder.setPeriodic(intervalMillis); - jobScheduler.cancel(JOB_ID_FEED_UPDATE); - - if (intervalMillis <= 0) { - Log.d(TAG, "Automatic update was deactivated"); - return; - } + OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(FeedUpdateWorker.class) + .setConstraints(getConstraints()) + .setInitialDelay(triggerAtMillis, TimeUnit.MILLISECONDS) + .build(); - jobScheduler.schedule(builder.build()); - Log.d(TAG, "JobScheduler was set at interval " + intervalMillis); + WorkManager.getInstance().enqueueUniqueWork(WORK_ID_FEED_UPDATE, ExistingWorkPolicy.REPLACE, workRequest); } - private static void restartAlarmManagerInterval(Context context, long triggerAtMillis, long intervalMillis) { - AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - - if (alarmManager == null) { - Log.d(TAG, "AlarmManager was null"); - return; - } + private static Constraints getConstraints() { + Constraints.Builder constraints = new Constraints.Builder(); - PendingIntent updateIntent = PendingIntent.getBroadcast(context, 0, - new Intent(context, FeedUpdateReceiver.class), 0); - alarmManager.cancel(updateIntent); - - if (intervalMillis <= 0) { - Log.d(TAG, "Automatic update was deactivated"); - return; - } - - alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, - SystemClock.elapsedRealtime() + triggerAtMillis, - updateIntent); - Log.d(TAG, "Changed alarm to new interval " + TimeUnit.MILLISECONDS.toHours(intervalMillis) + " h"); - } - - @RequiresApi(api = Build.VERSION_CODES.N) - private static void restartJobServiceTriggerAt(Context context, long triggerAtMillis) { - JobScheduler jobScheduler = context.getSystemService(JobScheduler.class); - if (jobScheduler == null) { - Log.d(TAG, "JobScheduler was null."); - return; - } - - JobInfo.Builder builder = getFeedUpdateJobBuilder(context); - builder.setMinimumLatency(triggerAtMillis); - jobScheduler.cancel(JOB_ID_FEED_UPDATE); - jobScheduler.schedule(builder.build()); - Log.d(TAG, "JobScheduler was set for " + triggerAtMillis); - } - - private static void restartAlarmManagerTimeOfDay(Context context, Calendar alarm) { - AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - - if (alarmManager == null) { - Log.d(TAG, "AlarmManager was null"); - return; - } - - PendingIntent updateIntent = PendingIntent.getBroadcast(context, 0, - new Intent(context, FeedUpdateReceiver.class), 0); - alarmManager.cancel(updateIntent); - - Log.d(TAG, "Alarm set for: " + alarm.toString() + " : " + alarm.getTimeInMillis()); - alarmManager.set(AlarmManager.RTC_WAKEUP, - alarm.getTimeInMillis(), - updateIntent); - Log.d(TAG, "Changed alarm to new time of day " + alarm.get(Calendar.HOUR_OF_DAY) + ":" + alarm.get(Calendar.MINUTE)); - } - - /* - * Checks if the app should refresh all feeds, i.e. if the last auto refresh failed. - * - * The feeds are only refreshed if an update interval or time of day is set and the last - * (successful) refresh was before the last interval or more than a day ago, respectively. - * - */ - public static void checkShouldRefreshFeeds(Context context) { - long interval = 0; - if(UserPreferences.getUpdateInterval() > 0) { - interval = UserPreferences.getUpdateInterval(); - } else if(UserPreferences.getUpdateTimeOfDay().length > 0){ - interval = TimeUnit.DAYS.toMillis(1); - } - if(interval == 0) { // auto refresh is disabled - return; - } - long lastRefresh = DBTasks.getLastRefreshAllFeedsTimeMillis(context); - Log.d(TAG, "last refresh: " + Converter.getDurationStringLocalized(context, - System.currentTimeMillis() - lastRefresh) + " ago"); - if(lastRefresh <= System.currentTimeMillis() - interval) { - FeedUpdateUtils.startAutoUpdate(context, null); + if (UserPreferences.isAllowMobileUpdate()) { + constraints.setRequiredNetworkType(NetworkType.CONNECTED); + } else { + constraints.setRequiredNetworkType(NetworkType.UNMETERED); } + constraints.setRequiresCharging(!UserPreferences.isEnableAutodownloadOnBattery()); + return constraints.build(); } } |