diff options
Diffstat (limited to 'core')
135 files changed, 394 insertions, 503 deletions
diff --git a/core/build.gradle b/core/build.gradle index 133f1b262..8614d5589 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -76,7 +76,6 @@ dependencies { annotationProcessor "org.greenrobot:eventbus-annotation-processor:$eventbusVersion" implementation "io.reactivex.rxjava2:rxandroid:$rxAndroidVersion" implementation "io.reactivex.rxjava2:rxjava:$rxJavaVersion" - implementation "org.awaitility:awaitility:$awaitilityVersion" implementation "com.google.android.exoplayer:exoplayer:$exoPlayerVersion" implementation "com.github.AntennaPod:AntennaPod-AudioPlayer:$audioPlayerVersion" @@ -92,6 +91,7 @@ dependencies { System.out.println("core: free build hack, skipping some dependencies") } + testImplementation "org.awaitility:awaitility:$awaitilityVersion" testImplementation 'junit:junit:4.12' testImplementation 'org.mockito:mockito-core:1.10.19' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' diff --git a/core/src/main/java/de/danoeh/antennapod/core/event/DownloadEvent.java b/core/src/main/java/de/danoeh/antennapod/core/event/DownloadEvent.java index 124fd3e64..24a71ec96 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/event/DownloadEvent.java +++ b/core/src/main/java/de/danoeh/antennapod/core/event/DownloadEvent.java @@ -25,4 +25,8 @@ public class DownloadEvent { "update=" + update + '}'; } + + public boolean hasChangedFeedUpdateStatus(boolean oldStatus) { + return oldStatus != update.feedIds.length > 0; + } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/event/FeedMediaEvent.java b/core/src/main/java/de/danoeh/antennapod/core/event/FeedMediaEvent.java deleted file mode 100644 index 4a591c996..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/event/FeedMediaEvent.java +++ /dev/null @@ -1,23 +0,0 @@ -package de.danoeh.antennapod.core.event; - -import de.danoeh.antennapod.core.feed.FeedMedia; - -public class FeedMediaEvent { - - public enum Action { - UPDATE - } - - private final Action action; - private final FeedMedia media; - - private FeedMediaEvent(Action action, FeedMedia media) { - this.action = action; - this.media = media; - } - - public static FeedMediaEvent update(FeedMedia media) { - return new FeedMediaEvent(Action.UPDATE, media); - } - -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/glide/ApOkHttpUrlLoader.java b/core/src/main/java/de/danoeh/antennapod/core/glide/ApOkHttpUrlLoader.java index b75e1630c..bb34e2c0f 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/glide/ApOkHttpUrlLoader.java +++ b/core/src/main/java/de/danoeh/antennapod/core/glide/ApOkHttpUrlLoader.java @@ -21,8 +21,12 @@ import de.danoeh.antennapod.core.service.download.AntennapodHttpClient; import de.danoeh.antennapod.core.service.download.HttpDownloader; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.util.NetworkUtils; -import okhttp3.*; -import okhttp3.internal.http.RealResponseBody; +import okhttp3.Interceptor; +import okhttp3.OkHttpClient; +import okhttp3.Protocol; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.ResponseBody; /** * @see com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader 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 b8ab1c888..787e32ccc 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 @@ -2,6 +2,7 @@ package de.danoeh.antennapod.core.preferences; import android.content.Context; import android.content.SharedPreferences; +import android.content.res.Configuration; import android.preference.PreferenceManager; import android.support.annotation.IntRange; import android.support.annotation.NonNull; @@ -164,7 +165,7 @@ public class UserPreferences { * @return R.style.Theme_AntennaPod_Light or R.style.Theme_AntennaPod_Dark */ public static int getTheme() { - return readThemeValue(prefs.getString(PREF_THEME, "0")); + return readThemeValue(prefs.getString(PREF_THEME, "system")); } public static int getNoTitleTheme() { @@ -621,7 +622,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(); + AutoUpdateManager.restartUpdateAlarm(); } /** @@ -631,7 +632,7 @@ public class UserPreferences { prefs.edit() .putString(PREF_UPDATE_INTERVAL, hourOfDay + ":" + minute) .apply(); - restartUpdateAlarm(); + AutoUpdateManager.restartUpdateAlarm(); } public static void disableAutoUpdate() { @@ -672,14 +673,18 @@ public class UserPreferences { } private static int readThemeValue(String valueFromPrefs) { - switch (Integer.parseInt(valueFromPrefs)) { - case 0: + switch (valueFromPrefs) { + case "0": return R.style.Theme_AntennaPod_Light; - case 1: + case "1": return R.style.Theme_AntennaPod_Dark; - case 2: + case "2": return R.style.Theme_AntennaPod_TrueBlack; default: + int nightMode = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; + if (nightMode == Configuration.UI_MODE_NIGHT_YES) { + return R.style.Theme_AntennaPod_Dark; + } return R.style.Theme_AntennaPod_Light; } } @@ -877,26 +882,6 @@ public class UserPreferences { return getUpdateTimeOfDay().length == 2; } - public static void restartUpdateAlarm() { - if (isAutoUpdateDisabled()) { - AutoUpdateManager.disableAutoUpdate(); - } else if (isAutoUpdateTimeOfDay()) { - int[] timeOfDay = getUpdateTimeOfDay(); - Log.d(TAG, "timeOfDay: " + Arrays.toString(timeOfDay)); - AutoUpdateManager.restartUpdateTimeOfDayAlarm(timeOfDay[0], timeOfDay[1]); - } else { - long milliseconds = getUpdateInterval(); - AutoUpdateManager.restartUpdateIntervalAlarm(milliseconds); - } - } - - /** - * Reads episode cache size as it is saved in the episode_cache_size_values array. - */ - public static int readEpisodeCacheSize(String valueFromPrefs) { - return readEpisodeCacheSizeInternal(valueFromPrefs); - } - /** * Evaluates whether Cast support (Chromecast, Audio Cast, etc) is enabled on the preferences. */ 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 126f12247..af0a0d426 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 @@ -6,8 +6,7 @@ import android.content.Intent; import android.util.Log; import de.danoeh.antennapod.core.ClientConfig; -import de.danoeh.antennapod.core.preferences.UserPreferences; -import de.danoeh.antennapod.core.util.FeedUpdateUtils; +import de.danoeh.antennapod.core.util.download.AutoUpdateManager; /** * Refreshes all feeds when it receives an intent @@ -20,7 +19,8 @@ public class FeedUpdateReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { Log.d(TAG, "Received intent"); ClientConfig.initialize(context); - FeedUpdateUtils.startAutoUpdate(context, null); + + AutoUpdateManager.runOnce(); } } 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 index efdb96dc1..87c18227b 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateWorker.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateWorker.java @@ -2,17 +2,23 @@ package de.danoeh.antennapod.core.service; import android.content.Context; import android.support.annotation.NonNull; +import android.util.Log; + 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; +import de.danoeh.antennapod.core.storage.DBTasks; +import de.danoeh.antennapod.core.util.NetworkUtils; +import de.danoeh.antennapod.core.util.download.AutoUpdateManager; public class FeedUpdateWorker extends Worker { + private static final String TAG = "FeedUpdateWorker"; + + public static final String PARAM_RUN_ONCE = "runOnce"; + public FeedUpdateWorker(@NonNull Context context, @NonNull WorkerParameters params) { super(context, params); } @@ -20,16 +26,20 @@ public class FeedUpdateWorker extends Worker { @Override @NonNull public Result doWork() { + final boolean isRunOnce = getInputData().getBoolean(PARAM_RUN_ONCE, false); + Log.d(TAG, "doWork() : isRunOnce = " + isRunOnce); ClientConfig.initialize(getApplicationContext()); - AtomicBoolean finished = new AtomicBoolean(false); - FeedUpdateUtils.startAutoUpdate(getApplicationContext(), () -> finished.set(true)); - Awaitility.await().until(finished::get); + if (NetworkUtils.networkAvailable() && NetworkUtils.isFeedRefreshAllowed()) { + DBTasks.refreshAllFeeds(getApplicationContext()); + } else { + Log.d(TAG, "Blocking automatic update: no wifi available / no mobile updates allowed"); + } - if (UserPreferences.isAutoUpdateTimeOfDay()) { + if (!isRunOnce && UserPreferences.isAutoUpdateTimeOfDay()) { // WorkManager does not allow to set specific time for repeated tasks. // We repeatedly schedule a OneTimeWorkRequest instead. - UserPreferences.restartUpdateAlarm(); + AutoUpdateManager.restartUpdateAlarm(); } return Result.success(); diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/AntennapodHttpClient.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/AntennapodHttpClient.java index 97007a214..04a6d5882 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/AntennapodHttpClient.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/AntennapodHttpClient.java @@ -16,7 +16,9 @@ import java.net.Socket; import java.net.SocketAddress; import java.security.GeneralSecurityException; import java.security.KeyStore; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import java.util.concurrent.TimeUnit; import javax.net.ssl.SSLContext; @@ -28,6 +30,8 @@ import javax.net.ssl.X509TrustManager; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.storage.DBWriter; +import okhttp3.CipherSuite; +import okhttp3.ConnectionSpec; import okhttp3.Credentials; import okhttp3.HttpUrl; import okhttp3.JavaNetCookieJar; @@ -138,9 +142,24 @@ public class AntennapodHttpClient { }); } } - if(16 <= Build.VERSION.SDK_INT && Build.VERSION.SDK_INT < 21) { + if (16 <= Build.VERSION.SDK_INT && Build.VERSION.SDK_INT < 21) { builder.sslSocketFactory(new CustomSslSocketFactory(), trustManager()); } + + if (Build.VERSION.SDK_INT < 21) { + // workaround for Android 4.x for certain web sites. + // see: https://github.com/square/okhttp/issues/4053#issuecomment-402579554 + List<CipherSuite> cipherSuites = new ArrayList<>(); + cipherSuites.addAll(ConnectionSpec.MODERN_TLS.cipherSuites()); + cipherSuites.add(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA); + cipherSuites.add(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA); + + ConnectionSpec legacyTls = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) + .cipherSuites(cipherSuites.toArray(new CipherSuite[0])) + .build(); + builder.connectionSpecs(Arrays.asList(legacyTls, ConnectionSpec.CLEARTEXT)); + } + return builder; } diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java index 787d465d8..ce61bff68 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java @@ -13,6 +13,7 @@ import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.v4.app.NotificationCompat; import android.text.TextUtils; import android.util.Log; @@ -190,10 +191,8 @@ public class DownloadService extends Service { handleFailedDownload(status, downloader.getDownloadRequest()); if (type == FeedMedia.FEEDFILETYPE_FEEDMEDIA) { - long id = status.getFeedfileId(); - FeedMedia media = DBReader.getFeedMedia(id); - FeedItem item; - if (media == null || (item = media.getItem()) == null) { + FeedItem item = getFeedItemFromId(status.getFeedfileId()); + if (item == null) { return; } boolean httpNotFound = status.getReason() == DownloadError.ERROR_HTTP_DATA_ERROR @@ -213,9 +212,8 @@ public class DownloadService extends Service { // if FeedMedia download has been canceled, fake FeedItem update // so that lists reload that it if (status.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) { - FeedMedia media = DBReader.getFeedMedia(status.getFeedfileId()); - FeedItem item; - if (media == null || (item = media.getItem()) == null) { + FeedItem item = getFeedItemFromId(status.getFeedfileId()); + if (item == null) { return; } EventBus.getDefault().post(FeedItemEvent.updated(item)); @@ -386,6 +384,12 @@ public class DownloadService extends Service { Downloader d = getDownloader(url); if (d != null) { d.cancel(); + DownloadRequester.getInstance().removeDownload(d.getDownloadRequest()); + + FeedItem item = getFeedItemFromId(d.getDownloadRequest().getFeedfileId()); + if (item != null) { + EventBus.getDefault().post(FeedItemEvent.updated(item)); + } } else { Log.e(TAG, "Could not cancel download with url " + url); } @@ -546,7 +550,7 @@ public class DownloadService extends Service { .setContentText(getText(R.string.authentication_notification_msg)) .setStyle(new NotificationCompat.BigTextStyle().bigText(getText(R.string.authentication_notification_msg) + ": " + resourceTitle)) - .setSmallIcon(R.drawable.ic_stat_authentication) + .setSmallIcon(R.drawable.ic_notification_key) .setAutoCancel(true) .setContentIntent(ClientConfig.downloadServiceCallbacks.getAuthentificationNotificationContentIntent(DownloadService.this, downloadRequest)); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { @@ -578,6 +582,16 @@ public class DownloadService extends Service { syncExecutor.execute(new FailedDownloadHandler(status, request)); } + @Nullable + private FeedItem getFeedItemFromId(long id) { + FeedMedia media = DBReader.getFeedMedia(id); + if (media != null) { + return media.getItem(); + } else { + return null; + } + } + /** * Takes a single Feed, parses the corresponding file and refreshes * information in the manager @@ -1058,7 +1072,13 @@ public class DownloadService extends Service { private final Runnable postDownloaderTask = new Runnable() { @Override public void run() { - List<Downloader> list = Collections.unmodifiableList(downloads); + List<Downloader> runningDownloads = new ArrayList<>(); + for (Downloader downloader : downloads) { + if (!downloader.cancelled) { + runningDownloads.add(downloader); + } + } + List<Downloader> list = Collections.unmodifiableList(runningDownloads); EventBus.getDefault().postSticky(DownloadEvent.refresh(list)); postHandler.postDelayed(postDownloaderTask, 1500); } @@ -1076,7 +1096,10 @@ public class DownloadService extends Service { private static String compileNotificationString(List<Downloader> downloads) { List<String> lines = new ArrayList<>(downloads.size()); for (Downloader downloader : downloads) { - StringBuilder line = new StringBuilder("\u2022 "); + if (downloader.cancelled) { + continue; + } + StringBuilder line = new StringBuilder("• "); DownloadRequest request = downloader.getDownloadRequest(); switch (request.getFeedfileType()) { case Feed.FEEDFILETYPE_FEED: diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadStatus.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadStatus.java index 5debc6d05..d88eb63f4 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadStatus.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadStatus.java @@ -193,10 +193,6 @@ public class DownloadStatus { this.cancelled = true; } - public void setCompletionDate(Date completionDate) { - this.completionDate = (Date) completionDate.clone(); - } - public void setId(long id) { this.id = id; } diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java index 0fc165183..c3b412012 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java @@ -26,26 +26,45 @@ import com.google.android.exoplayer2.upstream.DefaultHttpDataSource; import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory; import com.google.android.exoplayer2.util.Util; +import io.reactivex.Observable; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; import org.antennapod.audio.MediaPlayer; import de.danoeh.antennapod.core.util.playback.IPlayer; +import java.util.concurrent.TimeUnit; public class ExoPlayerWrapper implements IPlayer { private final Context mContext; + private final Disposable bufferingUpdateDisposable; private SimpleExoPlayer mExoPlayer; private MediaSource mediaSource; private MediaPlayer.OnSeekCompleteListener audioSeekCompleteListener; private MediaPlayer.OnCompletionListener audioCompletionListener; private MediaPlayer.OnErrorListener audioErrorListener; + private MediaPlayer.OnBufferingUpdateListener bufferingUpdateListener; + ExoPlayerWrapper(Context context) { mContext = context; mExoPlayer = createPlayer(); + + bufferingUpdateDisposable = Observable.interval(2, TimeUnit.SECONDS) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(aLong -> { + if (bufferingUpdateListener != null) { + bufferingUpdateListener.onBufferingUpdate(null, mExoPlayer.getBufferedPercentage()); + } + }); } private SimpleExoPlayer createPlayer() { + DefaultLoadControl.Builder loadControl = new DefaultLoadControl.Builder(); + loadControl.setBufferDurationsMs(30000, 120000, + DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS, + DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS); SimpleExoPlayer p = ExoPlayerFactory.newSimpleInstance(mContext, new DefaultRenderersFactory(mContext), - new DefaultTrackSelector(), new DefaultLoadControl()); + new DefaultTrackSelector(), loadControl.createDefaultLoadControl()); p.setSeekParameters(SeekParameters.PREVIOUS_SYNC); p.addListener(new Player.EventListener() { @Override @@ -150,12 +169,14 @@ public class ExoPlayerWrapper implements IPlayer { @Override public void release() { + bufferingUpdateDisposable.dispose(); if (mExoPlayer != null) { mExoPlayer.release(); } audioSeekCompleteListener = null; audioCompletionListener = null; audioErrorListener = null; + bufferingUpdateListener = null; } @Override @@ -253,4 +274,8 @@ public class ExoPlayerWrapper implements IPlayer { } return mExoPlayer.getVideoFormat().height; } + + void setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListener bufferingUpdateListener) { + this.bufferingUpdateListener = bufferingUpdateListener; + } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java index 5177fa6be..9164f561f 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java @@ -1025,6 +1025,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { ExoPlayerWrapper ap = (ExoPlayerWrapper) mp; ap.setOnCompletionListener(audioCompletionListener); ap.setOnSeekCompleteListener(audioSeekCompleteListener); + ap.setOnBufferingUpdateListener(audioBufferingUpdateListener); ap.setOnErrorListener(audioErrorListener); } else { Log.w(TAG, "Unknown media player: " + mp); diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java index 7d23b4c4c..a3535616e 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java @@ -1086,7 +1086,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { editor.putInt( PlaybackPreferences.PREF_CURRENT_PLAYER_STATUS, playerStatus); - editor.commit(); + editor.apply(); } private void writePlayerStatusPlaybackPreferences() { @@ -1095,11 +1095,8 @@ public class PlaybackService extends MediaBrowserServiceCompat { SharedPreferences.Editor editor = PreferenceManager .getDefaultSharedPreferences(getApplicationContext()).edit(); int playerStatus = getCurrentPlayerStatusAsInt(mediaPlayer.getPlayerStatus()); - - editor.putInt( - PlaybackPreferences.PREF_CURRENT_PLAYER_STATUS, playerStatus); - - editor.commit(); + editor.putInt(PlaybackPreferences.PREF_CURRENT_PLAYER_STATUS, playerStatus); + editor.apply(); } private void sendNotificationBroadcast(int type, int code) { diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceNotificationBuilder.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceNotificationBuilder.java index 0e7339ac4..1a13fe5a7 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceNotificationBuilder.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceNotificationBuilder.java @@ -115,7 +115,7 @@ public class PlaybackServiceNotificationBuilder extends NotificationCompat.Build stopCastingIntent.putExtra(PlaybackService.EXTRA_CAST_DISCONNECT, true); PendingIntent stopCastingPendingIntent = PendingIntent.getService(context, numActions, stopCastingIntent, PendingIntent.FLAG_UPDATE_CURRENT); - addAction(R.drawable.ic_media_cast_disconnect, + addAction(R.drawable.ic_notification_cast_off, context.getString(R.string.cast_disconnect_label), stopCastingPendingIntent); numActions++; @@ -124,7 +124,7 @@ public class PlaybackServiceNotificationBuilder extends NotificationCompat.Build // always let them rewind PendingIntent rewindButtonPendingIntent = getPendingIntentForMediaAction( KeyEvent.KEYCODE_MEDIA_REWIND, numActions); - addAction(android.R.drawable.ic_media_rew, context.getString(R.string.rewind_label), rewindButtonPendingIntent); + addAction(R.drawable.ic_notification_fast_rewind, context.getString(R.string.rewind_label), rewindButtonPendingIntent); if (UserPreferences.showRewindOnCompactNotification()) { compactActionList.add(numActions); } @@ -133,14 +133,14 @@ public class PlaybackServiceNotificationBuilder extends NotificationCompat.Build if (playerStatus == PlayerStatus.PLAYING) { PendingIntent pauseButtonPendingIntent = getPendingIntentForMediaAction( KeyEvent.KEYCODE_MEDIA_PAUSE, numActions); - addAction(android.R.drawable.ic_media_pause, //pause action + addAction(R.drawable.ic_notification_pause, //pause action context.getString(R.string.pause_label), pauseButtonPendingIntent); compactActionList.add(numActions++); } else { PendingIntent playButtonPendingIntent = getPendingIntentForMediaAction( KeyEvent.KEYCODE_MEDIA_PLAY, numActions); - addAction(android.R.drawable.ic_media_play, //play action + addAction(R.drawable.ic_notification_play, //play action context.getString(R.string.play_label), playButtonPendingIntent); compactActionList.add(numActions++); @@ -149,7 +149,7 @@ public class PlaybackServiceNotificationBuilder extends NotificationCompat.Build // ff follows play, then we have skip (if it's present) PendingIntent ffButtonPendingIntent = getPendingIntentForMediaAction( KeyEvent.KEYCODE_MEDIA_FAST_FORWARD, numActions); - addAction(android.R.drawable.ic_media_ff, context.getString(R.string.fast_forward_label), ffButtonPendingIntent); + addAction(R.drawable.ic_notification_fast_forward, context.getString(R.string.fast_forward_label), ffButtonPendingIntent); if (UserPreferences.showFastForwardOnCompactNotification()) { compactActionList.add(numActions); } @@ -158,7 +158,7 @@ public class PlaybackServiceNotificationBuilder extends NotificationCompat.Build if (UserPreferences.isFollowQueue()) { PendingIntent skipButtonPendingIntent = getPendingIntentForMediaAction( KeyEvent.KEYCODE_MEDIA_NEXT, numActions); - addAction(android.R.drawable.ic_media_next, + addAction(R.drawable.ic_notification_skip, context.getString(R.string.skip_episode_label), skipButtonPendingIntent); if (UserPreferences.showSkipOnCompactNotification()) { diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java index e68bff16e..4c15f5f00 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java @@ -3,7 +3,7 @@ package de.danoeh.antennapod.core.storage; import android.content.Context; import android.content.SharedPreferences; import android.database.Cursor; -import android.support.annotation.Nullable; +import android.os.Looper; import android.util.Log; import java.util.ArrayList; @@ -144,58 +144,36 @@ public final class DBTasks { private static final AtomicBoolean isRefreshing = new AtomicBoolean(false); /** - * Refreshes a given list of Feeds in a separate Thread. This method might ignore subsequent calls if it is still + * Refreshes all feeds. + * It must not be from the main thread. + * This method might ignore subsequent calls if it is still * enqueuing Feeds for download from a previous call * * @param context Might be used for accessing the database - * @param feeds List of Feeds that should be refreshed. */ - public static void refreshAllFeeds(final Context context, final List<Feed> feeds) { - refreshAllFeeds(context, feeds, null); - } - - /** - * Refreshes a given list of Feeds in a separate Thread. This method might ignore subsequent calls if it is still - * enqueuing Feeds for download from a previous call - * - * @param context Might be used for accessing the database - * @param feeds List of Feeds that should be refreshed. - * @param callback Called after everything was added enqueued for download. Might be null. - */ - public static void refreshAllFeeds(final Context context, final List<Feed> feeds, @Nullable Runnable callback) { + public static void refreshAllFeeds(final Context context) { if (!isRefreshing.compareAndSet(false, true)) { Log.d(TAG, "Ignoring request to refresh all feeds: Refresh lock is locked"); return; } - new Thread(() -> { - if (feeds != null) { - refreshFeeds(context, feeds); - } else { - refreshFeeds(context, DBReader.getFeedList()); - } - isRefreshing.set(false); + if (Looper.myLooper() == Looper.getMainLooper()) { + throw new IllegalStateException("DBTasks.refreshAllFeeds() must not be called from the main thread."); + } - SharedPreferences prefs = context.getSharedPreferences(PREF_NAME, MODE_PRIVATE); - prefs.edit().putLong(PREF_LAST_REFRESH, System.currentTimeMillis()).apply(); + refreshFeeds(context, DBReader.getFeedList()); + isRefreshing.set(false); - if (ClientConfig.gpodnetCallbacks.gpodnetEnabled()) { - GpodnetSyncService.sendSyncIntent(context); - } - // Note: automatic download of episodes will be done but not here. - // Instead it is done after all feeds have been refreshed (asynchronously), - // in DownloadService.onDestroy() - // See Issue #2577 for the details of the rationale + SharedPreferences prefs = context.getSharedPreferences(PREF_NAME, MODE_PRIVATE); + prefs.edit().putLong(PREF_LAST_REFRESH, System.currentTimeMillis()).apply(); - if (callback != null) { - callback.run(); - } - }).start(); - } - - public static long getLastRefreshAllFeedsTimeMillis(final Context context) { - SharedPreferences prefs = context.getSharedPreferences(DBTasks.PREF_NAME, MODE_PRIVATE); - return prefs.getLong(DBTasks.PREF_LAST_REFRESH, 0); + if (ClientConfig.gpodnetCallbacks.gpodnetEnabled()) { + GpodnetSyncService.sendSyncIntent(context); + } + // Note: automatic download of episodes will be done but not here. + // Instead it is done after all feeds have been refreshed (asynchronously), + // in DownloadService.onDestroy() + // See Issue #2577 for the details of the rationale } /** diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java index 892a4675a..9c48f31dd 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java @@ -34,7 +34,6 @@ import de.danoeh.antennapod.core.util.URLChecker; public class DownloadRequester { private static final String TAG = "DownloadRequester"; - public static final String IMAGE_DOWNLOADPATH = "images/"; private static final String FEED_DOWNLOADPATH = "cache/"; private static final String MEDIA_DOWNLOADPATH = "media/"; @@ -274,10 +273,6 @@ public class DownloadRequester { return item.getDownload_url() != null && downloads.containsKey(item.getDownload_url()); } - public synchronized DownloadRequest getDownload(String downloadUrl) { - return downloads.get(downloadUrl); - } - /** * Checks if feedfile with the given download url is in the downloads list */ diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java index 13ea9daf0..a3271bcf9 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java @@ -55,16 +55,10 @@ public class PodDBAdapter { */ private static final int IN_OPERATOR_MAXIMUM = 800; - /** - * Maximum number of entries per search request. - */ - public static final int SEARCH_LIMIT = 30; - // Key-constants public static final String KEY_ID = "id"; public static final String KEY_TITLE = "title"; public static final String KEY_CUSTOM_TITLE = "custom_title"; - public static final String KEY_NAME = "name"; public static final String KEY_LINK = "link"; public static final String KEY_DESCRIPTION = "description"; public static final String KEY_FILE_URL = "file_url"; @@ -1400,13 +1394,6 @@ public class PodDBAdapter { return db.rawQuery(query, null); } - - public static final int IDX_FEEDSTATISTICS_FEED = 0; - public static final int IDX_FEEDSTATISTICS_NUM_ITEMS = 1; - public static final int IDX_FEEDSTATISTICS_NEW_ITEMS = 2; - public static final int IDX_FEEDSTATISTICS_LATEST_EPISODE = 3; - public static final int IDX_FEEDSTATISTICS_IN_PROGRESS_EPISODES = 4; - /** * Select number of items, new items, the date of the latest episode and the number of episodes in progress. The result * is sorted by the title of the feed. diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/DuckType.java b/core/src/main/java/de/danoeh/antennapod/core/util/DuckType.java deleted file mode 100644 index 69dc38895..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/util/DuckType.java +++ /dev/null @@ -1,117 +0,0 @@ -/* Adapted from: http://thinking-in-code.blogspot.com/2008/11/duck-typing-in-java-using-dynamic.html */ - -package de.danoeh.antennapod.core.util; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; - -import de.danoeh.antennapod.core.BuildConfig; - -/** - * Allows "duck typing" or dynamic invocation based on method signature rather - * than type hierarchy. In other words, rather than checking whether something - * IS-a duck, check whether it WALKS-like-a duck or QUACKS-like a duck. - * - * To use first use the coerce static method to indicate the object you want to - * do Duck Typing for, then specify an interface to the to method which you want - * to coerce the type to, e.g: - * - * public interface Foo { void aMethod(); } class Bar { ... public void - * aMethod() { ... } ... } Bar bar = ...; Foo foo = - * DuckType.coerce(bar).to(Foo.class); foo.aMethod(); - * - * - */ -public class DuckType { - - private final Object objectToCoerce; - - private DuckType(Object objectToCoerce) { - this.objectToCoerce = objectToCoerce; - } - - private class CoercedProxy implements InvocationHandler { - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - Method delegateMethod = findMethodBySignature(method); - assert delegateMethod != null; - return delegateMethod.invoke(DuckType.this.objectToCoerce, args); - } - } - - /** - * Specify the duck typed object to coerce. - * - * @param object - * the object to coerce - * @return - */ - public static DuckType coerce(Object object) { - return new DuckType(object); - } - - /** - * Coerce the Duck Typed object to the given interface providing it - * implements all the necessary methods. - * - * @param - * @param iface - * @return an instance of the given interface that wraps the duck typed - * class - * @throws ClassCastException - * if the object being coerced does not implement all the - * methods in the given interface. - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - public <T> T to(Class iface) { - if (BuildConfig.DEBUG && !iface.isInterface()) throw new AssertionError("cannot coerce object to a class, must be an interface"); - if (isA(iface)) { - return (T) iface.cast(objectToCoerce); - } - if (quacksLikeA(iface)) { - return generateProxy(iface); - } - throw new ClassCastException("Could not coerce object of type " + objectToCoerce.getClass() + " to " + iface); - } - - @SuppressWarnings("rawtypes") - private boolean isA(Class iface) { - return objectToCoerce.getClass().isInstance(iface); - } - - /** - * Determine whether the duck typed object can be used with the given - * interface. - * - * @param Type - * of the interface to check. - * @param iface - * Interface class to check - * @return true if the object will support all the methods in the interface, - * false otherwise. - */ - @SuppressWarnings("rawtypes") - private boolean quacksLikeA(Class iface) { - for (Method method : iface.getMethods()) { - if (findMethodBySignature(method) == null) { - return false; - } - } - return true; - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - private <T> T generateProxy(Class iface) { - return (T) Proxy.newProxyInstance(iface.getClassLoader(), new Class[] { iface }, new CoercedProxy()); - } - - private Method findMethodBySignature(Method method) { - try { - return objectToCoerce.getClass().getMethod(method.getName(), method.getParameterTypes()); - } catch (NoSuchMethodException e) { - return null; - } - } - -}
\ No newline at end of file diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/FeedItemUtil.java b/core/src/main/java/de/danoeh/antennapod/core/util/FeedItemUtil.java index 826c06822..a8206d3bd 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/FeedItemUtil.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/FeedItemUtil.java @@ -7,19 +7,6 @@ import de.danoeh.antennapod.core.feed.FeedItem; public class FeedItemUtil { private FeedItemUtil(){} - public static int indexOfItemWithDownloadUrl(List<FeedItem> items, String downloadUrl) { - if(items == null) { - return -1; - } - for(int i=0; i < items.size(); i++) { - FeedItem item = items.get(i); - if(item.hasMedia() && item.getMedia().getDownload_url().equals(downloadUrl)) { - return i; - } - } - return -1; - } - public static int indexOfItemWithId(List<FeedItem> items, long id) { for(int i=0; i < items.size(); i++) { FeedItem item = items.get(i); @@ -40,17 +27,6 @@ public class FeedItemUtil { return -1; } - public static long[] getIds(FeedItem... items) { - if(items == null || items.length == 0) { - return new long[0]; - } - long[] result = new long[items.length]; - for(int i=0; i < items.length; i++) { - result[i] = items[i].getId(); - } - return result; - } - public static long[] getIds(List<FeedItem> items) { if(items == null || items.size() == 0) { return new long[0]; @@ -62,20 +38,6 @@ public class FeedItemUtil { return result; } - public static boolean containsAnyId(List<FeedItem> items, long[] ids) { - if(items == null || items.size() == 0) { - return false; - } - for(FeedItem item : items) { - for(long id : ids) { - if(item.getId() == id) { - return true; - } - } - } - return false; - } - /** * Get the link for the feed item for the purpose of Share. It fallbacks to * use the feed's link if the named feed item has no link. diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/FeedUpdateUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/FeedUpdateUtils.java deleted file mode 100644 index b425687ae..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/util/FeedUpdateUtils.java +++ /dev/null @@ -1,36 +0,0 @@ -package de.danoeh.antennapod.core.util; - -import android.content.Context; -import android.util.Log; - -import org.awaitility.core.ConditionTimeoutException; - -import java.util.concurrent.TimeUnit; - -import de.danoeh.antennapod.core.storage.DBTasks; - -import static org.awaitility.Awaitility.with; - -public class FeedUpdateUtils { - private static final String TAG = "FeedUpdateUtils"; - - private FeedUpdateUtils() {} - - public static void startAutoUpdate(Context context, Runnable callback) { - // the network check is blocking for possibly a long time: so run the logic - // in a separate thread to prevent the code blocking the callers - final Runnable runnable = () -> { - try { - with().pollInterval(1, TimeUnit.SECONDS) - .await() - .atMost(10, TimeUnit.SECONDS) - .until(() -> NetworkUtils.networkAvailable() && NetworkUtils.isFeedRefreshAllowed()); - DBTasks.refreshAllFeeds(context, null, callback); - } catch (ConditionTimeoutException ignore) { - Log.d(TAG, "Blocking automatic update: no wifi available / no mobile updates allowed"); - } - }; - new Thread(runnable).start(); - } - -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/FeedtitleComparator.java b/core/src/main/java/de/danoeh/antennapod/core/util/FeedtitleComparator.java deleted file mode 100644 index 29d095cd2..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/util/FeedtitleComparator.java +++ /dev/null @@ -1,15 +0,0 @@ -package de.danoeh.antennapod.core.util; - -import java.util.Comparator; - -import de.danoeh.antennapod.core.feed.Feed; - -/** Compares the title of two feeds for sorting. */ -class FeedtitleComparator implements Comparator<Feed> { - - @Override - public int compare(Feed lhs, Feed rhs) { - return lhs.getTitle().compareToIgnoreCase(rhs.getTitle()); - } - -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/IntentUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/IntentUtils.java index e81ab47ed..656b518bf 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/IntentUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/IntentUtils.java @@ -1,13 +1,20 @@ package de.danoeh.antennapod.core.util; +import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.net.Uri; +import android.util.Log; +import android.widget.Toast; +import de.danoeh.antennapod.core.R; import java.util.List; public class IntentUtils { + private static final String TAG = "IntentUtils"; + private IntentUtils(){} /* @@ -28,4 +35,13 @@ public class IntentUtils { context.sendBroadcast(new Intent(action).setPackage(context.getPackageName())); } + public static void openInBrowser(Context context, String url) { + try { + Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); + context.startActivity(myIntent); + } catch (ActivityNotFoundException e) { + Toast.makeText(context, R.string.pref_no_browser_found, Toast.LENGTH_LONG).show(); + Log.e(TAG, Log.getStackTraceString(e)); + } + } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/Optional.java b/core/src/main/java/de/danoeh/antennapod/core/util/Optional.java index 0fe11ec53..37f12c01c 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/Optional.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/Optional.java @@ -77,7 +77,7 @@ public final class Optional<T> { * @param <T> Type of the non-existent value * @return an empty {@code Optional} */ - public static<T> Optional<T> empty() { + public static <T> Optional<T> empty() { @SuppressWarnings("unchecked") Optional<T> t = (Optional<T>) EMPTY; return t; diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/comparator/SearchResultValueComparator.java b/core/src/main/java/de/danoeh/antennapod/core/util/comparator/SearchResultValueComparator.java deleted file mode 100644 index 56a684475..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/util/comparator/SearchResultValueComparator.java +++ /dev/null @@ -1,27 +0,0 @@ -package de.danoeh.antennapod.core.util.comparator; - -import java.util.Comparator; - -import de.danoeh.antennapod.core.feed.FeedItem; -import de.danoeh.antennapod.core.feed.SearchResult; - -public class SearchResultValueComparator implements Comparator<SearchResult> { - - /** - * Compare items based, first, on where they were found (ie. title, chapters, or show notes). - * If they were found in the same section, then compare based on the title, in lexicographic - * order. This is still not ideal since, for example, "#12 Example A" would be considered - * before "#8 Example B" due to the fact that "8" has a larger unicode value than "1" - */ - @Override - public int compare(SearchResult lhs, SearchResult rhs) { - int value = rhs.getValue() - lhs.getValue(); - if (value == 0 && lhs.getComponent() instanceof FeedItem && rhs.getComponent() instanceof FeedItem) { - String lhsTitle = ((FeedItem) lhs.getComponent()).getTitle(); - String rhsTitle = ((FeedItem) rhs.getComponent()).getTitle(); - return lhsTitle.compareTo(rhsTitle); - } - return value; - } - -} 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 412b150fa..ebeec058d 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,21 +1,29 @@ package de.danoeh.antennapod.core.util.download; +import android.content.Context; +import android.support.annotation.NonNull; import android.util.Log; + import androidx.work.Constraints; +import androidx.work.Data; 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.Arrays; import java.util.Calendar; import java.util.concurrent.TimeUnit; +import de.danoeh.antennapod.core.preferences.UserPreferences; +import de.danoeh.antennapod.core.service.FeedUpdateWorker; +import de.danoeh.antennapod.core.storage.DBTasks; + public class AutoUpdateManager { - private static final String WORK_ID_FEED_UPDATE = FeedUpdateWorker.class.getName(); + private static final String WORK_ID_FEED_UPDATE = "de.danoeh.antennapod.core.service.FeedUpdateWorker"; + private static final String WORK_ID_FEED_UPDATE_ONCE = WORK_ID_FEED_UPDATE + "Once"; private static final String TAG = "AutoUpdateManager"; private AutoUpdateManager() { @@ -23,9 +31,25 @@ public class AutoUpdateManager { } /** + * Start / restart periodic auto feed refresh + */ + public static void restartUpdateAlarm() { + if (UserPreferences.isAutoUpdateDisabled()) { + disableAutoUpdate(); + } else if (UserPreferences.isAutoUpdateTimeOfDay()) { + int[] timeOfDay = UserPreferences.getUpdateTimeOfDay(); + Log.d(TAG, "timeOfDay: " + Arrays.toString(timeOfDay)); + restartUpdateTimeOfDayAlarm(timeOfDay[0], timeOfDay[1]); + } else { + long milliseconds = UserPreferences.getUpdateInterval(); + restartUpdateIntervalAlarm(milliseconds); + } + } + + /** * Sets the interval in which the feeds are refreshed automatically */ - public static void restartUpdateIntervalAlarm(long intervalMillis) { + private static void restartUpdateIntervalAlarm(long intervalMillis) { Log.d(TAG, "Restarting update alarm."); PeriodicWorkRequest workRequest = new PeriodicWorkRequest.Builder(FeedUpdateWorker.class, @@ -40,7 +64,7 @@ public class AutoUpdateManager { /** * Sets time of day the feeds are refreshed automatically */ - public static void restartUpdateTimeOfDayAlarm(int hoursOfDay, int minute) { + private static void restartUpdateTimeOfDayAlarm(int hoursOfDay, int minute) { Log.d(TAG, "Restarting update alarm."); Calendar now = Calendar.getInstance(); @@ -60,6 +84,41 @@ public class AutoUpdateManager { WorkManager.getInstance().enqueueUniqueWork(WORK_ID_FEED_UPDATE, ExistingWorkPolicy.REPLACE, workRequest); } + /** + * Run auto feed refresh once in background, as soon as what OS scheduling allows. + * + * Callers from UI should use {@link #runImmediate(Context)}, as it will guarantee + * the refresh be run immediately. + */ + public static void runOnce() { + Log.d(TAG, "Run auto update once, as soon as OS allows."); + + OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(FeedUpdateWorker.class) + .setConstraints(getConstraints()) + .setInitialDelay(0L, TimeUnit.MILLISECONDS) + .setInputData(new Data.Builder() + .putBoolean(FeedUpdateWorker.PARAM_RUN_ONCE, true) + .build() + ) + .build(); + + WorkManager.getInstance().enqueueUniqueWork(WORK_ID_FEED_UPDATE_ONCE, ExistingWorkPolicy.REPLACE, workRequest); + + } + + /** + /** + * Run auto feed refresh once in background immediately, using its own thread. + * + * Callers where the additional threads is not suitable should use {@link #runOnce()} + */ + public static void runImmediate(@NonNull Context context) { + Log.d(TAG, "Run auto update immediately in background."); + new Thread(() -> { + DBTasks.refreshAllFeeds(context.getApplicationContext()); + }, "ManualRefreshAllFeeds").start(); + } + public static void disableAutoUpdate() { WorkManager.getInstance().cancelUniqueWork(WORK_ID_FEED_UPDATE); } @@ -74,4 +133,5 @@ public class AutoUpdateManager { } return constraints.build(); } + } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ChapterReader.java b/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ChapterReader.java index d22d08e09..a3f747e09 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ChapterReader.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ChapterReader.java @@ -72,7 +72,7 @@ public class ChapterReader extends ID3Reader { String decodedLink = URLDecoder.decode(link.toString(), "UTF-8"); currentChapter.setLink(decodedLink); Log.d(TAG, "Found link: " + currentChapter.getLink()); - } catch (IllegalArgumentException _iae) { + } catch (IllegalArgumentException iae) { Log.w(TAG, "Bad URL found in ID3 data"); } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/ExternalMedia.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/ExternalMedia.java index 645bae5f3..9b644c3ba 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/ExternalMedia.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/ExternalMedia.java @@ -182,7 +182,7 @@ public class ExternalMedia implements Playable { editor.putLong(PREF_LAST_PLAYED_TIME, timestamp); position = newPosition; lastPlayedTime = timestamp; - editor.commit(); + editor.apply(); } @Override diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java index 0cfaaab3c..ac5418dd0 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java @@ -728,6 +728,8 @@ public class PlaybackController { public void setPlaybackSpeed(float speed) { if (playbackService != null) { playbackService.setSpeed(speed); + } else { + onPlaybackSpeedChange(); } } public void setSkipSilence(boolean skipSilence) { diff --git a/core/src/main/res/drawable-hdpi/ic_baseline_question_answer_white_24dp.png b/core/src/main/res/drawable-hdpi/ic_baseline_question_answer_white_24dp.png Binary files differdeleted file mode 100755 index 67924a5a2..000000000 --- a/core/src/main/res/drawable-hdpi/ic_baseline_question_answer_white_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-hdpi/ic_cast_disabled_light.png b/core/src/main/res/drawable-hdpi/ic_cast_disabled_light.png Binary files differdeleted file mode 100644 index c0a55d555..000000000 --- a/core/src/main/res/drawable-hdpi/ic_cast_disabled_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-hdpi/ic_cast_light.png b/core/src/main/res/drawable-hdpi/ic_cast_light.png Binary files differdeleted file mode 100644 index b0c581a0e..000000000 --- a/core/src/main/res/drawable-hdpi/ic_cast_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-hdpi/ic_cast_off_light.png b/core/src/main/res/drawable-hdpi/ic_cast_off_light.png Binary files differdeleted file mode 100644 index 5f3c0179c..000000000 --- a/core/src/main/res/drawable-hdpi/ic_cast_off_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-hdpi/ic_cast_on_0_light.png b/core/src/main/res/drawable-hdpi/ic_cast_on_0_light.png Binary files differdeleted file mode 100644 index e872693a4..000000000 --- a/core/src/main/res/drawable-hdpi/ic_cast_on_0_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-hdpi/ic_cast_on_1_light.png b/core/src/main/res/drawable-hdpi/ic_cast_on_1_light.png Binary files differdeleted file mode 100644 index d8be1ebc6..000000000 --- a/core/src/main/res/drawable-hdpi/ic_cast_on_1_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-hdpi/ic_cast_on_2_light.png b/core/src/main/res/drawable-hdpi/ic_cast_on_2_light.png Binary files differdeleted file mode 100644 index 27cda9e9d..000000000 --- a/core/src/main/res/drawable-hdpi/ic_cast_on_2_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-hdpi/ic_cast_on_light.png b/core/src/main/res/drawable-hdpi/ic_cast_on_light.png Binary files differdeleted file mode 100644 index 4ee525875..000000000 --- a/core/src/main/res/drawable-hdpi/ic_cast_on_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-hdpi/ic_close_light.png b/core/src/main/res/drawable-hdpi/ic_close_light.png Binary files differdeleted file mode 100644 index 93187e450..000000000 --- a/core/src/main/res/drawable-hdpi/ic_close_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-hdpi/ic_format_list_bulleted_grey600_24dp.png b/core/src/main/res/drawable-hdpi/ic_format_list_bulleted_grey600_24dp.png Binary files differdeleted file mode 100644 index 3668c9a00..000000000 --- a/core/src/main/res/drawable-hdpi/ic_format_list_bulleted_grey600_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-hdpi/ic_format_list_bulleted_white_24dp.png b/core/src/main/res/drawable-hdpi/ic_format_list_bulleted_white_24dp.png Binary files differdeleted file mode 100644 index a1a2c5b68..000000000 --- a/core/src/main/res/drawable-hdpi/ic_format_list_bulleted_white_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-hdpi/ic_forum_grey600_24dp.png b/core/src/main/res/drawable-hdpi/ic_forum_grey600_24dp.png Binary files differdeleted file mode 100644 index da5398d15..000000000 --- a/core/src/main/res/drawable-hdpi/ic_forum_grey600_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-hdpi/ic_media_cast_disconnect.png b/core/src/main/res/drawable-hdpi/ic_media_cast_disconnect.png Binary files differdeleted file mode 100644 index 700c116e5..000000000 --- a/core/src/main/res/drawable-hdpi/ic_media_cast_disconnect.png +++ /dev/null diff --git a/core/src/main/res/drawable-hdpi/ic_pause_light.png b/core/src/main/res/drawable-hdpi/ic_pause_light.png Binary files differdeleted file mode 100644 index 0c505d1c8..000000000 --- a/core/src/main/res/drawable-hdpi/ic_pause_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-hdpi/ic_play_light.png b/core/src/main/res/drawable-hdpi/ic_play_light.png Binary files differdeleted file mode 100644 index 7957dff5b..000000000 --- a/core/src/main/res/drawable-hdpi/ic_play_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-hdpi/ic_stat_antenna_default.png b/core/src/main/res/drawable-hdpi/ic_stat_antenna_default.png Binary files differdeleted file mode 100644 index af99f4b3b..000000000 --- a/core/src/main/res/drawable-hdpi/ic_stat_antenna_default.png +++ /dev/null diff --git a/core/src/main/res/drawable-hdpi/ic_stat_authentication.png b/core/src/main/res/drawable-hdpi/ic_stat_authentication.png Binary files differdeleted file mode 100644 index 398dffa4b..000000000 --- a/core/src/main/res/drawable-hdpi/ic_stat_authentication.png +++ /dev/null diff --git a/core/src/main/res/drawable-ldpi/ic_stat_antenna_default.png b/core/src/main/res/drawable-ldpi/ic_stat_antenna_default.png Binary files differdeleted file mode 100644 index ddf545c0b..000000000 --- a/core/src/main/res/drawable-ldpi/ic_stat_antenna_default.png +++ /dev/null diff --git a/core/src/main/res/drawable-mdpi/ic_baseline_question_answer_white_24dp.png b/core/src/main/res/drawable-mdpi/ic_baseline_question_answer_white_24dp.png Binary files differdeleted file mode 100755 index e87df752e..000000000 --- a/core/src/main/res/drawable-mdpi/ic_baseline_question_answer_white_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-mdpi/ic_cast_disabled_light.png b/core/src/main/res/drawable-mdpi/ic_cast_disabled_light.png Binary files differdeleted file mode 100644 index 7940a0332..000000000 --- a/core/src/main/res/drawable-mdpi/ic_cast_disabled_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-mdpi/ic_cast_light.png b/core/src/main/res/drawable-mdpi/ic_cast_light.png Binary files differdeleted file mode 100644 index 1f5bec20b..000000000 --- a/core/src/main/res/drawable-mdpi/ic_cast_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-mdpi/ic_cast_off_light.png b/core/src/main/res/drawable-mdpi/ic_cast_off_light.png Binary files differdeleted file mode 100644 index 963db27d4..000000000 --- a/core/src/main/res/drawable-mdpi/ic_cast_off_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-mdpi/ic_cast_on_0_light.png b/core/src/main/res/drawable-mdpi/ic_cast_on_0_light.png Binary files differdeleted file mode 100644 index a90d9e305..000000000 --- a/core/src/main/res/drawable-mdpi/ic_cast_on_0_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-mdpi/ic_cast_on_1_light.png b/core/src/main/res/drawable-mdpi/ic_cast_on_1_light.png Binary files differdeleted file mode 100644 index bb2cf30bf..000000000 --- a/core/src/main/res/drawable-mdpi/ic_cast_on_1_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-mdpi/ic_cast_on_2_light.png b/core/src/main/res/drawable-mdpi/ic_cast_on_2_light.png Binary files differdeleted file mode 100644 index 3ed59e55b..000000000 --- a/core/src/main/res/drawable-mdpi/ic_cast_on_2_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-mdpi/ic_cast_on_light.png b/core/src/main/res/drawable-mdpi/ic_cast_on_light.png Binary files differdeleted file mode 100644 index 713427b97..000000000 --- a/core/src/main/res/drawable-mdpi/ic_cast_on_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-mdpi/ic_close_light.png b/core/src/main/res/drawable-mdpi/ic_close_light.png Binary files differdeleted file mode 100644 index 2c52c9b0f..000000000 --- a/core/src/main/res/drawable-mdpi/ic_close_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-mdpi/ic_format_list_bulleted_grey600_24dp.png b/core/src/main/res/drawable-mdpi/ic_format_list_bulleted_grey600_24dp.png Binary files differdeleted file mode 100644 index 726eae499..000000000 --- a/core/src/main/res/drawable-mdpi/ic_format_list_bulleted_grey600_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-mdpi/ic_format_list_bulleted_white_24dp.png b/core/src/main/res/drawable-mdpi/ic_format_list_bulleted_white_24dp.png Binary files differdeleted file mode 100644 index 0cc401dff..000000000 --- a/core/src/main/res/drawable-mdpi/ic_format_list_bulleted_white_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-mdpi/ic_forum_grey600_24dp.png b/core/src/main/res/drawable-mdpi/ic_forum_grey600_24dp.png Binary files differdeleted file mode 100644 index d3bcfe7b6..000000000 --- a/core/src/main/res/drawable-mdpi/ic_forum_grey600_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-mdpi/ic_media_cast_disconnect.png b/core/src/main/res/drawable-mdpi/ic_media_cast_disconnect.png Binary files differdeleted file mode 100644 index 767f420df..000000000 --- a/core/src/main/res/drawable-mdpi/ic_media_cast_disconnect.png +++ /dev/null diff --git a/core/src/main/res/drawable-mdpi/ic_pause_light.png b/core/src/main/res/drawable-mdpi/ic_pause_light.png Binary files differdeleted file mode 100644 index 6218a774f..000000000 --- a/core/src/main/res/drawable-mdpi/ic_pause_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-mdpi/ic_play_light.png b/core/src/main/res/drawable-mdpi/ic_play_light.png Binary files differdeleted file mode 100644 index 1e0ccaf80..000000000 --- a/core/src/main/res/drawable-mdpi/ic_play_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-mdpi/ic_stat_antenna_default.png b/core/src/main/res/drawable-mdpi/ic_stat_antenna_default.png Binary files differdeleted file mode 100644 index 41fd20655..000000000 --- a/core/src/main/res/drawable-mdpi/ic_stat_antenna_default.png +++ /dev/null diff --git a/core/src/main/res/drawable-mdpi/ic_stat_authentication.png b/core/src/main/res/drawable-mdpi/ic_stat_authentication.png Binary files differdeleted file mode 100644 index 550b56b33..000000000 --- a/core/src/main/res/drawable-mdpi/ic_stat_authentication.png +++ /dev/null diff --git a/core/src/main/res/drawable-xhdpi/ic_baseline_question_answer_white_24dp.png b/core/src/main/res/drawable-xhdpi/ic_baseline_question_answer_white_24dp.png Binary files differdeleted file mode 100755 index 731f89c83..000000000 --- a/core/src/main/res/drawable-xhdpi/ic_baseline_question_answer_white_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xhdpi/ic_cast_disabled_light.png b/core/src/main/res/drawable-xhdpi/ic_cast_disabled_light.png Binary files differdeleted file mode 100644 index fbb3e062c..000000000 --- a/core/src/main/res/drawable-xhdpi/ic_cast_disabled_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-xhdpi/ic_cast_light.png b/core/src/main/res/drawable-xhdpi/ic_cast_light.png Binary files differdeleted file mode 100644 index f2713e20e..000000000 --- a/core/src/main/res/drawable-xhdpi/ic_cast_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-xhdpi/ic_cast_off_light.png b/core/src/main/res/drawable-xhdpi/ic_cast_off_light.png Binary files differdeleted file mode 100644 index f4f8aaea8..000000000 --- a/core/src/main/res/drawable-xhdpi/ic_cast_off_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-xhdpi/ic_cast_on_0_light.png b/core/src/main/res/drawable-xhdpi/ic_cast_on_0_light.png Binary files differdeleted file mode 100644 index 247fc95ba..000000000 --- a/core/src/main/res/drawable-xhdpi/ic_cast_on_0_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-xhdpi/ic_cast_on_1_light.png b/core/src/main/res/drawable-xhdpi/ic_cast_on_1_light.png Binary files differdeleted file mode 100644 index ecf4b4723..000000000 --- a/core/src/main/res/drawable-xhdpi/ic_cast_on_1_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-xhdpi/ic_cast_on_2_light.png b/core/src/main/res/drawable-xhdpi/ic_cast_on_2_light.png Binary files differdeleted file mode 100644 index 60e3afa5d..000000000 --- a/core/src/main/res/drawable-xhdpi/ic_cast_on_2_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-xhdpi/ic_cast_on_light.png b/core/src/main/res/drawable-xhdpi/ic_cast_on_light.png Binary files differdeleted file mode 100644 index 40ce9d4f2..000000000 --- a/core/src/main/res/drawable-xhdpi/ic_cast_on_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-xhdpi/ic_close_light.png b/core/src/main/res/drawable-xhdpi/ic_close_light.png Binary files differdeleted file mode 100644 index 49faa429a..000000000 --- a/core/src/main/res/drawable-xhdpi/ic_close_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-xhdpi/ic_format_list_bulleted_grey600_24dp.png b/core/src/main/res/drawable-xhdpi/ic_format_list_bulleted_grey600_24dp.png Binary files differdeleted file mode 100644 index 322adb6e0..000000000 --- a/core/src/main/res/drawable-xhdpi/ic_format_list_bulleted_grey600_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xhdpi/ic_format_list_bulleted_white_24dp.png b/core/src/main/res/drawable-xhdpi/ic_format_list_bulleted_white_24dp.png Binary files differdeleted file mode 100644 index c25860017..000000000 --- a/core/src/main/res/drawable-xhdpi/ic_format_list_bulleted_white_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xhdpi/ic_forum_grey600_24dp.png b/core/src/main/res/drawable-xhdpi/ic_forum_grey600_24dp.png Binary files differdeleted file mode 100644 index ac6876140..000000000 --- a/core/src/main/res/drawable-xhdpi/ic_forum_grey600_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xhdpi/ic_media_cast_disconnect.png b/core/src/main/res/drawable-xhdpi/ic_media_cast_disconnect.png Binary files differdeleted file mode 100644 index 740867129..000000000 --- a/core/src/main/res/drawable-xhdpi/ic_media_cast_disconnect.png +++ /dev/null diff --git a/core/src/main/res/drawable-xhdpi/ic_pause_light.png b/core/src/main/res/drawable-xhdpi/ic_pause_light.png Binary files differdeleted file mode 100644 index 40cd79f14..000000000 --- a/core/src/main/res/drawable-xhdpi/ic_pause_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-xhdpi/ic_play_light.png b/core/src/main/res/drawable-xhdpi/ic_play_light.png Binary files differdeleted file mode 100644 index 33f6a5919..000000000 --- a/core/src/main/res/drawable-xhdpi/ic_play_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-xhdpi/ic_stat_antenna_default.png b/core/src/main/res/drawable-xhdpi/ic_stat_antenna_default.png Binary files differdeleted file mode 100644 index 30431ed6a..000000000 --- a/core/src/main/res/drawable-xhdpi/ic_stat_antenna_default.png +++ /dev/null diff --git a/core/src/main/res/drawable-xhdpi/ic_stat_authentication.png b/core/src/main/res/drawable-xhdpi/ic_stat_authentication.png Binary files differdeleted file mode 100644 index e83cbc333..000000000 --- a/core/src/main/res/drawable-xhdpi/ic_stat_authentication.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxhdpi/ic_baseline_question_answer_white_24dp.png b/core/src/main/res/drawable-xxhdpi/ic_baseline_question_answer_white_24dp.png Binary files differdeleted file mode 100755 index 255b82707..000000000 --- a/core/src/main/res/drawable-xxhdpi/ic_baseline_question_answer_white_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxhdpi/ic_cast_disabled_light.png b/core/src/main/res/drawable-xxhdpi/ic_cast_disabled_light.png Binary files differdeleted file mode 100644 index e94df3889..000000000 --- a/core/src/main/res/drawable-xxhdpi/ic_cast_disabled_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxhdpi/ic_cast_light.png b/core/src/main/res/drawable-xxhdpi/ic_cast_light.png Binary files differdeleted file mode 100644 index c5722a6eb..000000000 --- a/core/src/main/res/drawable-xxhdpi/ic_cast_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxhdpi/ic_cast_off_light.png b/core/src/main/res/drawable-xxhdpi/ic_cast_off_light.png Binary files differdeleted file mode 100644 index 92ac67b34..000000000 --- a/core/src/main/res/drawable-xxhdpi/ic_cast_off_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxhdpi/ic_cast_on_0_light.png b/core/src/main/res/drawable-xxhdpi/ic_cast_on_0_light.png Binary files differdeleted file mode 100644 index 2742fcb4a..000000000 --- a/core/src/main/res/drawable-xxhdpi/ic_cast_on_0_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxhdpi/ic_cast_on_1_light.png b/core/src/main/res/drawable-xxhdpi/ic_cast_on_1_light.png Binary files differdeleted file mode 100644 index 405178e64..000000000 --- a/core/src/main/res/drawable-xxhdpi/ic_cast_on_1_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxhdpi/ic_cast_on_2_light.png b/core/src/main/res/drawable-xxhdpi/ic_cast_on_2_light.png Binary files differdeleted file mode 100644 index dfe52428d..000000000 --- a/core/src/main/res/drawable-xxhdpi/ic_cast_on_2_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxhdpi/ic_cast_on_light.png b/core/src/main/res/drawable-xxhdpi/ic_cast_on_light.png Binary files differdeleted file mode 100644 index 7e69a0864..000000000 --- a/core/src/main/res/drawable-xxhdpi/ic_cast_on_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxhdpi/ic_close_light.png b/core/src/main/res/drawable-xxhdpi/ic_close_light.png Binary files differdeleted file mode 100644 index be519bfcb..000000000 --- a/core/src/main/res/drawable-xxhdpi/ic_close_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxhdpi/ic_format_list_bulleted_grey600_24dp.png b/core/src/main/res/drawable-xxhdpi/ic_format_list_bulleted_grey600_24dp.png Binary files differdeleted file mode 100644 index 87f8073ea..000000000 --- a/core/src/main/res/drawable-xxhdpi/ic_format_list_bulleted_grey600_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxhdpi/ic_format_list_bulleted_white_24dp.png b/core/src/main/res/drawable-xxhdpi/ic_format_list_bulleted_white_24dp.png Binary files differdeleted file mode 100644 index da3433c61..000000000 --- a/core/src/main/res/drawable-xxhdpi/ic_format_list_bulleted_white_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxhdpi/ic_forum_grey600_24dp.png b/core/src/main/res/drawable-xxhdpi/ic_forum_grey600_24dp.png Binary files differdeleted file mode 100644 index 7a3204693..000000000 --- a/core/src/main/res/drawable-xxhdpi/ic_forum_grey600_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxhdpi/ic_media_cast_disconnect.png b/core/src/main/res/drawable-xxhdpi/ic_media_cast_disconnect.png Binary files differdeleted file mode 100644 index 2d2ec9035..000000000 --- a/core/src/main/res/drawable-xxhdpi/ic_media_cast_disconnect.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxhdpi/ic_pause_light.png b/core/src/main/res/drawable-xxhdpi/ic_pause_light.png Binary files differdeleted file mode 100644 index a36d4d11e..000000000 --- a/core/src/main/res/drawable-xxhdpi/ic_pause_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxhdpi/ic_play_light.png b/core/src/main/res/drawable-xxhdpi/ic_play_light.png Binary files differdeleted file mode 100644 index b1424874a..000000000 --- a/core/src/main/res/drawable-xxhdpi/ic_play_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxhdpi/ic_stat_authentication.png b/core/src/main/res/drawable-xxhdpi/ic_stat_authentication.png Binary files differdeleted file mode 100755 index 965fabc57..000000000 --- a/core/src/main/res/drawable-xxhdpi/ic_stat_authentication.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxxhdpi/ic_baseline_question_answer_white_24db.png b/core/src/main/res/drawable-xxxhdpi/ic_baseline_question_answer_white_24db.png Binary files differdeleted file mode 100755 index 0d697e0f9..000000000 --- a/core/src/main/res/drawable-xxxhdpi/ic_baseline_question_answer_white_24db.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxxhdpi/ic_close_light.png b/core/src/main/res/drawable-xxxhdpi/ic_close_light.png Binary files differdeleted file mode 100644 index 679c2a4d5..000000000 --- a/core/src/main/res/drawable-xxxhdpi/ic_close_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxxhdpi/ic_format_list_bulleted_grey600_24dp.png b/core/src/main/res/drawable-xxxhdpi/ic_format_list_bulleted_grey600_24dp.png Binary files differdeleted file mode 100644 index c56590fe0..000000000 --- a/core/src/main/res/drawable-xxxhdpi/ic_format_list_bulleted_grey600_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxxhdpi/ic_format_list_bulleted_white_24dp.png b/core/src/main/res/drawable-xxxhdpi/ic_format_list_bulleted_white_24dp.png Binary files differdeleted file mode 100644 index 5deea3286..000000000 --- a/core/src/main/res/drawable-xxxhdpi/ic_format_list_bulleted_white_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxxhdpi/ic_forum_grey600_24dp.png b/core/src/main/res/drawable-xxxhdpi/ic_forum_grey600_24dp.png Binary files differdeleted file mode 100644 index 0ae33696b..000000000 --- a/core/src/main/res/drawable-xxxhdpi/ic_forum_grey600_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxxhdpi/ic_pause_light.png b/core/src/main/res/drawable-xxxhdpi/ic_pause_light.png Binary files differdeleted file mode 100644 index 7de2ef4ed..000000000 --- a/core/src/main/res/drawable-xxxhdpi/ic_pause_light.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxxhdpi/ic_play_light.png b/core/src/main/res/drawable-xxxhdpi/ic_play_light.png Binary files differdeleted file mode 100644 index 4428c8477..000000000 --- a/core/src/main/res/drawable-xxxhdpi/ic_play_light.png +++ /dev/null diff --git a/core/src/main/res/drawable/ic_antenna.xml b/core/src/main/res/drawable/ic_antenna.xml new file mode 100644 index 000000000..9fcfab000 --- /dev/null +++ b/core/src/main/res/drawable/ic_antenna.xml @@ -0,0 +1,6 @@ +<vector android:height="24dp" android:viewportHeight="12.7" + android:viewportWidth="12.7" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillAlpha="1" android:fillColor="#ffffff" + android:pathData="m6.0631,0.4728v0.3274c1.1582,0.0249 1.911,0.4225 2.5991,1.1189 0.6881,0.6964 1.0924,1.7043 1.1125,2.9246h0.3211c0.0078,-1.3792 -0.5291,-2.4905 -1.1981,-3.1576C8.2288,1.019 7.3415,0.4734 6.0631,0.4728ZM6.0631,1.4283v0.3453c0.859,0.0361 1.3465,0.2123 1.9398,0.8081 0.5933,0.5957 0.843,1.3669 0.8598,2.2621L9.2029,4.8438c-0.0088,-1.2333 -0.5414,-2.0907 -0.9568,-2.5047 -0.4154,-0.4139 -0.9948,-0.9065 -2.183,-0.9108zM6.0625,2.4323 L6.0631,2.7495c0.3968,0.007 0.8308,0.1395 1.2089,0.5642 0.3781,0.4247 0.495,1.0244 0.51,1.53h0.3255c-0.0016,-0.669 -0.2787,-1.3891 -0.6153,-1.747 -0.3366,-0.358 -0.7368,-0.6621 -1.4298,-0.6645zM6.0906,3.7766c-0.4059,0.0002 -0.7349,0.3294 -0.7347,0.7353 0.0001,0.2677 0.1459,0.5142 0.3804,0.6434l-3.0102,6.2227 0.5151,0.3351 0.607,-1.2485 5.3821,1.5453 0.083,0.1609 0.5732,-0.2508 -3.4927,-6.7397c0.2624,-0.1189 0.4311,-0.3802 0.4315,-0.6683 0.0002,-0.4059 -0.3287,-0.7352 -0.7347,-0.7353zM6.065,5.8631 L6.5929,6.8882 5.2882,7.4761zM6.6976,7.0918 L7.6065,8.8561 5.137,7.8016zM5.0259,8.0199 L7.611,9.1184 4.0314,10.0854zM7.8395,9.3086 L9.081,11.7201 4.1489,10.3069z" + android:strokeAlpha="1" android:strokeColor="#00000000" android:strokeWidth="0.32680494"/> +</vector> diff --git a/core/src/main/res/drawable/ic_chat_grey600.xml b/core/src/main/res/drawable/ic_chat_grey600.xml new file mode 100644 index 000000000..ebae2dbed --- /dev/null +++ b/core/src/main/res/drawable/ic_chat_grey600.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" + android:viewportHeight="24.0" android:viewportWidth="24.0" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="#FF757575" android:pathData="M21,6h-2v9L6,15v2c0,0.55 0.45,1 1,1h11l4,4L22,7c0,-0.55 -0.45,-1 -1,-1zM17,12L17,3c0,-0.55 -0.45,-1 -1,-1L3,2c-0.55,0 -1,0.45 -1,1v14l4,-4h10c0.55,0 1,-0.45 1,-1z"/> +</vector> diff --git a/core/src/main/res/drawable/ic_chat_white.xml b/core/src/main/res/drawable/ic_chat_white.xml new file mode 100644 index 000000000..45691c525 --- /dev/null +++ b/core/src/main/res/drawable/ic_chat_white.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" + android:viewportHeight="24.0" android:viewportWidth="24.0" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="#FFFFFFFF" android:pathData="M21,6h-2v9L6,15v2c0,0.55 0.45,1 1,1h11l4,4L22,7c0,-0.55 -0.45,-1 -1,-1zM17,12L17,3c0,-0.55 -0.45,-1 -1,-1L3,2c-0.55,0 -1,0.45 -1,1v14l4,-4h10c0.55,0 1,-0.45 1,-1z"/> +</vector> diff --git a/core/src/main/res/drawable/ic_notification.png b/core/src/main/res/drawable/ic_notification.png Binary files differdeleted file mode 100644 index 8bd22b54a..000000000 --- a/core/src/main/res/drawable/ic_notification.png +++ /dev/null diff --git a/core/src/main/res/drawable/ic_notification_cast_off.xml b/core/src/main/res/drawable/ic_notification_cast_off.xml new file mode 100644 index 000000000..63a21fbe2 --- /dev/null +++ b/core/src/main/res/drawable/ic_notification_cast_off.xml @@ -0,0 +1,5 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="24dp" android:viewportHeight="24.0" + android:viewportWidth="24.0" android:width="24dp"> + <path android:fillColor="#FFFFFFFF" android:pathData="M1.6,1.27L0.25,2.75L1.41,3.8C1.16,4.13 1,4.55 1,5V8H3V5.23L18.2,19H14V21H20.41L22.31,22.72L23.65,21.24M6.5,3L8.7,5H21V16.14L23,17.95V5C23,3.89 22.1,3 21,3M1,10V12A9,9 0 0,1 10,21H12C12,14.92 7.08,10 1,10M1,14V16A5,5 0 0,1 6,21H8A7,7 0 0,0 1,14M1,18V21H4A3,3 0 0,0 1,18Z" /> +</vector>
\ No newline at end of file diff --git a/core/src/main/res/drawable/ic_notification_fast_forward.xml b/core/src/main/res/drawable/ic_notification_fast_forward.xml new file mode 100644 index 000000000..bf564977c --- /dev/null +++ b/core/src/main/res/drawable/ic_notification_fast_forward.xml @@ -0,0 +1,5 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="24dp" android:viewportHeight="24.0" + android:viewportWidth="24.0" android:width="24dp"> + <path android:fillColor="#FFFFFFFF" android:pathData="M4,18l8.5,-6L4,6v12zM13,6v12l8.5,-6L13,6z"/> +</vector> diff --git a/core/src/main/res/drawable/ic_notification_fast_rewind.xml b/core/src/main/res/drawable/ic_notification_fast_rewind.xml new file mode 100644 index 000000000..847159cc5 --- /dev/null +++ b/core/src/main/res/drawable/ic_notification_fast_rewind.xml @@ -0,0 +1,5 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="24dp" android:viewportHeight="24.0" + android:viewportWidth="24.0" android:width="24dp"> + <path android:fillColor="#FFFFFFFF" android:pathData="M11,18L11,6l-8.5,6 8.5,6zM11.5,12l8.5,6L20,6l-8.5,6z"/> +</vector> diff --git a/core/src/main/res/drawable/ic_notification_key.xml b/core/src/main/res/drawable/ic_notification_key.xml new file mode 100644 index 000000000..c8a817eeb --- /dev/null +++ b/core/src/main/res/drawable/ic_notification_key.xml @@ -0,0 +1,6 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="24dp" android:viewportHeight="24.0" + android:viewportWidth="24.0" android:width="24dp"> + <path android:fillColor="#FFFFFFFF" + android:pathData="M12.65,10C11.83,7.67 9.61,6 7,6c-3.31,0 -6,2.69 -6,6s2.69,6 6,6c2.61,0 4.83,-1.67 5.65,-4H17v4h4v-4h2v-4H12.65zM7,14c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2z"/> +</vector> diff --git a/core/src/main/res/drawable/ic_notification_pause.xml b/core/src/main/res/drawable/ic_notification_pause.xml new file mode 100644 index 000000000..d46efb2f5 --- /dev/null +++ b/core/src/main/res/drawable/ic_notification_pause.xml @@ -0,0 +1,5 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="24dp" android:viewportHeight="24.0" + android:viewportWidth="24.0" android:width="24dp"> + <path android:fillColor="#FFFFFFFF" android:pathData="M6,19h4L10,5L6,5v14zM14,5v14h4L18,5h-4z"/> +</vector> diff --git a/core/src/main/res/drawable/ic_notification_play.xml b/core/src/main/res/drawable/ic_notification_play.xml new file mode 100644 index 000000000..d571460c6 --- /dev/null +++ b/core/src/main/res/drawable/ic_notification_play.xml @@ -0,0 +1,5 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="24dp" android:viewportHeight="24.0" + android:viewportWidth="24.0" android:width="24dp"> + <path android:fillColor="#FFFFFFFF" android:pathData="M8,5v14l11,-7z"/> +</vector> diff --git a/core/src/main/res/drawable/ic_notification_skip.xml b/core/src/main/res/drawable/ic_notification_skip.xml new file mode 100644 index 000000000..0c65448cc --- /dev/null +++ b/core/src/main/res/drawable/ic_notification_skip.xml @@ -0,0 +1,5 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="24dp" android:viewportHeight="24.0" + android:viewportWidth="24.0" android:width="24dp"> + <path android:fillColor="#FFFFFFFF" android:pathData="M6,18l8.5,-6L6,6v12zM16,6v12h2V6h-2z"/> +</vector> diff --git a/core/src/main/res/drawable/ic_playback_speed_dark.xml b/core/src/main/res/drawable/ic_playback_speed_dark.xml new file mode 100644 index 000000000..7c7d1cf8c --- /dev/null +++ b/core/src/main/res/drawable/ic_playback_speed_dark.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="24dp" + android:width="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path android:fillColor="#FF757575" android:pathData="M 12,14.888154 A 2.2284437,2.2284437 0 0 1 9.7715563,12.659711 c 0,-0.831952 0.4531167,-1.559911 1.1142217,-1.938746 L 18.098507,6.5463469 13.990743,13.66251 C 13.619336,14.390469 12.869093,14.888154 12,14.888154 m 0,-9.6565888 c 1.344494,0 2.599851,0.3714073 3.691789,0.9805151 L 14.131878,7.110886 C 13.485629,6.858329 12.742815,6.7171943 12,6.7171943 A 5.9425165,5.9425165 0 0 0 6.0574835,12.659711 c 0,1.64162 0.661105,3.127249 1.7381861,4.196902 h 0.00743 c 0.2896977,0.289697 0.2896977,0.757671 0,1.047369 -0.2896977,0.289697 -0.7650991,0.289697 -1.0547967,0.0075 v 0 C 5.4038067,16.566915 4.5718544,14.709879 4.5718544,12.659711 A 7.4281456,7.4281456 0 0 1 12,5.2315652 m 7.428145,7.4281458 c 0,2.050168 -0.831952,3.907204 -2.176446,5.251699 v 0 c -0.289698,0.282269 -0.757671,0.282269 -1.047369,-0.0075 -0.289697,-0.289698 -0.289697,-0.757671 0,-1.047368 v 0 c 1.077082,-1.077082 1.738186,-2.555282 1.738186,-4.196902 0,-0.742815 -0.141134,-1.48563 -0.401119,-2.154163 l 0.898805,-1.5599106 c 0.616537,1.1142216 0.987943,2.3621496 0.987943,3.7140736 z" /> +</vector>
\ No newline at end of file diff --git a/core/src/main/res/drawable/ic_playback_speed_white.xml b/core/src/main/res/drawable/ic_playback_speed_white.xml new file mode 100644 index 000000000..cc6af0d55 --- /dev/null +++ b/core/src/main/res/drawable/ic_playback_speed_white.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="48dp" + android:width="48dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path android:fillColor="#ffffffff" android:pathData="M 12,14.888154 A 2.2284437,2.2284437 0 0 1 9.7715563,12.659711 c 0,-0.831952 0.4531167,-1.559911 1.1142217,-1.938746 L 18.098507,6.5463469 13.990743,13.66251 C 13.619336,14.390469 12.869093,14.888154 12,14.888154 m 0,-9.6565888 c 1.344494,0 2.599851,0.3714073 3.691789,0.9805151 L 14.131878,7.110886 C 13.485629,6.858329 12.742815,6.7171943 12,6.7171943 A 5.9425165,5.9425165 0 0 0 6.0574835,12.659711 c 0,1.64162 0.661105,3.127249 1.7381861,4.196902 h 0.00743 c 0.2896977,0.289697 0.2896977,0.757671 0,1.047369 -0.2896977,0.289697 -0.7650991,0.289697 -1.0547967,0.0075 v 0 C 5.4038067,16.566915 4.5718544,14.709879 4.5718544,12.659711 A 7.4281456,7.4281456 0 0 1 12,5.2315652 m 7.428145,7.4281458 c 0,2.050168 -0.831952,3.907204 -2.176446,5.251699 v 0 c -0.289698,0.282269 -0.757671,0.282269 -1.047369,-0.0075 -0.289697,-0.289698 -0.289697,-0.757671 0,-1.047368 v 0 c 1.077082,-1.077082 1.738186,-2.555282 1.738186,-4.196902 0,-0.742815 -0.141134,-1.48563 -0.401119,-2.154163 l 0.898805,-1.5599106 c 0.616537,1.1142216 0.987943,2.3621496 0.987943,3.7140736 z" /> +</vector>
\ No newline at end of file diff --git a/core/src/main/res/drawable/ic_questionmark_grey600.xml b/core/src/main/res/drawable/ic_questionmark_grey600.xml new file mode 100644 index 000000000..0907fcdec --- /dev/null +++ b/core/src/main/res/drawable/ic_questionmark_grey600.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" + android:viewportHeight="24.0" android:viewportWidth="24.0" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="#FF757575" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,19h-2v-2h2v2zM15.07,11.25l-0.9,0.92C13.45,12.9 13,13.5 13,15h-2v-0.5c0,-1.1 0.45,-2.1 1.17,-2.83l1.24,-1.26c0.37,-0.36 0.59,-0.86 0.59,-1.41 0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2L8,9c0,-2.21 1.79,-4 4,-4s4,1.79 4,4c0,0.88 -0.36,1.68 -0.93,2.25z"/> +</vector> diff --git a/core/src/main/res/drawable/ic_questionmark_white.xml b/core/src/main/res/drawable/ic_questionmark_white.xml new file mode 100644 index 000000000..69b42fef8 --- /dev/null +++ b/core/src/main/res/drawable/ic_questionmark_white.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" + android:viewportHeight="24.0" android:viewportWidth="24.0" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="#FFFFFFFF" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,19h-2v-2h2v2zM15.07,11.25l-0.9,0.92C13.45,12.9 13,13.5 13,15h-2v-0.5c0,-1.1 0.45,-2.1 1.17,-2.83l1.24,-1.26c0.37,-0.36 0.59,-0.86 0.59,-1.41 0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2L8,9c0,-2.21 1.79,-4 4,-4s4,1.79 4,4c0,0.88 -0.36,1.68 -0.93,2.25z"/> +</vector> diff --git a/core/src/main/res/drawable/ic_warning_red.xml b/core/src/main/res/drawable/ic_warning_red.xml new file mode 100644 index 000000000..475a41bbb --- /dev/null +++ b/core/src/main/res/drawable/ic_warning_red.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="#FF0000" + android:viewportHeight="24.0" android:viewportWidth="24.0" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="#FF000000" android:pathData="M1,21h22L12,2 1,21zM13,18h-2v-2h2v2zM13,14h-2v-4h2v4z"/> +</vector> diff --git a/core/src/main/res/drawable/white_circle.xml b/core/src/main/res/drawable/white_circle.xml deleted file mode 100644 index 597b70a2d..000000000 --- a/core/src/main/res/drawable/white_circle.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<shape xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="oval" > - - <solid android:color="@color/white" /> - - <size - android:height="4dp" - android:width="4dp" /> - -</shape>
\ No newline at end of file diff --git a/core/src/main/res/values-id/strings.xml b/core/src/main/res/values-in/strings.xml index 2f1ffecea..2f1ffecea 100644 --- a/core/src/main/res/values-id/strings.xml +++ b/core/src/main/res/values-in/strings.xml diff --git a/core/src/main/res/values-land/styles.xml b/core/src/main/res/values-land/styles.xml deleted file mode 100644 index d964ef3d4..000000000 --- a/core/src/main/res/values-land/styles.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <style name="Theme.MediaPlayer" parent="@style/Theme.AppCompat.Light"> - <item name="android:windowActionBarOverlay">true</item> - </style> -</resources>
\ No newline at end of file diff --git a/core/src/main/res/values-large/dimens.xml b/core/src/main/res/values-large/dimens.xml index 2da283c5b..2d107eef0 100644 --- a/core/src/main/res/values-large/dimens.xml +++ b/core/src/main/res/values-large/dimens.xml @@ -4,5 +4,4 @@ <dimen name="thumbnail_length">170dp</dimen> <dimen name="thumbnail_length_queue_item">64dp</dimen> <dimen name="thumbnail_length_downloaded_item">64dp</dimen> - <dimen name="queue_title_text_size">@dimen/text_size_medium</dimen> </resources>
\ No newline at end of file diff --git a/core/src/main/res/values-v16/styles.xml b/core/src/main/res/values-v16/styles.xml index a92790152..947e43f38 100644 --- a/core/src/main/res/values-v16/styles.xml +++ b/core/src/main/res/values-v16/styles.xml @@ -6,12 +6,4 @@ <item name="android:textColor">?android:attr/textColorPrimary</item> <item name="android:fontFamily">sans-serif-light</item> </style> - - <style name="AntennaPod.Dialog.Title" parent="@android:style/TextAppearance.Medium"> - <item name="android:textSize">@dimen/text_size_medium</item> - <item name="android:textColor">@color/holo_blue_light</item> - <item name="android:maxLines">2</item> - <item name="android:ellipsize">end</item> - <item name="android:fontFamily">sans-serif-light</item> - </style> </resources>
\ No newline at end of file diff --git a/core/src/main/res/values-v19/colors.xml b/core/src/main/res/values-v19/colors.xml index 16c065d75..4154280e8 100644 --- a/core/src/main/res/values-v19/colors.xml +++ b/core/src/main/res/values-v19/colors.xml @@ -1,5 +1,4 @@ <?xml version="1.0" encoding="utf-8"?> <resources> <color name="selection_background_color_dark">#484B4D</color> - <color name="selection_background_color_light">#E3E3E3</color> </resources>
\ No newline at end of file diff --git a/core/src/main/res/values/arrays.xml b/core/src/main/res/values/arrays.xml index 0eaf0e5e7..5e7eab1ea 100644 --- a/core/src/main/res/values/arrays.xml +++ b/core/src/main/res/values/arrays.xml @@ -156,19 +156,15 @@ <item>4.00</item> </string-array> - <string-array name="autodl_select_networks_default_entries"> - <item>N/A</item> - </string-array> - <string-array name="autodl_select_networks_default_values"> - <item>0</item> - </string-array> - <string-array name="theme_options"> + <item>@string/pref_theme_title_use_system</item> <item>@string/pref_theme_title_light</item> <item>@string/pref_theme_title_dark</item> <item>@string/pref_theme_title_trueblack</item> </string-array> + <string-array name="theme_values"> + <item>system</item> <item>0</item> <item>1</item> <item>2</item> diff --git a/core/src/main/res/values/attrs.xml b/core/src/main/res/values/attrs.xml index 5b0bf5717..530b40d46 100644 --- a/core/src/main/res/values/attrs.xml +++ b/core/src/main/res/values/attrs.xml @@ -9,6 +9,7 @@ <attr name="av_fast_forward" format="reference"/> <attr name="av_pause" format="reference"/> <attr name="av_play" format="reference"/> + <attr name="av_speed" format="reference"/> <attr name="av_rewind" format="reference"/> <attr name="content_discard" format="reference"/> <attr name="content_new" format="reference"/> @@ -56,9 +57,9 @@ <attr name="ic_cast_disconnect" format="reference"/> <attr name="ic_swap" format="reference"/> <attr name="ic_cellphone_text" format="reference"/> - <attr name="ic_question_answer" format="reference" /> + <attr name="ic_questionmark" format="reference" /> + <attr name="ic_chat" format="reference"/> <attr name="ic_bug" format="reference" /> - <attr name="ic_known_issues" format="reference" /> <attr name="master_switch_background" format="color"/> <attr name="currently_playing_background" format="color"/> <attr name="ic_bookmark" format="reference"/> diff --git a/core/src/main/res/values/colors.xml b/core/src/main/res/values/colors.xml index 0e4533977..fea7da4a4 100644 --- a/core/src/main/res/values/colors.xml +++ b/core/src/main/res/values/colors.xml @@ -2,22 +2,16 @@ <resources> <color name="white">#FFFFFF</color> - <color name="gray">#808080</color> <color name="grey600">#757575</color> <color name="light_gray">#bfbfbf</color> <color name="black">#000000</color> <color name="holo_blue_light">#33B5E5</color> <color name="holo_blue_dark">#0099CC</color> - <color name="ics_gray">#858585</color> - <color name="actionbar_gray">#DDDDDD</color> <color name="download_success_green">#669900</color> <color name="download_failed_red">#CC0000</color> <color name="status_progress">#E033B5E5</color> - <color name="status_playing">#E0EE5F52</color> <color name="overlay_dark">#2C2C2C</color> <color name="overlay_light">#FFFFFF</color> - <color name="swipe_refresh_secondary_color_light">#EDEDED</color> - <color name="swipe_refresh_secondary_color_dark">#060708</color> <color name="new_indicator_green">#669900</color> <color name="image_readability_tint">#80000000</color> <color name="feed_image_bg">#50000000</color> diff --git a/core/src/main/res/values/dimens.xml b/core/src/main/res/values/dimens.xml index cdde0027d..02c398b62 100644 --- a/core/src/main/res/values/dimens.xml +++ b/core/src/main/res/values/dimens.xml @@ -10,7 +10,6 @@ <dimen name="text_size_navdrawer">16sp</dimen> <dimen name="text_size_medium">18sp</dimen> <dimen name="text_size_large">22sp</dimen> - <dimen name="status_indicator_width">32dp</dimen> <dimen name="thumbnail_length_itemlist">64dp</dimen> <dimen name="thumbnail_length_queue_item">64dp</dimen> <dimen name="thumbnail_length_downloaded_item">64dp</dimen> @@ -21,7 +20,6 @@ <dimen name="drawer_width">280dp</dimen> <dimen name="listitem_iconwithtext_height">48dp</dimen> <dimen name="listitem_iconwithtext_textleftpadding">16dp</dimen> - <dimen name="listitem_iconwithtext_textverticalpadding">16dp</dimen> <dimen name="listitem_threeline_textleftpadding">16dp</dimen> <dimen name="listitem_threeline_textrightpadding">8dp</dimen> @@ -29,7 +27,6 @@ <dimen name="listitem_threeline_horizontalpadding">16dp</dimen> <dimen name="list_vertical_padding">8dp</dimen> - <dimen name="minimum_text_margin">8dp</dimen> <dimen name="listitem_icon_leftpadding">16dp</dimen> <dimen name="listitem_icon_rightpadding">16dp</dimen> diff --git a/core/src/main/res/values/integers.xml b/core/src/main/res/values/integers.xml index 33501d9fb..73d90cf98 100644 --- a/core/src/main/res/values/integers.xml +++ b/core/src/main/res/values/integers.xml @@ -1,4 +1,3 @@ <resources> - <integer name="undobar_hide_delay">5000</integer> <integer name="episode_cache_size_unlimited">-1</integer> </resources> diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index c9c6506a9..adf938d75 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -27,10 +27,8 @@ <string name="gpodnet_main_label">gpodder.net</string> <string name="gpodnet_summary">Synchronize with other devices</string> <string name="gpodnet_auth_label">gpodder.net Login</string> - <string name="free_space_label">%1$s free</string> <string name="episode_cache_full_title">Episode cache full</string> <string name="episode_cache_full_message">The episode cache limit has been reached. You can increase the cache size in the Settings.</string> - <string name="synchronizing">Synchronizing…</string> <!-- Statistics fragment --> <string name="total_time_listened_to_podcasts">Total time of podcasts played:</string> @@ -73,7 +71,6 @@ <string name="author_label">Author(s)</string> <string name="language_label">Language</string> <string name="url_label">URL</string> - <string name="podcast_settings_label">Settings</string> <string name="cover_label">Picture</string> <string name="error_label">Error</string> <string name="error_msg_prefix">An error occurred:</string> @@ -82,14 +79,9 @@ <string name="external_storage_error_msg">No external storage is available. Please make sure that external storage is mounted so that the app can work properly.</string> <string name="chapters_label">Chapters</string> <string name="chapter_duration">Duration: %1$s</string> - <string name="shownotes_label">Shownotes</string> <string name="description_label">Description</string> - <string name="most_recent_prefix">Most recent episode:\u0020</string> <string name="episodes_suffix">\u0020episodes</string> - <string name="length_prefix">Length:\u0020</string> - <string name="size_prefix">Size:\u0020</string> <string name="processing_label">Processing</string> - <string name="loading_label">Loading…</string> <string name="save_username_password_label">Save username and password</string> <string name="close_label">Close</string> <string name="retry_label">Retry</string> @@ -119,8 +111,6 @@ <string name="feedurl_label">Feed URL</string> <string name="etxtFeedurlHint">www.example.com/feed</string> <string name="txtvfeedurl_label">Add Podcast by URL</string> - <string name="podcastdirectories_label">Find Podcast in Directory</string> - <string name="podcastdirectories_descr">For new podcasts, you can search iTunes or fyyd, or browse gpodder.net by name, category or popularity.</string> <string name="browse_gpoddernet_label">Browse gpodder.net</string> <string name="discover">Discover</string> <string name="discover_more">more »</string> @@ -143,13 +133,13 @@ <string name="share_link_label">Share Episode URL</string> <string name="share_link_with_position_label">Share Episode URL with Position</string> <string name="share_file_label">Share File</string> + <string name="share_website_url_label">Share Website URL</string> <string name="share_feed_url_label">Share Feed URL</string> <string name="share_item_url_label">Share Media File URL</string> <string name="share_item_url_with_position_label">Share Media File URL with Position</string> <string name="feed_delete_confirmation_msg">Please confirm that you want to delete the podcast \"%1$s\" and ALL its episodes (including downloaded episodes).</string> <string name="feed_remover_msg">Removing podcast</string> <string name="load_complete_feed">Refresh complete podcast</string> - <string name="hide_episodes_title">Hide Episodes</string> <string name="batch_edit">Batch edit</string> <string name="select_all_above">Select all above</string> <string name="select_all_below">Select all below</string> @@ -174,9 +164,7 @@ </plurals> <string name="play_label">Play</string> <string name="pause_label">Pause</string> - <string name="stop_label">Stop</string> <string name="stream_label">Stream</string> - <string name="remove_label">Remove</string> <string name="delete_label">Delete</string> <string name="delete_failed">Unable to delete file. Rebooting the device could help.</string> <string name="delete_episode_label">Delete Episode</string> @@ -221,14 +209,12 @@ <!-- Download messages and labels --> <string name="download_successful">successful</string> - <string name="download_failed">failed</string> <string name="download_pending">Download pending</string> <string name="download_running">Download running</string> <string name="download_error_details">Details</string> <string name="download_error_details_message">%1$s \n\nFile URL:\n%2$s</string> <string name="download_error_device_not_found">Storage Device not found</string> <string name="download_error_insufficient_space">Insufficient Space</string> - <string name="download_error_file_error">File Error</string> <string name="download_error_http_data_error">HTTP Data Error</string> <string name="download_error_error_unknown">Unknown Error</string> <string name="download_error_parser_exception">Parser Exception</string> @@ -238,7 +224,6 @@ <string name="download_error_unauthorized">Authentication Error</string> <string name="download_error_file_type_type">File Type Error</string> <string name="download_error_forbidden">Forbidden</string> - <string name="cancel_all_downloads_label">Cancel all downloads</string> <string name="download_canceled_msg">Download canceled</string> <string name="download_canceled_autodownload_enabled_msg">Download canceled\nDisabled <i>Auto Download</i> for this item</string> <string name="download_report_title">Downloads completed with error(s)</string> @@ -257,7 +242,6 @@ <string name="download_log_title_unknown">Unknown Title</string> <string name="download_type_feed">Feed</string> <string name="download_type_media">Media file</string> - <string name="download_type_image">Image</string> <string name="download_request_error_dialog_message_prefix">An error occurred when trying to download the file:\u0020</string> <string name="null_value_podcast_error">No podcast was provided that could be shown.</string> <string name="authentication_notification_title">Authentication required</string> @@ -285,7 +269,6 @@ <string name="position_default_label" translate="false">00:00:00</string> <string name="player_buffering_msg">Buffering</string> <string name="player_go_to_picture_in_picture">Picture-in-picture mode</string> - <string name="playbackservice_notification_title">Playing podcast</string> <string name="unknown_media_key">AntennaPod - Unknown media key: %1$d</string> <!-- Queue operations --> @@ -293,9 +276,10 @@ <string name="unlock_queue">Unlock Queue</string> <string name="queue_locked">Queue locked</string> <string name="queue_unlocked">Queue unlocked</string> + <string name="queue_lock_warning">If you lock the queue, you can no longer swipe or reorder episodes.</string> + <string name="checkbox_do_not_show_again">Do not show again</string> <string name="clear_queue_label">Clear Queue</string> <string name="undo">Undo</string> - <string name="removed_from_queue">Item removed</string> <string name="move_to_top_label">Move to top</string> <string name="move_to_bottom_label">Move to bottom</string> <string name="sort">Sort</string> @@ -322,7 +306,6 @@ <!-- Empty list labels --> <string name="no_items_header_label">No queued episodes</string> <string name="no_items_label">Add an episode by downloading it, or long press an episode and select \"Add to queue\".</string> - <string name="no_feeds_label">You haven\'t subscribed to any podcasts yet.</string> <string name="no_shownotes_label">This episode has no shownotes.</string> <string name="no_run_downloads_head_label">No downloads running</string> <string name="no_run_downloads_label">You can download episodes on the podcast details screen.</string> @@ -344,7 +327,6 @@ <!-- Preferences --> <string name="storage_pref">Storage</string> <string name="project_pref">Project</string> - <string name="other_pref">Other</string> <string name="about_pref">About</string> <string name="queue_label">Queue</string> <string name="integrations_label">Integrations</string> @@ -388,9 +370,7 @@ <string name="pref_autoUpdateIntervallOrTime_TimeOfDay">Set Time of Day</string> <string name="pref_autoUpdateIntervallOrTime_every">every %1$s</string> <string name="pref_autoUpdateIntervallOrTime_at">at %1$s</string> - <string name="pref_downloadMediaOnWifiOnly_sum">Download media files only over WiFi</string> <string name="pref_followQueue_title">Continuous Playback</string> - <string name="pref_downloadMediaOnWifiOnly_title">WiFi media download</string> <string name="pref_pauseOnHeadsetDisconnect_title">Headphones Disconnect</string> <string name="pref_unpauseOnHeadsetReconnect_title">Headphones Reconnect</string> <string name="pref_unpauseOnBluetoothReconnect_title">Bluetooth Reconnect</string> @@ -401,11 +381,8 @@ <string name="pref_mobileUpdate_auto_download">Auto download</string> <string name="pref_mobileUpdate_episode_download">Episode download</string> <string name="pref_mobileUpdate_streaming">Streaming</string> - <string name="refreshing_label">Refreshing</string> <string name="user_interface_label">User Interface</string> <string name="pref_set_theme_title">Select Theme</string> - <string name="pref_nav_drawer_title">Customize Navigation Drawer</string> - <string name="pref_nav_drawer_sum">Customize the appearance of the navigation drawer.</string> <string name="pref_nav_drawer_items_title">Set Navigation Drawer items</string> <string name="pref_nav_drawer_items_sum">Change which items appear in the navigation drawer.</string> <string name="pref_nav_drawer_feed_order_title">Set Subscription Order</string> @@ -417,13 +394,14 @@ <string name="pref_automatic_download_sum">Configure the automatic download of episodes.</string> <string name="pref_autodl_wifi_filter_title">Enable Wi-Fi filter</string> <string name="pref_autodl_wifi_filter_sum">Allow automatic download only for selected Wi-Fi networks.</string> - <string name="pref_autodl_allow_on_mobile_title">Download on mobile connection</string> - <string name="pref_autodl_allow_on_mobile_sum">Allow automatic download over the mobile data connection.</string> + <string name="autodl_wifi_filter_permission_title">Permission required</string> + <string name="autodl_wifi_filter_permission_message">Location permission is required for Wi-Fi filter. Tap to grant the permission.</string> <string name="pref_automatic_download_on_battery_title">Download when not charging</string> <string name="pref_automatic_download_on_battery_sum">Allow automatic download when the battery is not charging</string> <string name="pref_parallel_downloads_title">Parallel Downloads</string> <string name="pref_episode_cache_title">Episode Cache</string> <string name="pref_episode_cache_summary">Total number of downloaded episodes cached on the device. Automatic download will be suspended if this number is reached.</string> + <string name="pref_theme_title_use_system">Use system theme</string> <string name="pref_theme_title_light">Light</string> <string name="pref_theme_title_dark">Dark</string> <string name="pref_theme_title_trueblack">Black (AMOLED ready)</string> @@ -443,7 +421,6 @@ <string name="pref_gpodnet_full_sync_sum">Sync all subscriptions and episode states with gpodder.net.</string> <string name="pref_gpodnet_sync_sum_last_sync_line">Last sync attempt: %1$s (%2$s)</string> <string name="pref_gpodnet_sync_started">Sync started</string> - <string name="pref_gpodnet_full_sync_started">Full sync started</string> <string name="pref_gpodnet_login_status"><![CDATA[Logged in as <i>%1$s</i> with device <i>%2$s</i>]]></string> <string name="pref_gpodnet_notifications_title">Show sync error notifications</string> <string name="pref_gpodnet_notifications_sum">This setting does not apply to authentication errors.</string> @@ -475,16 +452,17 @@ <string name="pref_smart_mark_as_played_disabled">Disabled</string> <string name="pref_image_cache_size_title">Image Cache Size</string> <string name="pref_image_cache_size_sum">Size of the disk cache for images.</string> - <string name="crash_report_title">Crash Report</string> - <string name="crash_report_sum">Send the latest crash report via e-mail</string> - <string name="send_email">Send e-mail</string> + <string name="view_mailing_list">View mailing list</string> + <string name="bug_report_title">Report bug</string> + <string name="open_bug_tracker">Open bug tracker</string> + <string name="copy_to_clipboard">Copy to clipboard</string> + <string name="copied_to_clipboard">Copied to clipboard</string> <string name="experimental_pref">Experimental</string> <string name="pref_media_player_message">Select which media player to use to play files</string> <string name="pref_current_value">Current value: %1$s</string> <string name="pref_proxy_title">Proxy</string> <string name="pref_proxy_sum">Set a network proxy</string> - <string name="pref_faq">FAQ</string> - <string name="pref_known_issues">Known issues</string> + <string name="pref_faq">Frequently Asked Questions</string> <string name="pref_no_browser_found">No web browser found.</string> <string name="pref_cast_title">Chromecast support</string> <string name="pref_cast_message_play_flavor">Enable support for remote media playback on Cast devices (such as Chromecast, Audio Speakers or Android TV)</string> @@ -525,21 +503,16 @@ <string name="no_results_for_query">No results were found for \"%1$s\"</string> <!-- OPML import and export --> - <string name="opml_import_txtv_button_lable">OPML files allow you to move your podcasts from one podcatcher to another.</string> <string name="opml_import_option">Option %1$d</string> <string name="opml_import_explanation_1">Choose a specific file path from the local filesystem.</string> - <string name="opml_import_explanation_2">Use an external applications like Dropbox, Google Drive or your favourite file manager to open an OPML file.</string> - <string name="opml_import_explanation_3">Many applications like Google Mail, Dropbox, Google Drive and most file managers can <i>open</i> OPML files <i>with</i> AntennaPod.</string> <string name="start_import_label">Start import</string> + <string name="opml_import_explanation_3">Many applications like Google Mail, Dropbox, Google Drive and most file managers can <i>open</i> OPML files <i>with</i> AntennaPod.</string> <string name="opml_import_label">OPML Import</string> - <string name="opml_directory_error">ERROR!</string> <string name="reading_opml_label">Reading OPML file</string> <string name="opml_reader_error">An error has occurred while reading the OPML document:</string> <string name="opml_import_error_no_file">No file selected!</string> <string name="select_all_label">Select all</string> <string name="deselect_all_label">Deselect all</string> - <string name="select_options_label">Select…</string> <string name="choose_file_from_filesystem">From local filesystem</string> - <string name="choose_file_from_external_application">Use external application</string> <string name="opml_export_label">OPML export</string> <string name="html_export_label">HTML export</string> <string name="exporting_label">Exporting…</string> @@ -638,7 +611,6 @@ <!-- Online feed view --> <string name="subscribe_label">Subscribe</string> - <string name="subscribed_label">Subscribed</string> <string name="downloading_label">Downloading…</string> <!-- Content descriptions for image buttons --> @@ -761,7 +733,6 @@ <string name="cast_failed_setting_volume">Failed to set the volume</string> <string name="cast_failed_no_connection">No connection to the cast device is present</string> <string name="cast_failed_no_connection_trans">Connection to the cast device has been lost. Application is trying to re-establish the connection, if possible. Please wait for a few seconds and try again.</string> - <string name="cast_failed_perform_action">Failed to perform the action</string> <string name="cast_failed_status_request">Failed to sync up with the cast device</string> <string name="cast_failed_seek">Failed to seek to the new position on the cast device</string> <string name="cast_failed_receiver_player_error">Receiver player has encountered a severe error</string> diff --git a/core/src/main/res/values/styles.xml b/core/src/main/res/values/styles.xml index fb69e54e7..d2ba4bb50 100644 --- a/core/src/main/res/values/styles.xml +++ b/core/src/main/res/values/styles.xml @@ -23,6 +23,7 @@ <item name="av_fast_forward">@drawable/ic_fast_forward_grey600_24dp</item> <item name="av_pause">@drawable/ic_pause_grey600_24dp</item> <item name="av_play">@drawable/ic_play_arrow_grey600_24dp</item> + <item name="av_speed">@drawable/ic_playback_speed_dark</item> <item name="av_rewind">@drawable/ic_fast_rewind_grey600_24dp</item> <item name="content_discard">@drawable/ic_delete_grey600_24dp</item> <item name="content_new">@drawable/ic_add_grey600_24dp</item> @@ -68,9 +69,9 @@ <item name="ic_create_new_folder">@drawable/ic_create_new_folder_grey600_24dp</item> <item name="ic_cast_disconnect">@drawable/ic_cast_disconnect_grey600_36dp</item> <item name="ic_cellphone_text">@drawable/ic_cellphone_text_grey600_24dp</item> - <item name="ic_question_answer">@drawable/ic_forum_grey600_24dp</item> + <item name="ic_questionmark">@drawable/ic_questionmark_grey600</item> + <item name="ic_chat">@drawable/ic_chat_grey600</item> <item name="ic_bug">@drawable/ic_bug_grey600_24dp</item> - <item name="ic_known_issues">@drawable/ic_format_list_bulleted_grey600_24dp</item> <item name="ic_bookmark">@drawable/ic_bookmark_grey600_24dp</item> <item name="batch_edit_fab_icon">@drawable/ic_fab_edit_white</item> <item name="master_switch_background">@color/master_switch_background_light</item> @@ -108,6 +109,7 @@ <item name="av_fast_forward">@drawable/ic_fast_forward_white_24dp</item> <item name="av_pause">@drawable/ic_pause_white_24dp</item> <item name="av_play">@drawable/ic_play_arrow_white_24dp</item> + <item name="av_speed">@drawable/ic_playback_speed_white</item> <item name="av_rewind">@drawable/ic_fast_rewind_white_24dp</item> <item name="content_discard">@drawable/ic_delete_white_24dp</item> <item name="content_new">@drawable/ic_add_white_24dp</item> @@ -153,9 +155,9 @@ <item name="ic_create_new_folder">@drawable/ic_create_new_folder_white_24dp</item> <item name="ic_cast_disconnect">@drawable/ic_cast_disconnect_white_36dp</item> <item name="ic_cellphone_text">@drawable/ic_cellphone_text_white_24dp</item> - <item name="ic_question_answer">@drawable/ic_baseline_question_answer_white_24dp</item> + <item name="ic_questionmark">@drawable/ic_questionmark_white</item> + <item name="ic_chat">@drawable/ic_chat_white</item> <item name="ic_bug">@drawable/ic_bug_white_24dp</item> - <item name="ic_known_issues">@drawable/ic_format_list_bulleted_white_24dp</item> <item name="ic_bookmark">@drawable/ic_bookmark_white_24dp</item> <item name="batch_edit_fab_icon">@drawable/ic_fab_edit_white</item> <item name="master_switch_background">@color/master_switch_background_dark</item> @@ -258,13 +260,6 @@ <item name="android:ellipsize">end</item> </style> - <style name="AntennaPod.Dialog.Title" parent="@android:style/TextAppearance.Medium"> - <item name="android:textSize">@dimen/text_size_medium</item> - <item name="android:textColor">?android:attr/textColorPrimary</item> - <item name="android:maxLines">2</item> - <item name="android:ellipsize">end</item> - </style> - <style name="AntennaPod.TextView.UnreadIndicator" parent="@android:style/TextAppearance.Small"> <item name="android:textSize">@dimen/text_size_micro</item> <item name="android:textColor">@color/new_indicator_green</item> @@ -276,16 +271,6 @@ <item name="textAllCaps">false</item> </style> - <style name="Divider"> - <item name="android:layout_width">match_parent</item> - <item name="android:layout_height">1dp</item> - <item name="android:layout_marginTop">8dp</item> - <item name="android:layout_marginLeft">16dp</item> - <item name="android:layout_marginRight">16dp</item> - <item name="android:layout_marginBottom">8dp</item> - <item name="android:background">?android:attr/listDivider</item> - </style> - <style name="AntennaPod.Dialog.Light" parent="Theme.AppCompat.Light.Dialog"> <item name="colorAccent">@color/holo_blue_light</item> </style> diff --git a/core/src/play/java/de/danoeh/antennapod/core/ClientConfig.java b/core/src/play/java/de/danoeh/antennapod/core/ClientConfig.java index 244fb0254..800222ada 100644 --- a/core/src/play/java/de/danoeh/antennapod/core/ClientConfig.java +++ b/core/src/play/java/de/danoeh/antennapod/core/ClientConfig.java @@ -1,6 +1,7 @@ package de.danoeh.antennapod.core; import android.content.Context; +import android.util.Log; import de.danoeh.antennapod.core.cast.CastManager; import de.danoeh.antennapod.core.preferences.PlaybackPreferences; @@ -15,6 +16,8 @@ import de.danoeh.antennapod.core.util.exception.RxJavaErrorHandlerSetup; * Apps using the core module of AntennaPod should register implementations of all interfaces here. */ public class ClientConfig { + private static final String TAG = "ClientConfig"; + private ClientConfig(){} /** @@ -44,7 +47,15 @@ public class ClientConfig { UserPreferences.init(context); PlaybackPreferences.init(context); NetworkUtils.init(context); - CastManager.init(context); + // Don't initialize Cast-related logic unless it is enabled, to avoid the unnecessary + // Google Play Service usage. + // Down side: when the user decides to enable casting, AntennaPod needs to be restarted + // for it to take effect. + if (UserPreferences.isCastEnabled()) { + CastManager.init(context); + } else { + Log.v(TAG, "Cast is disabled. All Cast-related initialization will be skipped."); + } SleepTimerPreferences.init(context); RxJavaErrorHandlerSetup.setupRxJavaErrorHandler(); initialized = true; diff --git a/core/src/play/java/de/danoeh/antennapod/core/cast/CastManager.java b/core/src/play/java/de/danoeh/antennapod/core/cast/CastManager.java index 5198a76bd..414a7840c 100644 --- a/core/src/play/java/de/danoeh/antennapod/core/cast/CastManager.java +++ b/core/src/play/java/de/danoeh/antennapod/core/cast/CastManager.java @@ -163,6 +163,10 @@ public class CastManager extends BaseCastManager implements OnFailedListener { return INSTANCE; } + public static boolean isInitialized() { + return INSTANCE != null; + } + /** * Returns the active {@link RemoteMediaPlayer} instance. Since there are a number of media * control APIs that this library do not provide a wrapper for, client applications can call diff --git a/core/src/play/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceFlavorHelper.java b/core/src/play/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceFlavorHelper.java index 7ab1be380..79c71f164 100644 --- a/core/src/play/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceFlavorHelper.java +++ b/core/src/play/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceFlavorHelper.java @@ -56,11 +56,18 @@ public class PlaybackServiceFlavorHelper { PlaybackServiceFlavorHelper(Context context, PlaybackService.FlavorHelperCallback callback) { this.callback = callback; + if (!CastManager.isInitialized()) { + return; + } mediaRouter = MediaRouter.getInstance(context.getApplicationContext()); setCastConsumer(context); } void initializeMediaPlayer(Context context) { + if (!CastManager.isInitialized()) { + callback.setMediaPlayer(new LocalPSMP(context, callback.getMediaPlayerCallback())); + return; + } castManager = CastManager.getInstance(); castManager.addCastConsumer(castConsumer); boolean isCasting = castManager.isConnected(); @@ -77,10 +84,16 @@ public class PlaybackServiceFlavorHelper { } void removeCastConsumer() { + if (!CastManager.isInitialized()) { + return; + } castManager.removeCastConsumer(castConsumer); } boolean castDisconnect(boolean castDisconnect) { + if (!CastManager.isInitialized()) { + return false; + } if (castDisconnect) { castManager.disconnect(); } @@ -88,6 +101,9 @@ public class PlaybackServiceFlavorHelper { } boolean onMediaPlayerInfo(Context context, int code, @StringRes int resourceId) { + if (!CastManager.isInitialized()) { + return false; + } switch (code) { case RemotePSMP.CAST_ERROR: callback.sendNotificationBroadcast(PlaybackService.NOTIFICATION_TYPE_SHOW_TOAST, resourceId); @@ -218,6 +234,9 @@ public class PlaybackServiceFlavorHelper { } void registerWifiBroadcastReceiver() { + if (!CastManager.isInitialized()) { + return; + } if (wifiBroadcastReceiver != null) { return; } @@ -243,6 +262,9 @@ public class PlaybackServiceFlavorHelper { } void unregisterWifiBroadcastReceiver() { + if (!CastManager.isInitialized()) { + return; + } if (wifiBroadcastReceiver != null) { callback.unregisterReceiver(wifiBroadcastReceiver); wifiBroadcastReceiver = null; @@ -250,6 +272,9 @@ public class PlaybackServiceFlavorHelper { } boolean onSharedPreference(String key) { + if (!CastManager.isInitialized()) { + return false; + } if (UserPreferences.PREF_CAST_ENABLED.equals(key)) { if (!UserPreferences.isCastEnabled()) { if (castManager.isConnecting() || castManager.isConnected()) { @@ -263,6 +288,9 @@ public class PlaybackServiceFlavorHelper { } void sessionStateAddActionForWear(PlaybackStateCompat.Builder sessionState, String actionName, CharSequence name, int icon) { + if (!CastManager.isInitialized()) { + return; + } PlaybackStateCompat.CustomAction.Builder actionBuilder = new PlaybackStateCompat.CustomAction.Builder(actionName, name, icon); Bundle actionExtras = new Bundle(); @@ -273,6 +301,9 @@ public class PlaybackServiceFlavorHelper { } void mediaSessionSetExtraForWear(MediaSessionCompat mediaSession) { + if (!CastManager.isInitialized()) { + return; + } Bundle sessionExtras = new Bundle(); sessionExtras.putBoolean(MediaControlConstants.EXTRA_RESERVE_SLOT_SKIP_TO_PREVIOUS, true); sessionExtras.putBoolean(MediaControlConstants.EXTRA_RESERVE_SLOT_SKIP_TO_NEXT, true); |