summaryrefslogtreecommitdiff
path: root/core/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/main')
-rw-r--r--core/src/main/AndroidManifest.xml14
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/FeedPreferences.java7
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java4
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadServiceNotification.java6
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java28
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java1
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java84
-rw-r--r--core/src/main/res/layout/player_widget.xml6
-rw-r--r--core/src/main/res/values/strings.xml8
-rw-r--r--core/src/main/res/values/styles.xml10
10 files changed, 109 insertions, 59 deletions
diff --git a/core/src/main/AndroidManifest.xml b/core/src/main/AndroidManifest.xml
index 1f6c36c40..ae5e56e55 100644
--- a/core/src/main/AndroidManifest.xml
+++ b/core/src/main/AndroidManifest.xml
@@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="de.danoeh.antennapod.core">
+ xmlns:tools="http://schemas.android.com/tools" package="de.danoeh.antennapod.core">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
@@ -12,15 +12,19 @@
<application
android:allowBackup="true"
- android:icon="@mipmap/ic_launcher">
+ android:icon="@mipmap/ic_launcher"
+ android:supportsRtl="true">
<service
android:name=".service.download.DownloadService"
android:enabled="true" />
+
<service android:name=".service.playback.PlaybackService"
android:label="@string/app_name"
android:enabled="true"
- android:exported="true">
+ android:exported="true"
+ tools:ignore="ExportedService">
+
<intent-filter>
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
@@ -39,8 +43,8 @@
<receiver android:name=".receiver.FeedUpdateReceiver"
android:label="@string/feed_update_receiver_name"
- android:exported="true"> <!-- allow feeds update to be triggered by external apps -->
- </receiver>
+ android:exported="true"
+ tools:ignore="ExportedReceiver" /> <!-- allow feeds update to be triggered by external apps -->
</application>
</manifest>
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedPreferences.java b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedPreferences.java
index 2a2568f28..5ffee0d62 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedPreferences.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedPreferences.java
@@ -38,11 +38,8 @@ public class FeedPreferences {
private int feedSkipEnding;
public FeedPreferences(long feedID, boolean autoDownload, AutoDeleteAction auto_delete_action, VolumeAdaptionSetting volumeAdaptionSetting, String username, String password) {
- this(feedID, autoDownload, true, auto_delete_action, volumeAdaptionSetting, username, password, new FeedFilter(), SPEED_USE_GLOBAL);
- }
-
- private FeedPreferences(long feedID, boolean autoDownload, boolean keepUpdated, AutoDeleteAction auto_delete_action, VolumeAdaptionSetting volumeAdaptionSetting, String username, String password, @NonNull FeedFilter filter, float feedPlaybackSpeed) {
- this(feedID, autoDownload, true, auto_delete_action, volumeAdaptionSetting, username, password, new FeedFilter(), feedPlaybackSpeed, 0, 0);
+ this(feedID, autoDownload, true, auto_delete_action, volumeAdaptionSetting,
+ username, password, new FeedFilter(), SPEED_USE_GLOBAL, 0, 0);
}
private FeedPreferences(long feedID, boolean autoDownload, boolean keepUpdated, AutoDeleteAction auto_delete_action, VolumeAdaptionSetting volumeAdaptionSetting, String username, String password, @NonNull FeedFilter filter, float feedPlaybackSpeed, int feedSkipIntro, int feedSkipEnding) {
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 bcbc041a6..5700bb9a0 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
@@ -249,7 +249,7 @@ public class UserPreferences {
public static void setFeedOrder(String selected) {
prefs.edit()
.putString(PREF_DRAWER_FEED_ORDER, selected)
- .commit();
+ .apply();
}
public static int getFeedCounterSetting() {
@@ -1054,7 +1054,7 @@ public class UserPreferences {
public static void setFeedFilter(String value) {
prefs.edit()
.putString(PREF_FILTER_FEED, value)
- .commit();
+ .apply();
}
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadServiceNotification.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadServiceNotification.java
index 64666d25d..975bc3cb3 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadServiceNotification.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadServiceNotification.java
@@ -153,7 +153,11 @@ public class DownloadServiceNotification {
iconId = R.drawable.ic_notification_sync_error;
intent = ClientConfig.downloadServiceCallbacks.getReportNotificationContentIntent(context);
id = R.id.notification_download_report;
- content = String.format(context.getString(R.string.download_report_content), successfulDownloads, failedDownloads);
+ content = context.getResources()
+ .getQuantityString(R.plurals.download_report_content,
+ successfulDownloads,
+ successfulDownloads,
+ failedDownloads);
}
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, channelId);
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java
index 883ba6023..9ef34cdac 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java
@@ -8,6 +8,7 @@ import androidx.annotation.NonNull;
import android.util.Log;
import de.danoeh.antennapod.core.preferences.SleepTimerPreferences;
+import io.reactivex.disposables.Disposable;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
@@ -57,7 +58,7 @@ public class PlaybackServiceTaskManager {
private ScheduledFuture<?> widgetUpdaterFuture;
private ScheduledFuture<?> sleepTimerFuture;
private volatile Future<List<FeedItem>> queueFuture;
- private volatile Future<?> chapterLoaderFuture;
+ private volatile Disposable chapterLoaderFuture;
private SleepTimer sleepTimer;
@@ -102,7 +103,7 @@ public class PlaybackServiceTaskManager {
private synchronized void loadQueue() {
if (!isQueueLoaderActive()) {
- queueFuture = schedExecutor.submit(DBReader::getQueue);
+ queueFuture = schedExecutor.submit(() -> DBReader.getQueue());
}
}
@@ -289,28 +290,19 @@ public class PlaybackServiceTaskManager {
}
}
- private synchronized void cancelChapterLoader() {
- if (isChapterLoaderActive()) {
- chapterLoaderFuture.cancel(true);
- }
- }
-
- private synchronized boolean isChapterLoaderActive() {
- return chapterLoaderFuture != null && !chapterLoaderFuture.isDone();
- }
-
/**
* Starts a new thread that loads the chapter marks from a playable object. If another chapter loader is already active,
* it will be cancelled first.
* On completion, the callback's onChapterLoaded method will be called.
*/
public synchronized void startChapterLoader(@NonNull final Playable media) {
- if (isChapterLoaderActive()) {
- cancelChapterLoader();
+ if (chapterLoaderFuture != null) {
+ chapterLoaderFuture.dispose();
+ chapterLoaderFuture = null;
}
if (media.getChapters() == null) {
- Completable.create(emitter -> {
+ chapterLoaderFuture = Completable.create(emitter -> {
media.loadChapterMarks();
emitter.onComplete();
})
@@ -330,7 +322,11 @@ public class PlaybackServiceTaskManager {
cancelWidgetUpdater();
disableSleepTimer();
cancelQueueLoader();
- cancelChapterLoader();
+
+ if (chapterLoaderFuture != null) {
+ chapterLoaderFuture.dispose();
+ chapterLoaderFuture = null;
+ }
}
/**
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 16e2825b4..4f2417b7d 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
@@ -257,7 +257,6 @@ public final class DBTasks {
EventBus.getDefault().post(new MessageEvent(context.getString(R.string.error_file_not_found)));
}
- @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
public static List<? extends FeedItem> enqueueFeedItemsToDownload(final Context context,
List<? extends FeedItem> items) throws InterruptedException, ExecutionException {
List<FeedItem> itemsToEnqueue = new ArrayList<>();
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 4b585d796..e552cc180 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
@@ -20,7 +20,6 @@ import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
-import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
@@ -1207,12 +1206,17 @@ public class PodDBAdapter {
* Uses DatabaseUtils to escape a search query and removes ' at the
* beginning and the end of the string returned by the escape method.
*/
- private String prepareSearchQuery(String query) {
- StringBuilder builder = new StringBuilder();
- DatabaseUtils.appendEscapedSQLString(builder, query);
- builder.deleteCharAt(0);
- builder.deleteCharAt(builder.length() - 1);
- return builder.toString();
+ private String[] prepareSearchQuery(String query) {
+ String[] queryWords = query.split("\\s+");
+ for (int i = 0; i < queryWords.length; ++i) {
+ StringBuilder builder = new StringBuilder();
+ DatabaseUtils.appendEscapedSQLString(builder, queryWords[i]);
+ builder.deleteCharAt(0);
+ builder.deleteCharAt(builder.length() - 1);
+ queryWords[i] = builder.toString();
+ }
+
+ return queryWords;
}
/**
@@ -1222,7 +1226,7 @@ public class PodDBAdapter {
* @return A cursor with all search results in SEL_FI_EXTRA selection.
*/
public Cursor searchItems(long feedID, String searchQuery) {
- String preparedQuery = prepareSearchQuery(searchQuery);
+ String[] queryWords = prepareSearchQuery(searchQuery);
String queryFeedId;
if (feedID != 0) {
@@ -1233,14 +1237,28 @@ public class PodDBAdapter {
queryFeedId = "1 = 1";
}
- String query = SELECT_FEED_ITEMS_AND_MEDIA_WITH_DESCRIPTION
- + " WHERE " + queryFeedId + " AND ("
- + KEY_DESCRIPTION + " LIKE '%" + preparedQuery + "%' OR "
- + KEY_CONTENT_ENCODED + " LIKE '%" + preparedQuery + "%' OR "
- + KEY_TITLE + " LIKE '%" + preparedQuery + "%'"
- + ") ORDER BY " + KEY_PUBDATE + " DESC "
- + "LIMIT 300";
- return db.rawQuery(query, null);
+ String queryStart = SELECT_FEED_ITEMS_AND_MEDIA_WITH_DESCRIPTION
+ + " WHERE " + queryFeedId + " AND (";
+ StringBuilder sb = new StringBuilder(queryStart);
+
+ for (int i = 0; i < queryWords.length; i++) {
+ sb
+ .append("(")
+ .append(KEY_DESCRIPTION + " LIKE '%").append(queryWords[i])
+ .append("%' OR ")
+ .append(KEY_CONTENT_ENCODED).append(" LIKE '%").append(queryWords[i])
+ .append("%' OR ")
+ .append(KEY_TITLE).append(" LIKE '%").append(queryWords[i])
+ .append("%') ");
+
+ if (i != queryWords.length - 1) {
+ sb.append("AND ");
+ }
+ }
+
+ sb.append(") ORDER BY " + KEY_PUBDATE + " DESC LIMIT 300");
+
+ return db.rawQuery(sb.toString(), null);
}
/**
@@ -1249,15 +1267,31 @@ public class PodDBAdapter {
* @return A cursor with all search results in SEL_FI_EXTRA selection.
*/
public Cursor searchFeeds(String searchQuery) {
- String preparedQuery = prepareSearchQuery(searchQuery);
- String query = "SELECT * FROM " + TABLE_NAME_FEEDS + " WHERE "
- + KEY_TITLE + " LIKE '%" + preparedQuery + "%' OR "
- + KEY_CUSTOM_TITLE + " LIKE '%" + preparedQuery + "%' OR "
- + KEY_AUTHOR + " LIKE '%" + preparedQuery + "%' OR "
- + KEY_DESCRIPTION + " LIKE '%" + preparedQuery + "%' "
- + "ORDER BY " + KEY_TITLE + " ASC "
- + "LIMIT 300";
- return db.rawQuery(query, null);
+ String[] queryWords = prepareSearchQuery(searchQuery);
+
+ String queryStart = "SELECT * FROM " + TABLE_NAME_FEEDS + " WHERE ";
+ StringBuilder sb = new StringBuilder(queryStart);
+
+ for (int i = 0; i < queryWords.length; i++) {
+ sb
+ .append("(")
+ .append(KEY_TITLE).append(" LIKE '%").append(queryWords[i])
+ .append("%' OR ")
+ .append(KEY_CUSTOM_TITLE).append(" LIKE '%").append(queryWords[i])
+ .append("%' OR ")
+ .append(KEY_AUTHOR).append(" LIKE '%").append(queryWords[i])
+ .append("%' OR ")
+ .append(KEY_DESCRIPTION).append(" LIKE '%").append(queryWords[i])
+ .append("%') ");
+
+ if (i != queryWords.length - 1) {
+ sb.append("AND ");
+ }
+ }
+
+ sb.append("ORDER BY " + KEY_TITLE + " ASC LIMIT 300");
+
+ return db.rawQuery(sb.toString(), null);
}
/**
diff --git a/core/src/main/res/layout/player_widget.xml b/core/src/main/res/layout/player_widget.xml
index 6e463e9cd..8e38d7f6e 100644
--- a/core/src/main/res/layout/player_widget.xml
+++ b/core/src/main/res/layout/player_widget.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/widget_margin" >
@@ -8,8 +9,8 @@
android:id="@+id/widgetLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="#262C31" >
-
+ android:background="#262C31"
+ tools:ignore="UselessParent">
<ImageButton
android:id="@+id/butPlay"
@@ -41,6 +42,7 @@
android:layout_width="@android:dimen/app_icon_size"
android:layout_height="match_parent"
android:src="@mipmap/ic_launcher_round"
+ android:importantForAccessibility="no"
android:layout_margin="12dp" />
<LinearLayout
diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml
index f33027f36..23c812f17 100644
--- a/core/src/main/res/values/strings.xml
+++ b/core/src/main/res/values/strings.xml
@@ -248,7 +248,10 @@
</plurals>
<string name="downloads_processing">Processing downloads</string>
<string name="download_notification_title">Downloading podcast data</string>
- <string name="download_report_content">%1$d downloads succeeded, %2$d failed</string>
+ <plurals name="download_report_content">
+ <item quantity="one">%d download succeeded, %d failed</item>
+ <item quantity="other">%d downloads succeeded, %d failed</item>
+ </plurals>
<string name="download_log_title_unknown">Unknown Title</string>
<string name="download_type_feed">Feed</string>
<string name="download_type_media">Media file</string>
@@ -565,6 +568,7 @@
<string name="database_export_summary">Transfer subscriptions, listened episodes and queue to AntennaPod on another device</string>
<string name="database_import_summary">Import AntennaPod database from another device</string>
<string name="opml_import_label">OPML Import</string>
+ <string name="opml_add_podcast_label">Import podcast list (OPML)</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>
@@ -726,7 +730,7 @@
<string name="search_powered_by">Results by %1$s</string>
<string name="filter">Filter</string>
-
+
<!-- Episodes apply actions -->
<string name="all_label">All</string>
<string name="selected_all_label">Selected all Episodes</string>
diff --git a/core/src/main/res/values/styles.xml b/core/src/main/res/values/styles.xml
index 73ecdb14e..92faa927a 100644
--- a/core/src/main/res/values/styles.xml
+++ b/core/src/main/res/values/styles.xml
@@ -306,4 +306,14 @@
<style name="Widget.AntennaPod.ActionBar.Black" parent="Widget.MaterialComponents.Light.ActionBar.Solid">
<item name="background">@color/black</item>
</style>
+
+ <style name="AddPodcastTextView">
+ <item name="android:drawablePadding">8dp</item>
+ <item name="android:paddingTop">8dp</item>
+ <item name="android:paddingBottom">8dp</item>
+ <item name="android:background">?android:attr/selectableItemBackground</item>
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
+ <item name="android:clickable">true</item>
+ </style>
+
</resources>