diff options
16 files changed, 140 insertions, 43 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/AdapterUtils.java b/app/src/main/java/de/danoeh/antennapod/adapter/AdapterUtils.java index 5c58d00f2..315b3a173 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/AdapterUtils.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/AdapterUtils.java @@ -49,7 +49,7 @@ class AdapterUtils { } else if (!media.isDownloaded()) { if (media.getSize() > 0) { txtvPos.setText(Converter.byteToString(media.getSize())); - } else if(NetworkUtils.isDownloadAllowed() && !media.checkedOnSizeButUnknown()) { + } else if(NetworkUtils.isEpisodeHeadDownloadAllowed() && !media.checkedOnSizeButUnknown()) { txtvPos.setText("{fa-spinner}"); Iconify.addIcons(txtvPos); NetworkUtils.getFeedMediaSizeObservable(media) diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java index 7aa9f8f21..2eff33339 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java @@ -130,7 +130,7 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR holder.txtvDuration.setText(Converter.getDurationStringLong(media.getDuration())); } else if (media.getSize() > 0) { holder.txtvDuration.setText(Converter.byteToString(media.getSize())); - } else if(NetworkUtils.isDownloadAllowed() && !media.checkedOnSizeButUnknown()) { + } else if(NetworkUtils.isEpisodeHeadDownloadAllowed() && !media.checkedOnSizeButUnknown()) { holder.txtvDuration.setText("{fa-spinner}"); Iconify.addIcons(holder.txtvDuration); NetworkUtils.getFeedMediaSizeObservable(media) diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java index d9d54ac15..382abfb32 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java @@ -252,7 +252,7 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap } else { if(media.getSize() > 0) { progressLeft.setText(Converter.byteToString(media.getSize())); - } else if(NetworkUtils.isDownloadAllowed() && !media.checkedOnSizeButUnknown()) { + } else if(NetworkUtils.isEpisodeHeadDownloadAllowed() && !media.checkedOnSizeButUnknown()) { progressLeft.setText("{fa-spinner}"); Iconify.addIcons(progressLeft); NetworkUtils.getFeedMediaSizeObservable(media) diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/DownloadActionButton.java b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/DownloadActionButton.java index 202a41161..c1559528e 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/DownloadActionButton.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/DownloadActionButton.java @@ -43,7 +43,7 @@ class DownloadActionButton extends ItemActionButton { return; } - if (NetworkUtils.isDownloadAllowed() || MobileDownloadHelper.userAllowedMobileDownloads()) { + if (NetworkUtils.isEpisodeDownloadAllowed() || MobileDownloadHelper.userAllowedMobileDownloads()) { downloadEpisode(context); } else if (MobileDownloadHelper.userChoseAddToQueue() && !isInQueue) { addEpisodeToQueue(context); diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/MobileDownloadHelper.java b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/MobileDownloadHelper.java index f8d2a139e..0d2498b60 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/MobileDownloadHelper.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/MobileDownloadHelper.java @@ -13,7 +13,7 @@ import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.storage.DownloadRequestException; -class MobileDownloadHelper { +public class MobileDownloadHelper { private static long addToQueueTimestamp; private static long allowMobileDownloadTimestamp; private static final int TEN_MINUTES_IN_MILLIS = 10 * 60 * 1000; @@ -41,6 +41,16 @@ class MobileDownloadHelper { builder.show(); } + public static void confirmMobileStreaming(final Context context, MaterialDialog.SingleButtonCallback onAllowed) { + MaterialDialog.Builder builder = new MaterialDialog.Builder(context) + .title(R.string.confirm_mobile_streaming_dialog_title) + .content(R.string.confirm_mobile_streaming_dialog_message) + .positiveText(R.string.yes) + .onPositive(onAllowed) + .negativeText(R.string.no); + builder.show(); + } + private static void addToQueue(Context context, FeedItem item) { addToQueueTimestamp = System.currentTimeMillis(); DBWriter.addQueueItem(context, item); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java index 432ada44e..e43d78ecc 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java @@ -35,6 +35,7 @@ import com.bumptech.glide.request.RequestOptions; import com.joanzapata.iconify.Iconify; import com.joanzapata.iconify.widget.IconButton; +import de.danoeh.antennapod.adapter.actionbutton.MobileDownloadHelper; import org.apache.commons.lang3.ArrayUtils; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; @@ -248,9 +249,16 @@ public class ItemFragment extends Fragment implements OnSwipeGesture { if (item.hasMedia()) { FeedMedia media = item.getMedia(); - if (!media.isDownloaded()) { - DBTasks.playMedia(getActivity(), media, true, true, true); - ((MainActivity) getActivity()).dismissChildFragment(); + if (!media.isDownloaded()) { // Stream + if (NetworkUtils.isStreamingAllowed()) { + DBTasks.playMedia(getActivity(), media, true, true, true); + ((MainActivity) getActivity()).dismissChildFragment(); + } else { + MobileDownloadHelper.confirmMobileStreaming(getContext(), (dialog, which) -> { + DBTasks.playMedia(getActivity(), media, true, true, true); + ((MainActivity) getActivity()).dismissChildFragment(); + }); + } } else { DBWriter.deleteFeedMediaOfItem(getActivity(), media.getId()); } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/AutoDownloadPreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/AutoDownloadPreferencesFragment.java index bfd94b9a2..6cba798ba 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/AutoDownloadPreferencesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/AutoDownloadPreferencesFragment.java @@ -66,7 +66,6 @@ public class AutoDownloadPreferencesFragment extends PreferenceFragmentCompat { findPreference(UserPreferences.PREF_ENABLE_AUTODL_ON_BATTERY).setEnabled(autoDownload); findPreference(UserPreferences.PREF_ENABLE_AUTODL_WIFI_FILTER).setEnabled(autoDownload); findPreference(UserPreferences.PREF_EPISODE_CLEANUP).setEnabled(autoDownload); - findPreference(UserPreferences.PREF_ENABLE_AUTODL_ON_MOBILE).setEnabled(autoDownload); setSelectedNetworksEnabled(autoDownload && UserPreferences.isEnableAutodownloadWifiFilter()); } diff --git a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceUpgrader.java b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceUpgrader.java index 5866f8715..751b6789a 100644 --- a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceUpgrader.java +++ b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceUpgrader.java @@ -2,11 +2,14 @@ package de.danoeh.antennapod.preferences; import android.content.Context; import android.content.SharedPreferences; +import android.preference.MultiSelectListPreference; import android.preference.PreferenceManager; import de.danoeh.antennapod.BuildConfig; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.util.gui.NotificationUtils; +import java.util.HashSet; + public class PreferenceUpgrader { private static final String PREF_CONFIGURED_VERSION = "configuredVersion"; private static final String PREF_NAME = "PreferenceUpgrader"; @@ -37,7 +40,7 @@ public class PreferenceUpgrader { } if (oldVersion < 1070197) { if (prefs.getBoolean("prefMobileUpdate", false)) { - prefs.edit().putString(UserPreferences.PREF_MOBILE_UPDATE, "everything").apply(); + prefs.edit().putString("prefMobileUpdateAllowed", "everything").apply(); } } if (oldVersion < 1070300) { @@ -47,6 +50,23 @@ public class PreferenceUpgrader { prefs.edit().putString(UserPreferences.PREF_MEDIA_PLAYER, UserPreferences.PREF_MEDIA_PLAYER_EXOPLAYER).apply(); } + + if (prefs.getBoolean("prefEnableAutoDownloadOnMobile", false)) { + UserPreferences.setAllowMobileAutoDownload(true); + } + switch (prefs.getString("prefMobileUpdateAllowed", "images")) { + case "everything": + UserPreferences.setAllowMobileFeedRefresh(true); + UserPreferences.setAllowMobileEpisodeDownload(true); + UserPreferences.setAllowMobileImages(true); + break; + case "images": + UserPreferences.setAllowMobileImages(true); + break; + case "nothing": + UserPreferences.setAllowMobileImages(false); + break; + } } } } diff --git a/app/src/main/res/xml/preferences_autodownload.xml b/app/src/main/res/xml/preferences_autodownload.xml index 0f3d5d024..a4967c839 100644 --- a/app/src/main/res/xml/preferences_autodownload.xml +++ b/app/src/main/res/xml/preferences_autodownload.xml @@ -31,11 +31,6 @@ android:summary="@string/pref_automatic_download_on_battery_sum" android:defaultValue="true"/> <SwitchPreference - android:key="prefEnableAutoDownloadOnMobile" - android:title="@string/pref_autodl_allow_on_mobile_title" - android:summary="@string/pref_autodl_allow_on_mobile_sum" - android:defaultValue="false"/> - <SwitchPreference android:key="prefEnableAutoDownloadWifiFilter" android:title="@string/pref_autodl_wifi_filter_title" android:summary="@string/pref_autodl_wifi_filter_sum"/> diff --git a/app/src/main/res/xml/preferences_network.xml b/app/src/main/res/xml/preferences_network.xml index 59dd0c51b..e418323a9 100644 --- a/app/src/main/res/xml/preferences_network.xml +++ b/app/src/main/res/xml/preferences_network.xml @@ -16,11 +16,11 @@ </PreferenceCategory> <PreferenceCategory android:title="@string/download_pref_details"> - <ListPreference + <MultiSelectListPreference android:defaultValue="images" android:entries="@array/mobile_update_entries" android:entryValues="@array/mobile_update_values" - android:key="prefMobileUpdateAllowed" + android:key="prefMobileUpdateTypes" android:summary="@string/pref_mobileUpdate_sum" android:title="@string/pref_mobileUpdate_title"/> <de.danoeh.antennapod.preferences.NumberPickerPreference 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 8f5f5ae1e..bcc4f533e 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 @@ -17,7 +17,9 @@ import java.io.IOException; import java.net.Proxy; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.concurrent.TimeUnit; import de.danoeh.antennapod.core.R; @@ -78,14 +80,13 @@ public class UserPreferences { // Network private static final String PREF_ENQUEUE_DOWNLOADED = "prefEnqueueDownloaded"; public static final String PREF_UPDATE_INTERVAL = "prefAutoUpdateIntervall"; - public static final String PREF_MOBILE_UPDATE = "prefMobileUpdateAllowed"; + private static final String PREF_MOBILE_UPDATE = "prefMobileUpdateTypes"; public static final String PREF_EPISODE_CLEANUP = "prefEpisodeCleanup"; public static final String PREF_PARALLEL_DOWNLOADS = "prefParallelDownloads"; public static final String PREF_EPISODE_CACHE_SIZE = "prefEpisodeCacheSize"; public static final String PREF_ENABLE_AUTODL = "prefEnableAutoDl"; public static final String PREF_ENABLE_AUTODL_ON_BATTERY = "prefEnableAutoDownloadOnBattery"; public static final String PREF_ENABLE_AUTODL_WIFI_FILTER = "prefEnableAutoDownloadWifiFilter"; - public static final String PREF_ENABLE_AUTODL_ON_MOBILE = "prefEnableAutoDownloadOnMobile"; private static final String PREF_AUTODL_SELECTED_NETWORKS = "prefAutodownloadSelectedNetworks"; private static final String PREF_PROXY_TYPE = "prefProxyType"; private static final String PREF_PROXY_HOST = "prefProxyHost"; @@ -379,16 +380,63 @@ public class UserPreferences { return prefs.getString(PREF_UPDATE_INTERVAL, "").equals("0"); } - public static String getMobileUpdatesEnabled() { - return prefs.getString(PREF_MOBILE_UPDATE, "images"); + private static boolean isAllowMobileFor(String type) { + HashSet<String> defaultValue = new HashSet<>(); + defaultValue.add("images"); + Set<String> allowed = prefs.getStringSet(PREF_MOBILE_UPDATE, defaultValue); + return allowed.contains(type); } - public static boolean isAllowMobileUpdate() { - return getMobileUpdatesEnabled().equals("everything"); + public static boolean isAllowMobileFeedRefresh() { + return isAllowMobileFor("feed_refresh"); + } + + public static boolean isAllowMobileEpisodeDownload() { + return isAllowMobileFor("episode_download"); + } + + public static boolean isAllowMobileAutoDownload() { + return isAllowMobileFor("auto_download"); + } + + public static boolean isAllowMobileStreaming() { + return isAllowMobileFor("streaming"); } public static boolean isAllowMobileImages() { - return isAllowMobileUpdate() || getMobileUpdatesEnabled().equals("images"); + return isAllowMobileFor("images"); + } + + private static void setAllowMobileFor(String type, boolean allow) { + HashSet<String> defaultValue = new HashSet<>(); + defaultValue.add("images"); + Set<String> allowed = prefs.getStringSet(PREF_MOBILE_UPDATE, defaultValue); + if (allow) { + allowed.remove(type); + } else { + allowed.add(type); + } + prefs.edit().putStringSet(PREF_MOBILE_UPDATE, allowed).apply(); + } + + public static void setAllowMobileFeedRefresh(boolean allow) { + setAllowMobileFor("feed_refresh", allow); + } + + public static void setAllowMobileEpisodeDownload(boolean allow) { + setAllowMobileFor("episode_download", allow); + } + + public static void setAllowMobileAutoDownload(boolean allow) { + setAllowMobileFor("auto_download", allow); + } + + public static void setAllowMobileStreaming(boolean allow) { + setAllowMobileFor("streaming", allow); + } + + public static void setAllowMobileImages(boolean allow) { + setAllowMobileFor("images", allow); } public static int getParallelDownloads() { @@ -420,11 +468,6 @@ public class UserPreferences { return prefs.getBoolean(PREF_ENABLE_AUTODL_WIFI_FILTER, false); } - public static boolean isEnableAutodownloadOnMobile() { - return prefs.getBoolean(PREF_ENABLE_AUTODL_ON_MOBILE, false); - } - - public static int getImageCacheSize() { String cacheSizeString = prefs.getString(PREF_IMAGE_CACHE_SIZE, IMAGE_CACHE_DEFAULT_VALUE); int cacheSizeInt = Integer.parseInt(cacheSizeString); 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 index a0195975f..b425687ae 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/FeedUpdateUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/FeedUpdateUtils.java @@ -24,7 +24,7 @@ public class FeedUpdateUtils { with().pollInterval(1, TimeUnit.SECONDS) .await() .atMost(10, TimeUnit.SECONDS) - .until(() -> NetworkUtils.networkAvailable() && NetworkUtils.isDownloadAllowed()); + .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"); diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/NetworkUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/NetworkUtils.java index d9431bc5d..ca48c9bc9 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/NetworkUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/NetworkUtils.java @@ -74,7 +74,7 @@ public class NetworkUtils { return true; } } else { - if (!UserPreferences.isEnableAutodownloadOnMobile()) { + if (!UserPreferences.isAllowMobileAutoDownload()) { Log.d(TAG, "Auto Download not enabled on Mobile"); return false; } @@ -95,14 +95,28 @@ public class NetworkUtils { return info != null && info.isConnected(); } - public static boolean isDownloadAllowed() { - return UserPreferences.isAllowMobileUpdate() || !NetworkUtils.isNetworkMetered(); + public static boolean isEpisodeDownloadAllowed() { + return UserPreferences.isAllowMobileEpisodeDownload() || !NetworkUtils.isNetworkMetered(); + } + + public static boolean isEpisodeHeadDownloadAllowed() { + // It is not an image but it is a similarly tiny request + // that is probably not even considered a download by most users + return isImageAllowed(); } public static boolean isImageAllowed() { return UserPreferences.isAllowMobileImages() || !NetworkUtils.isNetworkMetered(); } + public static boolean isStreamingAllowed() { + return UserPreferences.isAllowMobileStreaming() || !NetworkUtils.isNetworkMetered(); + } + + public static boolean isFeedRefreshAllowed() { + return UserPreferences.isAllowMobileFeedRefresh() || !NetworkUtils.isNetworkMetered(); + } + private static boolean isNetworkMetered() { ConnectivityManager connManager = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); @@ -123,7 +137,7 @@ public class NetworkUtils { public static Single<Long> getFeedMediaSizeObservable(FeedMedia media) { return Single.create((SingleOnSubscribe<Long>) emitter -> { - if (!NetworkUtils.isDownloadAllowed()) { + if (!NetworkUtils.isEpisodeHeadDownloadAllowed()) { emitter.onSuccess(0L); return; } 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 e5aaa2db0..412b150fa 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 @@ -67,7 +67,7 @@ public class AutoUpdateManager { private static Constraints getConstraints() { Constraints.Builder constraints = new Constraints.Builder(); - if (UserPreferences.isAllowMobileUpdate()) { + if (UserPreferences.isAllowMobileFeedRefresh()) { constraints.setRequiredNetworkType(NetworkType.CONNECTED); } else { constraints.setRequiredNetworkType(NetworkType.UNMETERED); diff --git a/core/src/main/res/values/arrays.xml b/core/src/main/res/values/arrays.xml index 39d1c0a94..d5f1c30b1 100644 --- a/core/src/main/res/values/arrays.xml +++ b/core/src/main/res/values/arrays.xml @@ -62,15 +62,19 @@ </string-array> <string-array name="mobile_update_entries"> - <item>@string/pref_mobileUpdate_nothing</item> + <item>@string/pref_mobileUpdate_refresh</item> + <item>@string/pref_mobileUpdate_episode_download</item> + <item>@string/pref_mobileUpdate_auto_download</item> + <item>@string/pref_mobileUpdate_streaming</item> <item>@string/pref_mobileUpdate_images</item> - <item>@string/pref_mobileUpdate_everything</item> </string-array> <string-array name="mobile_update_values"> - <item>nothing</item> + <item>feed_refresh</item> + <item>episode_download</item> + <item>auto_download</item> + <item>streaming</item> <item>images</item> - <item>everything</item> </string-array> <string-array name="episode_cleanup_entries"> diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index 6025dc888..82a56cf88 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -265,6 +265,8 @@ <string name="confirm_mobile_download_dialog_title">Confirm Mobile Download</string> <string name="confirm_mobile_download_dialog_message_not_in_queue">Downloading over mobile data connection is disabled in the settings.\n\nYou can choose to either only add the episode to the queue or you can allow downloading temporarily.\n\n<small>Your choice will be remembered for 10 minutes.</small></string> <string name="confirm_mobile_download_dialog_message">Downloading over mobile data connection is disabled in the settings.\n\nDo you want to allow downloading temporarily?\n\n<small>Your choice will be remembered for 10 minutes.</small></string> + <string name="confirm_mobile_streaming_dialog_title">Confirm Mobile streaming</string> + <string name="confirm_mobile_streaming_dialog_message">Streaming over mobile data connection is disabled in the settings. Do you want to stream anyway?</string> <string name="confirm_mobile_download_dialog_only_add_to_queue">Enqueue</string> <string name="confirm_mobile_download_dialog_enable_temporarily">Allow temporarily</string> @@ -386,10 +388,12 @@ <string name="pref_unpauseOnHeadsetReconnect_title">Headphones Reconnect</string> <string name="pref_unpauseOnBluetoothReconnect_title">Bluetooth Reconnect</string> <string name="pref_mobileUpdate_title">Mobile Updates</string> - <string name="pref_mobileUpdate_sum">Allow updates and manual episode downloads over the mobile data connection</string> - <string name="pref_mobileUpdate_nothing">Nothing</string> - <string name="pref_mobileUpdate_images">Images only</string> - <string name="pref_mobileUpdate_everything">Everything</string> + <string name="pref_mobileUpdate_sum">Select what should be allowed over the mobile data connection</string> + <string name="pref_mobileUpdate_refresh">Feed refresh</string> + <string name="pref_mobileUpdate_images">Cover images</string> + <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> |