summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md72
-rw-r--r--ISSUE_TEMPLATE.md4
-rw-r--r--app/build.gradle6
-rw-r--r--app/proguard.cfg2
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java49
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java46
-rw-r--r--app/src/androidTest/java/de/test/antennapod/util/FilenameGeneratorTest.java10
-rw-r--r--app/src/main/AndroidManifest.xml34
-rw-r--r--app/src/main/java/de/danoeh/antennapod/PodcastApp.java3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java186
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromIntentActivity.java17
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/StatisticsActivity.java70
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java12
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/StatisticsListAdapter.java7
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java13
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/EpisodesFragment.java24
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java33
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java5
-rw-r--r--app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java17
-rw-r--r--app/src/main/play/es_ES/listing/fulldescription30
-rw-r--r--app/src/main/play/et/listing/fulldescription26
-rw-r--r--app/src/main/play/fr/listing/fulldescription32
-rw-r--r--app/src/main/play/gl/listing/fulldescription43
-rw-r--r--app/src/main/play/is/listing/fulldescription43
-rw-r--r--app/src/main/play/it_IT/listing/fulldescription30
-rw-r--r--app/src/main/play/lt/listing/fulldescription44
-rw-r--r--app/src/main/play/pl_PL/listing/fulldescription80
-rw-r--r--app/src/main/play/ru_RU/listing/fulldescription80
-rw-r--r--app/src/main/play/sw_KE/listing/fulldescription43
-rw-r--r--app/src/main/res/layout/nav_list.xml23
-rw-r--r--app/src/main/res/layout/simplechapter_item.xml10
-rw-r--r--app/src/main/res/layout/statistics_mode_select_dialog.xml25
-rw-r--r--app/src/main/res/layout/subscription_item.xml19
-rw-r--r--app/src/main/res/menu/allepisodes_context.xml4
-rw-r--r--app/src/main/res/menu/feeditem_options.xml4
-rw-r--r--app/src/main/res/menu/feeditemlist_context.xml4
-rw-r--r--app/src/main/res/menu/mediaplayer.xml4
-rw-r--r--app/src/main/res/menu/queue_context.xml4
-rw-r--r--app/src/main/res/menu/statistics.xml12
-rw-r--r--app/src/main/res/xml/automotive_app_desc.xml4
-rw-r--r--app/src/main/res/xml/preferences.xml15
-rw-r--r--app/src/play/java/de/danoeh/antennapod/dialog/CustomMRControllerDialog.java5
-rw-r--r--app/src/play/res/layout/media_router_controller.xml4
-rw-r--r--build.gradle43
-rw-r--r--circle.yml4
-rw-r--r--core/build.gradle1
-rw-r--r--core/src/androidTest/java/de/danoeh/antennapod/core/feed/FeedImageMother.java9
-rw-r--r--core/src/androidTest/java/de/danoeh/antennapod/core/feed/FeedItemMother.java16
-rw-r--r--core/src/androidTest/java/de/danoeh/antennapod/core/feed/FeedItemTest.java65
-rw-r--r--core/src/androidTest/java/de/danoeh/antennapod/core/feed/FeedMother.java14
-rw-r--r--core/src/androidTest/java/de/danoeh/antennapod/core/feed/FeedTest.java92
-rw-r--r--core/src/androidTest/java/de/danoeh/antennapod/core/tests/util/DateUtilsTest.java31
-rw-r--r--core/src/androidTest/java/de/danoeh/antennapod/core/tests/util/service/download/DownloadServiceTest.java35
-rw-r--r--core/src/free/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceFlavorHelper.java10
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/dialog/ConfirmationDialog.java16
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java38
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java3
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/gpoddernet/GpodnetService.java4
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java17
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/receiver/FeedUpdateReceiver.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java287
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java24
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java100
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java921
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java48
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java10
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java4
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/FeedSearcher.java32
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java266
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSITunes.java5
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/DateUtils.java46
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/FileNameGenerator.java29
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/ShareUtils.java11
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/URLChecker.java3
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/comparator/SearchResultValueComparator.java15
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java1
-rw-r--r--core/src/main/res/values-az/strings.xml1
-rw-r--r--core/src/main/res/values-b+ast/strings.xml29
-rw-r--r--core/src/main/res/values-ca/strings.xml24
-rw-r--r--core/src/main/res/values-cs-rCZ/strings.xml42
-rw-r--r--core/src/main/res/values-da/strings.xml1
-rw-r--r--core/src/main/res/values-de/strings.xml97
-rw-r--r--core/src/main/res/values-el/strings.xml1
-rw-r--r--core/src/main/res/values-es-rES/strings.xml8
-rw-r--r--core/src/main/res/values-es/strings.xml6
-rw-r--r--core/src/main/res/values-et/strings.xml35
-rw-r--r--core/src/main/res/values-fr/strings.xml62
-rw-r--r--core/src/main/res/values-hi-rIN/strings.xml1
-rw-r--r--core/src/main/res/values-hu/strings.xml114
-rw-r--r--core/src/main/res/values-it-rIT/strings.xml10
-rw-r--r--core/src/main/res/values-it/strings.xml1
-rw-r--r--core/src/main/res/values-iw-rIL/strings.xml1
-rw-r--r--core/src/main/res/values-ja/strings.xml18
-rw-r--r--core/src/main/res/values-kn-rIN/strings.xml1
-rw-r--r--core/src/main/res/values-ko/strings.xml40
-rw-r--r--core/src/main/res/values-lt/strings.xml211
-rw-r--r--core/src/main/res/values-nb/strings.xml6
-rw-r--r--core/src/main/res/values-nl/strings.xml6
-rw-r--r--core/src/main/res/values-no-rNB/strings.xml6
-rw-r--r--core/src/main/res/values-pl-rPL/strings.xml41
-rw-r--r--core/src/main/res/values-pt-rBR/strings.xml6
-rw-r--r--core/src/main/res/values-pt/strings.xml21
-rw-r--r--core/src/main/res/values-ro-rRO/strings.xml1
-rw-r--r--core/src/main/res/values-ru/strings.xml71
-rw-r--r--core/src/main/res/values-sv-rSE/strings.xml54
-rw-r--r--core/src/main/res/values-te/strings.xml65
-rw-r--r--core/src/main/res/values-tr/strings.xml27
-rw-r--r--core/src/main/res/values-uk-rUA/strings.xml24
-rw-r--r--core/src/main/res/values-vi/strings.xml259
-rw-r--r--core/src/main/res/values-zh-rCN/strings.xml4
-rw-r--r--core/src/main/res/values/arrays.xml2
-rw-r--r--core/src/main/res/values/strings.xml27
-rw-r--r--core/src/play/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceFlavorHelper.java21
-rw-r--r--gradle/wrapper/gradle-wrapper.jarbin54227 -> 54708 bytes
-rw-r--r--gradle/wrapper/gradle-wrapper.properties3
-rwxr-xr-xgradlew6
123 files changed, 3391 insertions, 1379 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 122213dfd..ef72e5a45 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,46 +1,62 @@
Change Log
==========
+Version 1.6.3
+-------------
+
+* New features:
+ * Support for Android Auto
+ * Sort feeds by number of played episodes
+ * Statistics modes
+ * Setting: Enqueue downloaded
+ * Launch screen
+* Improvements
+ * Chapter duration
+ * Feed title in deletion confirmation
+* Fixes:
+ * Episodes refresh spinner
+ * Publication date parsing
+ * Unknown mime type
Version 1.6.2
-------------
* New features:
- * Integration of fyyd Podcast Search Engine
- * Export subscriptions as HTML
- * Rename feeds
- * Auto-enable sleep timer
- * "has media" filter
- * Force gpodder full sync
+ * Integration of fyyd Podcast Search Engine
+ * Export subscriptions as HTML
+ * Rename feeds
+ * Auto-enable sleep timer
+ * "has media" filter
+ * Force gpodder full sync
* Improvements:
- * Better support for Atom feeds, e.g. summary tag
- * Confirmation dialog on mark all as seen
- * Number of downloaded episodes in subscription counter
- * Gpodder sync error optional
- * Search results
- * MRSS support
- * Sanitize HTML from Atom feed
+ * Better support for Atom feeds, e.g. summary tag
+ * Confirmation dialog on mark all as seen
+ * Number of downloaded episodes in subscription counter
+ * Gpodder sync error optional
+ * Search results
+ * MRSS support
+ * Sanitize HTML from Atom feed
* Fixes:
- * Reset sleep timer on shake to current waiting time
- * Cast dialog image
- * Mini player not showing up
- * Audio player cover fragment
- * Prevent out of memory and casting crashes
+ * Reset sleep timer on shake to current waiting time
+ * Cast dialog image
+ * Mini player not showing up
+ * Audio player cover fragment
+ * Prevent out of memory and casting crashes
Version 1.6.0
-------------
* New features:
- * Experimental Chromecast support
- * Subscription overview
- * Proxy support
- * Statistics
- * Manual gpodder.net sync
+ * Experimental Chromecast support
+ * Subscription overview
+ * Proxy support
+ * Statistics
+ * Manual gpodder.net sync
* Fixes:
- * Audioplayer controls
- * Audio ducking
- * Video control fade-out
- * External media controls
- * Feed parsing
+ * Audioplayer controls
+ * Audio ducking
+ * Video control fade-out
+ * External media controls
+ * Feed parsing
Version 1.5.0
-------------
diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md
index e7b99c56d..dc02f85f4 100644
--- a/ISSUE_TEMPLATE.md
+++ b/ISSUE_TEMPLATE.md
@@ -7,11 +7,11 @@ In particular, please not only tell us that you want something (*what*), but als
---
-**App version:** 1.x (from Google Play/F-Store/Custom build)
+**App version:** 1.x (from Google Play/F-Droid/Custom build)
**Android version**: 5.x [Please mention if you are using a custom rom!]
-**Devide model**:
+**Device model**:
**Expected behaviour**:
diff --git a/app/build.gradle b/app/build.gradle
index c7b95421b..09763fdbb 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,6 +30,7 @@ android {
defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
+ multiDexEnabled true
versionCode getMyVersionCode()
versionName "${getMyVersionName()}"
testApplicationId "de.test.antennapod"
@@ -130,6 +131,7 @@ dependencies {
} else {
System.out.println("app: free build hack, skipping some dependencies")
}
+ compile 'com.android.support:multidex:1.0.1'
compile "com.android.support:support-v4:$supportVersion"
compile "com.android.support:appcompat-v7:$supportVersion"
compile "com.android.support:design:$supportVersion"
@@ -153,7 +155,7 @@ dependencies {
compile "com.artemzin.rxjava:proguard-rules:$rxJavaRulesVersion"
compile "com.joanzapata.iconify:android-iconify-fontawesome:$iconifyVersion"
compile "com.joanzapata.iconify:android-iconify-material:$iconifyVersion"
- compile("com.github.afollestad.material-dialogs:commons:$materialDialogsVersion") {
+ compile("com.afollestad.material-dialogs:commons:$materialDialogsVersion") {
transitive = true
}
compile "com.yqritc:recyclerview-flexibledivider:$recyclerviewFlexibledividerVersion"
@@ -179,7 +181,7 @@ task filterAbout {
inputs.files files(["src/main/templates/about.html",
"src/main/AndroidManifest.xml"])
outputs.file "src/main/assets/about.html"
-} << {
+} doLast {
copy {
from "src/main/templates/about.html"
into "src/main/assets"
diff --git a/app/proguard.cfg b/app/proguard.cfg
index 815a89452..769079bd8 100644
--- a/app/proguard.cfg
+++ b/app/proguard.cfg
@@ -66,8 +66,10 @@
-keep interface android.support.v4.** { *; }
-keep class !android.support.v7.internal.view.menu.**,android.support.v7.** {*;}
-keep interface android.support.v7.** { *; }
+-keep class com.google.android.wearable.** { *; }
-dontwarn android.support.v4.**
-dontwarn android.support.v7.**
+-dontwarn com.google.android.wearable.**
-keepattributes *Annotation*
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java
index 9386e3bd6..0c5cf10cb 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java
@@ -218,58 +218,43 @@ public class DBReaderTest extends InstrumentationTestCase {
}
}
- private List<FeedItem> saveUnreadItems(int numItems) {
- if (numItems <= 0) {
- throw new IllegalArgumentException("numItems<=0");
- }
+ private List<FeedItem> saveNewItems(int numItems) {
List<Feed> feeds = saveFeedlist(numItems, numItems, true);
List<FeedItem> items = new ArrayList<>();
for (Feed f : feeds) {
items.addAll(f.getItems());
}
- List<FeedItem> unread = new ArrayList<>();
+ List<FeedItem> newItems = new ArrayList<>();
Random random = new Random();
- while (unread.size() < numItems) {
+ while (newItems.size() < numItems) {
int i = random.nextInt(numItems);
- if (!unread.contains(items.get(i))) {
+ if (!newItems.contains(items.get(i))) {
FeedItem item = items.get(i);
- item.setPlayed(false);
- unread.add(item);
+ item.setNew();
+ newItems.add(item);
}
}
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
- adapter.setFeedItemlist(unread);
+ adapter.setFeedItemlist(newItems);
adapter.close();
- return unread;
- }
-
- public void testGetUnreadItemsList() {
- final int numItems = 10;
-
- List<FeedItem> unread = saveUnreadItems(numItems);
- List<FeedItem> unreadSaved = DBReader.getUnreadItemsList();
- assertNotNull(unreadSaved);
- assertTrue(unread.size() == unreadSaved.size());
- for (FeedItem item : unreadSaved) {
- assertFalse(item.isPlayed());
- }
+ return newItems;
}
public void testGetNewItemIds() {
final int numItems = 10;
- List<FeedItem> unread = saveUnreadItems(numItems);
- long[] unreadIds = new long[unread.size()];
- for (int i = 0; i < unread.size(); i++) {
- unreadIds[i] = unread.get(i).getId();
+ List<FeedItem> newItems = saveNewItems(numItems);
+ long[] unreadIds = new long[newItems.size()];
+ for (int i = 0; i < newItems.size(); i++) {
+ unreadIds[i] = newItems.get(i).getId();
}
- List<FeedItem> unreadSaved = DBReader.getUnreadItemsList();
- assertNotNull(unreadSaved);
- assertTrue(unread.size() == unreadSaved.size());
- for(int i=0; i < unreadSaved.size(); i++) {
- long savedId = unreadSaved.get(i).getId();
+ List<FeedItem> newItemsSaved = DBReader.getNewItemsList();
+ assertNotNull(newItemsSaved);
+ assertTrue(newItems.size() == newItemsSaved.size());
+ for(int i=0; i < newItemsSaved.size(); i++) {
+ long savedId = newItemsSaved.get(i).getId();
boolean found = false;
for (long id : unreadIds) {
if (id == savedId) {
diff --git a/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java b/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java
index 040f4150b..91928f01e 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java
@@ -3,10 +3,12 @@ package de.test.antennapod.ui;
import android.content.Context;
import android.content.res.Resources;
import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
import com.robotium.solo.Solo;
import com.robotium.solo.Timeout;
+import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import de.danoeh.antennapod.R;
@@ -362,4 +364,48 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
Timeout.getLargeTimeout()));
}
+
+ public void testRewindChange() {
+ int seconds = UserPreferences.getRewindSecs();
+ int deltas[] = res.getIntArray(R.array.seek_delta_values);
+
+ solo.clickOnText(solo.getString(R.string.pref_rewind));
+ solo.waitForDialogToOpen();
+
+ int currentIndex = Arrays.binarySearch(deltas, seconds);
+ assertTrue(currentIndex >= 0 && currentIndex < deltas.length); // found?
+
+ // Find next value (wrapping around to next)
+ int newIndex = (currentIndex + 1) % deltas.length;
+
+ solo.clickOnText(String.valueOf(deltas[newIndex]) + " seconds");
+ solo.clickOnButton("Confirm");
+
+ solo.waitForDialogToClose();
+ assertTrue(solo.waitForCondition(() -> UserPreferences.getRewindSecs() == deltas[newIndex],
+ Timeout.getLargeTimeout()));
+ }
+
+ public void testFastForwardChange() {
+ for (int i = 2; i > 0; i--) { // repeat twice to catch any error where fastforward is tracking rewind
+ int seconds = UserPreferences.getFastForwardSecs();
+ int deltas[] = res.getIntArray(R.array.seek_delta_values);
+
+ solo.clickOnText(solo.getString(R.string.pref_fast_forward));
+ solo.waitForDialogToOpen();
+
+ int currentIndex = Arrays.binarySearch(deltas, seconds);
+ assertTrue(currentIndex >= 0 && currentIndex < deltas.length); // found?
+
+ // Find next value (wrapping around to next)
+ int newIndex = (currentIndex + 1) % deltas.length;
+
+ solo.clickOnText(String.valueOf(deltas[newIndex]) + " seconds");
+ solo.clickOnButton("Confirm");
+
+ solo.waitForDialogToClose();
+ assertTrue(solo.waitForCondition(() -> UserPreferences.getFastForwardSecs() == deltas[newIndex],
+ Timeout.getLargeTimeout()));
+ }
+ }
}
diff --git a/app/src/androidTest/java/de/test/antennapod/util/FilenameGeneratorTest.java b/app/src/androidTest/java/de/test/antennapod/util/FilenameGeneratorTest.java
index 6d24fa526..13e8b9582 100644
--- a/app/src/androidTest/java/de/test/antennapod/util/FilenameGeneratorTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/util/FilenameGeneratorTest.java
@@ -34,6 +34,16 @@ public class FilenameGeneratorTest extends AndroidTestCase {
createFiles(result);
}
+ public void testFeedTitleContainsApostrophe() {
+ String result = FileNameGenerator.generateFileName("Feed's Title ...");
+ assertEquals("Feeds Title", result);
+ }
+
+ public void testFeedTitleContainsDash() {
+ String result = FileNameGenerator.generateFileName("Left - Right");
+ assertEquals("Left Right", result);
+ }
+
/**
* Tests if files can be created.
*
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 2049b6bae..10917f613 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.danoeh.antennapod"
- android:versionCode="1060203"
- android:versionName="1.6.2.3">
+ android:installLocation="auto"
+ android:versionCode="1060398"
+ android:versionName="1.6.3.0">
<!--
Version code schema:
"1.2.3-SNAPSHOT" -> 1020300
@@ -37,6 +38,8 @@
android:backupAgent=".core.backup.OpmlBackupAgent"
android:restoreAnyVersion="true"
android:logo="@drawable/ic_launcher">
+ <meta-data android:name="com.google.android.gms.car.notification.SmallIcon"
+ android:resource="@drawable/ic_notification" />
<meta-data
android:name="com.google.android.backup.api_key"
android:value="AEdPqrEAAAAI3a05VToCTlqBymJrbFGaKQMvF-bBAuLsOdavBA"/>
@@ -51,6 +54,13 @@
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
+
+ <intent-filter>
+ <action android:name=
+ "android.media.action.MEDIA_PLAY_FROM_SEARCH" />
+ <category android:name=
+ "android.intent.category.DEFAULT" />
+ </intent-filter>
</activity>
<activity
android:name=".activity.MainActivity"
@@ -191,6 +201,21 @@
<data android:host="*"/>
</intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.SEND"/>
+
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
+
+ <data android:mimeType="text/xml"/>
+ <data android:mimeType="text/plain"/>
+ <data android:mimeType="text/x-opml"/>
+ <data android:mimeType="application/xml"/>
+ <data android:mimeType="application/octet-stream"/>
+
+ <data android:scheme="http"/>
+ <data android:scheme="https"/>
+ </intent-filter>
</activity>
<activity
android:name=".activity.OpmlFeedChooserActivity"
@@ -243,6 +268,7 @@
<data android:host="*"/>
<data android:pathPattern=".*\\.xml"/>
<data android:pathPattern=".*\\.rss"/>
+ <data android:pathPattern=".*\\.atom"/>
</intent-filter>
<!-- Feedburner URLs -->
@@ -349,6 +375,10 @@
<meta-data
android:name="de.danoeh.antennapod.core.glide.ApGlideModule"
android:value="GlideModule" />
+
+ <meta-data
+ android:name="com.google.android.gms.car.application"
+ android:resource="@xml/automotive_app_desc"/>
</application>
</manifest>
diff --git a/app/src/main/java/de/danoeh/antennapod/PodcastApp.java b/app/src/main/java/de/danoeh/antennapod/PodcastApp.java
index f6a8db5fb..caa82d725 100644
--- a/app/src/main/java/de/danoeh/antennapod/PodcastApp.java
+++ b/app/src/main/java/de/danoeh/antennapod/PodcastApp.java
@@ -3,6 +3,7 @@ package de.danoeh.antennapod;
import android.app.Application;
import android.os.Build;
import android.os.StrictMode;
+import android.support.multidex.MultiDexApplication;
import com.joanzapata.iconify.Iconify;
import com.joanzapata.iconify.fonts.FontAwesomeModule;
@@ -13,7 +14,7 @@ import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.spa.SPAUtil;
/** Main application class. */
-public class PodcastApp extends Application {
+public class PodcastApp extends MultiDexApplication {
// make sure that ClientConfigurator executes its static code
static {
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java
index 19aabfc88..2a58d5104 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java
@@ -228,7 +228,7 @@ public class FeedInfoActivity extends AppCompatActivity {
cbxAutoDownload.setChecked(prefs.getAutoDownload());
cbxAutoDownload.setOnCheckedChangeListener((compoundButton, checked) -> {
feed.getPreferences().setAutoDownload(checked);
- feed.savePreferences(FeedInfoActivity.this);
+ feed.savePreferences();
updateAutoDownloadSettings();
ApplyToEpisodesDialog dialog = new ApplyToEpisodesDialog(FeedInfoActivity.this,
feed, checked);
@@ -237,7 +237,7 @@ public class FeedInfoActivity extends AppCompatActivity {
cbxKeepUpdated.setChecked(prefs.getKeepUpdated());
cbxKeepUpdated.setOnCheckedChangeListener((compoundButton, checked) -> {
feed.getPreferences().setKeepUpdated(checked);
- feed.savePreferences(FeedInfoActivity.this);
+ feed.savePreferences();
});
spnAutoDelete.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
index 41ed963c2..f0fcdca90 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
@@ -593,7 +593,7 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
};
ConfirmationDialog conDialog = new ConfirmationDialog(this,
R.string.remove_feed_label,
- R.string.feed_delete_confirmation_msg) {
+ getString(R.string.feed_delete_confirmation_msg, feed.getTitle())) {
@Override
public void onConfirmButtonPressed(
DialogInterface dialog) {
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java
index 48b578be7..21a0fa66f 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java
@@ -1,6 +1,7 @@
package de.danoeh.antennapod.activity;
import android.annotation.TargetApi;
+import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
@@ -9,6 +10,7 @@ import android.graphics.PixelFormat;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
+import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import android.view.Menu;
@@ -42,6 +44,7 @@ import de.danoeh.antennapod.core.util.Converter;
import de.danoeh.antennapod.core.util.Flavors;
import de.danoeh.antennapod.core.util.ShareUtils;
import de.danoeh.antennapod.core.util.StorageUtils;
+import de.danoeh.antennapod.core.util.Supplier;
import de.danoeh.antennapod.core.util.playback.MediaPlayerError;
import de.danoeh.antennapod.core.util.playback.Playable;
import de.danoeh.antennapod.core.util.playback.PlaybackController;
@@ -49,6 +52,8 @@ import de.danoeh.antennapod.dialog.SleepTimerDialog;
import de.danoeh.antennapod.dialog.VariableSpeedDialog;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
+import rx.functions.Action1;
+import rx.functions.Func1;
import rx.schedulers.Schedulers;
@@ -178,6 +183,13 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
};
}
+ protected static TextView getTxtvFFFromActivity(MediaplayerActivity activity) {
+ return activity.txtvFF;
+ }
+ protected static TextView getTxtvRevFromActivity(MediaplayerActivity activity) {
+ return activity.txtvRev;
+ }
+
protected void onSetSpeedAbilityChanged() {
Log.d(TAG, "onSetSpeedAbilityChanged()");
updatePlaybackSpeedButton();
@@ -297,10 +309,9 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
return false;
}
Playable media = controller.getMedia();
+ boolean isFeedMedia = media != null && (media instanceof FeedMedia);
- menu.findItem(R.id.support_item).setVisible(
- media != null && media.getPaymentLink() != null &&
- (media instanceof FeedMedia) &&
+ menu.findItem(R.id.support_item).setVisible(isFeedMedia && media.getPaymentLink() != null &&
((FeedMedia) media).getItem() != null &&
((FeedMedia) media).getItem().getFlattrStatus().flattrable()
);
@@ -308,20 +319,21 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
boolean hasWebsiteLink = media != null && media.getWebsiteLink() != null;
menu.findItem(R.id.visit_website_item).setVisible(hasWebsiteLink);
- boolean isItemAndHasLink = media != null && (media instanceof FeedMedia) &&
+ boolean isItemAndHasLink = isFeedMedia &&
((FeedMedia) media).getItem() != null && ((FeedMedia) media).getItem().getLink() != null;
menu.findItem(R.id.share_link_item).setVisible(isItemAndHasLink);
menu.findItem(R.id.share_link_with_position_item).setVisible(isItemAndHasLink);
- boolean isItemHasDownloadLink = media != null && (media instanceof FeedMedia) && ((FeedMedia) media).getDownload_url() != null;
+ boolean isItemHasDownloadLink = isFeedMedia && ((FeedMedia) media).getDownload_url() != null;
menu.findItem(R.id.share_download_url_item).setVisible(isItemHasDownloadLink);
menu.findItem(R.id.share_download_url_with_position_item).setVisible(isItemHasDownloadLink);
+ menu.findItem(R.id.share_file).setVisible(isFeedMedia && ((FeedMedia) media).fileExists());
menu.findItem(R.id.share_item).setVisible(hasWebsiteLink || isItemAndHasLink || isItemHasDownloadLink);
menu.findItem(R.id.add_to_favorites_item).setVisible(false);
menu.findItem(R.id.remove_from_favorites_item).setVisible(false);
- if(media != null && media instanceof FeedMedia) {
+ if (isFeedMedia) {
menu.findItem(R.id.add_to_favorites_item).setVisible(!isFavorite);
menu.findItem(R.id.remove_from_favorites_item).setVisible(isFavorite);
}
@@ -562,6 +574,11 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
ShareUtils.shareFeedItemDownloadLink(this, ((FeedMedia) media).getItem(), true);
}
break;
+ case R.id.share_file:
+ if (media instanceof FeedMedia) {
+ ShareUtils.shareFeedItemFile(this, ((FeedMedia) media));
+ }
+ break;
default:
return false;
}
@@ -650,6 +667,91 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
// Only meaningful on AudioplayerActivity, where it is overridden.
}
+ /**
+ * Abstract directions to skip forward or back (rewind) and encapsulates behavior to get or set preference (including update of UI on the skip buttons).
+ */
+ static public enum SkipDirection {
+ SKIP_FORWARD(
+ UserPreferences::getFastForwardSecs,
+ MediaplayerActivity::getTxtvFFFromActivity,
+ UserPreferences::setFastForwardSecs,
+ R.string.pref_fast_forward),
+ SKIP_REWIND(UserPreferences::getRewindSecs,
+ MediaplayerActivity::getTxtvRevFromActivity,
+ UserPreferences::setRewindSecs,
+ R.string.pref_rewind);
+
+ private final Supplier<Integer> getPrefSecsFn;
+ private final Func1<MediaplayerActivity, TextView> getTextViewFn;
+ private final Action1<Integer> setPrefSecsFn;
+ private final int titleResourceID;
+
+ /**
+ * Constructor for skip direction enum. Stores references to utility functions and resource
+ * id's that vary dependending on the direction.
+ *
+ * @param getPrefSecsFn Handle to function that retrieves current seconds of the skip delta
+ * @param getTextViewFn Handle to function that gets the TextView which displays the current skip delta value
+ * @param setPrefSecsFn Handle to function that sets the preference (setting) for the skip delta value (and optionally updates the button label with the current values)
+ * @param titleResourceID ID of the resource string with the title for a view
+ */
+ SkipDirection(Supplier<Integer> getPrefSecsFn, Func1<MediaplayerActivity, TextView> getTextViewFn, Action1<Integer> setPrefSecsFn, int titleResourceID) {
+ this.getPrefSecsFn = getPrefSecsFn;
+ this.getTextViewFn = getTextViewFn;
+ this.setPrefSecsFn = setPrefSecsFn;
+ this.titleResourceID = titleResourceID;
+ }
+
+
+ public int getPrefSkipSeconds() {
+ return(getPrefSecsFn.get());
+ }
+
+ /**
+ * Updates preferences for a forward or backward skip depending on the direction of the instance, optionally updating the UI.
+ *
+ * @param seconds Number of seconds to set the preference associated with the direction of the instance.
+ * @param activity MediaplyerActivity that contains textview to update the display of the skip delta setting (or null if nothing to update)
+ */
+ public void setPrefSkipSeconds(int seconds, @Nullable Activity activity) {
+ setPrefSecsFn.call(seconds);
+
+ if (activity != null && activity instanceof MediaplayerActivity) {
+ TextView tv = getTextViewFn.call((MediaplayerActivity)activity);
+ if (tv != null) tv.setText(String.valueOf(seconds));
+ }
+ }
+ public int getTitleResourceID() {
+ return titleResourceID;
+ }
+ }
+
+ static public void showSkipPreference(Activity activity, SkipDirection direction) {
+ int checked = 0;
+ int skipSecs = direction.getPrefSkipSeconds();
+ final int[] values = activity.getResources().getIntArray(R.array.seek_delta_values);
+ final String[] choices = new String[values.length];
+ for (int i = 0; i < values.length; i++) {
+ if (skipSecs == values[i]) {
+ checked = i;
+ }
+ choices[i] = String.valueOf(values[i]) + " " + activity.getString(R.string.time_seconds);
+ }
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+ builder.setTitle(direction.getTitleResourceID());
+ builder.setSingleChoiceItems(choices, checked, null);
+ builder.setNegativeButton(R.string.cancel_label, null);
+ builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> {
+ int choice = ((AlertDialog)dialog).getListView().getCheckedItemPosition();
+ if (choice < 0 || choice >= values.length) {
+ System.err.printf("Choice in showSkipPreference is out of bounds %d", choice);
+ } else {
+ direction.setPrefSkipSeconds(values[choice], activity);
+ }
+ });
+ builder.create().show();
+ }
protected void setupGUI() {
setContentView(getContentViewResourceId());
@@ -692,7 +794,7 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
butFF = (ImageButton) findViewById(R.id.butFF);
txtvFF = (TextView) findViewById(R.id.txtvFF);
if (txtvFF != null) {
- txtvFF.setText(String.valueOf(UserPreferences.getFastFowardSecs()));
+ txtvFF.setText(String.valueOf(UserPreferences.getFastForwardSecs()));
}
butSkip = (ImageButton) findViewById(R.id.butSkip);
@@ -704,37 +806,9 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
if (butRev != null) {
butRev.setOnClickListener(v -> onRewind());
- butRev.setOnLongClickListener(new View.OnLongClickListener() {
-
- int choice;
-
- @Override
- public boolean onLongClick(View v) {
- int checked = 0;
- int rewindSecs = UserPreferences.getRewindSecs();
- final int[] values = getResources().getIntArray(R.array.seek_delta_values);
- final String[] choices = new String[values.length];
- for (int i = 0; i < values.length; i++) {
- if (rewindSecs == values[i]) {
- checked = i;
- }
- choices[i] = String.valueOf(values[i]) + " " + getString(R.string.time_seconds);
- }
- choice = values[checked];
- AlertDialog.Builder builder = new AlertDialog.Builder(MediaplayerActivity.this);
- builder.setTitle(R.string.pref_rewind);
- builder.setSingleChoiceItems(choices, checked,
- (dialog, which) -> choice = values[which]);
- builder.setNegativeButton(R.string.cancel_label, null);
- builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> {
- UserPreferences.setPrefRewindSecs(choice);
- if(txtvRev != null){
- txtvRev.setText(String.valueOf(choice));
- }
- });
- builder.create().show();
- return true;
- }
+ butRev.setOnLongClickListener(v -> {
+ showSkipPreference(MediaplayerActivity.this, SkipDirection.SKIP_REWIND);
+ return true;
});
}
@@ -742,37 +816,9 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
if (butFF != null) {
butFF.setOnClickListener(v -> onFastForward());
- butFF.setOnLongClickListener(new View.OnLongClickListener() {
-
- int choice;
-
- @Override
- public boolean onLongClick(View v) {
- int checked = 0;
- int rewindSecs = UserPreferences.getFastFowardSecs();
- final int[] values = getResources().getIntArray(R.array.seek_delta_values);
- final String[] choices = new String[values.length];
- for (int i = 0; i < values.length; i++) {
- if (rewindSecs == values[i]) {
- checked = i;
- }
- choices[i] = String.valueOf(values[i]) + " " + getString(R.string.time_seconds);
- }
- choice = values[checked];
- AlertDialog.Builder builder = new AlertDialog.Builder(MediaplayerActivity.this);
- builder.setTitle(R.string.pref_fast_forward);
- builder.setSingleChoiceItems(choices, checked,
- (dialog, which) -> choice = values[which]);
- builder.setNegativeButton(R.string.cancel_label, null);
- builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> {
- UserPreferences.setPrefFastForwardSecs(choice);
- if(txtvFF != null) {
- txtvFF.setText(String.valueOf(choice));
- }
- });
- builder.create().show();
- return true;
- }
+ butFF.setOnLongClickListener(v -> {
+ showSkipPreference(MediaplayerActivity.this, SkipDirection.SKIP_FORWARD);
+ return false;
});
}
@@ -801,7 +847,7 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
return;
}
int curr = controller.getPosition();
- controller.seekTo(curr + UserPreferences.getFastFowardSecs() * 1000);
+ controller.seekTo(curr + UserPreferences.getFastForwardSecs() * 1000);
}
protected abstract int getContentViewResourceId();
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java
index 9d2f35e3d..b3cda69d3 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java
@@ -395,7 +395,7 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem
};
ConfirmationDialog conDialog = new ConfirmationDialog(this,
R.string.remove_feed_label,
- R.string.feed_delete_confirmation_msg) {
+ getString(R.string.feed_delete_confirmation_msg, feed.getTitle())) {
@Override
public void onConfirmButtonPressed(
DialogInterface dialog) {
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
index a4e661f62..f6bf11e66 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
@@ -146,7 +146,7 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
|| TextUtils.equals(getIntent().getAction(), Intent.ACTION_VIEW)) {
feedUrl = (TextUtils.equals(getIntent().getAction(), Intent.ACTION_SEND))
? getIntent().getStringExtra(Intent.EXTRA_TEXT) : getIntent().getDataString();
- getSupportActionBar().setTitle(R.string.add_new_feed_label);
+ getSupportActionBar().setTitle(R.string.add_feed_label);
} else {
throw new IllegalArgumentException("Activity must be started with feedurl argument!");
}
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromIntentActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromIntentActivity.java
index 02e16a7b5..4c94e2b76 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromIntentActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromIntentActivity.java
@@ -1,25 +1,30 @@
package de.danoeh.antennapod.activity;
+import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import de.danoeh.antennapod.core.preferences.UserPreferences;
-/** Lets the user start the OPML-import process. */
+/**
+ * Lets the user start the OPML-import process.
+ */
public class OpmlImportFromIntentActivity extends OpmlImportBaseActivity {
private static final String TAG = "OpmlImportFromIntentAct";
@Override
- protected void onCreate(Bundle savedInstanceState) {
- setTheme(UserPreferences.getTheme());
- super.onCreate(savedInstanceState);
+ protected void onCreate(Bundle savedInstanceState) {
+ setTheme(UserPreferences.getTheme());
+ super.onCreate(savedInstanceState);
- getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Uri uri = getIntent().getData();
- if(uri.toString().startsWith("/")) {
+ if (uri != null && uri.toString().startsWith("/")) {
uri = Uri.parse("file://" + uri.toString());
+ } else {
+ uri = Uri.parse(getIntent().getStringExtra(Intent.EXTRA_TEXT));
}
importUri(uri);
}
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/StatisticsActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/StatisticsActivity.java
index 9bb8f8856..b2ff43c43 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/StatisticsActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/StatisticsActivity.java
@@ -1,14 +1,18 @@
package de.danoeh.antennapod.activity;
+import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.ProgressBar;
+import android.widget.RadioButton;
import android.widget.TextView;
import de.danoeh.antennapod.R;
@@ -28,12 +32,16 @@ public class StatisticsActivity extends AppCompatActivity
implements AdapterView.OnItemClickListener {
private static final String TAG = StatisticsActivity.class.getSimpleName();
+ private static final String PREF_NAME = "StatisticsActivityPrefs";
+ private static final String PREF_COUNT_ALL = "countAll";
private Subscription subscription;
private TextView totalTimeTextView;
private ListView feedStatisticsList;
private ProgressBar progressBar;
private StatisticsListAdapter listAdapter;
+ private boolean countAll = false;
+ private SharedPreferences prefs;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -42,10 +50,14 @@ public class StatisticsActivity extends AppCompatActivity
getSupportActionBar().setDisplayShowHomeEnabled(true);
setContentView(R.layout.statistics_activity);
+ prefs = getSharedPreferences(PREF_NAME, MODE_PRIVATE);
+ countAll = prefs.getBoolean(PREF_COUNT_ALL, false);
+
totalTimeTextView = (TextView) findViewById(R.id.total_time);
feedStatisticsList = (ListView) findViewById(R.id.statistics_list);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
listAdapter = new StatisticsListAdapter(this);
+ listAdapter.setCountAll(countAll);
feedStatisticsList.setAdapter(listAdapter);
feedStatisticsList.setOnItemClickListener(this);
}
@@ -53,10 +65,15 @@ public class StatisticsActivity extends AppCompatActivity
@Override
public void onResume() {
super.onResume();
- progressBar.setVisibility(View.VISIBLE);
- totalTimeTextView.setVisibility(View.GONE);
- feedStatisticsList.setVisibility(View.GONE);
- loadStats();
+ refreshStatistics();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.statistics, menu);
+ return true;
}
@Override
@@ -64,22 +81,54 @@ public class StatisticsActivity extends AppCompatActivity
if (item.getItemId() == android.R.id.home) {
finish();
return true;
+ } else if (item.getItemId() == R.id.statistics_mode) {
+ selectStatisticsMode();
+ return true;
} else {
return super.onOptionsItemSelected(item);
}
}
- private void loadStats() {
- if(subscription != null) {
+ private void selectStatisticsMode() {
+ View contentView = View.inflate(this, R.layout.statistics_mode_select_dialog, null);
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setView(contentView);
+ builder.setTitle(R.string.statistics_mode);
+
+ if (countAll) {
+ ((RadioButton) contentView.findViewById(R.id.statistics_mode_count_all)).setChecked(true);
+ } else {
+ ((RadioButton) contentView.findViewById(R.id.statistics_mode_normal)).setChecked(true);
+ }
+
+ builder.setPositiveButton(android.R.string.ok, (dialog, which) -> {
+ countAll = ((RadioButton) contentView.findViewById(R.id.statistics_mode_count_all)).isChecked();
+ listAdapter.setCountAll(countAll);
+ prefs.edit().putBoolean(PREF_COUNT_ALL, countAll).apply();
+ refreshStatistics();
+ });
+
+ builder.show();
+ }
+
+ private void refreshStatistics() {
+ progressBar.setVisibility(View.VISIBLE);
+ totalTimeTextView.setVisibility(View.GONE);
+ feedStatisticsList.setVisibility(View.GONE);
+ loadStatistics();
+ }
+
+ private void loadStatistics() {
+ if (subscription != null) {
subscription.unsubscribe();
}
- subscription = Observable.fromCallable(() -> DBReader.getStatistics())
+ subscription = Observable.fromCallable(() -> DBReader.getStatistics(countAll))
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
if (result != null) {
totalTimeTextView.setText(Converter
- .shortLocalizedDuration(this, result.totalTime));
+ .shortLocalizedDuration(this, countAll ? result.totalTimeCountAll : result.totalTime));
listAdapter.update(result.feedTime);
progressBar.setVisibility(View.GONE);
totalTimeTextView.setVisibility(View.VISIBLE);
@@ -95,9 +144,10 @@ public class StatisticsActivity extends AppCompatActivity
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle(stats.feed.getTitle());
dialog.setMessage(getString(R.string.statistics_details_dialog,
- stats.episodesStarted,
+ countAll ? stats.episodesStartedIncludingMarked : stats.episodesStarted,
stats.episodes,
- Converter.shortLocalizedDuration(this, stats.timePlayed),
+ Converter.shortLocalizedDuration(this, countAll ?
+ stats.timePlayedCountAll : stats.timePlayed),
Converter.shortLocalizedDuration(this, stats.time)));
dialog.setPositiveButton(android.R.string.ok, null);
dialog.show();
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java
index 81d727283..62bff0891 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java
@@ -55,7 +55,7 @@ public class StorageErrorActivity extends AppCompatActivity {
openDirectoryChooser();
}
});
- if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
int readPermission = ActivityCompat.checkSelfPermission(this,
Manifest.permission.READ_EXTERNAL_STORAGE);
int writePermission = ActivityCompat.checkSelfPermission(this,
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java
index 37e00ab74..d7bebb672 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java
@@ -60,6 +60,7 @@ public class ChaptersListAdapter extends ArrayAdapter<Chapter> {
defaultTextColor = holder.title.getTextColors().getDefaultColor();
holder.start = (TextView) convertView.findViewById(R.id.txtvStart);
holder.link = (TextView) convertView.findViewById(R.id.txtvLink);
+ holder.duration = (TextView) convertView.findViewById(R.id.txtvDuration);
holder.butPlayChapter = (ImageButton) convertView.findViewById(R.id.butPlayChapter);
convertView.setTag(holder);
} else {
@@ -70,6 +71,16 @@ public class ChaptersListAdapter extends ArrayAdapter<Chapter> {
holder.title.setText(sc.getTitle());
holder.start.setText(Converter.getDurationStringLong((int) sc
.getStart()));
+
+ long duration;
+ if (position + 1 < media.getChapters().size()) {
+ duration = media.getChapters().get(position + 1).getStart() - sc.getStart();
+ } else {
+ duration = media.getDuration() - sc.getStart();
+ }
+ holder.duration.setText(getContext().getString(R.string.chapter_duration,
+ Converter.getDurationStringLong((int) duration)));
+
if (sc.getLink() != null) {
holder.link.setVisibility(View.VISIBLE);
holder.link.setText(sc.getLink());
@@ -155,6 +166,7 @@ public class ChaptersListAdapter extends ArrayAdapter<Chapter> {
TextView title;
TextView start;
TextView link;
+ TextView duration;
ImageButton butPlayChapter;
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/StatisticsListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/StatisticsListAdapter.java
index fe891281b..c060083a6 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/StatisticsListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/StatisticsListAdapter.java
@@ -25,11 +25,15 @@ import de.danoeh.antennapod.core.util.Converter;
public class StatisticsListAdapter extends BaseAdapter {
private Context context;
List<DBReader.StatisticsItem> feedTime = new ArrayList<>();
+ private boolean countAll = true;
public StatisticsListAdapter(Context context) {
this.context = context;
}
+ public void setCountAll(boolean countAll) {
+ this.countAll = countAll;
+ }
@Override
public int getCount() {
@@ -77,7 +81,8 @@ public class StatisticsListAdapter extends BaseAdapter {
holder.title.setText(feed.getTitle());
holder.time.setText(Converter.shortLocalizedDuration(context,
- feedTime.get(position).timePlayed));
+ countAll ? feedTime.get(position).timePlayedCountAll
+ : feedTime.get(position).timePlayed));
return convertView;
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java
index e381b4651..f1f8be559 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java
@@ -2,6 +2,7 @@ package de.danoeh.antennapod.adapter.itunes;
import android.content.Context;
import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
@@ -69,7 +70,7 @@ public class ItunesAdapter extends ArrayAdapter<ItunesAdapter.Podcast> {
//Set the title
viewHolder.titleView.setText(podcast.title);
- if(!podcast.feedUrl.contains("itunes.apple.com")) {
+ if(podcast.feedUrl != null && !podcast.feedUrl.contains("itunes.apple.com")) {
viewHolder.urlView.setText(podcast.feedUrl);
viewHolder.urlView.setVisibility(View.VISIBLE);
} else {
@@ -102,14 +103,16 @@ public class ItunesAdapter extends ArrayAdapter<ItunesAdapter.Podcast> {
/**
* URL of the podcast image
*/
+ @Nullable
public final String imageUrl;
/**
* URL of the podcast feed
*/
+ @Nullable
public final String feedUrl;
- private Podcast(String title, String imageUrl, String feedUrl) {
+ private Podcast(String title, @Nullable String imageUrl, @Nullable String feedUrl) {
this.title = title;
this.imageUrl = imageUrl;
this.feedUrl = feedUrl;
@@ -122,9 +125,9 @@ public class ItunesAdapter extends ArrayAdapter<ItunesAdapter.Podcast> {
* @throws JSONException
*/
public static Podcast fromSearch(JSONObject json) throws JSONException {
- String title = json.getString("collectionName");
- String imageUrl = json.getString("artworkUrl100");
- String feedUrl = json.getString("feedUrl");
+ String title = json.optString("collectionName", "");
+ String imageUrl = json.optString("artworkUrl100", null);
+ String feedUrl = json.optString("feedUrl", null);
return new Podcast(title, imageUrl, feedUrl);
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
index ab8808093..bbfd1688d 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
@@ -80,6 +80,7 @@ public class AllEpisodesFragment extends Fragment {
private boolean viewsCreated = false;
private boolean isUpdatingFeeds;
+ protected boolean isMenuInvalidationAllowed = false;
protected Subscription subscription;
private LinearLayoutManager layoutManager;
@@ -430,7 +431,7 @@ public class AllEpisodesFragment extends Fragment {
Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
DownloaderUpdate update = event.update;
downloaderList = update.downloaders;
- if (isUpdatingFeeds != update.feedIds.length > 0) {
+ if (isMenuInvalidationAllowed && isUpdatingFeeds != update.feedIds.length > 0) {
getActivity().supportInvalidateOptionsMenu();
}
if(listAdapter != null && update.mediaIds.length > 0) {
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesFragment.java
index f23981935..e2fbd91f3 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesFragment.java
@@ -79,6 +79,11 @@ public class EpisodesFragment extends Fragment {
public static class EpisodesPagerAdapter extends FragmentPagerAdapter {
private final Resources resources;
+ private AllEpisodesFragment[] fragments = {
+ new NewEpisodesFragment(),
+ new AllEpisodesFragment(),
+ new FavoriteEpisodesFragment()
+ };
public EpisodesPagerAdapter(FragmentManager fm, Resources resources) {
super(fm);
@@ -87,15 +92,7 @@ public class EpisodesFragment extends Fragment {
@Override
public Fragment getItem(int position) {
- switch (position) {
- case POS_ALL_EPISODES:
- return new AllEpisodesFragment();
- case POS_NEW_EPISODES:
- return new NewEpisodesFragment();
- case POS_FAV_EPISODES:
- return new FavoriteEpisodesFragment();
- }
- return null;
+ return fragments[position];
}
@Override
@@ -116,5 +113,14 @@ public class EpisodesFragment extends Fragment {
return super.getPageTitle(position);
}
}
+
+ @Override
+ public void setPrimaryItem(ViewGroup container, int position, Object object) {
+ super.setPrimaryItem(container, position, object);
+ for (int i = 0; i < TOTAL_COUNT; i++) {
+ // Invalidating the OptionsMenu is only allowed for the currently active fragment
+ fragments[i].isMenuInvalidationAllowed = (i == position);
+ }
+ }
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java
index 75f9c0d35..a118673a6 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java
@@ -110,6 +110,8 @@ public class ItemlistFragment extends ListFragment {
private TextView txtvTitle;
private IconTextView txtvFailure;
+ private ImageView imgvBackground;
+ private ImageView imgvCover;
private TextView txtvInformation;
@@ -265,7 +267,7 @@ public class ItemlistFragment extends ListFragment {
};
ConfirmationDialog conDialog = new ConfirmationDialog(getActivity(),
R.string.remove_feed_label,
- R.string.feed_delete_confirmation_msg) {
+ getString(R.string.feed_delete_confirmation_msg, feed.getTitle())) {
@Override
public void onConfirmButtonPressed(
@@ -471,6 +473,7 @@ public class ItemlistFragment extends ListFragment {
Log.e(TAG, "Unable to refresh header view");
return;
}
+ loadFeedImage();
if(feed.hasLastUpdateFailed()) {
txtvFailure.setVisibility(View.VISIBLE);
} else {
@@ -508,8 +511,8 @@ public class ItemlistFragment extends ListFragment {
txtvTitle = (TextView) header.findViewById(R.id.txtvTitle);
TextView txtvAuthor = (TextView) header.findViewById(R.id.txtvAuthor);
- ImageView imgvBackground = (ImageView) header.findViewById(R.id.imgvBackground);
- ImageView imgvCover = (ImageView) header.findViewById(R.id.imgvCover);
+ imgvBackground = (ImageView) header.findViewById(R.id.imgvBackground);
+ imgvCover = (ImageView) header.findViewById(R.id.imgvCover);
ImageButton butShowInfo = (ImageButton) header.findViewById(R.id.butShowInfo);
txtvInformation = (TextView) header.findViewById(R.id.txtvInformation);
txtvFailure = (IconTextView) header.findViewById(R.id.txtvFailure);
@@ -521,6 +524,20 @@ public class ItemlistFragment extends ListFragment {
// https://github.com/bumptech/glide/issues/529
imgvBackground.setColorFilter(new LightingColorFilter(0xff828282, 0x000000));
+ loadFeedImage();
+
+ butShowInfo.setOnClickListener(v -> {
+ if (viewsCreated && itemsLoaded) {
+ Intent startIntent = new Intent(getActivity(), FeedInfoActivity.class);
+ startIntent.putExtra(FeedInfoActivity.EXTRA_FEED_ID,
+ feed.getId());
+ startActivity(startIntent);
+ }
+ });
+ headerCreated = true;
+ }
+
+ private void loadFeedImage() {
Glide.with(getActivity())
.load(feed.getImageLocation())
.placeholder(R.color.image_readability_tint)
@@ -538,16 +555,6 @@ public class ItemlistFragment extends ListFragment {
.fitCenter()
.dontAnimate()
.into(imgvCover);
-
- butShowInfo.setOnClickListener(v -> {
- if (viewsCreated && itemsLoaded) {
- Intent startIntent = new Intent(getActivity(), FeedInfoActivity.class);
- startIntent.putExtra(FeedInfoActivity.EXTRA_FEED_ID,
- feed.getId());
- startActivity(startIntent);
- }
- });
- headerCreated = true;
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java
index 01119bcff..9626e6c2e 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java
@@ -178,7 +178,7 @@ public class SubscriptionFragment extends Fragment {
};
ConfirmationDialog conDialog = new ConfirmationDialog(getContext(),
R.string.remove_feed_label,
- R.string.feed_delete_confirmation_msg) {
+ getString(R.string.feed_delete_confirmation_msg, feed.getTitle())) {
@Override
public void onConfirmButtonPressed(
DialogInterface dialog) {
diff --git a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java
index 6799114f7..57b7c359c 100644
--- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java
+++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java
@@ -101,6 +101,8 @@ public class FeedItemMenuHandler {
mi.setItemVisibility(R.id.share_download_url_with_position_item, false);
}
+ mi.setItemVisibility(R.id.share_file, hasMedia && selectedItem.getMedia().fileExists());
+
if (selectedItem.isPlayed()) {
mi.setItemVisibility(R.id.mark_read_item, false);
} else {
@@ -239,6 +241,9 @@ public class FeedItemMenuHandler {
case R.id.share_download_url_with_position_item:
ShareUtils.shareFeedItemDownloadLink(context, selectedItem, true);
break;
+ case R.id.share_file:
+ ShareUtils.shareFeedItemFile(context, selectedItem.getMedia());
+ break;
default:
Log.d(TAG, "Unknown menuItemId: " + menuItemId);
return false;
diff --git a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java
index 7f1d3075f..2ca7dd029 100644
--- a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java
+++ b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java
@@ -54,6 +54,7 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.AboutActivity;
import de.danoeh.antennapod.activity.DirectoryChooserActivity;
import de.danoeh.antennapod.activity.MainActivity;
+import de.danoeh.antennapod.activity.MediaplayerActivity;
import de.danoeh.antennapod.activity.PreferenceActivity;
import de.danoeh.antennapod.activity.PreferenceActivityGingerbread;
import de.danoeh.antennapod.activity.StatisticsActivity;
@@ -96,6 +97,8 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
private static final String PREF_CHOOSE_DATA_DIR = "prefChooseDataDir";
private static final String AUTO_DL_PREF_SCREEN = "prefAutoDownloadSettings";
private static final String PREF_PLAYBACK_SPEED_LAUNCHER = "prefPlaybackSpeedLauncher";
+ public static final String PREF_PLAYBACK_REWIND_DELTA_LAUNCHER = "prefPlaybackRewindDeltaLauncher";
+ public static final String PREF_PLAYBACK_FAST_FORWARD_DELTA_LAUNCHER = "prefPlaybackFastForwardDeltaLauncher";
private static final String PREF_GPODNET_LOGIN = "pref_gpodnet_authenticate";
private static final String PREF_GPODNET_SETLOGIN_INFORMATION = "pref_gpodnet_setlogin_information";
private static final String PREF_GPODNET_SYNC = "pref_gpodnet_sync";
@@ -333,6 +336,16 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
VariableSpeedDialog.showDialog(activity);
return true;
});
+ ui.findPreference(PreferenceController.PREF_PLAYBACK_REWIND_DELTA_LAUNCHER)
+ .setOnPreferenceClickListener(preference -> {
+ MediaplayerActivity.showSkipPreference(activity, MediaplayerActivity.SkipDirection.SKIP_REWIND);
+ return true;
+ });
+ ui.findPreference(PreferenceController.PREF_PLAYBACK_FAST_FORWARD_DELTA_LAUNCHER)
+ .setOnPreferenceClickListener(preference -> {
+ MediaplayerActivity.showSkipPreference(activity, MediaplayerActivity.SkipDirection.SKIP_FORWARD);
+ return true;
+ });
ui.findPreference(PreferenceController.PREF_GPODNET_SETLOGIN_INFORMATION)
.setOnPreferenceClickListener(preference -> {
AuthenticationDialog dialog = new AuthenticationDialog(activity,
@@ -701,7 +714,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
val = String.format(context.getString(R.string.pref_autoUpdateIntervallOrTime_at),
timeOfDayStr);
} else {
- val = context.getString(R.string.pref_smart_mark_as_played_disabled);
+ val = context.getString(R.string.pref_smart_mark_as_played_disabled); // TODO: Is this a bug? Otherwise document why is this related to smart mark???
}
}
String summary = context.getString(R.string.pref_autoUpdateIntervallOrTime_sum) + "\n"
@@ -746,7 +759,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
clearAutodownloadSelectedNetworsPreference();
}
// get configured networks
- WifiManager wifiservice = (WifiManager) activity.getSystemService(Context.WIFI_SERVICE);
+ WifiManager wifiservice = (WifiManager) activity.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
List<WifiConfiguration> networks = wifiservice.getConfiguredNetworks();
if (networks != null) {
diff --git a/app/src/main/play/es_ES/listing/fulldescription b/app/src/main/play/es_ES/listing/fulldescription
index 46dce8df5..1ce12e3b4 100644
--- a/app/src/main/play/es_ES/listing/fulldescription
+++ b/app/src/main/play/es_ES/listing/fulldescription
@@ -1,6 +1,4 @@
-Easy-to-use, flexible and open-source podcast manager and player
-
-AntennaPod is a podcast manager and player that gives you instant access to millions of free and paid podcasts, from independent podcasters to large publishing houses such as the BBC, NPR and CNN. Add, import and export their feeds hassle-free using the iTunes podcast database, OPML files or simple RSS URLs. Save effort, battery power and mobile data usage with powerful automation controls for downloading episodes (episode filtering, specify times, intervals and WiFi networks) and deleting episodes (based your favorites and delay settings).<br>
+AntennaPod is a podcast manager and player that gives you instant access to millions of free and paid podcasts, from independent podcasters to large publishing houses such as the BBC, NPR and CNN. Add, import and export their feeds hassle-free using the iTunes podcast database, OPML files or simple RSS URLs. Save effort, battery power and mobile data usage with powerful automation controls for downloading episodes (specify times, intervals and WiFi networks) and deleting episodes (based your favourites and delay settings).<br>
But most importantly: Download, stream or queue episodes and enjoy them the way you like with adjustable playback speeds, chapter support and a sleep timer. You can even show your love to the content creators with our Flattr integration.
Made by podcast-enthousiast, AntennaPod is free in all senses of the word: open source, no costs, no ads.
@@ -14,32 +12,32 @@ IMPORT, ORGANIZE AND PLAY<br>
&#8226; Take advantage of paged feeds (www.podlove.org/paged-feeds)
KEEP TRACK, SHARE & APPRECIATE<br>
-&#8226; Keep track of the best of the best by marking episodes as favorites<br>
+&#8226; Keep track of the best of the best by marking episodes as favourites<br>
&#8226; Find that one episode through the playback history or by searching (titles and shownotes)<br>
&#8226; Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br>
&#8226; Support content creators with Flattr integration including automatic flattring
CONTROL THE SYSTEM<br>
-&#8226; Take control over automated downloading: choose feeds, filter episodes based on keywords, exclude mobile networks, select specific WiFi networks, require the phone to be charging and set times or intervals<br>
-&#8226; Manage storage by setting the amount of cached episodes, smart deletion (based on your favorites and play status) and selecting your preferred location<br>
+&#8226; Take control over automated downloading: choose feeds, exclude mobile networks, select specific WiFi networks, require the phone to be charging and set times or intervals<br>
+&#8226; Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br>
&#8226; Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br>
&#8226; Adapt to your environment using the light and dark theme<br>
&#8226; Back-up your subscriptions with the gPodder.net integration and OPML export
-<b>Join the AntennaPod community!</b>
+<b>¡Únete a la comunidad de AntennaPod!</b><br>
AntennaPod is under active development by volunteers. You can contribute too, with code or with comment!
-Ask your question or give feedback via Twitter:
-https://twitter.com/@AntennaPod
+GitHub is the place to go for feature requests, bug reports and code contributions:<br>
+https://www.github.com/AntennaPod/AntennaPod
-Share your ideas, favorite podcasting moments and gratitude to all the volunteers in our Google group:
+Our Google Group is the place to share your ideas, favourite podcasting moments and gratitude to all the volunteers:<br>
https://groups.google.com/forum/#!forum/antennapod
-Help translate the app to your mother tongue on Transifex:
-https://www.transifex.com/antennapod/antennapod
+Have a question or want to give us feedback?
+https://twitter.com/@AntennaPod
-Check out our Beta Testing programme to get the latest features first:
-https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
+Transifex is the place to help with translations:<br>
+https://www.transifex.com/antennapod/antennapod
-Visit GitHub to submit feature requests, bug reports and code contributions:
-https://www.github.com/AntennaPod/AntennaPod \ No newline at end of file
+Check out our Beta Testing programme to get the latest features first:<br>
+https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod \ No newline at end of file
diff --git a/app/src/main/play/et/listing/fulldescription b/app/src/main/play/et/listing/fulldescription
index fdd02a737..d33e8f4e8 100644
--- a/app/src/main/play/et/listing/fulldescription
+++ b/app/src/main/play/et/listing/fulldescription
@@ -1,6 +1,4 @@
-Easy-to-use, flexible and open-source podcast manager and player
-
-AntennaPod is a podcast manager and player that gives you instant access to millions of free and paid podcasts, from independent podcasters to large publishing houses such as the BBC, NPR and CNN. Add, import and export their feeds hassle-free using the iTunes podcast database, OPML files or simple RSS URLs. Save effort, battery power and mobile data usage with powerful automation controls for downloading episodes (episode filtering, specify times, intervals and WiFi networks) and deleting episodes (based your favorites and delay settings).<br>
+AntennaPod is a podcast manager and player that gives you instant access to millions of free and paid podcasts, from independent podcasters to large publishing houses such as the BBC, NPR and CNN. Add, import and export their feeds hassle-free using the iTunes podcast database, OPML files or simple RSS URLs. Save effort, battery power and mobile data usage with powerful automation controls for downloading episodes (specify times, intervals and WiFi networks) and deleting episodes (based your favourites and delay settings).<br>
But most importantly: Download, stream or queue episodes and enjoy them the way you like with adjustable playback speeds, chapter support and a sleep timer. You can even show your love to the content creators with our Flattr integration.
Made by podcast-enthousiast, AntennaPod is free in all senses of the word: open source, no costs, no ads.
@@ -14,14 +12,14 @@ IMPORDI, ORGANISEERI JA ESITA<br>
&#8226; Kasuta ära lehekülgedeks jagatud voogusid (www.podlove.org/paged-feeds)
JÄLGI, JAGA JA HINDA<br>
-&#8226; Keep track of the best of the best by marking episodes as favorites<br>
+&#8226; Keep track of the best of the best by marking episodes as favourites<br>
&#8226; Find that one episode through the playback history or by searching (titles and shownotes)<br>
&#8226; Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br>
&#8226; Support content creators with Flattr integration including automatic flattring
KONTROLLI SÜSTEEMI<br>
-&#8226; Take control over automated downloading: choose feeds, filter episodes based on keywords, exclude mobile networks, select specific WiFi networks, require the phone to be charging and set times or intervals<br>
-&#8226; Manage storage by setting the amount of cached episodes, smart deletion (based on your favorites and play status) and selecting your preferred location<br>
+&#8226; Take control over automated downloading: choose feeds, exclude mobile networks, select specific WiFi networks, require the phone to be charging and set times or intervals<br>
+&#8226; Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br>
&#8226; Kasuta AntennaPodi omaenda keeles (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH, ET)<br>
&#8226; Kohandu oma keskkonnale valides heleda ja tumeda ekraani vahet<br>
&#8226; Back-up your subscriptions with the gPodder.net integration and OPML export
@@ -29,17 +27,17 @@ KONTROLLI SÜSTEEMI<br>
<b>Liitu AntennaPodi kogukonnaga!</b>
AntennaPod on vabatahtlike poolt aktiivselt arendamisel. Ka sina võid anda oma osa kirjutades koodi või andes oma kommentaare!
-Küsi küsimusi või anna tagasisidet läbi Twitteri:
-https://twitter.com/@AntennaPod
+GitHub is the place to go for feature requests, bug reports and code contributions:<br>
+https://www.github.com/AntennaPod/AntennaPod
-Share your ideas, favorite podcasting moments and gratitude to all the volunteers in our Google group:
+Our Google Group is the place to share your ideas, favourite podcasting moments and gratitude to all the volunteers:<br>
https://groups.google.com/forum/#!forum/antennapod
-Aita tõlkida rakendust oma emakeelde Transifexis:
+Kas sul on küsimus või soovid anda meile tagasisidet?
+https://twitter.com/@AntennaPod
+
+Transifex on koht, kus saad abiks olla tõlkimisega:<br>
https://www.transifex.com/antennapod/antennapod
Vaata meie beeta testide programmi, et saada esimesena osa värskeimatest omadustest:
-https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
-
-Külasta GitHubi, et esitada soove uute võimaluste kohta, lisada veateateid ja anda oma osa koodi kirjutamisesse:
-https://www.github.com/AntennaPod/AntennaPod \ No newline at end of file
+https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod \ No newline at end of file
diff --git a/app/src/main/play/fr/listing/fulldescription b/app/src/main/play/fr/listing/fulldescription
index b46f1a985..372e1da60 100644
--- a/app/src/main/play/fr/listing/fulldescription
+++ b/app/src/main/play/fr/listing/fulldescription
@@ -1,9 +1,7 @@
-Un lecteur et gestionnaire de podcast facile à utiliser et flexible
+AntennaPod est un lecteur et gestionnaire de podcast permettant l'accès à des millions de podcast gratuits ou payants produit aussi bien par des podcasters indépendants que de gros éditeurs comme la BBC, NPR ou CNN. Ajoutez, importez et exportez leurs flux facilement à partir d'ITunes, de fichiers OPML ou simplement à partir de liens RSS. Gagnez du temps, préservez votre batterie et consommation internet grâce à une automatisation puissante des téléchargements (date, fréquence, choix du réseau WiFi, etc...) et des suppressions d’épisodes écoutés (selon vos critères)<br>
+Avant tout : téléchargez, streamez ou ajoutez à la liste de lecture vos épisodes et écoutez les comme vous voulez grâce au réglage de vitesse de lecture, au support des chapitres et au minuteur d'arrêt. Vous pouvez même montrer votre appréciation aux créateurs de contenu avec notre intégration de Flattr.
-AntennaPod est un lecteur et gestionnaire de podcast permettant l'accès à des millions de podcasts gratuits ou payants produit aussi bien par des podcasters indépendants que de gros éditeurs comme la BBC, NPR ou CNN. Ajoutez, importez et exportez leurs flux facilement à partir d'ITunes, de fichiers OPML ou simplement à partir de liens RSS. Gagnez du temps, préservez votre batterie et consommation internet grâce à une automatisation puissante des téléchargements (filtrage des épisodes, date, fréquence, choix du réseau WiFi, etc...) et des suppressions d’épisodes écoutés (selon vos critères).<br>
-Plus important : téléchargez, streamez ou ajoutez à la liste de lecture vos épisodes et écoutez les comme vous voulez grâce au réglage de vitesse de lecture, au support des chapitres et au minuteur d'arrêt automatique. Vous pouvez même montrer votre appréciation aux créateurs de contenu avec notre intégration de Flattr.
-
-Programmé par des fans de podcast, AntennaPod est gratuit dans tous les sens du terme : open source, gratuit et sans publicité.
+Conçu par des fans de podcast, AntennaPod est gratuit dans tous les sens du terme : open source, gratuit et sans publicité.
<b>Caractéristiques complètes :</b><br>
IMPORTER, GÉRER ET ÉCOUTER<br>
@@ -14,32 +12,32 @@ IMPORTER, GÉRER ET ÉCOUTER<br>
&#8226; Tirez profit des flux paginés (www.podlove.org/paged-feeds)
SUIVEZ, PARTAGEZ & PROFITEZ<br>
-&#8226; Gardez trace des meilleurs épisodes en les marquant comme favoris<br>
+&#8226; Marquer les meilleurs épisodes en tant que favoris<br>
&#8226; Retrouvez un épisode à partir de l'historique de lecture ou en recherchant parmi les titres et commentaires des épisodes précédents<br>
&#8226; Partagez vos épisodes et flux sur les réseaux sociaux, par email, sur gPodder.net ou en les exportant au format OPML<br>
&#8226; Soutenez les créateurs de contenu avec l'intégration à Flattr et la possibilité de flatter automatiquement
CONTRÔLER LE SYSTÈME<br>
-&#8226; Prenez le contrôle en automatisant vos téléchargements : choix des flux, filtrage des épisodes, restriction de la connexion mobile, sélection du réseau WIFI à utiliser, uniquement durant la recharge et spécifiez la fréquence de mise à jour vous-même<br>
+&#8226; Prenez le contrôle en automatisant vos téléchargements : choix des flux, restriction de la connexion mobile, sélection du réseau WIFI à utiliser, uniquement durant la recharge et spécifiez la fréquence de mise à jour vous-même<br>
&#8226; Gérez l'espace de stockage en paramétrant le nombre d'épisodes à garder, leur suppression automatique (en fonction de vos favoris et de leur statut) et leur emplacement sur le disque<br>
&#8226; Utilisez AntennaPod dans votre langue (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br>
&#8226; Choix d'un thème clair ou sombre selon vos préférences<br>
&#8226; Sauvegardez vos abonnements avec l’intégration à gPodder.net et les exports OPML
-<b>Rejoignez la communauté d'AntennaPod !</b>
+<b>Rejoignez la communauté d'AntennaPod !</b><br>
AntennaPod est développé activement par des volontaires. Vous pouvez aussi contribuer avec du code, des traductions ou des commentaires !
-Posez vos questions ou donnez votre avis sur Twitter :
-https://twitter.com/@AntennaPod
+GitHub est l'endroit où aller pour demander de nouvelles options, faire part de bug ou pour contribuer au code :<br>
+https://www.github.com/AntennaPod/AntennaPod
-Partager vos idées, podcast préférés et adressez vos remerciements à tous les bénévoles dans notre groupe Google :
+Rejoignez notre Google Group pour partager vos idées, podcast préférés et vos remerciements à tous les bénévoles :<br>
https://groups.google.com/forum/#!forum/antennapod
-Aider à traduire l'application dans votre langue sur Transifex :
-https://www.transifex.com/antennapod/antennapod
+Vous avez une question ou des suggestions ?
+https://twitter.com/@AntennaPod
-Jetez un coup d’œil à la version Beta pour bénéficier des dernières nouveautés :
-https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
+Retrouvez nous sur Transifex pour contribuer à la traduction de cette app :<br>
+https://www.transifex.com/antennapod/antennapod
-Allez sur GitHub pour demander de nouvelles options, faire part de bugs et pour contribuer au code :
-https://www.github.com/AntennaPod/AntennaPod \ No newline at end of file
+Jetez un coup d’œil à notre programme de version Beta pour bénéficier des dernières options :<br>
+https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod \ No newline at end of file
diff --git a/app/src/main/play/gl/listing/fulldescription b/app/src/main/play/gl/listing/fulldescription
new file mode 100644
index 000000000..87b477fdc
--- /dev/null
+++ b/app/src/main/play/gl/listing/fulldescription
@@ -0,0 +1,43 @@
+AntennaPod is a podcast manager and player that gives you instant access to millions of free and paid podcasts, from independent podcasters to large publishing houses such as the BBC, NPR and CNN. Add, import and export their feeds hassle-free using the iTunes podcast database, OPML files or simple RSS URLs. Save effort, battery power and mobile data usage with powerful automation controls for downloading episodes (specify times, intervals and WiFi networks) and deleting episodes (based your favourites and delay settings).<br>
+But most importantly: Download, stream or queue episodes and enjoy them the way you like with adjustable playback speeds, chapter support and a sleep timer. You can even show your love to the content creators with our Flattr integration.
+
+Made by podcast-enthousiast, AntennaPod is free in all senses of the word: open source, no costs, no ads.
+
+<b>All features:</b><br>
+IMPORT, ORGANIZE AND PLAY<br>
+&#8226; Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br>
+&#8226; Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br>
+&#8226; Enjoy listening your way with adjustable playback speed, chapter support (MP3, VorbisComment and Podlove), remembered playback position and an advanced sleep timer (shake to reset, lower volume and slow down playback)<br>
+&#8226; Access password-protected feeds and episodes<br>
+&#8226; Take advantage of paged feeds (www.podlove.org/paged-feeds)
+
+KEEP TRACK, SHARE & APPRECIATE<br>
+&#8226; Keep track of the best of the best by marking episodes as favourites<br>
+&#8226; Find that one episode through the playback history or by searching (titles and shownotes)<br>
+&#8226; Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br>
+&#8226; Support content creators with Flattr integration including automatic flattring
+
+CONTROL THE SYSTEM<br>
+&#8226; Take control over automated downloading: choose feeds, exclude mobile networks, select specific WiFi networks, require the phone to be charging and set times or intervals<br>
+&#8226; Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br>
+&#8226; Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br>
+&#8226; Adapt to your environment using the light and dark theme<br>
+&#8226; Back-up your subscriptions with the gPodder.net integration and OPML export
+
+<b>Join the AntennaPod community!</b><br>
+AntennaPod is under active development by volunteers. You can contribute too, with code or with comment!
+
+GitHub is the place to go for feature requests, bug reports and code contributions:<br>
+https://www.github.com/AntennaPod/AntennaPod
+
+Our Google Group is the place to share your ideas, favourite podcasting moments and gratitude to all the volunteers:<br>
+https://groups.google.com/forum/#!forum/antennapod
+
+Have a question or want to give us feedback?
+https://twitter.com/@AntennaPod
+
+Transifex is the place to help with translations:<br>
+https://www.transifex.com/antennapod/antennapod
+
+Check out our Beta Testing programme to get the latest features first:<br>
+https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod \ No newline at end of file
diff --git a/app/src/main/play/is/listing/fulldescription b/app/src/main/play/is/listing/fulldescription
new file mode 100644
index 000000000..87b477fdc
--- /dev/null
+++ b/app/src/main/play/is/listing/fulldescription
@@ -0,0 +1,43 @@
+AntennaPod is a podcast manager and player that gives you instant access to millions of free and paid podcasts, from independent podcasters to large publishing houses such as the BBC, NPR and CNN. Add, import and export their feeds hassle-free using the iTunes podcast database, OPML files or simple RSS URLs. Save effort, battery power and mobile data usage with powerful automation controls for downloading episodes (specify times, intervals and WiFi networks) and deleting episodes (based your favourites and delay settings).<br>
+But most importantly: Download, stream or queue episodes and enjoy them the way you like with adjustable playback speeds, chapter support and a sleep timer. You can even show your love to the content creators with our Flattr integration.
+
+Made by podcast-enthousiast, AntennaPod is free in all senses of the word: open source, no costs, no ads.
+
+<b>All features:</b><br>
+IMPORT, ORGANIZE AND PLAY<br>
+&#8226; Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br>
+&#8226; Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br>
+&#8226; Enjoy listening your way with adjustable playback speed, chapter support (MP3, VorbisComment and Podlove), remembered playback position and an advanced sleep timer (shake to reset, lower volume and slow down playback)<br>
+&#8226; Access password-protected feeds and episodes<br>
+&#8226; Take advantage of paged feeds (www.podlove.org/paged-feeds)
+
+KEEP TRACK, SHARE & APPRECIATE<br>
+&#8226; Keep track of the best of the best by marking episodes as favourites<br>
+&#8226; Find that one episode through the playback history or by searching (titles and shownotes)<br>
+&#8226; Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br>
+&#8226; Support content creators with Flattr integration including automatic flattring
+
+CONTROL THE SYSTEM<br>
+&#8226; Take control over automated downloading: choose feeds, exclude mobile networks, select specific WiFi networks, require the phone to be charging and set times or intervals<br>
+&#8226; Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br>
+&#8226; Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br>
+&#8226; Adapt to your environment using the light and dark theme<br>
+&#8226; Back-up your subscriptions with the gPodder.net integration and OPML export
+
+<b>Join the AntennaPod community!</b><br>
+AntennaPod is under active development by volunteers. You can contribute too, with code or with comment!
+
+GitHub is the place to go for feature requests, bug reports and code contributions:<br>
+https://www.github.com/AntennaPod/AntennaPod
+
+Our Google Group is the place to share your ideas, favourite podcasting moments and gratitude to all the volunteers:<br>
+https://groups.google.com/forum/#!forum/antennapod
+
+Have a question or want to give us feedback?
+https://twitter.com/@AntennaPod
+
+Transifex is the place to help with translations:<br>
+https://www.transifex.com/antennapod/antennapod
+
+Check out our Beta Testing programme to get the latest features first:<br>
+https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod \ No newline at end of file
diff --git a/app/src/main/play/it_IT/listing/fulldescription b/app/src/main/play/it_IT/listing/fulldescription
index 772d41dff..eb2abb40d 100644
--- a/app/src/main/play/it_IT/listing/fulldescription
+++ b/app/src/main/play/it_IT/listing/fulldescription
@@ -1,6 +1,4 @@
-Un riproduttore e gestore di podcast open-source, flessibile e facile da usare
-
-AntennaPod is a podcast manager and player that gives you instant access to millions of free and paid podcasts, from independent podcasters to large publishing houses such as the BBC, NPR and CNN. Add, import and export their feeds hassle-free using the iTunes podcast database, OPML files or simple RSS URLs. Save effort, battery power and mobile data usage with powerful automation controls for downloading episodes (episode filtering, specify times, intervals and WiFi networks) and deleting episodes (based your favorites and delay settings).<br>
+AntennaPod è un riproduttore e gestore di podcast che ti da accesso immediato a milioni di podcast gratuiti e a pagamento, dai podcaster indipendenti alle più grandi emittenti come BBC, NPR e CNN. Aggiungi, importa e esporta in modo semplici usando il database di podcast di iTunes, da file OPML o da semplici URL RSS. Risparmia fatica, batteria e dati con il potente controllo automatizzato per il download di episodi (orari specifici, intervalli e reti WiFi) e l'eliminazione degli episodi.<br>
But most importantly: Download, stream or queue episodes and enjoy them the way you like with adjustable playback speeds, chapter support and a sleep timer. You can even show your love to the content creators with our Flattr integration.
Creato da amanti dei podcast, AntennaPod è libero in tutti i sensi: open source, gratis, senza pubblicità.
@@ -14,32 +12,32 @@ IMPORTA, ORGANIZZA E RIPRODUCI<br>
&#8226; Take advantage of paged feeds (www.podlove.org/paged-feeds)
TIENI TRACCIA, CONDIVIDI & APPREZZA<br>
-&#8226; Keep track of the best of the best by marking episodes as favorites<br>
+&#8226; Keep track of the best of the best by marking episodes as favourites<br>
&#8226; Find that one episode through the playback history or by searching (titles and shownotes)<br>
&#8226; Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br>
&#8226; Supporta i creatori di contenuti tramite l'integrazione con Flattr e il flattring automatico
CONTROLLA IL SISTEMA<br>
-&#8226; Take control over automated downloading: choose feeds, filter episodes based on keywords, exclude mobile networks, select specific WiFi networks, require the phone to be charging and set times or intervals<br>
-&#8226; Manage storage by setting the amount of cached episodes, smart deletion (based on your favorites and play status) and selecting your preferred location<br>
+&#8226; Take control over automated downloading: choose feeds, exclude mobile networks, select specific WiFi networks, require the phone to be charging and set times or intervals<br>
+&#8226; Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br>
&#8226; Usa AntennaPod nella tua lingua (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br>
&#8226; Adapt to your environment using the light and dark theme<br>
&#8226; Back-up your subscriptions with the gPodder.net integration and OPML export
-<b>Entra nella community di AntennaPod!</b>
+<b>Entra nella community di AntennaPod!</b><br>
AntennaPod è sviluppato da volontari. Anche tu puoi contribuire, con il codice o con dei commenti!
-Fai le tue domande o invia un feedback via Twitter:
-https://twitter.com/@AntennaPod
+GitHub è il posto nel quale fare richieste, segnalare bug e contribuire allo sviluppo:<br>
+https://www.github.com/AntennaPod/AntennaPod
-Condividi le tue idee, podcast preferiti o esprimi la tua gratitudine a tutti i volontari nel nostro gruppo Google:
+Our Google Group is the place to share your ideas, favourite podcasting moments and gratitude to all the volunteers:<br>
https://groups.google.com/forum/#!forum/antennapod
-Aiuta a tradurre l'app nella tua lingua su Transifex:
-https://www.transifex.com/antennapod/antennapod
+Hai una domanda o vuoi darci un feedback?
+https://twitter.com/@AntennaPod
-Dai un'occhiata al nostro programma di Beta Testing per provare le nuove features in anticipo:
-https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
+Transifex è il posto dove puoi contribuire alla traduzione di AntennaPod:<br>
+https://www.transifex.com/antennapod/antennapod
-Visita GitHub per inviare le ture richieste per nuove funzionalità, segnalare bug e contribuire allo sviluppo:
-https://www.github.com/AntennaPod/AntennaPod \ No newline at end of file
+Dai un'occhiata al nostro programma di Beta Testing per avere accesso in anticipo alle nuove features:<br>
+https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod \ No newline at end of file
diff --git a/app/src/main/play/lt/listing/fulldescription b/app/src/main/play/lt/listing/fulldescription
index 87b477fdc..6b17a60c8 100644
--- a/app/src/main/play/lt/listing/fulldescription
+++ b/app/src/main/play/lt/listing/fulldescription
@@ -1,43 +1,43 @@
AntennaPod is a podcast manager and player that gives you instant access to millions of free and paid podcasts, from independent podcasters to large publishing houses such as the BBC, NPR and CNN. Add, import and export their feeds hassle-free using the iTunes podcast database, OPML files or simple RSS URLs. Save effort, battery power and mobile data usage with powerful automation controls for downloading episodes (specify times, intervals and WiFi networks) and deleting episodes (based your favourites and delay settings).<br>
-But most importantly: Download, stream or queue episodes and enjoy them the way you like with adjustable playback speeds, chapter support and a sleep timer. You can even show your love to the content creators with our Flattr integration.
+Bet svarbiausia: atsisiųskite, klausykitės iš karto ar pridėkite epizodus į eilę ir mėgaukitės jais pasirinkdami atkūrimo spartą, naudodamiesi skyrių palaikymu bei miego laikmačiu. Jūs netgi galite išreikšti savo meilę turinio kūrėjams naudodamiesi mūsų „Flattr“ integracija.
-Made by podcast-enthousiast, AntennaPod is free in all senses of the word: open source, no costs, no ads.
+Sukurtas tinklalaidžių entuziasto, „AntennaPod“ yra laisvas visomis šio žodžio prasmėmis: atvirojo kodo, jokių mokesčių, jokių reklamų.
-<b>All features:</b><br>
-IMPORT, ORGANIZE AND PLAY<br>
-&#8226; Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br>
+<b>Visos funkcijos:</b><br>
+IMPORTUOKITE, TVARKYKITE BEI KLAUSYKITĖS<br>
+&#8226; Pridėkite bei importuokite sklaidos kanalus iš „iTunes“ bei „gPodder.net“ paslaugų, OPML failų ir RSS ar Atom nuorodų<br>
&#8226; Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br>
&#8226; Enjoy listening your way with adjustable playback speed, chapter support (MP3, VorbisComment and Podlove), remembered playback position and an advanced sleep timer (shake to reset, lower volume and slow down playback)<br>
-&#8226; Access password-protected feeds and episodes<br>
-&#8226; Take advantage of paged feeds (www.podlove.org/paged-feeds)
+&#8226; Pasiekite slaptažodžiu apsaugotus sklaidos kanalus bei epizodus<br>
+&#8226; Išnaudokite puslapiuotus sklaidos kanalus (www.podlove.org/paged-feeds)
-KEEP TRACK, SHARE & APPRECIATE<br>
-&#8226; Keep track of the best of the best by marking episodes as favourites<br>
+STEBĖKITE, DALINKITĖS IR MĖGAUKITĖS<br>
+&#8226; Kaupkite geriausius iš geriausiųjų pažymėdami epizodus kaip mėgstamiausius<br>
&#8226; Find that one episode through the playback history or by searching (titles and shownotes)<br>
-&#8226; Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br>
-&#8226; Support content creators with Flattr integration including automatic flattring
+&#8226; Dalinkitės epizodais bei sklaidos kanalais per socialinius tinklus, el. paštu, „gPodder.net“ paslaugą bei eksportuotus OPML failus<br>
+&#8226; Remkite turinio kūrėjus naudodamiesi „Flattr“ integracija bei automatiniu rėmimu
-CONTROL THE SYSTEM<br>
+VALDYKITE SISTEMĄ<br>
&#8226; Take control over automated downloading: choose feeds, exclude mobile networks, select specific WiFi networks, require the phone to be charging and set times or intervals<br>
&#8226; Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br>
-&#8226; Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br>
-&#8226; Adapt to your environment using the light and dark theme<br>
-&#8226; Back-up your subscriptions with the gPodder.net integration and OPML export
+&#8226; Naudokitės „AntennaPod“ savo kalba (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH, LT)<br>
+&#8226; Pritaikykite savo aplinkai pasirinkdami šviesią arba tamsią temą<br>
+&#8226; Sukurkite savo prenumeratų atsarginę kopiją pasinaudodami „gPodder.net“ integracija arba OPML eksportu
-<b>Join the AntennaPod community!</b><br>
-AntennaPod is under active development by volunteers. You can contribute too, with code or with comment!
+<b>Prisijunkite prie AntennaPod bendruomenės!</b><br>
+„AntennaPod“ aplikaciją aktyviai vysto savanoriai. Jūs taip pat galite prisidėti, nuo atsiliepimų iki programinio kodo!
-GitHub is the place to go for feature requests, bug reports and code contributions:<br>
+„GitHub“ yra ta vieta, kur galite pageidauti naujų funkcijų, pranešti apie riktą arba prisidėti programiniu kodu:<br>
https://www.github.com/AntennaPod/AntennaPod
-Our Google Group is the place to share your ideas, favourite podcasting moments and gratitude to all the volunteers:<br>
+Mūsų „Google“ grupė yra puiki vieta pasidalinti idėjomis, mėgstamiausiais tinklalaidžių sklaidos momentais ar išreikšti padėką visiems savanoriams:<br>
https://groups.google.com/forum/#!forum/antennapod
-Have a question or want to give us feedback?
+Turite klausimų ar norite palikti atsiliepimą?
https://twitter.com/@AntennaPod
-Transifex is the place to help with translations:<br>
+„Transifex“ yra ta vieta, kur galite prisidėti prie aplikacijos vertimo:<br>
https://www.transifex.com/antennapod/antennapod
-Check out our Beta Testing programme to get the latest features first:<br>
+Išbandykite mūsų Beta Testavimo programą, jei norite pirmieji gauti naujausias funkcijas:<br>
https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod \ No newline at end of file
diff --git a/app/src/main/play/pl_PL/listing/fulldescription b/app/src/main/play/pl_PL/listing/fulldescription
index 46dce8df5..c2c8cc597 100644
--- a/app/src/main/play/pl_PL/listing/fulldescription
+++ b/app/src/main/play/pl_PL/listing/fulldescription
@@ -1,45 +1,43 @@
-Easy-to-use, flexible and open-source podcast manager and player
-
-AntennaPod is a podcast manager and player that gives you instant access to millions of free and paid podcasts, from independent podcasters to large publishing houses such as the BBC, NPR and CNN. Add, import and export their feeds hassle-free using the iTunes podcast database, OPML files or simple RSS URLs. Save effort, battery power and mobile data usage with powerful automation controls for downloading episodes (episode filtering, specify times, intervals and WiFi networks) and deleting episodes (based your favorites and delay settings).<br>
-But most importantly: Download, stream or queue episodes and enjoy them the way you like with adjustable playback speeds, chapter support and a sleep timer. You can even show your love to the content creators with our Flattr integration.
-
-Made by podcast-enthousiast, AntennaPod is free in all senses of the word: open source, no costs, no ads.
-
-<b>All features:</b><br>
-IMPORT, ORGANIZE AND PLAY<br>
-&#8226; Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br>
-&#8226; Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br>
-&#8226; Enjoy listening your way with adjustable playback speed, chapter support (MP3, VorbisComment and Podlove), remembered playback position and an advanced sleep timer (shake to reset, lower volume and slow down playback)<br>
-&#8226; Access password-protected feeds and episodes<br>
-&#8226; Take advantage of paged feeds (www.podlove.org/paged-feeds)
-
-KEEP TRACK, SHARE & APPRECIATE<br>
-&#8226; Keep track of the best of the best by marking episodes as favorites<br>
-&#8226; Find that one episode through the playback history or by searching (titles and shownotes)<br>
-&#8226; Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br>
-&#8226; Support content creators with Flattr integration including automatic flattring
-
-CONTROL THE SYSTEM<br>
-&#8226; Take control over automated downloading: choose feeds, filter episodes based on keywords, exclude mobile networks, select specific WiFi networks, require the phone to be charging and set times or intervals<br>
-&#8226; Manage storage by setting the amount of cached episodes, smart deletion (based on your favorites and play status) and selecting your preferred location<br>
-&#8226; Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br>
-&#8226; Adapt to your environment using the light and dark theme<br>
-&#8226; Back-up your subscriptions with the gPodder.net integration and OPML export
-
-<b>Join the AntennaPod community!</b>
-AntennaPod is under active development by volunteers. You can contribute too, with code or with comment!
-
-Ask your question or give feedback via Twitter:
-https://twitter.com/@AntennaPod
-
-Share your ideas, favorite podcasting moments and gratitude to all the volunteers in our Google group:
+AntennaPod jest programem katalogującym i odtwarzającym który daje możliwość natychmiastowego dostępu do milionów darmowych i płatnych podcastów. Od niezależych twórców po wielkich producentów takich jak BBC, NPR czy CNN. Dodawaj, importuj, eksportuj wątki bez przeszkód używając bazy iTunes, plików OPML czy po prostu przez linki RSS. Oszczędź wysiłek, baterię oraz pakiety danych mobilnych poprzez zaawansowaną kontrolę automatycznego pobierania (określone godziny, interwały czy sieci WiFi) oraz inteligentne usuwanie odcinków ( na podstawie ulubionych i ustawień opóźnień).<br>
+Najważniejsze: pobieraj , streamuj lub kolejkuj odcinki oraz rozkoszuj się nimi jak tylko chcesz z możliwością zmiany prędkości odtwarzania, wsparciem rozdziałów i wyłącznikiem czasowym. Możesz nawet pokazać jak bardzo doceniach twórców dzięki integracji z Flattr.
+
+Stworzone przez entuzjastów podcastów, AntennaPod jest darmowe w każdym słowa znaczeniu: otwarty kod, brak opłat i reklam.
+
+<b>Wszystkie funkcje:</b><br>
+ZAIMPORTUJ, ZORGANIZUJ I ODTWARZAJ<br>
+&#8226; Dodawaj i importuj kanały poprzez iTunes, gPodder.net, z plików OPML, RSS i linków Atom<br>
+&#8226; Zarządzaj odtwarzaniem zewsząd: widget na ekranie głównym, powiadomienia systemowe i kontrolery bluetooth<br>
+&#8226; Delektuj się słuchaniem po swojemu z: zmienną prędkością odtwarzania, wsparciem rozdziałów (MP3, VorbisComment i Podlove), zapamiętywaniem miejsca zakończenia słuchania i zaawansowanym wyłącznikiem czasowym (potrząśnij aby zrestartować, zmiejszanie głośności i zwalnianie odtwarzania) <br>
+&#8226; Dostęp do odcinków i kanałów chroniony hasłem<br>
+&#8226; Wykorzystaj zapisane kanały (www.podlove.org/paged-feeds)
+
+ŚLEDŹ, DZIEL SIĘ I DOCENIAJ<br>
+&#8226; Zapamiętywanie najlepszych z najlepszych poprzez dodawania odcinków do ulubionych<br>
+&#8226; Wyszukiwanie odcinów w historii odtwarzania lub poprzez tytuł/przypisy<br>
+&#8226; Dzial się odcinkami i wątkami poprzez zaawansowane opcje medii społecznych oraz emaila, serwisu gPodder.net lub poprzez eksport do OPML<br>
+&#8226; Wsparcie twórców poprzez integrację z Flattr, również poprzez automatyczne flattr-owanie
+
+Kontroluj system<br>
+&#8226; Ustaw automatyczne pobieranie zgodnie z własnymi preferencjami: wybieranie wątków, pobieranie tylko przez WiFi, wybór określonych sieci WiFi, wymaganie ładowania przy pobieraniu oraz ustawienie harmonogramu i interwałów<br>
+&#8226; Zarządanie pamięcią poprzez ustawienia liczby pobranych odcinków z pomocą inteligentnego kasowania( na podstawie ulubionych i statusu odtwarzania) oraz wyboru lokalizacji<br>
+&#8226; Używaj AntennaPod w swoim języku (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br>
+&#8226; Dostosowanie wyglądu jasną i ciemną skórką<br>
+&#8226; Twórz kopie bezpieczeństwa swoich subskrypcji z pomocą zintegrowanego gPoddder.net oraz plików OPML
+
+<b>Dołącz do społeczności AntennaPod</b><br>
+AntennaPod jest ciągle rozwijane przez ochotników. Ty też możesz pomóc, kodem lub komentarzem!
+
+Sugestie ulepszeń, raporty błędów oraz dodatki do kodu prosimy kierować poprzez GitHub<br>
+https://www.github.com/AntennaPod/AntennaPod
+
+Nasza grupa Google jest miejsce do dzielenia się pomysłami, ulubionymi momentami podcastów oraz miejscem gdzie można podziękować ochotnikom za ich pracę:<br>
https://groups.google.com/forum/#!forum/antennapod
-Help translate the app to your mother tongue on Transifex:
-https://www.transifex.com/antennapod/antennapod
+Masz pytanie lub chcesz przekazać nam swoją opinię ?
+https://twitter.com/@AntennaPod
-Check out our Beta Testing programme to get the latest features first:
-https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
+Pomoc w tłumaczeniach na Transifex:<br>
+https://www.transifex.com/antennapod/antennapod
-Visit GitHub to submit feature requests, bug reports and code contributions:
-https://www.github.com/AntennaPod/AntennaPod \ No newline at end of file
+Jeśli chcesz otrzymywać najnowsze ulepszenia wcześniej niż inni rozważ dołączenie do programu beta testów:<br>
+https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod \ No newline at end of file
diff --git a/app/src/main/play/ru_RU/listing/fulldescription b/app/src/main/play/ru_RU/listing/fulldescription
index 46dce8df5..7fa9a820f 100644
--- a/app/src/main/play/ru_RU/listing/fulldescription
+++ b/app/src/main/play/ru_RU/listing/fulldescription
@@ -1,45 +1,43 @@
-Easy-to-use, flexible and open-source podcast manager and player
-
-AntennaPod is a podcast manager and player that gives you instant access to millions of free and paid podcasts, from independent podcasters to large publishing houses such as the BBC, NPR and CNN. Add, import and export their feeds hassle-free using the iTunes podcast database, OPML files or simple RSS URLs. Save effort, battery power and mobile data usage with powerful automation controls for downloading episodes (episode filtering, specify times, intervals and WiFi networks) and deleting episodes (based your favorites and delay settings).<br>
-But most importantly: Download, stream or queue episodes and enjoy them the way you like with adjustable playback speeds, chapter support and a sleep timer. You can even show your love to the content creators with our Flattr integration.
-
-Made by podcast-enthousiast, AntennaPod is free in all senses of the word: open source, no costs, no ads.
-
-<b>All features:</b><br>
-IMPORT, ORGANIZE AND PLAY<br>
-&#8226; Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br>
-&#8226; Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br>
-&#8226; Enjoy listening your way with adjustable playback speed, chapter support (MP3, VorbisComment and Podlove), remembered playback position and an advanced sleep timer (shake to reset, lower volume and slow down playback)<br>
-&#8226; Access password-protected feeds and episodes<br>
-&#8226; Take advantage of paged feeds (www.podlove.org/paged-feeds)
-
-KEEP TRACK, SHARE & APPRECIATE<br>
-&#8226; Keep track of the best of the best by marking episodes as favorites<br>
-&#8226; Find that one episode through the playback history or by searching (titles and shownotes)<br>
-&#8226; Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br>
-&#8226; Support content creators with Flattr integration including automatic flattring
-
-CONTROL THE SYSTEM<br>
-&#8226; Take control over automated downloading: choose feeds, filter episodes based on keywords, exclude mobile networks, select specific WiFi networks, require the phone to be charging and set times or intervals<br>
-&#8226; Manage storage by setting the amount of cached episodes, smart deletion (based on your favorites and play status) and selecting your preferred location<br>
-&#8226; Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br>
-&#8226; Adapt to your environment using the light and dark theme<br>
-&#8226; Back-up your subscriptions with the gPodder.net integration and OPML export
-
-<b>Join the AntennaPod community!</b>
-AntennaPod is under active development by volunteers. You can contribute too, with code or with comment!
-
-Ask your question or give feedback via Twitter:
-https://twitter.com/@AntennaPod
-
-Share your ideas, favorite podcasting moments and gratitude to all the volunteers in our Google group:
+AntennaPod — менеджер и проигрыватель подкастов, который обеспечит Вас мгновенным доступом к миллионам бесплатных и платных подкастов, как от независимых подкастеров, так и крупных издательских домов, например, BBC, NPR и CNN. С лёгкостью добавляйте, импортируйте и экспортируйте их каналы используя каталог подкастов iTunes, файлы OPML или адреса каналов RSS. Сберегите усилия, заряд батареи и мобильный трафик при помощи мощных средств автоматизации загрузки выпусков (фильтрация, указание времени и интервалов, а также сетей WiFi) и их удаления (в соответствии с настройками избранного и ожидания).<br>
+Но самое главное: Загружайте, слушайте с эфира или ставьте в очередь и получайте удовольствие от их прослушивания применяя регулируемую скорость воспроизведения, оглавления и таймер сна. Вы даже можете выразить свою благодарность создателям аудио посредством интеграции с Flattr.
+
+Созданное поклонниками подкастов, AntennaPod — бесплатное и свободное приложение без рекламы и платежей.
+
+<b>Все возможности:</b><br>
+Импортируйте, систематизируйте и прослушивайте<br>
+&#8226; Добавление и импорт каналов через каталоги iTunes и gPodder.net, файлы OPML и ссылки на каналы RSS или Atom<br>
+&#8226; Всевозможное управление воспроизведением: виджетом, системным уведомлением и кнопками проводных и беспроводных гарнитур<br>
+&#8226; Приятное, по вашему вкусу, прослушивание применяя регулировку скорости воспроизведения, оглавления (MP3, VorbisComment и Podlove), запоминание места воспроизведения и продвинутый таймер сна (сброс при встряхивание, снижение громкости и замедление воспроизведения)<br>
+&#8226; Доступ к каналам и выпускам защищенным паролем<br>
+&#8226; Использует преимущества листаемых каналов (www.podlove.org/paged-feeds)
+
+Отслеживайте, делитесь и благодарите<br>
+&#8226; Отслеживайте лучших из лучших, помещая выпуски в избранное<br>
+&#8226; Поиск того самого выпуска в истории воспроизведения или по контексту (заголовки и заметки к выпуску)<br>
+&#8226; Разнообразные возможности поделиться выпусками и каналами через социальные службы и e-mail, услуги gPodder.net и экспорт в OPML<br>
+&#8226; Поддержка создателей аудио при помощи интеграции с Flattr, в том числе и автоматически
+
+Управляйте системой<br>
+&#8226; Управление автоматической загрузкой: выбор отдельных каналов, отбор выпусков на основе ключевых слов, запрет на использование мобильных сетей, выбор отдельных точек доступа WiFi, только во время зарядки телефона и задание времени и интервалов<br>
+&#8226; Управление хранением путём задания количества выпусков в кэше, автоудаление (на основании настроек избранного и статуса прослушивания) и выбор предпочитаемого расположения<br>
+&#8226; AntennaPod на родном Вам языке (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH, RU)<br>
+&#8226; Приспосабливается к Вашему окружению посредством светлой или тёмной темы<br>
+&#8226; Резервирование Ваших подписок путём интеграции с gPodder.net и экпорта в OPML
+
+<b>Присоединяйтесь к сообществу AntennaPod!</b><br>
+AntennaPod постоянно развивается силами добровольцев. Вы тоже можете сделать свой вклад при помощи кода или комментария!
+
+Посещайте GitHub для запроса новых возможностей, уведомления об ошибках и внесения кода:<br>
+https://www.github.com/AntennaPod/AntennaPod
+
+Поделитесь идеями, любимыми мгновениями прослушивания и благодарностью со всеми добровольцами из нашей группы Google:<br>
https://groups.google.com/forum/#!forum/antennapod
-Help translate the app to your mother tongue on Transifex:
-https://www.transifex.com/antennapod/antennapod
+Появились вопросы и обратная связь?
+https://twitter.com/@AntennaPod
-Check out our Beta Testing programme to get the latest features first:
-https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
+Помогайте с переводом приложения на Transifex:<br>
+https://www.transifex.com/antennapod/antennapod
-Visit GitHub to submit feature requests, bug reports and code contributions:
-https://www.github.com/AntennaPod/AntennaPod \ No newline at end of file
+Попробуйте себя в программе Бета тестирования и получите доступ к распоследним возможностям в числе первых:<br>
+https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod \ No newline at end of file
diff --git a/app/src/main/play/sw_KE/listing/fulldescription b/app/src/main/play/sw_KE/listing/fulldescription
new file mode 100644
index 000000000..87b477fdc
--- /dev/null
+++ b/app/src/main/play/sw_KE/listing/fulldescription
@@ -0,0 +1,43 @@
+AntennaPod is a podcast manager and player that gives you instant access to millions of free and paid podcasts, from independent podcasters to large publishing houses such as the BBC, NPR and CNN. Add, import and export their feeds hassle-free using the iTunes podcast database, OPML files or simple RSS URLs. Save effort, battery power and mobile data usage with powerful automation controls for downloading episodes (specify times, intervals and WiFi networks) and deleting episodes (based your favourites and delay settings).<br>
+But most importantly: Download, stream or queue episodes and enjoy them the way you like with adjustable playback speeds, chapter support and a sleep timer. You can even show your love to the content creators with our Flattr integration.
+
+Made by podcast-enthousiast, AntennaPod is free in all senses of the word: open source, no costs, no ads.
+
+<b>All features:</b><br>
+IMPORT, ORGANIZE AND PLAY<br>
+&#8226; Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br>
+&#8226; Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br>
+&#8226; Enjoy listening your way with adjustable playback speed, chapter support (MP3, VorbisComment and Podlove), remembered playback position and an advanced sleep timer (shake to reset, lower volume and slow down playback)<br>
+&#8226; Access password-protected feeds and episodes<br>
+&#8226; Take advantage of paged feeds (www.podlove.org/paged-feeds)
+
+KEEP TRACK, SHARE & APPRECIATE<br>
+&#8226; Keep track of the best of the best by marking episodes as favourites<br>
+&#8226; Find that one episode through the playback history or by searching (titles and shownotes)<br>
+&#8226; Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br>
+&#8226; Support content creators with Flattr integration including automatic flattring
+
+CONTROL THE SYSTEM<br>
+&#8226; Take control over automated downloading: choose feeds, exclude mobile networks, select specific WiFi networks, require the phone to be charging and set times or intervals<br>
+&#8226; Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br>
+&#8226; Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br>
+&#8226; Adapt to your environment using the light and dark theme<br>
+&#8226; Back-up your subscriptions with the gPodder.net integration and OPML export
+
+<b>Join the AntennaPod community!</b><br>
+AntennaPod is under active development by volunteers. You can contribute too, with code or with comment!
+
+GitHub is the place to go for feature requests, bug reports and code contributions:<br>
+https://www.github.com/AntennaPod/AntennaPod
+
+Our Google Group is the place to share your ideas, favourite podcasting moments and gratitude to all the volunteers:<br>
+https://groups.google.com/forum/#!forum/antennapod
+
+Have a question or want to give us feedback?
+https://twitter.com/@AntennaPod
+
+Transifex is the place to help with translations:<br>
+https://www.transifex.com/antennapod/antennapod
+
+Check out our Beta Testing programme to get the latest features first:<br>
+https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod \ No newline at end of file
diff --git a/app/src/main/res/layout/nav_list.xml b/app/src/main/res/layout/nav_list.xml
index 9fcf9d9fc..7e72bb39b 100644
--- a/app/src/main/res/layout/nav_list.xml
+++ b/app/src/main/res/layout/nav_list.xml
@@ -1,7 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<RelativeLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
+<?xml version='1.0' encoding='utf-8'?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_layout"
android:layout_width="@dimen/drawer_width"
@@ -23,8 +21,6 @@
android:id="@+id/imgvCover"
android:layout_width="@dimen/thumbnail_length_navlist"
android:layout_height="@dimen/thumbnail_length_navlist"
- android:layout_alignParentLeft="true"
- android:layout_centerVertical="true"
android:layout_marginBottom="4dp"
android:layout_marginLeft="@dimen/listitem_icon_leftpadding"
android:layout_marginTop="4dp"
@@ -34,8 +30,8 @@
android:padding="8dp"
android:scaleType="centerCrop"
android:src="?attr/ic_settings"
- tools:src="@android:drawable/sym_def_app_icon"
- tools:background="@android:color/holo_orange_dark" />
+ tools:background="@android:color/holo_orange_dark"
+ tools:src="@android:drawable/sym_def_app_icon"></ImageView>
<TextView
android:layout_width="wrap_content"
@@ -47,16 +43,15 @@
android:text="@string/settings_label"
android:textColor="?android:attr/textColorPrimary"
android:textSize="@dimen/text_size_navdrawer"
- tools:background="@android:color/holo_green_light"/>
-
+ tools:background="@android:color/holo_green_light" />
</LinearLayout>
<View
android:id="@+id/divider"
android:layout_width="@dimen/drawer_width"
android:layout_height="1dp"
- android:layout_centerVertical="true"
android:layout_above="@id/nav_settings"
+ android:layout_centerVertical="true"
android:background="?android:attr/listDivider"
tools:background="@android:color/holo_red_dark" />
@@ -64,7 +59,6 @@
android:id="@+id/nav_list"
android:layout_width="@dimen/drawer_width"
android:layout_height="wrap_content"
- android:layout_weight="1"
android:layout_above="@id/divider"
android:layout_alignParentTop="true"
android:choiceMode="singleChoice"
@@ -74,7 +68,6 @@
android:paddingBottom="@dimen/list_vertical_padding"
android:paddingTop="@dimen/list_vertical_padding"
android:scrollbarStyle="outsideOverlay"
- tools:listitem="@layout/nav_listitem"
- tools:background="@android:color/holo_purple" />
-
+ tools:background="@android:color/holo_purple"
+ tools:listitem="@layout/nav_listitem"></ListView>
</RelativeLayout>
diff --git a/app/src/main/res/layout/simplechapter_item.xml b/app/src/main/res/layout/simplechapter_item.xml
index fae6bac8c..21bbc9545 100644
--- a/app/src/main/res/layout/simplechapter_item.xml
+++ b/app/src/main/res/layout/simplechapter_item.xml
@@ -53,6 +53,16 @@
tools:text="Link"
tools:background="@android:color/holo_green_dark" />
+ <TextView
+ android:id="@+id/txtvDuration"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:focusable="false"
+ android:focusableInTouchMode="false"
+ android:maxLines="1"
+ tools:text="Duration"
+ tools:background="@android:color/holo_green_dark" />
+
</LinearLayout>
<include layout="@layout/vertical_list_divider" />
diff --git a/app/src/main/res/layout/statistics_mode_select_dialog.xml b/app/src/main/res/layout/statistics_mode_select_dialog.xml
new file mode 100644
index 000000000..8f8e1e657
--- /dev/null
+++ b/app/src/main/res/layout/statistics_mode_select_dialog.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RadioGroup xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="16dp">
+
+ <TextView
+ android:text="@string/statistics_speed_not_counted"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="16dp"/>
+
+ <RadioButton
+ android:id="@+id/statistics_mode_normal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/statistics_mode_normal"/>
+
+ <RadioButton
+ android:id="@+id/statistics_mode_count_all"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/statistics_mode_count_all"/>
+</RadioGroup>
diff --git a/app/src/main/res/layout/subscription_item.xml b/app/src/main/res/layout/subscription_item.xml
index 19b9943e4..8f0539dfa 100644
--- a/app/src/main/res/layout/subscription_item.xml
+++ b/app/src/main/res/layout/subscription_item.xml
@@ -1,7 +1,7 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version='1.0' encoding='utf-8'?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
@@ -10,31 +10,28 @@
android:id="@+id/imgvCover"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
- android:layout_centerHorizontal="true"
- android:layout_centerVertical="true"
android:scaleType="centerCrop"
- tools:src="@drawable/ic_launcher" />
+ tools:src="@drawable/ic_launcher">
+ </de.danoeh.antennapod.view.SquareImageView>
<com.joanzapata.iconify.widget.IconTextView
android:id="@+id/txtvTitle"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:background="@color/light_gray"
android:ellipsize="end"
android:gravity="center"
- android:background="@color/light_gray"
tools:text="@string/app_name" />
<jp.shts.android.library.TriangleLabelView
android:id="@+id/triangleCountView"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_alignParentRight="true"
- android:layout_alignParentTop="true"
+ android:layout_gravity="right|top"
app:backgroundColor="@color/antennapod_blue"
app:corner="rightTop"
app:primaryText="Test"
app:primaryTextColor="@color/white"
- app:primaryTextSize="12sp"
- android:layout_gravity="right|top"/>
-
+ app:primaryTextSize="12sp">
+ </jp.shts.android.library.TriangleLabelView>
</FrameLayout>
diff --git a/app/src/main/res/menu/allepisodes_context.xml b/app/src/main/res/menu/allepisodes_context.xml
index c5356535c..7398b9118 100644
--- a/app/src/main/res/menu/allepisodes_context.xml
+++ b/app/src/main/res/menu/allepisodes_context.xml
@@ -71,6 +71,10 @@
android:id="@+id/share_download_url_with_position_item"
android:menuCategory="container"
android:title="@string/share_item_url_with_position_label" />
+ <item
+ android:id="@+id/share_file"
+ android:menuCategory="container"
+ android:title="@string/share_file_label" />
</menu>
</item>
diff --git a/app/src/main/res/menu/feeditem_options.xml b/app/src/main/res/menu/feeditem_options.xml
index 511758c2e..7e111d816 100644
--- a/app/src/main/res/menu/feeditem_options.xml
+++ b/app/src/main/res/menu/feeditem_options.xml
@@ -84,6 +84,10 @@
android:id="@+id/share_download_url_with_position_item"
android:menuCategory="container"
android:title="@string/share_item_url_with_position_label" />
+ <item
+ android:id="@+id/share_file"
+ android:menuCategory="container"
+ android:title="@string/share_file_label" />
</menu>
</item>
diff --git a/app/src/main/res/menu/feeditemlist_context.xml b/app/src/main/res/menu/feeditemlist_context.xml
index 271cb96a7..d3ec88bc7 100644
--- a/app/src/main/res/menu/feeditemlist_context.xml
+++ b/app/src/main/res/menu/feeditemlist_context.xml
@@ -73,6 +73,10 @@
android:id="@+id/share_download_url_with_position_item"
android:menuCategory="container"
android:title="@string/share_item_url_with_position_label" />
+ <item
+ android:id="@+id/share_file"
+ android:menuCategory="container"
+ android:title="@string/share_file_label" />
</menu>
</item>
diff --git a/app/src/main/res/menu/mediaplayer.xml b/app/src/main/res/menu/mediaplayer.xml
index c4086bf5e..530eb3400 100644
--- a/app/src/main/res/menu/mediaplayer.xml
+++ b/app/src/main/res/menu/mediaplayer.xml
@@ -64,6 +64,10 @@
android:id="@+id/share_download_url_with_position_item"
android:menuCategory="container"
android:title="@string/share_item_url_with_position_label" />
+ <item
+ android:id="@+id/share_file"
+ android:menuCategory="container"
+ android:title="@string/share_file_label" />
</menu>
</item>
<item
diff --git a/app/src/main/res/menu/queue_context.xml b/app/src/main/res/menu/queue_context.xml
index 3eb1d9d5e..e93d808c1 100644
--- a/app/src/main/res/menu/queue_context.xml
+++ b/app/src/main/res/menu/queue_context.xml
@@ -74,6 +74,10 @@
android:id="@+id/share_download_url_with_position_item"
android:menuCategory="container"
android:title="@string/share_item_url_with_position_label" />
+ <item
+ android:id="@+id/share_file"
+ android:menuCategory="container"
+ android:title="@string/share_file_label" />
</menu>
</item>
<item
diff --git a/app/src/main/res/menu/statistics.xml b/app/src/main/res/menu/statistics.xml
new file mode 100644
index 000000000..6ecc70707
--- /dev/null
+++ b/app/src/main/res/menu/statistics.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:custom="http://schemas.android.com/apk/res-auto">
+
+ <item
+ android:id="@+id/statistics_mode"
+ android:icon="?attr/ic_filter"
+ android:title="@string/statistics_mode"
+ custom:showAsAction="never">
+ </item>
+
+</menu>
diff --git a/app/src/main/res/xml/automotive_app_desc.xml b/app/src/main/res/xml/automotive_app_desc.xml
new file mode 100644
index 000000000..8f0a7c59c
--- /dev/null
+++ b/app/src/main/res/xml/automotive_app_desc.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<automotiveApp xmlns:android="http://schemas.android.com/apk/res/android">
+ <uses name="media"/>
+</automotiveApp> \ No newline at end of file
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index b4c6e6068..c18838c51 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -109,6 +109,14 @@
android:key="prefHardwareForwardButtonSkips"
android:summary="@string/pref_hardwareForwardButtonSkips_sum"
android:title="@string/pref_hardwareForwardButtonSkips_title"/>
+ <Preference
+ android:key="prefPlaybackFastForwardDeltaLauncher"
+ android:summary="@string/pref_fast_forward_sum"
+ android:title="@string/pref_fast_forward" />
+ <Preference
+ android:key="prefPlaybackRewindDeltaLauncher"
+ android:summary="@string/pref_rewind_sum"
+ android:title="@string/pref_rewind" />
<de.danoeh.antennapod.preferences.SwitchCompatPreference
android:defaultValue="false"
android:enabled="true"
@@ -151,7 +159,6 @@
android:key="prefPlaybackSpeedLauncher"
android:summary="@string/pref_playback_speed_sum"
android:title="@string/pref_playback_speed_title" />
-
<de.danoeh.antennapod.preferences.SwitchCompatPreference
android:defaultValue="false"
android:enabled="true"
@@ -167,6 +174,12 @@
</PreferenceCategory>
<PreferenceCategory android:title="@string/network_pref">
+ <de.danoeh.antennapod.preferences.SwitchCompatPreference
+ android:defaultValue="true"
+ android:enabled="true"
+ android:key="prefEnqueueDownloaded"
+ android:summary="@string/pref_enqueue_downloaded_summary"
+ android:title="@string/pref_enqueue_downloaded_title" />
<Preference
android:key="prefAutoUpdateIntervall"
android:summary="@string/pref_autoUpdateIntervallOrTime_sum"
diff --git a/app/src/play/java/de/danoeh/antennapod/dialog/CustomMRControllerDialog.java b/app/src/play/java/de/danoeh/antennapod/dialog/CustomMRControllerDialog.java
index 93ec4e3f0..7b07d3f84 100644
--- a/app/src/play/java/de/danoeh/antennapod/dialog/CustomMRControllerDialog.java
+++ b/app/src/play/java/de/danoeh/antennapod/dialog/CustomMRControllerDialog.java
@@ -354,14 +354,15 @@ public class CustomMRControllerDialog extends MediaRouteControllerDialog {
boolean showTitle = false;
boolean showSubtitle = false;
- if (route.getPresentationDisplayId() != MediaRouter.RouteInfo.PRESENTATION_DISPLAY_ID_NONE) {
+ if (route.getPresentationDisplay() != null &&
+ route.getPresentationDisplay().getDisplayId() != MediaRouter.RouteInfo.PRESENTATION_DISPLAY_ID_NONE) {
// The user is currently casting screen.
titleView.setText(android.support.v7.mediarouter.R.string.mr_controller_casting_screen);
showTitle = true;
} else if (state == null || state.getState() == PlaybackStateCompat.STATE_NONE) {
// Show "No media selected" as we don't yet know the playback state.
// (Only exception is bluetooth where we don't show anything.)
- if (!route.isDeviceTypeBluetooth()) {
+ if (!route.isBluetooth()) {
titleView.setText(android.support.v7.mediarouter.R.string.mr_controller_no_media_selected);
showTitle = true;
}
diff --git a/app/src/play/res/layout/media_router_controller.xml b/app/src/play/res/layout/media_router_controller.xml
index 659ac0a78..9489173a3 100644
--- a/app/src/play/res/layout/media_router_controller.xml
+++ b/app/src/play/res/layout/media_router_controller.xml
@@ -31,11 +31,11 @@
<TextView android:id="@+id/mrc_control_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textAppearance="?attr/mediaRouteControllerPrimaryTextStyle"/>
+ android:textAppearance="@style/TextAppearance.MediaRouter.PrimaryText"/>
<TextView android:id="@+id/mrc_control_subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textAppearance="?attr/mediaRouteControllerSecondaryTextStyle"
+ android:textAppearance="@style/TextAppearance.MediaRouter.SecondaryText"
android:singleLine="true" />
</LinearLayout>
</RelativeLayout>
diff --git a/build.gradle b/build.gradle
index ba4e7abb9..d0fee89c9 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,8 +6,8 @@ buildscript {
mavenCentral()
}
dependencies {
- classpath "com.android.tools.build:gradle:2.2.3"
- classpath "me.tatarka:gradle-retrolambda:3.3.1"
+ classpath "com.android.tools.build:gradle:2.3.3"
+ classpath "me.tatarka:gradle-retrolambda:3.7.0"
classpath "me.tatarka.retrolambda.projectlombok:lombok.ast:0.2.3.a2"
classpath "com.github.triplet.gradle:play-publisher:1.1.4"
// Exclude the version that the android plugin depends on.
@@ -37,38 +37,39 @@ subprojects {
}
project.ext {
- compileSdkVersion = 23
- buildToolsVersion = "23.0.3"
+ compileSdkVersion = 25
+ buildToolsVersion = "25.0.3"
minSdkVersion = 10
- targetSdkVersion = 23
+ targetSdkVersion = 25
- supportVersion = "23.4.0"
- commonsioVersion = "2.4"
- commonslangVersion = "3.4"
+ supportVersion = "25.3.1"
+ commonsioVersion = "2.5"
+ commonslangVersion = "3.6"
eventbusVersion = "2.4.0"
- flattr4jVersion = "2.13"
- glideVersion = "3.7.0"
- glideOkhttpIntegrationVersion = "1.4.0"
+ flattr4jVersion = "2.14"
+ glideVersion = "3.8.0"
+ glideOkhttpIntegrationVersion = "1.5.0"
iconifyVersion = "2.2.2"
- jsoupVersion = "1.9.2"
- materialDialogsVersion = "0.8.5.8@aar"
- okhttpVersion = "3.4.2"
- okioVersion = "1.11.0"
+ jsoupVersion = "1.10.3"
+ materialDialogsVersion = "0.9.0.2"
+ okhttpVersion = "3.9.0"
+ okioVersion = "1.13.0"
recyclerviewFlexibledividerVersion = "1.2.6"
- robotiumSoloVersion = "5.6.0"
+ robotiumSoloVersion = "5.6.3"
rxAndroidVersion = "1.2.1"
- rxJavaVersion = "1.1.8"
- rxJavaRulesVersion = "1.1.8.0"
+ rxJavaVersion = "1.3.2"
+ rxJavaRulesVersion = "1.3.2.0"
triangleLabelViewVersion = "1.1.0"
- audioPlayerVersion = "v1.0.16"
+ audioPlayerVersion = "v1.0.17"
- castCompanionLibVer = "2.8.3"
+ castCompanionLibVer = "2.9.1"
playServicesVersion = "8.4.0"
+ wearableSupportVersion = "2.0.3"
}
task wrapper(type: Wrapper) {
- gradleVersion = "3.2.1"
+ gradleVersion = "4.2"
}
// free build hack: common functions
diff --git a/circle.yml b/circle.yml
index 6549e756e..01055725a 100644
--- a/circle.yml
+++ b/circle.yml
@@ -11,8 +11,8 @@ dependencies:
- ~/.android
- ~/android
pre:
- - echo y | android update sdk --no-ui --all --filter "tool,extra-android-m2repository,extra-android-support,extra-google-google_play_services,extra-google-m2repository,android-23"
- - echo y | android update sdk --no-ui --all --filter "build-tools-23.0.3"
+ - echo y | android update sdk --no-ui --all --filter "tool,extra-android-m2repository,extra-android-support,extra-google-google_play_services,extra-google-m2repository,android-25"
+ - echo y | android update sdk --no-ui --all --filter "build-tools-25.0.3"
override:
- echo override dependencies
diff --git a/core/build.gradle b/core/build.gradle
index c2ddd24da..f70083ec1 100644
--- a/core/build.gradle
+++ b/core/build.gradle
@@ -72,6 +72,7 @@ dependencies {
playCompile "com.google.android.libraries.cast.companionlibrary:ccl:$castCompanionLibVer"
compile "com.android.support:mediarouter-v7:$supportVersion"
playCompile "com.google.android.gms:play-services-cast:$playServicesVersion"
+ compile "com.google.android.support:wearable:$wearableSupportVersion"
} else {
System.out.println("core: free build hack, skipping some dependencies")
}
diff --git a/core/src/androidTest/java/de/danoeh/antennapod/core/feed/FeedImageMother.java b/core/src/androidTest/java/de/danoeh/antennapod/core/feed/FeedImageMother.java
new file mode 100644
index 000000000..f240c870e
--- /dev/null
+++ b/core/src/androidTest/java/de/danoeh/antennapod/core/feed/FeedImageMother.java
@@ -0,0 +1,9 @@
+package de.danoeh.antennapod.core.feed;
+
+public class FeedImageMother {
+
+ public static FeedImage anyFeedImage() {
+ return new FeedImage(0, "image", null, "http://example.com/picture", false);
+ }
+
+}
diff --git a/core/src/androidTest/java/de/danoeh/antennapod/core/feed/FeedItemMother.java b/core/src/androidTest/java/de/danoeh/antennapod/core/feed/FeedItemMother.java
new file mode 100644
index 000000000..3d7c4fe5f
--- /dev/null
+++ b/core/src/androidTest/java/de/danoeh/antennapod/core/feed/FeedItemMother.java
@@ -0,0 +1,16 @@
+package de.danoeh.antennapod.core.feed;
+
+import java.util.Date;
+
+import static de.danoeh.antennapod.core.feed.FeedImageMother.anyFeedImage;
+import static de.danoeh.antennapod.core.feed.FeedMother.anyFeed;
+
+class FeedItemMother {
+
+ static FeedItem anyFeedItemWithImage() {
+ FeedItem item = new FeedItem(0, "Item", "Item", "url", new Date(), FeedItem.PLAYED, anyFeed());
+ item.setImage(anyFeedImage());
+ return item;
+ }
+
+}
diff --git a/core/src/androidTest/java/de/danoeh/antennapod/core/feed/FeedItemTest.java b/core/src/androidTest/java/de/danoeh/antennapod/core/feed/FeedItemTest.java
new file mode 100644
index 000000000..9e12e8ae0
--- /dev/null
+++ b/core/src/androidTest/java/de/danoeh/antennapod/core/feed/FeedItemTest.java
@@ -0,0 +1,65 @@
+package de.danoeh.antennapod.core.feed;
+
+import android.test.AndroidTestCase;
+
+import static de.danoeh.antennapod.core.feed.FeedItemMother.anyFeedItemWithImage;
+
+public class FeedItemTest extends AndroidTestCase {
+
+ private FeedItem original;
+ private FeedImage originalImage;
+ private FeedItem changedFeedItem;
+
+ @Override
+ protected void setUp() {
+ original = anyFeedItemWithImage();
+ originalImage = original.getImage();
+ changedFeedItem = anyFeedItemWithImage();
+ }
+
+ public void testUpdateFromOther_feedItemImageDownloadUrlChanged() throws Exception {
+ setNewFeedItemImageDownloadUrl();
+
+ original.updateFromOther(changedFeedItem);
+
+ feedItemImageWasUpdated();
+ }
+
+ public void testUpdateFromOther_feedItemImageRemoved() throws Exception {
+ feedItemImageRemoved();
+
+ original.updateFromOther(changedFeedItem);
+
+ feedItemImageWasNotUpdated();
+ }
+
+ public void testUpdateFromOther_feedItemImageAdded() throws Exception {
+ feedItemHadNoImage();
+ setNewFeedItemImageDownloadUrl();
+
+ original.updateFromOther(changedFeedItem);
+
+ feedItemImageWasUpdated();
+ }
+
+ private void feedItemHadNoImage() {
+ original.setImage(null);
+ }
+
+ private void setNewFeedItemImageDownloadUrl() {
+ changedFeedItem.getImage().setDownload_url("http://example.com/new_picture");
+ }
+
+ private void feedItemImageRemoved() {
+ changedFeedItem.setImage(null);
+ }
+
+ private void feedItemImageWasUpdated() {
+ assertEquals(original.getImage().getDownload_url(), changedFeedItem.getImage().getDownload_url());
+ }
+
+ private void feedItemImageWasNotUpdated() {
+ assertTrue(originalImage == original.getImage());
+ }
+
+} \ No newline at end of file
diff --git a/core/src/androidTest/java/de/danoeh/antennapod/core/feed/FeedMother.java b/core/src/androidTest/java/de/danoeh/antennapod/core/feed/FeedMother.java
new file mode 100644
index 000000000..1cea6b9c9
--- /dev/null
+++ b/core/src/androidTest/java/de/danoeh/antennapod/core/feed/FeedMother.java
@@ -0,0 +1,14 @@
+package de.danoeh.antennapod.core.feed;
+
+import static de.danoeh.antennapod.core.feed.FeedImageMother.anyFeedImage;
+
+public class FeedMother {
+
+ public static Feed anyFeed() {
+ FeedImage image = anyFeedImage();
+ return new Feed(0, null, "title", "http://example.com", "This is the description",
+ "http://example.com/payment", "Daniel", "en", null, "http://example.com/feed", image,
+ null, "http://example.com/feed", true);
+ }
+
+}
diff --git a/core/src/androidTest/java/de/danoeh/antennapod/core/feed/FeedTest.java b/core/src/androidTest/java/de/danoeh/antennapod/core/feed/FeedTest.java
new file mode 100644
index 000000000..8067ec93f
--- /dev/null
+++ b/core/src/androidTest/java/de/danoeh/antennapod/core/feed/FeedTest.java
@@ -0,0 +1,92 @@
+package de.danoeh.antennapod.core.feed;
+
+import android.test.AndroidTestCase;
+
+import static de.danoeh.antennapod.core.feed.FeedImageMother.anyFeedImage;
+import static de.danoeh.antennapod.core.feed.FeedMother.anyFeed;
+
+public class FeedTest extends AndroidTestCase {
+
+ private Feed original;
+ private FeedImage originalImage;
+ private Feed changedFeed;
+
+ @Override
+ protected void setUp() {
+ original = anyFeed();
+ originalImage = original.getImage();
+ changedFeed = anyFeed();
+ }
+
+ public void testCompareWithOther_feedImageDownloadUrlChanged() throws Exception {
+ setNewFeedImageDownloadUrl();
+
+ feedHasChanged();
+ }
+
+ public void testCompareWithOther_sameFeedImage() throws Exception {
+ changedFeed.setImage(anyFeedImage());
+
+ feedHasNotChanged();
+ }
+
+ public void testCompareWithOther_feedImageRemoved() throws Exception {
+ feedImageRemoved();
+
+ feedHasNotChanged();
+ }
+
+ public void testUpdateFromOther_feedImageDownloadUrlChanged() throws Exception {
+ setNewFeedImageDownloadUrl();
+
+ original.updateFromOther(changedFeed);
+
+ feedImageWasUpdated();
+ }
+
+ public void testUpdateFromOther_feedImageRemoved() throws Exception {
+ feedImageRemoved();
+
+ original.updateFromOther(changedFeed);
+
+ feedImageWasNotUpdated();
+ }
+
+ public void testUpdateFromOther_feedImageAdded() throws Exception {
+ feedHadNoImage();
+ setNewFeedImageDownloadUrl();
+
+ original.updateFromOther(changedFeed);
+
+ feedImageWasUpdated();
+ }
+
+ private void feedHasNotChanged() {
+ assertFalse(original.compareWithOther(changedFeed));
+ }
+
+ private void feedHadNoImage() {
+ original.setImage(null);
+ }
+
+ private void setNewFeedImageDownloadUrl() {
+ changedFeed.getImage().setDownload_url("http://example.com/new_picture");
+ }
+
+ private void feedHasChanged() {
+ assertTrue(original.compareWithOther(changedFeed));
+ }
+
+ private void feedImageRemoved() {
+ changedFeed.setImage(null);
+ }
+
+ private void feedImageWasUpdated() {
+ assertEquals(original.getImage().getDownload_url(), changedFeed.getImage().getDownload_url());
+ }
+
+ private void feedImageWasNotUpdated() {
+ assertTrue(originalImage == original.getImage());
+ }
+
+} \ No newline at end of file
diff --git a/core/src/androidTest/java/de/danoeh/antennapod/core/tests/util/DateUtilsTest.java b/core/src/androidTest/java/de/danoeh/antennapod/core/tests/util/DateUtilsTest.java
index 2727b1447..8adcc41c5 100644
--- a/core/src/androidTest/java/de/danoeh/antennapod/core/tests/util/DateUtilsTest.java
+++ b/core/src/androidTest/java/de/danoeh/antennapod/core/tests/util/DateUtilsTest.java
@@ -86,7 +86,7 @@ public class DateUtilsTest extends AndroidTestCase {
}
public void testAsctime() throws Exception {
- GregorianCalendar exp = new GregorianCalendar(2011, 4, 25, 12, 33, 00);
+ GregorianCalendar exp = new GregorianCalendar(2011, 4, 25, 12, 33, 0);
exp.setTimeZone(TimeZone.getTimeZone("UTC"));
Date expected = new Date(exp.getTimeInMillis());
Date actual = DateUtils.parse("Wed, 25 May 2011 12:33:00");
@@ -101,4 +101,33 @@ public class DateUtilsTest extends AndroidTestCase {
assertEquals(expected, actual);
}
+ public void testParseDateWithNoTimezonePadding() throws Exception {
+ GregorianCalendar exp = new GregorianCalendar(2017, 1, 22, 22, 28, 0);
+ exp.setTimeZone(TimeZone.getTimeZone("UTC"));
+ Date expected = new Date(exp.getTimeInMillis() + 2);
+ Date actual = DateUtils.parse("2017-02-22T14:28:00.002-08:00");
+ assertEquals(expected, actual);
+ }
+
+ public void testParseDateWithForCest() throws Exception {
+ GregorianCalendar exp1 = new GregorianCalendar(2017, 0, 28, 22, 0, 0);
+ exp1.setTimeZone(TimeZone.getTimeZone("UTC"));
+ Date expected1 = new Date(exp1.getTimeInMillis());
+ Date actual1 = DateUtils.parse("Sun, 29 Jan 2017 00:00:00 CEST");
+ assertEquals(expected1, actual1);
+
+ GregorianCalendar exp2 = new GregorianCalendar(2017, 0, 28, 23, 0, 0);
+ exp2.setTimeZone(TimeZone.getTimeZone("UTC"));
+ Date expected2 = new Date(exp2.getTimeInMillis());
+ Date actual2 = DateUtils.parse("Sun, 29 Jan 2017 00:00:00 CET");
+ assertEquals(expected2, actual2);
+ }
+
+ public void testParseDateWithIncorrectWeekday() {
+ GregorianCalendar exp1 = new GregorianCalendar(2014, 9, 8, 9, 0, 0);
+ exp1.setTimeZone(TimeZone.getTimeZone("GMT"));
+ Date expected = new Date(exp1.getTimeInMillis());
+ Date actual = DateUtils.parse("Thu, 8 Oct 2014 09:00:00 GMT"); // actually a Wednesday
+ assertEquals(expected, actual);
+ }
}
diff --git a/core/src/androidTest/java/de/danoeh/antennapod/core/tests/util/service/download/DownloadServiceTest.java b/core/src/androidTest/java/de/danoeh/antennapod/core/tests/util/service/download/DownloadServiceTest.java
new file mode 100644
index 000000000..94cfb3278
--- /dev/null
+++ b/core/src/androidTest/java/de/danoeh/antennapod/core/tests/util/service/download/DownloadServiceTest.java
@@ -0,0 +1,35 @@
+package de.danoeh.antennapod.core.tests.util.service.download;
+
+import android.test.AndroidTestCase;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import de.danoeh.antennapod.core.feed.Feed;
+import de.danoeh.antennapod.core.feed.FeedImage;
+import de.danoeh.antennapod.core.feed.FeedItem;
+import de.danoeh.antennapod.core.service.download.DownloadService;
+
+public class DownloadServiceTest extends AndroidTestCase {
+
+ public void testRemoveDuplicateImages() {
+ List<FeedItem> items = new ArrayList<>();
+ for (int i = 0; i < 50; i++) {
+ FeedItem item = new FeedItem();
+ String url = (i % 5 == 0) ? "dupe_url" : String.format("url_%d", i);
+ item.setImage(new FeedImage(null, url, ""));
+ items.add(item);
+ }
+ Feed feed = new Feed();
+ feed.setItems(items);
+
+ DownloadService.removeDuplicateImages(feed);
+
+ assertEquals(50, items.size());
+ for (int i = 0; i < items.size(); i++) {
+ FeedItem item = items.get(i);
+ String want = (i == 0) ? "dupe_url" : (i % 5 == 0) ? null : String.format("url_%d", i);
+ assertEquals(want, item.getImageLocation());
+ }
+ }
+}
diff --git a/core/src/free/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceFlavorHelper.java b/core/src/free/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceFlavorHelper.java
index 6bc3ed7c5..4e6482fda 100644
--- a/core/src/free/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceFlavorHelper.java
+++ b/core/src/free/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceFlavorHelper.java
@@ -2,6 +2,8 @@ package de.danoeh.antennapod.core.service.playback;
import android.content.Context;
import android.support.annotation.StringRes;
+import android.support.v4.media.session.MediaSessionCompat;
+import android.support.v4.media.session.PlaybackStateCompat;
/**
* Class intended to work along PlaybackService and provide support for different flavors.
@@ -41,4 +43,12 @@ public class PlaybackServiceFlavorHelper {
boolean onSharedPreference(String key) {
return false;
}
+
+ void sessionStateAddActionForWear(PlaybackStateCompat.Builder sessionState, String actionName, CharSequence name, int icon) {
+ // no-op
+ }
+
+ void mediaSessionSetExtraForWear(MediaSessionCompat mediaSession) {
+ // no-op
+ }
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/dialog/ConfirmationDialog.java b/core/src/main/java/de/danoeh/antennapod/core/dialog/ConfirmationDialog.java
index 266526d82..b14803751 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/dialog/ConfirmationDialog.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/dialog/ConfirmationDialog.java
@@ -16,16 +16,20 @@ public abstract class ConfirmationDialog {
private static final String TAG = ConfirmationDialog.class.getSimpleName();
protected Context context;
- int titleId;
- int messageId;
+ private int titleId;
+ private String message;
- int positiveText;
- int negativeText;
+ private int positiveText;
+ private int negativeText;
public ConfirmationDialog(Context context, int titleId, int messageId) {
+ this(context, titleId, context.getString(messageId));
+ }
+
+ public ConfirmationDialog(Context context, int titleId, String message) {
this.context = context;
this.titleId = titleId;
- this.messageId = messageId;
+ this.message = message;
}
public void onCancelButtonPressed(DialogInterface dialog) {
@@ -47,7 +51,7 @@ public abstract class ConfirmationDialog {
public final AlertDialog createNewDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(titleId);
- builder.setMessage(messageId);
+ builder.setMessage(message);
builder.setPositiveButton(positiveText != 0 ? positiveText : R.string.confirm_label,
(dialog, which) -> onConfirmButtonPressed(dialog));
builder.setNegativeButton(negativeText != 0 ? negativeText : R.string.cancel_label,
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java b/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java
index ac23f3d3d..746dd43c4 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java
@@ -1,6 +1,5 @@
package de.danoeh.antennapod.core.feed;
-import android.content.Context;
import android.database.Cursor;
import android.support.annotation.Nullable;
import android.text.TextUtils;
@@ -21,9 +20,9 @@ import de.danoeh.antennapod.core.util.flattr.FlattrThing;
* @author daniel
*/
public class Feed extends FeedFile implements FlattrThing, ImageResource {
+
public static final int FEEDFILETYPE_FEED = 0;
public static final String TYPE_RSS2 = "rss";
- public static final String TYPE_RSS091 = "rss";
public static final String TYPE_ATOM1 = "atom";
/* title as defined by the feed */
@@ -221,33 +220,6 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource {
return feed;
}
-
- /**
- * Returns true if at least one item in the itemlist is unread.
- *
- */
- public boolean hasNewItems() {
- for (FeedItem item : items) {
- if (item.isNew()) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns true if at least one item in the itemlist is unread.
- *
- */
- public boolean hasUnplayedItems() {
- for (FeedItem item : items) {
- if (!item.isNew() && !item.isPlayed()) {
- return true;
- }
- }
- return false;
- }
-
/**
* Returns the number of FeedItems.
*
@@ -294,6 +266,9 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource {
public void updateFromOther(Feed other) {
// don't update feed's download_url, we do that manually if redirected
// see AntennapodHttpClient
+ if (other.image != null) {
+ this.image = other.image;
+ }
if (other.feedTitle != null) {
feedTitle = other.feedTitle;
}
@@ -330,6 +305,9 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource {
if (super.compareWithOther(other)) {
return true;
}
+ if(other.image != null && !TextUtils.equals(image.download_url, other.image.download_url)) {
+ return true;
+ }
if (!TextUtils.equals(feedTitle, other.feedTitle)) {
return true;
}
@@ -511,7 +489,7 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource {
return preferences;
}
- public void savePreferences(Context context) {
+ public void savePreferences() {
DBWriter.setFeedPreferences(preferences);
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java
index ee7a738d0..66c4b10d0 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java
@@ -177,6 +177,9 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr
public void updateFromOther(FeedItem other) {
super.updateFromOther(other);
+ if (other.image != null) {
+ this.image = other.image;
+ }
if (other.title != null) {
title = other.title;
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/gpoddernet/GpodnetService.java b/core/src/main/java/de/danoeh/antennapod/core/gpoddernet/GpodnetService.java
index 0218b103a..4459fbd08 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/gpoddernet/GpodnetService.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/gpoddernet/GpodnetService.java
@@ -568,7 +568,9 @@ public class GpodnetService {
e.printStackTrace();
throw new GpodnetServiceException(e);
} finally {
- body.close();
+ if (body != null) {
+ body.close();
+ }
}
return responseString;
}
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 3f2562178..48492ced9 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
@@ -75,6 +75,7 @@ public class UserPreferences {
public static final String PREF_RESUME_AFTER_CALL = "prefResumeAfterCall";
// Network
+ public static final String PREF_ENQUEUE_DOWNLOADED = "prefEnqueueDownloaded";
public static final String PREF_UPDATE_INTERVAL = "prefAutoUpdateIntervall";
public static final String PREF_MOBILE_UPDATE = "prefMobileUpdate";
public static final String PREF_EPISODE_CLEANUP = "prefEpisodeCleanup";
@@ -126,6 +127,7 @@ public class UserPreferences {
public static final int FEED_ORDER_COUNTER = 0;
public static final int FEED_ORDER_ALPHABETICAL = 1;
public static final int FEED_ORDER_LAST_UPDATE = 2;
+ public static final int FEED_ORDER_MOST_PLAYED = 3;
public static final int FEED_COUNTER_SHOW_NEW_UNPLAYED_SUM = 0;
public static final int FEED_COUNTER_SHOW_NEW = 1;
public static final int FEED_COUNTER_SHOW_UNPLAYED = 2;
@@ -259,11 +261,10 @@ public class UserPreferences {
return prefs.getBoolean(PREF_SHOW_DOWNLOAD_REPORT, true);
}
- /**
- * Returns {@code true} if new queue elements are added to the front
- *
- * @return {@code true} if new queue elements are added to the front; {@code false} otherwise
- */
+ public static boolean enqueueDownloadedEpisodes() {
+ return prefs.getBoolean(PREF_ENQUEUE_DOWNLOADED, true);
+ }
+
public static boolean enqueueAtFront() {
return prefs.getBoolean(PREF_QUEUE_ADD_TO_FRONT, false);
}
@@ -413,7 +414,7 @@ public class UserPreferences {
return cacheSizeMB;
}
- public static int getFastFowardSecs() {
+ public static int getFastForwardSecs() {
return prefs.getInt(PREF_FAST_FORWARD_SECS, 30);
}
@@ -478,13 +479,13 @@ public class UserPreferences {
return prefs.getBoolean(PREF_QUEUE_LOCKED, false);
}
- public static void setPrefFastForwardSecs(int secs) {
+ public static void setFastForwardSecs(int secs) {
prefs.edit()
.putInt(PREF_FAST_FORWARD_SECS, secs)
.apply();
}
- public static void setPrefRewindSecs(int secs) {
+ public static void setRewindSecs(int secs) {
prefs.edit()
.putInt(PREF_REWIND_SECS, secs)
.apply();
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 e0abe0efb..9bbeb7c88 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/receiver/FeedUpdateReceiver.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/receiver/FeedUpdateReceiver.java
@@ -21,7 +21,7 @@ public class FeedUpdateReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "Received intent");
ClientConfig.initialize(context);
- if (NetworkUtils.isDownloadAllowed()) {
+ if (NetworkUtils.networkAvailable() && NetworkUtils.isDownloadAllowed()) {
DBTasks.refreshAllFeeds(context, null);
} else {
Log.d(TAG, "Blocking automatic update: no wifi available / no mobile updates allowed");
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 6bd9fc83c..64f6ec774 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
@@ -1,6 +1,5 @@
package de.danoeh.antennapod.core.service.download;
-import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
@@ -15,13 +14,15 @@ import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.support.annotation.NonNull;
+import android.support.annotation.VisibleForTesting;
import android.support.v4.app.NotificationCompat;
-import android.support.v4.util.Pair;
import android.text.TextUtils;
import android.util.Log;
+import android.util.Pair;
import android.webkit.URLUtil;
import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.StringUtils;
import org.xml.sax.SAXException;
import java.io.File;
@@ -30,8 +31,10 @@ import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
+import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
@@ -196,11 +199,11 @@ public class DownloadService extends Service {
saveDownloadStatus(status);
handleFailedDownload(status, downloader.getDownloadRequest());
- if(type == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
+ if (type == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
long id = status.getFeedfileId();
FeedMedia media = DBReader.getFeedMedia(id);
FeedItem item;
- if(media == null || (item = media.getItem()) == null) {
+ if (media == null || (item = media.getItem()) == null) {
return;
}
boolean httpNotFound = status.getReason() == DownloadError.ERROR_HTTP_DATA_ERROR
@@ -219,10 +222,10 @@ public class DownloadService extends Service {
} else {
// if FeedMedia download has been canceled, fake FeedItem update
// so that lists reload that it
- if(status.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
+ if (status.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
FeedMedia media = DBReader.getFeedMedia(status.getFeedfileId());
FeedItem item;
- if(media == null || (item = media.getItem()) == null) {
+ if (media == null || (item = media.getItem()) == null) {
return;
}
EventBus.getDefault().post(FeedItemEvent.updated(item));
@@ -231,9 +234,9 @@ public class DownloadService extends Service {
queryDownloadsAsync();
}
} catch (InterruptedException e) {
- Log.d(TAG, "DownloadCompletionThread was interrupted");
+ Log.e(TAG, "DownloadCompletionThread was interrupted");
} catch (ExecutionException e) {
- e.printStackTrace();
+ Log.e(TAG, "ExecutionException in DownloadCompletionThread: " + e.getMessage());
numberOfDownloads.decrementAndGet();
}
}
@@ -251,7 +254,6 @@ public class DownloadService extends Service {
return Service.START_NOT_STICKY;
}
- @SuppressLint("NewApi")
@Override
public void onCreate() {
Log.d(TAG, "Service started");
@@ -326,7 +328,7 @@ public class DownloadService extends Service {
// if this was the initial gpodder sync, i.e. we just synced the feeds successfully,
// it is now time to sync the episode actions
- if(GpodnetPreferences.loggedIn() &&
+ if (GpodnetPreferences.loggedIn() &&
GpodnetPreferences.getLastSubscriptionSyncTimestamp() > 0 &&
GpodnetPreferences.getLastEpisodeActionsSyncTimestamp() == 0) {
GpodnetSyncService.sendSyncActionsIntent(this);
@@ -337,16 +339,14 @@ public class DownloadService extends Service {
}
private void setupNotificationBuilders() {
- Bitmap icon = BitmapFactory.decodeResource(getResources(),
- R.drawable.stat_notify_sync);
-
- notificationCompatBuilder = new NotificationCompat.Builder(this)
- .setOngoing(true)
- .setContentIntent(ClientConfig.downloadServiceCallbacks.getNotificationContentIntent(this))
- .setLargeIcon(icon)
- .setSmallIcon(R.drawable.stat_notify_sync)
- .setVisibility(Notification.VISIBILITY_PUBLIC);
+ Bitmap icon = BitmapFactory.decodeResource(getResources(), R.drawable.stat_notify_sync);
+ notificationCompatBuilder = new NotificationCompat.Builder(this)
+ .setOngoing(true)
+ .setContentIntent(ClientConfig.downloadServiceCallbacks.getNotificationContentIntent(this))
+ .setLargeIcon(icon)
+ .setSmallIcon(R.drawable.stat_notify_sync)
+ .setVisibility(Notification.VISIBILITY_PUBLIC);
Log.d(TAG, "Notification set up");
}
@@ -356,49 +356,21 @@ public class DownloadService extends Service {
* before setupNotificationBuilders.
*/
private Notification updateNotifications() {
- String contentTitle = getString(R.string.download_notification_title);
- int numDownloads = requester.getNumberOfDownloads();
- String downloadsLeft;
- if (numDownloads > 0) {
- downloadsLeft = getResources()
- .getQuantityString(R.plurals.downloads_left, numDownloads, numDownloads);
- } else {
- downloadsLeft = getString(R.string.downloads_processing);
+ if (notificationCompatBuilder == null) {
+ return null;
}
- if (notificationCompatBuilder != null) {
-
- StringBuilder bigText = new StringBuilder("");
- for (int i = 0; i < downloads.size(); i++) {
- Downloader downloader = downloads.get(i);
- final DownloadRequest request = downloader
- .getDownloadRequest();
- if (request.getFeedfileType() == Feed.FEEDFILETYPE_FEED) {
- if (request.getTitle() != null) {
- if (i > 0) {
- bigText.append("\n");
- }
- bigText.append("\u2022 ").append(request.getTitle());
- }
- } else if (request.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
- if (request.getTitle() != null) {
- if (i > 0) {
- bigText.append("\n");
- }
- bigText.append("\u2022 ").append(request.getTitle())
- .append(" (").append(request.getProgressPercent())
- .append("%)");
- }
- }
- }
- notificationCompatBuilder.setContentTitle(contentTitle);
- notificationCompatBuilder.setContentText(downloadsLeft);
- if (bigText != null) {
- notificationCompatBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(bigText.toString()));
- }
- return notificationCompatBuilder.build();
- }
- return null;
+ String contentTitle = getString(R.string.download_notification_title);
+ int numDownloads = requester.getNumberOfDownloads();
+ String downloadsLeft = (numDownloads > 0) ?
+ getResources().getQuantityString(R.plurals.downloads_left, numDownloads, numDownloads) :
+ getString(R.string.downloads_processing);
+ String bigText = compileNotificationString(downloads);
+
+ notificationCompatBuilder.setContentTitle(contentTitle);
+ notificationCompatBuilder.setContentText(downloadsLeft);
+ notificationCompatBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(bigText));
+ return notificationCompatBuilder.build();
}
private Downloader getDownloader(String downloadUrl) {
@@ -416,7 +388,7 @@ public class DownloadService extends Service {
public void onReceive(Context context, Intent intent) {
if (TextUtils.equals(intent.getAction(), ACTION_CANCEL_DOWNLOAD)) {
String url = intent.getStringExtra(EXTRA_DOWNLOAD_URL);
- if(url == null) {
+ if (url == null) {
throw new IllegalArgumentException("ACTION_CANCEL_DOWNLOAD intent needs download url extra");
}
@@ -453,7 +425,7 @@ public class DownloadService extends Service {
if (downloader != null) {
numberOfDownloads.incrementAndGet();
// smaller rss feeds before bigger media files
- if(request.getFeedfileType() == Feed.FEEDFILETYPE_FEED) {
+ if (request.getFeedfileType() == Feed.FEEDFILETYPE_FEED) {
downloads.add(0, downloader);
} else {
downloads.add(downloader);
@@ -467,15 +439,11 @@ public class DownloadService extends Service {
}
private Downloader getDownloader(DownloadRequest request) {
- if (URLUtil.isHttpUrl(request.getSource())
- || URLUtil.isHttpsUrl(request.getSource())) {
- return new HttpDownloader(request);
+ if (!URLUtil.isHttpUrl(request.getSource()) && !URLUtil.isHttpsUrl(request.getSource())) {
+ Log.e(TAG, "Could not find appropriate downloader for " + request.getSource());
+ return null;
}
- Log.e(TAG,
- "Could not find appropriate downloader for "
- + request.getSource()
- );
- return null;
+ return new HttpDownloader(request);
}
/**
@@ -484,8 +452,7 @@ public class DownloadService extends Service {
*/
private void removeDownload(final Downloader d) {
handler.post(() -> {
- Log.d(TAG, "Removing downloader: "
- + d.getDownloadRequest().getSource());
+ Log.d(TAG, "Removing downloader: " + d.getDownloadRequest().getSource());
boolean rc = downloads.remove(d);
Log.d(TAG, "Result of downloads.remove: " + rc);
DownloadRequester.getInstance().removeDownload(d.getDownloadRequest());
@@ -532,10 +499,8 @@ public class DownloadService extends Service {
Log.d(TAG, "Creating report");
// create notification object
Notification notification = new NotificationCompat.Builder(this)
- .setTicker(
- getString(R.string.download_report_title))
- .setContentTitle(
- getString(R.string.download_report_content_title))
+ .setTicker(getString(R.string.download_report_title))
+ .setContentTitle(getString(R.string.download_report_content_title))
.setContentText(
String.format(
getString(R.string.download_report_content),
@@ -585,8 +550,8 @@ public class DownloadService extends Service {
private void postAuthenticationNotification(final DownloadRequest downloadRequest) {
handler.post(() -> {
- final String resourceTitle = (downloadRequest.getTitle() != null)
- ? downloadRequest.getTitle() : downloadRequest.getSource();
+ final String resourceTitle = (downloadRequest.getTitle() != null) ?
+ downloadRequest.getTitle() : downloadRequest.getSource();
NotificationCompat.Builder builder = new NotificationCompat.Builder(DownloadService.this);
builder.setTicker(getText(R.string.authentication_notification_title))
@@ -611,7 +576,6 @@ public class DownloadService extends Service {
private void handleCompletedFeedDownload(DownloadRequest request) {
Log.d(TAG, "Handling completed Feed Download");
feedSyncThread.submitCompletedDownload(request);
-
}
/**
@@ -660,6 +624,7 @@ public class DownloadService extends Service {
parserService.submit(new FeedParserTask(request));
tasks++;
} catch (InterruptedException e) {
+ Log.e(TAG, "FeedSyncThread was interrupted");
return null;
}
@@ -695,9 +660,10 @@ public class DownloadService extends Service {
if (result != null) {
results.add(result);
}
- } catch (InterruptedException | ExecutionException e) {
- e.printStackTrace();
-
+ } catch (InterruptedException e) {
+ Log.e(TAG, "FeedSyncThread was interrupted");
+ } catch (ExecutionException e) {
+ Log.e(TAG, "ExecutionException in FeedSyncThread: " + e.getMessage());
}
}
@@ -706,7 +672,7 @@ public class DownloadService extends Service {
private int pollCompletedDownloads() {
int tasks = 0;
- for (int i = 0; i < completedRequests.size(); i++) {
+ while (!completedRequests.isEmpty()) {
parserService.submit(new FeedParserTask(completedRequests.poll()));
tasks++;
}
@@ -732,8 +698,10 @@ public class DownloadService extends Service {
if (dbUpdateFuture != null) {
try {
dbUpdateFuture.get();
- } catch (InterruptedException | ExecutionException e) {
- e.printStackTrace();
+ } catch (InterruptedException e) {
+ Log.e(TAG, "FeedSyncThread was interrupted");
+ } catch (ExecutionException e) {
+ Log.e(TAG, "ExecutionException in FeedSyncThread: " + e.getMessage());
}
}
@@ -770,14 +738,13 @@ public class DownloadService extends Service {
try {
dbUpdateFuture.get();
} catch (InterruptedException e) {
+ Log.e(TAG, "interrupted while updating the db");
} catch (ExecutionException e) {
- e.printStackTrace();
+ Log.e(TAG, "ExecutionException while updating the db: " + e.getMessage());
}
}
-
Log.d(TAG, "Shutting down");
-
}
/**
@@ -842,25 +809,28 @@ public class DownloadService extends Service {
successful = false;
reason = DownloadError.ERROR_PARSER_EXCEPTION;
reasonDetailed = e.getMessage();
+ } finally {
+ File feedFile = new File(request.getDestination());
+ if (feedFile.exists()) {
+ boolean deleted = feedFile.delete();
+ Log.d(TAG, "Deletion of file '" + feedFile.getAbsolutePath() + "' " + (deleted ? "successful" : "FAILED"));
+ }
}
- // cleanup();
-
-
if (successful) {
// we create a 'successful' download log if the feed's last refresh failed
List<DownloadStatus> log = DBReader.getFeedDownloadLog(feed);
- if(log.size() > 0 && !log.get(0).isSuccessful()) {
- saveDownloadStatus(new DownloadStatus(feed,
- feed.getHumanReadableIdentifier(), DownloadError.SUCCESS, successful,
- reasonDetailed));
+ if (log.size() > 0 && !log.get(0).isSuccessful()) {
+ saveDownloadStatus(
+ new DownloadStatus(feed, feed.getHumanReadableIdentifier(),
+ DownloadError.SUCCESS, successful, reasonDetailed));
}
return Pair.create(request, result);
} else {
numberOfDownloads.decrementAndGet();
- saveDownloadStatus(new DownloadStatus(feed,
- feed.getHumanReadableIdentifier(), reason, successful,
- reasonDetailed));
+ saveDownloadStatus(
+ new DownloadStatus(feed, feed.getHumanReadableIdentifier(), reason,
+ successful, reasonDetailed));
return null;
}
}
@@ -881,26 +851,6 @@ public class DownloadService extends Service {
return true;
}
- /**
- * Checks if the FeedItems of this feed have images that point
- * to the same URL. If two FeedItems have an image that points to
- * the same URL, the reference of the second item is removed, so that every image
- * reference is unique.
- */
- private void removeDuplicateImages(Feed feed) {
- for (int x = 0; x < feed.getItems().size(); x++) {
- for (int y = x + 1; y < feed.getItems().size(); y++) {
- FeedItem item1 = feed.getItems().get(x);
- FeedItem item2 = feed.getItems().get(y);
- if (item1.hasItemImage() && item2.hasItemImage()) {
- if (TextUtils.equals(item1.getImage().getDownload_url(), item2.getImage().getDownload_url())) {
- item2.setImage(null);
- }
- }
- }
- }
- }
-
private boolean hasValidFeedItems(Feed feed) {
for (FeedItem item : feed.getItems()) {
if (item.getTitle() == null) {
@@ -908,8 +858,7 @@ public class DownloadService extends Service {
return false;
}
if (item.getPubDate() == null) {
- Log.e(TAG,
- "Item has no pubDate. Using current time as pubDate");
+ Log.e(TAG, "Item has no pubDate. Using current time as pubDate");
if (item.getTitle() != null) {
Log.e(TAG, "Title of invalid item: " + item.getTitle());
}
@@ -971,11 +920,11 @@ public class DownloadService extends Service {
@Override
public void run() {
- if(request.getFeedfileType() == Feed.FEEDFILETYPE_FEED) {
+ if (request.getFeedfileType() == Feed.FEEDFILETYPE_FEED) {
DBWriter.setFeedLastUpdateFailed(request.getFeedfileId(), true);
} else if (request.isDeleteOnFailure()) {
Log.d(TAG, "Ignoring failed download, deleteOnFailure=true");
- } else {
+ } else {
File dest = new File(request.getDestination());
if (dest.exists() && request.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
Log.d(TAG, "File has been partially downloaded. Writing file url");
@@ -983,8 +932,10 @@ public class DownloadService extends Service {
media.setFile_url(request.getDestination());
try {
DBWriter.setFeedMedia(media).get();
- } catch (InterruptedException | ExecutionException e) {
- e.printStackTrace();
+ } catch (InterruptedException e) {
+ Log.e(TAG, "FailedDownloadHandler was interrupted");
+ } catch (ExecutionException e) {
+ Log.e(TAG, "ExecutionException in FailedDownloadHandler: " + e.getMessage());
}
}
}
@@ -1020,50 +971,51 @@ public class DownloadService extends Service {
ChapterUtils.loadChaptersFromFileUrl(media);
// Get duration
- MediaMetadataRetriever mmr = null;
+ MediaMetadataRetriever mmr = new MediaMetadataRetriever();
+ String durationStr = null;
try {
- mmr = new MediaMetadataRetriever();
mmr.setDataSource(media.getFile_url());
- String durationStr = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
+ durationStr = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
media.setDuration(Integer.parseInt(durationStr));
Log.d(TAG, "Duration of file is " + media.getDuration());
} catch (NumberFormatException e) {
- e.printStackTrace();
- } catch (RuntimeException e) {
- e.printStackTrace();
+ Log.d(TAG, "Invalid file duration: " + durationStr);
+ } catch(Exception e) {
+ Log.e(TAG, "Get duration failed", e);
} finally {
- if (mmr != null) {
- mmr.release();
- }
+ mmr.release();
}
final FeedItem item = media.getItem();
try {
// we've received the media, we don't want to autodownload it again
- if(item != null) {
+ if (item != null) {
item.setAutoDownload(false);
DBWriter.setFeedItem(item).get();
}
DBWriter.setFeedMedia(media).get();
- if (item != null && !DBTasks.isInQueue(DownloadService.this, item.getId())) {
+ if (item != null && UserPreferences.enqueueDownloadedEpisodes() &&
+ !DBTasks.isInQueue(DownloadService.this, item.getId())) {
DBWriter.addQueueItem(DownloadService.this, item).get();
}
- } catch (ExecutionException | InterruptedException e) {
- e.printStackTrace();
+ } catch (InterruptedException e) {
+ Log.e(TAG, "MediaHandlerThread was interrupted");
+ } catch (ExecutionException e) {
+ Log.e(TAG, "ExecutionException in MediaHandlerThread: " + e.getMessage());
status = new DownloadStatus(media, media.getEpisodeTitle(), DownloadError.ERROR_DB_ACCESS_ERROR, false, e.getMessage());
}
saveDownloadStatus(status);
- if(GpodnetPreferences.loggedIn() && item != null) {
- GpodnetEpisodeAction action = new GpodnetEpisodeAction.Builder(item, Action.DOWNLOAD)
- .currentDeviceId()
- .currentTimestamp()
- .build();
- GpodnetPreferences.enqueueEpisodeAction(action);
+ if (GpodnetPreferences.loggedIn() && item != null) {
+ GpodnetEpisodeAction action = new GpodnetEpisodeAction.Builder(item, Action.DOWNLOAD)
+ .currentDeviceId()
+ .currentTimestamp()
+ .build();
+ GpodnetPreferences.enqueueEpisodeAction(action);
}
numberOfDownloads.decrementAndGet();
@@ -1103,6 +1055,7 @@ public class DownloadService extends Service {
}
});
}
+
}
@@ -1119,11 +1072,57 @@ public class DownloadService extends Service {
private void postDownloaders() {
long now = System.currentTimeMillis();
- if(now - lastPost >= 250) {
+ if (now - lastPost >= 250) {
postHandler.removeCallbacks(postDownloaderTask);
postDownloaderTask.run();
lastPost = now;
}
}
+ /**
+ * Checks if the FeedItems of this feed have images that point to the same URL. If two FeedItems
+ * have an image that points to the same URL, the reference of the second item is removed, so
+ * that every image reference is unique.
+ */
+ @VisibleForTesting
+ public static void removeDuplicateImages(Feed feed) {
+ Set<String> known = new HashSet<String>();
+ for (FeedItem item : feed.getItems()) {
+ String url = item.hasItemImage() ? item.getImage().getDownload_url() : null;
+ if (url != null) {
+ if (known.contains(url)) {
+ item.setImage(null);
+ } else {
+ known.add(url);
+ }
+ }
+ }
+ }
+
+ private static String compileNotificationString(List<Downloader> downloads) {
+ List<String> lines = new ArrayList<>(downloads.size());
+ for (Downloader downloader : downloads) {
+ StringBuilder line = new StringBuilder("\u2022 ");
+ DownloadRequest request = downloader.getDownloadRequest();
+ switch (request.getFeedfileType()) {
+ case Feed.FEEDFILETYPE_FEED:
+ if (request.getTitle() != null) {
+ line.append(request.getTitle());
+ }
+ break;
+ case FeedMedia.FEEDFILETYPE_FEEDMEDIA:
+ if (request.getTitle() != null) {
+ line.append(request.getTitle())
+ .append(" (")
+ .append(request.getProgressPercent())
+ .append("%)");
+ }
+ break;
+ default:
+ line.append("Unknown: ").append(request.getFeedfileType());
+ }
+ lines.add(line.toString());
+ }
+ return StringUtils.join(lines, '\n');
+ }
}
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 f395dfb32..11cd21db5 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
@@ -300,7 +300,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
/**
* Called after media player has been prepared. This method is executed on the caller's thread.
*/
- void onPrepared(final boolean startWhenPrepared) {
+ private void onPrepared(final boolean startWhenPrepared) {
playerLock.lock();
if (playerStatus != PlayerStatus.PREPARING) {
@@ -688,18 +688,22 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
media = playable;
}
- private IPlayer createMediaPlayer() {
+ private void createMediaPlayer() {
if (mediaPlayer != null) {
mediaPlayer.release();
}
- if (media == null || media.getMediaType() == MediaType.VIDEO) {
+ if(media == null) {
+ mediaPlayer = null;
+ return;
+ }
+ if (media.getMediaType() == MediaType.VIDEO) {
mediaPlayer = new VideoPlayer();
} else {
mediaPlayer = new AudioPlayer(context);
}
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setWakeMode(context, PowerManager.PARTIAL_WAKE_LOCK);
- return setMediaPlayerListeners(mediaPlayer);
+ setMediaPlayerListeners(mediaPlayer);
}
private final AudioManager.OnAudioFocusChangeListener audioFocusChangeListener = new AudioManager.OnAudioFocusChangeListener() {
@@ -855,14 +859,20 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
if (mp == null || media == null) {
return mp;
}
- if (media.getMediaType() == MediaType.VIDEO) {
+ if (mp instanceof VideoPlayer) {
+ if (media.getMediaType() != MediaType.VIDEO) {
+ Log.w(TAG, "video player, but media type is " + media.getMediaType());
+ }
VideoPlayer vp = (VideoPlayer) mp;
vp.setOnCompletionListener(videoCompletionListener);
vp.setOnSeekCompleteListener(videoSeekCompleteListener);
vp.setOnErrorListener(videoErrorListener);
vp.setOnBufferingUpdateListener(videoBufferingUpdateListener);
vp.setOnInfoListener(videoInfoListener);
- } else {
+ } else if (mp instanceof AudioPlayer) {
+ if (media.getMediaType() != MediaType.AUDIO) {
+ Log.w(TAG, "audio player, but media type is " + media.getMediaType());
+ }
AudioPlayer ap = (AudioPlayer) mp;
ap.setOnCompletionListener(audioCompletionListener);
ap.setOnSeekCompleteListener(audioSeekCompleteListener);
@@ -870,6 +880,8 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
ap.setOnBufferingUpdateListener(audioBufferingUpdateListener);
ap.setOnInfoListener(audioInfoListener);
ap.setOnSpeedAdjustmentAvailableChangedListener(audioSetSpeedAbilityListener);
+ } else {
+ Log.w(TAG, "Unknown media player: " + mp);
}
return 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 7aa6c2697..b8ab70ed4 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
@@ -15,6 +15,7 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.AudioManager;
import android.media.MediaPlayer;
+import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
@@ -49,9 +50,11 @@ import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.R;
import de.danoeh.antennapod.core.event.MessageEvent;
import de.danoeh.antennapod.core.feed.Chapter;
+import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.feed.MediaType;
+import de.danoeh.antennapod.core.feed.SearchResult;
import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.preferences.SleepTimerPreferences;
@@ -60,6 +63,7 @@ import de.danoeh.antennapod.core.receiver.MediaButtonReceiver;
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.util.IntList;
import de.danoeh.antennapod.core.util.QueueAccess;
import de.danoeh.antennapod.core.util.playback.ExternalMedia;
@@ -129,6 +133,12 @@ public class PlaybackService extends MediaBrowserServiceCompat {
*/
public static final String ACTION_RESUME_PLAY_CURRENT_EPISODE = "action.de.danoeh.antennapod.core.service.resumePlayCurrentEpisode";
+ /**
+ * Custom action used by Android Wear
+ */
+ private static final String CUSTOM_ACTION_FAST_FORWARD = "action.de.danoeh.antennapod.core.service.fastForward";
+ private static final String CUSTOM_ACTION_REWIND = "action.de.danoeh.antennapod.core.service.rewind";
+
/**
* Used in NOTIFICATION_TYPE_RELOAD.
@@ -363,6 +373,23 @@ public class PlaybackService extends MediaBrowserServiceCompat {
MediaBrowserCompat.MediaItem.FLAG_BROWSABLE);
}
+ private MediaBrowserCompat.MediaItem createBrowsableMediaItemForFeed(Feed feed) {
+ MediaDescriptionCompat.Builder builder = new MediaDescriptionCompat.Builder()
+ .setMediaId("FeedId:" + Long.toString(feed.getId()))
+ .setTitle(feed.getTitle())
+ .setDescription(feed.getDescription())
+ .setSubtitle(feed.getCustomTitle());
+ if(feed.getImageLocation() != null) {
+ builder.setIconUri(Uri.parse(feed.getImageLocation()));
+ }
+ if(feed.getLink() != null) {
+ builder.setMediaUri(Uri.parse(feed.getLink()));
+ }
+ MediaDescriptionCompat description = builder.build();
+ return new MediaBrowserCompat.MediaItem(description,
+ MediaBrowserCompat.MediaItem.FLAG_BROWSABLE);
+ }
+
@Override
public void onLoadChildren(@NonNull String parentId,
@NonNull Result<List<MediaBrowserCompat.MediaItem>> result) {
@@ -370,7 +397,17 @@ public class PlaybackService extends MediaBrowserServiceCompat {
List<MediaBrowserCompat.MediaItem> mediaItems = new ArrayList<>();
if (parentId.equals(getResources().getString(R.string.app_name))) {
// Root List
- mediaItems.add(createBrowsableMediaItemForRoot());
+ try {
+ if (!(taskManager.getQueue().isEmpty())) {
+ mediaItems.add(createBrowsableMediaItemForRoot());
+ }
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ List<Feed> feeds = DBReader.getFeedList();
+ for (Feed feed: feeds) {
+ mediaItems.add(createBrowsableMediaItemForFeed(feed));
+ }
} else if (parentId.equals(getResources().getString(R.string.queue_label))){
// Child List
try {
@@ -380,6 +417,14 @@ public class PlaybackService extends MediaBrowserServiceCompat {
} catch (InterruptedException e) {
e.printStackTrace();
}
+ } else if (parentId.startsWith("FeedId:")) {
+ Long feedId = Long.parseLong(parentId.split(":")[1]);
+ List<FeedItem> feedItems = DBReader.getFeedItemList(DBReader.getFeed(feedId));
+ for (FeedItem feedItem: feedItems) {
+ if(feedItem.getMedia() != null && feedItem.getMedia().getMediaItem() != null) {
+ mediaItems.add(feedItem.getMedia().getMediaItem());
+ }
+ }
}
result.sendResult(mediaItems);
}
@@ -477,11 +522,11 @@ public class PlaybackService extends MediaBrowserServiceCompat {
} else {
// assume skip command comes from a (bluetooth) media button
// user actually wants to fast-forward
- seekDelta(UserPreferences.getFastFowardSecs() * 1000);
+ seekDelta(UserPreferences.getFastForwardSecs() * 1000);
}
break;
case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
- mediaPlayer.seekDelta(UserPreferences.getFastFowardSecs() * 1000);
+ mediaPlayer.seekDelta(UserPreferences.getFastForwardSecs() * 1000);
break;
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
if(UserPreferences.shouldHardwarePreviousButtonRestart()) {
@@ -1045,6 +1090,14 @@ public class PlaybackService extends MediaBrowserServiceCompat {
}
sessionState.setActions(capabilities);
+
+ flavorHelper.sessionStateAddActionForWear(sessionState,
+ CUSTOM_ACTION_REWIND, getString(R.string.rewind_label), android.R.drawable.ic_media_rew);
+ flavorHelper.sessionStateAddActionForWear(sessionState,
+ CUSTOM_ACTION_FAST_FORWARD, getString(R.string.fast_forward_label), android.R.drawable.ic_media_ff);
+
+ flavorHelper.mediaSessionSetExtraForWear(mediaSession);
+
mediaSession.setPlaybackState(sessionState.build());
}
@@ -1369,8 +1422,15 @@ public class PlaybackService extends MediaBrowserServiceCompat {
Log.d(TAG, "Car was unplugged during playback.");
pauseIfPauseOnDisconnect();
} else {
- mediaPlayer.setStartWhenPrepared(true);
- mediaPlayer.prepare();
+ PlayerStatus playerStatus = mediaPlayer.getPlayerStatus();
+ if (playerStatus == PlayerStatus.PAUSED || playerStatus == PlayerStatus.PREPARED) {
+ mediaPlayer.resume();
+ } else if (playerStatus == PlayerStatus.PREPARING) {
+ mediaPlayer.setStartWhenPrepared(!mediaPlayer.isStartWhenPrepared());
+ } else if (playerStatus == PlayerStatus.INITIALIZED) {
+ mediaPlayer.setStartWhenPrepared(true);
+ mediaPlayer.prepare();
+ }
}
}
};
@@ -1636,8 +1696,22 @@ public class PlaybackService extends MediaBrowserServiceCompat {
@Override
public void onPlayFromSearch (String query, Bundle extras) {
- //Until we parse the query just play from queue
+ Log.d(TAG, "onPlayFromSearch query=" + query + " extras=" + extras.toString());
+
+ List<SearchResult> results = FeedSearcher.performSearch(getBaseContext(),query,0);
+ for( SearchResult result : results) {
+ try {
+ FeedMedia p = ((FeedItem)(result.getComponent())).getMedia();
+ mediaPlayer.playMediaObject(p, !p.localFileAvailable(), true, true);
+ return;
+ } catch (Exception e) {
+ Log.d(TAG, e.getMessage());
+ e.printStackTrace();
+ continue;
+ }
+ }
onPlay();
+ return;
}
@Override
@@ -1669,7 +1743,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
@Override
public void onFastForward() {
Log.d(TAG, "onFastForward()");
- seekDelta(UserPreferences.getFastFowardSecs() * 1000);
+ seekDelta(UserPreferences.getFastForwardSecs() * 1000);
}
@Override
@@ -1678,7 +1752,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
if(UserPreferences.shouldHardwareButtonSkip()) {
mediaPlayer.skip();
} else {
- seekDelta(UserPreferences.getFastFowardSecs() * 1000);
+ seekDelta(UserPreferences.getFastForwardSecs() * 1000);
}
}
@@ -1702,6 +1776,16 @@ public class PlaybackService extends MediaBrowserServiceCompat {
}
return false;
}
+
+ @Override
+ public void onCustomAction(String action, Bundle extra) {
+ Log.d(TAG, "onCustomAction(" + action + ")");
+ if (CUSTOM_ACTION_FAST_FORWARD.equals(action)) {
+ onFastForward();
+ } else if (CUSTOM_ACTION_REWIND.equals(action)) {
+ onRewind();
+ }
+ }
};
private SharedPreferences.OnSharedPreferenceChangeListener prefListener =
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java
index 1d57d902c..a2ecd0a52 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java
@@ -4,7 +4,6 @@ import android.database.Cursor;
import android.support.v4.util.ArrayMap;
import android.util.Log;
-import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -66,23 +65,28 @@ public final class DBReader {
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
- List<Feed> result = getFeedList(adapter);
- adapter.close();
- return result;
+ try {
+ return getFeedList(adapter);
+ } finally {
+ adapter.close();
+ }
}
private static List<Feed> getFeedList(PodDBAdapter adapter) {
- Cursor feedlistCursor = adapter.getAllFeedsCursor();
- List<Feed> feeds = new ArrayList<>(feedlistCursor.getCount());
-
- if (feedlistCursor.moveToFirst()) {
- do {
- Feed feed = extractFeedFromCursorRow(adapter, feedlistCursor);
+ Cursor cursor = null;
+ try {
+ cursor = adapter.getAllFeedsCursor();
+ List<Feed> feeds = new ArrayList<>(cursor.getCount());
+ while (cursor.moveToNext()) {
+ Feed feed = extractFeedFromCursorRow(adapter, cursor);
feeds.add(feed);
- } while (feedlistCursor.moveToNext());
+ }
+ return feeds;
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
}
- feedlistCursor.close();
- return feeds;
}
/**
@@ -92,23 +96,26 @@ public final class DBReader {
*/
public static List<String> getFeedListDownloadUrls() {
PodDBAdapter adapter = PodDBAdapter.getInstance();
- List<String> result = new ArrayList<>();
adapter.open();
- Cursor feeds = adapter.getFeedCursorDownloadUrls();
- if (feeds.moveToFirst()) {
- do {
- result.add(feeds.getString(1));
- } while (feeds.moveToNext());
+ Cursor cursor = null;
+ try {
+ cursor = adapter.getFeedCursorDownloadUrls();
+ List<String> result = new ArrayList<>(cursor.getCount());
+ while (cursor.moveToNext()) {
+ result.add(cursor.getString(1));
+ }
+ return result;
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ adapter.close();
}
- feeds.close();
- adapter.close();
-
- return result;
}
-
/**
* Loads additional data in to the feed items from other database queries
+ *
* @param items the FeedItems who should have other data loaded
*/
public static void loadAdditionalFeedItemListData(List<FeedItem> items) {
@@ -135,20 +142,21 @@ public final class DBReader {
* The feedID-attribute of a FeedItem must be set to the ID of its feed or the method will
* not find the correct feed of an item.
*
- * @param items The FeedItems whose Feed-objects should be loaded.
+ * @param items The FeedItems whose Feed-objects should be loaded.
*/
public static void loadFeedDataOfFeedItemList(List<FeedItem> items) {
List<Feed> feeds = getFeedList();
+
+ Map<Long, Feed> feedIndex = new ArrayMap<>(feeds.size());
+ for (Feed feed : feeds) {
+ feedIndex.put(feed.getId(), feed);
+ }
for (FeedItem item : items) {
- for (Feed feed : feeds) {
- if (feed.getId() == item.getFeedId()) {
- item.setFeed(feed);
- break;
- }
- }
- if (item.getFeed() == null) {
+ Feed feed = feedIndex.get(item.getFeedId());
+ if (feed == null) {
Log.w(TAG, "No match found for item with ID " + item.getId() + ". Feed ID was " + item.getFeedId());
}
+ item.setFeed(feed);
}
}
@@ -156,7 +164,7 @@ public final class DBReader {
* Loads the list of FeedItems for a certain Feed-object. This method should NOT be used if the FeedItems are not
* used. In order to get information ABOUT the list of FeedItems, consider using {@link #getFeedStatisticsList()} instead.
*
- * @param feed The Feed whose items should be loaded
+ * @param feed The Feed whose items should be loaded
* @return A list with the FeedItems of the Feed. The Feed-attribute of the FeedItems will already be set correctly.
* The method does NOT change the items-attribute of the feed.
*/
@@ -165,33 +173,35 @@ public final class DBReader {
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
-
- Cursor itemlistCursor = adapter.getAllItemsOfFeedCursor(feed);
- List<FeedItem> items = extractItemlistFromCursor(adapter,
- itemlistCursor);
- itemlistCursor.close();
- adapter.close();
-
- Collections.sort(items, new FeedItemPubdateComparator());
-
- for (FeedItem item : items) {
- item.setFeed(feed);
+ Cursor cursor = null;
+ try {
+ cursor = adapter.getAllItemsOfFeedCursor(feed);
+ List<FeedItem> items = extractItemlistFromCursor(adapter, cursor);
+ Collections.sort(items, new FeedItemPubdateComparator());
+ for (FeedItem item : items) {
+ item.setFeed(feed);
+ }
+ return items;
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ adapter.close();
}
-
- return items;
}
public static List<FeedItem> extractItemlistFromCursor(Cursor itemlistCursor) {
Log.d(TAG, "extractItemlistFromCursor() called with: " + "itemlistCursor = [" + itemlistCursor + "]");
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
- List<FeedItem> result = extractItemlistFromCursor(adapter, itemlistCursor);
- adapter.close();
- return result;
+ try {
+ return extractItemlistFromCursor(adapter, itemlistCursor);
+ } finally {
+ adapter.close();
+ }
}
- private static List<FeedItem> extractItemlistFromCursor(PodDBAdapter adapter,
- Cursor cursor) {
+ private static List<FeedItem> extractItemlistFromCursor(PodDBAdapter adapter, Cursor cursor) {
List<FeedItem> result = new ArrayList<>(cursor.getCount());
LongList imageIds = new LongList(cursor.getCount());
@@ -206,16 +216,16 @@ public final class DBReader {
result.add(item);
itemIds.add(item.getId());
} while (cursor.moveToNext());
- Map<Long,FeedImage> images = getFeedImages(adapter, imageIds.toArray());
- Map<Long,FeedMedia> medias = getFeedMedia(adapter, itemIds.toArray());
- for(int i=0; i < result.size(); i++) {
+ Map<Long, FeedImage> images = getFeedImages(adapter, imageIds.toArray());
+ Map<Long, FeedMedia> medias = getFeedMedia(adapter, itemIds);
+ for (int i = 0; i < result.size(); i++) {
FeedItem item = result.get(i);
long imageId = imageIds.get(i);
FeedImage image = images.get(imageId);
item.setImage(image);
FeedMedia media = medias.get(item.getId());
item.setMedia(media);
- if(media != null) {
+ if (media != null) {
media.setItem(item);
}
}
@@ -223,15 +233,14 @@ public final class DBReader {
return result;
}
- private static Map<Long,FeedMedia> getFeedMedia(PodDBAdapter adapter,
- long... itemIds) {
-
- String[] ids = new String[itemIds.length];
- for(int i=0, len=itemIds.length; i < len; i++) {
- ids[i] = String.valueOf(itemIds[i]);
+ private static Map<Long, FeedMedia> getFeedMedia(PodDBAdapter adapter, LongList itemIds) {
+ List<String> ids = new ArrayList<>(itemIds.size());
+ for (long item : itemIds.toArray()) {
+ ids.add(String.valueOf(item));
}
- Map<Long,FeedMedia> result = new ArrayMap<>(itemIds.length);
- Cursor cursor = adapter.getFeedMediaCursor(ids);
+
+ Map<Long, FeedMedia> result = new ArrayMap<>(itemIds.size());
+ Cursor cursor = adapter.getFeedMediaCursor(ids.toArray(new String[0]));
try {
if (cursor.moveToFirst()) {
do {
@@ -247,8 +256,7 @@ public final class DBReader {
return result;
}
- private static Feed extractFeedFromCursorRow(PodDBAdapter adapter,
- Cursor cursor) {
+ private static Feed extractFeedFromCursorRow(PodDBAdapter adapter, Cursor cursor) {
final FeedImage image;
int indexImage = cursor.getColumnIndex(PodDBAdapter.KEY_IMAGE);
long imageId = cursor.getLong(indexImage);
@@ -272,11 +280,17 @@ public final class DBReader {
static List<FeedItem> getQueue(PodDBAdapter adapter) {
Log.d(TAG, "getQueue()");
- Cursor itemlistCursor = adapter.getQueueCursor();
- List<FeedItem> items = extractItemlistFromCursor(adapter, itemlistCursor);
- itemlistCursor.close();
- loadAdditionalFeedItemListData(items);
- return items;
+ Cursor cursor = null;
+ try {
+ cursor = adapter.getQueueCursor();
+ List<FeedItem> items = extractItemlistFromCursor(adapter, cursor);
+ loadAdditionalFeedItemListData(items);
+ return items;
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
}
/**
@@ -290,22 +304,27 @@ public final class DBReader {
Log.d(TAG, "getQueueIDList() called");
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
- LongList result = getQueueIDList(adapter);
- adapter.close();
- return result;
+ try {
+ return getQueueIDList(adapter);
+ } finally {
+ adapter.close();
+ }
}
- static LongList getQueueIDList(PodDBAdapter adapter) {
- Cursor queueCursor = adapter.getQueueIDCursor();
-
- LongList queueIds = new LongList(queueCursor.getCount());
- if (queueCursor.moveToFirst()) {
- do {
- queueIds.add(queueCursor.getLong(0));
- } while (queueCursor.moveToNext());
+ private static LongList getQueueIDList(PodDBAdapter adapter) {
+ Cursor cursor = null;
+ try {
+ cursor = adapter.getQueueIDCursor();
+ LongList queueIds = new LongList(cursor.getCount());
+ while (cursor.moveToNext()) {
+ queueIds.add(cursor.getLong(0));
+ }
+ return queueIds;
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
}
- queueCursor.close();
- return queueIds;
}
/**
@@ -316,13 +335,15 @@ public final class DBReader {
* list in a {@link de.danoeh.antennapod.core.util.QueueAccess} object for easier access to the queue's properties.
*/
public static List<FeedItem> getQueue() {
- Log.d(TAG, "getQueue() called with: " + "");
+ Log.d(TAG, "getQueue() called");
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
- List<FeedItem> items = getQueue(adapter);
- adapter.close();
- return items;
+ try {
+ return getQueue(adapter);
+ } finally {
+ adapter.close();
+ }
}
/**
@@ -331,48 +352,29 @@ public final class DBReader {
* @return A list of FeedItems whose episdoe has been downloaded.
*/
public static List<FeedItem> getDownloadedItems() {
- Log.d(TAG, "getDownloadedItems() called with: " + "");
-
- PodDBAdapter adapter = PodDBAdapter.getInstance();
- adapter.open();
-
- Cursor itemlistCursor = adapter.getDownloadedItemsCursor();
- List<FeedItem> items = extractItemlistFromCursor(adapter,
- itemlistCursor);
- itemlistCursor.close();
- loadAdditionalFeedItemListData(items);
- adapter.close();
-
- Collections.sort(items, new FeedItemPubdateComparator());
-
- return items;
-
- }
-
- /**
- * Loads a list of FeedItems whose 'read'-attribute is set to false.
- *
- * @return A list of FeedItems whose 'read'-attribute it set to false.
- */
- public static List<FeedItem> getUnreadItemsList() {
- Log.d(TAG, "getUnreadItemsList() called");
+ Log.d(TAG, "getDownloadedItems() called");
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
- Cursor itemlistCursor = adapter.getUnreadItemsCursor();
- List<FeedItem> items = extractItemlistFromCursor(adapter, itemlistCursor);
- itemlistCursor.close();
-
- loadAdditionalFeedItemListData(items);
-
- adapter.close();
-
- return items;
+ Cursor cursor = null;
+ try {
+ cursor = adapter.getDownloadedItemsCursor();
+ List<FeedItem> items = extractItemlistFromCursor(adapter, cursor);
+ loadAdditionalFeedItemListData(items);
+ Collections.sort(items, new FeedItemPubdateComparator());
+ return items;
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ adapter.close();
+ }
}
/**
* Loads a list of FeedItems that are considered new.
* Excludes items from feeds that do not have keep updated enabled.
+ *
* @return A list of FeedItems that are considered new.
*/
public static List<FeedItem> getNewItemsList() {
@@ -380,16 +382,18 @@ public final class DBReader {
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
-
- Cursor itemlistCursor = adapter.getNewItemsCursor();
- List<FeedItem> items = extractItemlistFromCursor(adapter, itemlistCursor);
- itemlistCursor.close();
-
- loadAdditionalFeedItemListData(items);
-
- adapter.close();
-
- return items;
+ Cursor cursor = null;
+ try {
+ cursor = adapter.getNewItemsCursor();
+ List<FeedItem> items = extractItemlistFromCursor(adapter, cursor);
+ loadAdditionalFeedItemListData(items);
+ return items;
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ adapter.close();
+ }
}
public static List<FeedItem> getFavoriteItemsList() {
@@ -397,55 +401,63 @@ public final class DBReader {
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
-
- Cursor itemlistCursor = adapter.getFavoritesCursor();
- List<FeedItem> items = extractItemlistFromCursor(adapter, itemlistCursor);
- itemlistCursor.close();
-
- loadAdditionalFeedItemListData(items);
-
- adapter.close();
-
- return items;
+ Cursor cursor = null;
+ try {
+ cursor = adapter.getFavoritesCursor();
+ List<FeedItem> items = extractItemlistFromCursor(adapter, cursor);
+ loadAdditionalFeedItemListData(items);
+ return items;
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ adapter.close();
+ }
}
public static LongList getFavoriteIDList() {
Log.d(TAG, "getFavoriteIDList() called");
+
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
- Cursor favoritesCursor = adapter.getFavoritesCursor();
-
- LongList favoriteIDs = new LongList(favoritesCursor.getCount());
- if (favoritesCursor.moveToFirst()) {
- do {
- favoriteIDs.add(favoritesCursor.getLong(0));
- } while (favoritesCursor.moveToNext());
+ Cursor cursor = null;
+ try {
+ cursor = adapter.getFavoritesCursor();
+ LongList favoriteIDs = new LongList(cursor.getCount());
+ while (cursor.moveToNext()) {
+ favoriteIDs.add(cursor.getLong(0));
+ }
+ return favoriteIDs;
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ adapter.close();
}
- favoritesCursor.close();
- adapter.close();
- return favoriteIDs;
}
/**
* Loads a list of FeedItems sorted by pubDate in descending order.
*
- * @param limit The maximum number of episodes that should be loaded.
+ * @param limit The maximum number of episodes that should be loaded.
*/
public static List<FeedItem> getRecentlyPublishedEpisodes(int limit) {
Log.d(TAG, "getRecentlyPublishedEpisodes() called with: " + "limit = [" + limit + "]");
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
-
- Cursor itemlistCursor = adapter.getRecentlyPublishedItemsCursor(limit);
- List<FeedItem> items = extractItemlistFromCursor(adapter, itemlistCursor);
- itemlistCursor.close();
-
- loadAdditionalFeedItemListData(items);
-
- adapter.close();
-
- return items;
+ Cursor cursor = null;
+ try {
+ cursor = adapter.getRecentlyPublishedItemsCursor(limit);
+ List<FeedItem> items = extractItemlistFromCursor(adapter, cursor);
+ loadAdditionalFeedItemListData(items);
+ return items;
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ adapter.close();
+ }
}
/**
@@ -461,21 +473,29 @@ public final class DBReader {
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
- Cursor mediaCursor = adapter.getCompletedMediaCursor(PLAYBACK_HISTORY_SIZE);
- String[] itemIds = new String[mediaCursor.getCount()];
- for (int i = 0; i < itemIds.length && mediaCursor.moveToPosition(i); i++) {
- int index = mediaCursor.getColumnIndex(PodDBAdapter.KEY_FEEDITEM);
- itemIds[i] = Long.toString(mediaCursor.getLong(index));
+ Cursor mediaCursor = null;
+ Cursor itemCursor = null;
+ try {
+ mediaCursor = adapter.getCompletedMediaCursor(PLAYBACK_HISTORY_SIZE);
+ String[] itemIds = new String[mediaCursor.getCount()];
+ for (int i = 0; i < itemIds.length && mediaCursor.moveToPosition(i); i++) {
+ int index = mediaCursor.getColumnIndex(PodDBAdapter.KEY_FEEDITEM);
+ itemIds[i] = Long.toString(mediaCursor.getLong(index));
+ }
+ itemCursor = adapter.getFeedItemCursor(itemIds);
+ List<FeedItem> items = extractItemlistFromCursor(adapter, itemCursor);
+ loadAdditionalFeedItemListData(items);
+ Collections.sort(items, new PlaybackCompletionDateComparator());
+ return items;
+ } finally {
+ if (mediaCursor != null) {
+ mediaCursor.close();
+ }
+ if (itemCursor != null) {
+ itemCursor.close();
+ }
+ adapter.close();
}
- mediaCursor.close();
- Cursor itemCursor = adapter.getFeedItemCursor(itemIds);
- List<FeedItem> items = extractItemlistFromCursor(adapter, itemCursor);
- loadAdditionalFeedItemListData(items);
- itemCursor.close();
- adapter.close();
-
- Collections.sort(items, new PlaybackCompletionDateComparator());
- return items;
}
/**
@@ -489,19 +509,21 @@ public final class DBReader {
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
- Cursor logCursor = adapter.getDownloadLogCursor(DOWNLOAD_LOG_SIZE);
- List<DownloadStatus> downloadLog = new ArrayList<>(logCursor.getCount());
-
- if (logCursor.moveToFirst()) {
- do {
- DownloadStatus status = DownloadStatus.fromCursor(logCursor);
- downloadLog.add(status);
- } while (logCursor.moveToNext());
+ Cursor cursor = null;
+ try {
+ cursor = adapter.getDownloadLogCursor(DOWNLOAD_LOG_SIZE);
+ List<DownloadStatus> downloadLog = new ArrayList<>(cursor.getCount());
+ while (cursor.moveToNext()) {
+ downloadLog.add(DownloadStatus.fromCursor(cursor));
+ }
+ Collections.sort(downloadLog, new DownloadStatusComparator());
+ return downloadLog;
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ adapter.close();
}
- logCursor.close();
- adapter.close();
- Collections.sort(downloadLog, new DownloadStatusComparator());
- return downloadLog;
}
/**
@@ -509,26 +531,28 @@ public final class DBReader {
*
* @param feed Feed for which the download log is loaded
* @return A list with DownloadStatus objects that represent the feed's download log,
- * newest events first.
+ * newest events first.
*/
public static List<DownloadStatus> getFeedDownloadLog(Feed feed) {
Log.d(TAG, "getFeedDownloadLog() called with: " + "feed = [" + feed + "]");
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
- Cursor cursor = adapter.getDownloadLog(Feed.FEEDFILETYPE_FEED, feed.getId());
- List<DownloadStatus> downloadLog = new ArrayList<>(cursor.getCount());
-
- if (cursor.moveToFirst()) {
- do {
- DownloadStatus status = DownloadStatus.fromCursor(cursor);
- downloadLog.add(status);
- } while (cursor.moveToNext());
+ Cursor cursor = null;
+ try {
+ cursor = adapter.getDownloadLog(Feed.FEEDFILETYPE_FEED, feed.getId());
+ List<DownloadStatus> downloadLog = new ArrayList<>(cursor.getCount());
+ while (cursor.moveToNext()) {
+ downloadLog.add(DownloadStatus.fromCursor(cursor));
+ }
+ Collections.sort(downloadLog, new DownloadStatusComparator());
+ return downloadLog;
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ adapter.close();
}
- cursor.close();
- adapter.close();
- Collections.sort(downloadLog, new DownloadStatusComparator());
- return downloadLog;
}
/**
@@ -542,103 +566,91 @@ public final class DBReader {
Log.d(TAG, "getFeedStatisticsList() called");
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
- List<FeedItemStatistics> result = new ArrayList<>();
- Cursor cursor = adapter.getFeedStatisticsCursor();
- if (cursor.moveToFirst()) {
- do {
+ Cursor cursor = null;
+ try {
+ cursor = adapter.getFeedStatisticsCursor();
+ List<FeedItemStatistics> result = new ArrayList<>(cursor.getCount());
+ while (cursor.moveToNext()) {
FeedItemStatistics fis = FeedItemStatistics.fromCursor(cursor);
result.add(fis);
- } while (cursor.moveToNext());
+ }
+ return result;
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ adapter.close();
}
-
- cursor.close();
- adapter.close();
- return result;
}
/**
* Loads a specific Feed from the database.
*
- * @param feedId The ID of the Feed
+ * @param feedId The ID of the Feed
* @return The Feed or null if the Feed could not be found. The Feeds FeedItems will also be loaded from the
* database and the items-attribute will be set correctly.
*/
public static Feed getFeed(final long feedId) {
Log.d(TAG, "getFeed() called with: " + "feedId = [" + feedId + "]");
+
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
- Feed result = getFeed(feedId, adapter);
- adapter.close();
- return result;
+ try {
+ return getFeed(feedId, adapter);
+ } finally {
+ adapter.close();
+ }
}
static Feed getFeed(final long feedId, PodDBAdapter adapter) {
Feed feed = null;
-
- Cursor feedCursor = adapter.getFeedCursor(feedId);
- if (feedCursor.moveToFirst()) {
- feed = extractFeedFromCursorRow(adapter, feedCursor);
- feed.setItems(getFeedItemList(feed));
- } else {
- Log.e(TAG, "getFeed could not find feed with id " + feedId);
- }
- feedCursor.close();
- return feed;
- }
-
- static FeedItem getFeedItem(final long itemId, PodDBAdapter adapter) {
- Log.d(TAG, "Loading feeditem with id " + itemId);
- FeedItem item = null;
-
- Cursor itemCursor = adapter.getFeedItemCursor(Long.toString(itemId));
- if (!itemCursor.moveToFirst()) {
- itemCursor.close();
- return null;
- }
- List<FeedItem> list = extractItemlistFromCursor(adapter, itemCursor);
- itemCursor.close();
- if (list.size() > 0) {
- item = list.get(0);
- loadAdditionalFeedItemListData(list);
- if (item.hasChapters()) {
- loadChaptersOfFeedItem(adapter, item);
+ Cursor cursor = null;
+ try {
+ cursor = adapter.getFeedCursor(feedId);
+ if (cursor.moveToNext()) {
+ feed = extractFeedFromCursorRow(adapter, cursor);
+ feed.setItems(getFeedItemList(feed));
+ } else {
+ Log.e(TAG, "getFeed could not find feed with id " + feedId);
+ }
+ return feed;
+ } finally {
+ if (cursor != null) {
+ cursor.close();
}
}
- return item;
}
- static List<FeedItem> getFeedItems(PodDBAdapter adapter, final long... itemIds) {
-
- String[] ids = new String[itemIds.length];
- for(int i = 0; i < itemIds.length; i++) {
- long itemId = itemIds[i];
- ids[i] = Long.toString(itemId);
- }
-
- List<FeedItem> result;
+ private static FeedItem getFeedItem(final long itemId, PodDBAdapter adapter) {
+ Log.d(TAG, "Loading feeditem with id " + itemId);
- Cursor itemCursor = adapter.getFeedItemCursor(ids);
- if (itemCursor.moveToFirst()) {
- result = extractItemlistFromCursor(adapter, itemCursor);
- loadAdditionalFeedItemListData(result);
- for(FeedItem item : result) {
- if (item.hasChapters()) {
- loadChaptersOfFeedItem(adapter, item);
+ FeedItem item = null;
+ Cursor cursor = null;
+ try {
+ cursor = adapter.getFeedItemCursor(Long.toString(itemId));
+ if (cursor.moveToNext()) {
+ List<FeedItem> list = extractItemlistFromCursor(adapter, cursor);
+ if (!list.isEmpty()) {
+ item = list.get(0);
+ loadAdditionalFeedItemListData(list);
+ if (item.hasChapters()) {
+ loadChaptersOfFeedItem(adapter, item);
+ }
}
}
- } else {
- result = Collections.emptyList();
+ return item;
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
}
- itemCursor.close();
- return result;
-
}
/**
* Loads a specific FeedItem from the database. This method should not be used for loading more
* than one FeedItem because this method might query the database several times for each item.
*
- * @param itemId The ID of the FeedItem
+ * @param itemId The ID of the FeedItem
* @return The FeedItem or null if the FeedItem could not be found. All FeedComponent-attributes
* as well as chapter marks of the FeedItem will also be loaded from the database.
*/
@@ -647,51 +659,42 @@ public final class DBReader {
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
- FeedItem item = getFeedItem(itemId, adapter);
- adapter.close();
- return item;
+ try {
+ return getFeedItem(itemId, adapter);
+ } finally {
+ adapter.close();
+ }
}
static FeedItem getFeedItem(final String podcastUrl, final String episodeUrl, PodDBAdapter adapter) {
Log.d(TAG, "Loading feeditem with podcast url " + podcastUrl + " and episode url " + episodeUrl);
- FeedItem item = null;
- Cursor itemCursor = adapter.getFeedItemCursor(podcastUrl, episodeUrl);
- if (itemCursor.moveToFirst()) {
- List<FeedItem> list = extractItemlistFromCursor(adapter, itemCursor);
- if (list.size() > 0) {
+ Cursor cursor = null;
+ try {
+ cursor = adapter.getFeedItemCursor(podcastUrl, episodeUrl);
+ if (!cursor.moveToNext()) {
+ return null;
+ }
+ List<FeedItem> list = extractItemlistFromCursor(adapter, cursor);
+ FeedItem item = null;
+ if (!list.isEmpty()) {
item = list.get(0);
loadAdditionalFeedItemListData(list);
if (item.hasChapters()) {
loadChaptersOfFeedItem(adapter, item);
}
}
+ return item;
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
}
- itemCursor.close();
- return item;
}
/**
- * Loads specific FeedItems from the database. This method canbe used for loading more
- * than one FeedItem
- *
- * @param itemIds The IDs of the FeedItems
- * @return The FeedItems or an empty list if none of the FeedItems could be found. All FeedComponent-attributes
- * as well as chapter marks of the FeedItems will also be loaded from the database.
- */
- public static List<FeedItem> getFeedItems(final long... itemIds) {
- Log.d(TAG, "getFeedItems() called with: " + "itemIds = [" + Arrays.toString(itemIds) + "]");
- PodDBAdapter adapter = PodDBAdapter.getInstance();
- adapter.open();
- List<FeedItem> items = getFeedItems(adapter, itemIds);
- adapter.close();
- return items;
- }
-
-
- /**
* Returns credentials based on image URL
*
- * @param imageUrl The URL of the image
+ * @param imageUrl The URL of the image
* @return Credentials in format "<Username>:<Password>", empty String if no authorization given
*/
public static String getImageAuthentication(final String imageUrl) {
@@ -699,20 +702,22 @@ public final class DBReader {
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
- String credentials = getImageAuthentication(imageUrl, adapter);
- adapter.close();
- return credentials;
-
+ try {
+ return getImageAuthentication(imageUrl, adapter);
+ } finally {
+ adapter.close();
+ }
}
- static String getImageAuthentication(final String imageUrl, PodDBAdapter adapter) {
+ private static String getImageAuthentication(final String imageUrl, PodDBAdapter adapter) {
String credentials = null;
- Cursor cursor = adapter.getImageAuthenticationCursor(imageUrl);
+ Cursor cursor = null;
try {
+ cursor = adapter.getImageAuthenticationCursor(imageUrl);
if (cursor.moveToFirst()) {
String username = cursor.getString(0);
String password = cursor.getString(1);
- if(username != null && password != null) {
+ if (username != null && password != null) {
credentials = username + ":" + password;
} else {
credentials = "";
@@ -721,7 +726,9 @@ public final class DBReader {
credentials = "";
}
} finally {
- cursor.close();
+ if (cursor != null) {
+ cursor.close();
+ }
}
return credentials;
}
@@ -739,31 +746,39 @@ public final class DBReader {
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
- FeedItem item = getFeedItem(podcastUrl, episodeUrl, adapter);
- adapter.close();
- return item;
+ try {
+ return getFeedItem(podcastUrl, episodeUrl, adapter);
+ } finally {
+ adapter.close();
+ }
}
/**
* Loads additional information about a FeedItem, e.g. shownotes
*
- * @param item The FeedItem
+ * @param item The FeedItem
*/
public static void loadExtraInformationOfFeedItem(final FeedItem item) {
Log.d(TAG, "loadExtraInformationOfFeedItem() called with: " + "item = [" + item + "]");
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
- Cursor extraCursor = adapter.getExtraInformationOfItem(item);
- if (extraCursor.moveToFirst()) {
- int indexDescription = extraCursor.getColumnIndex(PodDBAdapter.KEY_DESCRIPTION);
- String description = extraCursor.getString(indexDescription);
- int indexContentEncoded = extraCursor.getColumnIndex(PodDBAdapter.KEY_CONTENT_ENCODED);
- String contentEncoded = extraCursor.getString(indexContentEncoded);
- item.setDescription(description);
- item.setContentEncoded(contentEncoded);
+ Cursor cursor = null;
+ try {
+ cursor = adapter.getExtraInformationOfItem(item);
+ if (cursor.moveToFirst()) {
+ int indexDescription = cursor.getColumnIndex(PodDBAdapter.KEY_DESCRIPTION);
+ String description = cursor.getString(indexDescription);
+ int indexContentEncoded = cursor.getColumnIndex(PodDBAdapter.KEY_CONTENT_ENCODED);
+ String contentEncoded = cursor.getString(indexContentEncoded);
+ item.setDescription(description);
+ item.setContentEncoded(contentEncoded);
+ }
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ adapter.close();
}
- extraCursor.close();
- adapter.close();
}
/**
@@ -771,56 +786,64 @@ public final class DBReader {
* any chapters that this FeedItem has. If no chapters were found in the database, the chapters
* reference of the FeedItem will be set to null.
*
- * @param item The FeedItem
+ * @param item The FeedItem
*/
public static void loadChaptersOfFeedItem(final FeedItem item) {
Log.d(TAG, "loadChaptersOfFeedItem() called with: " + "item = [" + item + "]");
+
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
- loadChaptersOfFeedItem(adapter, item);
- adapter.close();
+ try {
+ loadChaptersOfFeedItem(adapter, item);
+ } finally {
+ adapter.close();
+ }
}
static void loadChaptersOfFeedItem(PodDBAdapter adapter, FeedItem item) {
- Cursor chapterCursor = adapter.getSimpleChaptersOfFeedItemCursor(item);
- if (chapterCursor.moveToFirst()) {
- item.setChapters(new ArrayList<>());
- do {
- int indexType = chapterCursor.getColumnIndex(PodDBAdapter.KEY_CHAPTER_TYPE);
- int indexStart = chapterCursor.getColumnIndex(PodDBAdapter.KEY_START);
- int indexTitle = chapterCursor.getColumnIndex(PodDBAdapter.KEY_TITLE);
- int indexLink = chapterCursor.getColumnIndex(PodDBAdapter.KEY_LINK);
-
- int chapterType = chapterCursor.getInt(indexType);
+ Cursor cursor = null;
+ try {
+ cursor = adapter.getSimpleChaptersOfFeedItemCursor(item);
+ int chaptersCount = cursor.getCount();
+ if (chaptersCount == 0) {
+ item.setChapters(null);
+ return;
+ }
+ item.setChapters(new ArrayList<>(chaptersCount));
+ while (cursor.moveToNext()) {
+ int indexType = cursor.getColumnIndex(PodDBAdapter.KEY_CHAPTER_TYPE);
+ int indexStart = cursor.getColumnIndex(PodDBAdapter.KEY_START);
+ int indexTitle = cursor.getColumnIndex(PodDBAdapter.KEY_TITLE);
+ int indexLink = cursor.getColumnIndex(PodDBAdapter.KEY_LINK);
+
+ int chapterType = cursor.getInt(indexType);
Chapter chapter = null;
- long start = chapterCursor.getLong(indexStart);
- String title = chapterCursor.getString(indexTitle);
- String link = chapterCursor.getString(indexLink);
+ long start = cursor.getLong(indexStart);
+ String title = cursor.getString(indexTitle);
+ String link = cursor.getString(indexLink);
switch (chapterType) {
case SimpleChapter.CHAPTERTYPE_SIMPLECHAPTER:
- chapter = new SimpleChapter(start, title, item,
- link);
+ chapter = new SimpleChapter(start, title, item, link);
break;
case ID3Chapter.CHAPTERTYPE_ID3CHAPTER:
- chapter = new ID3Chapter(start, title, item,
- link);
+ chapter = new ID3Chapter(start, title, item, link);
break;
case VorbisCommentChapter.CHAPTERTYPE_VORBISCOMMENT_CHAPTER:
- chapter = new VorbisCommentChapter(start,
- title, item, link);
+ chapter = new VorbisCommentChapter(start, title, item, link);
break;
}
if (chapter != null) {
- int indexId = chapterCursor.getColumnIndex(PodDBAdapter.KEY_ID);
- chapter.setId(chapterCursor.getLong(indexId));
+ int indexId = cursor.getColumnIndex(PodDBAdapter.KEY_ID);
+ chapter.setId(cursor.getLong(indexId));
item.getChapters().add(chapter);
}
- } while (chapterCursor.moveToNext());
- } else {
- item.setChapters(null);
+ }
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
}
- chapterCursor.close();
}
/**
@@ -828,13 +851,17 @@ public final class DBReader {
*
* @return The number of downloaded episodes.
*/
+
public static int getNumberOfDownloadedEpisodes() {
Log.d(TAG, "getNumberOfDownloadedEpisodes() called with: " + "");
+
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
- final int result = adapter.getNumberOfDownloadedEpisodes();
- adapter.close();
- return result;
+ try {
+ return adapter.getNumberOfDownloadedEpisodes();
+ } finally {
+ adapter.close();
+ }
}
/**
@@ -847,9 +874,11 @@ public final class DBReader {
Log.d(TAG, "getFeedImage() called with: " + "imageId = [" + imageId + "]");
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
- FeedImage result = getFeedImage(adapter, imageId);
- adapter.close();
- return result;
+ try {
+ return getFeedImage(adapter, imageId);
+ } finally {
+ adapter.close();
+ }
}
/**
@@ -868,21 +897,23 @@ public final class DBReader {
* @param imageIds The ids of the images
* @return Map that associates the id of an image with the image itself
*/
- private static Map<Long,FeedImage> getFeedImages(PodDBAdapter adapter, final long... imageIds) {
+ private static Map<Long, FeedImage> getFeedImages(PodDBAdapter adapter, final long... imageIds) {
String[] ids = new String[imageIds.length];
- for(int i=0, len=imageIds.length; i < len; i++) {
+ for (int i = 0, len = imageIds.length; i < len; i++) {
ids[i] = String.valueOf(imageIds[i]);
}
Cursor cursor = adapter.getImageCursor(ids);
- Map<Long, FeedImage> result = new ArrayMap<>(cursor.getCount());
+ int imageCount = cursor.getCount();
+ if (imageCount == 0) {
+ cursor.close();
+ return Collections.emptyMap();
+ }
+ Map<Long, FeedImage> result = new ArrayMap<>(imageCount);
try {
- if ((cursor.getCount() == 0) || !cursor.moveToFirst()) {
- return Collections.emptyMap();
- }
- do {
+ while (cursor.moveToNext()) {
FeedImage image = FeedImage.fromCursor(cursor);
result.put(image.getId(), image);
- } while(cursor.moveToNext());
+ }
} finally {
cursor.close();
}
@@ -899,92 +930,137 @@ public final class DBReader {
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
- Cursor mediaCursor = adapter.getSingleFeedMediaCursor(mediaId);
-
- if (!mediaCursor.moveToFirst()) {
- mediaCursor.close();
- return null;
- }
+ Cursor mediaCursor = null;
+ try {
+ mediaCursor = adapter.getSingleFeedMediaCursor(mediaId);
+ if (!mediaCursor.moveToFirst()) {
+ return null;
+ }
- int indexFeedItem = mediaCursor.getColumnIndex(PodDBAdapter.KEY_FEEDITEM);
- long itemId = mediaCursor.getLong(indexFeedItem);
- FeedMedia media = FeedMedia.fromCursor(mediaCursor);
- mediaCursor.close();
+ int indexFeedItem = mediaCursor.getColumnIndex(PodDBAdapter.KEY_FEEDITEM);
+ long itemId = mediaCursor.getLong(indexFeedItem);
+ FeedMedia media = FeedMedia.fromCursor(mediaCursor);
+ if (media != null) {
+ FeedItem item = getFeedItem(itemId);
+ if (item != null) {
+ media.setItem(item);
+ item.setMedia(media);
+ }
+ }
+ return media;
- if(media != null) {
- FeedItem item = getFeedItem(itemId);
- if (item != null) {
- media.setItem(item);
- item.setMedia(media);
+ } finally {
+ if (mediaCursor != null) {
+ mediaCursor.close();
}
+ adapter.close();
}
-
- adapter.close();
-
- return media;
}
/**
* Searches the DB for statistics
*
+ * @param sortByCountAll If true, the statistic items will be sorted according to the
+ * countAll calculation time
* @return The StatisticsInfo object
*/
- public static StatisticsData getStatistics() {
+ public static StatisticsData getStatistics(boolean sortByCountAll) {
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
+ long totalTimeCountAll = 0;
long totalTime = 0;
List<StatisticsItem> feedTime = new ArrayList<>();
List<Feed> feeds = getFeedList();
for (Feed feed : feeds) {
+ long feedPlayedTimeCountAll = 0;
long feedPlayedTime = 0;
long feedTotalTime = 0;
long episodes = 0;
long episodesStarted = 0;
+ long episodesStartedIncludingMarked = 0;
List<FeedItem> items = getFeed(feed.getId()).getItems();
- for(FeedItem item : items) {
+ for (FeedItem item : items) {
FeedMedia media = item.getMedia();
- if(media == null) {
+ if (media == null) {
continue;
}
// played duration used to be reset when the item is added to the playback history
- if(media.getPlaybackCompletionDate() != null) {
+ if (media.getPlaybackCompletionDate() != null) {
feedPlayedTime += media.getDuration() / 1000;
}
feedPlayedTime += media.getPlayedDuration() / 1000;
+
+ if (item.isPlayed()) {
+ feedPlayedTimeCountAll += media.getDuration() / 1000;
+ } else {
+ feedPlayedTimeCountAll += media.getPosition() / 1000;
+ }
+
if (media.getPlaybackCompletionDate() != null || media.getPlayedDuration() > 0) {
episodesStarted++;
}
+
+ if (item.isPlayed() || media.getPosition() != 0) {
+ episodesStartedIncludingMarked++;
+ }
+
feedTotalTime += media.getDuration() / 1000;
episodes++;
}
feedTime.add(new StatisticsItem(
- feed, feedTotalTime, feedPlayedTime, episodes, episodesStarted));
+ feed, feedTotalTime, feedPlayedTime, feedPlayedTimeCountAll, episodes,
+ episodesStarted, episodesStartedIncludingMarked));
totalTime += feedPlayedTime;
+ totalTimeCountAll += feedPlayedTimeCountAll;
}
- Collections.sort(feedTime, (item1, item2) -> {
- if(item1.timePlayed > item2.timePlayed) {
- return -1;
- } else if(item1.timePlayed < item2.timePlayed) {
- return 1;
- } else {
- return 0;
- }
- });
+ if (sortByCountAll) {
+ Collections.sort(feedTime, (item1, item2) ->
+ compareLong(item1.timePlayedCountAll, item2.timePlayedCountAll));
+ } else {
+ Collections.sort(feedTime, (item1, item2) ->
+ compareLong(item1.timePlayed, item2.timePlayed));
+ }
adapter.close();
- return new StatisticsData(totalTime, feedTime);
+ return new StatisticsData(totalTime, totalTimeCountAll, feedTime);
+ }
+
+ /**
+ * Compares two {@code long} values. Long.compare() is not available before API 19
+ *
+ * @return 0 if long1 = long2, less than 0 if long1 &lt; long2,
+ * and greater than 0 if long1 &gt; long2.
+ */
+ private static int compareLong(long long1, long long2) {
+ if (long1 > long2) {
+ return -1;
+ } else if (long1 < long2) {
+ return 1;
+ } else {
+ return 0;
+ }
}
public static class StatisticsData {
+ /**
+ * Simply sums up time of podcasts that are marked as played
+ */
+ public long totalTimeCountAll;
+
+ /**
+ * Respects speed, listening twice, ...
+ */
public long totalTime;
+
public List<StatisticsItem> feedTime;
- public StatisticsData(long totalTime, List<StatisticsItem> feedTime) {
+ public StatisticsData(long totalTime, long totalTimeCountAll, List<StatisticsItem> feedTime) {
this.totalTime = totalTime;
+ this.totalTimeCountAll = totalTimeCountAll;
this.feedTime = feedTime;
}
}
@@ -992,17 +1068,34 @@ public final class DBReader {
public static class StatisticsItem {
public Feed feed;
public long time;
+
+ /**
+ * Respects speed, listening twice, ...
+ */
public long timePlayed;
+ /**
+ * Simply sums up time of podcasts that are marked as played
+ */
+ public long timePlayedCountAll;
public long episodes;
+ /**
+ * Episodes that are actually played
+ */
public long episodesStarted;
+ /**
+ * All episodes that are marked as played (or have position != 0)
+ */
+ public long episodesStartedIncludingMarked;
- public StatisticsItem(Feed feed, long time, long timePlayed,
- long episodes, long episodesStarted) {
+ public StatisticsItem(Feed feed, long time, long timePlayed, long timePlayedCountAll,
+ long episodes, long episodesStarted, long episodesStartedIncludingMarked) {
this.feed = feed;
this.time = time;
this.timePlayed = timePlayed;
+ this.timePlayedCountAll = timePlayedCountAll;
this.episodes = episodes;
this.episodesStarted = episodesStarted;
+ this.episodesStartedIncludingMarked = episodesStartedIncludingMarked;
}
}
@@ -1040,7 +1133,6 @@ public final class DBReader {
* Returns data necessary for displaying the navigation drawer. This includes
* the list of subscriptions, the number of items in the queue and the number of unread
* items.
- *
*/
public static NavDrawerData getNavDrawerData() {
Log.d(TAG, "getNavDrawerData() called with: " + "");
@@ -1048,51 +1140,66 @@ public final class DBReader {
adapter.open();
List<Feed> feeds = getFeedList(adapter);
long[] feedIds = new long[feeds.size()];
- for(int i=0; i < feeds.size(); i++) {
+ for (int i = 0; i < feeds.size(); i++) {
feedIds[i] = feeds.get(i).getId();
}
final LongIntMap feedCounters = adapter.getFeedCounters(feedIds);
Comparator<Feed> comparator;
int feedOrder = UserPreferences.getFeedOrder();
- if(feedOrder == UserPreferences.FEED_ORDER_COUNTER) {
+ if (feedOrder == UserPreferences.FEED_ORDER_COUNTER) {
comparator = (lhs, rhs) -> {
long counterLhs = feedCounters.get(lhs.getId());
long counterRhs = feedCounters.get(rhs.getId());
- if(counterLhs > counterRhs) {
+ if (counterLhs > counterRhs) {
// reverse natural order: podcast with most unplayed episodes first
return -1;
- } else if(counterLhs == counterRhs) {
+ } else if (counterLhs == counterRhs) {
return lhs.getTitle().compareToIgnoreCase(rhs.getTitle());
} else {
return 1;
}
};
- } else if(feedOrder == UserPreferences.FEED_ORDER_ALPHABETICAL) {
+ } else if (feedOrder == UserPreferences.FEED_ORDER_ALPHABETICAL) {
comparator = (lhs, rhs) -> {
String t1 = lhs.getTitle();
String t2 = rhs.getTitle();
- if(t1 == null) {
+ if (t1 == null) {
return 1;
- } else if(t2 == null) {
+ } else if (t2 == null) {
return -1;
} else {
return t1.compareToIgnoreCase(t2);
}
};
+ } else if (feedOrder == UserPreferences.FEED_ORDER_MOST_PLAYED) {
+ final LongIntMap playedCounters = adapter.getPlayedEpisodesCounters(feedIds);
+
+ comparator = (lhs, rhs) -> {
+ long counterLhs = playedCounters.get(lhs.getId());
+ long counterRhs = playedCounters.get(rhs.getId());
+ if (counterLhs > counterRhs) {
+ // podcast with most played episodes first
+ return -1;
+ } else if (counterLhs == counterRhs) {
+ return lhs.getTitle().compareToIgnoreCase(rhs.getTitle());
+ } else {
+ return 1;
+ }
+ };
} else {
comparator = (lhs, rhs) -> {
- if(lhs.getItems() == null || lhs.getItems().size() == 0) {
+ if (lhs.getItems() == null || lhs.getItems().size() == 0) {
List<FeedItem> items = DBReader.getFeedItemList(lhs);
lhs.setItems(items);
}
- if(rhs.getItems() == null || rhs.getItems().size() == 0) {
+ if (rhs.getItems() == null || rhs.getItems().size() == 0) {
List<FeedItem> items = DBReader.getFeedItemList(rhs);
rhs.setItems(items);
}
- if(lhs.getMostRecentItem() == null) {
+ if (lhs.getMostRecentItem() == null) {
return 1;
- } else if(rhs.getMostRecentItem() == null) {
+ } else if (rhs.getMostRecentItem() == null) {
return -1;
} else {
Date d1 = lhs.getMostRecentItem().getPubDate();
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 4d442aac2..148b530a7 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
@@ -678,6 +678,54 @@ public final class DBTasks {
}
/**
+ * Searches the authors of FeedItems of a specific Feed for a given
+ * string.
+ *
+ * @param context Used for accessing the DB.
+ * @param feedID The id of the feed whose items should be searched.
+ * @param query The search string.
+ * @return A FutureTask object that executes the search request and returns the search result as a List of FeedItems.
+ */
+ public static FutureTask<List<FeedItem>> searchFeedItemAuthor(final Context context,
+ final long feedID, final String query) {
+ return new FutureTask<>(new QueryTask<List<FeedItem>>(context) {
+ @Override
+ public void execute(PodDBAdapter adapter) {
+ Cursor searchResult = adapter.searchItemAuthors(feedID,
+ query);
+ List<FeedItem> items = DBReader.extractItemlistFromCursor(searchResult);
+ DBReader.loadAdditionalFeedItemListData(items);
+ setResult(items);
+ searchResult.close();
+ }
+ });
+ }
+
+ /**
+ * Searches the feed identifiers of FeedItems of a specific Feed for a given
+ * string.
+ *
+ * @param context Used for accessing the DB.
+ * @param feedID The id of the feed whose items should be searched.
+ * @param query The search string.
+ * @return A FutureTask object that executes the search request and returns the search result as a List of FeedItems.
+ */
+ public static FutureTask<List<FeedItem>> searchFeedItemFeedIdentifier(final Context context,
+ final long feedID, final String query) {
+ return new FutureTask<>(new QueryTask<List<FeedItem>>(context) {
+ @Override
+ public void execute(PodDBAdapter adapter) {
+ Cursor searchResult = adapter.searchItemFeedIdentifiers(feedID,
+ query);
+ List<FeedItem> items = DBReader.extractItemlistFromCursor(searchResult);
+ DBReader.loadAdditionalFeedItemListData(items);
+ setResult(items);
+ searchResult.close();
+ }
+ });
+ }
+
+ /**
* Searches the descriptions of FeedItems of a specific Feed for a given
* string.
*
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java
index 563d80da0..49ec07004 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java
@@ -7,6 +7,8 @@ import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;
+import de.danoeh.antennapod.core.R;
+import de.danoeh.antennapod.core.event.MessageEvent;
import org.shredzone.flattr4j.model.Flattr;
import java.io.File;
@@ -84,12 +86,13 @@ public class DBWriter {
if (media != null) {
Log.i(TAG, String.format("Requested to delete FeedMedia [id=%d, title=%s, downloaded=%s",
media.getId(), media.getEpisodeTitle(), String.valueOf(media.isDownloaded())));
- boolean result = false;
if (media.isDownloaded()) {
// delete downloaded media file
File mediaFile = new File(media.getFile_url());
- if (mediaFile.exists()) {
- result = mediaFile.delete();
+ if (mediaFile.exists() && !mediaFile.delete()) {
+ MessageEvent evt = new MessageEvent(context.getString(R.string.delete_failed));
+ EventBus.getDefault().post(evt);
+ return;
}
media.setDownloaded(false);
media.setFile_url(null);
@@ -129,7 +132,6 @@ public class DBWriter {
GpodnetPreferences.enqueueEpisodeAction(action);
}
}
- Log.d(TAG, "Deleting File. Result: " + result);
EventBus.getDefault().post(FeedItemEvent.deletedMedia(Collections.singletonList(media.getItem())));
EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast();
}
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 04afc504b..7051d7f4d 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
@@ -345,9 +345,7 @@ public class DownloadRequester {
// Try to generate the filename by the item title
if (media.getItem() != null && media.getItem().getTitle() != null) {
String title = media.getItem().getTitle();
- // Delete reserved characters
- titleBaseFilename = title.replaceAll("[^a-zA-Z0-9 ._()-]", "");
- titleBaseFilename = titleBaseFilename.trim();
+ titleBaseFilename = FileNameGenerator.generateFileName(title);
}
String URLBaseFilename = URLUtil.guessFileName(media.getDownload_url(),
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/FeedSearcher.java b/core/src/main/java/de/danoeh/antennapod/core/storage/FeedSearcher.java
index 9d136273c..aa5706ad0 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/FeedSearcher.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/FeedSearcher.java
@@ -4,7 +4,9 @@ import android.content.Context;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
@@ -33,11 +35,13 @@ public class FeedSearcher {
*/
public static List<SearchResult> performSearch(final Context context,
final String query, final long selectedFeed) {
- final int values[] = {2, 1, 0, 0};
+ final int values[] = {2, 1, 0, 0, 0, 0};
final String[] subtitles = {context.getString(R.string.found_in_title_label),
context.getString(R.string.found_in_chapters_label),
context.getString(R.string.found_in_shownotes_label),
- context.getString(R.string.found_in_shownotes_label)};
+ context.getString(R.string.found_in_shownotes_label),
+ context.getString(R.string.found_in_authors_label),
+ context.getString(R.string.found_in_feeds_label)};
List<SearchResult> result = new ArrayList<>();
@@ -46,20 +50,24 @@ public class FeedSearcher {
tasks.add(DBTasks.searchFeedItemChapters(context, selectedFeed, query));
tasks.add(DBTasks.searchFeedItemDescription(context, selectedFeed, query));
tasks.add(DBTasks.searchFeedItemContentEncoded(context, selectedFeed, query));
+ tasks.add(DBTasks.searchFeedItemAuthor(context, selectedFeed, query));
+ tasks.add(DBTasks.searchFeedItemFeedIdentifier(context, selectedFeed, query));
for (FutureTask<List<FeedItem>> task : tasks) {
task.run();
}
try {
+ Set<Long> set = new HashSet<>();
+
for (int i = 0; i < tasks.size(); i++) {
FutureTask<List<FeedItem>> task = tasks.get(i);
List<FeedItem> items = task.get();
for (FeedItem item : items) {
- if (result.isEmpty() || !isDuplicate(result, item)) {
+ if (!set.contains(item.getId())) { // to prevent duplicate results
result.add(new SearchResult(item, values[i], subtitles[i]));
+ set.add(item.getId());
}
}
-
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
@@ -67,20 +75,4 @@ public class FeedSearcher {
Collections.sort(result, new SearchResultValueComparator());
return result;
}
-
- /**
- * Determines if the feed item is already in the search result list.
- *
- * @param result list of search results
- * @param item feed item to validate
- * @return true if the feed item is already in the results
- */
- private static boolean isDuplicate(List<SearchResult> result, FeedItem item) {
- for (SearchResult resultItem : result) {
- if (resultItem.getComponent().getId() == item.getId()) {
- return true;
- }
- }
- return false;
- }
}
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 ff003550c..dc8692866 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
@@ -15,9 +15,12 @@ import android.text.TextUtils;
import android.util.Log;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
import de.danoeh.antennapod.core.R;
import de.danoeh.antennapod.core.event.ProgressEvent;
@@ -40,7 +43,7 @@ import de.greenrobot.event.EventBus;
* Implements methods for accessing the database
*/
public class PodDBAdapter {
-
+
private static final String TAG = "PodDBAdapter";
private static final String DATABASE_NAME = "Antennapod.db";
@@ -219,7 +222,7 @@ public class PodDBAdapter {
public static final String CREATE_TABLE_FAVORITES = "CREATE TABLE "
+ TABLE_NAME_FAVORITES + "(" + KEY_ID + " INTEGER PRIMARY KEY,"
+ KEY_FEEDITEM + " INTEGER," + KEY_FEED + " INTEGER)";
-
+
/**
* Select all columns from the feed-table
*/
@@ -252,7 +255,7 @@ public class PodDBAdapter {
TABLE_NAME_FEEDS + "." + KEY_INCLUDE_FILTER,
TABLE_NAME_FEEDS + "." + KEY_EXCLUDE_FILTER
};
-
+
/**
* Select all columns from the feeditems-table except description and
* content-encoded.
@@ -303,59 +306,87 @@ public class PodDBAdapter {
private static final String[] SEL_FI_EXTRA = {KEY_ID, KEY_DESCRIPTION,
KEY_CONTENT_ENCODED, KEY_FEED};
-
- private static SQLiteDatabase db;
private static Context context;
private static PodDBHelper dbHelper;
+
+ private static volatile SQLiteDatabase db;
+ private static Lock dbLock = new ReentrantLock();
private static AtomicInteger counter = new AtomicInteger(0);
public static void init(Context context) {
PodDBAdapter.context = context.getApplicationContext();
}
- public static synchronized PodDBAdapter getInstance() {
- if(dbHelper == null) {
- dbHelper = new PodDBHelper(PodDBAdapter.context, DATABASE_NAME, null);
- }
+ private static class PodDBHelperholder {
+ public static final PodDBHelper dbHelper = new PodDBHelper(PodDBAdapter.context, DATABASE_NAME, null);
+ }
+
+ public static PodDBAdapter getInstance() {
+ dbHelper = PodDBHelperholder.dbHelper;
return new PodDBAdapter();
}
- private PodDBAdapter() {}
+ private PodDBAdapter() {
+ }
- public synchronized PodDBAdapter open() {
+ public PodDBAdapter open() {
int adapters = counter.incrementAndGet();
Log.v(TAG, "Opening DB #" + adapters);
- if (db == null || !db.isOpen() || db.isReadOnly()) {
+
+ if ((db == null) || (!db.isOpen()) || (db.isReadOnly())) {
try {
- db = dbHelper.getWritableDatabase();
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
- db.enableWriteAheadLogging();
+ dbLock.lock();
+ if ((db == null) || (!db.isOpen()) || (db.isReadOnly())) {
+ db = openDb();
}
- } catch (SQLException ex) {
- Log.e(TAG, Log.getStackTraceString(ex));
- db = dbHelper.getReadableDatabase();
+ } finally {
+ dbLock.unlock();
}
}
return this;
}
- public synchronized void close() {
+ private SQLiteDatabase openDb() {
+ SQLiteDatabase newDb = null;
+ try {
+ newDb = dbHelper.getWritableDatabase();
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+ newDb.enableWriteAheadLogging();
+ }
+ } catch (SQLException ex) {
+ Log.e(TAG, Log.getStackTraceString(ex));
+ newDb = dbHelper.getReadableDatabase();
+ }
+ return newDb;
+ }
+
+ public void close() {
int adapters = counter.decrementAndGet();
Log.v(TAG, "Closing DB #" + adapters);
- if(adapters == 0) {
+
+ if (adapters == 0) {
Log.v(TAG, "Closing DB, really");
- db.close();
+ try {
+ dbLock.lock();
+ db.close();
+ db = null;
+ } finally {
+ dbLock.unlock();
+ }
}
}
public static boolean deleteDatabase() {
PodDBAdapter adapter = getInstance();
adapter.open();
- for (String tableName : ALL_TABLES) {
- db.delete(tableName, "1", null);
+ try {
+ for (String tableName : ALL_TABLES) {
+ db.delete(tableName, "1", null);
+ }
+ return true;
+ } finally {
+ adapter.close();
}
- adapter.close();
- return true;
}
/**
@@ -390,8 +421,8 @@ public class PodDBAdapter {
values.put(KEY_FLATTR_STATUS, feed.getFlattrStatus().toLong());
values.put(KEY_IS_PAGED, feed.isPaged());
values.put(KEY_NEXT_PAGE_LINK, feed.getNextPageLink());
- if(feed.getItemFilter() != null && feed.getItemFilter().getValues().length > 0) {
- values.put(KEY_HIDE, TextUtils.join( ",", feed.getItemFilter().getValues()));
+ if (feed.getItemFilter() != null && feed.getItemFilter().getValues().length > 0) {
+ values.put(KEY_HIDE, TextUtils.join(",", feed.getItemFilter().getValues()));
} else {
values.put(KEY_HIDE, "");
}
@@ -415,7 +446,7 @@ public class PodDBAdapter {
ContentValues values = new ContentValues();
values.put(KEY_AUTO_DOWNLOAD, prefs.getAutoDownload());
values.put(KEY_KEEP_UPDATED, prefs.getKeepUpdated());
- values.put(KEY_AUTO_DELETE_ACTION,prefs.getAutoDeleteAction().ordinal());
+ values.put(KEY_AUTO_DELETE_ACTION, prefs.getAutoDeleteAction().ordinal());
values.put(KEY_USERNAME, prefs.getUsername());
values.put(KEY_PASSWORD, prefs.getPassword());
values.put(KEY_INCLUDE_FILTER, prefs.getFilter().getIncludeFilter());
@@ -424,10 +455,11 @@ public class PodDBAdapter {
}
public void setFeedItemFilter(long feedId, Set<String> filterValues) {
- Log.d(TAG, "setFeedItemFilter() called with: " + "feedId = [" + feedId + "], " +
- "filterValues = [" + TextUtils.join(",", filterValues) + "]");
+ String valuesList = TextUtils.join(",", filterValues);
+ Log.d(TAG, String.format(
+ "setFeedItemFilter() called with: feedId = [%d], filterValues = [%s]", feedId, valuesList));
ContentValues values = new ContentValues();
- values.put(KEY_HIDE, TextUtils.join(",", filterValues));
+ values.put(KEY_HIDE, valuesList);
db.update(TABLE_NAME_FEEDS, values, KEY_ID + "=?", new String[]{String.valueOf(feedId)});
}
@@ -458,7 +490,7 @@ public class PodDBAdapter {
image.setId(db.insert(TABLE_NAME_FEED_IMAGES, null, values));
} else {
db.update(TABLE_NAME_FEED_IMAGES, values, KEY_ID + "=?",
- new String[]{String.valueOf(image.getId())});
+ new String[]{String.valueOf(image.getId())});
}
final FeedComponent owner = image.getOwner();
@@ -746,9 +778,9 @@ public class PodDBAdapter {
setFeed(item.getFeed());
}
values.put(KEY_FEED, item.getFeed().getId());
- if(item.isNew()) {
+ if (item.isNew()) {
values.put(KEY_READ, FeedItem.NEW);
- } else if(item.isPlayed()) {
+ } else if (item.isPlayed()) {
values.put(KEY_READ, FeedItem.PLAYED);
} else {
values.put(KEY_READ, FeedItem.UNPLAYED);
@@ -808,7 +840,8 @@ public class PodDBAdapter {
/**
* Sets the 'read' attribute of the item.
- * @param read must be one of FeedItem.PLAYED, FeedItem.NEW, FeedItem.UNPLAYED
+ *
+ * @param read must be one of FeedItem.PLAYED, FeedItem.NEW, FeedItem.UNPLAYED
* @param itemIds items to change the value of
*/
public void setFeedItemRead(int read, long... itemIds) {
@@ -851,8 +884,8 @@ public class PodDBAdapter {
public void setFeedLastUpdateFailed(long feedId, boolean failed) {
final String sql = "UPDATE " + TABLE_NAME_FEEDS
- + " SET " + KEY_LAST_UPDATE_FAILED+ "=" + (failed ? "1" : "0")
- + " WHERE " + KEY_ID + "="+ feedId;
+ + " SET " + KEY_LAST_UPDATE_FAILED + "=" + (failed ? "1" : "0")
+ + " WHERE " + KEY_ID + "=" + feedId;
db.execSQL(sql);
}
@@ -892,7 +925,7 @@ public class PodDBAdapter {
public void setFeedsItemsAutoDownload(Feed feed, boolean autoDownload) {
final String sql = "UPDATE " + TABLE_NAME_FEED_ITEMS
- + " SET " + KEY_AUTO_DOWNLOAD + "="+ (autoDownload ? "1" : "0")
+ + " SET " + KEY_AUTO_DOWNLOAD + "=" + (autoDownload ? "1" : "0")
+ " WHERE " + KEY_FEED + "=" + feed.getId();
db.execSQL(sql);
}
@@ -994,8 +1027,8 @@ public class PodDBAdapter {
public void removeFeedMedia(FeedMedia media) {
// delete download log entries for feed media
- db.delete(TABLE_NAME_DOWNLOAD_LOG, KEY_FEEDFILE + "=? AND " + KEY_FEEDFILETYPE +"=?",
- new String[] { String.valueOf(media.getId()), String.valueOf(FeedMedia.FEEDFILETYPE_FEEDMEDIA) });
+ db.delete(TABLE_NAME_DOWNLOAD_LOG, KEY_FEEDFILE + "=? AND " + KEY_FEEDFILETYPE + "=?",
+ new String[]{String.valueOf(media.getId()), String.valueOf(FeedMedia.FEEDFILETYPE_FEEDMEDIA)});
db.delete(TABLE_NAME_FEED_MEDIA, KEY_ID + "=?",
new String[]{String.valueOf(media.getId())});
@@ -1048,10 +1081,10 @@ public class PodDBAdapter {
}
// delete download log entries for feed
db.delete(TABLE_NAME_DOWNLOAD_LOG, KEY_FEEDFILE + "=? AND " + KEY_FEEDFILETYPE + "=?",
- new String[]{String.valueOf(feed.getId()), String.valueOf(Feed.FEEDFILETYPE_FEED)});
+ new String[]{String.valueOf(feed.getId()), String.valueOf(Feed.FEEDFILETYPE_FEED)});
db.delete(TABLE_NAME_FEEDS, KEY_ID + "=?",
- new String[]{String.valueOf(feed.getId())});
+ new String[]{String.valueOf(feed.getId())});
db.setTransactionSuccessful();
} catch (SQLException e) {
Log.e(TAG, Log.getStackTraceString(e));
@@ -1156,7 +1189,9 @@ public class PodDBAdapter {
+ TABLE_NAME_FEED_IMAGES + " WHERE " + KEY_ID + " IN "
+ buildInOperator(neededLength), parts);
}
- return new MergeCursor(cursors);
+ Cursor result = new MergeCursor(cursors);
+ result.moveToFirst();
+ return result;
} else {
return db.query(TABLE_NAME_FEED_IMAGES, null, KEY_ID + " IN "
+ buildInOperator(length), imageIds, null, null, null);
@@ -1188,12 +1223,12 @@ public class PodDBAdapter {
* cursor uses the FEEDITEM_SEL_FI_SMALL selection.
*/
public final Cursor getQueueCursor() {
- Object[] args = new String[] {
+ Object[] args = new String[]{
SEL_FI_SMALL_STR,
TABLE_NAME_FEED_ITEMS, TABLE_NAME_QUEUE,
TABLE_NAME_FEED_ITEMS + "." + KEY_ID,
TABLE_NAME_QUEUE + "." + KEY_FEEDITEM,
- TABLE_NAME_QUEUE + "." + KEY_ID };
+ TABLE_NAME_QUEUE + "." + KEY_ID};
String query = String.format("SELECT %s FROM %s INNER JOIN %s ON %s=%s ORDER BY %s", args);
return db.rawQuery(query, null);
}
@@ -1204,25 +1239,16 @@ public class PodDBAdapter {
public final Cursor getFavoritesCursor() {
- Object[] args = new String[] {
+ Object[] args = new String[]{
SEL_FI_SMALL_STR,
TABLE_NAME_FEED_ITEMS, TABLE_NAME_FAVORITES,
TABLE_NAME_FEED_ITEMS + "." + KEY_ID,
TABLE_NAME_FAVORITES + "." + KEY_FEEDITEM,
- TABLE_NAME_FEED_ITEMS + "." + KEY_PUBDATE };
+ TABLE_NAME_FEED_ITEMS + "." + KEY_PUBDATE};
String query = String.format("SELECT %s FROM %s INNER JOIN %s ON %s=%s ORDER BY %s DESC", args);
return db.rawQuery(query, null);
}
- /**
- * Returns a cursor which contains all feed items in the unread items list.
- * The returned cursor uses the FEEDITEM_SEL_FI_SMALL selection.
- */
- public final Cursor getUnreadItemsCursor() {
- return db.query(TABLE_NAME_FEED_ITEMS, FEEDITEM_SEL_FI_SMALL, KEY_READ
- + "<" + FeedItem.PLAYED, null, null, null, KEY_PUBDATE + " DESC");
- }
-
public void setFeedItems(int state) {
setFeedItems(Integer.MIN_VALUE, state, 0);
}
@@ -1237,10 +1263,10 @@ public class PodDBAdapter {
public void setFeedItems(int oldState, int newState, long feedId) {
String sql = "UPDATE " + TABLE_NAME_FEED_ITEMS + " SET " + KEY_READ + "=" + newState;
- if(feedId > 0) {
+ if (feedId > 0) {
sql += " WHERE " + KEY_FEED + "=" + feedId;
}
- if(FeedItem.NEW <= oldState && oldState <= FeedItem.PLAYED) {
+ if (FeedItem.NEW <= oldState && oldState <= FeedItem.PLAYED) {
sql += feedId > 0 ? " AND " : " WHERE ";
sql += KEY_READ + "=" + oldState;
}
@@ -1248,25 +1274,12 @@ public class PodDBAdapter {
}
/**
- * Returns a cursor which contains all items of a feed that are considered new.
- * The returned cursor uses the FEEDITEM_SEL_FI_SMALL selection.
- */
- public final Cursor getNewItemsIdsCursor(long feedId) {
- final String query = "SELECT " + KEY_ID
- + " FROM " + TABLE_NAME_FEED_ITEMS
- + " WHERE " + KEY_FEED + "=" + feedId
- + " AND " + KEY_READ + "=" + FeedItem.NEW
- + " ORDER BY " + KEY_PUBDATE + " DESC";
- return db.rawQuery(query, null);
- }
-
- /**
* Returns a cursor which contains all feed items that are considered new.
* Excludes those feeds that do not have 'Keep Updated' enabled.
* The returned cursor uses the FEEDITEM_SEL_FI_SMALL selection.
*/
public final Cursor getNewItemsCursor() {
- Object[] args = new String[] {
+ Object[] args = new String[]{
SEL_FI_SMALL_STR,
TABLE_NAME_FEED_ITEMS,
TABLE_NAME_FEEDS,
@@ -1300,7 +1313,7 @@ public class PodDBAdapter {
* @throws IllegalArgumentException if limit < 0
*/
public final Cursor getCompletedMediaCursor(int limit) {
- if(limit < 0) {
+ if (limit < 0) {
throw new IllegalArgumentException("Limit must be >= 0");
}
@@ -1341,7 +1354,9 @@ public class PodDBAdapter {
+ TABLE_NAME_FEED_MEDIA + " WHERE " + KEY_FEEDITEM + " IN "
+ buildInOperator(neededLength), parts);
}
- return new MergeCursor(cursors);
+ Cursor result = new MergeCursor(cursors);
+ result.moveToFirst();
+ return result;
} else {
return db.query(TABLE_NAME_FEED_MEDIA, null, KEY_FEEDITEM + " IN "
+ buildInOperator(length), itemIds, null, null, null);
@@ -1355,11 +1370,10 @@ public class PodDBAdapter {
if (size == 1) {
return "(?)";
}
- StringBuilder builder = new StringBuilder("(");
- for (int i = 0; i < size - 1; i++) {
- builder.append("?,");
- }
- builder.append("?)");
+ StringBuilder builder =
+ new StringBuilder("(")
+ .append(TextUtils.join(",", Collections.nCopies(size, "?")))
+ .append(")");
return builder.toString();
}
@@ -1393,7 +1407,7 @@ public class PodDBAdapter {
+ " INNER JOIN " + TABLE_NAME_FEEDS
+ " ON " + TABLE_NAME_FEED_ITEMS + "." + KEY_FEED + "=" + TABLE_NAME_FEEDS + "." + KEY_ID
+ " INNER JOIN " + TABLE_NAME_FEED_MEDIA
- + " ON " + TABLE_NAME_FEED_MEDIA + "." + KEY_FEEDITEM + "=" + TABLE_NAME_FEED_ITEMS + "." + KEY_ID
+ + " ON " + TABLE_NAME_FEED_MEDIA + "." + KEY_FEEDITEM + "=" + TABLE_NAME_FEED_ITEMS + "." + KEY_ID
+ " WHERE " + TABLE_NAME_FEED_MEDIA + "." + KEY_DOWNLOAD_URL + "=" + escapedEpisodeUrl
+ " AND " + TABLE_NAME_FEEDS + "." + KEY_DOWNLOAD_URL + "=" + escapedPodcastUrl;
Log.d(TAG, "SQL: " + query);
@@ -1444,10 +1458,10 @@ public class PodDBAdapter {
public final LongIntMap getFeedCounters(long... feedIds) {
int setting = UserPreferences.getFeedCounterSetting();
String whereRead;
- switch(setting) {
+ switch (setting) {
case UserPreferences.FEED_COUNTER_SHOW_NEW_UNPLAYED_SUM:
whereRead = "(" + KEY_READ + "=" + FeedItem.NEW +
- " OR " + KEY_READ + "=" + FeedItem.UNPLAYED + ")";
+ " OR " + KEY_READ + "=" + FeedItem.UNPLAYED + ")";
break;
case UserPreferences.FEED_COUNTER_SHOW_NEW:
whereRead = KEY_READ + "=" + FeedItem.NEW;
@@ -1463,7 +1477,10 @@ public class PodDBAdapter {
default: // NONE
return new LongIntMap(0);
}
+ return conditionalFeedCounterRead(whereRead, feedIds);
+ }
+ private LongIntMap conditionalFeedCounterRead(String whereRead, long... feedIds) {
// work around TextUtils.join wanting only boxed items
// and StringUtils.join() causing NoSuchMethodErrors on MIUI
StringBuilder builder = new StringBuilder();
@@ -1490,12 +1507,17 @@ public class PodDBAdapter {
long feedId = c.getLong(0);
int count = c.getInt(1);
result.put(feedId, count);
- } while(c.moveToNext());
+ } while (c.moveToNext());
}
c.close();
return result;
}
+ public final LongIntMap getPlayedEpisodesCounters(long... feedIds) {
+ String whereRead = KEY_READ + "=" + FeedItem.PLAYED;
+ return conditionalFeedCounterRead(whereRead, feedIds);
+ }
+
public final int getNumberOfDownloadedEpisodes() {
final String query = "SELECT COUNT(DISTINCT " + KEY_ID + ") AS count FROM " + TABLE_NAME_FEED_MEDIA +
" WHERE " + KEY_DOWNLOADED + " > 0";
@@ -1589,6 +1611,52 @@ public class PodDBAdapter {
}
}
+ public Cursor searchItemAuthors(long feedID, String query) {
+ if (feedID != 0) {
+ // search items in specific feed
+ return db.rawQuery("SELECT " + TextUtils.join(", ", FEEDITEM_SEL_FI_SMALL) + " FROM " + TABLE_NAME_FEED_ITEMS
+ + " JOIN " + TABLE_NAME_FEEDS + " ON " + TABLE_NAME_FEED_ITEMS + "." + KEY_FEED + "=" + TABLE_NAME_FEEDS + "." + KEY_ID
+ + " WHERE " + KEY_FEED
+ + "=? AND " + KEY_AUTHOR + " LIKE '%"
+ + prepareSearchQuery(query) + "%' ORDER BY "
+ + TABLE_NAME_FEED_ITEMS + "." + KEY_PUBDATE + " DESC",
+ new String[]{String.valueOf(feedID)}
+ );
+ } else {
+ // search through all items
+ return db.rawQuery("SELECT " + TextUtils.join(", ", FEEDITEM_SEL_FI_SMALL) + " FROM " + TABLE_NAME_FEED_ITEMS
+ + " JOIN " + TABLE_NAME_FEEDS + " ON " + TABLE_NAME_FEED_ITEMS + "." + KEY_FEED + "=" + TABLE_NAME_FEEDS + "." + KEY_ID
+ + " WHERE " + KEY_AUTHOR + " LIKE '%"
+ + prepareSearchQuery(query) + "%' ORDER BY "
+ + TABLE_NAME_FEED_ITEMS + "." + KEY_PUBDATE + " DESC",
+ null
+ );
+ }
+ }
+
+ public Cursor searchItemFeedIdentifiers(long feedID, String query) {
+ if (feedID != 0) {
+ // search items in specific feed
+ return db.rawQuery("SELECT " + TextUtils.join(", ", FEEDITEM_SEL_FI_SMALL) + " FROM " + TABLE_NAME_FEED_ITEMS
+ + " JOIN " + TABLE_NAME_FEEDS + " ON " + TABLE_NAME_FEED_ITEMS + "." + KEY_FEED + "=" + TABLE_NAME_FEEDS + "." + KEY_ID
+ + " WHERE " + KEY_FEED
+ + "=? AND " + KEY_FEED_IDENTIFIER + " LIKE '%"
+ + prepareSearchQuery(query) + "%' ORDER BY "
+ + TABLE_NAME_FEED_ITEMS + "." + KEY_PUBDATE + " DESC",
+ new String[]{String.valueOf(feedID)}
+ );
+ } else {
+ // search through all items
+ return db.rawQuery("SELECT " + TextUtils.join(", ", FEEDITEM_SEL_FI_SMALL) + " FROM " + TABLE_NAME_FEED_ITEMS
+ + " JOIN " + TABLE_NAME_FEEDS + " ON " + TABLE_NAME_FEED_ITEMS + "." + KEY_FEED + "=" + TABLE_NAME_FEEDS + "." + KEY_ID
+ + " WHERE " + KEY_FEED_IDENTIFIER + " LIKE '%"
+ + prepareSearchQuery(query) + "%' ORDER BY "
+ + TABLE_NAME_FEED_ITEMS + "." + KEY_PUBDATE + " DESC",
+ null
+ );
+ }
+ }
+
public Cursor searchItemChapters(long feedID, String searchQuery) {
final String query;
if (feedID != 0) {
@@ -1784,7 +1852,7 @@ public class PodDBAdapter {
KEY_LINK,
KEY_CHAPTER_TYPE));
}
- if(oldVersion <= 14) {
+ if (oldVersion <= 14) {
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
+ " ADD COLUMN " + KEY_AUTO_DOWNLOAD + " INTEGER");
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
@@ -1807,7 +1875,7 @@ public class PodDBAdapter {
db.execSQL(PodDBAdapter.CREATE_INDEX_QUEUE_FEEDITEM);
db.execSQL(PodDBAdapter.CREATE_INDEX_SIMPLECHAPTERS_FEEDITEM);
}
- if(oldVersion <= 15) {
+ if (oldVersion <= 15) {
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
+ " ADD COLUMN " + KEY_HAS_EMBEDDED_PICTURE + " INTEGER DEFAULT -1");
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
@@ -1817,7 +1885,7 @@ public class PodDBAdapter {
+ " FROM " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
+ " WHERE " + KEY_DOWNLOADED + "=1 "
+ " AND " + KEY_HAS_EMBEDDED_PICTURE + "=-1", null);
- if(c.moveToFirst()) {
+ if (c.moveToFirst()) {
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
do {
String fileUrl = c.getString(0);
@@ -1827,20 +1895,20 @@ public class PodDBAdapter {
if (image != null) {
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
+ " SET " + KEY_HAS_EMBEDDED_PICTURE + "=1"
- + " WHERE " + KEY_FILE_URL + "='"+ fileUrl + "'");
+ + " WHERE " + KEY_FILE_URL + "='" + fileUrl + "'");
} else {
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
+ " SET " + KEY_HAS_EMBEDDED_PICTURE + "=0"
- + " WHERE " + KEY_FILE_URL + "='"+ fileUrl + "'");
+ + " WHERE " + KEY_FILE_URL + "='" + fileUrl + "'");
}
- } catch(Exception e) {
+ } catch (Exception e) {
e.printStackTrace();
}
- } while(c.moveToNext());
+ } while (c.moveToNext());
}
c.close();
}
- if(oldVersion <= 16) {
+ if (oldVersion <= 16) {
String selectNew = "SELECT " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + KEY_ID
+ " FROM " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
+ " INNER JOIN " + PodDBAdapter.TABLE_NAME_FEED_MEDIA + " ON "
@@ -1854,29 +1922,29 @@ public class PodDBAdapter {
+ PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + KEY_DOWNLOADED + " = 0 AND " // undownloaded
+ PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + KEY_POSITION + " = 0 AND " // not partially played
+ PodDBAdapter.TABLE_NAME_QUEUE + "." + KEY_ID + " IS NULL"; // not in queue
- String sql = "UPDATE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
+ String sql = "UPDATE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
+ " SET " + KEY_READ + "=" + FeedItem.NEW
+ " WHERE " + KEY_ID + " IN (" + selectNew + ")";
Log.d("Migration", "SQL: " + sql);
db.execSQL(sql);
}
- if(oldVersion <= 17) {
+ if (oldVersion <= 17) {
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
+ " ADD COLUMN " + PodDBAdapter.KEY_AUTO_DELETE_ACTION + " INTEGER DEFAULT 0");
}
- if(oldVersion < 1030005) {
+ if (oldVersion < 1030005) {
db.execSQL("UPDATE FeedItems SET auto_download=0 WHERE " +
"(read=1 OR id IN (SELECT feeditem FROM FeedMedia WHERE position>0 OR downloaded=1)) " +
"AND id NOT IN (SELECT feeditem FROM Queue)");
}
- if(oldVersion < 1040001) {
+ if (oldVersion < 1040001) {
db.execSQL(CREATE_TABLE_FAVORITES);
}
- if (oldVersion < 1040002) {
+ if (oldVersion < 1040002) {
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
+ " ADD COLUMN " + PodDBAdapter.KEY_LAST_PLAYED_TIME + " INTEGER DEFAULT 0");
}
- if(oldVersion < 1040013) {
+ if (oldVersion < 1040013) {
db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_PUBDATE);
db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_READ);
}
@@ -1930,9 +1998,9 @@ public class PodDBAdapter {
if (oldVersion < 1050004) {
// prevent old timestamps to be misinterpreted as ETags
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS
- +" SET " + PodDBAdapter.KEY_LASTUPDATE + "=NULL");
+ + " SET " + PodDBAdapter.KEY_LASTUPDATE + "=NULL");
}
- if(oldVersion < 1060200) {
+ if (oldVersion < 1060200) {
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
+ " ADD COLUMN " + PodDBAdapter.KEY_CUSTOM_TITLE + " TEXT");
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSITunes.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSITunes.java
index 1c424c6b5..7d60566b2 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSITunes.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSITunes.java
@@ -101,7 +101,10 @@ public class NSITunes extends Namespace {
if (TextUtils.isEmpty(summary)) {
return;
}
- if (state.getCurrentItem() != null) {
+ if (state.getCurrentItem() != null &&
+ (TextUtils.isEmpty(state.getCurrentItem().getDescription()) ||
+ state.getCurrentItem().getDescription().length() * 1.25 < summary.length())
+ ) {
state.getCurrentItem().setDescription(summary);
} else if (state.getFeed() != null) {
state.getFeed().setDescription(summary);
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/DateUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/DateUtils.java
index 314062e52..f63f0983f 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/DateUtils.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/DateUtils.java
@@ -16,41 +16,45 @@ import java.util.TimeZone;
* Parses several date formats.
*/
public class DateUtils {
-
- private static final String TAG = "DateUtils";
+
+ private static final String TAG = "DateUtils";
private static final TimeZone defaultTimezone = TimeZone.getTimeZone("GMT");
public static Date parse(final String input) {
- if(input == null) {
+ if (input == null) {
throw new IllegalArgumentException("Date must not be null");
}
String date = input.trim().replace('/', '-').replaceAll("( ){2,}+", " ");
+ // CEST is widely used but not in the "ISO 8601 Time zone" list. Let's hack around.
+ date = date.replaceAll("CEST$", "+02:00");
+ date = date.replaceAll("CET$", "+01:00");
+
// if datetime is more precise than seconds, make sure the value is in ms
- if(date.contains(".")) {
+ if (date.contains(".")) {
int start = date.indexOf('.');
- int current = start+1;
- while(current < date.length() && Character.isDigit(date.charAt(current))) {
+ int current = start + 1;
+ while (current < date.length() && Character.isDigit(date.charAt(current))) {
current++;
}
// even more precise than microseconds: discard further decimal places
- if(current - start > 4) {
- if(current < date.length()-1) {
+ if (current - start > 4) {
+ if (current < date.length() - 1) {
date = date.substring(0, start + 4) + date.substring(current);
} else {
date = date.substring(0, start + 4);
}
- // less than 4 decimal places: pad to have a consistent format for the parser
- } else if(current - start < 4) {
- if(current < date.length()-1) {
- date = date.substring(0, current) + StringUtils.repeat("0", 4-(current-start)) + date.substring(current);
+ // less than 4 decimal places: pad to have a consistent format for the parser
+ } else if (current - start < 4) {
+ if (current < date.length() - 1) {
+ date = date.substring(0, current) + StringUtils.repeat("0", 4 - (current - start)) + date.substring(current);
} else {
- date = date.substring(0, current) + StringUtils.repeat("0", 4-(current-start));
+ date = date.substring(0, current) + StringUtils.repeat("0", 4 - (current - start));
}
}
}
- String[] patterns = {
+ final String[] patterns = {
"dd MMM yy HH:mm:ss Z",
"dd MMM yy HH:mm Z",
"EEE, dd MMM yyyy HH:mm:ss Z",
@@ -76,6 +80,7 @@ public class DateUtils {
"yyyy-MM-dd'T'HH:mm:ss.SSS",
"yyyy-MM-dd'T'HH:mm:ssZ",
"yyyy-MM-dd'T'HH:mm:ss'Z'",
+ "yyyy-MM-dd'T'HH:mm:ss.SSSZ",
"yyyy-MM-ddZ",
"yyyy-MM-dd"
};
@@ -85,7 +90,7 @@ public class DateUtils {
parser.setTimeZone(defaultTimezone);
ParsePosition pos = new ParsePosition(0);
- for(String pattern : patterns) {
+ for (String pattern : patterns) {
parser.applyPattern(pattern);
pos.setIndex(0);
try {
@@ -93,11 +98,16 @@ public class DateUtils {
if (result != null && pos.getIndex() == date.length()) {
return result;
}
- } catch(Exception e) {
+ } catch (Exception e) {
Log.e(TAG, Log.getStackTraceString(e));
}
}
+ // if date string starts with a weekday, try parsing date string without it
+ if(date.matches("^\\w+, .*$")) {
+ return parse(date.substring(date.indexOf(',') + 1));
+ }
+
Log.d(TAG, "Could not parse date string \"" + input + "\" [" + date + "]");
return null;
}
@@ -143,7 +153,7 @@ public class DateUtils {
}
public static String formatAbbrev(final Context context, final Date date) {
- if(date == null) {
+ if (date == null) {
return "";
}
GregorianCalendar cal = new GregorianCalendar();
@@ -152,7 +162,7 @@ public class DateUtils {
cal.add(GregorianCalendar.DAY_OF_MONTH, 10);
boolean withinLastYear = date.after(cal.getTime());
int format = android.text.format.DateUtils.FORMAT_ABBREV_ALL;
- if(withinLastYear) {
+ if (withinLastYear) {
format |= android.text.format.DateUtils.FORMAT_NO_YEAR;
}
return android.text.format.DateUtils.formatDateTime(context, date.getTime(), format);
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/FileNameGenerator.java b/core/src/main/java/de/danoeh/antennapod/core/util/FileNameGenerator.java
index 30c2e62f2..8da176c82 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/FileNameGenerator.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/FileNameGenerator.java
@@ -1,18 +1,21 @@
package de.danoeh.antennapod.core.util;
+import org.apache.commons.lang3.ArrayUtils;
+
import java.util.Arrays;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/** Generates valid filenames for a given string. */
public class FileNameGenerator {
- private static final char[] ILLEGAL_CHARACTERS = { '/', '\\', '?', '%',
- '*', ':', '|', '"', '<', '>', '\n' };
- static {
- Arrays.sort(ILLEGAL_CHARACTERS);
- }
+ private static final char[] validChars = (
+ "abcdefghijklmnopqrstuvwxyz" +
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
+ "0123456789" +
+ " _-").toCharArray();
private FileNameGenerator() {
-
}
/**
@@ -20,17 +23,17 @@ public class FileNameGenerator {
* characters of the given string.
*/
public static String generateFileName(String string) {
- StringBuilder builder = new StringBuilder();
+ StringBuilder buf = new StringBuilder();
for (int i = 0; i < string.length(); i++) {
char c = string.charAt(i);
- if (Arrays.binarySearch(ILLEGAL_CHARACTERS, c) < 0) {
- builder.append(c);
+ if(Character.isSpaceChar(c) && (buf.length() == 0 || Character.isSpaceChar(buf.charAt(buf.length()-1)))) {
+ continue;
+ }
+ if (ArrayUtils.contains(validChars, c)) {
+ buf.append(c);
}
}
- return builder.toString().replaceFirst(" *$","");
+ return buf.toString().trim();
}
- public static long generateLong(final String str) {
- return str.hashCode();
- }
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/ShareUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/ShareUtils.java
index 35916a604..887c0055c 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/ShareUtils.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/ShareUtils.java
@@ -3,9 +3,13 @@ package de.danoeh.antennapod.core.util;
import android.content.Context;
import android.content.Intent;
+import android.net.Uri;
import de.danoeh.antennapod.core.R;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedItem;
+import de.danoeh.antennapod.core.feed.FeedMedia;
+
+import java.io.File;
/** Utility methods for sharing data */
public class ShareUtils {
@@ -58,4 +62,11 @@ public class ShareUtils {
shareLink(context, text);
}
+ public static void shareFeedItemFile(Context context, FeedMedia media) {
+ Intent i = new Intent(Intent.ACTION_SEND);
+ i.setType(media.getMime_type());
+ i.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(media.getLocalMediaUrl())));
+ i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ context.startActivity(Intent.createChooser(i, context.getString(R.string.share_file_label)));
+ }
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/URLChecker.java b/core/src/main/java/de/danoeh/antennapod/core/util/URLChecker.java
index 415a1d3a2..40faa1dd2 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/URLChecker.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/URLChecker.java
@@ -37,6 +37,9 @@ public final class URLChecker {
} else if (url.startsWith("pcast://")) {
if (BuildConfig.DEBUG) Log.d(TAG, "Removing pcast://");
return prepareURL(url.substring("pcast://".length()));
+ } else if (url.startsWith("pcast:")) {
+ if (BuildConfig.DEBUG) Log.d(TAG, "Removing pcast:");
+ return prepareURL(url.substring("pcast:".length()));
} else if (url.startsWith("itpc")) {
if (BuildConfig.DEBUG) Log.d(TAG, "Replacing itpc:// with http://");
return url.replaceFirst("itpc://", "http://");
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
index b16e0949d..d23901a45 100644
--- 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
@@ -1,14 +1,27 @@
package de.danoeh.antennapod.core.util.comparator;
+import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.SearchResult;
import java.util.Comparator;
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) {
- return rhs.getValue() - lhs.getValue();
+ 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/playback/PlaybackController.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java
index 6251cc4a0..9d3854f41 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
@@ -461,6 +461,7 @@ public abstract class PlaybackController {
checkMediaInfoLoaded();
postStatusMsg(R.string.player_ready_msg, false);
updatePlayButtonAppearance(playResource, playText);
+ onPositionObserverUpdate();
break;
case SEEKING:
onPositionObserverUpdate();
diff --git a/core/src/main/res/values-az/strings.xml b/core/src/main/res/values-az/strings.xml
index 89322bc62..bde3d8393 100644
--- a/core/src/main/res/values-az/strings.xml
+++ b/core/src/main/res/values-az/strings.xml
@@ -41,7 +41,6 @@
<string name="mark_all_read_label">Hamısını oxunmuş kimi işarələ</string>
<string name="show_info_label">Məlumatı göstər</string>
<string name="share_link_label">Web-səhifəyi paylaş</string>
- <string name="feed_delete_confirmation_msg">Bütün kanallar və epizodlar silinəçək.</string>
<!--actions on feeditems-->
<string name="download_label">Yüklə</string>
<string name="play_label">Oynat</string>
diff --git a/core/src/main/res/values-b+ast/strings.xml b/core/src/main/res/values-b+ast/strings.xml
index ad96d9f0f..87ca9ed3e 100644
--- a/core/src/main/res/values-b+ast/strings.xml
+++ b/core/src/main/res/values-b+ast/strings.xml
@@ -107,7 +107,6 @@
<string name="share_link_label">Compartir enllaz</string>
<string name="share_feed_url_label">Compartir URL del feed</string>
<string name="share_item_url_label">Compatir URL del ficheru del episodiu</string>
- <string name="feed_delete_confirmation_msg">Confirma que quies desaniciar esti feed y TOLOS episodios d\'elli que baxares.</string>
<string name="feed_remover_msg">Desaniciando fees</string>
<string name="load_complete_feed">Completóse\'l refrescu\'l feed</string>
<string name="hide_episodes_title">Anubrir episodios</string>
@@ -226,23 +225,37 @@
<string name="return_home_label">Volver al aniciu</string>
<string name="flattr_auth_success">¡L\'autenticación tuvo ésitu! Agora pues facer flattr a coses dientro l\'aplicación.</string>
<string name="no_flattr_token_title">Nun s\'alcontró\'l pase de Flattr</string>
+ <string name="no_flattr_token_notification_msg">La to cuenta Flattr nun paez tar coneutada con AntennaPod. Calca equí p\'autenticar.</string>
+ <string name="no_flattr_token_msg">La to cuenta Flattr nun paez tar coneutada con AntennaPod. Pues o coneutar la cuenta con AntennaPod pa facer Flattr a coses dientro l\'aplicación, o pues visitar el sitiu web de la cosa a facer Flattr.</string>
<string name="authenticate_now_label">Autenticar</string>
+ <string name="action_forbidden_title">Torgóse la aición</string>
+ <string name="action_forbidden_msg">AntennaPod nun tien permisu pa esta aición. La razón quiciabes seya que se revocare\'l pase d\'accesu d\'AntennaPod a la to cuenta. Pues o reautenticate, o visitar el sitiu web de la cosa.</string>
+ <string name="access_revoked_title">Revocóse l\'accesu</string>
+ <string name="access_revoked_info">Revoquesti con ésitu\'l pase d\'accesu AntennaPod a la to cuenta. Pa completar el procesu, tienes de desaniciar esta aplicación del llistáu d\'aplicaciones aprobaes nos axustes de la to cuenta nel sitiu web de Flattr.</string>
<!--Flattr-->
<!--Variable Speed-->
<string name="download_plugin_label">Baxar complementu</string>
<string name="no_playback_plugin_title">Nun s\'instaló\'l complementu</string>
+ <string name="set_playback_speed_label">Velocidaes de reproducción</string>
<!--Empty list labels-->
<string name="no_items_label">Nun hai elementos nesti llistáu.</string>
<string name="no_feeds_label">Entá nun tas soscritu a feed dalu.</string>
<string name="no_chapters_label">Esti episodiu nun tien capítulos.</string>
<!--Preferences-->
+ <string name="storage_pref">Almacenamientu</string>
<string name="project_pref">Proyeutu</string>
<string name="services_label">Servicios</string>
<string name="flattr_label">Flattr</string>
<string name="pref_episode_cleanup_title">Llimpieza d\'episodios</string>
+ <string name="pref_pauseOnDisconnect_sum">Posa la reproducción al desconeutase los auriculares o Bluetooth</string>
+ <string name="pref_unpauseOnHeadsetReconnect_sum">Sigue la reproducción al coneutar los auriculares</string>
+ <string name="pref_unpauseOnBluetoothReconnect_sum">Sigue la reproducción al reconeutar el Bluetooth</string>
+ <string name="pref_auto_delete_sum">Desanicia l\'episodiu al completase la reproducción</string>
+ <string name="pref_skip_keeps_episodes_sum">Caltién los episodios al saltalos</string>
<string name="pref_skip_keeps_episodes_title">Caltener episodios saltaos</string>
<string name="playback_pref">Reproducción</string>
<string name="network_pref">Rede</string>
+ <string name="pref_autoUpdateIntervallOrTime_sum">Especifica un intervalu o una hora específica del día pa refrescar automáticamente los feeds</string>
<string name="pref_autoUpdateIntervallOrTime_Interval">Afitar intervalu</string>
<string name="pref_autoUpdateIntervallOrTime_every">cada %1$s</string>
<string name="pref_downloadMediaOnWifiOnly_sum">Baxa los ficheros de medios namái na WiFi</string>
@@ -251,18 +264,32 @@
<string name="refreshing_label">Refrescando</string>
<string name="flattr_settings_label">Axustes de Flattr</string>
<string name="pref_flattr_auth_title">Aniciu de sesión de Flattr</string>
+ <string name="pref_revokeAccess_sum">Revoca\'l permisu d\'accesu a la to cuenta Flatrr pa esta aplicación.</string>
+ <string name="pref_nav_drawer_sum">Personaliza l\'aspeutu del caxón de navegación.</string>
+ <string name="pref_nav_drawer_items_sum">Camuda qué elementos apaecen nel caxón de navegación.</string>
+ <string name="pref_nav_drawer_feed_order_sum">Camuda l\'orde de les tos soscripciones</string>
+ <string name="pref_nav_drawer_feed_counter_sum">Camuda la información amosada pol contador de soscripciones</string>
+ <string name="pref_set_theme_sum">Camuda l\'aspeutu d\'AntennaPod</string>
+ <string name="pref_automatic_download_sum">Configura la descarga automática d\'episodios.</string>
+ <string name="pref_autodl_wifi_filter_sum">Permite la descarga namái dende les redes Wi-Fi esbillaes.</string>
+ <string name="pref_automatic_download_on_battery_sum">Permite la descarga automárica cuando la batería nun tea cargando.</string>
<string name="pref_episode_cache_title">Caché d\'episodios</string>
<string name="pref_update_interval_hours_plural">hores</string>
<string name="pref_update_interval_hours_singular">hora</string>
<string name="pref_update_interval_hours_manual">Manual</string>
+ <string name="pref_gpodnet_authenticate_sum">Anicia sesión cola to cuenta de gpodder.net pa sincronizar les tos soscripciones.</string>
+ <string name="pref_gpodnet_setlogin_information_sum">Camuda la información d\'aniciu de sesión de la to cuenta de gpodder.net.</string>
<string name="pref_gpodnet_notifications_sum">Esti axuste nun s\'aplica a los fallos d\'autenticación.</string>
<string name="pref_playback_speed_title">Velocidaes de reproducción</string>
<string name="pref_expandNotify_title">Espander avisu</string>
+ <string name="pref_expandNotify_sum">Siempres espande l\'avisu p\'amosar los botones de reproducción.</string>
<string name="pref_showDownloadReport_title">Amosar informe de descarga</string>
+ <string name="pref_showDownloadReport_sum">SI falla la descarga, xenera un informe qu\'amuesa los detalles del fallu.</string>
<string name="pref_image_cache_size_sum">Tamañu del discu pa la caché d\'imáxenes.</string>
<string name="crash_report_title">Informe de casque</string>
<string name="experimental_pref">Esperimental</string>
<string name="pref_proxy_sum">Afita un proxy de rede</string>
+ <string name="pref_faq">FAQ</string>
<string name="pref_known_issues">Problemes conocíos</string>
<string name="pref_no_browser_found">Nun s\'alcontró un restolador web.</string>
<string name="pref_cast_title">Sofitu de Chromecast</string>
diff --git a/core/src/main/res/values-ca/strings.xml b/core/src/main/res/values-ca/strings.xml
index 6990b9db8..68b2b42d8 100644
--- a/core/src/main/res/values-ca/strings.xml
+++ b/core/src/main/res/values-ca/strings.xml
@@ -69,6 +69,7 @@
<string name="auto_download_label">Inclou a baixades automàtiques</string>
<string name="auto_download_apply_to_items_title">Aplica als episodis previs</string>
<string name="auto_download_apply_to_items_message">El nou ajustament de <i>baixada automàtica</i> s\'aplicarà als nous episodis.\nVols que també sigui aplicat als episodis publicats prèviament?</string>
+ <string name="auto_delete_label">Esborrar episodi automàticament</string>
<string name="parallel_downloads_suffix">\u0020baixades paral·leles</string>
<string name="feed_auto_download_always">Sempre</string>
<string name="feed_auto_download_never">Mai</string>
@@ -92,13 +93,17 @@
<string name="mark_all_read_confirmation_msg">Si us plau confirma que vols marcar tots els episodis com reproduits.</string>
<string name="mark_all_read_feed_confirmation_msg">Si us plau confirma que vols marcar tots els episodis d\'aquest canal com reproduits.</string>
<string name="mark_all_seen_label">Marca tot com a llegit</string>
+ <string name="mark_all_seen_msg">S\'han marcat tots els episodis com a vistos</string>
+ <string name="mark_all_seen_confirmation_msg">Si us plau confirma que vols marcar tots els episodis com vistos.</string>
<string name="show_info_label">Mostra informació</string>
+ <string name="rename_feed_label">Renombra podcast</string>
<string name="remove_feed_label">Esborra podcast</string>
<string name="share_label">Compartir...</string>
<string name="share_link_label">Comparteix l\'enllaç</string>
<string name="share_link_with_position_label">Comparteix enllaç amb posició</string>
<string name="share_feed_url_label">Comparteix adreça del canal</string>
- <string name="feed_delete_confirmation_msg">Confirmeu que, efectivament, voleu suprimir aquest canal i tots els episodis que us n\'heu baixat.</string>
+ <string name="share_item_url_label">Comparteix adreça del fitxer del canal</string>
+ <string name="share_item_url_with_position_label">Comparteix adreça del fitxer del canal amb posició</string>
<string name="feed_remover_msg">S\'està esborrant el canal</string>
<string name="load_complete_feed">S\'ha actualitzat el canal</string>
<string name="hide_episodes_title">Amaga Episodis</string>
@@ -110,8 +115,10 @@
<string name="hide_not_queued_episodes_label">No en cua</string>
<string name="hide_downloaded_episodes_label">Baixat</string>
<string name="hide_not_downloaded_episodes_label">No baixat</string>
+ <string name="hide_has_media_label">Conté medis</string>
<string name="filtered_label">Filtrat</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Darrera actualització fallida</string>
+ <string name="open_podcast">Obrir podcast</string>
<!--actions on feeditems-->
<string name="download_label">Baixa</string>
<string name="play_label">Reprodueix</string>
@@ -119,7 +126,9 @@
<string name="stop_label">Atura</string>
<string name="stream_label">Reprodueix sense baixar</string>
<string name="remove_label">Suprimeix</string>
+ <string name="delete_label">Esborrar</string>
<string name="remove_episode_lable">Esborra episodi</string>
+ <string name="marked_as_seen_label">Marcat com a vist</string>
<string name="mark_read_label">Marca com a llegit</string>
<string name="marked_as_read_label">Marcats com llegits</string>
<string name="mark_unread_label">Marca com a pendent</string>
@@ -152,6 +161,8 @@
<string name="download_error_connection_error">Error de connexió</string>
<string name="download_error_unknown_host">Amfitrió desconegut</string>
<string name="download_error_unauthorized">Error d\'autenticació</string>
+ <string name="download_error_file_type_type">Error de tipus de fitxer</string>
+ <string name="download_error_forbidden">Prohibit</string>
<string name="cancel_all_downloads_label">Cancel·la totes les baixades</string>
<string name="download_canceled_msg">S\'ha cancel·lat la baixada</string>
<string name="download_canceled_autodownload_enabled_msg">Baixada cancel·lada\nDesactivada les <i>baixades automàtiques</i> per aquest element</string>
@@ -205,6 +216,8 @@
<string name="sort">Ordena</string>
<string name="date">Data</string>
<string name="duration">Durada</string>
+ <string name="episode_title">Títol de l\'episodi</string>
+ <string name="feed_title">Títol del feed</string>
<string name="ascending">Ascendent</string>
<string name="descending">Descendent</string>
<string name="clear_queue_confirmation_msg">Si us plau confirma que vols suprimir tots els episodis de la cua</string>
@@ -255,13 +268,11 @@
<string name="pref_pauseOnDisconnect_sum">Pausa la reproducció en desconnectar els auriculars o el bluetooth</string>
<string name="pref_unpauseOnHeadsetReconnect_sum">Continua la reproducció en connectar novament els auriculars</string>
<string name="pref_unpauseOnBluetoothReconnect_sum">Continua la reproducció en connectar novament el bluetooth</string>
- <string name="pref_hardwareForwardButtonSkips_title">Botó \'Endavant\' passa al següent</string>
<string name="pref_hardwareForwardButtonSkips_sum">Al prémer el botó de hardware \'Endavant\' passar al següent episodi en comptes d\'avançar a la reproducció</string>
<string name="pref_followQueue_sum">Salta al següent element de la cua en acabar la reproducció</string>
<string name="pref_auto_delete_sum">Suprimeix l\'episodi quan s\'acabi de reproduir</string>
<string name="pref_auto_delete_title">Esborrat automàtic</string>
<string name="pref_smart_mark_as_played_sum">Marca episodis com com reproduits, encara que quedi menys d\'una certa quantitat de segons de temps</string>
- <string name="pref_smart_mark_as_played_title">Marcació intel·ligent com a reproduit</string>
<string name="pref_skip_keeps_episodes_sum">Mantenir episodis quan són passats de llarg</string>
<string name="pref_skip_keeps_episodes_title">Mantenir els episodis passats de llarg</string>
<string name="playback_pref">Reproducció</string>
@@ -325,8 +336,6 @@
<string name="pref_gpodnet_setlogin_information_sum">Canvia les dades d\'inici de sessió del vostre compte de gpodder.net</string>
<string name="pref_playback_speed_title">Velocitats de reproducció</string>
<string name="pref_playback_speed_sum">Personalitzeu les velocitats disponibles per a una velocitat de reproducció d\'àudio variable</string>
- <string name="pref_fast_forward">Temps d\'avançada ràpida</string>
- <string name="pref_rewind">Temps de rebobinat</string>
<string name="pref_gpodnet_sethostname_title">Definex nom del servidor</string>
<string name="pref_gpodnet_sethostname_use_default_host">Utilitza el servidor per defecte</string>
<string name="pref_expandNotify_title">Amplia la notificació</string>
@@ -347,7 +356,6 @@
<string name="crash_report_sum">Enviar l\'últim report de tancament abrupte per e-mail</string>
<string name="send_email">Envia e-mail</string>
<string name="experimental_pref">Experimental</string>
- <string name="pref_sonic_title">Reproductor multimèdia Sonic</string>
<string name="pref_sonic_message">Fer servir el reproductor Sonic Media integrat en comptes del reproductor natiu d\'Android i Prestissimo</string>
<string name="pref_current_value">Valor actual: %1$s</string>
<!--Auto-Flattr dialog-->
@@ -527,5 +535,9 @@
<string name="sonic_only">Només Sonic</string>
<!--proxy settings-->
<!--Casting-->
+ <string name="cast_failed_to_play">Error en començar la reproducció del medi</string>
+ <string name="cast_failed_to_stop">Error en aturar la reproducció del medi</string>
+ <string name="cast_failed_to_pause">Error en pausar la reproducció del medi</string>
<!--<string name="cast_failed_to_connect">Could not connect to the device</string>-->
+ <string name="cast_failed_setting_volume">Error al establir el volum</string>
</resources>
diff --git a/core/src/main/res/values-cs-rCZ/strings.xml b/core/src/main/res/values-cs-rCZ/strings.xml
index d91492b2d..9eb2ccb7f 100644
--- a/core/src/main/res/values-cs-rCZ/strings.xml
+++ b/core/src/main/res/values-cs-rCZ/strings.xml
@@ -36,6 +36,7 @@
<string name="drawer_feed_counter_new_unplayed">Počet nových a nepřehraných epizod</string>
<string name="drawer_feed_counter_new">Počet nových epizod</string>
<string name="drawer_feed_counter_unplayed">Počet nepřehraných epizod</string>
+ <string name="drawer_feed_counter_downloaded">Počet stažených epizod</string>
<string name="drawer_feed_counter_none">Žádné</string>
<!--Webview actions-->
<string name="open_in_browser_label">Otevřít v prohlížeči</string>
@@ -51,6 +52,7 @@
<string name="yes">Ano</string>
<string name="no">Ne
</string>
+ <string name="reset">Reset</string>
<string name="author_label">Autor</string>
<string name="language_label">Jazyk</string>
<string name="url_label">URL</string>
@@ -94,14 +96,18 @@
<string name="etxtFeedurlHint">URL nebo webová stránka kanálu</string>
<string name="txtvfeedurl_label">Přidat podcast pomocí URL</string>
<string name="podcastdirectories_label">Najít podcast v seznamu</string>
+ <string name="podcastdirectories_descr">Nové podcasty můžete hledat pomocí iTunes nebo fyyd, nebo hledat na gpodder.net podle jména, kategorie či popularity.</string>
<string name="browse_gpoddernet_label">Prohledávat gpodder.net</string>
<!--Actions on feeds-->
<string name="mark_all_read_label">Označit vše jako poslechnuté</string>
<string name="mark_all_read_msg">Všechny epizody označeny jako poslechnuté</string>
- <string name="mark_all_read_confirmation_msg">Prosím potvrďte, že chcete označit všechny vybrané epizody jako poslechnuté.</string>
- <string name="mark_all_read_feed_confirmation_msg">Prosím potvrďte, že chcete označit všechny epizody z tohoto zdroje jako poslechnuté.</string>
+ <string name="mark_all_read_confirmation_msg">Potvrďte prosím, že chcete označit všechny vybrané epizody jako poslechnuté.</string>
+ <string name="mark_all_read_feed_confirmation_msg">Potvrďte prosím, že chcete označit všechny epizody z tohoto zdroje jako poslechnuté.</string>
<string name="mark_all_seen_label">Označit vše jako zobrazené</string>
+ <string name="mark_all_seen_msg">Označit všechny epizody jako shlédnuté</string>
+ <string name="mark_all_seen_confirmation_msg">Potvrďte prosím, že chcete označit všechny epizody jako shlédnuté.</string>
<string name="show_info_label">Informace o zdroji</string>
+ <string name="rename_feed_label">Přejmenovat podcast</string>
<string name="remove_feed_label">Odstranit podcast</string>
<string name="share_label">Sdílet</string>
<string name="share_link_label">Sdílet odkaz</string>
@@ -109,7 +115,6 @@
<string name="share_feed_url_label">Sdílet URL kanálu</string>
<string name="share_item_url_label">Sdílet URL souboru epizody</string>
<string name="share_item_url_with_position_label">Sdílet URL souboru epizody s pozicí</string>
- <string name="feed_delete_confirmation_msg">Prosím potvrďte, že chcete smazat tento kanál včetně všech stažených epizod.</string>
<string name="feed_remover_msg">Odstranit kanál</string>
<string name="load_complete_feed">Obnovit kompletní kanál</string>
<string name="hide_episodes_title">Skrýt epizody</string>
@@ -121,6 +126,7 @@
<string name="hide_not_queued_episodes_label">Mimo frontu</string>
<string name="hide_downloaded_episodes_label">Stažené</string>
<string name="hide_not_downloaded_episodes_label">Nestažené</string>
+ <string name="hide_has_media_label">Obsahuje média</string>
<string name="filtered_label">Filtrované</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Poslední aktualizace selhala</string>
<string name="open_podcast">Otevřít podcast</string>
@@ -131,6 +137,7 @@
<string name="stop_label">Zastavit</string>
<string name="stream_label">Vysílat</string>
<string name="remove_label">Odstranit</string>
+ <string name="delete_label">Smazat</string>
<string name="remove_episode_lable">Odstranit epizodu</string>
<string name="marked_as_seen_label">Označit jako shlédnuté</string>
<string name="mark_read_label">Označit jako poslechnuté</string>
@@ -225,7 +232,7 @@
<string name="feed_title">Název kanálu</string>
<string name="ascending">Vzestupně</string>
<string name="descending">Sestupně</string>
- <string name="clear_queue_confirmation_msg">Prosím potvrďte, že chcete vyčistit tuto frontu a VŠECHNY v ní obsažené epizody</string>
+ <string name="clear_queue_confirmation_msg">Potvrďte prosím, že chcete vyčistit tuto frontu a VŠECHNY v ní obsažené epizody</string>
<!--Flattr-->
<string name="flattr_auth_label">Flattr přihlášení</string>
<string name="flattr_auth_explanation">Stiskněte následující tlačítko pro spuštění autentizačního procesu. Budete přesměrováni na přihlašovací obrazovku flattru a vyzváni k potvrzení udělení práv pro použití flattru aplikací AntennaPod. Po udělení práv se automaticky vrátíte na tuto obrazovku.</string>
@@ -276,13 +283,13 @@
<string name="pref_pauseOnDisconnect_sum">Při odpojení sluchátek nebo bluetooth připojení pozastavit přehrávání.</string>
<string name="pref_unpauseOnHeadsetReconnect_sum">Pokračovat v přehrávání po připojení sluchátek</string>
<string name="pref_unpauseOnBluetoothReconnect_sum">Pokračovat v přehrávání po připojení bluetooth</string>
- <string name="pref_hardwareForwardButtonSkips_title">Přeskočit tlačítkem vpřed</string>
<string name="pref_hardwareForwardButtonSkips_sum">Po stlačení hardwarového tlačítka pro posun vpřed místo přetočení vpřed přeskočit na další epizodu</string>
+ <string name="pref_hardwarePreviousButtonRestarts_title">Tlačítko zpět restartuje</string>
+ <string name="pref_hardwarePreviousButtonRestarts_sum">Po stlačení hardwarového tlačítka pro posun zpět místo přetočení vpřed restartovat přehrávání aktuální epizody</string>
<string name="pref_followQueue_sum">Po přehrání položky z fronty přejít automaticky na další</string>
<string name="pref_auto_delete_sum">Smazat díl po jeho přehrání</string>
<string name="pref_auto_delete_title">Automatické mazání</string>
<string name="pref_smart_mark_as_played_sum">Označit epizody jako poslechnuté i pokud ještě zbývá určitý počet sekund přehrávání do jejich konce</string>
- <string name="pref_smart_mark_as_played_title">Chytré označování jako poslechnuté</string>
<string name="pref_skip_keeps_episodes_sum">Neodstraňovat epizody při jejich přeskočení</string>
<string name="pref_skip_keeps_episodes_title">Nemazat přeskočené epizody</string>
<string name="playback_pref">Přehrávání</string>
@@ -344,12 +351,18 @@
<string name="pref_gpodnet_logout_toast">Úspěšně odhlášeno</string>
<string name="pref_gpodnet_setlogin_information_title">Změna přihlašovacích údajů</string>
<string name="pref_gpodnet_setlogin_information_sum">Změní přihlašovací údaje k vašemu gpodder.net účtu.</string>
+ <string name="pref_gpodnet_sync_changes_title">Synchronizovat změny</string>
+ <string name="pref_gpodnet_sync_changes_sum">Synchronizovat odběr a změny stavu epizody s gpodder.net.</string>
+ <string name="pref_gpodnet_full_sync_title">Plná synchronizace</string>
+ <string name="pref_gpodnet_full_sync_sum">Synchronizovat všechny odběry a stav epizod s gpodder.net.</string>
+ <string name="pref_gpodnet_sync_sum_last_sync_line">Poslední pokus o synchronizaci: %1$s (%2$s)</string>
<string name="pref_gpodnet_sync_started">Synchronizace spuštěna</string>
+ <string name="pref_gpodnet_full_sync_started">Spuštěna plná synchronizace</string>
<string name="pref_gpodnet_login_status"><![CDATA[Přihlášen jako <i>%1$s</i> z přístroje <i>%2$s</i>]]></string>
+ <string name="pref_gpodnet_notifications_title">Zobrazovat upozornění na chyby synchronizace</string>
+ <string name="pref_gpodnet_notifications_sum">Toto nastavení se netýká chyb přihlášení.</string>
<string name="pref_playback_speed_title">Rychlosti přehrávání</string>
<string name="pref_playback_speed_sum">Přizpůsobení rychlosti je dostupné pro přehrávání zvuku různými rychlostmi</string>
- <string name="pref_fast_forward">Čas rychlého posunu</string>
- <string name="pref_rewind">Čas přetočení</string>
<string name="pref_gpodnet_sethostname_title">Nastavit hostname</string>
<string name="pref_gpodnet_sethostname_use_default_host">Použít přednastaveného hosta</string>
<string name="pref_expandNotify_title">Rozšířené upozornění</string>
@@ -374,7 +387,6 @@
<string name="crash_report_sum">Odesílat hlášení o posledním pádu aplikace emailem</string>
<string name="send_email">Poslat email</string>
<string name="experimental_pref">Experimentální</string>
- <string name="pref_sonic_title">Přehrávač médií Sonic</string>
<string name="pref_sonic_message">Použít připojený sonic media player jako náhradu za výchozí přehrávač médií pro Android a Prestissimo</string>
<string name="pref_current_value">Aktuální hodnota: %1$s</string>
<string name="pref_proxy_title">Proxy</string>
@@ -391,10 +403,13 @@
<string name="auto_flattr_ater_beginning">Flattrovat díl po začátku přehrávání</string>
<string name="auto_flattr_ater_end">Flattrovat díl po konci přehrávání</string>
<!--Search-->
+ <string name="search_hint">Hledat epizody</string>
+ <string name="found_in_shownotes_label">Nalezeno v poznámkách pořadu</string>
<string name="found_in_chapters_label">Nalezeno v kapitolách</string>
<string name="search_status_no_results">Žádné výsledky</string>
<string name="search_label">Vyhledat</string>
<string name="found_in_title_label">Nalezeno v názvu</string>
+ <string name="no_results_for_query">Nebyly nalezeny žádné výsledky pro \"%1$s\"</string>
<!--OPML import and export-->
<string name="opml_import_txtv_button_lable">OPML soubory umožňují přenést vaše podcasty z jednoho přehrávače na jiný.</string>
<string name="opml_import_option">Možnost %1$d</string>
@@ -413,6 +428,7 @@
<string name="choose_file_from_filesystem">Z místního souborového systému</string>
<string name="choose_file_from_external_application">Použít externí aplikaci</string>
<string name="opml_export_label">OPML export</string>
+ <string name="html_export_label">HTML export</string>
<string name="exporting_label">Export</string>
<string name="export_error_label">Chyba exportu</string>
<string name="opml_export_success_title">OPML export byl úspěšný.</string>
@@ -446,6 +462,9 @@
<item quantity="few">%d hodiny</item>
<item quantity="other">%d hodin</item>
</plurals>
+ <string name="auto_enable_label">Automaticky zapnout</string>
+ <string name="sleep_timer_enabled_label">Časovač vypnutí povolen</string>
+ <string name="sleep_timer_disabled_label">Časovač vypnutí zakázán</string>
<!--gpodder.net-->
<string name="gpodnet_taglist_header">KATEGORIE</string>
<string name="gpodnet_toplist_header">TOP PODCASTY</string>
@@ -475,6 +494,8 @@
<string name="gpodnetsync_auth_error_descr">Špatné přihlašovací jméno nebo heslo</string>
<string name="gpodnetsync_error_title">gpodder.net synchronizace selhala</string>
<string name="gpodnetsync_error_descr">V průběhu synchronizace nastala chyba:\u0020</string>
+ <string name="gpodnetsync_pref_report_successful">Úspěšné</string>
+ <string name="gpodnetsync_pref_report_failed">Selhalo</string>
<!--Directory chooser-->
<string name="selected_folder_label">Vybraný adresář:</string>
<string name="create_folder_label">Vytvořit adresář</string>
@@ -527,6 +548,7 @@
<string name="sp_apps_importing_feeds_msg">Importuji odběry z jednoúčelových aplikací...</string>
<string name="search_itunes_label">Prohledat iTunes</string>
<string name="filter">Filtr</string>
+ <string name="search_fyyd_label">Prohledat fyyd</string>
<!--Episodes apply actions-->
<string name="all_label">Vše</string>
<string name="selected_all_label">Vybrány všechny epizody</string>
@@ -544,6 +566,8 @@
<string name="selected_queued_label">Vybrané epizody ve frontě</string>
<string name="not_queued_label">Mimo frontu</string>
<string name="selected_not_queued_label">Vybrané epizody mimo frontu</string>
+ <string name="has_media">Obsahuje média</string>
+ <string name="selected_has_media_label">Vybrané epizody s médii</string>
<!--Sort-->
<string name="sort_title_a_z">Názvu (A \u2192 Z)</string>
<string name="sort_title_z_a">Názvu (Z \u2192 A)</string>
diff --git a/core/src/main/res/values-da/strings.xml b/core/src/main/res/values-da/strings.xml
index fdf1a9504..d553f1ddb 100644
--- a/core/src/main/res/values-da/strings.xml
+++ b/core/src/main/res/values-da/strings.xml
@@ -61,7 +61,6 @@
<string name="show_info_label">Vis information</string>
<string name="remove_feed_label">Fjern podcast</string>
<string name="share_link_label">Del webside link</string>
- <string name="feed_delete_confirmation_msg">Bekræft venligst at du vil fjerne dette feed og ALLE episoder du har downloadet fra dette feed.</string>
<string name="feed_remover_msg">Fjerner feed</string>
<string name="load_complete_feed">Opdater hele feed\'et</string>
<!--actions on feeditems-->
diff --git a/core/src/main/res/values-de/strings.xml b/core/src/main/res/values-de/strings.xml
index 4c5a8f1be..c7da72961 100644
--- a/core/src/main/res/values-de/strings.xml
+++ b/core/src/main/res/values-de/strings.xml
@@ -26,21 +26,27 @@
<!--Statistics fragment-->
<string name="total_time_listened_to_podcasts">Gesamtzeit gespielter Podcasts:</string>
<string name="statistics_details_dialog">%1$d von %2$d Episoden gestartet.\n\n%3$s von %4$s Episoden gespielt.</string>
+ <string name="statistics_mode">Statistik-Modus</string>
+ <string name="statistics_mode_normal">Berechne die tatsächlich gespielte Dauer. Zweimaliges Abspielen wird auch zwei Mal gezählt, als gespielt markierte Episoden jedoch gar nicht</string>
+ <string name="statistics_mode_count_all">Aufsummieren aller als gespielt markierter Episoden</string>
+ <string name="statistics_speed_not_counted">Hinweis: Die Abspielgeschwindigkeit wird nicht berücksichtigt.</string>
<!--Main activity-->
<string name="drawer_open">Menü öffnen</string>
<string name="drawer_close">Menü schließen</string>
<string name="drawer_preferences">Seitenleisten-Einstellungen</string>
- <string name="drawer_feed_order_unplayed_episodes">Sortieren nach Zähler</string>
+ <string name="drawer_feed_order_unplayed_episodes">Nach Zähler sortieren </string>
<string name="drawer_feed_order_alphabetical">Alphabetisch sortieren</string>
- <string name="drawer_feed_order_last_update">Sortiere nach Veröffentlichungsdatum</string>
+ <string name="drawer_feed_order_last_update">Nach Veröffentlichungsdatum sortieren</string>
+ <string name="drawer_feed_order_most_played">Nach Anzahl gespielter Episoden sortieren</string>
<string name="drawer_feed_counter_new_unplayed">Anzahl neuer und ungespielter Episoden</string>
<string name="drawer_feed_counter_new">Anzahl neuer Episoden</string>
<string name="drawer_feed_counter_unplayed">Anzahl ungespielter Episoden</string>
+ <string name="drawer_feed_counter_downloaded">Anzahl heruntergeladener Episoden</string>
<string name="drawer_feed_counter_none">Keine</string>
<!--Webview actions-->
<string name="open_in_browser_label">Im Browser öffnen</string>
<string name="copy_url_label">URL kopieren</string>
- <string name="share_url_label">URL teilen</string>
+ <string name="share_url_label">Teile URL</string>
<string name="copied_url_msg">URL wurde in die Zwischenablage kopiert.</string>
<string name="go_to_position_label">Gehe zu dieser Position</string>
<!--Playback history-->
@@ -50,6 +56,7 @@
<string name="cancel_label">Abbrechen</string>
<string name="yes">Ja</string>
<string name="no">Nein</string>
+ <string name="reset">Reset</string>
<string name="author_label">Autor</string>
<string name="language_label">Sprache</string>
<string name="url_label">URL</string>
@@ -60,7 +67,8 @@
<string name="refresh_label">Aktualisieren</string>
<string name="external_storage_error_msg">Der externe Speicher ist nicht verfügbar. Bitte stelle sicher, dass das externe Speichermedium eingelegt ist, damit die Anwendung funktioniert.</string>
<string name="chapters_label">Kapitel</string>
- <string name="shownotes_label">Notizen</string>
+ <string name="chapter_duration">Dauer: %1$s</string>
+ <string name="shownotes_label">Shownotizen</string>
<string name="description_label">Beschreibung</string>
<string name="most_recent_prefix">Letzte Episode:\u0020</string>
<string name="episodes_suffix">\u0020Episoden</string>
@@ -82,7 +90,7 @@
<string name="send_label">Senden…</string>
<string name="episode_cleanup_never">Nie</string>
<string name="episode_cleanup_queue_removal">Wenn nicht in der Abspielliste</string>
- <string name="episode_cleanup_after_listening">wenn fertig gespielt gespielt</string>
+ <string name="episode_cleanup_after_listening">Wenn fertig gespielt</string>
<plurals name="episode_cleanup_days_after_listening">
<item quantity="one">1 Tag nachdem fertig gespielt</item>
<item quantity="other">%d Tage nachdem fertig gespielt</item>
@@ -92,22 +100,26 @@
<string name="etxtFeedurlHint">URL des Feeds oder der Webseite</string>
<string name="txtvfeedurl_label">Podcast per URL hinzufügen</string>
<string name="podcastdirectories_label">Podcast in Verzeichnis finden</string>
+ <string name="podcastdirectories_descr">Für neue Podcasts kannst du iTunes oder fyyd durchsuchen, oder gpodder.net nach Name, Kategorie oder Popularität durchstöbern</string>
<string name="browse_gpoddernet_label">gpodder.net durchsuchen</string>
<!--Actions on feeds-->
<string name="mark_all_read_label">Alle als gespielt markieren</string>
- <string name="mark_all_read_msg">Alle Episoden als gespielt markieren</string>
+ <string name="mark_all_read_msg">Alle Episoden als gespielt markiert</string>
<string name="mark_all_read_confirmation_msg">Bitte bestätige, dass alle Episoden als gespielt markiert werden sollen.</string>
<string name="mark_all_read_feed_confirmation_msg">Bitte bestätige, dass alle Episoden in diesem Feed als gespielt markiert werden sollen.</string>
<string name="mark_all_seen_label">Alle als gesehen markieren</string>
+ <string name="mark_all_seen_msg">Alle Episoden als gesehen markiert</string>
+ <string name="mark_all_seen_confirmation_msg">Bitte bestätige, dass alle Episoden als gesehen markiert werden sollen.</string>
<string name="show_info_label">Informationen anzeigen</string>
+ <string name="rename_feed_label">Podcast umbenennen</string>
<string name="remove_feed_label">Podcast entfernen</string>
<string name="share_label">Teilen…</string>
- <string name="share_link_label">Webseiten-Link teilen</string>
+ <string name="share_link_label">Teile Link</string>
<string name="share_link_with_position_label">Teile Link mit Zeitmarke</string>
<string name="share_feed_url_label">Teile URL des Podcasts</string>
- <string name="share_item_url_label">URL zur Datei teilen</string>
- <string name="share_item_url_with_position_label">URL zur Datei und Zeitmarke teilen</string>
- <string name="feed_delete_confirmation_msg">Bitte bestätige, dass du diesen Feed und ALLE heruntergeladenen Episoden dieses Feeds entfernen möchtest.</string>
+ <string name="share_item_url_label">Teile URL der Episode</string>
+ <string name="share_item_url_with_position_label">Teile URL der Episode mit Zeitmarke</string>
+ <string name="feed_delete_confirmation_msg">Bitte bestätige, dass du den Feed \"%1$s\" und ALLE heruntergeladenen Episoden löschen möchtest.</string>
<string name="feed_remover_msg">Entferne Feed</string>
<string name="load_complete_feed">Kompletten Feed aktualisieren</string>
<string name="hide_episodes_title">Episoden verbergen</string>
@@ -119,9 +131,10 @@
<string name="hide_not_queued_episodes_label">Nicht in Abspielliste</string>
<string name="hide_downloaded_episodes_label">Heruntergeladen</string>
<string name="hide_not_downloaded_episodes_label">Nicht heruntergeladen</string>
+ <string name="hide_has_media_label">Hat Medien</string>
<string name="filtered_label">Gefiltert</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Aktualisierung fehlgeschlagen</string>
- <string name="open_podcast">Öffne Podcast</string>
+ <string name="open_podcast">Podcast öffnen</string>
<!--actions on feeditems-->
<string name="download_label">Herunterladen</string>
<string name="play_label">Abspielen</string>
@@ -129,6 +142,7 @@
<string name="stop_label">Stop</string>
<string name="stream_label">Streamen</string>
<string name="remove_label">Entfernen</string>
+ <string name="delete_label">Löschen</string>
<string name="remove_episode_lable">Episode entfernen</string>
<string name="marked_as_seen_label">Als gesehen markiert</string>
<string name="mark_read_label">Als gespielt markieren</string>
@@ -222,7 +236,7 @@
<string name="feed_title">Podcastname</string>
<string name="ascending">Aufsteigend</string>
<string name="descending">Absteigend</string>
- <string name="clear_queue_confirmation_msg">Bitte bestätige, dass alle Episoden in der Warteschlange gelöscht werden sollen</string>
+ <string name="clear_queue_confirmation_msg">Bitte bestätige, dass ALLE Episoden aus der Abspielliste entfernt werden sollen</string>
<!--Flattr-->
<string name="flattr_auth_label">Flattr Anmeldung</string>
<string name="flattr_auth_explanation">Drücke den Button unten, um den Authentifizierungsprozess zu starten. Du wirst zur Flattr-Anmeldeseite weitergeleitet. Hier wirst du gefragt, AntennaPod die Erlaubnis zu geben, Dinge zu flattrn. Nachdem du die Erlaubnis erteilt hast, kehrst du automatisch zu diesem Bildschirm zurück.</string>
@@ -259,7 +273,7 @@
<string name="no_items_label">Es sind keine Einträge in dieser Liste.</string>
<string name="no_feeds_label">Du hast noch keine Feeds abonniert.</string>
<string name="no_chapters_label">Diese Episode hat keine Kapitel.</string>
- <string name="no_shownotes_label">Episode hat keine Shownotes.</string>
+ <string name="no_shownotes_label">Episode hat keine Shownotizen.</string>
<!--Preferences-->
<string name="storage_pref">Speicher</string>
<string name="project_pref">Projekt</string>
@@ -269,17 +283,19 @@
<string name="services_label">Dienste</string>
<string name="flattr_label">Flattr</string>
<string name="pref_episode_cleanup_title">Automatisches Löschen</string>
- <string name="pref_episode_cleanup_summary">Episoden, die weder in Abspielliste noch favorisiert sind, können gelöscht werden, wenn beim automatischen Herunterladen Speicherplatz für neue Episoden gebraucht wird</string>
+ <string name="pref_episode_cleanup_summary">Episoden, die weder in der Abspielliste noch Favoriten sind, können gelöscht werden, wenn beim automatischen Herunterladen Speicherplatz für neue Episoden gebraucht wird</string>
<string name="pref_pauseOnDisconnect_sum">Wiedergabe pausieren, wenn Kopfhörer ausgesteckt oder Bluetooth getrennt wird</string>
<string name="pref_unpauseOnHeadsetReconnect_sum">Wiedergabe fortsetzen, wenn Kopfhörer wieder eingesteckt werden</string>
<string name="pref_unpauseOnBluetoothReconnect_sum">Wiedergabe fortsetzen, wenn Bluetooth wieder verbunden ist</string>
- <string name="pref_hardwareForwardButtonSkips_title">Nächster-Taste überspringt</string>
- <string name="pref_hardwareForwardButtonSkips_sum">Springe zur nächsten Episode (statt Vorspulen), wenn die \"Nächster\"-Taste gedrückt wird</string>
- <string name="pref_followQueue_sum">Springe zur nächsten Episode, wenn die vorherige Episode endet</string>
+ <string name="pref_hardwareForwardButtonSkips_title">\"Nächster\"-Taste springt zur nächsten Episode</string>
+ <string name="pref_hardwareForwardButtonSkips_sum">Zur nächsten Episode springen, wenn die \"Nächster\"-Taste gedrückt wird (statt vorzuspulen)</string>
+ <string name="pref_hardwarePreviousButtonRestarts_title">Vorheriger-Taste startet neu</string>
+ <string name="pref_hardwarePreviousButtonRestarts_sum">Die Wiedergabe der aktuellen Episode neu starten, wenn die \"Vorheriger\"-Taste gedrückt wird (statt zurückzuspulen)</string>
+ <string name="pref_followQueue_sum">Springe zur nächsten Episode in der Abspielliste, wenn die Wiedergabe endet</string>
<string name="pref_auto_delete_sum">Episode löschen, wenn die Wiedergabe endet</string>
<string name="pref_auto_delete_title">Automatisches Löschen</string>
- <string name="pref_smart_mark_as_played_sum">Episoden werden als gespielt markiert, wenn weniger als eine bestimmte Anzahl Sekunden Restspielzeit übrig sind</string>
- <string name="pref_smart_mark_as_played_title">Schlaues als gespielt markieren</string>
+ <string name="pref_smart_mark_as_played_sum">Episoden werden bereits als gespielt markiert, wenn weniger als eine bestimmte Anzahl Sekunden Restspielzeit übrig sind</string>
+ <string name="pref_smart_mark_as_played_title">Schlau als gespielt markieren</string>
<string name="pref_skip_keeps_episodes_sum">Behalte Episoden beim Überspringen</string>
<string name="pref_skip_keeps_episodes_title">Behalte übersprungene Episoden</string>
<string name="playback_pref">Wiedergabe</string>
@@ -341,12 +357,22 @@
<string name="pref_gpodnet_logout_toast">Abmeldung war erfolgreich</string>
<string name="pref_gpodnet_setlogin_information_title">Anmeldeinformationen ändern</string>
<string name="pref_gpodnet_setlogin_information_sum">Ändere die Anmeldeinformationen deines gpodder.net Profils</string>
+ <string name="pref_gpodnet_sync_changes_title">Jetzt Änderungen synchronisieren</string>
+ <string name="pref_gpodnet_sync_changes_sum">Änderungen an Abonnement- und Episoden-Status mit gpodder.net synchronisieren.</string>
+ <string name="pref_gpodnet_full_sync_title">Jetzt komplett synchronisieren</string>
+ <string name="pref_gpodnet_full_sync_sum">Kompletten Abonnement- und Episoden-Status mit gpodder.net synchronisieren.</string>
+ <string name="pref_gpodnet_sync_sum_last_sync_line">Letzter Synchronisierungsversuch: %1$s (%2$s)</string>
<string name="pref_gpodnet_sync_started">Synchronisation starten</string>
+ <string name="pref_gpodnet_full_sync_started">Komplette Synchronisierung gestartet</string>
<string name="pref_gpodnet_login_status"><![CDATA[Eingeloggt als <i>%1$s</i> mit dem Gerät <i>%2$s</i>]]></string>
+ <string name="pref_gpodnet_notifications_title">Zeige Benachrichtungen bei Synchronisierungsfehlern</string>
+ <string name="pref_gpodnet_notifications_sum">Diese Einstellung gilt nicht für Authentifizierungsfehler.</string>
<string name="pref_playback_speed_title">Wiedergabegeschwindigkeiten</string>
<string name="pref_playback_speed_sum">Lege die verfügbaren Werte für die Veränderung der Wiedergabeschwindigkeit fest</string>
<string name="pref_fast_forward">Vorspulzeit</string>
+ <string name="pref_fast_forward_sum">Passe an, wie viele Sekunden vorgespult wird, wenn die entsprechende Hardware-Taste gedrückt wird</string>
<string name="pref_rewind">Rückspulzeit</string>
+ <string name="pref_rewind_sum">Passe an, wie viele Sekunden zurückgespult wird, wenn die entsprechende Hardware-Taste gedrückt wird</string>
<string name="pref_gpodnet_sethostname_title">Hostname ändern</string>
<string name="pref_gpodnet_sethostname_use_default_host">Standard-Host verwenden</string>
<string name="pref_expandNotify_title">Benachrichtigung erweitern</string>
@@ -362,8 +388,8 @@
<string name="pref_showDownloadReport_title">Zeige Download-Bericht</string>
<string name="pref_showDownloadReport_sum">Wenn Downloads fehlschlagen, erstelle einen Bericht, der die Details des Fehlschlages beschreibt.</string>
<string name="pref_expand_notify_unsupport_toast">Android-Versionen vor 4.1 unterstützen keine erweiterten Benachrichtigungen.</string>
- <string name="pref_queueAddToFront_sum">Fügen Sie neue Folgen auf den Anfang der Warteschlange.</string>
- <string name="pref_queueAddToFront_title">Vorne in Abspielliste einreihen</string>
+ <string name="pref_queueAddToFront_sum">Neue Folgen zum Anfang der Abspielliste hinzufügen.</string>
+ <string name="pref_queueAddToFront_title">Zum Anfang der Abspielliste hinzufügen</string>
<string name="pref_smart_mark_as_played_disabled">Deaktiviert</string>
<string name="pref_image_cache_size_title">Größe des Bilder-Zwischenspeichers</string>
<string name="pref_image_cache_size_sum">Größe des Zwischenspeichers für Bilder</string>
@@ -371,7 +397,7 @@
<string name="crash_report_sum">Sende den aktuellen Absturzbericht per E-Mail</string>
<string name="send_email">E-Mail senden</string>
<string name="experimental_pref">Experimentell</string>
- <string name="pref_sonic_title">Sonic Mediaplayer</string>
+ <string name="pref_sonic_title">Sonic Media Player</string>
<string name="pref_sonic_message">Benutze den integrierten Sonic Mediaplayer als Ersatz für Androids eigenen Mediaplayer und Prestissimo</string>
<string name="pref_current_value">Aktueller Wert: %1$s</string>
<string name="pref_proxy_title">Proxy</string>
@@ -382,16 +408,23 @@
<string name="pref_cast_title">Chromecast-Unterstützung</string>
<string name="pref_cast_message_play_flavor">Aktiviere die Unterstützung von Cast-Geräten (Chromecast, Lautsprecher oder Android TV) zum entfernten Abspielen</string>
<string name="pref_cast_message_free_flavor">Chromecast benötigt proprietäre Bibliotheken von Drittanbietern, die in dieser Version von AntennaPod deaktiviert sind</string>
+ <string name="pref_enqueue_downloaded_title">Downloads zur Abspielliste hinzufügen</string>
+ <string name="pref_enqueue_downloaded_summary">Füge heruntergeladene Episoden zur Abspielliste hinzu</string>
<!--Auto-Flattr dialog-->
<string name="auto_flattr_enable">Automatisches Flattrn aktivieren</string>
<string name="auto_flattr_after_percent">Flattr eine Episode, sobald %d Prozent gespielt worden sind</string>
<string name="auto_flattr_ater_beginning">Flattr Episode, sobald die Wiedergabe beginnt</string>
<string name="auto_flattr_ater_end">Flattr Episode, sobald die Wiedergabe endet</string>
<!--Search-->
+ <string name="search_hint">Suche nach Episoden</string>
+ <string name="found_in_shownotes_label">In Shownotizen gefunden</string>
<string name="found_in_chapters_label">In Kapiteln gefunden</string>
+ <string name="found_in_authors_label">In Autoren gefunden</string>
+ <string name="found_in_feeds_label">In Feeds gefunden</string>
<string name="search_status_no_results">Keine Ergebnisse gefunden</string>
- <string name="search_label">Suche</string>
+ <string name="search_label">Suchen</string>
<string name="found_in_title_label">In Titel gefunden</string>
+ <string name="no_results_for_query">Es wurden keine Ergebnisse für \"%1$s\" gefunden</string>
<!--OPML import and export-->
<string name="opml_import_txtv_button_lable">Mit OPML Dateien kannst du deine Podcasts von einem Podcatcher auf einen anderen übertragen</string>
<string name="opml_import_option">Option %1$d</string>
@@ -410,21 +443,22 @@
<string name="choose_file_from_filesystem">Vom lokalen Dateisystem</string>
<string name="choose_file_from_external_application">Verwende externe Anwendung</string>
<string name="opml_export_label">OPML Export</string>
+ <string name="html_export_label">HTML Export</string>
<string name="exporting_label">Exportiere…</string>
<string name="export_error_label">Exportfehler</string>
<string name="opml_export_success_title">OPML Export erfolgreich</string>
<string name="opml_export_success_sum">Die OPML Datei wurde unter dem folgenden Pfad gespeichert:\u0020</string>
<string name="opml_import_ask_read_permission">Zugriff auf externen Speicher wird benötigt, um die OPML Datei zu lesen</string>
<!--Sleep timer-->
- <string name="set_sleeptimer_label">Schlummerfunktion</string>
+ <string name="set_sleeptimer_label">Timer einstellen</string>
<string name="disable_sleeptimer_label">Schlummerfunktion deaktivieren</string>
<string name="enter_time_here_label">Zeit eingeben</string>
<string name="sleep_timer_label">Schlummerfunktion</string>
<string name="time_left_label">Zeit übrig:\u0020</string>
<string name="time_dialog_invalid_input">Ungültige Eingabe, Zeit muss eine Ganzzahl sein</string>
- <string name="timer_about_to_expire_label"><b>Wenn der Timer gleich abläuft:</b></string>
+ <string name="timer_about_to_expire_label"><b>Kurz bevor der Timer abläuft:</b></string>
<string name="shake_to_reset_label">Timer durch Schütteln zurücksetzen</string>
- <string name="timer_vibration_label">Vibriere</string>
+ <string name="timer_vibration_label">Vibrieren</string>
<string name="time_seconds">Sekunden</string>
<string name="time_minutes">Minuten</string>
<string name="time_hours">Stunden</string>
@@ -440,6 +474,9 @@
<item quantity="one">1 Stunde</item>
<item quantity="other">%d Stunden</item>
</plurals>
+ <string name="auto_enable_label">Automatisch aktivieren</string>
+ <string name="sleep_timer_enabled_label">Schlummerfunktion aktiviert</string>
+ <string name="sleep_timer_disabled_label">Schlummerfunktion deaktiviert</string>
<!--gpodder.net-->
<string name="gpodnet_taglist_header">KATEGORIEN</string>
<string name="gpodnet_toplist_header">BESTE PODCASTS</string>
@@ -469,8 +506,10 @@
<string name="gpodnetsync_auth_error_descr">Falscher Benutzername oder falsches Passwort</string>
<string name="gpodnetsync_error_title">gpodder.net Synchronisierungsfehler</string>
<string name="gpodnetsync_error_descr">Ein Fehler ist beim Synchronisieren aufgetreten:\u0020</string>
+ <string name="gpodnetsync_pref_report_successful">Erfolgreich</string>
+ <string name="gpodnetsync_pref_report_failed">Fehlgeschlagen</string>
<!--Directory chooser-->
- <string name="selected_folder_label">Ausgewählter Ordner</string>
+ <string name="selected_folder_label">Ausgewählter Ordner:</string>
<string name="create_folder_label">Neuer Ordner</string>
<string name="choose_data_directory">Datenordner auswählen</string>
<string name="choose_data_directory_message">Bitte wähle eine Basis für deinen Datenordner. AntennaPod erstellt automatisch die richtigen Unterverzeichnisse.</string>
@@ -521,6 +560,7 @@
<string name="sp_apps_importing_feeds_msg">Importiere Abonnements aus Single-Purpose Apps</string>
<string name="search_itunes_label">iTunes durchsuchen</string>
<string name="filter">Filtern</string>
+ <string name="search_fyyd_label">fyyd durchsuchen</string>
<!--Episodes apply actions-->
<string name="all_label">Alle</string>
<string name="selected_all_label">Alle Episoden ausgewählt</string>
@@ -538,6 +578,8 @@
<string name="selected_queued_label">Episoden in Abspielliste ausgewählt</string>
<string name="not_queued_label">Nicht in Abspielliste</string>
<string name="selected_not_queued_label">Episoden nicht in Abspielliste ausgewählt</string>
+ <string name="has_media">Hat Medien</string>
+ <string name="selected_has_media_label">Episoden mit Medien ausgewählt</string>
<!--Sort-->
<string name="sort_title_a_z">Titel (A \u2192 Z)</string>
<string name="sort_title_z_a">Titel (Z \u2192 A)</string>
@@ -586,5 +628,6 @@
<string name="cast_failed_perform_action">Aktion konnte nicht ausgeführt werden</string>
<string name="cast_failed_status_request">Synchronization mit Cast-Gerät fehlgeschlagen</string>
<string name="cast_failed_seek">Spulen zur neuen Position fehlgeschlagen</string>
+ <string name="cast_failed_receiver_player_error">Es wurde ein schwerer Fehler beim Empfangsgerät festgestellt</string>
<string name="cast_failed_media_error_skipping">Fehler bei Wiedergabe. Überspringe...</string>
</resources>
diff --git a/core/src/main/res/values-el/strings.xml b/core/src/main/res/values-el/strings.xml
index c65280c71..9768efa59 100644
--- a/core/src/main/res/values-el/strings.xml
+++ b/core/src/main/res/values-el/strings.xml
@@ -68,7 +68,6 @@
<!--Actions on feeds-->
<string name="show_info_label">Εμφάνιση πληροφοριών</string>
<string name="remove_feed_label">Κατάργηση Podcast</string>
- <string name="feed_delete_confirmation_msg">Παρακαλούμε επιβεβαιώστε ότι θέλετε να διαγράφθουν αυτες οι τροφοδοσιες και όλα τα επεισόδια του υλικού αυτού που έχετε κανει λήψη.</string>
<string name="hide_episodes_title">Απόκρυψη Επεισοδίων</string>
<string name="hide_downloaded_episodes_label">Ειλημμένα</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Η Τελευταία Ανανέωση Απέτυχε</string>
diff --git a/core/src/main/res/values-es-rES/strings.xml b/core/src/main/res/values-es-rES/strings.xml
index ca8201930..f183c8028 100644
--- a/core/src/main/res/values-es-rES/strings.xml
+++ b/core/src/main/res/values-es-rES/strings.xml
@@ -2,7 +2,7 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!--Activitiy and fragment titles-->
<string name="feeds_label">Canales</string>
- <string name="add_feed_label">Añadir podcast</string>
+ <string name="add_feed_label">Añadir Podcast</string>
<string name="episodes_label">Episodios</string>
<string name="all_episodes_short_label">Todos</string>
<string name="favorite_episodes_label">Favoritos</string>
@@ -17,8 +17,8 @@
<string name="free_space_label">%1$s disponible</string>
<!--Statistics fragment-->
<!--Main activity-->
- <string name="drawer_open">Abrir menu</string>
- <string name="drawer_close">Cerrar menu</string>
+ <string name="drawer_open">Abrir menú</string>
+ <string name="drawer_close">Cerrar menú</string>
<string name="drawer_feed_order_unplayed_episodes">Ordenar por contador</string>
<string name="drawer_feed_order_alphabetical">Ordenar alfabéticamente</string>
<string name="drawer_feed_order_last_update">Ordenar por fecha de publicación</string>
@@ -80,7 +80,7 @@
<string name="show_info_label">Información del programa</string>
<string name="remove_feed_label">Eliminar podcast</string>
<string name="share_link_label">Compartir el enlace de la web</string>
- <string name="feed_delete_confirmation_msg">Confirme que quiere eliminar este canal y TODOS los episodios descargados del mismo.</string>
+ <string name="hide_queued_episodes_label">En cola</string>
<!--actions on feeditems-->
<string name="download_label">Descargar</string>
<string name="play_label">Reproducir</string>
diff --git a/core/src/main/res/values-es/strings.xml b/core/src/main/res/values-es/strings.xml
index 157627150..a40157756 100644
--- a/core/src/main/res/values-es/strings.xml
+++ b/core/src/main/res/values-es/strings.xml
@@ -113,7 +113,6 @@
<string name="share_feed_url_label">Compartir URL del canal</string>
<string name="share_item_url_label">Compartir URL del archivo del episodio</string>
<string name="share_item_url_with_position_label">Compartir URL del episodio con posición</string>
- <string name="feed_delete_confirmation_msg">Confirme que quiere eliminar este canal y TODOS los episodios descargados del mismo.</string>
<string name="feed_remover_msg">Quitando el canal</string>
<string name="load_complete_feed">Actualizar el canal completo</string>
<string name="hide_episodes_title">Ocultar episodios</string>
@@ -281,7 +280,6 @@
<string name="pref_pauseOnDisconnect_sum">Pausar la reproducción al desconectar los auriculares o el bluetooth</string>
<string name="pref_unpauseOnHeadsetReconnect_sum">Reanudar reproducción cuando se reconecten los auriculares</string>
<string name="pref_unpauseOnBluetoothReconnect_sum">Reanudar reproducción cuando se reconecte el bluetooth</string>
- <string name="pref_hardwareForwardButtonSkips_title">Saltar episodio con botón</string>
<string name="pref_hardwareForwardButtonSkips_sum">Al pulsar el botón físico de avanzar se saltará al siguiente episodio en lugar de sólo avanzar</string>
<string name="pref_hardwarePreviousButtonRestarts_title">Botón anterior reinicia</string>
<string name="pref_hardwarePreviousButtonRestarts_sum">Al pulsar el botón físico de retroceder se comenzará el episodio de nuevo, en lugar de rebobinar</string>
@@ -289,7 +287,6 @@
<string name="pref_auto_delete_sum">Borrar episodio cuando finalice la reproducción</string>
<string name="pref_auto_delete_title">Eliminar automáticamente</string>
<string name="pref_smart_mark_as_played_sum">Marcar episodios como escuchados incluso si todavía quedan unos segundos por escuchar</string>
- <string name="pref_smart_mark_as_played_title">Marcar como escuchado inteligente</string>
<string name="pref_skip_keeps_episodes_sum">Conservar episodios al saltarlos</string>
<string name="pref_skip_keeps_episodes_title">Conservar episodios saltados</string>
<string name="playback_pref">Reproducción</string>
@@ -363,8 +360,6 @@
<string name="pref_gpodnet_notifications_sum">Este ajuste no afecta a errores de autenticación.</string>
<string name="pref_playback_speed_title">Velocidades de reproducción</string>
<string name="pref_playback_speed_sum">Personalice las velocidades disponibles para la reproducción de audio a velocidad variable</string>
- <string name="pref_fast_forward">Intervalo de avance</string>
- <string name="pref_rewind">Intervalo de retroceso</string>
<string name="pref_gpodnet_sethostname_title">Definir nombre de equipo</string>
<string name="pref_gpodnet_sethostname_use_default_host">Usar nombre de equipo por defecto</string>
<string name="pref_expandNotify_title">Expandir Notificación</string>
@@ -389,7 +384,6 @@
<string name="crash_report_sum">Enviar el último informe de fallo por e-mail</string>
<string name="send_email">Enviar e-mail</string>
<string name="experimental_pref">Experimental</string>
- <string name="pref_sonic_title">Sonic media player</string>
<string name="pref_sonic_message">Usar el reproductor Sonic Media incorporado en lugar del reproductor multimedia de Android y Prestissimo</string>
<string name="pref_current_value">Valor actual: %1$s</string>
<string name="pref_proxy_title">Proxy</string>
diff --git a/core/src/main/res/values-et/strings.xml b/core/src/main/res/values-et/strings.xml
index 0e33981b5..629fd4654 100644
--- a/core/src/main/res/values-et/strings.xml
+++ b/core/src/main/res/values-et/strings.xml
@@ -48,6 +48,7 @@
<string name="cancel_label">Loobu</string>
<string name="yes">Jah</string>
<string name="no">Ei</string>
+ <string name="reset">Nulli</string>
<string name="author_label">Autor</string>
<string name="language_label">Keel</string>
<string name="url_label">URL</string>
@@ -93,7 +94,9 @@
<string name="mark_all_read_label">Märgi kuulatuks</string>
<string name="mark_all_read_msg">Märgi kõik saated esitatuks</string>
<string name="mark_all_seen_label">Märgi kõik nähtuks</string>
+ <string name="mark_all_seen_msg">Märgi kõik saated nähtuks</string>
<string name="show_info_label">Näita infot</string>
+ <string name="rename_feed_label">Nimeta taskuhääling ümber</string>
<string name="remove_feed_label">Eemalda taskuhääling</string>
<string name="share_label">Jaga...</string>
<string name="share_link_label">Jaga linki</string>
@@ -110,6 +113,7 @@
<string name="hide_not_queued_episodes_label">Pole järjekorras</string>
<string name="hide_downloaded_episodes_label">Alla laaditud</string>
<string name="hide_not_downloaded_episodes_label">Pole alla laaditud</string>
+ <string name="hide_has_media_label">On meediafaile</string>
<string name="filtered_label">Filtreeritud</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Viimane värskendamine ebaõnnestus</string>
<string name="open_podcast">Ava taskuhääling</string>
@@ -120,7 +124,9 @@
<string name="stop_label">Stopp</string>
<string name="stream_label">Voogedastusena</string>
<string name="remove_label">Eemalda</string>
+ <string name="delete_label">Kustuta</string>
<string name="remove_episode_lable">Eemalda saade</string>
+ <string name="marked_as_seen_label">Märgitud nähtuks</string>
<string name="mark_read_label">Märgi esitatuks</string>
<string name="marked_as_read_label">Märgitud kuulatuks</string>
<string name="mark_unread_label">Märgitud kui kuulamata</string>
@@ -153,6 +159,7 @@
<string name="download_error_unknown_host">Tundmatu host</string>
<string name="download_error_unauthorized">Autentimise viga</string>
<string name="download_error_file_type_type">Failitüübi viga</string>
+ <string name="download_error_forbidden">Keelatud</string>
<string name="cancel_all_downloads_label">Tühista kõik allalaadimised</string>
<string name="download_canceled_msg">Allalaadimine on tühistatud</string>
<string name="download_report_title">Allalaadimised lõpetati veaga (vigadega)</string>
@@ -200,6 +207,8 @@
<string name="sort">Sorteeri</string>
<string name="date">Kuupäeva järgi</string>
<string name="duration">Kestuse järgi</string>
+ <string name="episode_title">Saate pealkiri</string>
+ <string name="feed_title">Uudisvoo pealkiri</string>
<string name="ascending">Kasvavalt</string>
<string name="descending">Kahanevalt</string>
<!--Flattr-->
@@ -220,6 +229,8 @@
<string name="no_chapters_label">Saatel pole peatükke.</string>
<string name="no_shownotes_label">Sellel saatel pole mingeid märkusi.</string>
<!--Preferences-->
+ <string name="storage_pref">Salvestusruum</string>
+ <string name="project_pref">Projekt</string>
<string name="other_pref">Muud</string>
<string name="about_pref">Info</string>
<string name="queue_label">Järjekord</string>
@@ -229,7 +240,6 @@
<string name="pref_followQueue_sum">Kui saade lõpeb, siis esita kohe järgmine järjekorras olev saade.</string>
<string name="pref_auto_delete_sum">Kustuta saated, kui need on kuulatud</string>
<string name="pref_auto_delete_title">Automaatne kustutamine</string>
- <string name="pref_smart_mark_as_played_title">Märgi nutikalt kuulatuks</string>
<string name="pref_skip_keeps_episodes_sum">Hoia saated alles, kui need jäetakse vahele</string>
<string name="pref_skip_keeps_episodes_title">Hoia vahelejäetud osad alles</string>
<string name="playback_pref">Esitamine</string>
@@ -239,6 +249,7 @@
<string name="pref_autoUpdateIntervallOrTime_Interval">Määra intervall</string>
<string name="pref_autoUpdateIntervallOrTime_TimeOfDay">Määra aeg päevades</string>
<string name="pref_autoUpdateIntervallOrTime_every">iga %1$s</string>
+ <string name="pref_autoUpdateIntervallOrTime_at">kell %1$s</string>
<string name="pref_downloadMediaOnWifiOnly_sum">Laadi meediafaile alla ainult üle Wifi</string>
<string name="pref_followQueue_title">Pidev esitamine</string>
<string name="pref_downloadMediaOnWifiOnly_title">Meedia allalaadimine üle Wifi</string>
@@ -276,18 +287,20 @@
<string name="pref_gpodnet_logout_title">Logi välja</string>
<string name="pref_gpodnet_logout_toast">Väljalogimine oli edukas</string>
<string name="pref_gpodnet_setlogin_information_title">Muuda kasutajakonto infot</string>
+ <string name="pref_gpodnet_sync_changes_title">Sünkrooni muudatused kohe</string>
+ <string name="pref_gpodnet_full_sync_title">Täielik sünkroonimine kohe</string>
<string name="pref_gpodnet_sync_started">Sünkroonimine on käivitatud</string>
<string name="pref_gpodnet_login_status"><![CDATA[Sisseloginud kui <i>%1$s</i> seadmega <i>%2$s</i>]]></string>
<string name="pref_playback_speed_title">Esitamise kiirused</string>
- <string name="pref_fast_forward">Kiire edasi kerimise aeg</string>
- <string name="pref_rewind">Tagasi kerimise aeg</string>
<string name="pref_gpodnet_sethostname_title">Määra hostinimi</string>
<string name="pref_gpodnet_sethostname_use_default_host">Kasuta vaikimisi hosti</string>
<string name="pref_expandNotify_title">Teavituste laiendamine</string>
<string name="pref_expandNotify_sum">Näita alati teavitustes pleieri nuppe.</string>
<string name="pref_persistNotify_title">Püsivad taasesitamise nupud</string>
+ <string name="pref_compact_notification_buttons_title">Määra lukustutekraani nupud</string>
<string name="pref_lockscreen_background_title">Määra lukustusekraani taustapilt</string>
<string name="pref_showDownloadReport_title">Näita allalaadimise aruannet</string>
+ <string name="pref_queueAddToFront_title">Pane järjekorra algusesse</string>
<string name="pref_smart_mark_as_played_disabled">Välja lülitatud</string>
<string name="pref_image_cache_size_title">Pildi vahemälu suurus</string>
<string name="pref_image_cache_size_sum">Piltide jaoks kasutatava vahemälu suurus</string>
@@ -298,9 +311,14 @@
<string name="pref_current_value">Praegune väärtus: %1$s</string>
<string name="pref_proxy_title">Vaheserver</string>
<string name="pref_proxy_sum">Määra võrgu vaheserver</string>
+ <string name="pref_faq">KKK</string>
<string name="pref_known_issues">Teadaolevad probleemid</string>
+ <string name="pref_no_browser_found">Veebilehitsejat ei leitud.</string>
+ <string name="pref_cast_title">Chromecasti tugi</string>
<!--Auto-Flattr dialog-->
<!--Search-->
+ <string name="search_hint">Otsi saateid</string>
+ <string name="found_in_shownotes_label">Leitud saate märkmetest</string>
<string name="found_in_chapters_label">Leitud peatükkidest</string>
<string name="search_status_no_results">ei leitud midagi</string>
<string name="search_label">Otsi</string>
@@ -322,12 +340,17 @@
<string name="choose_file_from_filesystem">Kohalikust failisüsteemist</string>
<string name="choose_file_from_external_application">Kasuta välist rakendust</string>
<string name="opml_export_label">OPML eksport</string>
+ <string name="html_export_label">HTML eksport</string>
<string name="exporting_label">Eksportimine...</string>
<string name="export_error_label">Viga eksportimisel</string>
<string name="opml_export_success_title">OPML eksport oli edukas.</string>
<string name="opml_export_success_sum">.opml fail kirjutati kausta:\u0020</string>
<!--Sleep timer-->
+ <string name="set_sleeptimer_label">Määra unetaimer</string>
+ <string name="disable_sleeptimer_label">Keela unetaimer</string>
<string name="enter_time_here_label">Sisesta aeg</string>
+ <string name="sleep_timer_label">Unetaimer</string>
+ <string name="time_left_label">Aega järgi:\u0020</string>
<string name="time_dialog_invalid_input">Vigane sisend, aeg peab olema arvuna</string>
<string name="shake_to_reset_label">Raputa taimeri nullimiseks</string>
<string name="timer_vibration_label">Vibreeri</string>
@@ -371,6 +394,8 @@
<string name="gpodnetsync_auth_error_descr">Vale kasutajanimi või parool</string>
<string name="gpodnetsync_error_title">gpodder.net sünkroonimise viga</string>
<string name="gpodnetsync_error_descr">Sünkroonimise ajal tekkis viga:\u0020</string>
+ <string name="gpodnetsync_pref_report_successful">Korras</string>
+ <string name="gpodnetsync_pref_report_failed">Ebaõnnestus</string>
<!--Directory chooser-->
<string name="selected_folder_label">Vali kaust:</string>
<string name="create_folder_label">Loo kaust</string>
@@ -432,6 +457,8 @@
<string name="selected_queued_label">Valitud järjekorras olevad saated</string>
<string name="not_queued_label">Pole järjekorras</string>
<string name="selected_not_queued_label">Valitud järjekorras mitte olevad saated</string>
+ <string name="has_media">On meediafaile</string>
+ <string name="selected_has_media_label">Valitud saated meediafailidega</string>
<!--Sort-->
<string name="sort_title_a_z">Pealkiri (A \u2192 Z)</string>
<string name="sort_title_z_a">Pealkiri (Z \u2192 A)</string>
@@ -463,7 +490,9 @@
<string name="proxy_checking">Kontrollimine...</string>
<string name="proxy_test_successful">Kontroll oli edukas</string>
<string name="proxy_test_failed">Kontroll ebaõnnestus</string>
+ <string name="proxy_host_empty_error">Hostinimi ei saa olla tühi</string>
<string name="proxy_port_invalid_error">Port pole korrektne</string>
<!--Casting-->
+ <string name="cast_media_route_menu_title">Esita...</string>
<!--<string name="cast_failed_to_connect">Could not connect to the device</string>-->
</resources>
diff --git a/core/src/main/res/values-fr/strings.xml b/core/src/main/res/values-fr/strings.xml
index fdc34bf9c..8ab6f39fa 100644
--- a/core/src/main/res/values-fr/strings.xml
+++ b/core/src/main/res/values-fr/strings.xml
@@ -26,6 +26,10 @@
<!--Statistics fragment-->
<string name="total_time_listened_to_podcasts">Temps d\'écoute total</string>
<string name="statistics_details_dialog">%1$d épisodes sur %2$d commencés.\n\nLu %3$s sur %4$s.</string>
+ <string name="statistics_mode">Type de statistiques</string>
+ <string name="statistics_mode_normal">Calculer la durée réellement écoutée. Les épisodes écoutés deux fois comptent double alors que ceux simplement marqués lus ne sont pas comptés</string>
+ <string name="statistics_mode_count_all">Additionner tous les podcasts marqués comme lus</string>
+ <string name="statistics_speed_not_counted">Note : la vitesse de lecture n\'est jamais prise en compte.</string>
<!--Main activity-->
<string name="drawer_open">Ouvrir le menu</string>
<string name="drawer_close">Fermer le menu</string>
@@ -33,6 +37,7 @@
<string name="drawer_feed_order_unplayed_episodes">Trier par compteur</string>
<string name="drawer_feed_order_alphabetical">Trier alphabétiquement</string>
<string name="drawer_feed_order_last_update">Trier par date de publication</string>
+ <string name="drawer_feed_order_most_played">Trier par nombre d\'épisodes lus</string>
<string name="drawer_feed_counter_new_unplayed">Nombre de nouveaux épisodes non-lus</string>
<string name="drawer_feed_counter_new">Nombre de nouveaux épisodes</string>
<string name="drawer_feed_counter_unplayed">Nombre d\'épisodes non-lus</string>
@@ -51,7 +56,7 @@
<string name="cancel_label">Annuler</string>
<string name="yes">Oui</string>
<string name="no">Non</string>
- <string name="reset">Reset</string>
+ <string name="reset">Réinitialiser</string>
<string name="author_label">Auteur</string>
<string name="language_label">Langue</string>
<string name="url_label">URL</string>
@@ -62,6 +67,7 @@
<string name="refresh_label">Rafraîchir</string>
<string name="external_storage_error_msg">Aucun stockage externe n\'est disponible. Merci de connecter un volume de stockage externe pour que l\'application puisse fonctionner correctement.</string>
<string name="chapters_label">Chapitres</string>
+ <string name="chapter_duration">Durée : %1$s</string>
<string name="shownotes_label">Notes d\'épisode</string>
<string name="description_label">Description</string>
<string name="most_recent_prefix">Épisode le plus récent :\u0020</string>
@@ -113,7 +119,7 @@
<string name="share_feed_url_label">Partager lien du flux</string>
<string name="share_item_url_label">Partager le lien de l\'épisode</string>
<string name="share_item_url_with_position_label">Partager le lien de l\'épisode avec la position</string>
- <string name="feed_delete_confirmation_msg">Veuillez confirmer que vous voulez bien supprimer ce flux et TOUS ses épisodes que vous avez téléchargés.</string>
+ <string name="feed_delete_confirmation_msg">Confirmer que vous voulez supprimer le flux \"%1$s\" et TOUS les épisodes que vous avez téléchargés.</string>
<string name="feed_remover_msg">Flux en cours de suppression</string>
<string name="load_complete_feed">Mettre à jour tout le flux</string>
<string name="hide_episodes_title">Cacher épisodes</string>
@@ -122,7 +128,7 @@
<string name="hide_paused_episodes_label">En pause</string>
<string name="hide_played_episodes_label">Joués</string>
<string name="hide_queued_episodes_label">Rajouté à la liste d\'attente</string>
- <string name="hide_not_queued_episodes_label">Pas rajouté à la liste d\'attente</string>
+ <string name="hide_not_queued_episodes_label">Non rajouté à la liste d\'attente</string>
<string name="hide_downloaded_episodes_label">Téléchargé</string>
<string name="hide_not_downloaded_episodes_label">Non téléchargé</string>
<string name="hide_has_media_label">À des médias</string>
@@ -138,7 +144,7 @@
<string name="remove_label">Supprimer</string>
<string name="delete_label">Effacer</string>
<string name="remove_episode_lable">Supprimer cet épisode</string>
- <string name="marked_as_seen_label">Marquer comme vu</string>
+ <string name="marked_as_seen_label">Marqué comme vu</string>
<string name="mark_read_label">Marquer comme lu</string>
<string name="marked_as_read_label">Les épisodes ont été marqués comme lus</string>
<string name="mark_unread_label">Marquer comme non lu</string>
@@ -281,22 +287,22 @@
<string name="pref_pauseOnDisconnect_sum">Interrompre la lecture lorsque le casque ou le bluetooth sont déconnectés</string>
<string name="pref_unpauseOnHeadsetReconnect_sum">Reprendre la lecture quand les écouteurs sont reconnectés</string>
<string name="pref_unpauseOnBluetoothReconnect_sum">Reprendre la lecture quand le Bluetooth se reconnecte</string>
- <string name="pref_hardwareForwardButtonSkips_title">Le bouton piste suivante saute l\'épisode</string>
- <string name="pref_hardwareForwardButtonSkips_sum">Passer à l\'épisode suivant au lieu de faire un saut avant quand il est pressé un bouton physique pour avancer à la piste suivante</string>
- <string name="pref_hardwarePreviousButtonRestarts_title">Bouton précédent redémarre</string>
- <string name="pref_hardwarePreviousButtonRestarts_sum">Quand un bouton précédent physique est appuyé l\'épisode en cours repart de zéro au lieu de revenir en arrière</string>
+ <string name="pref_hardwareForwardButtonSkips_title">Le bouton \"saut avant\" saute l\'épisode</string>
+ <string name="pref_hardwareForwardButtonSkips_sum">Passer à l\'épisode suivant au lieu de faire un saut avant quand un bouton physique \\"saut avant\\" est pressé</string>
+ <string name="pref_hardwarePreviousButtonRestarts_title">Le bouton \"saut arrière\" redémarre l\'épisode</string>
+ <string name="pref_hardwarePreviousButtonRestarts_sum">Repartir de zéro au lieu de faire un saut arrière quand un bouton physique \"saut arrière\" est pressé</string>
<string name="pref_followQueue_sum">Après la fin d\'un épisode, passer au suivant</string>
<string name="pref_auto_delete_sum">Supprimer l\'épisode quand la lecture est finie</string>
<string name="pref_auto_delete_title">Suppression automatique</string>
- <string name="pref_smart_mark_as_played_sum">Marquer les épisodes comme lus même s\'il reste encore un certain nombre de secondes à jouer</string>
- <string name="pref_smart_mark_as_played_title">Marquer comme lu de manière intelligente</string>
+ <string name="pref_smart_mark_as_played_sum">Les épisodes seront marqués comme lus même s\'il reste quelques secondes à jouer</string>
+ <string name="pref_smart_mark_as_played_title">Marquer comme lu intelligemment</string>
<string name="pref_skip_keeps_episodes_sum">Garder les épisodes quand ils sont passés</string>
<string name="pref_skip_keeps_episodes_title">Garder les épisodes passés</string>
<string name="playback_pref">Lecture</string>
<string name="network_pref">Réseau</string>
<string name="pref_autoUpdateIntervallOrTime_title">Mettre à jour l’intervalle ou l\'heure</string>
<string name="pref_autoUpdateIntervallOrTime_sum">Indiquer un intervalle ou une heure spécifique de mise à jour des flux</string>
- <string name="pref_autoUpdateIntervallOrTime_message">Vous pouvez mettre en place un <i>intervalle</i> comme \"toutes les 2 heures\", une <i>heure précise</i> comme \"7:00\" ou désactiver les mises à jours automatique.\n\n<small>Note: Il est possible qu\'il y ait un délai car l\'heure de mise à jour peut être inexacte.</small></string>
+ <string name="pref_autoUpdateIntervallOrTime_message">Vous pouvez mettre en place un <i>intervalle</i> comme \\"toutes les 2 heures\\", une <i>heure précise</i> comme \\"7:00\\" ou désactiver les mises à jours automatique.\n\n<small>Note: Il est possible qu\'il y ait un délai car l\'heure de mise à jour peut être inexacte.</small></string>
<string name="pref_autoUpdateIntervallOrTime_Disable">Désactiver</string>
<string name="pref_autoUpdateIntervallOrTime_Interval">Définir intervalle</string>
<string name="pref_autoUpdateIntervallOrTime_TimeOfDay">Régler l\'heure</string>
@@ -362,13 +368,15 @@
<string name="pref_gpodnet_notifications_title">Notification des erreurs de synchronisation</string>
<string name="pref_gpodnet_notifications_sum">Ce paramètre ne s\'applique pas aux erreurs d\'authentification.</string>
<string name="pref_playback_speed_title">Vitesses de lecture</string>
- <string name="pref_playback_speed_sum">Modifier la liste des vitesses disponibles pour la lecture audio</string>
- <string name="pref_fast_forward">Avance rapide</string>
- <string name="pref_rewind">Retour en arrière</string>
+ <string name="pref_playback_speed_sum">Définir les vitesses disponibles lors de la lecture audio</string>
+ <string name="pref_fast_forward">Durée du saut avant</string>
+ <string name="pref_fast_forward_sum">Nombre de secondes à sauter quand le bouton \"saut avant\" est cliqué</string>
+ <string name="pref_rewind">Durée du saut arrière</string>
+ <string name="pref_rewind_sum">Nombre de secondes à sauter quand le bouton \"saut arrière\" est cliqué</string>
<string name="pref_gpodnet_sethostname_title">Choisir un nom de domaine</string>
<string name="pref_gpodnet_sethostname_use_default_host">Utiliser le nom de domaine par défaut</string>
<string name="pref_expandNotify_title">Etendre la notification</string>
- <string name="pref_expandNotify_sum">Toujours étendre les notifications pour montrer les boutons de lecture</string>
+ <string name="pref_expandNotify_sum">Toujours étendre la notification pour montrer tous les boutons de lecture </string>
<string name="pref_persistNotify_title">Boutons de lecture permanents</string>
<string name="pref_persistNotify_sum">Garder les notifications et les boutons de lecture sur l\'écran de verouillage quand la lecture est en pause</string>
<string name="pref_compact_notification_buttons_title">Définir les boutons de l\'écran de verrouillage</string>
@@ -380,7 +388,7 @@
<string name="pref_showDownloadReport_title">Afficher le rapport de téléchargements</string>
<string name="pref_showDownloadReport_sum">Si les téléchargements échouent, générer un rapport des détails des échecs.</string>
<string name="pref_expand_notify_unsupport_toast">Les versions d\'Android antérieures à 4.1 ne sont pas compatibles avec les notifications élargies</string>
- <string name="pref_queueAddToFront_sum">Ajouter de nouveaux épisodes en tête de file</string>
+ <string name="pref_queueAddToFront_sum">Ajouter les nouveaux épisodes au début de la liste de lecture.</string>
<string name="pref_queueAddToFront_title">Mettre au début de la file d\'attente</string>
<string name="pref_smart_mark_as_played_disabled">Désactivé</string>
<string name="pref_image_cache_size_title">Taille du cache de l\'image</string>
@@ -390,7 +398,7 @@
<string name="send_email">Envoyer e-mail</string>
<string name="experimental_pref">Expérimental</string>
<string name="pref_sonic_title">Lecteur multimédia Sonic</string>
- <string name="pref_sonic_message">Utiliser le lecteur multimédia interne Sonic au lieu du natif d\'Android ou de Prestissimo</string>
+ <string name="pref_sonic_message">Utiliser le lecteur multimédia interne Sonic au lieu du lecteur natif d\'Android ou Prestissimo</string>
<string name="pref_current_value">Valeur actuelle : %1$s</string>
<string name="pref_proxy_title">Proxy</string>
<string name="pref_proxy_sum">Paramétrer un réseau proxy</string>
@@ -400,6 +408,8 @@
<string name="pref_cast_title">Support Chromecast</string>
<string name="pref_cast_message_play_flavor">Activer la lecture à distance sur les appareils Cast (comme Chromecast, Audio Speaker ou Android TV)</string>
<string name="pref_cast_message_free_flavor">Chromecast nécessite des bibiliothèques tierces qui sont désactivées dans cette version d\'AntennaPod</string>
+ <string name="pref_enqueue_downloaded_title">File d\'attente après téléchargement</string>
+ <string name="pref_enqueue_downloaded_summary">Mettre en file d\'attente après téléchargement</string>
<!--Auto-Flattr dialog-->
<string name="auto_flattr_enable">Activer le paiement flattr automatique</string>
<string name="auto_flattr_after_percent">Lancer un paiement flattr pour un épisode dès que %d de l\'épisode a été joué</string>
@@ -409,6 +419,8 @@
<string name="search_hint">Chercher les épisodes</string>
<string name="found_in_shownotes_label">Trouvé dans les notes d\'épisodes</string>
<string name="found_in_chapters_label">Trouvé dans les titres de chapitre</string>
+ <string name="found_in_authors_label">Trouvés en tant qu\'auteur</string>
+ <string name="found_in_feeds_label">Trouvés dans les flux</string>
<string name="search_status_no_results">Aucun résultat trouvé</string>
<string name="search_label">Recherche</string>
<string name="found_in_title_label">Trouvé dans le titre</string>
@@ -438,14 +450,14 @@
<string name="opml_export_success_sum">Le fichier .opml a été écrit ici :\u0020</string>
<string name="opml_import_ask_read_permission">L\'accès au stockage externe est requis pour lire le fichier OPML</string>
<!--Sleep timer-->
- <string name="set_sleeptimer_label">Définir le minuteur d\'arrêt automatique</string>
- <string name="disable_sleeptimer_label">Désactiver le minuteur d\'arrêt automatique</string>
+ <string name="set_sleeptimer_label">Activer le minuteur d\'arrêt</string>
+ <string name="disable_sleeptimer_label">Désactiver le minuteur d\'arrêt</string>
<string name="enter_time_here_label">Entrer l\'heure</string>
- <string name="sleep_timer_label">Minuteur de mise en veille</string>
+ <string name="sleep_timer_label">Minuteur d\'arrêt</string>
<string name="time_left_label">Durée restante :\u0020</string>
<string name="time_dialog_invalid_input">Entrée invalide, la durée doit être un nombre entier</string>
- <string name="timer_about_to_expire_label"><b>Quand le minuteur est sur le point de se terminer:</b></string>
- <string name="shake_to_reset_label">Secouer afin de remettre le minuteur a zéro</string>
+ <string name="timer_about_to_expire_label"><b>Quand le minuteur se termine :</b></string>
+ <string name="shake_to_reset_label">Secouer pour redémarrer le minuteur</string>
<string name="timer_vibration_label">Vibrer</string>
<string name="time_seconds">secondes</string>
<string name="time_minutes">minutes</string>
@@ -513,7 +525,7 @@
<string name="folder_not_empty_dialog_title">Le répertoire n\'est pas vide</string>
<string name="folder_not_empty_dialog_msg">Le répertoire que vous avez choisi n\'est pas vide. Les fichiers téléchargés seront ajoutés à ce répertoire. Continuer malgré tout ?</string>
<string name="set_to_default_folder">Choisir le répertoire par défaut</string>
- <string name="pref_pausePlaybackForFocusLoss_sum">Mettre la lecture en pause au lieu de baisser le volume quand une autre application veut jouer un son</string>
+ <string name="pref_pausePlaybackForFocusLoss_sum">Pauser la lecture au lieu de baisser le volume quand une autre application joue un son</string>
<string name="pref_pausePlaybackForFocusLoss_title">Mettre en pause lors d\'interruptions</string>
<string name="pref_resumeAfterCall_sum">Reprendre la lecture après un appel téléphonique</string>
<string name="pref_resumeAfterCall_title">Reprendre après appel</string>
@@ -523,8 +535,8 @@
<string name="subscribed_label">Abonné</string>
<string name="downloading_label">En cours de téléchargement...</string>
<!--Content descriptions for image buttons-->
- <string name="rewind_label">Retour en arrière</string>
- <string name="fast_forward_label">Avance rapide</string>
+ <string name="rewind_label">Saut arrière</string>
+ <string name="fast_forward_label">Saut avant</string>
<string name="media_type_audio_label">Audio</string>
<string name="media_type_video_label">Vidéo</string>
<string name="navigate_upwards_label">Naviguer vers le haut</string>
diff --git a/core/src/main/res/values-hi-rIN/strings.xml b/core/src/main/res/values-hi-rIN/strings.xml
index bc0101edf..9e30ff59d 100644
--- a/core/src/main/res/values-hi-rIN/strings.xml
+++ b/core/src/main/res/values-hi-rIN/strings.xml
@@ -52,7 +52,6 @@
<string name="remove_feed_label">पॉडकास्ट हटाएँ
</string>
<string name="share_link_label">शेयर वेबसाइट लिंक</string>
- <string name="feed_delete_confirmation_msg">इसकी पुष्टि करें कि आप इस फ़ीड और इस फ़ीड के सभी प्रकरणों को हटाना चाहते हैं जिन्हें आपने डाउनलोड किया है.</string>
<string name="feed_remover_msg">फ़ीड निकाल रहा है</string>
<!--actions on feeditems-->
<string name="download_label">डाउनलोड</string>
diff --git a/core/src/main/res/values-hu/strings.xml b/core/src/main/res/values-hu/strings.xml
index e370a2229..91eef6144 100644
--- a/core/src/main/res/values-hu/strings.xml
+++ b/core/src/main/res/values-hu/strings.xml
@@ -1,6 +1,7 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources xmlns:tools="http://schemas.android.com/tools">
<!--Activitiy and fragment titles-->
+ <string name="feeds_label">Idővonalak</string>
<string name="statistics_label">Statisztika</string>
<string name="add_feed_label">Podcast hozzáadása</string>
<string name="episodes_label">Epizódok</string>
@@ -16,50 +17,163 @@
<string name="subscriptions_label">Feliratkozások</string>
<string name="subscriptions_list_label">Feliratkozások listája</string>
<string name="cancel_download_label">Letöltés megállítása</string>
+ <string name="playback_history_label">Lejátszási Napló</string>
+ <string name="gpodnet_main_label">gpodder.net</string>
+ <string name="gpodnet_auth_label">gpodder.net Bejelentkezés</string>
+ <string name="free_space_label">%1$s szabad</string>
+ <string name="episode_cache_full_title">Epizód tárhely megtelt</string>
+ <string name="episode_cache_full_message">Az epizódok tárolására megadott maximális tárhely megtelt. A méretét a \"Beállítások\" menüpontban tudod megnövelni.</string>
<!--Statistics fragment-->
+ <string name="total_time_listened_to_podcasts">A lejátszott podcast-ok összideje:</string>
+ <string name="statistics_details_dialog">%1$d-ból %2$d epizód elindítva.\n\n%3$s-ból %4$s lejátszva.</string>
<!--Main activity-->
<string name="drawer_open">Menü megnyitása</string>
<string name="drawer_close">Menü bezárása</string>
+ <string name="drawer_preferences">Oldalsáv beállításai</string>
<string name="drawer_feed_order_unplayed_episodes">Rendezés számláló szerint</string>
<string name="drawer_feed_order_alphabetical">Rendezés ABC rendben</string>
<string name="drawer_feed_order_last_update">Rendezés megjelenés dátuma szerint</string>
<string name="drawer_feed_counter_new_unplayed">Új és nem játszott epizódok száma</string>
<string name="drawer_feed_counter_new">Új epizódok száma</string>
<string name="drawer_feed_counter_unplayed">Nem játszott epizódok száma</string>
+ <string name="drawer_feed_counter_downloaded">Letöltött epizódok száma</string>
+ <string name="drawer_feed_counter_none">Nincs</string>
<!--Webview actions-->
<string name="open_in_browser_label">Megnyitás böngészőben</string>
<string name="copy_url_label">URL másolása</string>
<string name="share_url_label">URL megosztása</string>
<string name="copied_url_msg">URL másolva a vásólapra</string>
+ <string name="go_to_position_label">Ugrás ehhez a pozícióhoz</string>
<!--Playback history-->
+ <string name="clear_history_label">Napló törlése</string>
<!--Other-->
<string name="confirm_label">Megerősít</string>
<string name="cancel_label">Mégsem</string>
<string name="yes">Igen</string>
<string name="no">Nem</string>
+ <string name="reset">Visszaállítás</string>
+ <string name="author_label">Szerző</string>
<string name="language_label">Nyelv</string>
<string name="url_label">URL</string>
<string name="podcast_settings_label">Beállítások</string>
<string name="cover_label">Kép</string>
<string name="error_label">Hiba</string>
+ <string name="error_msg_prefix">Hiba történt:</string>
<string name="refresh_label">Frissítés</string>
+ <string name="external_storage_error_msg">Nem található külső tárhely. Biztosíts egy külső tárhelyet hogy az alkalmazás működni tudjon.</string>
<string name="chapters_label">Fejezetek</string>
+ <string name="shownotes_label">Jegyzetek</string>
<string name="description_label">Leírás</string>
+ <string name="most_recent_prefix">Legfrissebb epizód:\u0020</string>
+ <string name="episodes_suffix">\u0020epizód</string>
+ <string name="length_prefix">Hossz:\u0020</string>
+ <string name="size_prefix">Méret:\u0020</string>
<string name="processing_label">Feldolgozás</string>
<string name="loading_label">Betöltés...</string>
<string name="save_username_password_label">Felhasználónév és jelszó mentése</string>
<string name="close_label">Bezárás</string>
<string name="retry_label">Újra</string>
+ <string name="auto_download_label">Automatikus letöltésekhez hozzáfűzés</string>
+ <string name="auto_download_apply_to_items_title">Alkalmazás előző epizódokra</string>
+ <string name="auto_download_apply_to_items_message">A beállított <i>Automatikus letöltés</i> az új epizódokra érvényes.\nVonatkozzon a korábban kibocsátott epizódokra is?</string>
<string name="auto_delete_label">Epizód automatikus törlése</string>
+ <string name="parallel_downloads_suffix">\u0020párhuzamos letöltés</string>
<string name="feed_auto_download_global">Globális alapértelmezett</string>
<string name="feed_auto_download_always">Mindig</string>
<string name="feed_auto_download_never">Soha</string>
<string name="send_label">Küldés…</string>
<string name="episode_cleanup_never">Soha</string>
+ <string name="episode_cleanup_queue_removal">Ha nem várakozik</string>
+ <string name="episode_cleanup_after_listening">Befejezés után</string>
+ <plurals name="episode_cleanup_days_after_listening">
+ <item quantity="one">1 nappal a befejezés után</item>
+ <item quantity="other">%d nappal a befejezés után</item>
+ </plurals>
<!--'Add Feed' Activity labels-->
+ <string name="feedurl_label">Idővonal URL</string>
+ <string name="etxtFeedurlHint">www.example.com/feed</string>
+ <string name="txtvfeedurl_label">Podcast hozzáadása URL alapján</string>
+ <string name="podcastdirectories_label">Podcast keresése mappában</string>
+ <string name="podcastdirectories_descr">Új podcastokat kereshetsz iTunes-on vagy fyyd-en, vagy a gpodder.net-en név, kategória vagy cím alapján.</string>
+ <string name="browse_gpoddernet_label">gpodder.net böngészése</string>
<!--Actions on feeds-->
+ <string name="mark_all_read_label">Az összes megjelölése lejátszottként</string>
+ <string name="mark_all_read_msg">Az összes epizód lejátszottként megjelölve</string>
+ <string name="mark_all_read_confirmation_msg">Biztosan megjelölöd az összes epizódot lejátszottként?</string>
+ <string name="mark_all_read_feed_confirmation_msg">Biztosan megjelölöd az összes epizódot az idővonalon lejátszottként?</string>
+ <string name="mark_all_seen_label">Az összes megjelölése megnézettként</string>
+ <string name="mark_all_seen_msg">Az összes epizód megnézettként megjelölve</string>
+ <string name="mark_all_seen_confirmation_msg">Biztosan megjelölöd az összes epizódott megnézettként?</string>
+ <string name="show_info_label">Információ mutatása</string>
+ <string name="rename_feed_label">Podcast átnevezése</string>
+ <string name="remove_feed_label">Podcast eltávolítása</string>
+ <string name="share_label">Megosztás…</string>
+ <string name="share_link_label">Link megosztása</string>
+ <string name="share_link_with_position_label">Link megosztása pozícióval</string>
+ <string name="share_feed_url_label">Idővonal URL megosztása</string>
+ <string name="share_item_url_label">Epizód fájl URL megosztása</string>
+ <string name="share_item_url_with_position_label">Epizód fájl URL megosztása pozícióval</string>
+ <string name="feed_remover_msg">Idővonal eltávolítása</string>
+ <string name="load_complete_feed">Teljes idővonal frissítése</string>
+ <string name="hide_episodes_title">Epizódok elrejtése</string>
+ <string name="episode_actions">Műveletek alkalmazása</string>
+ <string name="hide_unplayed_episodes_label">Nem lejátszott</string>
+ <string name="hide_paused_episodes_label">Szüneteltetett</string>
+ <string name="hide_played_episodes_label">Lejátszott</string>
+ <string name="hide_queued_episodes_label">Várakozó</string>
+ <string name="hide_not_queued_episodes_label">Nem várakozó</string>
+ <string name="hide_downloaded_episodes_label">Letöltött</string>
+ <string name="hide_not_downloaded_episodes_label">Nem letöltött</string>
+ <string name="hide_has_media_label">További tartalma van</string>
+ <string name="filtered_label">Szűrt</string>
+ <string name="refresh_failed_msg">{fa-exclamation-circle} A legutóbbi frissítés sikertelen</string>
+ <string name="open_podcast">Podcast megnyitása</string>
<!--actions on feeditems-->
+ <string name="download_label">Letöltés</string>
+ <string name="play_label">Lejátszás</string>
+ <string name="pause_label">Szüneteltetés</string>
+ <string name="stop_label">Megállítás</string>
+ <string name="stream_label">Stream-elés</string>
+ <string name="remove_label">Eltávolítás</string>
+ <string name="delete_label">Törlés</string>
+ <string name="remove_episode_lable">Epizód eltávolítása</string>
+ <string name="marked_as_seen_label">Megtekintettként megjelölve</string>
+ <string name="mark_read_label">Lejátszottként megjelölés</string>
+ <string name="marked_as_read_label">Lejátszottként megjelölve</string>
+ <string name="mark_unread_label">Nem lejátszottként megjelölés</string>
+ <string name="add_to_queue_label">Várakozási sorhoz adás</string>
+ <string name="added_to_queue_label">Várakozási sorhoz adva</string>
+ <string name="remove_from_queue_label">Várakozási sorból eltávolítás</string>
+ <string name="add_to_favorite_label">Kedvencekhez adás</string>
+ <string name="added_to_favorites">Kedvencekhez adva</string>
+ <string name="remove_from_favorite_label">Kedvencekből eltávolítás</string>
+ <string name="removed_from_favorites">Kedvencekből eltávolítva</string>
+ <string name="visit_website_label">Honlap megtekintése</string>
+ <string name="support_label">Flattr-ezés</string>
+ <string name="skip_episode_label">Epizód átugrása</string>
+ <string name="activate_auto_download">Automatikus letöltés bekapcsolása</string>
+ <string name="deactivate_auto_download">Automatikus letöltés kikapcsolása</string>
+ <string name="reset_position">Lejátszási pozíció visszaállítása</string>
+ <string name="removed_item">Elem eltávolítva</string>
<!--Download messages and labels-->
+ <string name="download_successful">sikeres</string>
+ <string name="download_failed">sikertelen</string>
+ <string name="download_pending">Letöltés várakozik</string>
+ <string name="download_running">Letöltés fut</string>
+ <string name="download_error_device_not_found">Táreszköz nem található</string>
+ <string name="download_error_insufficient_space">Túl kevés tárhely</string>
+ <string name="download_error_file_error">Fájl Hiba</string>
+ <string name="download_error_http_data_error">HTTP Adat Hiba</string>
+ <string name="download_error_error_unknown">Ismeretlen Hiba</string>
+ <string name="download_error_parser_exception">Értelmező Kivétel</string>
+ <string name="download_error_unsupported_type">Nem Támogatott Idővonal Típus</string>
+ <string name="download_error_connection_error">Kapcsolódási Hiba</string>
+ <string name="download_error_unknown_host">Ismeretlen Hoszt</string>
+ <string name="download_error_unauthorized">Azonosítási Hiba</string>
+ <string name="download_error_file_type_type">Fájl Típus Hiba</string>
+ <string name="download_error_forbidden">Tiltott</string>
+ <string name="cancel_all_downloads_label">Az összes letöltés visszavonása</string>
+ <string name="download_canceled_msg">Letöltés visszavonva</string>
<!--Mediaplayer messages-->
<!--Queue operations-->
<!--Flattr-->
diff --git a/core/src/main/res/values-it-rIT/strings.xml b/core/src/main/res/values-it-rIT/strings.xml
index 1322813f9..4d4e44bff 100644
--- a/core/src/main/res/values-it-rIT/strings.xml
+++ b/core/src/main/res/values-it-rIT/strings.xml
@@ -20,6 +20,7 @@
<string name="playback_history_label">Cronologia delle riproduzioni</string>
<string name="gpodnet_main_label">gpodder.net</string>
<string name="gpodnet_auth_label">gpodder.net login</string>
+ <string name="free_space_label">%1$s disponibili</string>
<string name="episode_cache_full_title">Cache degli episodi piena</string>
<string name="episode_cache_full_message">Il limite della cache degli episodi è stato raggiunto. Puoi incrementare la dimensione della cache nelle Impostazioni.</string>
<!--Statistics fragment-->
@@ -28,11 +29,13 @@
<!--Main activity-->
<string name="drawer_open">Apri il menù</string>
<string name="drawer_close">Chiudi il menù</string>
+ <string name="drawer_preferences">Preferenze Cassetto</string>
<string name="drawer_feed_order_alphabetical">Ordina alfabeticamente</string>
<string name="drawer_feed_order_last_update">Ordina per data di pubblicazione</string>
<string name="drawer_feed_counter_new_unplayed">Numero di episodi nuovi e non riprodotti</string>
<string name="drawer_feed_counter_new">Numero di episodi nuovi</string>
<string name="drawer_feed_counter_unplayed">Numero di episodi non riprodotti</string>
+ <string name="drawer_feed_counter_downloaded">Numero di episodi scaricati</string>
<string name="drawer_feed_counter_none">Nessuno</string>
<!--Webview actions-->
<string name="open_in_browser_label">Apri nel browser</string>
@@ -70,6 +73,7 @@
<string name="retry_label">Riprova</string>
<string name="auto_download_label">Includi nei download automatici</string>
<string name="auto_download_apply_to_items_title">Applica ai Precedenti Episodi</string>
+ <string name="auto_download_apply_to_items_message">La nuova funzione <i>Auto Download</i> sarà applicata automaticamente ai nuovi episodi.\nVuoi attivarla anche per gli episodi pubblicati precedentemente?</string>
<string name="auto_delete_label">Elimina Episodi Automaticamente</string>
<string name="parallel_downloads_suffix">\u0020download paralleli</string>
<string name="feed_auto_download_always">Sempre</string>
@@ -94,14 +98,14 @@
<string name="mark_all_read_feed_confirmation_msg">Per favore conferma che vuoi segnare tutti gli episodi di questo feed come riprodotti.</string>
<string name="mark_all_seen_label">Segna tutti come visti</string>
<string name="show_info_label">Informazioni</string>
- <string name="remove_feed_label">Rimuovi un podcast</string>
+ <string name="rename_feed_label">Rinomina Podcast</string>
+ <string name="remove_feed_label">Rimuovi podcast</string>
<string name="share_label">Condividi...</string>
<string name="share_link_label">Condividi il link al sito</string>
<string name="share_link_with_position_label">Condividi il Link con la Posizione</string>
<string name="share_feed_url_label">Condividi URL del Feed</string>
<string name="share_item_url_label">Condividi URL del File dell\'episodio</string>
<string name="share_item_url_with_position_label">Condividi l\'URL del File dell\'epsiodio con la Posizione</string>
- <string name="feed_delete_confirmation_msg">Per favore conferma la cancellazione di questo feed e di TUTTI gli episodi collegati che sono stati precedentemente scaricati.</string>
<string name="feed_remover_msg">Rimozione feed</string>
<string name="load_complete_feed">Ricarica il feed completo</string>
<string name="hide_episodes_title">Nascondi gli episodi</string>
@@ -123,7 +127,9 @@
<string name="stop_label">Ferma</string>
<string name="stream_label">Stream</string>
<string name="remove_label">Rimuovi</string>
+ <string name="delete_label">Elimina</string>
<string name="remove_episode_lable">Rimuovi l\'episodio</string>
+ <string name="marked_as_seen_label">Segna come visto</string>
<string name="mark_read_label">Segna come riprodotto</string>
<string name="marked_as_read_label">Segnato come riprodotto</string>
<string name="mark_unread_label">Segna come non riprodotto</string>
diff --git a/core/src/main/res/values-it/strings.xml b/core/src/main/res/values-it/strings.xml
index b36d8acd4..5e74e5c57 100644
--- a/core/src/main/res/values-it/strings.xml
+++ b/core/src/main/res/values-it/strings.xml
@@ -73,7 +73,6 @@
<string name="mark_all_read_confirmation_msg">Conferma che desideri segnare tutti gli episodi come riprodotti.</string>
<string name="mark_all_read_feed_confirmation_msg">Conferma che desideri segnare tutti gli episodi in questo feed come riprodotti.</string>
<string name="show_info_label">Mostra delle informazioni</string>
- <string name="feed_delete_confirmation_msg">Conferma che desideri cancellare questo feed e TUTTI gli episodi di questo feed che hai scaricato.</string>
<string name="hide_episodes_title">Nascondi gli episodi</string>
<string name="episode_actions">Applica le azioni</string>
<string name="hide_unplayed_episodes_label">Non riprodotti</string>
diff --git a/core/src/main/res/values-iw-rIL/strings.xml b/core/src/main/res/values-iw-rIL/strings.xml
index 4aa4de3fc..bdfd00a2e 100644
--- a/core/src/main/res/values-iw-rIL/strings.xml
+++ b/core/src/main/res/values-iw-rIL/strings.xml
@@ -77,7 +77,6 @@
<string name="show_info_label">הצג מידע</string>
<string name="remove_feed_label">הסר פודקאסט</string>
<string name="share_link_label">שתף קישור אתר</string>
- <string name="feed_delete_confirmation_msg">אשר מחיקת הזנה זו ואת כל פרקי ההזנה שהורדת.</string>
<string name="feed_remover_msg">הסר הזנה</string>
<string name="load_complete_feed">רענן את כל ההזנה</string>
<!--actions on feeditems-->
diff --git a/core/src/main/res/values-ja/strings.xml b/core/src/main/res/values-ja/strings.xml
index 94e2d8ac0..2e70594ec 100644
--- a/core/src/main/res/values-ja/strings.xml
+++ b/core/src/main/res/values-ja/strings.xml
@@ -26,6 +26,10 @@
<!--Statistics fragment-->
<string name="total_time_listened_to_podcasts">ポッドキャストを再生した合計時間:</string>
<string name="statistics_details_dialog">%2$d から %1$d のエピソードが開始しました。\n\n%4$s から%3$s を再生しました。</string>
+ <string name="statistics_mode">統計情報モード</string>
+ <string name="statistics_mode_normal">実際に再生された時間を計算します。 2回再生すると2回カウントされ、再生済のマークはカウントされません</string>
+ <string name="statistics_mode_count_all">再生済みとマークされたすべてのポッドキャストを集計する</string>
+ <string name="statistics_speed_not_counted">注意: 再生速度は考慮されません。</string>
<!--Main activity-->
<string name="drawer_open">メニューを開く</string>
<string name="drawer_close">メニューを閉じる</string>
@@ -33,6 +37,7 @@
<string name="drawer_feed_order_unplayed_episodes">カウンターで並び替え</string>
<string name="drawer_feed_order_alphabetical">アルファベット順に並び替え</string>
<string name="drawer_feed_order_last_update">公開日で並び替え</string>
+ <string name="drawer_feed_order_most_played">再生されたエピソードの数で並べ替え</string>
<string name="drawer_feed_counter_new_unplayed">新しい未再生のエピソードの数</string>
<string name="drawer_feed_counter_new">新しいエピソードの数</string>
<string name="drawer_feed_counter_unplayed">未再生のエピソードの数</string>
@@ -62,6 +67,7 @@
<string name="refresh_label">更新</string>
<string name="external_storage_error_msg">外部ストレージが利用できません。アプリが正常に動作できるように、外部ストレージがマウントされていることを確認してください。</string>
<string name="chapters_label">チャプター</string>
+ <string name="chapter_duration">時間: %1$s</string>
<string name="shownotes_label">ショーノート</string>
<string name="description_label">説明</string>
<string name="most_recent_prefix">最も最近のエピソード:\u0020</string>
@@ -112,7 +118,7 @@
<string name="share_feed_url_label">フィード URLを共有</string>
<string name="share_item_url_label">エピソードファイル URLを共有</string>
<string name="share_item_url_with_position_label">エピソードファイル URL を位置と共に共有</string>
- <string name="feed_delete_confirmation_msg">このフィードと、このフィードのダウンロードしたすべてのエピソードを削除することを確認してください。</string>
+ <string name="feed_delete_confirmation_msg">フィード \"%1$s\" と、このフィードのすべてのダウンロードしたエピソードを削除することを確認してください。</string>
<string name="feed_remover_msg">フィードの削除中</string>
<string name="load_complete_feed">フィードをすべて更新</string>
<string name="hide_episodes_title">エピソードを非表示にする</string>
@@ -361,8 +367,10 @@
<string name="pref_gpodnet_notifications_sum">この設定は、認証エラーには適用されません。</string>
<string name="pref_playback_speed_title">再生速度</string>
<string name="pref_playback_speed_sum">可変速度音声再生に使用可能な速度をカスタマイズします</string>
- <string name="pref_fast_forward">早送り時間</string>
- <string name="pref_rewind">巻き戻し時間</string>
+ <string name="pref_fast_forward">早送りのスキップ時間</string>
+ <string name="pref_fast_forward_sum">早送りボタンがクリックされたときにジャンプする秒数をカスタマイズします</string>
+ <string name="pref_rewind">巻き戻しスキップ時間</string>
+ <string name="pref_rewind_sum">巻き戻しボタンがクリックされたときに後方にジャンプする秒数をカスタマイズします</string>
<string name="pref_gpodnet_sethostname_title">ホスト名をセット</string>
<string name="pref_gpodnet_sethostname_use_default_host">デフォルトホストを使用</string>
<string name="pref_expandNotify_title">拡張通知</string>
@@ -398,6 +406,8 @@
<string name="pref_cast_title">Chromecast サポート</string>
<string name="pref_cast_message_play_flavor">(Chromecast、オーディオスピーカー、Android TV など) キャストデバイス上でリモートメディア再生のサポートを有効にします</string>
<string name="pref_cast_message_free_flavor">Chromecast は AntennaPod のこのバージョンで無効になっているサードパーティ独自のライブラリーが必要です</string>
+ <string name="pref_enqueue_downloaded_title">ダウンロード済みをキューに入れる</string>
+ <string name="pref_enqueue_downloaded_summary">ダウンロードしたエピソードをキューに追加します</string>
<!--Auto-Flattr dialog-->
<string name="auto_flattr_enable">自動Flattrを有効にする</string>
<string name="auto_flattr_after_percent">%d %再生したらエピソードをFlattr </string>
@@ -407,6 +417,8 @@
<string name="search_hint">エピソードの検索</string>
<string name="found_in_shownotes_label">ショーノートで見つかりました</string>
<string name="found_in_chapters_label">チャプターで見つかりました</string>
+ <string name="found_in_authors_label">作者で見つかりました</string>
+ <string name="found_in_feeds_label">フィードで見つかりました</string>
<string name="search_status_no_results">見つかりませんでした</string>
<string name="search_label">検索</string>
<string name="found_in_title_label">タイトルで見つかりました</string>
diff --git a/core/src/main/res/values-kn-rIN/strings.xml b/core/src/main/res/values-kn-rIN/strings.xml
index 118b28979..3d24900c9 100644
--- a/core/src/main/res/values-kn-rIN/strings.xml
+++ b/core/src/main/res/values-kn-rIN/strings.xml
@@ -28,7 +28,6 @@
<string name="feedurl_label">ಫೀಡ್ ಯು.ಆರ್.ಎಲ್</string>
<!--Actions on feeds-->
<string name="show_info_label">ಮಾಹಿತಿ ತೋರಿಸು</string>
- <string name="feed_delete_confirmation_msg">ನೀವು ಈ ಫೀಡ್ ಮತ್ತು ನೀವು ಡೌನ್ಲೋಡ್ ಮಾಡಿದ ಈ ಫೀಡ್ನ ಎಲ್ಲಾ ಕಂತುಗಳು ಅಳಿಸಲು ಬಯಸುತ್ತೀರಿ ಎಂಬುದನ್ನು ದಯವಿಟ್ಟು ದೃಢಪಡಿಸಿ.</string>
<!--actions on feeditems-->
<string name="download_label">ಡೌನ್ಲೋಡ್</string>
<string name="play_label">ಚಾಲನೆಗೊಳಿಸು</string>
diff --git a/core/src/main/res/values-ko/strings.xml b/core/src/main/res/values-ko/strings.xml
index 53235d737..fc8f59be7 100644
--- a/core/src/main/res/values-ko/strings.xml
+++ b/core/src/main/res/values-ko/strings.xml
@@ -36,6 +36,7 @@
<string name="drawer_feed_counter_new_unplayed">새로운 에피소드와 재생하지 않은 에피소드 수</string>
<string name="drawer_feed_counter_new">새로운 에피소드 수</string>
<string name="drawer_feed_counter_unplayed">재생하지 않은 에피소드 수</string>
+ <string name="drawer_feed_counter_downloaded">다운로드한 에피소드 수</string>
<string name="drawer_feed_counter_none">없음</string>
<!--Webview actions-->
<string name="open_in_browser_label">브라우저에서 열기</string>
@@ -50,6 +51,7 @@
<string name="cancel_label">취소</string>
<string name="yes">예</string>
<string name="no">아니요</string>
+ <string name="reset">초기화</string>
<string name="author_label">저자</string>
<string name="language_label">언어</string>
<string name="url_label">URL</string>
@@ -91,6 +93,7 @@
<string name="etxtFeedurlHint">피드의 URL 또는 홈페이지</string>
<string name="txtvfeedurl_label">URL로 팟캐스트를 추가</string>
<string name="podcastdirectories_label">디렉터리에서 팟캐스트 찾기</string>
+ <string name="podcastdirectories_descr">새 팟캐스트는 iTunes, fyyd, gpodder.net에서 이름, 분류, 인기로 검색할 수 있습니다.</string>
<string name="browse_gpoddernet_label">gpodder.net 둘러보기</string>
<!--Actions on feeds-->
<string name="mark_all_read_label">모두 재생했다고 표시</string>
@@ -98,7 +101,10 @@
<string name="mark_all_read_confirmation_msg">모든 에피소드를 재생했다고 표시할지 확인하십시오.</string>
<string name="mark_all_read_feed_confirmation_msg">이 피드에 들어 있는 모든 에피소드를 재생했다고 표시할지 확인하십시오.</string>
<string name="mark_all_seen_label">모두 봤다고 표시</string>
+ <string name="mark_all_seen_msg">모든 에피소드를 봤다고 표시했습니다</string>
+ <string name="mark_all_seen_confirmation_msg">모든 에피소드를 본 것으로 표시하는지 확인하십시오.</string>
<string name="show_info_label">정보 표시</string>
+ <string name="rename_feed_label">팟캐스트 이름 바꾸기</string>
<string name="remove_feed_label">팟캐스트 제거</string>
<string name="share_label">공유…</string>
<string name="share_link_label">홈페이지 링크 공유</string>
@@ -106,7 +112,6 @@
<string name="share_feed_url_label">피드 URL 공유</string>
<string name="share_item_url_label">에피소드 파일 URL 공유</string>
<string name="share_item_url_with_position_label">에피소드 파일 URL과 재생 위치 공유</string>
- <string name="feed_delete_confirmation_msg">이 피드와 이 피드에서 다운로드한 모든 에피소드를 삭제하시려면 확인을 누르십시오.</string>
<string name="feed_remover_msg">피드 삭제하는 중</string>
<string name="load_complete_feed">전체 피드 새로고침</string>
<string name="hide_episodes_title">에피소드 감추기</string>
@@ -118,6 +123,7 @@
<string name="hide_not_queued_episodes_label">대기열 추가 안 함</string>
<string name="hide_downloaded_episodes_label">다운로드함</string>
<string name="hide_not_downloaded_episodes_label">다운로드 안 함</string>
+ <string name="hide_has_media_label">미디어 있음</string>
<string name="filtered_label">필터링함</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} 최근 새로 고침 실패</string>
<string name="open_podcast">팟캐스트 열기</string>
@@ -128,10 +134,11 @@
<string name="stop_label">중지</string>
<string name="stream_label">스트리밍</string>
<string name="remove_label">제거</string>
+ <string name="delete_label">삭제</string>
<string name="remove_episode_lable">에피소드 제거</string>
- <string name="marked_as_seen_label">봤다고 표시</string>
+ <string name="marked_as_seen_label">봤다고 표시했습니다</string>
<string name="mark_read_label">재생했다고 표시</string>
- <string name="marked_as_read_label">재생했다고 표시함</string>
+ <string name="marked_as_read_label">재생했다고 표시했습니다</string>
<string name="mark_unread_label">재생하지 않음으로 표시</string>
<string name="add_to_queue_label">대기열에 추가</string>
<string name="added_to_queue_label">대기열에 추가함</string>
@@ -271,13 +278,13 @@
<string name="pref_pauseOnDisconnect_sum">헤드폰이나 블루투스가 연결 해제되었을 경우 일시정지합니다.</string>
<string name="pref_unpauseOnHeadsetReconnect_sum">헤드폰 다시 연결할 때 재생을 계속합니다.</string>
<string name="pref_unpauseOnBluetoothReconnect_sum">블루투스가 다시 연결되면 재생을 계속합니다.</string>
- <string name="pref_hardwareForwardButtonSkips_title">빨리감기 버튼을 넘김 버튼으로</string>
<string name="pref_hardwareForwardButtonSkips_sum">빨리감기 하드웨어 버튼을 눌렀을 경우 빨리감기 대신 다음 에피소드로 넘깁니다.</string>
+ <string name="pref_hardwarePreviousButtonRestarts_title">이전 버튼을 누르면 재시작</string>
+ <string name="pref_hardwarePreviousButtonRestarts_sum">하드웨어 이전 버튼을 누르면 뒤로감기 대신 현재 에피소드를 재시작합니다</string>
<string name="pref_followQueue_sum">재생을 마쳤을 때 다음 대기열로 이동</string>
<string name="pref_auto_delete_sum">재생이 끝나면 에피소드를 삭제합니다.</string>
<string name="pref_auto_delete_title">자동 삭제</string>
<string name="pref_smart_mark_as_played_sum">재생이 일정한 시간보다 (초 단위) 적게 남으면 에피소드를 재생한 것으로 표시</string>
- <string name="pref_smart_mark_as_played_title">똑똑하게 재생한 것으로 표시</string>
<string name="pref_skip_keeps_episodes_sum">에피소드를 넘겼을 경우에도 유지합니다.</string>
<string name="pref_skip_keeps_episodes_title">넘긴 에피소드 유지 보관</string>
<string name="playback_pref">재생</string>
@@ -339,12 +346,18 @@
<string name="pref_gpodnet_logout_toast">로그아웃 성공</string>
<string name="pref_gpodnet_setlogin_information_title">로그인 정보 바꾸기</string>
<string name="pref_gpodnet_setlogin_information_sum">gpodder.net 계정의 로그인 정보를 바꿉니다.</string>
+ <string name="pref_gpodnet_sync_changes_title">변경 사항 지금 동기화</string>
+ <string name="pref_gpodnet_sync_changes_sum">gpodder.net의 구독과 에피소드 상태 변화를 동기화합니다.</string>
+ <string name="pref_gpodnet_full_sync_title">지금 전체 동기화</string>
+ <string name="pref_gpodnet_full_sync_sum">gpodder.net의 모든 구독과 에피소드 상태를 동기화합니다.</string>
+ <string name="pref_gpodnet_sync_sum_last_sync_line">최근 동기화 시도: %1$s (%2$s)</string>
<string name="pref_gpodnet_sync_started">동기화 시작함</string>
+ <string name="pref_gpodnet_full_sync_started">전체 동기화 시작함</string>
<string name="pref_gpodnet_login_status"><![CDATA[<i>%1$s</i> 사용자로 로그인, <i>%2$s</i> 장치]]></string>
+ <string name="pref_gpodnet_notifications_title">동기화 오류 알림 표시</string>
+ <string name="pref_gpodnet_notifications_sum">이 설정은 인증 오류에는 적용되지 않습니다.</string>
<string name="pref_playback_speed_title">재생 속도</string>
<string name="pref_playback_speed_sum">여러가지 오디오 재생 속도 직접 설정</string>
- <string name="pref_fast_forward">빠르게 감기 시간</string>
- <string name="pref_rewind">뒤로 감기 시간</string>
<string name="pref_gpodnet_sethostname_title">호스트 이름 설정</string>
<string name="pref_gpodnet_sethostname_use_default_host">기본 호스트 사용</string>
<string name="pref_expandNotify_title">알림 확장</string>
@@ -369,7 +382,6 @@
<string name="crash_report_sum">최근의 이상 종료 보고서를 이메일로 보냅니다.</string>
<string name="send_email">이메일 보내기</string>
<string name="experimental_pref">실험적 기능</string>
- <string name="pref_sonic_title">소닉 미디어 플레이어</string>
<string name="pref_sonic_message">내장 소닉 미디어 플레이어를 안드로이드 고유 미디어 플레이어와 Prestissimo 대신 사용합니다.</string>
<string name="pref_current_value">현재 값: %1$s</string>
<string name="pref_proxy_title">프록시</string>
@@ -386,10 +398,13 @@
<string name="auto_flattr_ater_beginning">재생이 시작하면 에피소드 flattr</string>
<string name="auto_flattr_ater_end">재생이 끝나면 에피소드 flattr</string>
<!--Search-->
+ <string name="search_hint">에피소드 검색</string>
+ <string name="found_in_shownotes_label">프로그램 메모에서 </string>
<string name="found_in_chapters_label">챕터에서 발견</string>
<string name="search_status_no_results">검색 결과가 없습니다</string>
<string name="search_label">검색</string>
<string name="found_in_title_label">제목에서 발견</string>
+ <string name="no_results_for_query">\"%1$s\" 검색 결과가 없습니다</string>
<!--OPML import and export-->
<string name="opml_import_txtv_button_lable">OPML 파일을 이용하면 팟캐스트 목록을 한 팟캐스트 프로그램에서 다른 팟캐스트 프로그램으로 옮길 수 있습니다.</string>
<string name="opml_import_option">옵션 %1$d</string>
@@ -408,6 +423,7 @@
<string name="choose_file_from_filesystem">로컬 파일시스템에서</string>
<string name="choose_file_from_external_application">외부 앱 사용</string>
<string name="opml_export_label">OPML 내보내기</string>
+ <string name="html_export_label">HTML 내보내기</string>
<string name="exporting_label">내보내는 중…</string>
<string name="export_error_label">내보내기 오류</string>
<string name="opml_export_success_title">OPML 내보내기가 성공했습니다.</string>
@@ -435,6 +451,9 @@
<plurals name="time_hours_quantified">
<item quantity="other">%d시간</item>
</plurals>
+ <string name="auto_enable_label">자동 사용</string>
+ <string name="sleep_timer_enabled_label">취침 타이머 사용함</string>
+ <string name="sleep_timer_disabled_label">취침 타이머 해제함</string>
<!--gpodder.net-->
<string name="gpodnet_taglist_header">분류</string>
<string name="gpodnet_toplist_header">상위 팟캐스트</string>
@@ -464,6 +483,8 @@
<string name="gpodnetsync_auth_error_descr">잘못된 사용자 이름 또는 암호</string>
<string name="gpodnetsync_error_title">gpodder.net 동기화 오류</string>
<string name="gpodnetsync_error_descr">동기화 중에 오류가 발생했습니다:\u0020</string>
+ <string name="gpodnetsync_pref_report_successful">성공</string>
+ <string name="gpodnetsync_pref_report_failed">실패</string>
<!--Directory chooser-->
<string name="selected_folder_label">선택한 폴더:</string>
<string name="create_folder_label">폴더 만들기</string>
@@ -516,6 +537,7 @@
<string name="sp_apps_importing_feeds_msg">단일 용도 앱에서 구독 정보를 가져옵니다...</string>
<string name="search_itunes_label">iTunes 검색</string>
<string name="filter">필터</string>
+ <string name="search_fyyd_label">fyyd 검색</string>
<!--Episodes apply actions-->
<string name="all_label">모두</string>
<string name="selected_all_label">모든 에피소드 선택함</string>
@@ -533,6 +555,8 @@
<string name="selected_queued_label">대기열의 에피소드 선택함</string>
<string name="not_queued_label">대기열에 없음</string>
<string name="selected_not_queued_label">대기열 외의 에피소드 선택함</string>
+ <string name="has_media">미디어 있음</string>
+ <string name="selected_has_media_label">미디어가 있는 에피소드 선택함</string>
<!--Sort-->
<string name="sort_title_a_z">제목 (A \u2192 Z)</string>
<string name="sort_title_z_a">제목 (Z \u2192 A)</string>
diff --git a/core/src/main/res/values-lt/strings.xml b/core/src/main/res/values-lt/strings.xml
index 798715fb3..7595d23e7 100644
--- a/core/src/main/res/values-lt/strings.xml
+++ b/core/src/main/res/values-lt/strings.xml
@@ -10,21 +10,40 @@
<string name="new_label">Nauji</string>
<string name="settings_label">Nustatymai</string>
<string name="add_new_feed_label">Pridėti tinklalaidę</string>
+ <string name="downloads_label">Atsiuntimai</string>
<string name="downloads_running_label">Vykdomi</string>
<string name="downloads_completed_label">Užbaigti</string>
<string name="downloads_log_label">Žurnalas</string>
<string name="subscriptions_label">Prenumeratos</string>
<string name="subscriptions_list_label">Prenumeratų sąrašas</string>
+ <string name="cancel_download_label">Atšaukti\natsiuntimą</string>
+ <string name="playback_history_label">Atkūrimo istorija</string>
<string name="gpodnet_main_label">gpodder.net</string>
<string name="gpodnet_auth_label">gpodder.net prisijungimas</string>
+ <string name="free_space_label">%1$s laisva</string>
+ <string name="episode_cache_full_title">Epizodų podėlis pilnas</string>
<!--Statistics fragment-->
+ <string name="total_time_listened_to_podcasts">Bendra perklausytų tinklalaidžių trukmė:</string>
+ <string name="statistics_mode">Statistikos režimas</string>
<!--Main activity-->
<string name="drawer_open">Atverti meniu</string>
<string name="drawer_close">Uždaryti meniu</string>
+ <string name="drawer_preferences">Stalčiuko parinktys</string>
+ <string name="drawer_feed_order_unplayed_episodes">Rikiuoti pagal skaitliuko reikšmę</string>
+ <string name="drawer_feed_order_alphabetical">Rikiuoti pagal abėcėlę</string>
+ <string name="drawer_feed_order_last_update">Rikiuoti pagal publikavimo datą</string>
+ <string name="drawer_feed_order_most_played">Rikiuoti pagal perklausytų epizodų kiekį</string>
+ <string name="drawer_feed_counter_new_unplayed">Naujų, dar neperklausytų epizodų skaičius</string>
+ <string name="drawer_feed_counter_new">Naujų epizodų skaičius</string>
+ <string name="drawer_feed_counter_unplayed">Neperklausytų epizodų skaičius</string>
+ <string name="drawer_feed_counter_downloaded">Atsisiųstų epizodų skaičius</string>
+ <string name="drawer_feed_counter_none">Nėra</string>
<!--Webview actions-->
<string name="open_in_browser_label">Atverti naršyklėje</string>
<string name="copy_url_label">Kopijuoti URL</string>
<string name="share_url_label">Dalintis URL</string>
+ <string name="copied_url_msg">URL nukopijuotas į iškarpinę</string>
+ <string name="go_to_position_label">Peršokti į šią poziciją</string>
<!--Playback history-->
<string name="clear_history_label">Išvalyti istoriją</string>
<!--Other-->
@@ -32,37 +51,72 @@
<string name="cancel_label">Atšaukti</string>
<string name="yes">Taip</string>
<string name="no">Ne</string>
+ <string name="reset">Nustatyti iš naujo</string>
<string name="author_label">Autorius</string>
<string name="language_label">Kalba</string>
<string name="url_label">URL</string>
<string name="podcast_settings_label">Nustatymai</string>
+ <string name="cover_label">Paveikslėlis</string>
<string name="error_label">Klaida</string>
<string name="error_msg_prefix">Įvyko klaida:</string>
<string name="refresh_label">Atnaujinti</string>
<string name="chapters_label">Skyriai</string>
+ <string name="chapter_duration">Trukmė: %1$s</string>
+ <string name="shownotes_label">Laidos užrašai</string>
<string name="description_label">Aprašymas</string>
+ <string name="most_recent_prefix">Naujausias epizodas:\u0020</string>
<string name="episodes_suffix">\u0020epizodai</string>
<string name="length_prefix">Trukmė:\u0020</string>
<string name="size_prefix">Dydis:\u0020</string>
<string name="processing_label">Apdorojama</string>
<string name="loading_label">Kraunama...</string>
<string name="save_username_password_label">Išsaugoti vartotojo vardą ir slaptažodį</string>
+ <string name="close_label">Užverti</string>
<string name="retry_label">Bandyti vėl</string>
+ <string name="auto_delete_label">Automatiškai trinti epizodus</string>
<string name="feed_auto_download_always">Visada</string>
<string name="feed_auto_download_never">Niekada</string>
<string name="send_label">Siųsti...</string>
<string name="episode_cleanup_never">Niekada</string>
+ <string name="episode_cleanup_queue_removal">Jei nėra eilėje</string>
+ <string name="episode_cleanup_after_listening">Pabaigus klausyti</string>
+ <plurals name="episode_cleanup_days_after_listening">
+ <item quantity="one">Praėjus dienai nuo perklausymo</item>
+ <item quantity="few">Praėjus %d dienoms nuo perklausymo</item>
+ <item quantity="other">Praėjus %d dienoms nuo perklausymo</item>
+ </plurals>
<!--'Add Feed' Activity labels-->
<string name="feedurl_label">Sklaidos kanalo URL</string>
+ <string name="etxtFeedurlHint">www.example.com/feed</string>
+ <string name="txtvfeedurl_label">Pridėti tinklalaidę pagal URL adresą</string>
+ <string name="browse_gpoddernet_label">Naršyti gpodder.net svetainėje</string>
<!--Actions on feeds-->
+ <string name="mark_all_read_label">Pažymėti visus kaip perklausytus</string>
+ <string name="mark_all_read_msg">Visi epizodai pažymėti kaip perklausyti</string>
+ <string name="mark_all_read_confirmation_msg">Patvirtinkite, jog norite pažymėti visus epizodus kaip perklausytus.</string>
+ <string name="mark_all_seen_label">Pažymėti visus kaip matytus</string>
+ <string name="mark_all_seen_msg">Visi epizodai pažymėti kaip matyti</string>
+ <string name="mark_all_seen_confirmation_msg">Patvirtinkite, jog norite pažymėti visus epizodus kaip matytus.</string>
<string name="show_info_label">Rodyti informaciją</string>
+ <string name="rename_feed_label">Pervadinti tinklalaidę</string>
<string name="remove_feed_label">Pašalinti tinklalaidę</string>
<string name="share_label">Dalintis...</string>
<string name="share_link_label">Dalintis nuoroda</string>
<string name="share_feed_url_label">Dalintis sklaidos kanalo URL</string>
<string name="share_item_url_label">Dalintis epizodo failo URL</string>
<string name="feed_remover_msg">Šalinamas sklaidos kanalas</string>
+ <string name="load_complete_feed">Atnaujinti visą sklaidos kanalą</string>
<string name="hide_episodes_title">Slėpti epizodus</string>
+ <string name="episode_actions">Pritaikyti veiksmus</string>
+ <string name="hide_unplayed_episodes_label">Neperklausyti</string>
+ <string name="hide_paused_episodes_label">Pristabdyti</string>
+ <string name="hide_played_episodes_label">Perklausyti</string>
+ <string name="hide_queued_episodes_label">Esantys eilėje</string>
+ <string name="hide_not_queued_episodes_label">Nesantys eilėje</string>
+ <string name="hide_downloaded_episodes_label">Atsiųsti</string>
+ <string name="hide_not_downloaded_episodes_label">Neatsiųsti</string>
+ <string name="hide_has_media_label">Turintys medijos failų</string>
+ <string name="refresh_failed_msg">{fa-exclamation-circle} Paskutinis atnaujinimas nepavyko</string>
<string name="open_podcast">Atverti tinklalaidę</string>
<!--actions on feeditems-->
<string name="download_label">Atsisiųsti</string>
@@ -70,41 +124,91 @@
<string name="pause_label">Pristabdyti</string>
<string name="stop_label">Sustabdyti</string>
<string name="remove_label">Pašalinti</string>
+ <string name="delete_label">Ištrinti</string>
<string name="remove_episode_lable">Pašalinti epizodą</string>
+ <string name="mark_read_label">Pažymėti kaip perklausytą</string>
+ <string name="marked_as_read_label">Pažymėtas kaip perklausytas</string>
+ <string name="mark_unread_label">Pažymėti kaip neperklausytą</string>
<string name="add_to_queue_label">Pridėti į eilę</string>
<string name="added_to_queue_label">Pridėtas į eilę</string>
<string name="remove_from_queue_label">Pašalinti iš eilės</string>
+ <string name="add_to_favorite_label">Pridėti prie mėgstamiausių</string>
+ <string name="added_to_favorites">Pridėtas prie mėgstamiausių</string>
+ <string name="remove_from_favorite_label">Pašalinti iš mėgstamiausių</string>
+ <string name="removed_from_favorites">Pašalintas iš mėgstamiausių</string>
+ <string name="visit_website_label">Aplankyti svetainę</string>
<string name="skip_episode_label">Praleisti epizodą</string>
+ <string name="activate_auto_download">Įjungti automatinį atsiuntimą</string>
+ <string name="deactivate_auto_download">Išjungti automatinį atsiuntimą</string>
+ <string name="reset_position">Nustatyti atkūrimo poziciją iš naujo</string>
<!--Download messages and labels-->
<string name="download_successful">sėkmingi</string>
<string name="download_failed">nepavyko</string>
+ <string name="download_running">Atsiuntimas vyksta</string>
+ <string name="download_error_insufficient_space">Trūksta laisvos vietos</string>
<string name="download_error_file_error">Failo klaida</string>
<string name="download_error_http_data_error">HTTP duomenų klaida</string>
<string name="download_error_error_unknown">Nežinoma klaida</string>
<string name="download_error_unsupported_type">Nepalaikomas sklaidos kanalo tipas</string>
<string name="download_error_connection_error">Susijungimo klaida</string>
+ <string name="download_error_unauthorized">Autentifikacijos klaida</string>
+ <string name="download_error_file_type_type">Failo tipo klaida</string>
+ <string name="download_error_forbidden">Uždrausta</string>
<string name="cancel_all_downloads_label">Atšaukti visus atsiuntimus</string>
+ <string name="download_canceled_msg">Atsiuntimas atšauktas</string>
<string name="download_report_content_title">Atsiuntimų ataskaita</string>
+ <string name="download_error_malformed_url">Netvarkingas URL</string>
+ <string name="download_error_io_error">Įvesties/išvesties klaida</string>
<string name="download_error_request_error">Užklausos klaida</string>
+ <string name="download_error_db_access">Duomenų bazės prieigos klaida</string>
+ <string name="downloads_processing">Apdorojami atsiuntimai</string>
<string name="download_notification_title">Atsiunčiami tinklalaidės duomenys</string>
+ <string name="download_log_title_unknown">Nežinomas pavadinimas</string>
<string name="download_type_feed">Sklaidos kanalas</string>
+ <string name="download_type_media">Medijos failas</string>
+ <string name="download_type_image">Paveikslėlis</string>
+ <string name="download_request_error_dialog_message_prefix">Įvyko klaida bandant atsisiųsti failą:\u0020</string>
<string name="authentication_notification_title">Reikalinga autentifikacija</string>
+ <string name="authentication_notification_msg">Šis išteklius reikalauja vartotojo vardo bei slaptažodžio</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">Pridėti į eilę</string>
+ <string name="confirm_mobile_download_dialog_enable_temporarily">Laikinai leisti</string>
<!--Mediaplayer messages-->
<string name="player_error_msg">Klaida!</string>
+ <string name="player_stopped_msg">Atkūrimas nevyksta</string>
+ <string name="player_preparing_msg">Ruošiamasi</string>
+ <string name="player_ready_msg">Pasiruošęs</string>
+ <string name="playback_error_unknown">Nežinoma klaida</string>
+ <string name="no_media_playing_label">Atkūrimas nevyksta</string>
+ <string name="player_buffering_msg">Buferizuojama</string>
+ <string name="playbackservice_notification_title">Atkuriama tinklalaidė</string>
<!--Queue operations-->
<string name="lock_queue">Užrakinti eilę</string>
<string name="unlock_queue">Atrakinti eilę</string>
<string name="queue_locked">Eilė užrakinta</string>
<string name="queue_unlocked">Eilė atrakinta</string>
<string name="clear_queue_label">Išvalyti eilę</string>
- <string name="ascending">Didėjančiai</string>
- <string name="descending">Mažėjančiai</string>
+ <string name="undo">Atšaukti</string>
+ <string name="removed_from_queue">Elementas pašalintas</string>
+ <string name="move_to_top_label">Perkelti į viršų</string>
+ <string name="move_to_bottom_label">Perkelti į apačią</string>
+ <string name="sort">Rikiuoti</string>
+ <string name="date">Data</string>
+ <string name="duration">Trukmė</string>
+ <string name="episode_title">Epizodo pavadinimas</string>
+ <string name="feed_title">Sklaidos kanalo pavadinimas</string>
+ <string name="ascending">Didėjančia tvarka</string>
+ <string name="descending">Mažėjančia tvarka</string>
<!--Flattr-->
<string name="action_forbidden_title">Veiksmas uždraustas</string>
<!--Flattr-->
<!--Variable Speed-->
+ <string name="download_plugin_label">Atsiųsti įskiepį</string>
+ <string name="no_playback_plugin_title">Įskiepis neįdiegtas</string>
+ <string name="set_playback_speed_label">Atkūrimo spartos</string>
<!--Empty list labels-->
+ <string name="no_items_label">Šiame sąraše nėra elementų.</string>
+ <string name="no_feeds_label">Kol kas nesate užsiprenumeravę jokio sklaidos kanalo.</string>
+ <string name="no_shownotes_label">Šis epizodas neturi užrašų.</string>
<!--Preferences-->
<string name="project_pref">Projektas</string>
<string name="other_pref">Kita</string>
@@ -112,42 +216,145 @@
<string name="queue_label">Eilė</string>
<string name="services_label">Paslaugos</string>
<string name="flattr_label">Flattr</string>
+ <string name="pref_episode_cleanup_title">Epizodų valymas</string>
+ <string name="pref_episode_cleanup_summary">Epizodai, nesantys eilėje ar tarp mėgstamiausiųjų, gali būti ištrinti automatinio atsiuntimo metu pritrūkus laisvos vietos naujiems epizodams </string>
+ <string name="pref_pauseOnDisconnect_sum">Pristabdyti atkūrimą, kai atjungiamos ausinės ar „Bluetooth“</string>
+ <string name="pref_unpauseOnHeadsetReconnect_sum">Pratęsti atkūrimą, kai ausinės pakartotinai prijungiamos</string>
+ <string name="pref_unpauseOnBluetoothReconnect_sum">Pratęsti atkūrimą, kai pakartotinai prisijungiama prie „Bluetooth“</string>
+ <string name="pref_auto_delete_title">Automatinis trynimas</string>
+ <string name="pref_skip_keeps_episodes_sum">Palikti epizodus, kai šie praleidžiami</string>
+ <string name="pref_skip_keeps_episodes_title">Palikti praleistus epizodus</string>
<string name="playback_pref">Atkūrimas</string>
<string name="network_pref">Tinklas</string>
+ <string name="pref_pauseOnHeadsetDisconnect_title">Ausinių atjungimas</string>
+ <string name="pref_unpauseOnHeadsetReconnect_title">Pakartotinai prijungus ausines</string>
+ <string name="pref_unpauseOnBluetoothReconnect_title">Pakartotinai prisijungus prie „Bluetooth“</string>
+ <string name="refreshing_label">Atnaujinama</string>
<string name="user_interface_label">Vartotojo sąsaja</string>
<string name="pref_set_theme_title">Pasirinkti temą</string>
+ <string name="pref_set_theme_sum">Keisti AntennaPod išvaizdą.</string>
+ <string name="pref_automatic_download_title">Automatinis atsiuntimas</string>
+ <string name="pref_parallel_downloads_title">Lygiagretūs atsiuntimai</string>
<string name="pref_episode_cache_title">Epizodų podėlis</string>
<string name="pref_theme_title_light">Šviesi</string>
<string name="pref_theme_title_dark">Tamsi</string>
+ <string name="pref_update_interval_hours_plural">valandos</string>
+ <string name="pref_update_interval_hours_singular">valanda</string>
+ <string name="pref_update_interval_hours_manual">Rankinis</string>
<string name="pref_gpodnet_logout_title">Atsijungti</string>
<string name="pref_gpodnet_logout_toast">Sėkmingai atsijungta</string>
+ <string name="pref_gpodnet_setlogin_information_title">Keisti prisijungimo duomenis</string>
+ <string name="pref_gpodnet_sync_changes_title">Sinchronizuoti pakeitimus dabar</string>
+ <string name="pref_gpodnet_sync_started">Pradėtas sinchronizavimas</string>
+ <string name="pref_gpodnet_notifications_title">Rodyti sinchronizavimo klaidų pranešimus</string>
+ <string name="pref_gpodnet_notifications_sum">Šis nustatymas negalioja autentifikacijos klaidoms.</string>
+ <string name="pref_playback_speed_title">Atkūrimo sparta</string>
+ <string name="pref_playback_speed_sum">Pasirinkite prieinamas garso atkūrimo spartas</string>
+ <string name="pref_persistNotify_sum">Pristabdžius atkūrimą palikti valdiklius ekrano užrakte bei programų pranešimuose. </string>
+ <string name="pref_compact_notification_buttons_title">Nustatyti ekrano užrakto mygtukus</string>
+ <string name="pref_compact_notification_buttons_sum">Keisti ekrano užrakte matomus atkūrimo valdymo mygtukus. Atkūrimo/pristabdymo mygtukas matomas visada.</string>
+ <string name="pref_lockscreen_background_title">Nustatyti ekrano užrakto foną</string>
+ <string name="pref_lockscreen_background_sum">Atkuriamo epizodo paveikslėlį naudoti kaip ekrano užrakto foną. Paveikslėlis taip pat bus matomas trečiųjų šalių programėlėse.</string>
+ <string name="pref_showDownloadReport_title">Rodyti atsiuntimų ataskaitą</string>
<string name="pref_queueAddToFront_sum">Naujus epizodus dėti į eilės priekį.</string>
<string name="pref_queueAddToFront_title">Dėti į eilės priekį</string>
+ <string name="pref_smart_mark_as_played_disabled">Išjungtas</string>
+ <string name="pref_image_cache_size_title">Paveikslėlių podėlio dydis</string>
+ <string name="pref_image_cache_size_sum">Paveikslėlių podėlio diske dydis.</string>
+ <string name="send_email">Siųsti el. laišką</string>
+ <string name="pref_current_value">Dabartinė reikšmė: %1$s</string>
<string name="pref_faq">DUK</string>
+ <string name="pref_known_issues">Žinomos problemos</string>
<string name="pref_no_browser_found">Nerasta jokia interneto naršyklė.</string>
<string name="pref_cast_title">„Chromecast“ palaikymas</string>
<!--Auto-Flattr dialog-->
<!--Search-->
<!--OPML import and export-->
+ <string name="start_import_label">Pradėti importą</string>
+ <string name="opml_import_label">OPML importas</string>
<string name="opml_directory_error">KLAIDA!</string>
+ <string name="reading_opml_label">Skaitomas OPML failas</string>
+ <string name="opml_reader_error">Skaitant OPML failą įvyko klaida:</string>
+ <string name="opml_import_error_no_file">Nepasirinktas failas!</string>
+ <string name="select_all_label">Pažymėti visus</string>
+ <string name="deselect_all_label">Nepažymėti nieko</string>
+ <string name="select_options_label">Pasirinkti...</string>
+ <string name="opml_export_label">OPML eksportas</string>
+ <string name="html_export_label">HTML eksportas</string>
+ <string name="exporting_label">Eksportuojama...</string>
+ <string name="export_error_label">Eksporto klaida</string>
<!--Sleep timer-->
+ <string name="set_sleeptimer_label">Nustatyti miego laikmatį</string>
+ <string name="disable_sleeptimer_label">Išjungti miego laikmatį</string>
+ <string name="sleep_timer_label">Miego laikmatis</string>
+ <string name="sleep_timer_enabled_label">Miego laikmatis įjungtas</string>
+ <string name="sleep_timer_disabled_label">Miego laikmatis išjungtas</string>
<!--gpodder.net-->
+ <string name="gpodnet_search_hint">Ieškoti gpodder.net svetainėje</string>
+ <string name="gpodnetauth_login_butLabel">Prisijungti</string>
<string name="username_label">Vartotojo vardas</string>
+ <string name="password_label">Slaptažodis</string>
+ <string name="gpodnetauth_finish_title">Sėkmingai prisijungta!</string>
<string name="gpodnetsync_auth_error_descr">Neteisingas vartotojo vardas ar slaptažodis</string>
<!--Directory chooser-->
+ <string name="selected_folder_label">Pasirinktas aplankas:</string>
+ <string name="create_folder_label">Sukurti aplanką</string>
+ <string name="choose_data_directory">Pasirinkite duomenų aplanką</string>
+ <string name="choose_data_directory_message">Prašome pasirinkti pamatinį duomenų aplanką. „AntennaPod“ sukurs reikiamus poaplankius.</string>
+ <string name="choose_data_directory_permission_rationale">Norinti pakeisti duomenų aplanką reikalinga prieiga prie nešiojamos duomenų saugyklos</string>
+ <string name="create_folder_msg">Sukurti naują aplanką pavadinimu \"%1$s\"?</string>
+ <string name="create_folder_success">Sukurtas naujas aplankas</string>
+ <string name="create_folder_error_no_write_access">Nepavyksta rašyti šiame aplanke</string>
+ <string name="create_folder_error_already_exists">Aplankas jau egzistuoja</string>
+ <string name="create_folder_error">Nepavyko sukurti aplanko</string>
+ <string name="folder_not_empty_dialog_title">Aplankas nėra tuščias</string>
+ <string name="folder_not_empty_dialog_msg">Jūsų pasirinktas aplankas nėra tuščias. Medijų atsisiuntimai bei kiti failai bus saugomi būtent šiame aplanke. Ar norite tęsti?</string>
+ <string name="set_to_default_folder">Pasirinkite numatytąjį aplanką</string>
+ <string name="pref_resumeAfterCall_sum">Pratęsti atkūrimą užbaigus pokalbį telefonu</string>
+ <string name="pref_resumeAfterCall_title">Pratęsti po skambučio</string>
<!--Online feed view-->
+ <string name="subscribe_label">Prenumeruoti</string>
+ <string name="downloading_label">Atsiunčiama...</string>
<!--Content descriptions for image buttons-->
+ <string name="in_queue_label">Epizodas yra eilėje</string>
+ <string name="load_next_page_label">Įkelti kitą puslapį</string>
<!--Feed information screen-->
+ <string name="authentication_label">Autentifikacija</string>
+ <string name="episode_filters_label">Epizodų filtras</string>
+ <string name="keep_updated">Pastoviai atnaujinti</string>
<!--Progress information-->
<!--AntennaPodSP-->
<!--Episodes apply actions-->
+ <string name="all_label">Visus</string>
+ <string name="none_label">Jokių</string>
+ <string name="played_label">Perklausytas</string>
+ <string name="unplayed_label">Neperklausytas</string>
+ <string name="downloaded_label">Atsiųstas</string>
+ <string name="queued_label">Eilėje</string>
+ <string name="not_queued_label">Ne eilėje</string>
<!--Sort-->
+ <string name="sort_title_a_z">Pavadinimas (A \u2192 Z)</string>
+ <string name="sort_title_z_a">Pavadinimas (Z \u2192 A)</string>
+ <string name="sort_date_new_old">Data (Nauji \u2192 Seni)</string>
+ <string name="sort_date_old_new">Data (Seni \u2192 Nauji)</string>
+ <string name="sort_duration_short_long">Trukmė (Trumpi \u2192 Ilgi)</string>
+ <string name="sort_duration_long_short">Trukmė (Ilgi \u2192 Trumpi)</string>
<!--Rating dialog-->
+ <string name="rating_never_label">Palikite mane ramybėje</string>
+ <string name="rating_later_label">Priminti vėliau</string>
+ <string name="rating_now_label">Žinoma, padarykime tai!</string>
<!--Audio controls-->
<string name="playback_speed">Atkūrimo sparta</string>
<string name="left_short">K</string>
<string name="right_short">D</string>
+ <string name="audio_effects">Garso efektai</string>
<!--proxy settings-->
+ <string name="port_label">Prievadas</string>
+ <string name="proxy_checking">Tikrinama...</string>
<!--Casting-->
+ <string name="cast_failed_to_play">Nepavyko pradėti medijos atkūrimo</string>
+ <string name="cast_failed_to_stop">Nepavyko sustabdyti medijos atkūrimo</string>
+ <string name="cast_failed_to_pause">Nepavyko pristabdyti medijos atkūrimo</string>
<!--<string name="cast_failed_to_connect">Could not connect to the device</string>-->
+ <string name="cast_failed_media_error_skipping">Įvyko medijos atkūrimo klaida. Praleidžiama...</string>
</resources>
diff --git a/core/src/main/res/values-nb/strings.xml b/core/src/main/res/values-nb/strings.xml
index fa188c3ea..13f9274ae 100644
--- a/core/src/main/res/values-nb/strings.xml
+++ b/core/src/main/res/values-nb/strings.xml
@@ -93,7 +93,6 @@
<string name="share_link_label">Del lenke</string>
<string name="share_link_with_position_label">Del lenke med plassering</string>
<string name="share_feed_url_label">Del strømmens URL</string>
- <string name="feed_delete_confirmation_msg">Vil du virkelig slette denne strømmen og alle episodene av denne strømmen du har lastet ned?</string>
<string name="feed_remover_msg">Fjerner strøm</string>
<string name="load_complete_feed">Oppdater hele strømmen</string>
<string name="hide_episodes_title">Skjul episoder</string>
@@ -239,13 +238,11 @@
<string name="pref_pauseOnDisconnect_sum">Sett playback på pause når hodetelefoner eller bluetooth er frakoblet</string>
<string name="pref_unpauseOnHeadsetReconnect_sum">Gjenoppta avspilling når hodetelefoner gjeninnkoples</string>
<string name="pref_unpauseOnBluetoothReconnect_sum">Fortsett avspilling når bluetooth er tilkoblet igjen</string>
- <string name="pref_hardwareForwardButtonSkips_title">Forover-knapp hopper</string>
<string name="pref_hardwareForwardButtonSkips_sum">Ved pressing av hardware forover-knapp hopp til neste episode istedenfor forover-spoling</string>
<string name="pref_followQueue_sum">Hopp til neste element i køen når avspillingen er ferdig</string>
<string name="pref_auto_delete_sum">Slett episode når avspillingen er ferdig</string>
<string name="pref_auto_delete_title">Automatisk sletting</string>
<string name="pref_smart_mark_as_played_sum">Marker episoder som avspilt selv om det er X antall sekunder igjen av avspillingen</string>
- <string name="pref_smart_mark_as_played_title">Smart markering av avspilt</string>
<string name="pref_skip_keeps_episodes_sum">Behold episoder når de hoppes over</string>
<string name="pref_skip_keeps_episodes_title">Behold episoder som er hoppet over</string>
<string name="playback_pref">Avspilling</string>
@@ -307,8 +304,6 @@
<string name="pref_gpodnet_setlogin_information_sum">Endre innlogginsinformasjonen til din gpodder.net konto</string>
<string name="pref_playback_speed_title">Avspillingshastigheter</string>
<string name="pref_playback_speed_sum">Egendefiner hastighetene tilgjengelig for variabel avspillingshastighet</string>
- <string name="pref_fast_forward">Spoling fremover</string>
- <string name="pref_rewind">Spoling bakover</string>
<string name="pref_gpodnet_sethostname_title">Sett vertsnavn</string>
<string name="pref_gpodnet_sethostname_use_default_host">Bruk standard vert</string>
<string name="pref_expandNotify_title">Utvid varsel</string>
@@ -329,7 +324,6 @@
<string name="crash_report_sum">Send den siste kræsj-rapporten via e-post</string>
<string name="send_email">Send e-post</string>
<string name="experimental_pref">Eksperimentell</string>
- <string name="pref_sonic_title">Sonic medieavspiller</string>
<!--Auto-Flattr dialog-->
<string name="auto_flattr_enable">Aktiver automatisk flattring</string>
<string name="auto_flattr_after_percent">Flattre episode så snart %d prosent er avspilt</string>
diff --git a/core/src/main/res/values-nl/strings.xml b/core/src/main/res/values-nl/strings.xml
index 36913c5cd..80755fc8b 100644
--- a/core/src/main/res/values-nl/strings.xml
+++ b/core/src/main/res/values-nl/strings.xml
@@ -113,7 +113,6 @@
<string name="share_feed_url_label">URL van de feed delen</string>
<string name="share_item_url_label">URL van het mediabestand delen</string>
<string name="share_item_url_with_position_label">URL van mediabestand met tijdstip delen</string>
- <string name="feed_delete_confirmation_msg">Bevestig dat u deze feed en ALLE afleveringen van deze feed die u heeft gedownload wilt verwijderen.</string>
<string name="feed_remover_msg">Feed verwijderen</string>
<string name="load_complete_feed">Hele feed vernieuwen</string>
<string name="hide_episodes_title">Afleveringen verbergen</string>
@@ -281,7 +280,6 @@
<string name="pref_pauseOnDisconnect_sum">Afspelen pauzeren wanneer de koptelefoon wordt losgekoppeld of de bluetooth verbinding wordt verbroken</string>
<string name="pref_unpauseOnHeadsetReconnect_sum">Afspelen hervatten wanneer de koptelefoon opnieuw wordt aangesloten</string>
<string name="pref_unpauseOnBluetoothReconnect_sum">Afspelen hervatten wanneer de bluetooth verbinding hervat wordt</string>
- <string name="pref_hardwareForwardButtonSkips_title">\'Volgende\' knop voor overslaan</string>
<string name="pref_hardwareForwardButtonSkips_sum">Aflevering overslaan ipv vooruitspoelen wanneer op een fysieke \'volgende\' knop wordt gedrukt</string>
<string name="pref_hardwarePreviousButtonRestarts_title">Vorige voor opnieuw afspelen</string>
<string name="pref_hardwarePreviousButtonRestarts_sum">Aflevering afspelen vanaf het begin ipv terugspoelen wanneer op een fysieke \'vorige\' knop wordt gedrukt</string>
@@ -289,7 +287,6 @@
<string name="pref_auto_delete_sum">Afleveringen verwijderen als ze zijn afgespeeld</string>
<string name="pref_auto_delete_title">Automatisch verwijderen</string>
<string name="pref_smart_mark_as_played_sum">Afleveringen als afgespeeld markeren wanneer deze nog maar een bepaald aantal seconden duurt</string>
- <string name="pref_smart_mark_as_played_title">Slimme afgespeeld markering</string>
<string name="pref_skip_keeps_episodes_sum">Afleveringen bewaren en in de wachtrij houden als u op \'overslaan\' klikt</string>
<string name="pref_skip_keeps_episodes_title">Overgeslagen afleveringen bewaren</string>
<string name="playback_pref">Afspelen</string>
@@ -363,8 +360,6 @@
<string name="pref_gpodnet_notifications_sum">Deze instelling is niet van toepassing op inlogfouten.</string>
<string name="pref_playback_speed_title">Afspeelsnelheden</string>
<string name="pref_playback_speed_sum">Pas de beschikbare snelheden aan voor de variabele audio afspeelsnelheid</string>
- <string name="pref_fast_forward">Snelheid van vooruitspoelen</string>
- <string name="pref_rewind">Snelheid terugspoelen</string>
<string name="pref_gpodnet_sethostname_title">Definieer hostname</string>
<string name="pref_gpodnet_sethostname_use_default_host">Gebruik standaard host</string>
<string name="pref_expandNotify_title">Bedienen via melding</string>
@@ -389,7 +384,6 @@
<string name="crash_report_sum">Verstuur laatste crashreport via email</string>
<string name="send_email">Verstuur email</string>
<string name="experimental_pref">Experimentele functie</string>
- <string name="pref_sonic_title">Sonic mediaspeler</string>
<string name="pref_sonic_message">Gebruik AntennaPod\'s ingebouwde Sonic mediaspeler als een alternatief voor Prestissimo en de mediaspeler van Android.</string>
<string name="pref_current_value">Huidige instelling: %1$s</string>
<string name="pref_proxy_title">Proxy</string>
diff --git a/core/src/main/res/values-no-rNB/strings.xml b/core/src/main/res/values-no-rNB/strings.xml
index 4cc52407f..56bff080b 100644
--- a/core/src/main/res/values-no-rNB/strings.xml
+++ b/core/src/main/res/values-no-rNB/strings.xml
@@ -93,7 +93,6 @@
<string name="share_link_label">Del lenke</string>
<string name="share_link_with_position_label">Del lenke med plassering</string>
<string name="share_feed_url_label">Del strømmens URL</string>
- <string name="feed_delete_confirmation_msg">Vil du virkelig slette denne strømmen og alle episodene av denne strømmen du har lastet ned?</string>
<string name="feed_remover_msg">Fjerner strøm</string>
<string name="load_complete_feed">Oppdater hele strømmen</string>
<string name="hide_episodes_title">Skjul episoder</string>
@@ -239,13 +238,11 @@
<string name="pref_pauseOnDisconnect_sum">Sett playback på pause når hodetelefoner eller bluetooth er frakoblet</string>
<string name="pref_unpauseOnHeadsetReconnect_sum">Gjenoppta avspilling når hodetelefoner gjeninnkoples</string>
<string name="pref_unpauseOnBluetoothReconnect_sum">Fortsett avspilling når bluetooth er tilkoblet igjen</string>
- <string name="pref_hardwareForwardButtonSkips_title">Forover-knapp hopper</string>
<string name="pref_hardwareForwardButtonSkips_sum">Ved pressing av hardware forover-knapp hopp til neste episode istedenfor forover-spoling</string>
<string name="pref_followQueue_sum">Hopp til neste element i køen når avspillingen er ferdig</string>
<string name="pref_auto_delete_sum">Slett episode når avspillingen er ferdig</string>
<string name="pref_auto_delete_title">Automatisk sletting</string>
<string name="pref_smart_mark_as_played_sum">Marker episoder som avspilt selv om det er X antall sekunder igjen av avspillingen</string>
- <string name="pref_smart_mark_as_played_title">Smart markering av avspilt</string>
<string name="pref_skip_keeps_episodes_sum">Behold episoder når de hoppes over</string>
<string name="pref_skip_keeps_episodes_title">Behold episoder som er hoppet over</string>
<string name="playback_pref">Avspilling</string>
@@ -307,8 +304,6 @@
<string name="pref_gpodnet_setlogin_information_sum">Endre innlogginsinformasjonen til din gpodder.net konto</string>
<string name="pref_playback_speed_title">Avspillingshastigheter</string>
<string name="pref_playback_speed_sum">Egendefiner hastighetene tilgjengelig for variabel avspillingshastighet</string>
- <string name="pref_fast_forward">Spoling fremover</string>
- <string name="pref_rewind">Spoling bakover</string>
<string name="pref_gpodnet_sethostname_title">Sett vertsnavn</string>
<string name="pref_gpodnet_sethostname_use_default_host">Bruk standard vert</string>
<string name="pref_expandNotify_title">Utvid varsel</string>
@@ -329,7 +324,6 @@
<string name="crash_report_sum">Send den siste kræsj-rapporten via e-post</string>
<string name="send_email">Send e-post</string>
<string name="experimental_pref">Eksperimentell</string>
- <string name="pref_sonic_title">Sonic medieavspiller</string>
<!--Auto-Flattr dialog-->
<string name="auto_flattr_enable">Aktiver automatisk flattring</string>
<string name="auto_flattr_after_percent">Flattre episode så snart %d prosent er avspilt</string>
diff --git a/core/src/main/res/values-pl-rPL/strings.xml b/core/src/main/res/values-pl-rPL/strings.xml
index 96d26526a..901d84b83 100644
--- a/core/src/main/res/values-pl-rPL/strings.xml
+++ b/core/src/main/res/values-pl-rPL/strings.xml
@@ -36,6 +36,7 @@
<string name="drawer_feed_counter_new_unplayed">Liczba nowych i nieodtworzonych odcinków</string>
<string name="drawer_feed_counter_new">Liczba nowych odcinków</string>
<string name="drawer_feed_counter_unplayed">Liczba nieodtworzonych odcinków</string>
+ <string name="drawer_feed_counter_downloaded">Liczba pobranych odcinków</string>
<string name="drawer_feed_counter_none">Brak</string>
<!--Webview actions-->
<string name="open_in_browser_label">Otwórz w przeglądarce</string>
@@ -50,6 +51,7 @@
<string name="cancel_label">Anuluj</string>
<string name="yes">Tak</string>
<string name="no">Nie</string>
+ <string name="reset">Reset</string>
<string name="author_label">Autor</string>
<string name="language_label">Język</string>
<string name="url_label">URL</string>
@@ -86,6 +88,7 @@
<plurals name="episode_cleanup_days_after_listening">
<item quantity="one">1 dzień po odtworzeniu</item>
<item quantity="few">%d dni po odtworzeniu</item>
+ <item quantity="many">%d dni po odtworzeniu</item>
<item quantity="other">%d dni po odtworzeniu</item>
</plurals>
<!--'Add Feed' Activity labels-->
@@ -93,6 +96,7 @@
<string name="etxtFeedurlHint">Adres URL kanału lub strony internetowej</string>
<string name="txtvfeedurl_label">Dodaj podcast przez adres</string>
<string name="podcastdirectories_label">Znajdź podcast w folderze</string>
+ <string name="podcastdirectories_descr">Możesz wyszukiwać nowe podcasty ze względu na nazwę, kategorię lub popularność na gpodder.net, Itunes lub fyyd</string>
<string name="browse_gpoddernet_label">Przeglądaj gpodder.net</string>
<!--Actions on feeds-->
<string name="mark_all_read_label">Oznacz wszystkie jako odtworzone</string>
@@ -100,7 +104,10 @@
<string name="mark_all_read_confirmation_msg">Proszę potwierdzić, że chcesz zaznaczyć wszystkie odcinki do odtworzenia.</string>
<string name="mark_all_read_feed_confirmation_msg">Proszę potwierdzić, że chcesz zaznaczyć wszystkie odcinki na tym kanale do odtworzenia.</string>
<string name="mark_all_seen_label">Oznacz wszystkie jako widziane</string>
+ <string name="mark_all_seen_msg">Zaznacz wszystkie Odcinki jako obejrzane</string>
+ <string name="mark_all_seen_confirmation_msg">Proszę potwierdzić chęć zaznaczenia wszystkich odcinków jako obejrzanych.</string>
<string name="show_info_label">Pokaż informacje</string>
+ <string name="rename_feed_label">Zmień nazwę podcast-u</string>
<string name="remove_feed_label">Usuń podcast</string>
<string name="share_label">Udostępnij...</string>
<string name="share_link_label">Udostępnij stronę</string>
@@ -108,7 +115,6 @@
<string name="share_feed_url_label">Udostępnij adres kanału</string>
<string name="share_item_url_label">Udostępnij plik URL odcinka</string>
<string name="share_item_url_with_position_label">Udostępnik plik URL odcinka z pozycją</string>
- <string name="feed_delete_confirmation_msg">Potwierdź chęć usunięcia tego kanału wraz ze WSZYSTKIMI odcinkami, które zostały pobrane.</string>
<string name="feed_remover_msg">Usuwanie kanału</string>
<string name="load_complete_feed">Odśwież cały kanał</string>
<string name="hide_episodes_title">Ukryj odcinki</string>
@@ -120,6 +126,7 @@
<string name="hide_not_queued_episodes_label">Nie w kolejce</string>
<string name="hide_downloaded_episodes_label">Pobrane</string>
<string name="hide_not_downloaded_episodes_label">Nie pobrane</string>
+ <string name="hide_has_media_label">Ma media</string>
<string name="filtered_label">Przefiltrowany</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Ostatnie odświerzanie nie powiodło się</string>
<string name="open_podcast">Otwarty Podcast</string>
@@ -130,6 +137,7 @@
<string name="stop_label">Stop</string>
<string name="stream_label">Strumień</string>
<string name="remove_label">Usuń</string>
+ <string name="delete_label">Usuń</string>
<string name="remove_episode_lable">Usuń odcinek</string>
<string name="marked_as_seen_label">Zaznaczono jako wyświetlone</string>
<string name="mark_read_label">Oznacz jako odtworzone</string>
@@ -178,6 +186,7 @@
<plurals name="downloads_left">
<item quantity="one">%d element został do pobrania</item>
<item quantity="few">%d elementów zostało do pobrania</item>
+ <item quantity="many">%d elementów zostało do pobrania</item>
<item quantity="other">%d elementów zostało do pobrania</item>
</plurals>
<string name="downloads_processing">Przetwarzanie pobranych</string>
@@ -275,13 +284,13 @@
<string name="pref_pauseOnDisconnect_sum">Wstrzymaj odtwarzanie po rozłączeniu słuchawek lub Bluetooth</string>
<string name="pref_unpauseOnHeadsetReconnect_sum">Wznów odtwarzanie kiedy słuchawki zostaną podłączone ponownie</string>
<string name="pref_unpauseOnBluetoothReconnect_sum">Wznów odtwarzanie po przywróceniu połączenia Bluetooth</string>
- <string name="pref_hardwareForwardButtonSkips_title">Przycisk \'Do przodu\' pomija odcinek</string>
<string name="pref_hardwareForwardButtonSkips_sum">Przyciśnięcie fizycznego przycisku \'Do przodu\' przeskakuje do następnego odcinka zamiast przewijania</string>
+ <string name="pref_hardwarePreviousButtonRestarts_title">Przycisk wstecz restartuje</string>
+ <string name="pref_hardwarePreviousButtonRestarts_sum">Podczas odtwarzania przycisk wstecz restartuje zamiast przewijać</string>
<string name="pref_followQueue_sum">Przeskocz do następnego elementu kolejki po zakończeniu odtwarzania</string>
<string name="pref_auto_delete_sum">Usuń odcinek kiedy jego odtwarzanie zostanie zakończone</string>
<string name="pref_auto_delete_title">Automatyczne usuwanie</string>
<string name="pref_smart_mark_as_played_sum">Oznacz odcinek jako odtworzony, jeśli do końca pozostało mniej niż określona ilość czasu</string>
- <string name="pref_smart_mark_as_played_title">Inteligentnie oznacz jako odtworzone</string>
<string name="pref_skip_keeps_episodes_sum">Zachowuje pominięte odcinki w kolejce</string>
<string name="pref_skip_keeps_episodes_title">Zachowaj pominięte odcinki</string>
<string name="playback_pref">Odtwarzanie</string>
@@ -343,12 +352,18 @@
<string name="pref_gpodnet_logout_toast">Wylogowanie się powiodło</string>
<string name="pref_gpodnet_setlogin_information_title">Zmień informacje logowania</string>
<string name="pref_gpodnet_setlogin_information_sum">Zmień dane logowania konta gpodder.net.</string>
+ <string name="pref_gpodnet_sync_changes_title">Zsynchronizuj zmiany teraz</string>
+ <string name="pref_gpodnet_sync_changes_sum">Synchronizuj subskrypcje oraz stan odcinków z pomocą gpodder.net.</string>
+ <string name="pref_gpodnet_full_sync_title">Wykonaj pełną synchronizację teraz</string>
+ <string name="pref_gpodnet_full_sync_sum">Synchronizuj wszystkie subskrypcje oraz stan odcinków z pomocą gpodder.net.</string>
+ <string name="pref_gpodnet_sync_sum_last_sync_line">Ostatnia próba synchronizacji: %1$s (%2$s)</string>
<string name="pref_gpodnet_sync_started">Synchronizacja uruchomiona</string>
+ <string name="pref_gpodnet_full_sync_started">Pełna synchronizacja rozpoczęta</string>
<string name="pref_gpodnet_login_status"><![CDATA[Zalogowano jako <i>%1$s</i> na urządzeniu <i>%2$s</i>]]></string>
+ <string name="pref_gpodnet_notifications_title">Pokaż powiadomienia błędów synchronizacji</string>
+ <string name="pref_gpodnet_notifications_sum">To ustawienie nie dotyczy błędów autoryzacji.</string>
<string name="pref_playback_speed_title">Prędkość odtwarzania</string>
<string name="pref_playback_speed_sum">Dostosuj prędkości dostępne dla odtwarzania audio o zmiennej prędkości</string>
- <string name="pref_fast_forward">Szybkie przewijanie do przodu</string>
- <string name="pref_rewind">Przewijanie do tyłu</string>
<string name="pref_gpodnet_sethostname_title">Ustaw nazwę hosta</string>
<string name="pref_gpodnet_sethostname_use_default_host">Użyj domyślnego hosta</string>
<string name="pref_expandNotify_title">Rozwiń Powiadomienia</string>
@@ -373,7 +388,6 @@
<string name="crash_report_sum">Wyślij ostatni raport o błędach przez e-mail</string>
<string name="send_email">Wyślij e-mail</string>
<string name="experimental_pref">Eksperymentalne</string>
- <string name="pref_sonic_title">Odtwarzacz mediów Sonic</string>
<string name="pref_sonic_message">Użyj wbudowanego odtwarzacza Sonic jako oprogramowanie zastępcze do natywnego odtwarzacza Android i Prestissimo</string>
<string name="pref_current_value">Aktualna wartość: %1$s</string>
<string name="pref_proxy_title">Proxy</string>
@@ -390,10 +404,13 @@
<string name="auto_flattr_ater_beginning">Z-flattr-uj odcinek gdy odtawarzanie zostanie rozpoczęte</string>
<string name="auto_flattr_ater_end">Z-flattr-uj odcinek gdy odtwarzanie zostanie zakończone</string>
<!--Search-->
+ <string name="search_hint">Szukaj odcinków</string>
+ <string name="found_in_shownotes_label">Znalezione w notatkach dotyczących show</string>
<string name="found_in_chapters_label">Znaleziono w rozdziałach</string>
<string name="search_status_no_results">Brak wyników</string>
<string name="search_label">Szukaj</string>
<string name="found_in_title_label">Znaleziono w tytułach</string>
+ <string name="no_results_for_query">Brak wyników dla \"%1$s\"</string>
<!--OPML import and export-->
<string name="opml_import_txtv_button_lable">Pliki OPML pozwalają na przenoszenie podcastów między aplikacjami.</string>
<string name="opml_import_option">Opcja %1$d</string>
@@ -412,6 +429,7 @@
<string name="choose_file_from_filesystem">Z lokalnego systemu plików</string>
<string name="choose_file_from_external_application">Użyj zewnętrznej aplikacji</string>
<string name="opml_export_label">Eksport OPML</string>
+ <string name="html_export_label">Eksport HTML</string>
<string name="exporting_label">Eksportowanie...</string>
<string name="export_error_label">Błąd eksportu</string>
<string name="opml_export_success_title">Eksport OPML udany.</string>
@@ -433,18 +451,24 @@
<plurals name="time_seconds_quantified">
<item quantity="one">1 sekunda</item>
<item quantity="few">%d sekundy</item>
+ <item quantity="many">%d sekund</item>
<item quantity="other">%d sekund</item>
</plurals>
<plurals name="time_minutes_quantified">
<item quantity="one">1 minuta</item>
<item quantity="few">%d minuty</item>
+ <item quantity="many">%d minut</item>
<item quantity="other">%d minut</item>
</plurals>
<plurals name="time_hours_quantified">
<item quantity="one">1 godzina</item>
<item quantity="few">%d godziny</item>
+ <item quantity="many">%d godzin</item>
<item quantity="other">%d godzin</item>
</plurals>
+ <string name="auto_enable_label">Automaczyne włączenie</string>
+ <string name="sleep_timer_enabled_label">Wyłącznik czasowy włączony</string>
+ <string name="sleep_timer_disabled_label">Wyłącznik czasowy wyłączony</string>
<!--gpodder.net-->
<string name="gpodnet_taglist_header">KATEGORIE</string>
<string name="gpodnet_toplist_header">TOP PODCASTY</string>
@@ -475,6 +499,8 @@ https://gpodder.net/register/</string>
<string name="gpodnetsync_auth_error_descr">Niepoprawna nazwa użytkownika lub hasło</string>
<string name="gpodnetsync_error_title">Błąd synchronizacji z gpodder.net</string>
<string name="gpodnetsync_error_descr">Wystąpił błąd podczas synchronizacji:\u0020</string>
+ <string name="gpodnetsync_pref_report_successful">Sukces</string>
+ <string name="gpodnetsync_pref_report_failed">Porażka</string>
<!--Directory chooser-->
<string name="selected_folder_label">Wybrany folder:</string>
<string name="create_folder_label">Utwórz folder</string>
@@ -527,6 +553,7 @@ https://gpodder.net/register/</string>
<string name="sp_apps_importing_feeds_msg">Importowanie subskrybcji z jednozadaniowych aplikacji</string>
<string name="search_itunes_label">Szukaj w iTunes</string>
<string name="filter">Filtruj</string>
+ <string name="search_fyyd_label">Szukaj w fyyd</string>
<!--Episodes apply actions-->
<string name="all_label">Wszystkie</string>
<string name="selected_all_label">Zaznaczono wszystkie odcinki</string>
@@ -544,6 +571,8 @@ https://gpodder.net/register/</string>
<string name="selected_queued_label">Wybierz odcinki w kolejce</string>
<string name="not_queued_label">Nie w kolejce</string>
<string name="selected_not_queued_label">Wybierz odcinki, które nie są w kolejce</string>
+ <string name="has_media">Ma media</string>
+ <string name="selected_has_media_label">Wybrane odcinki z mediami</string>
<!--Sort-->
<string name="sort_title_a_z">Tytuł (A \u2192 Z)</string>
<string name="sort_title_z_a">Tytuł (Z \u2192 A)</string>
diff --git a/core/src/main/res/values-pt-rBR/strings.xml b/core/src/main/res/values-pt-rBR/strings.xml
index 1b7306222..5156fd3cc 100644
--- a/core/src/main/res/values-pt-rBR/strings.xml
+++ b/core/src/main/res/values-pt-rBR/strings.xml
@@ -107,7 +107,6 @@
<string name="share_feed_url_label">Compartilhar Link do Feed</string>
<string name="share_item_url_label">Compartilhar URL do arquivo do episódio</string>
<string name="share_item_url_with_position_label">Compartilhar URL do arquivo do episódio com posição</string>
- <string name="feed_delete_confirmation_msg">Por favor confirme que você deseja apagar este feed e TODOS os episódios que você fez download deste feed.</string>
<string name="feed_remover_msg">Removendo feed</string>
<string name="load_complete_feed">Atualizar feed completamente</string>
<string name="hide_episodes_title">Ocultar Episódios</string>
@@ -273,13 +272,11 @@
<string name="pref_pauseOnDisconnect_sum">Pausar a reprodução quando o fone de ouvido ou bluetooth forem disconectados</string>
<string name="pref_unpauseOnHeadsetReconnect_sum">Continuar a reprodução quando os fones de ouvido forem reconectados</string>
<string name="pref_unpauseOnBluetoothReconnect_sum">Continuar a reprodução quando o bluetooth reconectar</string>
- <string name="pref_hardwareForwardButtonSkips_title">Botão avançar pula</string>
<string name="pref_hardwareForwardButtonSkips_sum">Quando pressionar um botão físico, avançar para o próximo episódio ao invés de avançar a reprodução</string>
<string name="pref_followQueue_sum">Pular para próximo item da fila quando a reprodução terminar</string>
<string name="pref_auto_delete_sum">Apagar os episódios quando a reprodução for concluída</string>
<string name="pref_auto_delete_title">Deletar automaticamente</string>
<string name="pref_smart_mark_as_played_sum">Marcar episódios como reproduzidos mesmo que restem alguns segundos de reprodução</string>
- <string name="pref_smart_mark_as_played_title">Marcar como reproduzido inteligentemente</string>
<string name="pref_skip_keeps_episodes_sum">Manter os episódios quando eles forem avançados</string>
<string name="pref_skip_keeps_episodes_title">Manter episódios avançados</string>
<string name="playback_pref">Reprodução</string>
@@ -345,8 +342,6 @@
<string name="pref_gpodnet_login_status"><![CDATA[Entrou como <i>%1$s</i> com o dispositivo <i>%2$s</i>]]></string>
<string name="pref_playback_speed_title">Velocidades de Reprodução</string>
<string name="pref_playback_speed_sum">Personalize as velocidades variáveis de reprodução de áudio.</string>
- <string name="pref_fast_forward">Avançar o tempo</string>
- <string name="pref_rewind">Voltar o tempo</string>
<string name="pref_gpodnet_sethostname_title">Configurar hostname</string>
<string name="pref_gpodnet_sethostname_use_default_host">Usar host padrão</string>
<string name="pref_expandNotify_title">Expandir Notificação</string>
@@ -371,7 +366,6 @@
<string name="crash_report_sum">Enviar o relatório da última falha por e-mail</string>
<string name="send_email">Enviar e-mail</string>
<string name="experimental_pref">Experimental</string>
- <string name="pref_sonic_title">Reprodutor de mídia Sonic</string>
<string name="pref_sonic_message">Utilizar o reprodutor de mídia Sonic no lugar do reprodutor de mídia nativo do Android e do Prestissimo</string>
<string name="pref_current_value">Valor atual: %1$s</string>
<string name="pref_proxy_title">Proxy</string>
diff --git a/core/src/main/res/values-pt/strings.xml b/core/src/main/res/values-pt/strings.xml
index 8e0e27e48..154b451b6 100644
--- a/core/src/main/res/values-pt/strings.xml
+++ b/core/src/main/res/values-pt/strings.xml
@@ -26,6 +26,10 @@
<!--Statistics fragment-->
<string name="total_time_listened_to_podcasts">Tempo total dos podcasts reproduzidos:</string>
<string name="statistics_details_dialog">%1$d de %2$d episódios iniciados.\n\nReproduzidos %3$s de %4$s.</string>
+ <string name="statistics_mode">Modo estatístico</string>
+ <string name="statistics_mode_normal">Calcula a duração dos podcasts reproduzidos. Se os reproduzir duas vezes, serão contados duas vezes mas se os marcar como reproduzidos não serão contados.</string>
+ <string name="statistics_mode_count_all">Somar todos os podcasts marcados como reproduzidos</string>
+ <string name="statistics_speed_not_counted">Aviso: a velocidade de reprodução nunca será considerada.</string>
<!--Main activity-->
<string name="drawer_open">Abrir menu</string>
<string name="drawer_close">Fechar menu</string>
@@ -33,6 +37,7 @@
<string name="drawer_feed_order_unplayed_episodes">Ordenar por contador</string>
<string name="drawer_feed_order_alphabetical">Ordenar alfabeticamente</string>
<string name="drawer_feed_order_last_update">Ordenar por data de publicação</string>
+ <string name="drawer_feed_order_most_played">Ordenar por número de episódios reproduzidos</string>
<string name="drawer_feed_counter_new_unplayed">Número de episódios novos ou por reproduzir</string>
<string name="drawer_feed_counter_new">Número de novos episódios</string>
<string name="drawer_feed_counter_unplayed">Número de episódios por reproduzir</string>
@@ -62,6 +67,7 @@
<string name="refresh_label">Atualizar</string>
<string name="external_storage_error_msg">Cartão SD não disponível. Certifique-se de que inseriu o cartão corretamente para que a aplicação funcione corretamente.</string>
<string name="chapters_label">Capítulos</string>
+ <string name="chapter_duration">Duração: %1$s</string>
<string name="shownotes_label">Notas</string>
<string name="description_label">Descrição</string>
<string name="most_recent_prefix">Episódio mais recente:\u0020</string>
@@ -113,7 +119,7 @@
<string name="share_feed_url_label">Partilhar URL da fonte</string>
<string name="share_item_url_label">Partilhar URL do episódio</string>
<string name="share_item_url_with_position_label">Partilhar URL do episódio com posição</string>
- <string name="feed_delete_confirmation_msg">Tem a certeza de que deseja remover esta fonte e todos os episódios descarregados?</string>
+ <string name="feed_delete_confirmation_msg">Tem a certeza de que deseja remover a fonte \"%1$s\" e TODOS os episódios descarregados?</string>
<string name="feed_remover_msg">Remover fonte</string>
<string name="load_complete_feed">Atualizar todas as páginas da fonte</string>
<string name="hide_episodes_title">Ocultar episódios</string>
@@ -125,6 +131,7 @@
<string name="hide_not_queued_episodes_label">Não na fila</string>
<string name="hide_downloaded_episodes_label">Descarregados</string>
<string name="hide_not_downloaded_episodes_label">Não descarregados</string>
+ <string name="hide_has_media_label">Tem ficheiro</string>
<string name="filtered_label">Filtrados</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Última atualização falhada</string>
<string name="open_podcast">Abrir podcast</string>
@@ -363,7 +370,9 @@
<string name="pref_playback_speed_title">Velocidades de reprodução</string>
<string name="pref_playback_speed_sum">Personalizar as velocidades de reprodução disponíveis</string>
<string name="pref_fast_forward">Tempo a avançar</string>
+ <string name="pref_fast_forward_sum">Personalizar o número de segundos a avançar ao clicar no botão de avanço rápido</string>
<string name="pref_rewind">Tempo a recuar</string>
+ <string name="pref_rewind_sum">Personalizar o número de segundos a recuar ao clicar no botão de recuo rápido</string>
<string name="pref_gpodnet_sethostname_title">Definir nome de servidor</string>
<string name="pref_gpodnet_sethostname_use_default_host">Utilizar predefinições</string>
<string name="pref_expandNotify_title">Expansão de notificação</string>
@@ -388,7 +397,7 @@
<string name="crash_report_sum">Enviar o relatório de erros por e-mail</string>
<string name="send_email">Enviar e-mail</string>
<string name="experimental_pref">Experimental</string>
- <string name="pref_sonic_title">Reprodutor Sonic</string>
+ <string name="pref_sonic_title">Reprodutor multimédia Sonic</string>
<string name="pref_sonic_message">Utilizar o Sonic Media Player como substituto do reprodutor nativo do Android e do Prestissimo</string>
<string name="pref_current_value">Valor atual: %1$s</string>
<string name="pref_proxy_title">Proxy</string>
@@ -399,6 +408,8 @@
<string name="pref_cast_title">Suporte Chromecast</string>
<string name="pref_cast_message_play_flavor">Ativar suporte a reprodução multimédia em dispositivos Cast (tais como Chromecast, Android TV...)</string>
<string name="pref_cast_message_free_flavor">O Chromecast necessita de bibliotecas proprietárias de terceiros que estão desativadas nesta versão do AntennaPod</string>
+ <string name="pref_enqueue_downloaded_title">Colocar descarregados na fila</string>
+ <string name="pref_enqueue_downloaded_summary">Adicionar à fila os episódios descarregados</string>
<!--Auto-Flattr dialog-->
<string name="auto_flattr_enable">Ativar flattr automático</string>
<string name="auto_flattr_after_percent">Flattr de episódios ao atingir %d porcento de reprodução</string>
@@ -408,6 +419,8 @@
<string name="search_hint">Pesquisar por episódios</string>
<string name="found_in_shownotes_label">Encontrado nas notas</string>
<string name="found_in_chapters_label">Encontrado nos capítulos</string>
+ <string name="found_in_authors_label">Encontrado em autores</string>
+ <string name="found_in_feeds_label">Encontrado em fontes</string>
<string name="search_status_no_results">Nenhum resultado</string>
<string name="search_label">Pesquisar</string>
<string name="found_in_title_label">Encontrado no título</string>
@@ -430,7 +443,7 @@
<string name="choose_file_from_filesystem">Do sistema local de ficheiros</string>
<string name="choose_file_from_external_application">Utilizar aplicação externa</string>
<string name="opml_export_label">Exportação OPML</string>
- <string name="html_export_label">Exportação OPML</string>
+ <string name="html_export_label">Exportação HTML</string>
<string name="exporting_label">A exportar...</string>
<string name="export_error_label">Erro de exportação</string>
<string name="opml_export_success_title">Exportação efetuada</string>
@@ -565,6 +578,8 @@
<string name="selected_queued_label">Episódios selecionados na fila</string>
<string name="not_queued_label">Não na fila</string>
<string name="selected_not_queued_label">Episódios não selecionados na fila</string>
+ <string name="has_media">Tem ficheiro</string>
+ <string name="selected_has_media_label">Episódios selecionados com ficheiros</string>
<!--Sort-->
<string name="sort_title_a_z">Título (A \u2192 Z)</string>
<string name="sort_title_z_a">Título (Z \u2192 A)</string>
diff --git a/core/src/main/res/values-ro-rRO/strings.xml b/core/src/main/res/values-ro-rRO/strings.xml
index b1c75912c..ba3f0ed4c 100644
--- a/core/src/main/res/values-ro-rRO/strings.xml
+++ b/core/src/main/res/values-ro-rRO/strings.xml
@@ -45,7 +45,6 @@
<string name="mark_all_read_label">Marchează toate ca citite</string>
<string name="show_info_label">Arată informații</string>
<string name="share_link_label">Împarte adresă website</string>
- <string name="feed_delete_confirmation_msg">Confirmați ștergerea feedului și a TUTUROR episoadelor pe care le-ați descărcat.</string>
<!--actions on feeditems-->
<string name="download_label">Descarcă</string>
<string name="play_label">Play</string>
diff --git a/core/src/main/res/values-ru/strings.xml b/core/src/main/res/values-ru/strings.xml
index f581a4fa8..db11eb90e 100644
--- a/core/src/main/res/values-ru/strings.xml
+++ b/core/src/main/res/values-ru/strings.xml
@@ -33,9 +33,11 @@
<string name="drawer_feed_order_unplayed_episodes">Сортировать по количеству</string>
<string name="drawer_feed_order_alphabetical">Сортировать по алфавиту</string>
<string name="drawer_feed_order_last_update">Сортировать по дате</string>
+ <string name="drawer_feed_order_most_played">Сортировать по количеству прослушанных выпусков</string>
<string name="drawer_feed_counter_new_unplayed">Количество новых и непрослушанных выпусков</string>
<string name="drawer_feed_counter_new">Количество новых выпусков</string>
<string name="drawer_feed_counter_unplayed">Количество непрослушанных выпусков</string>
+ <string name="drawer_feed_counter_downloaded">Количество загруженных выпусков</string>
<string name="drawer_feed_counter_none">Ничего</string>
<!--Webview actions-->
<string name="open_in_browser_label">Открыть в браузере</string>
@@ -50,6 +52,7 @@
<string name="cancel_label">Отмена</string>
<string name="yes">Да</string>
<string name="no">Нет</string>
+ <string name="reset">Сброс</string>
<string name="author_label">Автор</string>
<string name="language_label">Язык</string>
<string name="url_label">Адрес</string>
@@ -60,6 +63,7 @@
<string name="refresh_label">Обновить</string>
<string name="external_storage_error_msg">Внешний носитель недоступен. Убедитесь что внешний носитель установлен, иначе приложение не сможет нормально работать.</string>
<string name="chapters_label">Главы</string>
+ <string name="chapter_duration">Продолжительность: %1$s</string>
<string name="shownotes_label">Примечания к выпуску</string>
<string name="description_label">Описание</string>
<string name="most_recent_prefix">Последний выпуск:\u0020</string>
@@ -94,14 +98,18 @@
<string name="etxtFeedurlHint">www.example.com/feed</string>
<string name="txtvfeedurl_label">Добавить подкаст по URL</string>
<string name="podcastdirectories_label">Найти подкаст в каталоге</string>
+ <string name="podcastdirectories_descr">Вы можете искать новые подкасты в каталогах iTunes, fyyd или gpodder.net по имени, категории или популярности.</string>
<string name="browse_gpoddernet_label">Просмотр gpodder.net</string>
<!--Actions on feeds-->
<string name="mark_all_read_label">Отметить как прослушанное</string>
<string name="mark_all_read_msg">Отметить все выпуски как прослушанные</string>
<string name="mark_all_read_confirmation_msg">Подтвердите, что хотите пометить все эпизоды как прослушанные.</string>
<string name="mark_all_read_feed_confirmation_msg">Подтвердите, что хотите пометить все эпизоды в этом канале как прослушанные.</string>
- <string name="mark_all_seen_label">Отметить все как замеченное</string>
+ <string name="mark_all_seen_label">Отметить все как просмотренное</string>
+ <string name="mark_all_seen_msg">Все эпизоды отмечены как просмотренные</string>
+ <string name="mark_all_seen_confirmation_msg">Пожалуйста, подтвердите намерение отметить все выпуски как просмотренные.</string>
<string name="show_info_label">Показать информацию</string>
+ <string name="rename_feed_label">Переименовать подкаст</string>
<string name="remove_feed_label">Удалить подкаст</string>
<string name="share_label">Поделиться…</string>
<string name="share_link_label">Поделиться ссылкой</string>
@@ -109,7 +117,7 @@
<string name="share_feed_url_label">Поделиться ссылкой на канал</string>
<string name="share_item_url_label">Поделиться ссылкой на файл выпуска</string>
<string name="share_item_url_with_position_label">Поделиться ссылкой на файл выпуска с отметкой времени</string>
- <string name="feed_delete_confirmation_msg">Подтвердите удаление канала и всех выпусков, загруженных с этого канала.</string>
+ <string name="feed_delete_confirmation_msg">Подтвердите, что хотите удалить канал \"%1$s\" и ВСЕ скачанные эпизоды этого канала.</string>
<string name="feed_remover_msg">Удаление канала</string>
<string name="load_complete_feed">Обновить весь канал</string>
<string name="hide_episodes_title">Скрыть выпуски</string>
@@ -121,6 +129,7 @@
<string name="hide_not_queued_episodes_label">Не в очереди</string>
<string name="hide_downloaded_episodes_label">Загружено</string>
<string name="hide_not_downloaded_episodes_label">Не загружено</string>
+ <string name="hide_has_media_label">С файлами</string>
<string name="filtered_label">Отфильтровано</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Последнее обновление не удалось</string>
<string name="open_podcast">Открыть подкаст</string>
@@ -131,8 +140,9 @@
<string name="stop_label">Остановить</string>
<string name="stream_label">Воспроизвести из сети</string>
<string name="remove_label">Удалить</string>
+ <string name="delete_label">Удалить</string>
<string name="remove_episode_lable">Удалить выпуск</string>
- <string name="marked_as_seen_label">Помечено все как замеченное</string>
+ <string name="marked_as_seen_label">Отмечено как просмотренное</string>
<string name="mark_read_label">Отметить как прослушанное</string>
<string name="marked_as_read_label">Помечено как прослушанное</string>
<string name="mark_unread_label">Отметить как непрослушанное</string>
@@ -165,7 +175,7 @@
<string name="download_error_connection_error">Ошибка соединения</string>
<string name="download_error_unknown_host">Неизвестный узел</string>
<string name="download_error_unauthorized">Ошибка авторизации</string>
- <string name="download_error_file_type_type">Ошибка в типе файла</string>
+ <string name="download_error_file_type_type">Ошибка типа файла</string>
<string name="download_error_forbidden">Доступ запрещён</string>
<string name="cancel_all_downloads_label">Отменить все загрузки</string>
<string name="download_canceled_msg">Загрузка отменена</string>
@@ -177,10 +187,10 @@
<string name="download_error_request_error">Ошибка запроса</string>
<string name="download_error_db_access">Ошибка доступа к базе данных</string>
<plurals name="downloads_left">
- <item quantity="one">осталась %d загрузка</item>
- <item quantity="few">осталось %d загрузки</item>
- <item quantity="many">осталось %d загрузок</item>
- <item quantity="other">осталось %d загрузок</item>
+ <item quantity="one">Осталась %d загрузка</item>
+ <item quantity="few">Осталось %d загрузки</item>
+ <item quantity="many">Осталось %d загрузок</item>
+ <item quantity="other">Осталось %d загрузок</item>
</plurals>
<string name="downloads_processing">Производится загрузка</string>
<string name="download_notification_title">Получение данных подкаста</string>
@@ -261,7 +271,7 @@
<string name="enable_sonic">Включить Sonic</string>
<!--Empty list labels-->
<string name="no_items_label">Список пуст</string>
- <string name="no_feeds_label">Вы еще не подписаны ни на один канал</string>
+ <string name="no_feeds_label">Вы ещё не подписаны ни на один канал.</string>
<string name="no_chapters_label">Этот выпуск не содержит оглавления.</string>
<string name="no_shownotes_label">Этот выпуск не содержит примечаний.</string>
<!--Preferences-->
@@ -277,13 +287,13 @@
<string name="pref_pauseOnDisconnect_sum">Приостановить воспроизведение, когда наушники или bluetooth отключены</string>
<string name="pref_unpauseOnHeadsetReconnect_sum">Продолжать воспроизведение после подключения наушников</string>
<string name="pref_unpauseOnBluetoothReconnect_sum">Продолжать воспроизведение после подключения наушников или восстановления bluetooth-соединения</string>
- <string name="pref_hardwareForwardButtonSkips_title">Пропускать кнопкой перемотки вперёд</string>
<string name="pref_hardwareForwardButtonSkips_sum">При нажатии на физическую кнопку перемотки вперёд переходить к следующему выпуску вместо перемотки</string>
+ <string name="pref_hardwarePreviousButtonRestarts_title">В начало кнопкой перемотки назад</string>
+ <string name="pref_hardwarePreviousButtonRestarts_sum">При нажатии на физическую кнопку перемотки назад переходить к началу выпуска вместо перемотки назад</string>
<string name="pref_followQueue_sum">После завершения воспроизведения перейти к следующему в очереди</string>
<string name="pref_auto_delete_sum">Удалять эпизод после завершения воспроизведения</string>
<string name="pref_auto_delete_title">Автоматическое удаление</string>
- <string name="pref_smart_mark_as_played_sum">Отмечать выпуск как прослушанный, даже если до завершения остается некоторое время</string>
- <string name="pref_smart_mark_as_played_title">Предварительная отметка \"прослушано\"</string>
+ <string name="pref_smart_mark_as_played_sum">Отмечать выпуски как прослушанные, даже если до завершения остаётся некоторое время</string>
<string name="pref_skip_keeps_episodes_sum">Сохранять выпуски, помеченные как пропущенные</string>
<string name="pref_skip_keeps_episodes_title">Сохранять пропущенные выпуски</string>
<string name="playback_pref">Воспроизведение</string>
@@ -322,8 +332,8 @@
<string name="pref_nav_drawer_items_sum">Изменение отображения пунктов в меню боковой панели</string>
<string name="pref_nav_drawer_feed_order_title">Порядок подписок</string>
<string name="pref_nav_drawer_feed_order_sum">Выбрать порядок отображения подписок</string>
- <string name="pref_nav_drawer_feed_counter_title">Счетчик подписок</string>
- <string name="pref_nav_drawer_feed_counter_sum">Выбрать какую информацию показывать в счетчике подписок</string>
+ <string name="pref_nav_drawer_feed_counter_title">Выбрать счётчик подписок</string>
+ <string name="pref_nav_drawer_feed_counter_sum">Выбрать какую информацию показывать в счётчике подписок</string>
<string name="pref_set_theme_sum">Изменить тему оформления AntennaPod</string>
<string name="pref_automatic_download_title">Автоматическая загрузка</string>
<string name="pref_automatic_download_sum">Настроить автоматическую загрузку выпусков.</string>
@@ -345,17 +355,23 @@
<string name="pref_gpodnet_logout_toast">Выход произведён успешно</string>
<string name="pref_gpodnet_setlogin_information_title">Изменить информацию авторизации</string>
<string name="pref_gpodnet_setlogin_information_sum">Изменить информацию авторизации для аккаунта gpodder.net</string>
+ <string name="pref_gpodnet_sync_changes_title">Синхронизировать изменения</string>
+ <string name="pref_gpodnet_sync_changes_sum">Синхронизировать изменения подписок и выпусков при помощи gpodder.net.</string>
+ <string name="pref_gpodnet_full_sync_title">Синхронизировать полностью</string>
+ <string name="pref_gpodnet_full_sync_sum">Синхронизировать состояния всех подписок и выпусков при помощи gpodder.net.</string>
+ <string name="pref_gpodnet_sync_sum_last_sync_line">Предыдущая попытка синхронизации: %1$s (%2$s)</string>
<string name="pref_gpodnet_sync_started">Синхронизация запущена</string>
+ <string name="pref_gpodnet_full_sync_started">Запущена полная синхронизация</string>
<string name="pref_gpodnet_login_status"><![CDATA[Вход как <i>%1$s</i> с устройства <i>%2$s</i>]]></string>
+ <string name="pref_gpodnet_notifications_title">Показывать уведомления об ошибках синхронизации</string>
+ <string name="pref_gpodnet_notifications_sum">Не затрагивает ошибки авторизации.</string>
<string name="pref_playback_speed_title">Скорость воспроизведения</string>
<string name="pref_playback_speed_sum">Настроить скорости воспроизведения</string>
- <string name="pref_fast_forward">Интервал быстрой перемотки вперед</string>
- <string name="pref_rewind">Интервал быстрой перемотки назад</string>
<string name="pref_gpodnet_sethostname_title">Задать имя узла</string>
<string name="pref_gpodnet_sethostname_use_default_host">Использовать узел по умолчанию</string>
- <string name="pref_expandNotify_title">Расширенное уведомление</string>
- <string name="pref_expandNotify_sum">Всегда показывать в уведомлении кнопки управления воспроизведением.</string>
- <string name="pref_persistNotify_title">Постоянный контроль воспроизведения</string>
+ <string name="pref_expandNotify_title">Развёрнутое уведомление</string>
+ <string name="pref_expandNotify_sum">Всегда разворачивать уведомление, показывая кнопки управления воспроизведением.</string>
+ <string name="pref_persistNotify_title">Постоянные кнопки воспроизведения</string>
<string name="pref_persistNotify_sum">Сохранять уведомление и кнопки воспроизведения на экране блокировки во время паузы.</string>
<string name="pref_compact_notification_buttons_title">Выбрать кнопки экрана блокировки</string>
<string name="pref_compact_notification_buttons_sum">Поменять кнопки управления на экране блокировки. Кнопка воспроизведения/паузы присутствует постоянно.</string>
@@ -375,7 +391,6 @@
<string name="crash_report_sum">Отослать последний отчёт о сбое по e-mail</string>
<string name="send_email">Отправить Email</string>
<string name="experimental_pref">Экспериментальные настройки</string>
- <string name="pref_sonic_title">Проигрыватель Sonic</string>
<string name="pref_sonic_message">Задействовать встроенный медиа проигрыватель Sonic вместо стандартного из ОС Android и Prestissimo</string>
<string name="pref_current_value">Текущее значение: %1$s</string>
<string name="pref_proxy_title">Прокси</string>
@@ -392,10 +407,15 @@
<string name="auto_flattr_ater_beginning">Поддерживать эпизод через Flattr в начале воспроизведения</string>
<string name="auto_flattr_ater_end">Поддерживать эпизод через Flattr в конце воспроизведения</string>
<!--Search-->
+ <string name="search_hint">Найти выпуски</string>
+ <string name="found_in_shownotes_label">Найдено в примечаниях к выпуску</string>
<string name="found_in_chapters_label">Найдено в главах</string>
+ <string name="found_in_authors_label">Найдено в авторах</string>
+ <string name="found_in_feeds_label">Найдено в каналах</string>
<string name="search_status_no_results">Ничего не найдено</string>
<string name="search_label">Поиск</string>
<string name="found_in_title_label">Найдено в заголовке</string>
+ <string name="no_results_for_query">Для \"%1$s\" ничего не найдено</string>
<!--OPML import and export-->
<string name="opml_import_txtv_button_lable">OPML файлы позволяют перемещать ваши подкасты из одного менеджера подкастов в другой.</string>
<string name="opml_import_option">Настройка %1$d</string>
@@ -414,6 +434,7 @@
<string name="choose_file_from_filesystem">Из файловой системы</string>
<string name="choose_file_from_external_application">С помощью внешнего приложения</string>
<string name="opml_export_label">Экспорт в OPML</string>
+ <string name="html_export_label">Экспорт в HTML</string>
<string name="exporting_label">Экспортируется...</string>
<string name="export_error_label">Ошибка экспорта</string>
<string name="opml_export_success_title">OPML успешно экспортирован.</string>
@@ -450,6 +471,9 @@
<item quantity="many">%d часов</item>
<item quantity="other">%d часов</item>
</plurals>
+ <string name="auto_enable_label">Запускать автоматически</string>
+ <string name="sleep_timer_enabled_label">Таймер сна включён</string>
+ <string name="sleep_timer_disabled_label">Таймер сна отключён</string>
<!--gpodder.net-->
<string name="gpodnet_taglist_header">Категории</string>
<string name="gpodnet_toplist_header">Лучшее</string>
@@ -479,6 +503,8 @@
<string name="gpodnetsync_auth_error_descr">Неправильное имя пользователя или пароль</string>
<string name="gpodnetsync_error_title">Ошибка синхронизации с gpodder.net</string>
<string name="gpodnetsync_error_descr">Произошла ошибка во время синхронизации:\u0020</string>
+ <string name="gpodnetsync_pref_report_successful">Успешно</string>
+ <string name="gpodnetsync_pref_report_failed">Неудачно</string>
<!--Directory chooser-->
<string name="selected_folder_label">Выбранная папка:</string>
<string name="create_folder_label">Создать папку</string>
@@ -507,7 +533,7 @@
<string name="downloading_label">Идёт загрузка…</string>
<!--Content descriptions for image buttons-->
<string name="rewind_label">Назад</string>
- <string name="fast_forward_label">Вперед</string>
+ <string name="fast_forward_label">Вперёд</string>
<string name="media_type_audio_label">Аудио</string>
<string name="media_type_video_label">Видео</string>
<string name="navigate_upwards_label">Перейти выше</string>
@@ -531,6 +557,7 @@
<string name="sp_apps_importing_feeds_msg">Импорт подписок из одноцелевых приложений…</string>
<string name="search_itunes_label">Поиск в iTunes</string>
<string name="filter">Фильтровать</string>
+ <string name="search_fyyd_label">Поиск в fyyd</string>
<!--Episodes apply actions-->
<string name="all_label">Все</string>
<string name="selected_all_label">Отмечены все выпуски</string>
@@ -548,6 +575,8 @@
<string name="selected_queued_label">Выбраны выпуски из очереди</string>
<string name="not_queued_label">Не в очереди</string>
<string name="selected_not_queued_label">Выбраны выпуски не из очереди</string>
+ <string name="has_media">С файлами</string>
+ <string name="selected_has_media_label">Выбраны выпуски с файлами</string>
<!--Sort-->
<string name="sort_title_a_z">Заголовку (А \u2192 Я)</string>
<string name="sort_title_z_a">Заголовку (Я \u2192 А)</string>
diff --git a/core/src/main/res/values-sv-rSE/strings.xml b/core/src/main/res/values-sv-rSE/strings.xml
index a9749ede9..83f618d48 100644
--- a/core/src/main/res/values-sv-rSE/strings.xml
+++ b/core/src/main/res/values-sv-rSE/strings.xml
@@ -26,6 +26,10 @@
<!--Statistics fragment-->
<string name="total_time_listened_to_podcasts">Total uppspelningstid:</string>
<string name="statistics_details_dialog">%1$d av %2$d episoder startade.\n\nSpelat %3$s av %4$s.</string>
+ <string name="statistics_mode">Statistikläge</string>
+ <string name="statistics_mode_normal">Beräkna faktisk speltid. Att spela två gånger räknas två gånger, men att markera som spelad räknas inte</string>
+ <string name="statistics_mode_count_all">Summera alla podcasts som markerats som spelade</string>
+ <string name="statistics_speed_not_counted">Notera: Uppspelningshastighet tas inte med i beräkningarna. </string>
<!--Main activity-->
<string name="drawer_open">Öppna meny</string>
<string name="drawer_close">Stäng meny</string>
@@ -33,9 +37,11 @@
<string name="drawer_feed_order_unplayed_episodes">Sortera efter räknare</string>
<string name="drawer_feed_order_alphabetical">Sortera alfabetiskt</string>
<string name="drawer_feed_order_last_update">Sortera efter publiceringsdatum</string>
+ <string name="drawer_feed_order_most_played">Sortera efter antal spelade episoder</string>
<string name="drawer_feed_counter_new_unplayed">Antal nya och ospelade episoder</string>
<string name="drawer_feed_counter_new">Antal nya episoder</string>
<string name="drawer_feed_counter_unplayed">Antal ospelade episoder</string>
+ <string name="drawer_feed_counter_downloaded">Antal nedladdade episoder</string>
<string name="drawer_feed_counter_none">Inga</string>
<!--Webview actions-->
<string name="open_in_browser_label">Öppna i Webbläsare</string>
@@ -50,6 +56,7 @@
<string name="cancel_label">Avbryt</string>
<string name="yes">Ja</string>
<string name="no">Nej</string>
+ <string name="reset">Återställ</string>
<string name="author_label">Skapare</string>
<string name="language_label">Språk</string>
<string name="url_label">URL</string>
@@ -60,6 +67,7 @@
<string name="refresh_label">Uppdatera</string>
<string name="external_storage_error_msg">Ingen extern lagring är tillgänglig. Se till att montera en extern lagringsenhet så att appen kan fungera korrekt.</string>
<string name="chapters_label">Kapitel</string>
+ <string name="chapter_duration">Längd: %1$s</string>
<string name="shownotes_label">Shownotes</string>
<string name="description_label">Beskrivning</string>
<string name="most_recent_prefix">Senaste episoden:\u0020</string>
@@ -92,6 +100,7 @@
<string name="etxtFeedurlHint">URL till flöde eller webbsida</string>
<string name="txtvfeedurl_label">Lägg till podcast via URL</string>
<string name="podcastdirectories_label">Hitta Podcast i Biblioteket</string>
+ <string name="podcastdirectories_descr">För att hitta nya podcasts kan du söka i iTunes, fyyd, eller på gpodder.net baserat på namn, kategori eller popularitet.</string>
<string name="browse_gpoddernet_label">Bläddra på gpodder.net</string>
<!--Actions on feeds-->
<string name="mark_all_read_label">Markera alla som spelade</string>
@@ -99,7 +108,10 @@
<string name="mark_all_read_confirmation_msg">Bekräfta att du verkligen vill markera alla episoder som spelade.</string>
<string name="mark_all_read_feed_confirmation_msg">Bekräfta att du verkligen vill markera alla episoder i detta flöde som spelade.</string>
<string name="mark_all_seen_label">Markera alla som sedda</string>
+ <string name="mark_all_seen_msg">Markera alla Episoder som sedda</string>
+ <string name="mark_all_seen_confirmation_msg">Bekräfta att du vill markera alla episoder som sedda.</string>
<string name="show_info_label">Visa information</string>
+ <string name="rename_feed_label">Byt namn på Podcast</string>
<string name="remove_feed_label">Ta bort Podcast</string>
<string name="share_label">Dela…</string>
<string name="share_link_label">Dela Länk</string>
@@ -107,7 +119,7 @@
<string name="share_feed_url_label">Dela Flödets URL</string>
<string name="share_item_url_label">Dela Episoden Fil-URL</string>
<string name="share_item_url_with_position_label">Dela Episodens Fil-URL med Position</string>
- <string name="feed_delete_confirmation_msg">Bekräfta att du vill ta bort denna feed och ALLA avsnitt av denna feed som du har hämtat.</string>
+ <string name="feed_delete_confirmation_msg">Bekräfta att du vill ta bort flödet \"%1$s\" och ALLA episoder du laddat ned från detta flöde.</string>
<string name="feed_remover_msg">Tar bort Flöde</string>
<string name="load_complete_feed">Uppdatera hela Flödet</string>
<string name="hide_episodes_title">Dölj Episoder</string>
@@ -119,6 +131,7 @@
<string name="hide_not_queued_episodes_label">Inte köade</string>
<string name="hide_downloaded_episodes_label">Nedladdade</string>
<string name="hide_not_downloaded_episodes_label">Ej nedladdade</string>
+ <string name="hide_has_media_label">Har media</string>
<string name="filtered_label">Filtrerad</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Senaste uppdateringen misslyckades</string>
<string name="open_podcast">Öppna Podcast</string>
@@ -129,6 +142,7 @@
<string name="stop_label">Stopp</string>
<string name="stream_label">Strömma</string>
<string name="remove_label">Ta bort</string>
+ <string name="delete_label">Ta bort</string>
<string name="remove_episode_lable">Ta bort Episod</string>
<string name="marked_as_seen_label">Markera som sedd</string>
<string name="mark_read_label">Markera som spelad</string>
@@ -273,13 +287,15 @@
<string name="pref_pauseOnDisconnect_sum">Pausa uppspelningen när hörlurar eller bluetooth kopplas ifrån.</string>
<string name="pref_unpauseOnHeadsetReconnect_sum">Fortsätt uppspelningen när hörlurarna återansluts</string>
<string name="pref_unpauseOnBluetoothReconnect_sum">Fortsätt uppspelningen när bluetooth återansluts</string>
- <string name="pref_hardwareForwardButtonSkips_title">Framåt-knappen hoppar</string>
+ <string name="pref_hardwareForwardButtonSkips_title">Knappen spola fram hoppar</string>
<string name="pref_hardwareForwardButtonSkips_sum">Hoppa till nästa episod istället för att snabbspola vid tryck på hårdvaruknappen</string>
+ <string name="pref_hardwarePreviousButtonRestarts_title">Knappen föregående startar om</string>
+ <string name="pref_hardwarePreviousButtonRestarts_sum">Starta om den nuvarande episoden när du trycker på hårdvaruknappen för föregående istället för att spola tillbaka</string>
<string name="pref_followQueue_sum">Hoppa till nästa i kön när uppspelningen är klar</string>
<string name="pref_auto_delete_sum">Ta bort episoden när uppspelningen är klar</string>
<string name="pref_auto_delete_title">Automatisk Borttagning</string>
<string name="pref_smart_mark_as_played_sum">Markera episoder som spelade även om mindre än ett visst antal sekunder är kvar</string>
- <string name="pref_smart_mark_as_played_title">Smart markering av uppspelat innehåll</string>
+ <string name="pref_smart_mark_as_played_title">Smart markera som spelad</string>
<string name="pref_skip_keeps_episodes_sum">Ta inte bort episoder när de hoppas över</string>
<string name="pref_skip_keeps_episodes_title">Behåll Överhoppade Episoder</string>
<string name="playback_pref">Uppspelning</string>
@@ -341,12 +357,22 @@
<string name="pref_gpodnet_logout_toast">Utloggning lyckades</string>
<string name="pref_gpodnet_setlogin_information_title">Ändra inloggningsinformation</string>
<string name="pref_gpodnet_setlogin_information_sum">Ändra inloggningsinformationen för ditt gpodder.net konto.</string>
+ <string name="pref_gpodnet_sync_changes_title">Synkronisera ändringar nu</string>
+ <string name="pref_gpodnet_sync_changes_sum">Synkronisera ändringar i prenumerationer och episodstatus med gpodder.net.</string>
+ <string name="pref_gpodnet_full_sync_title">Full synkronisering nu</string>
+ <string name="pref_gpodnet_full_sync_sum">Synkronisera alla prenumerationer och episodstatus med gpodder.net.</string>
+ <string name="pref_gpodnet_sync_sum_last_sync_line">Senaste synkroniseringsförsök: %1$s (%2$s)</string>
<string name="pref_gpodnet_sync_started">Synkronisering startad</string>
+ <string name="pref_gpodnet_full_sync_started">Full synkronisering påbörjad</string>
<string name="pref_gpodnet_login_status"><![CDATA[Inloggad som <i>%1$s</i> med enhet <i>%2$s</i>]]></string>
+ <string name="pref_gpodnet_notifications_title">Visa notifieringar om synkroniseringsfel</string>
+ <string name="pref_gpodnet_notifications_sum">Denna inställning påverkar inte autentiseringsfel.</string>
<string name="pref_playback_speed_title">Uppspelningshastigheter</string>
<string name="pref_playback_speed_sum">Anpassa de tillgängliga hastigheterna för variabel uppspelningshastighet.</string>
- <string name="pref_fast_forward">Spola framåt</string>
- <string name="pref_rewind">Spola bakåt</string>
+ <string name="pref_fast_forward">Snabbspolningslängd</string>
+ <string name="pref_fast_forward_sum">Anpassa antalet sekunder att hoppa framåt när snabbspolningsknappen används</string>
+ <string name="pref_rewind">Snabbspolningslängd bakåt</string>
+ <string name="pref_rewind_sum">Anpassa antalet sekunder att hoppa bakåt när snabbspolningsknappen bakåt används</string>
<string name="pref_gpodnet_sethostname_title">Sätt värdnamn</string>
<string name="pref_gpodnet_sethostname_use_default_host">Använd standardvärden</string>
<string name="pref_expandNotify_title">Expandera aviseringen</string>
@@ -371,7 +397,7 @@
<string name="crash_report_sum">Sänd den senaste krashrapporten via e-post</string>
<string name="send_email">Sänd e-post</string>
<string name="experimental_pref">Experimentellt</string>
- <string name="pref_sonic_title">Sonic mediaspelare</string>
+ <string name="pref_sonic_title">Sonic Mediaspelare</string>
<string name="pref_sonic_message">Använd den inbyggda Sonic mediaspelare som ersättning för Androids egna mediaspelare och Prestissimo</string>
<string name="pref_current_value">Nuvarande värde: %1$s</string>
<string name="pref_proxy_title">Proxy</string>
@@ -382,16 +408,23 @@
<string name="pref_cast_title">Chromecast-stöd</string>
<string name="pref_cast_message_play_flavor">Aktivera stöd för fjärruppspelning av media på Cast-enheter (såsom Chromecast, Ljudanläggningar eller Android TV)</string>
<string name="pref_cast_message_free_flavor">Chromecast kräver propretiära tredjepartsbibliotek som inte är inkluderade i denna version av AntennaPod</string>
+ <string name="pref_enqueue_downloaded_title">Lägg nedladdade i kön</string>
+ <string name="pref_enqueue_downloaded_summary">Lägg nedladdade episoder i uppspelningskön</string>
<!--Auto-Flattr dialog-->
<string name="auto_flattr_enable">Aktivera automatisk Flattring</string>
<string name="auto_flattr_after_percent">Flattra episoden så snart %d procent har spelats</string>
<string name="auto_flattr_ater_beginning">Flattra episoden när den startas</string>
<string name="auto_flattr_ater_end">Flattra episoden när den spelats klart</string>
<!--Search-->
+ <string name="search_hint">Sök efter episoder</string>
+ <string name="found_in_shownotes_label">Hittad i shownotes</string>
<string name="found_in_chapters_label">Hittad i kapitel</string>
+ <string name="found_in_authors_label">Hittad i författare</string>
+ <string name="found_in_feeds_label">Hittad i flöden</string>
<string name="search_status_no_results">Inga resultat hittades</string>
<string name="search_label">Sök</string>
<string name="found_in_title_label">Hittad i titeln</string>
+ <string name="no_results_for_query">Inga resultat hittades för \"%1$s\"</string>
<!--OPML import and export-->
<string name="opml_import_txtv_button_lable">OPML-filer låter dig flytta dina podcasts från en podcatcher till en annan.</string>
<string name="opml_import_option">Val %1$d</string>
@@ -410,6 +443,7 @@
<string name="choose_file_from_filesystem">Från lokalt filsystem</string>
<string name="choose_file_from_external_application">Använd extern applikation</string>
<string name="opml_export_label">OPML export</string>
+ <string name="html_export_label">HTML export</string>
<string name="exporting_label">Exporterar…</string>
<string name="export_error_label">Exporteringsfel</string>
<string name="opml_export_success_title">OPML Exportering lyckades.</string>
@@ -440,6 +474,9 @@
<item quantity="one">1 timme</item>
<item quantity="other">%d timmar</item>
</plurals>
+ <string name="auto_enable_label">Auto-aktivera</string>
+ <string name="sleep_timer_enabled_label">Sömntimer aktiverad</string>
+ <string name="sleep_timer_disabled_label">Sömntimer inaktiverad</string>
<!--gpodder.net-->
<string name="gpodnet_taglist_header">KATEGORIER</string>
<string name="gpodnet_toplist_header">BÄSTA PODCASTS</string>
@@ -469,6 +506,8 @@
<string name="gpodnetsync_auth_error_descr">Fel användarnamn eller lösenord</string>
<string name="gpodnetsync_error_title">gpodder.net synkroniseringsfel</string>
<string name="gpodnetsync_error_descr">Ett fel uppstod under synkronisering:\u0020</string>
+ <string name="gpodnetsync_pref_report_successful">Lyckades</string>
+ <string name="gpodnetsync_pref_report_failed">Misslyckades</string>
<!--Directory chooser-->
<string name="selected_folder_label">Vald mapp:</string>
<string name="create_folder_label">Skapa mapp</string>
@@ -521,6 +560,7 @@
<string name="sp_apps_importing_feeds_msg">Importerar prenumerationer från appar gjorda för ett enda syfte…</string>
<string name="search_itunes_label">Leta i iTunes</string>
<string name="filter">Filtrera</string>
+ <string name="search_fyyd_label">Sök i fyyd</string>
<!--Episodes apply actions-->
<string name="all_label">Alla</string>
<string name="selected_all_label">Välj alla Episoder</string>
@@ -538,6 +578,8 @@
<string name="selected_queued_label">Valde köade Episoder</string>
<string name="not_queued_label">Ej köad</string>
<string name="selected_not_queued_label">Välj ej köade Episoder</string>
+ <string name="has_media">Har media</string>
+ <string name="selected_has_media_label">Valde episoder med media</string>
<!--Sort-->
<string name="sort_title_a_z">Titel (A \u2192 Ö)</string>
<string name="sort_title_z_a">Titel (Ö \u2192 A)</string>
diff --git a/core/src/main/res/values-te/strings.xml b/core/src/main/res/values-te/strings.xml
index 28dfeb6e8..8afbdb37d 100644
--- a/core/src/main/res/values-te/strings.xml
+++ b/core/src/main/res/values-te/strings.xml
@@ -1,27 +1,87 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources xmlns:tools="http://schemas.android.com/tools">
<!--Activitiy and fragment titles-->
+ <string name="feeds_label">ఫీడులు</string>
+ <string name="statistics_label">గణాంకాలు</string>
+ <string name="all_episodes_short_label">అన్నీ</string>
+ <string name="favorite_episodes_label">ఇష్టాలు</string>
+ <string name="new_label">కొత్తది</string>
+ <string name="settings_label">అమరికలు</string>
+ <string name="downloads_label">దింపుకోళ్ళు</string>
+ <string name="downloads_running_label">నడుస్తున్నవి</string>
+ <string name="downloads_completed_label">పూర్తయినవి</string>
+ <string name="downloads_log_label">చిట్టా</string>
+ <string name="subscriptions_label">చందాలు</string>
+ <string name="subscriptions_list_label">చందాల జాబితా</string>
+ <string name="free_space_label">%1$s ఖాళీ</string>
<!--Statistics fragment-->
<!--Main activity-->
+ <string name="drawer_feed_counter_none">ఏమీలేవు</string>
<!--Webview actions-->
<!--Playback history-->
<!--Other-->
+ <string name="cancel_label">రద్దుచేయి</string>
+ <string name="yes">అవును</string>
+ <string name="no">కాదు</string>
+ <string name="language_label">భాష</string>
+ <string name="podcast_settings_label">అమరికలు</string>
+ <string name="description_label">వివరణ</string>
+ <string name="length_prefix">నిడివి:\u0020</string>
+ <string name="loading_label">వస్తోంది…</string>
+ <string name="close_label">మూసివేయి</string>
+ <string name="feed_auto_download_always">ఎల్లప్పుడూ</string>
+ <string name="send_label">పంపించు…</string>
<!--'Add Feed' Activity labels-->
<!--Actions on feeds-->
+ <string name="share_label">పంచుకోండి…</string>
<!--actions on feeditems-->
+ <string name="play_label">ఆడించు</string>
+ <string name="pause_label">నిలుపు</string>
+ <string name="stop_label">ఆపివేయి</string>
+ <string name="delete_label">తొలగించు</string>
<!--Download messages and labels-->
<!--Mediaplayer messages-->
<!--Queue operations-->
+ <string name="date">తేదీ</string>
+ <string name="duration">నిడివి</string>
+ <string name="ascending">ఆరోహణ</string>
+ <string name="descending">అవరోహణ</string>
<!--Flattr-->
<!--Flattr-->
<!--Variable Speed-->
<!--Empty list labels-->
<!--Preferences-->
+ <string name="about_pref">గురించి</string>
+ <string name="services_label">సేవలు</string>
+ <string name="network_pref">నెట్‌వర్క్</string>
+ <string name="pref_update_interval_hours_plural">గంటలు</string>
+ <string name="pref_update_interval_hours_singular">గంట</string>
+ <string name="experimental_pref">ప్రయోగాత్మకం</string>
+ <string name="pref_proxy_title">ప్రాక్సీ</string>
<!--Auto-Flattr dialog-->
<!--Search-->
<!--OPML import and export-->
+ <string name="select_all_label">అన్నీ ఎంచుకోండి</string>
<!--Sleep timer-->
+ <string name="time_seconds">క్షణాలు</string>
+ <string name="time_minutes">నిమిషాలు</string>
+ <string name="time_hours">గంటలు</string>
+ <plurals name="time_seconds_quantified">
+ <item quantity="one">1 క్షణం</item>
+ <item quantity="other">%d క్షణాలు</item>
+ </plurals>
+ <plurals name="time_minutes_quantified">
+ <item quantity="one">1 నిమిషం</item>
+ <item quantity="other">%d నిమిషాలు</item>
+ </plurals>
+ <plurals name="time_hours_quantified">
+ <item quantity="one">1 గంట</item>
+ <item quantity="other">%d గంటలు</item>
+ </plurals>
<!--gpodder.net-->
+ <string name="gpodnet_taglist_header">వర్గాలు</string>
+ <string name="username_label">వాడుకరి పేరు</string>
+ <string name="password_label">సంకేతపదం</string>
<!--Directory chooser-->
<!--Online feed view-->
<!--Content descriptions for image buttons-->
@@ -29,10 +89,15 @@
<!--Progress information-->
<!--AntennaPodSP-->
<!--Episodes apply actions-->
+ <string name="all_label">అన్నీ</string>
+ <string name="none_label">ఏమీలేదు</string>
<!--Sort-->
<!--Rating dialog-->
+ <string name="rating_later_label">తర్వాత గుర్తుచేయి</string>
<!--Audio controls-->
<!--proxy settings-->
+ <string name="proxy_type_label">రకం</string>
+ <string name="optional_hint">(ఐచ్చికం)</string>
<!--Casting-->
<!--<string name="cast_failed_to_connect">Could not connect to the device</string>-->
</resources>
diff --git a/core/src/main/res/values-tr/strings.xml b/core/src/main/res/values-tr/strings.xml
index 33c316762..8b9bd5f20 100644
--- a/core/src/main/res/values-tr/strings.xml
+++ b/core/src/main/res/values-tr/strings.xml
@@ -33,6 +33,7 @@
<string name="drawer_feed_counter_new_unplayed">Yeni ve çalınmamış bölümlerin sayısı</string>
<string name="drawer_feed_counter_new">Yeni bölümlerin sayısı</string>
<string name="drawer_feed_counter_unplayed">Çalınmamış bölümlerin sayısı</string>
+ <string name="drawer_feed_counter_downloaded">İndirilen bölümlerin sayısı</string>
<string name="drawer_feed_counter_none">Hiçbiri</string>
<!--Webview actions-->
<string name="open_in_browser_label">Tarayıcıda aç</string>
@@ -47,6 +48,7 @@
<string name="cancel_label">İptal</string>
<string name="yes">Evet</string>
<string name="no">Hayır</string>
+ <string name="reset">Sıfırla</string>
<string name="author_label">Yayıncı</string>
<string name="language_label">Dil</string>
<string name="url_label">URL</string>
@@ -70,7 +72,9 @@
<string name="retry_label">Yeniden dene</string>
<string name="auto_download_label">Otomatik indirmelere dahil et</string>
<string name="auto_download_apply_to_items_title">Önceki Bölümlere Uygula</string>
+ <string name="auto_delete_label">Bölümü Otomatik Sil</string>
<string name="parallel_downloads_suffix">\u0020paralel indirmeler</string>
+ <string name="feed_auto_download_global">Varsayılan ayarlar</string>
<string name="feed_auto_download_always">Her zaman</string>
<string name="feed_auto_download_never">Hiçbir zaman</string>
<string name="send_label">Gönder...</string>
@@ -93,13 +97,17 @@
<string name="mark_all_read_confirmation_msg">Lütfen tüm bölümleri oynatıldı olarak işaretlemek istediğinizi onaylayın.</string>
<string name="mark_all_read_feed_confirmation_msg">Lütfen bu besleme içindeki tüm bölümleri oynatıldı olarak işaretlemek istediğinizi onaylayın.</string>
<string name="mark_all_seen_label">Hepsini görüldü olarak işaretle</string>
+ <string name="mark_all_seen_msg">Tüm bölümler görüldü olarak işaretlendi</string>
+ <string name="mark_all_seen_confirmation_msg">Lütfen tüm bölümleri görüldü olarak işaretlemek istediğinizi onaylayın.</string>
<string name="show_info_label">Bilgiyi göster</string>
+ <string name="rename_feed_label">Cep yayınını yeniden adlandır</string>
<string name="remove_feed_label">Cep yayını kaldır</string>
<string name="share_label">Paylaş...</string>
<string name="share_link_label">Link\'i paylaş</string>
<string name="share_link_with_position_label">Link\'i Konumla birlikte paylaş</string>
<string name="share_feed_url_label">Besleme Adresini Paylaş</string>
- <string name="feed_delete_confirmation_msg">Lütfen bu beslemeyi ve bu beslemeye ait indirilmiş BÜTÜN bölümleri silme isteğinizi onaylayın.</string>
+ <string name="share_item_url_label">Bölüm Dosyası Adresini Paylaş</string>
+ <string name="share_item_url_with_position_label">Bölüm Dosyası Adresini Konumla birlikte paylaş</string>
<string name="feed_remover_msg">Besleme kaldırılıyor</string>
<string name="load_complete_feed">Tüm beslemeyi yenile</string>
<string name="hide_episodes_title">Bölümleri gizle</string>
@@ -111,8 +119,10 @@
<string name="hide_not_queued_episodes_label">Kuyrukta değil</string>
<string name="hide_downloaded_episodes_label">İndirildi</string>
<string name="hide_not_downloaded_episodes_label">İndirilmedi</string>
+ <string name="hide_has_media_label">Medya var</string>
<string name="filtered_label">Filtrelendi</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Son yenileme başarısız oldu</string>
+ <string name="open_podcast">Cep yayını aç</string>
<!--actions on feeditems-->
<string name="download_label">İndir</string>
<string name="play_label">Oynat</string>
@@ -120,7 +130,9 @@
<string name="stop_label">Durdur</string>
<string name="stream_label">Akış</string>
<string name="remove_label">Kaldır</string>
+ <string name="delete_label">Sil</string>
<string name="remove_episode_lable">Bölümü kaldır</string>
+ <string name="marked_as_seen_label">Görüldü olarak işaretlendi</string>
<string name="mark_read_label">Oynatıldı olarak işaretle</string>
<string name="marked_as_read_label">Oynatıldı olarak işaretlendi</string>
<string name="mark_unread_label">Oynatılmadı olarak işaretle</string>
@@ -153,6 +165,8 @@
<string name="download_error_connection_error">Baplantı hatası</string>
<string name="download_error_unknown_host">Bilinmeyen sunucu</string>
<string name="download_error_unauthorized">Yetkilendirme hatası</string>
+ <string name="download_error_file_type_type">Dosya Tipi Hatası</string>
+ <string name="download_error_forbidden">Yasak</string>
<string name="cancel_all_downloads_label">Bütün indirmeleri iptal et</string>
<string name="download_canceled_msg">İndirme iptal edildi</string>
<string name="download_canceled_autodownload_enabled_msg">İndirme iptal edildi\nBu öğe için <i>Otomatik İndirme</i> devre dışı</string>
@@ -196,6 +210,8 @@
<!--Queue operations-->
<string name="lock_queue">Kuyruğu kilitle</string>
<string name="unlock_queue">Kuyruğun kilidini aç</string>
+ <string name="queue_locked">Kuyruk kilitlendi</string>
+ <string name="queue_unlocked">Kuyruk kilidi açıldı</string>
<string name="clear_queue_label">Kuyruğu temizle</string>
<string name="undo">Geri al</string>
<string name="removed_from_queue">Öge kaldırıldı</string>
@@ -204,6 +220,8 @@
<string name="sort">Sırala</string>
<string name="date">Tarih</string>
<string name="duration">Süre</string>
+ <string name="episode_title">Blüm başlığı</string>
+ <string name="feed_title">Besleme başlığı</string>
<string name="ascending">Artan</string>
<string name="descending">Azalan</string>
<string name="clear_queue_confirmation_msg">Lütfen içerisindeki BÜTÜN ölümlerle birlikte kuyruğu temizleme isteğinizi onaylayın.</string>
@@ -311,8 +329,6 @@
<string name="pref_gpodnet_setlogin_information_sum">gpodder.net hesabınız için giriş bilgisini değiştirin.</string>
<string name="pref_playback_speed_title">Çalma hızları</string>
<string name="pref_playback_speed_sum">Değişken hızlı ses yürütmesi için kullanılabilir hızları özelleştirin</string>
- <string name="pref_fast_forward">İleri sarma süresi</string>
- <string name="pref_rewind">Geri sarma süresi</string>
<string name="pref_gpodnet_sethostname_title">Sunucu ismini ayarla</string>
<string name="pref_gpodnet_sethostname_use_default_host">Varsayılan sunucuyu kullan</string>
<string name="pref_expandNotify_title">Bildirimi Genişlet</string>
@@ -331,7 +347,6 @@
<string name="crash_report_sum">En son çökme raporunu e-posta ile gönder</string>
<string name="send_email">E-posta gönder</string>
<string name="experimental_pref">Deneysel</string>
- <string name="pref_sonic_title">Sonic ortam yürütücüsü</string>
<string name="pref_faq">SSS</string>
<!--Auto-Flattr dialog-->
<string name="auto_flattr_enable">Otomatik Flattr\'lamayı etkinleştir</string>
@@ -355,6 +370,7 @@
<string name="reading_opml_label">OPML dosyası okunuyor</string>
<string name="select_all_label">Hepsini seç</string>
<string name="deselect_all_label">Tüm seçimleri geri al</string>
+ <string name="select_options_label">Seç...</string>
<string name="choose_file_from_filesystem">Yerel dosya sisteminden</string>
<string name="choose_file_from_external_application">Harici uygulama kullan</string>
<string name="opml_export_label">OPML dışa aktar</string>
@@ -438,6 +454,7 @@
<!--Online feed view-->
<string name="subscribe_label">Üye ol</string>
<string name="subscribed_label">Üye olundu</string>
+ <string name="downloading_label">İndiriliyor...</string>
<!--Content descriptions for image buttons-->
<string name="rewind_label">Geri sar</string>
<string name="fast_forward_label">İleri sar</string>
@@ -451,6 +468,7 @@
<!--Feed information screen-->
<string name="authentication_label">Yetkilendirme</string>
<string name="authentication_descr">Bu cep yayını ve içerdiği bölümler için kullanıcı adı şifreyi değiştir.</string>
+ <string name="auto_download_settings_label">Otomatik İndirme Seçenekleri</string>
<!--Progress information-->
<string name="progress_upgrading_database">Veritabanı yükseltiliyor</string>
<!--AntennaPodSP-->
@@ -483,6 +501,7 @@
<string name="rating_later_label">Daha sonra hatırlat</string>
<string name="rating_now_label">Evet, şimdi yapalım!</string>
<!--Audio controls-->
+ <string name="volume">Ses</string>
<!--proxy settings-->
<string name="proxy_test_label">Test</string>
<string name="proxy_test_successful">Test başarılı</string>
diff --git a/core/src/main/res/values-uk-rUA/strings.xml b/core/src/main/res/values-uk-rUA/strings.xml
index 029a6e749..308d390c6 100644
--- a/core/src/main/res/values-uk-rUA/strings.xml
+++ b/core/src/main/res/values-uk-rUA/strings.xml
@@ -26,6 +26,10 @@
<!--Statistics fragment-->
<string name="total_time_listened_to_podcasts">Загальний час прослуханих подкастів:</string>
<string name="statistics_details_dialog">%1$d з %2$d епізодів почато.\n\nПрослухано %3$s з %4$s.</string>
+ <string name="statistics_mode">Режим статистики</string>
+ <string name="statistics_mode_normal">Обчислити тривалість прослуханого. Прослухане двічі враховується двічи, але просто позначене як прослухане не враховується </string>
+ <string name="statistics_mode_count_all">Підсумувати всі подкасти позначені як прослухані</string>
+ <string name="statistics_speed_not_counted">Зауваження: Швидкість програвання не береться до уваги.</string>
<!--Main activity-->
<string name="drawer_open">Показати меню</string>
<string name="drawer_close">Сховати меню</string>
@@ -33,6 +37,7 @@
<string name="drawer_feed_order_unplayed_episodes">Сортувати за лічильником</string>
<string name="drawer_feed_order_alphabetical">Сортування за абеткою</string>
<string name="drawer_feed_order_last_update">Сортувати за датою публікації</string>
+ <string name="drawer_feed_order_most_played">Сортування за кількістю прослуханих епізодів</string>
<string name="drawer_feed_counter_new_unplayed">Кількість нових та непрослуханих епізодів</string>
<string name="drawer_feed_counter_new">Кількість нових епізодів</string>
<string name="drawer_feed_counter_unplayed">Кількість непрослуханих епізодів</string>
@@ -62,6 +67,7 @@
<string name="refresh_label">Оновити</string>
<string name="external_storage_error_msg">Немає доступної карти пам\'яті. Зовнішній носій потрібен для коректної роботи додатку</string>
<string name="chapters_label">Глави</string>
+ <string name="chapter_duration">Тривалість: %1$s</string>
<string name="shownotes_label">Нотатки до епізода</string>
<string name="description_label">Опис</string>
<string name="most_recent_prefix">Найновіший епізод:\u0020</string>
@@ -114,7 +120,7 @@
<string name="share_feed_url_label">Поділитись посиланням на канал</string>
<string name="share_item_url_label">Поділитись посиланням на файл епізода</string>
<string name="share_item_url_with_position_label">Поділитись посиланням на файл епізода з позицією</string>
- <string name="feed_delete_confirmation_msg">Ви впенені що хочете видаліти канал та всі завантажені епізоди?</string>
+ <string name="feed_delete_confirmation_msg">Будь ласка, підтвердіть що ви бажаєте видалити канал \"%1$s\" і ВСІ епізоди цього канала які ви завантажили.</string>
<string name="feed_remover_msg">Удаляю канал</string>
<string name="load_complete_feed">Оновити канал цілком</string>
<string name="hide_episodes_title">Приховати епізоди</string>
@@ -283,7 +289,7 @@
<string name="pref_pauseOnDisconnect_sum">Зупинятись коли навушники або блютуз від’єднано</string>
<string name="pref_unpauseOnHeadsetReconnect_sum">Поновити відтворення коли навушники повторно під’єднано</string>
<string name="pref_unpauseOnBluetoothReconnect_sum">Поновити відтворення коли блютуз повторно під’єднано</string>
- <string name="pref_hardwareForwardButtonSkips_title">Пропуск кнопкой перемотки</string>
+ <string name="pref_hardwareForwardButtonSkips_title">Кнопка перемотки пропускає</string>
<string name="pref_hardwareForwardButtonSkips_sum">При натисканні апаратної кнопки перемотки перейти до наступного епізода замість перемотки.</string>
<string name="pref_hardwarePreviousButtonRestarts_title">Кнопка \"назад\" повертає до початку</string>
<string name="pref_hardwarePreviousButtonRestarts_sum">При натисканні апаратної кнопки \"назад\", замість перемотки, розпочати програвання поточного епізода заново</string>
@@ -291,7 +297,7 @@
<string name="pref_auto_delete_sum">Видалити епізод після повного відтворення</string>
<string name="pref_auto_delete_title">Автовидалення</string>
<string name="pref_smart_mark_as_played_sum">Позначити епізоди як грані навіть якщо залишилось менш ніж зазначене число секунд до кінця відтворення</string>
- <string name="pref_smart_mark_as_played_title">Розумне позначення граних епізодів</string>
+ <string name="pref_smart_mark_as_played_title">Розумне позначення прослуханих епізодів</string>
<string name="pref_skip_keeps_episodes_sum">Зберігати епізоди що пропущені при програванні </string>
<string name="pref_skip_keeps_episodes_title">Зберігати пропущені при програванні епізоди </string>
<string name="playback_pref">Відтворення</string>
@@ -365,8 +371,10 @@
<string name="pref_gpodnet_notifications_sum">Це налаштування не застосовується до помилок автентифікації.</string>
<string name="pref_playback_speed_title">Швидкість програвання</string>
<string name="pref_playback_speed_sum">Налаштування швідкості доступно для змінної швидкості програвання</string>
- <string name="pref_fast_forward">Час перемотки вперед</string>
- <string name="pref_rewind">Час перемотки назад</string>
+ <string name="pref_fast_forward">Час пропуска кнопкой перемотки вперед</string>
+ <string name="pref_fast_forward_sum">Налаштувати кількість секунд які пропускаються при натисканні кнопки перемотки вперед</string>
+ <string name="pref_rewind">Час пропуска кнопкой перемотки назад</string>
+ <string name="pref_rewind_sum">Налаштувати кількість секунд які відмотуються при натисканні кнопки перемотки назад</string>
<string name="pref_gpodnet_sethostname_title">Встановити ім\'я хоста</string>
<string name="pref_gpodnet_sethostname_use_default_host">Використати хост по замовчанню</string>
<string name="pref_expandNotify_title">Розгорнути повідомлення</string>
@@ -391,7 +399,7 @@
<string name="crash_report_sum">Надіслати е-пошту зі звітом про останній збій</string>
<string name="send_email">Надіслати е-пошту</string>
<string name="experimental_pref">Експериментальні</string>
- <string name="pref_sonic_title">Програвач Sonic</string>
+ <string name="pref_sonic_title">Sonic Media Player</string>
<string name="pref_sonic_message">Застосувати вбудований програвач sonic замість програвача Android та Prestissimo</string>
<string name="pref_current_value">Поточне значення: %1$s</string>
<string name="pref_proxy_title">Проксі</string>
@@ -402,6 +410,8 @@
<string name="pref_cast_title">Підтримка для Chromecast</string>
<string name="pref_cast_message_play_flavor">Включити підтримку програвання на таких пристроях як Chromecast або Android TV</string>
<string name="pref_cast_message_free_flavor">Для підтримки Chromecast потрібні бібліотеки які не включені в цю версію AntennaPod</string>
+ <string name="pref_enqueue_downloaded_title">Додавати до черги завантажене</string>
+ <string name="pref_enqueue_downloaded_summary">Додавати завантажені епізоди до черги</string>
<!--Auto-Flattr dialog-->
<string name="auto_flattr_enable">Включити автоматичне заохочення авторів через сервіс flattr</string>
<string name="auto_flattr_after_percent">Заохотити автора через Flattr щойно %d відсотків епізода було відтворено</string>
@@ -411,6 +421,8 @@
<string name="search_hint">Пошук епізодів</string>
<string name="found_in_shownotes_label">Знайдено в нотатках епізода</string>
<string name="found_in_chapters_label">Знайдено в главах</string>
+ <string name="found_in_authors_label">Знайдено в авторах</string>
+ <string name="found_in_feeds_label">Знайдено в каналах</string>
<string name="search_status_no_results">Жодних результатів немає</string>
<string name="search_label">Пошук</string>
<string name="found_in_title_label">Знайдено у назві</string>
diff --git a/core/src/main/res/values-vi/strings.xml b/core/src/main/res/values-vi/strings.xml
index a900b1217..2c304e07c 100644
--- a/core/src/main/res/values-vi/strings.xml
+++ b/core/src/main/res/values-vi/strings.xml
@@ -2,63 +2,310 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!--Activitiy and fragment titles-->
<string name="feeds_label">Các feed</string>
+ <string name="statistics_label">Thống kê</string>
+ <string name="add_feed_label">Thêm podcast</string>
+ <string name="episodes_label">Số tập</string>
+ <string name="all_episodes_short_label">Tất cả</string>
+ <string name="favorite_episodes_label">Lượt thích</string>
<string name="new_label">Tạo mới</string>
<string name="settings_label">Thiết lập</string>
+ <string name="add_new_feed_label">Thêm podcast</string>
<string name="downloads_label">Tải về</string>
+ <string name="downloads_running_label">Đang tải</string>
+ <string name="downloads_completed_label">Đã tải</string>
+ <string name="downloads_log_label">Lịch sử</string>
+ <string name="cancel_download_label">Huỷ\ntải xuống</string>
+ <string name="playback_history_label">Lịch sử phát</string>
+ <string name="gpodnet_main_label">gpodder.net</string>
+ <string name="gpodnet_auth_label">Đăng nhập gpodder.net</string>
+ <string name="free_space_label">Còn trống %1$s</string>
+ <string name="episode_cache_full_title">Đầy bộ nhớ tạm</string>
+ <string name="episode_cache_full_message">Bộ nhớ tạm cho các tập podcast đã đạt dung lượng tối đa. Bạn có thể tăng giới hạn này lên trong phần Thiết lập.</string>
<!--Statistics fragment-->
+ <string name="total_time_listened_to_podcasts">Tổng thời gian nghe:</string>
<!--Main activity-->
+ <string name="drawer_open">Mở menu</string>
+ <string name="drawer_close">Đóng menu</string>
+ <string name="drawer_preferences">Cài đặt menu kéo ra</string>
+ <string name="drawer_feed_order_unplayed_episodes">Sắp xếp theo số lượng</string>
+ <string name="drawer_feed_order_alphabetical">Sắp xếp theo bảng chữ cái</string>
+ <string name="drawer_feed_order_last_update">Sắp xếp theo ngày phát hành</string>
+ <string name="drawer_feed_counter_new_unplayed">Số tập mới hoặc chưa nghe</string>
+ <string name="drawer_feed_counter_new">Số tập mới</string>
+ <string name="drawer_feed_counter_unplayed">Số tập chưa nghe</string>
+ <string name="drawer_feed_counter_downloaded">Số tập đã tải</string>
+ <string name="drawer_feed_counter_none">Không có</string>
<!--Webview actions-->
+ <string name="open_in_browser_label">Mở bằng trình duyệt</string>
+ <string name="copy_url_label">Sao chép liên kết</string>
+ <string name="share_url_label">Chia sẻ liên kết</string>
+ <string name="copied_url_msg">Đã sao chép liên kết vào bảng nhớ tạm</string>
+ <string name="go_to_position_label">Đi đến vị trí này</string>
<!--Playback history-->
+ <string name="clear_history_label">Xoá lịch sử</string>
<!--Other-->
<string name="confirm_label">Xác nhận</string>
<string name="cancel_label">Hủy bỏ</string>
+ <string name="yes">Có</string>
+ <string name="no">Không</string>
+ <string name="reset">Đặt lại</string>
<string name="author_label">Tác giả</string>
<string name="language_label">Ngôn ngữ</string>
+ <string name="url_label">Liên kết</string>
+ <string name="podcast_settings_label">Thiết lập</string>
+ <string name="cover_label">Hình</string>
<string name="error_label">Lỗi</string>
+ <string name="error_msg_prefix">Đã xảy ra lỗi:</string>
<string name="refresh_label">Cập nhật lại</string>
<string name="external_storage_error_msg">Hiện không có thiết bị lưu trữ gắn ngoài nào. Hãy chắc rằng bạn đã kết nối máy của mình với thiết bị lưu trữ gắn ngoài để ứng dụng có thể được hoạt động trơn tru.</string>
<string name="chapters_label">Chương</string>
- <string name="shownotes_label">Hiển thị ghi chú</string>
+ <string name="shownotes_label">Ghi chú</string>
+ <string name="description_label">Mô tả</string>
+ <string name="most_recent_prefix">Tập mới nhất:\u0020</string>
<string name="episodes_suffix">\u0020tập</string>
<string name="length_prefix">Độ dài:\u0020</string>
<string name="size_prefix">Kích thước:\u0020</string>
- <string name="processing_label">Đang xử lý</string>
+ <string name="processing_label">Đang xử lí</string>
+ <string name="loading_label">Đang tải…</string>
+ <string name="save_username_password_label">Lưu tên đăng nhập và mật khẩu</string>
+ <string name="close_label">Đóng</string>
+ <string name="retry_label">Thử lại</string>
+ <string name="auto_download_apply_to_items_title">Áp dụng cho các tập trước</string>
+ <string name="auto_delete_label">Tự xoá tập podcast</string>
+ <string name="parallel_downloads_suffix">\u0020tải xuống song song</string>
+ <string name="feed_auto_download_always">Luôn luôn</string>
+ <string name="feed_auto_download_never">Không bao giờ</string>
+ <string name="send_label">Gửi…</string>
+ <string name="episode_cleanup_never">Không bao giờ</string>
+ <string name="episode_cleanup_queue_removal">Khi không trong hàng đợi</string>
+ <string name="episode_cleanup_after_listening">Sau khi nghe xong</string>
+ <plurals name="episode_cleanup_days_after_listening">
+ <item quantity="other">%d ngày sau khi nghe xong</item>
+ </plurals>
<!--'Add Feed' Activity labels-->
<string name="feedurl_label">Đường dẫn liên kết feed</string>
+ <string name="etxtFeedurlHint">www.example.com/feed</string>
+ <string name="txtvfeedurl_label">Thêm podcast theo liên kết</string>
+ <string name="podcastdirectories_label">Tìm podcast trong danh mục</string>
+ <string name="podcastdirectories_descr">Để tải podcast mới, bạn có thể tìm kiếm trên iTunes hoặc fyyd, tra cứu trên gpodder.net theo tên, thể loại hoặc xếp hạng.</string>
+ <string name="browse_gpoddernet_label">Tra cứu gpodder.net</string>
<!--Actions on feeds-->
- <string name="show_info_label">Hiển thị thông ti</string>
- <string name="feed_delete_confirmation_msg">Xin vui lòng xác nhận rằng bạn muốn xóa feed này và toàn bộ các phần khác của feed này mà bạn đã tải về.</string>
+ <string name="mark_all_read_label">Đánh dấu đã nghe tất cả</string>
+ <string name="mark_all_read_msg">Đánh dấu đã nghe tất cả các tập</string>
+ <string name="mark_all_read_confirmation_msg">Hãy xác nhận bạn muốn đánh dấu đã nghe tất cả các tập.</string>
+ <string name="mark_all_seen_label">Đánh dấu đã xem tất cả</string>
+ <string name="mark_all_seen_msg">Đánh dấu đã xem tất cả các tập</string>
+ <string name="mark_all_seen_confirmation_msg">Hãy xác nhận bạn muốn đánh dấu đã xem tất cả các tập.</string>
+ <string name="show_info_label">Hiện thông tin</string>
+ <string name="rename_feed_label">Đổi tên podcast</string>
+ <string name="remove_feed_label">Xoá podcast</string>
+ <string name="share_label">Chia sẻ…</string>
+ <string name="share_link_label">Chia sẻ liên kết</string>
+ <string name="share_link_with_position_label">Chia sẻ liên kết cùng vị trí phát</string>
+ <string name="share_feed_url_label">Chia sẻ liên kết feed</string>
+ <string name="share_item_url_label">Chia sẻ liên kết của tập này</string>
+ <string name="share_item_url_with_position_label">Chia sẻ liên kết và vị trí phát tập này</string>
+ <string name="feed_remover_msg">Đang xoá feed</string>
+ <string name="hide_episodes_title">Ẩn các tập</string>
+ <string name="episode_actions">Áp dụng hành động</string>
+ <string name="hide_unplayed_episodes_label">Chưa nghe</string>
+ <string name="hide_paused_episodes_label">Đang tạm dừng</string>
+ <string name="hide_played_episodes_label">Đã nghe</string>
+ <string name="hide_queued_episodes_label">Đã thêm vào hàng đợi</string>
+ <string name="hide_not_queued_episodes_label">Chưa thêm vào hàng đợi</string>
+ <string name="hide_downloaded_episodes_label">Đã tải</string>
+ <string name="hide_not_downloaded_episodes_label">Chưa tải</string>
+ <string name="hide_has_media_label">Có tập tin phương tiện</string>
+ <string name="filtered_label">Đã lọc</string>
+ <string name="open_podcast">Mở podcast</string>
<!--actions on feeditems-->
<string name="download_label">Tải về</string>
<string name="play_label">Phát</string>
- <string name="stream_label">Phân luồng</string>
+ <string name="pause_label">Tạm dừng</string>
+ <string name="stop_label">Dừng</string>
+ <string name="stream_label">Nghe trực tiếp</string>
<string name="remove_label">Loại bỏ</string>
+ <string name="delete_label">Xoá</string>
+ <string name="remove_episode_lable">Xoá tập này</string>
+ <string name="marked_as_seen_label">Đánh dấu đã xem</string>
+ <string name="mark_read_label">Đánh dấu đã nghe</string>
+ <string name="marked_as_read_label">Đã đánh dấu đã nghe</string>
+ <string name="mark_unread_label">Đánh dấu chưa nghe</string>
<string name="add_to_queue_label">Thêm vào hàng đợi</string>
- <string name="remove_from_queue_label">Loại bỏ khỏi hàng đợi</string>
+ <string name="added_to_queue_label">Đã thêm vào hàng đợi</string>
+ <string name="remove_from_queue_label">Xoá khỏi hàng đợi</string>
+ <string name="add_to_favorite_label">Thêm vào danh sách ưa thích</string>
+ <string name="added_to_favorites">Đã thêm vào danh sách ưa thích</string>
+ <string name="remove_from_favorite_label">Xoá khỏi danh sách ưa thích</string>
+ <string name="removed_from_favorites">Đã xoá khỏi danh sách ưa thích</string>
<string name="visit_website_label">Truy cập website</string>
+ <string name="skip_episode_label">Bỏ qua tập này</string>
+ <string name="activate_auto_download">Bật tự động tải xuống</string>
+ <string name="deactivate_auto_download">Tắt tự động tải xuống</string>
+ <string name="reset_position">Đặt lại vị trí phát</string>
+ <string name="removed_item">Đã xoá mục này</string>
<!--Download messages and labels-->
+ <string name="download_successful">thành công</string>
+ <string name="download_failed">thất bại</string>
+ <string name="download_pending">Đang chờ tải xuống</string>
+ <string name="download_running">Đang tải xuống</string>
+ <string name="download_error_device_not_found">Không tìm được thiết bị lưu trữ</string>
+ <string name="download_error_insufficient_space">Không đủ bộ nhớ</string>
+ <string name="download_error_file_error">Lỗi tập tin</string>
+ <string name="download_error_http_data_error">Lỗi dữ liệu HTTP</string>
+ <string name="download_error_error_unknown">Lỗi không rõ nguyên nhân</string>
+ <string name="download_error_unsupported_type">Loại feed không được hỗ trợ</string>
+ <string name="download_error_connection_error">Lỗi kết nối</string>
+ <string name="download_error_unknown_host">Không rõ máy chủ</string>
+ <string name="download_error_unauthorized">Lỗi xác thực</string>
+ <string name="download_error_file_type_type">Lỗi loại tập tin</string>
+ <string name="download_error_forbidden">Bị cấm truy cập</string>
+ <string name="cancel_all_downloads_label">Huỷ bỏ mọi tải xuống</string>
+ <string name="download_canceled_msg">Đã huỷ bỏ tải xuống</string>
+ <string name="download_canceled_autodownload_enabled_msg">Đã huỷ bỏ tải xuống\n
+Đã tắt <i>tự động tải xuống</i> với mục này</string>
+ <string name="download_report_content_title">Báo cáo tải xuống</string>
+ <string name="download_error_malformed_url">Liên kết sai định dạng</string>
+ <string name="download_error_io_error">Lỗi vào ra dữ liệu</string>
+ <string name="download_error_db_access">Lỗi truy cập cơ sở dữ liệu</string>
+ <plurals name="downloads_left">
+ <item quantity="other">Còn %d tải xuống</item>
+ </plurals>
+ <string name="downloads_processing">Đang xử lí các mục tải xuống</string>
+ <string name="download_notification_title">Đang tải dữ liệu podcast</string>
+ <string name="download_report_content">%1$d tải xuống thành công, %2$d thất bại</string>
+ <string name="download_log_title_unknown">Không rõ tiêu đề</string>
+ <string name="download_type_feed">Feed</string>
+ <string name="download_type_media">Tập tin phương tiện</string>
+ <string name="download_type_image">Hình</string>
+ <string name="download_request_error_dialog_message_prefix">Đã xảy ra lỗi khi tải tập tin:\u0020</string>
+ <string name="authentication_notification_title">Yêu cầu xác thực</string>
+ <string name="authentication_notification_msg">Phải nhập tên đăng nhập và mật khẩu để truy cập tài nguyên</string>
+ <string name="confirm_mobile_download_dialog_title">Xác nhận tải xuống bằng kết nối di động</string>
+ <string name="confirm_mobile_download_dialog_only_add_to_queue">Thêm vào hàng đợi</string>
+ <string name="confirm_mobile_download_dialog_enable_temporarily">Tạm thời cho phép</string>
<!--Mediaplayer messages-->
+ <string name="player_error_msg">Lỗi!</string>
+ <string name="player_preparing_msg">Đang chuẩn bị</string>
+ <string name="player_ready_msg">Sẵn sàng</string>
+ <string name="playback_error_server_died">Máy chủ lỗi</string>
+ <string name="playback_error_unknown">Lỗi không rõ nguyên nhân</string>
+ <string name="playbackservice_notification_title">Đang nghe podcast</string>
<!--Queue operations-->
+ <string name="lock_queue">Khoá hàng đợi</string>
+ <string name="unlock_queue">Mở khoá hàng đợi</string>
+ <string name="queue_locked">Đã khoá hàng đợi</string>
+ <string name="queue_unlocked">Đã mở khoá hàng đợi</string>
+ <string name="clear_queue_label">Xoá hàng đợi</string>
+ <string name="undo">Hoàn tác</string>
+ <string name="removed_from_queue">Đã xoá mục này</string>
+ <string name="move_to_top_label">Chuyển lên trên cùng</string>
+ <string name="move_to_bottom_label">Chuyển xuống dưới cùng</string>
+ <string name="sort">Sắp xếp</string>
+ <string name="date">Ngày</string>
+ <string name="duration">Thời lượng</string>
+ <string name="episode_title">Tiêu đề tập</string>
+ <string name="feed_title">Tiêu đề feed</string>
+ <string name="ascending">Tăng dần</string>
+ <string name="descending">Giảm dần</string>
<!--Flattr-->
+ <string name="flattr_auth_label">Đăng nhập Flatter</string>
+ <string name="authenticate_label">Xác thực</string>
+ <string name="return_home_label">Trở về trang chủ</string>
+ <string name="authenticate_now_label">Xác thực</string>
<!--Flattr-->
<!--Variable Speed-->
+ <string name="download_plugin_label">Tải plugin</string>
+ <string name="no_playback_plugin_title">Chưa cài plugin</string>
+ <string name="set_playback_speed_label">Tốc độ phát</string>
+ <string name="enable_sonic">Bật plugin Sonic</string>
<!--Empty list labels-->
+ <string name="no_items_label">Danh sách này không có mục nào.</string>
+ <string name="no_chapters_label">Tập này không có chương nào.</string>
+ <string name="no_shownotes_label">Tập này không có ghi chú.</string>
<!--Preferences-->
+ <string name="storage_pref">Bộ nhớ lưu trữ</string>
+ <string name="other_pref">Khác</string>
+ <string name="about_pref">Thông tin</string>
+ <string name="queue_label">Hàng đợi</string>
+ <string name="flattr_label">Flatter</string>
+ <string name="pref_episode_cleanup_title">Dọn các tập podcast</string>
+ <string name="pref_episode_cleanup_summary">Có thể xoá các tập không trong hàng đợi phát hoặc danh sách ưa thích nếu tính năng tự tải xuống cần thêm bộ nhớ trống cho các tập mới </string>
+ <string name="pref_pauseOnDisconnect_sum">Tạm dừng khi tai nghe hoặc thiết bị Bluetooth bị ngắt kết nối</string>
+ <string name="pref_unpauseOnHeadsetReconnect_sum">Tiếp tục phát khi tai nghe được kết nối lại</string>
+ <string name="pref_unpauseOnBluetoothReconnect_sum">Tiếp tục phát khi thiết bị Bluetooth được kết nối lại</string>
+ <string name="pref_hardwareForwardButtonSkips_sum">Khi ấn nút tua nhanh (nút cứng), không tua mà chuyến sang tập tiếp theo</string>
+ <string name="pref_hardwarePreviousButtonRestarts_title">Nghe lại khi ấn nút tua lại</string>
+ <string name="pref_hardwarePreviousButtonRestarts_sum">Khi ấn nút tua lại (nút cứng), không tua lại mà phát lại tập đang nghe</string>
+ <string name="pref_followQueue_sum">Chuyển đến mục đợi phát tiếp theo khi nghe xong</string>
+ <string name="pref_auto_delete_sum">Xoá các tập podcast sau khi nghe xong</string>
+ <string name="pref_auto_delete_title">Tự động xoá</string>
+ <string name="pref_smart_mark_as_played_sum">Khi còn một khoảng thời gian chưa nghe hết, vẫn đánh dấu đã nghe tập podcast</string>
+ <string name="pref_skip_keeps_episodes_sum">Giữ lại các tập podcast khi bị bỏ qua</string>
+ <string name="pref_skip_keeps_episodes_title">Giữ các tập bị bỏ qua</string>
+ <string name="playback_pref">Phát</string>
+ <string name="network_pref">Mạng</string>
+ <string name="pref_autoUpdateIntervallOrTime_Disable">Tắt</string>
+ <string name="pref_autoUpdateIntervallOrTime_every">mỗi %1$s</string>
+ <string name="pref_autoUpdateIntervallOrTime_at">vào lúc %1$s</string>
+ <string name="pref_downloadMediaOnWifiOnly_sum">Chỉ tải xuống tập tin đa phương tiện qua WiFi</string>
+ <string name="pref_followQueue_title">Phát liên tục</string>
+ <string name="pref_mobileUpdate_title">Cập nhật qua mạng di động</string>
+ <string name="pref_mobileUpdate_sum">Cho phép cập nhật qua kết nối mạng di động</string>
+ <string name="pref_theme_title_light">Sáng</string>
+ <string name="pref_theme_title_dark">Tối</string>
+ <string name="pref_episode_cache_unlimited">Không giới hạn</string>
+ <string name="pref_update_interval_hours_plural">giờ</string>
+ <string name="pref_update_interval_hours_singular">giờ</string>
+ <string name="pref_update_interval_hours_manual">Thủ công</string>
+ <string name="pref_gpodnet_authenticate_title">Đăng nhập</string>
+ <string name="pref_gpodnet_logout_title">Đăng xuất</string>
+ <string name="pref_gpodnet_logout_toast">Đăng xuất thành công</string>
+ <string name="pref_gpodnet_setlogin_information_title">Thay đổi thông tin đăng nhập</string>
+ <string name="pref_showDownloadReport_title">Hiện báo cáo tải xuống</string>
+ <string name="pref_queueAddToFront_title">Thêm vào đầu hàng đợi</string>
+ <string name="pref_smart_mark_as_played_disabled">Tắt</string>
+ <string name="pref_image_cache_size_sum">Kích cỡ bộ nhớ tạm cho các hình ảnh.</string>
+ <string name="send_email">Gửi email</string>
+ <string name="experimental_pref">Thử nghiệm</string>
+ <string name="pref_proxy_title">Proxy</string>
+ <string name="pref_proxy_sum">Đặt proxy mạng</string>
+ <string name="pref_faq">Câu hỏi thường gặp</string>
+ <string name="pref_no_browser_found">Không tìm thấy trình duyệt nào.</string>
+ <string name="pref_cast_title">Hỗ trợ Chromecast</string>
<!--Auto-Flattr dialog-->
<!--Search-->
+ <string name="search_hint">Tìm các tập podcast</string>
+ <string name="search_status_no_results">Không tìm thấy kết quả nào</string>
+ <string name="search_label">Tìm kiếm</string>
<!--OPML import and export-->
<!--Sleep timer-->
<!--gpodder.net-->
+ <string name="gpodnet_search_hint">Tìm kiếm gpodder.net</string>
<!--Directory chooser-->
<!--Online feed view-->
<!--Content descriptions for image buttons-->
<!--Feed information screen-->
<!--Progress information-->
<!--AntennaPodSP-->
+ <string name="search_itunes_label">Tìm kiếm iTunes</string>
+ <string name="filter">Lọc</string>
+ <string name="search_fyyd_label">Tìm kiếm fyyd</string>
<!--Episodes apply actions-->
<!--Sort-->
+ <string name="sort_title_a_z">Tiêu đề (A \u2192 Z)</string>
+ <string name="sort_title_z_a">Tiêu đề (Z \u2192 A)</string>
+ <string name="sort_date_new_old">Ngày (Mới \u2192 Cũ)</string>
+ <string name="sort_date_old_new">Ngày (Cũ \u2192 Mới)</string>
+ <string name="sort_duration_short_long">Thời lượng (Ngắn \u2192 Dài)</string>
+ <string name="sort_duration_long_short">Thời lượng (Dài \u2192 Ngắn)</string>
<!--Rating dialog-->
+ <string name="rating_later_label">Nhắc lại sau</string>
+ <string name="rating_now_label">Dĩ nhiên rồi!</string>
<!--Audio controls-->
+ <string name="playback_speed">Tốc độ phát</string>
+ <string name="volume">Âm lượng</string>
+ <string name="audio_effects">Hiệu ứng âm thanh</string>
<!--proxy settings-->
<!--Casting-->
<!--<string name="cast_failed_to_connect">Could not connect to the device</string>-->
diff --git a/core/src/main/res/values-zh-rCN/strings.xml b/core/src/main/res/values-zh-rCN/strings.xml
index ab49e8c49..c09ec4b42 100644
--- a/core/src/main/res/values-zh-rCN/strings.xml
+++ b/core/src/main/res/values-zh-rCN/strings.xml
@@ -105,7 +105,6 @@
<string name="share_feed_url_label">分享订阅地址</string>
<string name="share_item_url_label">分享剧集文件URL</string>
<string name="share_item_url_with_position_label">分享剧集文件URL及其状态</string>
- <string name="feed_delete_confirmation_msg">确认要删除这些订阅吗? 该订阅所有已经下载的曲目将一并删除. </string>
<string name="feed_remover_msg">删除订阅</string>
<string name="load_complete_feed">刷新全部订阅</string>
<string name="hide_episodes_title">隐藏曲目</string>
@@ -270,7 +269,6 @@
<string name="pref_auto_delete_sum">当播放完成后删除曲目</string>
<string name="pref_auto_delete_title">自动删除</string>
<string name="pref_smart_mark_as_played_sum">当曲目的剩余未播放时间小于一个确定值时将其表为已播放</string>
- <string name="pref_smart_mark_as_played_title">智能标记为已播放</string>
<string name="playback_pref">播放</string>
<string name="network_pref">网络</string>
<string name="pref_autoUpdateIntervallOrTime_title">定时更新</string>
@@ -333,7 +331,6 @@
<string name="pref_gpodnet_sync_started">已开始同步</string>
<string name="pref_playback_speed_title">播放速度</string>
<string name="pref_playback_speed_sum">自定义音频播放速度</string>
- <string name="pref_rewind">时间倒回</string>
<string name="pref_gpodnet_sethostname_title">设置主机名</string>
<string name="pref_gpodnet_sethostname_use_default_host">使用默认主机</string>
<string name="pref_expandNotify_title">扩展通知</string>
@@ -355,7 +352,6 @@
<string name="crash_report_title">崩溃报告</string>
<string name="crash_report_sum">通过 E-mail 发送最后崩溃报告</string>
<string name="send_email">发送 E-mail</string>
- <string name="pref_sonic_title">内置播放器</string>
<string name="pref_current_value">当前值:%1$s</string>
<string name="pref_proxy_title">代理</string>
<string name="pref_proxy_sum">选择一个网络代理</string>
diff --git a/core/src/main/res/values/arrays.xml b/core/src/main/res/values/arrays.xml
index 133a3ed6e..45650495c 100644
--- a/core/src/main/res/values/arrays.xml
+++ b/core/src/main/res/values/arrays.xml
@@ -157,11 +157,13 @@
<item>@string/drawer_feed_order_unplayed_episodes</item>
<item>@string/drawer_feed_order_alphabetical</item>
<item>@string/drawer_feed_order_last_update</item>
+ <item>@string/drawer_feed_order_most_played</item>
</string-array>
<string-array name="nav_drawer_feed_order_values">
<item>0</item>
<item>1</item>
<item>2</item>
+ <item>3</item>
</string-array>
<string-array name="nav_drawer_feed_counter_options">
diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml
index 1616b3ecb..38c891d99 100644
--- a/core/src/main/res/values/strings.xml
+++ b/core/src/main/res/values/strings.xml
@@ -13,7 +13,6 @@
<string name="favorite_episodes_label">Favorites</string>
<string name="new_label">New</string>
<string name="settings_label">Settings</string>
- <string name="add_new_feed_label">Add Podcast</string>
<string name="downloads_label">Downloads</string>
<string name="downloads_running_label">Running</string>
<string name="downloads_completed_label">Completed</string>
@@ -31,6 +30,10 @@
<!-- Statistics fragment -->
<string name="total_time_listened_to_podcasts">Total time of podcasts played:</string>
<string name="statistics_details_dialog">%1$d out of %2$d episodes started.\n\nPlayed %3$s out of %4$s.</string>
+ <string name="statistics_mode">Statistics mode</string>
+ <string name="statistics_mode_normal">Calculate duration that was actually played. Playing twice is counted twice, while marking as played is not counted</string>
+ <string name="statistics_mode_count_all">Sum up all podcasts marked as played</string>
+ <string name="statistics_speed_not_counted">Notice: Playback speed is never taken into account.</string>
<!-- Main activity -->
<string name="drawer_open">Open menu</string>
@@ -39,6 +42,7 @@
<string name="drawer_feed_order_unplayed_episodes">Sort by counter</string>
<string name="drawer_feed_order_alphabetical">Sort alphabetically</string>
<string name="drawer_feed_order_last_update">Sort by publication date</string>
+ <string name="drawer_feed_order_most_played">Sort by number of played episodes</string>
<string name="drawer_feed_counter_new_unplayed">Number of new and unplayed episodes</string>
<string name="drawer_feed_counter_new">Number of new episodes</string>
<string name="drawer_feed_counter_unplayed">Number of unplayed episodes</string>
@@ -71,6 +75,7 @@
<string name="refresh_label">Refresh</string>
<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>
@@ -120,11 +125,12 @@
<string name="remove_feed_label">Remove Podcast</string>
<string name="share_label">Share&#8230;</string>
<string name="share_link_label">Share Link</string>
+ <string name="share_file_label">Share File</string>
<string name="share_link_with_position_label">Share Link with Position</string>
<string name="share_feed_url_label">Share Feed URL</string>
<string name="share_item_url_label">Share Episode File URL</string>
<string name="share_item_url_with_position_label">Share Episode File URL with Position</string>
- <string name="feed_delete_confirmation_msg">Please confirm that you want to delete this feed and ALL episodes of this feed that you have downloaded.</string>
+ <string name="feed_delete_confirmation_msg">Please confirm that you want to delete the feed \"%1$s\" and ALL episodes of this feed that you have downloaded.</string>
<string name="feed_remover_msg">Removing Feed</string>
<string name="load_complete_feed">Refresh complete Feed</string>
<string name="hide_episodes_title">Hide Episodes</string>
@@ -149,6 +155,7 @@
<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="remove_episode_lable">Remove Episode</string>
<string name="marked_as_seen_label">Marked as seen</string>
<string name="mark_read_label">Mark as played</string>
@@ -302,7 +309,7 @@
<string name="pref_pauseOnDisconnect_sum">Pause playback when headphones or bluetooth are disconnected</string>
<string name="pref_unpauseOnHeadsetReconnect_sum">Resume playback when the headphones are reconnected</string>
<string name="pref_unpauseOnBluetoothReconnect_sum">Resume playback when bluetooth reconnects</string>
- <string name="pref_hardwareForwardButtonSkips_title">Forward button skips</string>
+ <string name="pref_hardwareForwardButtonSkips_title">Forward Button Skips</string>
<string name="pref_hardwareForwardButtonSkips_sum">When pressing a hardware forward button skip to the next episode instead of fast-forwarding</string>
<string name="pref_hardwarePreviousButtonRestarts_title">Previous button restarts</string>
<string name="pref_hardwarePreviousButtonRestarts_sum">When pressing a hardware previous button restart playing the current episode instead of rewinding</string>
@@ -310,7 +317,7 @@
<string name="pref_auto_delete_sum">Delete episode when playback completes</string>
<string name="pref_auto_delete_title">Auto Delete</string>
<string name="pref_smart_mark_as_played_sum">Mark episodes as played even if less than a certain amount of seconds of playing time is still left</string>
- <string name="pref_smart_mark_as_played_title">Smart mark as played</string>
+ <string name="pref_smart_mark_as_played_title">Smart Mark as Played</string>
<string name="pref_skip_keeps_episodes_sum">Keep episodes when they are skipped</string>
<string name="pref_skip_keeps_episodes_title">Keep Skipped Episodes</string>
<string name="pref_favorite_keeps_episodes_sum">Keep episodes when they are marked Favorite</string>
@@ -386,8 +393,10 @@
<string name="pref_gpodnet_notifications_sum">This setting does not apply to authentication errors.</string>
<string name="pref_playback_speed_title">Playback Speeds</string>
<string name="pref_playback_speed_sum">Customize the speeds available for variable speed audio playback</string>
- <string name="pref_fast_forward">Fast forward time</string>
- <string name="pref_rewind">Rewind time</string>
+ <string name="pref_fast_forward">Fast Forward Skip Time</string>
+ <string name="pref_fast_forward_sum">Customize the number of seconds to jump forward when the fast forward button is clicked</string>
+ <string name="pref_rewind">Rewind Skip Time</string>
+ <string name="pref_rewind_sum">Customize the number of seconds to jump backwards when the rewind button is clicked</string>
<string name="pref_gpodnet_sethostname_title">Set hostname</string>
<string name="pref_gpodnet_sethostname_use_default_host">Use default host</string>
<string name="pref_expandNotify_title">Expand Notification</string>
@@ -412,7 +421,7 @@
<string name="crash_report_sum">Send the latest crash report via e-mail</string>
<string name="send_email">Send e-mail</string>
<string name="experimental_pref">Experimental</string>
- <string name="pref_sonic_title">Sonic media player</string>
+ <string name="pref_sonic_title">Sonic Media Player</string>
<string name="pref_sonic_message">Use built-in sonic media player as a replacement for Android\'s native mediaplayer and Prestissimo</string>
<string name="pref_current_value">Current value: %1$s</string>
<string name="pref_proxy_title">Proxy</string>
@@ -423,6 +432,8 @@
<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>
<string name="pref_cast_message_free_flavor">Chromecast requires third party proprietary libraries that are disabled in this version of AntennaPod</string>
+ <string name="pref_enqueue_downloaded_title">Enqueue Downloaded</string>
+ <string name="pref_enqueue_downloaded_summary">Add downloaded episodes to the queue</string>
<!-- Auto-Flattr dialog -->
<string name="auto_flattr_enable">Enable automatic flattring</string>
@@ -434,6 +445,8 @@
<string name="search_hint">Search for episodes</string>
<string name="found_in_shownotes_label">Found in show notes</string>
<string name="found_in_chapters_label">Found in chapters</string>
+ <string name="found_in_authors_label">Found in authors</string>
+ <string name="found_in_feeds_label">Found in feeds</string>
<string name="search_status_no_results">No results were found</string>
<string name="search_label">Search</string>
<string name="found_in_title_label">Found in title</string>
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 0f493e63e..0cca2ffa4 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
@@ -6,9 +6,13 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
+import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
+import android.support.v4.media.session.MediaSessionCompat;
+import android.support.v4.media.session.PlaybackStateCompat;
import android.support.v7.media.MediaRouter;
+import android.support.wearable.media.MediaControlConstants;
import android.util.Log;
import android.widget.Toast;
@@ -255,4 +259,21 @@ public class PlaybackServiceFlavorHelper {
}
return false;
}
+
+ void sessionStateAddActionForWear(PlaybackStateCompat.Builder sessionState, String actionName, CharSequence name, int icon) {
+ PlaybackStateCompat.CustomAction.Builder actionBuilder =
+ new PlaybackStateCompat.CustomAction.Builder(actionName, name, icon);
+ Bundle actionExtras = new Bundle();
+ actionExtras.putBoolean(MediaControlConstants.EXTRA_CUSTOM_ACTION_SHOW_ON_WEAR, true);
+ actionBuilder.setExtras(actionExtras);
+
+ sessionState.addCustomAction(actionBuilder.build());
+ }
+
+ void mediaSessionSetExtraForWear(MediaSessionCompat mediaSession) {
+ Bundle sessionExtras = new Bundle();
+ sessionExtras.putBoolean(MediaControlConstants.EXTRA_RESERVE_SLOT_SKIP_TO_PREVIOUS, true);
+ sessionExtras.putBoolean(MediaControlConstants.EXTRA_RESERVE_SLOT_SKIP_TO_NEXT, true);
+ mediaSession.setExtras(sessionExtras);
+ }
}
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 51288f9c2..736fb7d3f 100644
--- a/gradle/wrapper/gradle-wrapper.jar
+++ b/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index daa995e8e..52dd1f044 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,5 @@
-#Sat Dec 03 12:40:10 CET 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-3.2.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.2-bin.zip
diff --git a/gradlew b/gradlew
index 4453ccea3..cccdd3d51 100755
--- a/gradlew
+++ b/gradlew
@@ -33,11 +33,11 @@ DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
-warn ( ) {
+warn () {
echo "$*"
}
-die ( ) {
+die () {
echo
echo "$*"
echo
@@ -155,7 +155,7 @@ if $cygwin ; then
fi
# Escape application args
-save ( ) {
+save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}