diff options
8 files changed, 543 insertions, 394 deletions
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 c0b17ae25..e620da0bd 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 @@ -387,7 +387,13 @@ 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)); 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 8ed6718c0..32c642de2 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,22 +352,23 @@ 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: " + ""); + Log.d(TAG, "getDownloadedItems() called"); 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; - + 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(); + } } /** @@ -359,20 +381,24 @@ public final class DBReader { 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.getUnreadItemsCursor(); + List<FeedItem> items = extractItemlistFromCursor(adapter, cursor); + loadAdditionalFeedItemListData(items); + 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 +406,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 +425,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 +497,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 +533,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 +555,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 +590,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 +683,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 +726,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 +750,9 @@ public final class DBReader { credentials = ""; } } finally { - cursor.close(); + if (cursor != null) { + cursor.close(); + } } return credentials; } @@ -739,31 +770,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 +810,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 +875,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 +898,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 +921,22 @@ 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) { + 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,29 +953,31 @@ 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; } /** @@ -1100,7 +1156,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: " + ""); @@ -1108,48 +1163,48 @@ 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) { + } 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) { + if (counterLhs > counterRhs) { // podcast with most played episodes first return -1; - } else if(counterLhs == counterRhs) { + } else if (counterLhs == counterRhs) { return lhs.getTitle().compareToIgnoreCase(rhs.getTitle()); } else { return 1; @@ -1157,17 +1212,17 @@ public final class DBReader { }; } 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/PodDBAdapter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java index 4e9198d90..7bb727d68 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 @@ -1189,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); @@ -1374,7 +1376,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); diff --git a/core/src/main/res/values-de/strings.xml b/core/src/main/res/values-de/strings.xml index 742277879..c7da72961 100644 --- a/core/src/main/res/values-de/strings.xml +++ b/core/src/main/res/values-de/strings.xml @@ -90,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</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> @@ -295,7 +295,7 @@ <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 bereits 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_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> diff --git a/core/src/main/res/values-fr/strings.xml b/core/src/main/res/values-fr/strings.xml index 80847d73b..b460eaef7 100644 --- a/core/src/main/res/values-fr/strings.xml +++ b/core/src/main/res/values-fr/strings.xml @@ -26,10 +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">Préférences statistiques</string> - <string name="statistics_mode_normal">Calculer la durée réellement écoutée. Les doubles écoutes comptent double alors que marqué lu n\'est pas compté</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 lu 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 pris en compte.</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> @@ -287,15 +287,15 @@ <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_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">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_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_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> @@ -398,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> @@ -535,7 +535,7 @@ <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="rewind_label">Saut arrière</string> <string name="fast_forward_label">Avance rapide</string> <string name="media_type_audio_label">Audio</string> <string name="media_type_video_label">Vidéo</string> diff --git a/core/src/main/res/values-ja/strings.xml b/core/src/main/res/values-ja/strings.xml index d49c0d6ae..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,6 +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">フィード \"%1$s\" と、このフィードのすべてのダウンロードしたエピソードを削除することを確認してください。</string> <string name="feed_remover_msg">フィードの削除中</string> <string name="load_complete_feed">フィードをすべて更新</string> <string name="hide_episodes_title">エピソードを非表示にする</string> @@ -278,6 +285,7 @@ <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> @@ -285,6 +293,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_skip_keeps_episodes_sum">エピソードをスキップした時に残しておきます</string> <string name="pref_skip_keeps_episodes_title">エピソードのスキップ時に残す</string> <string name="playback_pref">再生</string> @@ -358,6 +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_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> @@ -382,6 +395,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_message">Android 標準のメディアプレーヤーと Prestissimo の代わりに、内蔵のソニックメディアプレーヤーを使用します</string> <string name="pref_current_value">現在の値: %1$s</string> <string name="pref_proxy_title">プロキシ</string> @@ -392,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> @@ -401,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-sv-rSE/strings.xml b/core/src/main/res/values-sv-rSE/strings.xml index 4b7d8f504..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,6 +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 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> @@ -118,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> @@ -128,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> @@ -272,11 +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">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 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> @@ -338,10 +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">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> @@ -366,6 +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_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> @@ -376,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> @@ -404,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> @@ -434,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> @@ -463,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> @@ -515,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> @@ -532,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-uk-rUA/strings.xml b/core/src/main/res/values-uk-rUA/strings.xml index 9540f595d..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,6 +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">Будь ласка, підтвердіть що ви бажаєте видалити канал \"%1$s\" і ВСІ епізоди цього канала які ви завантажили.</string> <string name="feed_remover_msg">Удаляю канал</string> <string name="load_complete_feed">Оновити канал цілком</string> <string name="hide_episodes_title">Приховати епізоди</string> @@ -282,6 +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_sum">При натисканні апаратної кнопки перемотки перейти до наступного епізода замість перемотки.</string> <string name="pref_hardwarePreviousButtonRestarts_title">Кнопка \"назад\" повертає до початку</string> <string name="pref_hardwarePreviousButtonRestarts_sum">При натисканні апаратної кнопки \"назад\", замість перемотки, розпочати програвання поточного епізода заново</string> @@ -289,6 +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_skip_keeps_episodes_sum">Зберігати епізоди що пропущені при програванні </string> <string name="pref_skip_keeps_episodes_title">Зберігати пропущені при програванні епізоди </string> <string name="playback_pref">Відтворення</string> @@ -362,6 +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_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> @@ -386,6 +399,7 @@ <string name="crash_report_sum">Надіслати е-пошту зі звітом про останній збій</string> <string name="send_email">Надіслати е-пошту</string> <string name="experimental_pref">Експериментальні</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> @@ -396,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> @@ -405,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> |