diff options
10 files changed, 76 insertions, 158 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/StoragePreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/StoragePreferencesFragment.java index 42b0cb96f..e5617b8ea 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/StoragePreferencesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/StoragePreferencesFragment.java @@ -1,7 +1,6 @@ package de.danoeh.antennapod.fragment.preferences; import android.os.Bundle; -import androidx.appcompat.app.AlertDialog; import androidx.preference.PreferenceFragmentCompat; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.PreferenceActivity; @@ -43,22 +42,6 @@ public class StoragePreferencesFragment extends PreferenceFragmentCompat { return true; } ); - findPreference(UserPreferences.PREF_IMAGE_CACHE_SIZE).setOnPreferenceChangeListener( - (preference, o) -> { - if (o instanceof String) { - int newValue = Integer.parseInt((String) o) * 1024 * 1024; - if (newValue != UserPreferences.getImageCacheSize()) { - AlertDialog.Builder dialog = new AlertDialog.Builder(getActivity()); - dialog.setTitle(android.R.string.dialog_alert_title); - dialog.setMessage(R.string.pref_restart_required); - dialog.setPositiveButton(android.R.string.ok, null); - dialog.show(); - } - return true; - } - return false; - } - ); findPreference(PREF_IMPORT_EXPORT).setOnPreferenceClickListener( preference -> { ((PreferenceActivity) getActivity()).openScreen(R.xml.preferences_import_export); diff --git a/app/src/main/res/layout/episode_filter_dialog.xml b/app/src/main/res/layout/episode_filter_dialog.xml index 43d074bfb..9661a8e72 100644 --- a/app/src/main/res/layout/episode_filter_dialog.xml +++ b/app/src/main/res/layout/episode_filter_dialog.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" @@ -7,7 +8,7 @@ <RadioGroup android:id="@+id/radio_filter_group" - android:layout_width="fill_parent" + android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> @@ -22,19 +23,21 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/episode_filters_exclude" /> + </RadioGroup> <EditText android:id="@+id/etxtEpisodeFilterText" - android:layout_width="fill_parent" + android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" - android:lines="8" - android:minLines="1" - android:maxLines="20" - android:scrollbars="vertical" - android:hint="@string/episode_filters_hint" + android:cursorVisible="true" android:focusable="true" android:focusableInTouchMode="true" - android:cursorVisible="true" /> + android:hint="@string/episode_filters_hint" + android:lines="8" + android:maxLines="20" + android:minLines="1" + android:scrollbars="vertical" /> + </LinearLayout> diff --git a/app/src/main/res/layout/subscription_item.xml b/app/src/main/res/layout/subscription_item.xml index 7fa738f12..ec918fdac 100644 --- a/app/src/main/res/layout/subscription_item.xml +++ b/app/src/main/res/layout/subscription_item.xml @@ -2,32 +2,32 @@ <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" - xmlns:tools="http://schemas.android.com/tools" xmlns:squareImageView="http://schemas.android.com/apk/de.danoeh.antennapod" + xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:foreground="?attr/selectableItemBackground"> <de.danoeh.antennapod.ui.common.SquareImageView android:id="@+id/imgvCover" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:scaleType="fitCenter" + android:layout_width="match_parent" + android:layout_height="match_parent" android:background="@color/non_square_icon_background" - tools:src="@mipmap/ic_launcher_round" - squareImageView:direction="width"/> + android:scaleType="fitCenter" + squareImageView:direction="width" + tools:src="@mipmap/ic_launcher_round" /> <com.joanzapata.iconify.widget.IconTextView android:id="@+id/txtvTitle" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/non_square_icon_background" - android:layout_alignLeft="@+id/imgvCover" - android:layout_alignRight="@+id/imgvCover" android:layout_alignStart="@+id/imgvCover" - android:layout_alignEnd="@+id/imgvCover" + android:layout_alignLeft="@+id/imgvCover" android:layout_alignTop="@+id/imgvCover" + android:layout_alignEnd="@+id/imgvCover" + android:layout_alignRight="@+id/imgvCover" android:layout_alignBottom="@+id/imgvCover" + android:background="@color/non_square_icon_background" android:ellipsize="end" android:gravity="center" android:textColor="?android:attr/textColorPrimary" @@ -37,12 +37,13 @@ android:id="@+id/triangleCountView" android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_alignParentRight="true" - android:layout_alignParentEnd="true" android:layout_alignParentTop="true" + android:layout_alignParentEnd="true" + android:layout_alignParentRight="true" app:backgroundColor="?attr/colorSecondary" app:corner="rightTop" app:primaryText="Test" app:primaryTextColor="?attr/colorOnSecondary" app:primaryTextSize="12sp" /> + </RelativeLayout> diff --git a/app/src/main/res/xml/preferences_storage.xml b/app/src/main/res/xml/preferences_storage.xml index d3d570e6c..89e8c4cf5 100644 --- a/app/src/main/res/xml/preferences_storage.xml +++ b/app/src/main/res/xml/preferences_storage.xml @@ -6,13 +6,6 @@ <Preference android:title="@string/choose_data_directory" android:key="prefChooseDataDir"/> - <ListPreference - android:entryValues="@array/image_cache_size_values" - android:entries="@array/image_cache_size_options" - android:title="@string/pref_image_cache_size_title" - android:key="prefImageCacheSize" - android:summary="@string/pref_image_cache_size_sum" - android:defaultValue="100"/> <SwitchPreferenceCompat android:defaultValue="false" android:enabled="true" diff --git a/core/src/main/java/de/danoeh/antennapod/core/glide/ApGlideModule.java b/core/src/main/java/de/danoeh/antennapod/core/glide/ApGlideModule.java index b3adc567e..8ad04cb47 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/glide/ApGlideModule.java +++ b/core/src/main/java/de/danoeh/antennapod/core/glide/ApGlideModule.java @@ -1,6 +1,8 @@ package de.danoeh.antennapod.core.glide; +import android.annotation.SuppressLint; import android.content.Context; +import android.util.Log; import androidx.annotation.NonNull; import com.bumptech.glide.Glide; @@ -16,7 +18,6 @@ import de.danoeh.antennapod.core.util.EmbeddedChapterImage; import java.io.InputStream; import com.bumptech.glide.request.RequestOptions; -import de.danoeh.antennapod.core.preferences.UserPreferences; import java.nio.ByteBuffer; /** @@ -24,12 +25,18 @@ import java.nio.ByteBuffer; */ @GlideModule public class ApGlideModule extends AppGlideModule { + private static final String TAG = "ApGlideModule"; + private static final long MEGABYTES = 1024 * 1024; + private static final long GIGABYTES = 1024 * 1024 * 1024; @Override public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) { builder.setDefaultRequestOptions(new RequestOptions().format(DecodeFormat.PREFER_ARGB_8888)); - builder.setDiskCache(new InternalCacheDiskCacheFactory(context, - UserPreferences.getImageCacheSize())); + @SuppressLint("UsableSpace") + long spaceAvailable = context.getCacheDir().getUsableSpace(); + long imageCacheSize = (spaceAvailable > 2 * GIGABYTES) ? (250 * MEGABYTES) : (50 * MEGABYTES); + Log.d(TAG, "Free space on cache dir: " + spaceAvailable + ", using image cache size: " + imageCacheSize); + builder.setDiskCache(new InternalCacheDiskCacheFactory(context, imageCacheSize)); } @Override 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 63414800d..76dfab169 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 @@ -114,7 +114,6 @@ public class UserPreferences { // Other private static final String PREF_DATA_FOLDER = "prefDataFolder"; - public static final String PREF_IMAGE_CACHE_SIZE = "prefImageCacheSize"; public static final String PREF_DELETE_REMOVES_FROM_QUEUE = "prefDeleteRemovesFromQueue"; public static final String PREF_USAGE_COUNTING_DATE = "prefUsageCounting"; @@ -127,8 +126,6 @@ public class UserPreferences { private static final String PREF_FAST_FORWARD_SECS = "prefFastForwardSecs"; private static final String PREF_REWIND_SECS = "prefRewindSecs"; private static final String PREF_QUEUE_LOCKED = "prefQueueLocked"; - private static final String IMAGE_CACHE_DEFAULT_VALUE = "100"; - private static final int IMAGE_CACHE_SIZE_MINIMUM = 20; private static final String PREF_LEFT_VOLUME = "prefLeftVolume"; private static final String PREF_RIGHT_VOLUME = "prefRightVolume"; @@ -596,18 +593,6 @@ public class UserPreferences { return Build.VERSION.SDK_INT < 29 && prefs.getBoolean(PREF_ENABLE_AUTODL_WIFI_FILTER, false); } - public static int getImageCacheSize() { - String cacheSizeString = prefs.getString(PREF_IMAGE_CACHE_SIZE, IMAGE_CACHE_DEFAULT_VALUE); - int cacheSizeInt = Integer.parseInt(cacheSizeString); - // if the cache size is too small the user won't get any images at all - // that's bad, force it back to the default. - if (cacheSizeInt < IMAGE_CACHE_SIZE_MINIMUM) { - prefs.edit().putString(PREF_IMAGE_CACHE_SIZE, IMAGE_CACHE_DEFAULT_VALUE).apply(); - cacheSizeInt = Integer.parseInt(IMAGE_CACHE_DEFAULT_VALUE); - } - return cacheSizeInt * 1024 * 1024; - } - public static int getFastForwardSecs() { return prefs.getInt(PREF_FAST_FORWARD_SECS, 30); } 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 679d8c3b6..2da06e226 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 @@ -13,7 +13,6 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.res.Configuration; -import android.graphics.Bitmap; import android.media.AudioManager; import android.media.MediaPlayer; import android.net.Uri; @@ -41,10 +40,6 @@ import android.view.SurfaceHolder; import android.webkit.URLUtil; import android.widget.Toast; -import com.bumptech.glide.Glide; -import com.bumptech.glide.request.RequestOptions; -import com.bumptech.glide.request.target.Target; - import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -63,7 +58,6 @@ import de.danoeh.antennapod.model.feed.FeedItem; import de.danoeh.antennapod.model.feed.FeedMedia; import de.danoeh.antennapod.model.feed.FeedPreferences; import de.danoeh.antennapod.model.playback.MediaType; -import de.danoeh.antennapod.core.glide.ApGlideSettings; import de.danoeh.antennapod.core.preferences.PlaybackPreferences; import de.danoeh.antennapod.core.preferences.SleepTimerPreferences; import de.danoeh.antennapod.core.preferences.UserPreferences; @@ -72,7 +66,6 @@ import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.storage.FeedSearcher; -import de.danoeh.antennapod.core.feed.util.ImageResourceUtils; import de.danoeh.antennapod.core.sync.SyncService; import de.danoeh.antennapod.core.util.FeedItemUtil; import de.danoeh.antennapod.core.util.IntentUtils; @@ -1280,81 +1273,43 @@ public class PlaybackService extends MediaBrowserServiceCompat { (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)); } - /** - * Used by updateMediaSessionMetadata to load notification data in another thread. - */ - private Thread mediaSessionSetupThread; - private void updateMediaSessionMetadata(final Playable p) { if (p == null || mediaSession == null) { return; } - if (mediaSessionSetupThread != null) { - mediaSessionSetupThread.interrupt(); - } - - Runnable mediaSessionSetupTask = () -> { - MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder(); - builder.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, p.getFeedTitle()); - builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, p.getEpisodeTitle()); - builder.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, p.getFeedTitle()); - builder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, p.getDuration()); - builder.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, p.getEpisodeTitle()); - builder.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE, p.getFeedTitle()); - - String imageLocation = p.getImageLocation(); - - if (!TextUtils.isEmpty(imageLocation)) { - if (UserPreferences.setLockscreenBackground()) { - Bitmap art; - builder.putString(MediaMetadataCompat.METADATA_KEY_ART_URI, imageLocation); - try { - art = Glide.with(this) - .asBitmap() - .load(imageLocation) - .apply(RequestOptions.diskCacheStrategyOf(ApGlideSettings.AP_DISK_CACHE_STRATEGY)) - .submit(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) - .get(); - builder.putBitmap(MediaMetadataCompat.METADATA_KEY_ART, art); - } catch (Throwable tr1) { - try { - art = Glide.with(this) - .asBitmap() - .load(ImageResourceUtils.getFallbackImageLocation(p)) - .apply(RequestOptions.diskCacheStrategyOf(ApGlideSettings.AP_DISK_CACHE_STRATEGY)) - .submit(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) - .get(); - builder.putBitmap(MediaMetadataCompat.METADATA_KEY_ART, art); - } catch (Throwable tr2) { - Log.e(TAG, Log.getStackTraceString(tr2)); - } - } - } else if (isCasting) { - // In the absence of metadata art, the controller dialog takes care of creating it. - builder.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON_URI, imageLocation); - } - } - if (!Thread.currentThread().isInterrupted() && stateManager.hasReceivedValidStartCommand()) { - mediaSession.setSessionActivity(PendingIntent.getActivity(this, R.id.pending_intent_player_activity, - PlaybackService.getPlayerActivityIntent(this), PendingIntent.FLAG_UPDATE_CURRENT)); - try { - mediaSession.setMetadata(builder.build()); - } catch (OutOfMemoryError e) { - Log.e(TAG, "Setting media session metadata", e); - builder.putBitmap(MediaMetadataCompat.METADATA_KEY_ART, null); - mediaSession.setMetadata(builder.build()); - } - } - }; - mediaSessionSetupThread = new Thread(mediaSessionSetupTask); - mediaSessionSetupThread.start(); + MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder(); + builder.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, p.getFeedTitle()); + builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, p.getEpisodeTitle()); + builder.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, p.getFeedTitle()); + builder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, p.getDuration()); + builder.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, p.getEpisodeTitle()); + builder.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE, p.getFeedTitle()); + + if (UserPreferences.setLockscreenBackground() && notificationBuilder.isIconCached()) { + builder.putBitmap(MediaMetadataCompat.METADATA_KEY_ART, notificationBuilder.getCachedIcon()); + } else if (isCasting && !TextUtils.isEmpty(p.getImageLocation())) { + // In the absence of metadata art, the controller dialog takes care of creating it. + builder.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON_URI, p.getImageLocation()); + } + + if (stateManager.hasReceivedValidStartCommand()) { + mediaSession.setSessionActivity(PendingIntent.getActivity(this, R.id.pending_intent_player_activity, + PlaybackService.getPlayerActivityIntent(this), PendingIntent.FLAG_UPDATE_CURRENT)); + try { + mediaSession.setMetadata(builder.build()); + } catch (OutOfMemoryError e) { + Log.e(TAG, "Setting media session metadata", e); + builder.putBitmap(MediaMetadataCompat.METADATA_KEY_ART, null); + mediaSession.setMetadata(builder.build()); + } + } } /** * Used by setupNotification to load notification data in another thread. */ - private Thread notificationSetupThread; + private Thread playableIconLoaderThread; /** * Prepares notification and starts the service in the foreground. @@ -1365,8 +1320,8 @@ public class PlaybackService extends MediaBrowserServiceCompat { private synchronized void setupNotification(final Playable playable) { Log.d(TAG, "setupNotification"); - if (notificationSetupThread != null) { - notificationSetupThread.interrupt(); + if (playableIconLoaderThread != null) { + playableIconLoaderThread.interrupt(); } if (playable == null || mediaPlayer == null) { Log.d(TAG, "setupNotification: playable=" + playable); @@ -1389,14 +1344,15 @@ public class PlaybackService extends MediaBrowserServiceCompat { startForegroundIfPlaying(playerStatus); if (!notificationBuilder.isIconCached()) { - notificationSetupThread = new Thread(() -> { + playableIconLoaderThread = new Thread(() -> { Log.d(TAG, "Loading notification icon"); notificationBuilder.loadIcon(); if (!Thread.currentThread().isInterrupted()) { notificationManager.notify(R.id.notification_playing, notificationBuilder.build()); + updateMediaSessionMetadata(playable); } }); - notificationSetupThread.start(); + playableIconLoaderThread.start(); } } 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 75ebf7e10..e7dea192a 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 @@ -89,14 +89,22 @@ public class PlaybackServiceNotificationBuilder { .apply(new RequestOptions().centerCrop()) .submit(iconSize, iconSize) .get(); + } catch (InterruptedException ignore) { + Log.e(TAG, "Media icon loader was interrupted"); } catch (Throwable tr) { Log.e(TAG, "Error loading the media icon for the notification", tr); } + } catch (InterruptedException ignore) { + Log.e(TAG, "Media icon loader was interrupted"); } catch (Throwable tr) { Log.e(TAG, "Error loading the media icon for the notification", tr); } } + public Bitmap getCachedIcon() { + return icon; + } + private Bitmap getDefaultIcon() { if (defaultIcon == null) { defaultIcon = getBitmap(context, R.mipmap.ic_launcher); diff --git a/core/src/main/res/values/arrays.xml b/core/src/main/res/values/arrays.xml index 290c8635f..97b677362 100644 --- a/core/src/main/res/values/arrays.xml +++ b/core/src/main/res/values/arrays.xml @@ -270,22 +270,6 @@ <item>DURATION_LONG_SHORT</item> </string-array> - <string-array name="image_cache_size_options"> - <item>20 MiB</item> - <item>50 MiB</item> - <item>100 MiB</item> - <item>250 MiB</item> - <item>500 MiB</item> - </string-array> - - <string-array name="image_cache_size_values"> - <item>20</item> - <item>50</item> - <item>100</item> - <item>250</item> - <item>500</item> - </string-array> - <string-array name="compact_notification_buttons_options"> <item>@string/rewind_label</item> <item>@string/fast_forward_label</item> diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index 0f4b78de7..38178e0e2 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -111,7 +111,7 @@ <string name="auto_download_label">Include in auto downloads</string> <string name="auto_delete_label">Auto Delete Episode</string> <string name="feed_volume_reduction">Volume Reduction</string> - <string name="feed_volume_reduction_summary">Turn down volume for episodes of this feed: %1$s</string> + <string name="feed_volume_reduction_summary">Turn down volume for episodes of this podcast: %1$s</string> <string name="feed_volume_reduction_off">Off</string> <string name="feed_volume_reduction_light">Light</string> <string name="feed_volume_reduction_heavy">Heavy</string> @@ -484,8 +484,6 @@ <string name="enqueue_location_front">Front</string> <string name="enqueue_location_after_current">After current episode</string> <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="documentation_support">Documentation & Support</string> <string name="visit_user_forum">User forum</string> <string name="bug_report_title">Report bug</string> |