summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Fietz <Martin.Fietz@gmail.com>2017-04-09 20:34:43 +0200
committerGitHub <noreply@github.com>2017-04-09 20:34:43 +0200
commit5cbf092f3bde5c185c1826a941909db5f2a32c7d (patch)
treef20546ce2e40c7037cb3aaadadbb113afdd8bbae
parentdc38ecdd688423232a7c1ac51d6efbecba1f5eab (diff)
parent4d256b7323d5a00b081508b13eb9141ab3aa9035 (diff)
downloadAntennaPod-5cbf092f3bde5c185c1826a941909db5f2a32c7d.zip
Merge branch 'develop' into develop
-rw-r--r--.tx/config4
-rw-r--r--CHANGELOG.md389
-rw-r--r--README.md2
-rw-r--r--app/build.gradle13
-rw-r--r--app/proguard.cfg19
-rw-r--r--app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java2
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java2
-rw-r--r--app/src/main/AndroidManifest.xml21
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java133
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java20
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java28
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java41
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/OpmlFeedChooserActivity.java6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/OpmlImportBaseActivity.java9
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/OpmlImportHolder.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java13
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivityGingerbread.java10
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/SplashActivity.java23
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/AdapterUtils.java5
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java67
-rw-r--r--app/src/main/java/de/danoeh/antennapod/asynctask/ExportWorker.java65
-rw-r--r--app/src/main/java/de/danoeh/antennapod/asynctask/OpmlExportWorker.java122
-rw-r--r--app/src/main/java/de/danoeh/antennapod/asynctask/OpmlFeedQueuer.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/asynctask/OpmlImportWorker.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java15
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java17
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/RenameFeedDialog.java44
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java57
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java5
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java20
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java16
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java19
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/FyydSearchFragment.java192
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java12
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java15
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/menuhandler/MenuItemUtils.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java178
-rw-r--r--app/src/main/play/ast_ES/listing/fulldescription43
-rw-r--r--app/src/main/play/lt/listing/fulldescription43
-rw-r--r--app/src/main/play/te/listing/fulldescription43
-rw-r--r--app/src/main/play/zh_TW/listing/fulldescription43
-rw-r--r--app/src/main/res/layout-v14/time_dialog.xml44
-rw-r--r--app/src/main/res/layout/addfeed.xml56
-rw-r--r--app/src/main/res/layout/nav_list.xml23
-rw-r--r--app/src/main/res/layout/subscription_item.xml19
-rw-r--r--app/src/main/res/layout/time_dialog.xml40
-rw-r--r--app/src/main/res/menu/episodes_apply_action_options.xml2
-rw-r--r--app/src/main/res/menu/feedlist.xml6
-rw-r--r--app/src/main/res/menu/nav_feed_context.xml5
-rw-r--r--app/src/main/res/xml/automotive_app_desc.xml4
-rw-r--r--app/src/main/res/xml/preferences.xml23
-rw-r--r--app/src/main/templates/about.html2
-rw-r--r--build.gradle14
-rw-r--r--circle.yml5
-rw-r--r--core/build.gradle6
-rw-r--r--core/src/free/java/de/danoeh/antennapod/core/ClientConfig.java3
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/asynctask/FeedRemover.java7
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java22
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/event/MessageEvent.java21
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/export/CommonSymbols.java24
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/export/ExportWriter.java29
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/export/html/HtmlSymbols.java30
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/export/html/HtmlWriter.java82
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlElement.java (renamed from core/src/main/java/de/danoeh/antennapod/core/opml/OpmlElement.java)2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlReader.java (renamed from core/src/main/java/de/danoeh/antennapod/core/opml/OpmlReader.java)2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlSymbols.java21
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlWriter.java (renamed from core/src/main/java/de/danoeh/antennapod/core/opml/OpmlWriter.java)30
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java52
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/FeedItemFilter.java6
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/glide/ApOkHttpUrlLoader.java24
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/gpoddernet/GpodnetService.java40
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/opml/OpmlSymbols.java22
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/preferences/SleepTimerPreferences.java80
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java42
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/download/AntennapodHttpClient.java78
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java12
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java41
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java51
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java96
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java58
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java4
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java39
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java11
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/FeedSearcher.java24
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java69
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/syndication/handler/SyndHandler.java19
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSMedia.java34
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSRSS20.java59
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/atom/NSAtom.java40
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/syndication/util/SyndTypeUtils.java53
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/NetworkUtils.java8
-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.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/syndication/HtmlToPlainText.java89
-rw-r--r--core/src/main/res/drawable/bg_splash.xml13
-rw-r--r--core/src/main/res/values-az/strings.xml2
-rw-r--r--core/src/main/res/values-b+ast/strings.xml354
-rw-r--r--core/src/main/res/values-ca-rES/strings.xml23
-rw-r--r--core/src/main/res/values-ca/strings.xml3
-rw-r--r--core/src/main/res/values-cs-rCZ/strings.xml17
-rw-r--r--core/src/main/res/values-da/strings.xml3
-rw-r--r--core/src/main/res/values-de/strings.xml7
-rw-r--r--core/src/main/res/values-el/strings.xml13
-rw-r--r--core/src/main/res/values-es-rES/strings.xml2
-rw-r--r--core/src/main/res/values-es/strings.xml35
-rw-r--r--core/src/main/res/values-et/strings.xml8
-rw-r--r--core/src/main/res/values-fr/strings.xml41
-rw-r--r--core/src/main/res/values-hi-rIN/strings.xml2
-rw-r--r--core/src/main/res/values-hu/strings.xml50
-rw-r--r--core/src/main/res/values-id/strings.xml1
-rw-r--r--core/src/main/res/values-it-rIT/strings.xml13
-rw-r--r--core/src/main/res/values-it/strings.xml2
-rw-r--r--core/src/main/res/values-iw-rIL/strings.xml9
-rw-r--r--core/src/main/res/values-ja/strings.xml33
-rw-r--r--core/src/main/res/values-kn-rIN/strings.xml2
-rw-r--r--core/src/main/res/values-ko/strings.xml26
-rw-r--r--core/src/main/res/values-lt/strings.xml153
-rw-r--r--core/src/main/res/values-nb/strings.xml3
-rw-r--r--core/src/main/res/values-nl/strings.xml40
-rw-r--r--core/src/main/res/values-no-rNB/strings.xml3
-rw-r--r--core/src/main/res/values-pl-rPL/strings.xml132
-rw-r--r--core/src/main/res/values-pt-rBR/strings.xml151
-rw-r--r--core/src/main/res/values-pt/strings.xml30
-rw-r--r--core/src/main/res/values-ro-rRO/strings.xml2
-rw-r--r--core/src/main/res/values-ru/strings.xml20
-rw-r--r--core/src/main/res/values-sv-rSE/strings.xml5
-rw-r--r--core/src/main/res/values-te/strings.xml38
-rw-r--r--core/src/main/res/values-tr/strings.xml23
-rw-r--r--core/src/main/res/values-uk-rUA/strings.xml57
-rw-r--r--core/src/main/res/values-zh-rCN/strings.xml39
-rw-r--r--core/src/main/res/values-zh-rTW/strings.xml38
-rw-r--r--core/src/main/res/values/arrays.xml4
-rw-r--r--core/src/main/res/values/strings.xml27
-rw-r--r--core/src/main/res/values/styles.xml14
-rw-r--r--core/src/play/java/de/danoeh/antennapod/core/ClientConfig.java2
-rw-r--r--core/src/play/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceFlavorHelper.java5
-rw-r--r--core/src/play/java/de/danoeh/antennapod/core/service/playback/RemotePSMP.java18
-rw-r--r--gradle/wrapper/gradle-wrapper.jarbin53324 -> 54227 bytes
-rw-r--r--gradle/wrapper/gradle-wrapper.properties4
-rwxr-xr-xgradlew22
-rw-r--r--gradlew.bat6
146 files changed, 3756 insertions, 1115 deletions
diff --git a/.tx/config b/.tx/config
index 5d5818118..2634a90f5 100644
--- a/.tx/config
+++ b/.tx/config
@@ -4,6 +4,7 @@ host = https://www.transifex.com
[antennapod.english]
source_file = core/src/main/res/values/strings.xml
source_lang = en
+trans.ast_ES = core/src/main/res/values-b+ast/strings.xml
trans.ar = core/src/main/res/values-ar/strings.xml
trans.az = core/src/main/res/values-az/strings.xml
trans.ca = core/src/main/res/values-ca/strings.xml
@@ -27,6 +28,7 @@ trans.ja = core/src/main/res/values-ja/strings.xml
trans.kn_IN = core/src/main/res/values-kn-rIN/strings.xml
trans.ko = core/src/main/res/values-ko/strings.xml
trans.ko_KR = core/src/main/res/values-ko-rKR/strings.xml
+trans.lt = core/src/main/res/values-lt/strings.xml
trans.nb = core/src/main/res/values-nb/strings.xml
trans.no = core/src/main/res/values-no/strings.xml
trans.nl = core/src/main/res/values-nl/strings.xml
@@ -42,9 +44,11 @@ trans.ru_RU = core/src/main/res/values-ru/strings.xml
trans.uk_UA = core/src/main/res/values-uk-rUA/strings.xml
trans.zh_CN = core/src/main/res/values-zh-rCN/strings.xml
trans.sv_SE = core/src/main/res/values-sv-rSE/strings.xml
+trans.te = core/src/main/res/values-te/strings.xml
trans.tr = core/src/main/res/values-tr/strings.xml
trans.vi = core/src/main/res/values-vi/strings.xml
trans.vi_VN = core/src/main/res/values-vi-rVN/strings.xml
+trans.zh_TW = core/src/main/res/values-zh-rTW/strings.xml
[antennapod.description]
file_filter = app/src/main/play/<lang>/listing/fulldescription
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 000000000..122213dfd
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,389 @@
+Change Log
+==========
+
+
+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
+* 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
+* 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
+
+Version 1.6.0
+-------------
+* New features:
+ * 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
+
+Version 1.5.0
+-------------
+* Exclude episodes from auto download by keyword
+* Configure feeds to prevent them from refreshing automatically
+* Improved audio player
+* Improved UI
+* Bug fixes
+
+Version 1.4.1
+-------------
+* Performance improvements
+* Hardware buttons now ff and rewind instead of skipping
+* Option to have forward button skip
+* Option to send crash reports directly to developers
+* Highlight currently playing episode
+* Widget improvements
+
+Version 1.4.0.12
+----------------
+* Fix for crash on Huawei devices (media buttons may not work)
+
+Version 1.4
+-----------
+* BLUETOOTH PERMISSION: Needed to be able to resume playback when a Bluetooth device reconnects with your phone
+* VIBRATE PERMISSION: Used optionally with the sleep timer
+* Native variable speed playback (experimental via options)
+* Improved sleep timer
+* Mark episodes as 'favorite'
+* Notification can skip episodes
+* Keep episodes when skipping them
+* Episode art on lock screen
+* Flexible episode cleanup
+* Rewind after pause
+* Usability improvements
+* Bug fixes
+
+Version 1.3
+-----------
+* Bulk actions on feed episodes (download, queue, delete)
+* Reduced space used by images
+* Automatic refresh at a certain time of day
+* Customizable indicators and sorting for feeds
+* Ability to share feeds
+* Improved auto download
+* Many fixes and usability improvements
+
+Version 1.2
+-----------
+* Optionally disable swiping and dragging in the queue
+* Resume playback after phone call
+* Filter episodes in the Podcast feed
+* Hide items in the Nav drawer
+* Customize times for fast forward and rewind
+* Resolved issues with opening some OPML files
+* Various bug fixes and usability improvements
+
+Version 1.1
+-----------
+* iTunes podcast integration
+* Swipe to remove items from the queue
+* Set the number of parallel downloads
+* Fix for gpodder.net on old devices
+* Fixed date problems for some feeds
+* Display improvements
+* Usability improvements
+* Several other bugfixes
+
+Version 1.0
+-----------
+* The queue can now be sorted
+* Added option to delete episode after playback
+* Fixed a bug that caused chapters to be displayed multiple times
+* Several other improvements and bugfixes
+
+
+Version 0.9.9.6
+---------------
+* Fixed problems related to variable playback speed plugins
+* Fixed automatic feed update problems
+* Several other bugfixes and improvements
+
+Version 0.9.9.5
+---------------
+* Added support for paged feeds
+* Improved user interface
+* Added Japanese and Turkish translations
+* Fixed more image loading problems
+* Other bugfixes and improvements
+
+Version 0.9.9.4
+---------------
+* Added option to keep notification and lockscreen controls when playback is paused
+* Fixed a bug where episode images were not loaded correctly
+* Fixed battery usage problems
+
+Version 0.9.9.3
+---------------
+* Fixed video playback problems
+* Improved image loading
+* Other bugfixes and improvements
+
+Version 0.9.9.2
+---------------
+* Added support for feed discovery if a website URL is entered
+* Added support for 'next'/'previous' media keys
+* Improved sleep timer
+* Timestamps in shownotes can now be used to jump to a specific position
+* Automatic Flattring is now configurable
+* Several bugfixes and improvements
+
+Version 0.9.9.1
+---------------
+* Several bugfixes and improvements
+
+Version 0.9.9.0
+---------------
+* New user interface
+* Failed downloads are now resumed when restarted
+* Added support for Podlove Alternate Feeds
+* Added support for "pcast"-protocol
+* Added backup & restore functionality. This feature has to be enabled in the Android settings in order to work
+* Several bugfixes and improvements
+
+Version 0.9.8.3
+---------------
+* Added support for password-protected feeds and episodes
+* Added support for more types of episode images
+* Added Hebrew translation
+* Several bugfixes and improvements
+
+Version 0.9.8.2
+---------------
+* Several bugfixes and improvements
+* Added Korean translation
+
+Version 0.9.8.1
+---------------
+* Added option to flattr an episode automatically after 80 percent of the episode have been played
+* Added Polish translation
+* Several bugfixes and improvements
+
+Version 0.9.8.0
+---------------
+* Added access to the gpodder.net directory
+* Added ability to sync podcast subscriptions with the gpodder.net service
+* Automatic download can now be turned on or off for specific podcasts
+* Added option to pause playback when another app is playing sounds
+* Added Dutch and Hindi translation
+* Resolved a problem with automatic podcast updates
+* Resolved a problem with the buttons' visibility in the episode screen
+* Resolved a problem where episodes would be re-downloaded unnecessarily
+* Several other bugfixes and usability improvements
+
+Version 0.9.7.5
+---------------
+* Reduced application startup time
+* Reduced memory usage
+* Added option to change the playback speed
+* Added Swedish translation
+* Several bugfixes and improvements
+
+Version 0.9.7.4
+---------------
+* Episode cache size can now be set to unlimited
+* Removing an episode in the queue via sliding can now be undone
+* Added support for Links in MP3 chapters
+* Added Czech(Czech Republic), Azerbaijani and Portuguese translations
+* Several bugfixes and improvements
+
+Version 0.9.7.3
+---------------
+* Bluetooth devices now display metadata during playback (requires AVRCP 1.3 or higher)
+* User interface improvements
+* Several bugfixes
+
+Version 0.9.7.2
+---------------
+* Automatic download can now be disabled
+* Added Italian (Italy) translation
+* Several bugfixes
+
+Version 0.9.7.1
+---------------
+* Added automatic download of new episodes
+* Added option to specify the number of downloaded episodes to keep on the device
+* Added support for playback of external media files
+* Several improvements and bugfixes
+* Added Catalan translation
+
+Version 0.9.7
+-------------
+* Improved user interface
+* OPML files can now be imported by selecting them in a file browser
+* The queue can now be organized via drag & drop
+* Added expandable notifications (only supported on Android 4.1 and above)
+* Added Danish, French, Romanian (Romania) and Ukrainian (Ukraine) translation (thanks to all translators!)
+* Several bugfixes and minor improvements
+
+Version 0.9.6.4
+---------------
+* Added Chinese translation (Thanks tupunco!)
+* Added Portuguese (Brazil) translation (Thanks mbaltar!)
+* Several bugfixes
+
+Version 0.9.6.3
+---------------
+* Added the ability change the location of AntennaPod's data folder
+* Added Spanish translation (Thanks frandavid100!)
+* Solved problems with several feeds
+
+Version 0.9.6.2
+---------------
+* Fixed import problems with some OPML files
+* Fixed download problems
+* AntennaPod now recognizes changes of episode information
+* Other improvements and bugfixes
+
+Version 0.9.6.1
+---------------
+* Added dark theme
+* Several bugfixes and improvements
+
+Version 0.9.6
+-------------
+* Added support for VorbisComment chapters
+* AntennaPod now shows items as 'in progress' when playback has started
+* Reduced memory usage
+* Added support for more feed types
+* Several bugfixes
+
+
+Version 0.9.5.3
+---------------
+* Fixed crash when trying to start playback on some devices
+* Fixed problems with some feeds
+* Other bugfixes and improvements
+
+Version 0.9.5.2
+---------------
+* Media player now doesn't use network bandwidth anymore if not in use
+* Other improvements and bugfixes
+
+Version 0.9.5.1
+---------------
+* Added playback history
+* Improved behavior of download report notifications
+* Improved support for headset controls
+* Bugfixes in the feed parser
+* Moved 'OPML import' button into the 'add feed' screen and the 'OPML export' button into the settings screen
+
+Version 0.9.5
+-------------
+* Experimental support for MP3 chapters
+* New menu options for the 'new' list and the queue
+* Auto-delete feature
+* Better Download error reports
+* Several Bugfixes
+
+Version 0.9.4.6
+---------------
+* Enabled support for small-screen devices
+* Disabling the sleep timer should now work again
+
+Version 0.9.4.5
+---------------
+* Added Russian translation (Thanks older!)
+* Added German translation
+* Several bugfixes
+
+Version 0.9.4.4
+---------------
+* Added player controls at the bottom of the main screen and the feedlist screens
+* Improved media playback
+
+Version 0.9.4.3
+---------------
+* Fixed several bugs in the feed parser
+* Improved behavior of download reports
+
+Version 0.9.4.2
+---------------
+* Fixed bug in the OPML importer
+* Reduced memory usage of images
+* Fixed download problems on some devices
+
+Version 0.9.4.1
+---------------
+* Changed behavior of download notifications
+
+Version 0.9.4
+-------------
+* Faster and more reliable downloads
+* Added lockscreen player controls for Android 4.x devices
+* Several bugfixes
+
+Version 0.9.3.1
+---------------
+* Added preference to hide feed items which don't have an episode
+* Improved image size for some some screen sizes
+* Added grid view for large screens
+* Several bugfixes
+
+Version 0.9.3
+-------------
+* MiroGuide integration
+* Bugfixes in the audio- and videoplayer
+* Automatically add feeds to the queue when they have been downloaded
+
+Version 0.9.2
+-------------
+* Bugfixes in the user interface
+* GUID and ID attributes are now recognized by the Feedparser
+* Stability improvements when adding several feeds at the same time
+* Fixed bugs that occured when adding certain feeds
+
+Version 0.9.1.1
+--------------------
+* Changed Flattr credentials
+* Improved layout of Feed information screen
+* AntennaPod is now open source! The source code is available at https://github.com/danieloeh/AntennaPod
+
+Version 0.9.1
+-----------------
+* Added support for links in SimpleChapters
+* Bugfix: Current Chapter wasn't always displayed correctly
+
+Version 0.9
+--------------
+
+* OPML export
+* Flattr integration
+* Sleep timer
+
+Version 0.8.2
+-------------
+
+* Added search
+* Improved OPML import experience
+* More bugfixes
+
+Version 0.8.1
+------------
+
+* Added support for SimpleChapters
+* OPML import
diff --git a/README.md b/README.md
index c106e7e1b..f7de41037 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@ AntennaPod has many users and we don't want them to run into trouble when we add
There are APKs available for every branch that is actively worked on. Please note that these might be very unstable versions of the app, which can break your current installation. Install them at your own risk!
-Click [here](https://www.dropbox.com/sh/4h2kfa2d2jesnu8/AABF7u5QsOn8Lg8MDie4Z4Ama?dl=0) to get to the nightly builds folder.
+Click [here](https://www.dropbox.com/sh/lzfd640z63qz3fr/AACyxTF1ygR9wMlPLPwVGIUKa?dl=0) to get to the nightly builds folder.
## License
diff --git a/app/build.gradle b/app/build.gradle
index a3b09ff6e..c7b95421b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -107,6 +107,10 @@ android {
play {
}
}
+
+ dexOptions {
+ jumboMode true
+ }
}
configurations {
@@ -139,8 +143,8 @@ dependencies {
compile "commons-io:commons-io:$commonsioVersion"
compile "org.jsoup:jsoup:$jsoupVersion"
compile "com.github.bumptech.glide:glide:$glideVersion"
- compile "com.squareup.okhttp:okhttp:$okhttpVersion"
- compile "com.squareup.okhttp:okhttp-urlconnection:$okhttpVersion"
+ compile "com.squareup.okhttp3:okhttp:$okhttpVersion"
+ compile "com.squareup.okhttp3:okhttp-urlconnection:$okhttpVersion"
compile "com.squareup.okio:okio:$okioVersion"
compile "de.greenrobot:eventbus:$eventbusVersion"
compile "io.reactivex:rxandroid:$rxAndroidVersion"
@@ -160,6 +164,8 @@ dependencies {
compile "com.github.shts:TriangleLabelView:$triangleLabelViewVersion"
compile "com.github.AntennaPod:AntennaPod-AudioPlayer:$audioPlayerVersion"
+
+ compile 'com.github.mfietz:fyydlin:v0.1'
}
play {
@@ -178,7 +184,8 @@ task filterAbout {
from "src/main/templates/about.html"
into "src/main/assets"
filter(ReplaceTokens, tokens: [versionname: android.defaultConfig.versionName,
- commit : "git rev-parse --short HEAD".execute().text])
+ commit : "git rev-parse --short HEAD".execute().text,
+ year : new Date().format('yyyy')])
}
}
diff --git a/app/proguard.cfg b/app/proguard.cfg
index a25664490..815a89452 100644
--- a/app/proguard.cfg
+++ b/app/proguard.cfg
@@ -53,7 +53,7 @@
public *;
}
--dontwarn com.squareup.okhttp.**
+-dontwarn okhttp3.**
-dontwarn okio.**
# for RxJava:
@@ -107,4 +107,19 @@
-dontwarn com.viewpagerindicator.LinePageIndicator
# for some reason ProGuard removes this file. Why? Unsure.
--keep class de.danoeh.antennapod.core.cast.SwitchableMediaRouteActionProvider { *; } \ No newline at end of file
+-keep class de.danoeh.antennapod.core.cast.SwitchableMediaRouteActionProvider { *; }
+
+# Retrofit 2.0
+-dontwarn retrofit2.**
+-keep class retrofit2.** { *; }
+-keepattributes Signature
+-keepattributes Exceptions
+
+-keepclasseswithmembers class * {
+ @retrofit2.http.* <methods>;
+}
+
+# Moshi
+-keep class com.squareup.moshi.** { *; }
+-keep interface com.squareup.moshi.** { *; }
+-keep public class retrofit2.adapter.rxjava.RxJavaCallAdapterFactory { *; }
diff --git a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java
index 30ab365bf..9ac92c2f9 100644
--- a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java
@@ -789,7 +789,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
}
@Override
- public void onPostPlayback(@NonNull Playable media, boolean ended, boolean playingNext) {
+ public void onPostPlayback(@NonNull Playable media, boolean ended, boolean skipped, boolean playingNext) {
}
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java b/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java
index 78b807710..d02efa521 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java
@@ -44,7 +44,7 @@ public class DBTestUtils {
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
for (int i = 0; i < numFeeds; i++) {
- Feed f = new Feed(0, null, "feed " + i, "link" + i, "descr", null, null,
+ Feed f = new Feed(0, null, "feed " + i, null, "link" + i, "descr", null, null,
null, null, "id" + i, null, null, "url" + i, false, new FlattrStatus(), false, null, null, false);
f.setItems(new ArrayList<>());
for (int j = 0; j < numItems; j++) {
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 14a38e017..2049b6bae 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.danoeh.antennapod"
- android:versionCode="1060102"
- android:versionName="1.6.1.2">
+ android:versionCode="1060203"
+ android:versionName="1.6.2.3">
<!--
Version code schema:
"1.2.3-SNAPSHOT" -> 1020300
@@ -37,23 +37,28 @@
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"/>
<activity
- android:name=".activity.MainActivity"
+ android:name=".activity.SplashActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:launchMode="singleTask"
- android:label="@string/app_name">
+ android:label="@string/app_name"
+ android:theme="@style/Theme.AntennaPod.Dark.Splash">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
+ android:name=".activity.MainActivity"
+ android:configChanges="keyboardHidden|orientation|screenSize"
+ android:launchMode="singleTask"
+ android:label="@string/app_name">
+ </activity>
+ <activity
android:name=".activity.AudioplayerActivity"
android:launchMode="singleTop">
<meta-data
@@ -344,10 +349,6 @@
<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/activity/FeedInfoActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java
index cfd633fae..19aabfc88 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java
@@ -8,6 +8,7 @@ import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
+import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Menu;
@@ -27,6 +28,10 @@ import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.joanzapata.iconify.Iconify;
+import org.apache.commons.lang3.StringUtils;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
@@ -40,6 +45,7 @@ import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.DownloadRequestException;
import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.core.util.LangUtils;
+import de.danoeh.antennapod.core.util.syndication.HtmlToPlainText;
import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
import rx.Observable;
import rx.Subscription;
@@ -50,17 +56,18 @@ import rx.schedulers.Schedulers;
* Displays information about a feed.
*/
public class FeedInfoActivity extends AppCompatActivity {
- private static final String TAG = "FeedInfoActivity";
- private boolean autoDeleteChanged = false;
public static final String EXTRA_FEED_ID = "de.danoeh.antennapod.extra.feedId";
-
+ private static final String TAG = "FeedInfoActivity";
+ private boolean autoDeleteChanged = false;
private Feed feed;
private ImageView imgvCover;
private TextView txtvTitle;
private TextView txtvDescription;
+ private TextView lblLanguage;
private TextView txtvLanguage;
+ private TextView lblAuthor;
private TextView txtvAuthor;
private TextView txtvUrl;
private EditText etxtUsername;
@@ -75,6 +82,7 @@ public class FeedInfoActivity extends AppCompatActivity {
private Subscription subscription;
+
private final View.OnClickListener copyUrlToClipboard = new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -96,6 +104,40 @@ public class FeedInfoActivity extends AppCompatActivity {
}
};
+ private boolean authInfoChanged = false;
+
+ private TextWatcher authTextWatcher = new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ authInfoChanged = true;
+ }
+ };
+
+ private boolean filterTextChanged = false;
+
+ private TextWatcher filterTextWatcher = new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ filterTextChanged = true;
+ }
+ };
+
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(UserPreferences.getTheme());
@@ -107,7 +149,9 @@ public class FeedInfoActivity extends AppCompatActivity {
imgvCover = (ImageView) findViewById(R.id.imgvCover);
txtvTitle = (TextView) findViewById(R.id.txtvTitle);
txtvDescription = (TextView) findViewById(R.id.txtvDescription);
+ lblLanguage = (TextView) findViewById(R.id.lblLanguage);
txtvLanguage = (TextView) findViewById(R.id.txtvLanguage);
+ lblAuthor = (TextView) findViewById(R.id.lblAuthor);
txtvAuthor = (TextView) findViewById(R.id.txtvAuthor);
txtvUrl = (TextView) findViewById(R.id.txtvUrl);
cbxAutoDownload = (CheckBox) findViewById(R.id.cbxAutoDownload);
@@ -152,14 +196,30 @@ public class FeedInfoActivity extends AppCompatActivity {
.into(imgvCover);
txtvTitle.setText(feed.getTitle());
+
String description = feed.getDescription();
- txtvDescription.setText((description != null) ? description.trim() : "");
- if (feed.getAuthor() != null) {
+ if(description != null) {
+ if(Feed.TYPE_ATOM1.equals(feed.getType())) {
+ HtmlToPlainText formatter = new HtmlToPlainText();
+ Document feedDescription = Jsoup.parse(feed.getDescription());
+ description = StringUtils.trim(formatter.getPlainText(feedDescription));
+ }
+ } else {
+ description = "";
+ }
+ txtvDescription.setText(description);
+
+ if (!TextUtils.isEmpty(feed.getAuthor())) {
txtvAuthor.setText(feed.getAuthor());
+ } else {
+ lblAuthor.setVisibility(View.GONE);
+ txtvAuthor.setVisibility(View.GONE);
}
- if (feed.getLanguage() != null) {
- txtvLanguage.setText(LangUtils
- .getLanguageString(feed.getLanguage()));
+ if (!TextUtils.isEmpty(feed.getLanguage())) {
+ txtvLanguage.setText(LangUtils.getLanguageString(feed.getLanguage()));
+ } else {
+ lblLanguage.setVisibility(View.GONE);
+ txtvLanguage.setVisibility(View.GONE);
}
txtvUrl.setText(feed.getDownload_url() + " {fa-paperclip}");
Iconify.addIcons(txtvUrl);
@@ -241,53 +301,6 @@ public class FeedInfoActivity extends AppCompatActivity {
}
@Override
- public void onDestroy() {
- super.onDestroy();
- if(subscription != null) {
- subscription.unsubscribe();
- }
- }
-
-
- private boolean authInfoChanged = false;
-
- private TextWatcher authTextWatcher = new TextWatcher() {
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
-
- }
-
- @Override
- public void afterTextChanged(Editable s) {
- authInfoChanged = true;
- }
- };
-
- private boolean filterTextChanged = false;
-
- private TextWatcher filterTextWatcher = new TextWatcher() {
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
-
- }
-
- @Override
- public void afterTextChanged(Editable s) {
- filterTextChanged = true;
- }
- };
-
- @Override
protected void onPause() {
super.onPause();
if (feed != null) {
@@ -319,6 +332,14 @@ public class FeedInfoActivity extends AppCompatActivity {
}
@Override
+ public void onDestroy() {
+ super.onDestroy();
+ if(subscription != null) {
+ subscription.unsubscribe();
+ }
+ }
+
+ @Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuInflater inflater = getMenuInflater();
@@ -369,7 +390,7 @@ public class FeedInfoActivity extends AppCompatActivity {
private final Feed feed;
private final boolean autoDownload;
- public ApplyToEpisodesDialog(Context context, Feed feed, boolean autoDownload) {
+ ApplyToEpisodesDialog(Context context, Feed feed, boolean autoDownload) {
super(context, R.string.auto_download_apply_to_items_title,
R.string.auto_download_apply_to_items_message);
this.feed = feed;
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 97732786e..41ed963c2 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
@@ -10,6 +10,7 @@ import android.database.DataSetObserver;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
+import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
@@ -38,6 +39,7 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.adapter.NavListAdapter;
import de.danoeh.antennapod.core.asynctask.FeedRemover;
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
+import de.danoeh.antennapod.core.event.MessageEvent;
import de.danoeh.antennapod.core.event.ProgressEvent;
import de.danoeh.antennapod.core.event.QueueEvent;
import de.danoeh.antennapod.core.feed.EventDistributor;
@@ -46,11 +48,13 @@ import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
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.util.FeedItemUtil;
import de.danoeh.antennapod.core.util.Flavors;
import de.danoeh.antennapod.core.util.StorageUtils;
import de.danoeh.antennapod.dialog.RatingDialog;
+import de.danoeh.antennapod.dialog.RenameFeedDialog;
import de.danoeh.antennapod.fragment.AddFeedFragment;
import de.danoeh.antennapod.fragment.DownloadsFragment;
import de.danoeh.antennapod.fragment.EpisodesFragment;
@@ -463,6 +467,7 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
protected void onResume() {
super.onResume();
StorageUtils.checkStorageAvailability(this);
+ DBTasks.checkShouldRefreshFeeds(getApplicationContext());
Intent intent = getIntent();
if (intent.hasExtra(EXTRA_FEED_ID) ||
@@ -573,6 +578,9 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
case R.id.mark_all_read_item:
DBWriter.markFeedRead(feed.getId());
return true;
+ case R.id.rename_item:
+ new RenameFeedDialog(this, feed).show();
+ return true;
case R.id.remove_item:
final FeedRemover remover = new FeedRemover(this, feed) {
@Override
@@ -731,6 +739,18 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
}
}
+ public void onEventMainThread(MessageEvent event) {
+ Log.d(TAG, "onEvent(" + event + ")");
+ View parentLayout = findViewById(R.id.drawer_layout);
+ Snackbar snackbar = Snackbar.make(parentLayout, event.message, Snackbar.LENGTH_SHORT);
+ if(event.action != null) {
+ snackbar.setAction(getString(R.string.undo), v -> {
+ event.action.run();
+ });
+ }
+ snackbar.show();
+ }
+
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
@Override
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 2880b26e8..9d2f35e3d 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java
@@ -8,6 +8,7 @@ import android.content.res.Configuration;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.design.widget.AppBarLayout;
+import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
@@ -36,6 +37,7 @@ import de.danoeh.antennapod.adapter.ChaptersListAdapter;
import de.danoeh.antennapod.adapter.NavListAdapter;
import de.danoeh.antennapod.core.asynctask.FeedRemover;
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
+import de.danoeh.antennapod.core.event.MessageEvent;
import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedMedia;
@@ -43,9 +45,11 @@ import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.service.playback.PlayerStatus;
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.util.playback.Playable;
import de.danoeh.antennapod.core.util.playback.PlaybackController;
+import de.danoeh.antennapod.dialog.RenameFeedDialog;
import de.danoeh.antennapod.fragment.AddFeedFragment;
import de.danoeh.antennapod.fragment.ChaptersFragment;
import de.danoeh.antennapod.fragment.CoverFragment;
@@ -57,6 +61,7 @@ import de.danoeh.antennapod.fragment.QueueFragment;
import de.danoeh.antennapod.fragment.SubscriptionFragment;
import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
import de.danoeh.antennapod.preferences.PreferenceController;
+import de.greenrobot.event.EventBus;
import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
@@ -102,6 +107,12 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem
private Subscription subscription;
@Override
+ protected void onPause() {
+ super.onPause();
+ EventBus.getDefault().unregister(this);
+ }
+
+ @Override
protected void onStop() {
super.onStop();
Log.d(TAG, "onStop()");
@@ -168,8 +179,10 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem
pagerAdapter.onMediaChanged(media);
pagerAdapter.setController(controller);
}
+ DBTasks.checkShouldRefreshFeeds(getApplicationContext());
EventDistributor.getInstance().register(contentUpdate);
+ EventBus.getDefault().register(this);
loadData();
}
@@ -370,6 +383,9 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem
case R.id.mark_all_read_item:
DBWriter.markFeedRead(feed.getId());
return true;
+ case R.id.rename_item:
+ new RenameFeedDialog(this, feed).show();
+ return true;
case R.id.remove_item:
final FeedRemover remover = new FeedRemover(this, feed) {
@Override
@@ -462,7 +478,17 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem
}, error -> Log.e(TAG, Log.getStackTraceString(error)));
}
-
+ public void onEventMainThread(MessageEvent event) {
+ Log.d(TAG, "onEvent(" + event + ")");
+ View parentLayout = findViewById(R.id.drawer_layout);
+ Snackbar snackbar = Snackbar.make(parentLayout, event.message, Snackbar.LENGTH_SHORT);
+ if (event.action != null) {
+ snackbar.setAction(getString(R.string.undo), v -> {
+ event.action.run();
+ });
+ }
+ snackbar.show();
+ }
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
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 a40877832..a4e661f62 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
@@ -29,7 +29,6 @@ import com.bumptech.glide.Glide;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
-import org.jsoup.examples.HtmlToPlainText;
import org.jsoup.nodes.Document;
import java.io.File;
@@ -63,6 +62,7 @@ import de.danoeh.antennapod.core.util.FileNameGenerator;
import de.danoeh.antennapod.core.util.StorageUtils;
import de.danoeh.antennapod.core.util.URLChecker;
import de.danoeh.antennapod.core.util.syndication.FeedDiscoverer;
+import de.danoeh.antennapod.core.util.syndication.HtmlToPlainText;
import de.danoeh.antennapod.dialog.AuthenticationDialog;
import de.greenrobot.event.EventBus;
import rx.Observable;
@@ -81,17 +81,12 @@ import rx.schedulers.Schedulers;
*/
public class OnlineFeedViewActivity extends AppCompatActivity {
- private static final String TAG = "OnlineFeedViewActivity";
-
public static final String ARG_FEEDURL = "arg.feedurl";
-
// Optional argument: specify a title for the actionbar.
public static final String ARG_TITLE = "title";
-
- private static final int EVENTS = EventDistributor.FEED_LIST_UPDATE;
-
public static final int RESULT_ERROR = 2;
-
+ private static final String TAG = "OnlineFeedViewActivity";
+ private static final int EVENTS = EventDistributor.FEED_LIST_UPDATE;
private volatile List<Feed> feeds;
private Feed feed;
private String selectedDownloadUrl;
@@ -106,17 +101,11 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
private Subscription download;
private Subscription parser;
private Subscription updater;
-
- public void onEventMainThread(DownloadEvent event) {
- Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
- setSubscribeButtonState(feed);
- }
-
private EventDistributor.EventListener listener = new EventDistributor.EventListener() {
@Override
public void update(EventDistributor eventDistributor, Integer arg) {
if ((arg & EventDistributor.FEED_LIST_UPDATE) != 0) {
- updater = Observable.fromCallable(() -> DBReader.getFeedList())
+ updater = Observable.fromCallable(DBReader::getFeedList)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
@@ -133,6 +122,11 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
}
};
+ public void onEventMainThread(DownloadEvent event) {
+ Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
+ setSubscribeButtonState(feed);
+ }
+
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(UserPreferences.getTheme());
@@ -284,7 +278,7 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
})
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
- .subscribe(status -> checkDownloadResult(status),
+ .subscribe(this::checkDownloadResult,
error -> Log.e(TAG, Log.getStackTraceString(error)));
}
@@ -360,14 +354,19 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
* This method is executed on a background thread
*/
private void beforeShowFeedInformation(Feed feed) {
- // remove HTML tags from descriptions
+ final HtmlToPlainText formatter = new HtmlToPlainText();
+ if(Feed.TYPE_ATOM1.equals(feed.getType()) && feed.getDescription() != null) {
+ // remove HTML tags from descriptions
+ Log.d(TAG, "Removing HTML from feed description");
+ Document feedDescription = Jsoup.parse(feed.getDescription());
+ feed.setDescription(StringUtils.trim(formatter.getPlainText(feedDescription)));
+ }
Log.d(TAG, "Removing HTML from shownotes");
if (feed.getItems() != null) {
- HtmlToPlainText formatter = new HtmlToPlainText();
for (FeedItem item : feed.getItems()) {
if (item.getDescription() != null) {
- Document description = Jsoup.parse(item.getDescription());
- item.setDescription(StringUtils.trim(formatter.getPlainText(description)));
+ Document itemDescription = Jsoup.parse(item.getDescription());
+ item.setDescription(StringUtils.trim(formatter.getPlainText(itemDescription)));
}
}
}
@@ -589,7 +588,7 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
private String feedUrl;
- public FeedViewAuthenticationDialog(Context context, int titleRes, String feedUrl) {
+ FeedViewAuthenticationDialog(Context context, int titleRes, String feedUrl) {
super(context, titleRes, true, false, null, null);
this.feedUrl = feedUrl;
}
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OpmlFeedChooserActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/OpmlFeedChooserActivity.java
index bc1a40b11..355e0f372 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OpmlFeedChooserActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OpmlFeedChooserActivity.java
@@ -15,7 +15,7 @@ import java.util.ArrayList;
import java.util.List;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.opml.OpmlElement;
+import de.danoeh.antennapod.core.export.opml.OpmlElement;
import de.danoeh.antennapod.core.preferences.UserPreferences;
/**
@@ -23,10 +23,8 @@ import de.danoeh.antennapod.core.preferences.UserPreferences;
* which feeds he wants to import.
*/
public class OpmlFeedChooserActivity extends AppCompatActivity {
- private static final String TAG = "OpmlFeedChooserActivity";
-
public static final String EXTRA_SELECTED_ITEMS = "de.danoeh.antennapod.selectedItems";
-
+ private static final String TAG = "OpmlFeedChooserActivity";
private Button butConfirm;
private Button butCancel;
private ListView feedlist;
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportBaseActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportBaseActivity.java
index 8726af281..07b0b3cdb 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportBaseActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportBaseActivity.java
@@ -3,6 +3,7 @@ package de.danoeh.antennapod.activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
+import android.os.Build;
import android.os.Environment;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
@@ -20,7 +21,7 @@ import java.util.ArrayList;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.asynctask.OpmlFeedQueuer;
import de.danoeh.antennapod.asynctask.OpmlImportWorker;
-import de.danoeh.antennapod.core.opml.OpmlElement;
+import de.danoeh.antennapod.core.export.opml.OpmlElement;
import de.danoeh.antennapod.core.util.LangUtils;
/**
@@ -29,9 +30,8 @@ import de.danoeh.antennapod.core.util.LangUtils;
public class OpmlImportBaseActivity extends AppCompatActivity {
private static final String TAG = "OpmlImportBaseActivity";
- private OpmlImportWorker importWorker;
-
private static final int PERMISSION_REQUEST_READ_EXTERNAL_STORAGE = 5;
+ private OpmlImportWorker importWorker;
@Nullable private Uri uri;
/**
@@ -77,7 +77,8 @@ public class OpmlImportBaseActivity extends AppCompatActivity {
return;
}
this.uri = uri;
- if(uri.toString().contains(Environment.getExternalStorageDirectory().toString())) {
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
+ uri.toString().contains(Environment.getExternalStorageDirectory().toString())) {
int permission = ActivityCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
requestPermission();
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportHolder.java b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportHolder.java
index 7afa270cc..b01cf43e4 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportHolder.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportHolder.java
@@ -1,9 +1,9 @@
package de.danoeh.antennapod.activity;
-import de.danoeh.antennapod.core.opml.OpmlElement;
-
import java.util.ArrayList;
+import de.danoeh.antennapod.core.export.opml.OpmlElement;
+
/**
* Hold infos gathered by Ompl-Import
* <p/>
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java
index 61765d6b7..dd932814f 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java
@@ -26,11 +26,9 @@ import de.danoeh.antennapod.preferences.PreferenceController;
*/
public class PreferenceActivity extends AppCompatActivity {
+ private static WeakReference<PreferenceActivity> instance;
private PreferenceController preferenceController;
private MainFragment prefFragment;
- private static WeakReference<PreferenceActivity> instance;
-
-
private final PreferenceController.PreferenceUI preferenceUI = new PreferenceController.PreferenceUI() {
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
@@ -128,5 +126,14 @@ public class PreferenceActivity extends AppCompatActivity {
}
super.onPause();
}
+
+ @Override
+ public void onStop() {
+ PreferenceActivity activity = instance.get();
+ if(activity != null && activity.preferenceController != null) {
+ activity.preferenceController.onStop();
+ }
+ super.onStop();
+ }
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivityGingerbread.java b/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivityGingerbread.java
index 4af988ea0..390bec15c 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivityGingerbread.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivityGingerbread.java
@@ -18,9 +18,6 @@ import de.danoeh.antennapod.preferences.PreferenceController;
*/
public class PreferenceActivityGingerbread extends android.preference.PreferenceActivity {
private static final String TAG = "PreferenceActivity";
-
- private PreferenceController preferenceController;
-
private final PreferenceController.PreferenceUI preferenceUI = new PreferenceController.PreferenceUI() {
@SuppressWarnings("deprecation")
@@ -34,6 +31,7 @@ public class PreferenceActivityGingerbread extends android.preference.Preference
return PreferenceActivityGingerbread.this;
}
};
+ private PreferenceController preferenceController;
@SuppressLint("NewApi")
@SuppressWarnings("deprecation")
@@ -61,6 +59,12 @@ public class PreferenceActivityGingerbread extends android.preference.Preference
}
@Override
+ protected void onStop() {
+ preferenceController.onStop();
+ super.onStop();
+ }
+
+ @Override
protected void onApplyThemeResource(Theme theme, int resid, boolean first) {
theme.applyStyle(UserPreferences.getTheme(), true);
}
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/SplashActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/SplashActivity.java
new file mode 100644
index 000000000..b92ac8577
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/activity/SplashActivity.java
@@ -0,0 +1,23 @@
+package de.danoeh.antennapod.activity;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v7.app.AppCompatActivity;
+
+/**
+ * Creator: vbarad
+ * Date: 2016-12-03
+ * Project: AntennaPod
+ */
+
+public class SplashActivity extends AppCompatActivity {
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Intent intent = new Intent(this, MainActivity.class);
+ startActivity(intent);
+ finish();
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java b/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java
index 1a8f0a67a..f0210f983 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java
@@ -47,6 +47,7 @@ public class ActionButtonUtils {
* Sets the displayed bitmap and content description of the given
* action button so that it matches the state of the FeedItem.
*/
+ @SuppressWarnings("ResourceType")
public void configureActionButton(ImageButton butSecondary, FeedItem item, boolean isInQueue) {
Validate.isTrue(butSecondary != null && item != null, "butSecondary or item was null");
@@ -57,8 +58,7 @@ public class ActionButtonUtils {
if (isDownloadingMedia) {
// item is being downloaded
butSecondary.setVisibility(View.VISIBLE);
- butSecondary.setImageDrawable(drawables
- .getDrawable(1));
+ butSecondary.setImageDrawable(drawables.getDrawable(1));
butSecondary.setContentDescription(context.getString(labels[1]));
} else {
// item is not downloaded and not being downloaded
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/AdapterUtils.java b/app/src/main/java/de/danoeh/antennapod/adapter/AdapterUtils.java
index 8aaf0055a..5c58d00f2 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/AdapterUtils.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/AdapterUtils.java
@@ -15,7 +15,7 @@ import de.danoeh.antennapod.core.util.NetworkUtils;
/**
* Utility methods for adapters
*/
-public class AdapterUtils {
+class AdapterUtils {
private static final String TAG = AdapterUtils.class.getSimpleName();
@@ -26,7 +26,7 @@ public class AdapterUtils {
/**
* Updates the contents of the TextView that shows the current playback position and the ProgressBar.
*/
- public static void updateEpisodePlaybackProgress(FeedItem item, TextView txtvPos, ProgressBar episodeProgress) {
+ static void updateEpisodePlaybackProgress(FeedItem item, TextView txtvPos, ProgressBar episodeProgress) {
FeedMedia media = item.getMedia();
episodeProgress.setVisibility(View.GONE);
if (media == null) {
@@ -47,7 +47,6 @@ public class AdapterUtils {
- media.getPosition()));
}
} else if (!media.isDownloaded()) {
- Log.d(TAG, "size: " + media.getSize());
if (media.getSize() > 0) {
txtvPos.setText(Converter.byteToString(media.getSize()));
} else if(NetworkUtils.isDownloadAllowed() && !media.checkedOnSizeButUnknown()) {
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java
index 07847d0d1..35c42725c 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java
@@ -87,6 +87,7 @@ public class FeedItemlistAdapter extends BaseAdapter {
}
@Override
+ @SuppressWarnings("ResourceType")
public View getView(final int position, View convertView, ViewGroup parent) {
Holder holder;
final FeedItem item = getItem(position);
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 e9756b467..e381b4651 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
@@ -1,6 +1,7 @@
package de.danoeh.antennapod.adapter.itunes;
import android.content.Context;
+import android.support.annotation.NonNull;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
@@ -18,6 +19,7 @@ import java.util.List;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
+import de.mfietz.fyydlin.SearchHit;
public class ItunesAdapter extends ArrayAdapter<ItunesAdapter.Podcast> {
/**
@@ -42,8 +44,9 @@ public class ItunesAdapter extends ArrayAdapter<ItunesAdapter.Podcast> {
this.context = context;
}
+ @NonNull
@Override
- public View getView(int position, View convertView, ViewGroup parent) {
+ public View getView(int position, View convertView, @NonNull ViewGroup parent) {
//Current podcast
Podcast podcast = data.get(position);
@@ -87,35 +90,6 @@ public class ItunesAdapter extends ArrayAdapter<ItunesAdapter.Podcast> {
}
/**
- * View holder object for the GridView
- */
- class PodcastViewHolder {
-
- /**
- * ImageView holding the Podcast image
- */
- public final ImageView coverView;
-
- /**
- * TextView holding the Podcast title
- */
- public final TextView titleView;
-
- public final TextView urlView;
-
-
- /**
- * Constructor
- * @param view GridView cell
- */
- PodcastViewHolder(View view){
- coverView = (ImageView) view.findViewById(R.id.imgvCover);
- titleView = (TextView) view.findViewById(R.id.txtvTitle);
- urlView = (TextView) view.findViewById(R.id.txtvUrl);
- }
- }
-
- /**
* Represents an individual podcast on the iTunes Store.
*/
public static class Podcast { //TODO: Move this out eventually. Possibly to core.itunes.model
@@ -154,6 +128,10 @@ public class ItunesAdapter extends ArrayAdapter<ItunesAdapter.Podcast> {
return new Podcast(title, imageUrl, feedUrl);
}
+ public static Podcast fromSearch(SearchHit searchHit) {
+ return new Podcast(searchHit.getTitle(), searchHit.getImageUrl(), searchHit.getXmlUrl());
+ }
+
/**
* Constructs a Podcast instance from iTunes toplist entry
*
@@ -177,4 +155,33 @@ public class ItunesAdapter extends ArrayAdapter<ItunesAdapter.Podcast> {
}
}
+
+ /**
+ * View holder object for the GridView
+ */
+ class PodcastViewHolder {
+
+ /**
+ * ImageView holding the Podcast image
+ */
+ final ImageView coverView;
+
+ /**
+ * TextView holding the Podcast title
+ */
+ final TextView titleView;
+
+ final TextView urlView;
+
+
+ /**
+ * Constructor
+ * @param view GridView cell
+ */
+ PodcastViewHolder(View view){
+ coverView = (ImageView) view.findViewById(R.id.imgvCover);
+ titleView = (TextView) view.findViewById(R.id.txtvTitle);
+ urlView = (TextView) view.findViewById(R.id.txtvUrl);
+ }
+ }
}
diff --git a/app/src/main/java/de/danoeh/antennapod/asynctask/ExportWorker.java b/app/src/main/java/de/danoeh/antennapod/asynctask/ExportWorker.java
new file mode 100644
index 000000000..192df8ca5
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/asynctask/ExportWorker.java
@@ -0,0 +1,65 @@
+package de.danoeh.antennapod.asynctask;
+
+import android.support.annotation.NonNull;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+
+import de.danoeh.antennapod.core.export.ExportWriter;
+import de.danoeh.antennapod.core.preferences.UserPreferences;
+import de.danoeh.antennapod.core.storage.DBReader;
+import de.danoeh.antennapod.core.util.LangUtils;
+import rx.Observable;
+
+/**
+ * Writes an OPML file into the export directory in the background.
+ */
+public class ExportWorker {
+
+ private static final String EXPORT_DIR = "export/";
+ private static final String TAG = "ExportWorker";
+ private static final String DEFAULT_OUTPUT_NAME = "antennapod-feeds";
+
+ private ExportWriter exportWriter;
+ private File output;
+
+ public ExportWorker(ExportWriter exportWriter) {
+ this(exportWriter, new File(UserPreferences.getDataFolder(EXPORT_DIR),
+ DEFAULT_OUTPUT_NAME + "." + exportWriter.fileExtension()));
+ }
+
+ public ExportWorker(ExportWriter exportWriter, @NonNull File output) {
+ this.exportWriter = exportWriter;
+ this.output = output;
+ }
+
+ public Observable<File> exportObservable() {
+ if (output.exists()) {
+ Log.w(TAG, "Overwriting previously exported file.");
+ output.delete();
+ }
+ return Observable.create(subscriber -> {
+ OutputStreamWriter writer = null;
+ try {
+ writer = new OutputStreamWriter(new FileOutputStream(output), LangUtils.UTF_8);
+ exportWriter.writeDocument(DBReader.getFeedList(), writer);
+ subscriber.onNext(output);
+ } catch (IOException e) {
+ subscriber.onError(e);
+ } finally {
+ if (writer != null) {
+ try {
+ writer.close();
+ } catch (IOException e) {
+ subscriber.onError(e);
+ }
+ }
+ subscriber.onCompleted();
+ }
+ });
+ }
+
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlExportWorker.java b/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlExportWorker.java
deleted file mode 100644
index 13abb26ea..000000000
--- a/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlExportWorker.java
+++ /dev/null
@@ -1,122 +0,0 @@
-package de.danoeh.antennapod.asynctask;
-
-import android.annotation.SuppressLint;
-import android.app.ProgressDialog;
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.support.v7.app.AlertDialog;
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-
-import de.danoeh.antennapod.core.R;
-import de.danoeh.antennapod.core.opml.OpmlWriter;
-import de.danoeh.antennapod.core.preferences.UserPreferences;
-import de.danoeh.antennapod.core.storage.DBReader;
-import de.danoeh.antennapod.core.util.LangUtils;
-
-/**
- * Writes an OPML file into the export directory in the background.
- */
-public class OpmlExportWorker extends AsyncTask<Void, Void, Void> {
- private static final String TAG = "OpmlExportWorker";
- private static final String DEFAULT_OUTPUT_NAME = "antennapod-feeds.opml";
- public static final String EXPORT_DIR = "export/";
-
- private Context context;
- private File output;
-
- private ProgressDialog progDialog;
- private Exception exception;
-
- public OpmlExportWorker(Context context, File output) {
- this.context = context;
- this.output = output;
- }
-
- public OpmlExportWorker(Context context) {
- this.context = context;
- }
-
- @Override
- protected Void doInBackground(Void... params) {
- OpmlWriter opmlWriter = new OpmlWriter();
- if (output == null) {
- output = new File(
- UserPreferences.getDataFolder(EXPORT_DIR),
- DEFAULT_OUTPUT_NAME);
- if (output.exists()) {
- Log.w(TAG, "Overwriting previously exported file.");
- output.delete();
- }
- }
- OutputStreamWriter writer = null;
- try {
- writer = new OutputStreamWriter(new FileOutputStream(output), LangUtils.UTF_8);
- opmlWriter.writeDocument(DBReader.getFeedList(), writer);
- } catch (IOException e) {
- e.printStackTrace();
- exception = e;
- } finally {
- if (writer != null) {
- try {
- writer.close();
- } catch (IOException ioe) {
- exception = ioe;
- }
- }
- }
- return null;
- }
-
- @Override
- protected void onPostExecute(Void result) {
- progDialog.dismiss();
- AlertDialog.Builder alert = new AlertDialog.Builder(context)
- .setNeutralButton(android.R.string.ok,
- (dialog, which) -> dialog.dismiss());
- if (exception != null) {
- alert.setTitle(R.string.export_error_label);
- alert.setMessage(exception.getMessage());
- } else {
- alert.setTitle(R.string.opml_export_success_title);
- alert.setMessage(context
- .getString(R.string.opml_export_success_sum)
- + output.toString())
- .setPositiveButton(R.string.send_label, (dialog, which) -> {
- Uri outputUri = Uri.fromFile(output);
- Intent sendIntent = new Intent(Intent.ACTION_SEND);
- sendIntent.putExtra(Intent.EXTRA_SUBJECT,
- context.getResources().getText(R.string.opml_export_label));
- sendIntent.putExtra(Intent.EXTRA_STREAM, outputUri);
- sendIntent.setType("text/plain");
- context.startActivity(Intent.createChooser(sendIntent,
- context.getResources().getText(R.string.send_label)));
- });
- }
- alert.create().show();
- }
-
- @Override
- protected void onPreExecute() {
- progDialog = new ProgressDialog(context);
- progDialog.setMessage(context.getString(R.string.exporting_label));
- progDialog.setIndeterminate(true);
- progDialog.show();
- }
-
- @SuppressLint("NewApi")
- public void executeAsync() {
- if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
- executeOnExecutor(THREAD_POOL_EXECUTOR);
- } else {
- execute();
- }
- }
-
-}
diff --git a/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlFeedQueuer.java b/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlFeedQueuer.java
index 1cb653f01..4449d82c2 100644
--- a/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlFeedQueuer.java
+++ b/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlFeedQueuer.java
@@ -9,8 +9,8 @@ import java.util.Arrays;
import de.danoeh.antennapod.activity.OpmlImportHolder;
import de.danoeh.antennapod.core.R;
+import de.danoeh.antennapod.core.export.opml.OpmlElement;
import de.danoeh.antennapod.core.feed.Feed;
-import de.danoeh.antennapod.core.opml.OpmlElement;
import de.danoeh.antennapod.core.storage.DownloadRequestException;
import de.danoeh.antennapod.core.storage.DownloadRequester;
diff --git a/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlImportWorker.java b/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlImportWorker.java
index f3b3aeca9..62ea85811 100644
--- a/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlImportWorker.java
+++ b/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlImportWorker.java
@@ -14,8 +14,8 @@ import java.io.Reader;
import java.util.ArrayList;
import de.danoeh.antennapod.core.R;
-import de.danoeh.antennapod.core.opml.OpmlElement;
-import de.danoeh.antennapod.core.opml.OpmlReader;
+import de.danoeh.antennapod.core.export.opml.OpmlElement;
+import de.danoeh.antennapod.core.export.opml.OpmlReader;
public class OpmlImportWorker extends
AsyncTask<Void, Void, ArrayList<OpmlElement>> {
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
index 577a3ecbe..ac073141d 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
@@ -225,6 +225,10 @@ public class EpisodesApplyActionFragment extends Fragment {
checkQueued(false);
resId = R.string.selected_not_queued_label;
break;
+ case R.id.check_has_media:
+ checkWithMedia();
+ resId = R.string.selected_has_media_label;
+ break;
case R.id.sort_title_a_z:
sortByTitle(false);
return true;
@@ -357,6 +361,17 @@ public class EpisodesApplyActionFragment extends Fragment {
refreshCheckboxes();
}
+ private void checkWithMedia() {
+ for (FeedItem episode : episodes) {
+ if(episode.hasMedia()) {
+ checkedIds.add(episode.getId());
+ } else {
+ checkedIds.remove(episode.getId());
+ }
+ }
+ refreshCheckboxes();
+ }
+
private void refreshTitles() {
titles.clear();
for(FeedItem episode : episodes) {
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java
index 98a4b5356..0bd75b5b0 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java
@@ -18,10 +18,6 @@ import android.widget.TextView;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.afollestad.materialdialogs.internal.MDButton;
-import com.squareup.okhttp.Credentials;
-import com.squareup.okhttp.OkHttpClient;
-import com.squareup.okhttp.Request;
-import com.squareup.okhttp.Response;
import java.io.IOException;
import java.net.InetSocketAddress;
@@ -33,6 +29,10 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.download.AntennapodHttpClient;
import de.danoeh.antennapod.core.service.download.ProxyConfig;
+import okhttp3.Credentials;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
@@ -258,10 +258,11 @@ public class ProxyDialog {
SocketAddress address = InetSocketAddress.createUnresolved(host, portValue);
Proxy.Type proxyType = Proxy.Type.valueOf(type.toUpperCase());
Proxy proxy = new Proxy(proxyType, address);
- OkHttpClient client = AntennapodHttpClient.newHttpClient();
- client.setConnectTimeout(10, TimeUnit.SECONDS);
- client.setProxy(proxy);
- client.interceptors().clear();
+ OkHttpClient.Builder builder = AntennapodHttpClient.newBuilder()
+ .connectTimeout(10, TimeUnit.SECONDS)
+ .proxy(proxy);
+ builder.interceptors().clear();
+ OkHttpClient client = builder.build();
if(!TextUtils.isEmpty(username)) {
String credentials = Credentials.basic(username, password);
client.interceptors().add(chain -> {
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/RenameFeedDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/RenameFeedDialog.java
new file mode 100644
index 000000000..31a544582
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/RenameFeedDialog.java
@@ -0,0 +1,44 @@
+package de.danoeh.antennapod.dialog;
+
+import android.app.Activity;
+import android.text.InputType;
+
+import com.afollestad.materialdialogs.MaterialDialog;
+
+import java.lang.ref.WeakReference;
+
+import de.danoeh.antennapod.core.feed.Feed;
+import de.danoeh.antennapod.core.storage.DBWriter;
+
+public class RenameFeedDialog {
+
+ private final WeakReference<Activity> activityRef;
+ private final Feed feed;
+
+ public RenameFeedDialog(Activity activity, Feed feed) {
+ this.activityRef = new WeakReference<>(activity);
+ this.feed = feed;
+ }
+
+ public void show() {
+ Activity activity = activityRef.get();
+ if(activity == null) {
+ return;
+ }
+ new MaterialDialog.Builder(activity)
+ .title(de.danoeh.antennapod.core.R.string.rename_feed_label)
+ .inputType(InputType.TYPE_CLASS_TEXT)
+ .input(feed.getTitle(), feed.getTitle(), true, (dialog, input) -> {
+ feed.setCustomTitle(input.toString());
+ DBWriter.setFeedCustomTitle(feed);
+ dialog.dismiss();
+ })
+ .neutralText(de.danoeh.antennapod.core.R.string.reset)
+ .onNeutral((dialog, which) -> dialog.getInputEditText().setText(feed.getFeedTitle()))
+ .negativeText(de.danoeh.antennapod.core.R.string.cancel_label)
+ .onNegative((dialog, which) -> dialog.dismiss())
+ .autoDismiss(false)
+ .show();
+ }
+
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java
index 8a13a75d9..7d6a66a54 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java
@@ -1,7 +1,7 @@
package de.danoeh.antennapod.dialog;
import android.content.Context;
-import android.content.SharedPreferences;
+import android.support.design.widget.Snackbar;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
@@ -9,6 +9,7 @@ import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
+import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;
@@ -16,36 +17,27 @@ import android.widget.Toast;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
-import java.util.concurrent.TimeUnit;
-
import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.event.MessageEvent;
+import de.danoeh.antennapod.core.preferences.SleepTimerPreferences;
+import de.greenrobot.event.EventBus;
public abstract class SleepTimerDialog {
private static final String TAG = SleepTimerDialog.class.getSimpleName();
- private static final int DEFAULT_SPINNER_POSITION = 1;
-
private Context context;
- private String PREF_NAME = "SleepTimerDialog";
- private String PREF_VALUE = "LastValue";
- private String PREF_TIME_UNIT = "LastTimeUnit";
- private String PREF_VIBRATE = "Vibrate";
- private String PREF_SHAKE_TO_RESET = "ShakeToReset";
- private SharedPreferences prefs;
private MaterialDialog dialog;
private EditText etxtTime;
private Spinner spTimeUnit;
private CheckBox cbShakeToReset;
private CheckBox cbVibrate;
+ private CheckBox chAutoEnable;
- private TimeUnit[] units = { TimeUnit.SECONDS, TimeUnit.MINUTES, TimeUnit.HOURS };
-
- public SleepTimerDialog(Context context) {
+ protected SleepTimerDialog(Context context) {
this.context = context;
- prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
}
public MaterialDialog createNewDialog() {
@@ -58,7 +50,7 @@ public abstract class SleepTimerDialog {
builder.onPositive((dialog, which) -> {
try {
savePreferences();
- long input = readTimeMillis();
+ long input = SleepTimerPreferences.timerMillis();
onTimerSet(input, cbShakeToReset.isChecked(), cbVibrate.isChecked());
dialog.dismiss();
} catch (NumberFormatException e) {
@@ -75,8 +67,9 @@ public abstract class SleepTimerDialog {
spTimeUnit = (Spinner) view.findViewById(R.id.spTimeUnit);
cbShakeToReset = (CheckBox) view.findViewById(R.id.cbShakeToReset);
cbVibrate = (CheckBox) view.findViewById(R.id.cbVibrate);
+ chAutoEnable = (CheckBox) view.findViewById(R.id.chAutoEnable);
- etxtTime.setText(prefs.getString(PREF_VALUE, "15"));
+ etxtTime.setText(SleepTimerPreferences.lastTimerValue());
etxtTime.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
@@ -104,12 +97,17 @@ public abstract class SleepTimerDialog {
android.R.layout.simple_spinner_item, spinnerContent);
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spTimeUnit.setAdapter(spinnerAdapter);
- int selection = prefs.getInt(PREF_TIME_UNIT, DEFAULT_SPINNER_POSITION);
- spTimeUnit.setSelection(selection);
+ spTimeUnit.setSelection(SleepTimerPreferences.lastTimerTimeUnit());
- cbShakeToReset.setChecked(prefs.getBoolean(PREF_SHAKE_TO_RESET, true));
- cbVibrate.setChecked(prefs.getBoolean(PREF_VIBRATE, true));
+ cbShakeToReset.setChecked(SleepTimerPreferences.shakeToReset());
+ cbVibrate.setChecked(SleepTimerPreferences.vibrate());
+ chAutoEnable.setChecked(SleepTimerPreferences.autoEnable());
+ chAutoEnable.setOnCheckedChangeListener((compoundButton, isChecked) -> {
+ SleepTimerPreferences.setAutoEnable(isChecked);
+ int messageString = isChecked ? R.string.sleep_timer_enabled_label : R.string.sleep_timer_disabled_label;
+ EventBus.getDefault().post(new MessageEvent(context.getString(messageString)));
+ });
return dialog;
}
@@ -125,19 +123,12 @@ public abstract class SleepTimerDialog {
public abstract void onTimerSet(long millis, boolean shakeToReset, boolean vibrate);
- private long readTimeMillis() {
- TimeUnit selectedUnit = units[spTimeUnit.getSelectedItemPosition()];
- long value = Long.parseLong(etxtTime.getText().toString());
- return selectedUnit.toMillis(value);
- }
-
private void savePreferences() {
- prefs.edit()
- .putString(PREF_VALUE, etxtTime.getText().toString())
- .putInt(PREF_TIME_UNIT, spTimeUnit.getSelectedItemPosition())
- .putBoolean(PREF_SHAKE_TO_RESET, cbShakeToReset.isChecked())
- .putBoolean(PREF_VIBRATE, cbVibrate.isChecked())
- .apply();
+ SleepTimerPreferences.setLastTimer(etxtTime.getText().toString(),
+ spTimeUnit.getSelectedItemPosition());
+ SleepTimerPreferences.setShakeToReset(cbShakeToReset.isChecked());
+ SleepTimerPreferences.setVibrate(cbVibrate.isChecked());
+ SleepTimerPreferences.setAutoEnable(chAutoEnable.isChecked());
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java
index 45364ca07..f14ebbdaf 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java
@@ -39,10 +39,11 @@ public class AddFeedFragment extends Fragment {
etxtFeedurl.setText(args.getString(ARG_FEED_URL));
}
+ Button butSearchITunes = (Button) root.findViewById(R.id.butSearchItunes);
Button butBrowserGpoddernet = (Button) root.findViewById(R.id.butBrowseGpoddernet);
+ Button butSearchFyyd = (Button) root.findViewById(R.id.butSearchFyyd);
Button butOpmlImport = (Button) root.findViewById(R.id.butOpmlImport);
Button butConfirm = (Button) root.findViewById(R.id.butConfirm);
- Button butSearchITunes = (Button) root.findViewById(R.id.butSearchItunes);
final MainActivity activity = (MainActivity) getActivity();
activity.getSupportActionBar().setTitle(R.string.add_feed_label);
@@ -51,6 +52,8 @@ public class AddFeedFragment extends Fragment {
butBrowserGpoddernet.setOnClickListener(v -> activity.loadChildFragment(new GpodnetMainFragment()));
+ butSearchFyyd.setOnClickListener(v -> activity.loadChildFragment(new FyydSearchFragment()));
+
butOpmlImport.setOnClickListener(v -> startActivity(new Intent(getActivity(),
OpmlImportFromPathActivity.class)));
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 29df6617d..ab8808093 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
@@ -227,22 +227,32 @@ public class AllEpisodesFragment extends Fragment {
}
return true;
case R.id.mark_all_read_item:
- ConfirmationDialog conDialog = new ConfirmationDialog(getActivity(),
+ ConfirmationDialog markAllReadConfirmationDialog = new ConfirmationDialog(getActivity(),
R.string.mark_all_read_label,
R.string.mark_all_read_confirmation_msg) {
@Override
- public void onConfirmButtonPressed(
- DialogInterface dialog) {
+ public void onConfirmButtonPressed(DialogInterface dialog) {
dialog.dismiss();
DBWriter.markAllItemsRead();
Toast.makeText(getActivity(), R.string.mark_all_read_msg, Toast.LENGTH_SHORT).show();
}
};
- conDialog.createNewDialog().show();
+ markAllReadConfirmationDialog.createNewDialog().show();
return true;
case R.id.mark_all_seen_item:
- DBWriter.markNewItemsSeen();
+ ConfirmationDialog markAllSeenConfirmationDialog = new ConfirmationDialog(getActivity(),
+ R.string.mark_all_seen_label,
+ R.string.mark_all_seen_confirmation_msg) {
+
+ @Override
+ public void onConfirmButtonPressed(DialogInterface dialog) {
+ dialog.dismiss();
+ DBWriter.markNewItemsSeen();
+ Toast.makeText(getActivity(), R.string.mark_all_seen_msg, Toast.LENGTH_SHORT).show();
+ }
+ };
+ markAllSeenConfirmationDialog.createNewDialog().show();
return true;
default:
return false;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java
index 77e66f3b0..4d34d076d 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java
@@ -69,16 +69,18 @@ public class ChaptersFragment extends ListFragment implements MediaplayerInfoCon
@Override
public void onMediaChanged(Playable media) {
- if(this.media == media || adapter == null) {
+ if(this.media == media) {
return;
}
this.media = media;
- adapter.setMedia(media);
- adapter.notifyDataSetChanged();
- if(media == null || media.getChapters() == null || media.getChapters().size() == 0) {
- setEmptyText(getString(R.string.no_items_label));
- } else {
- setEmptyText(null);
+ if (adapter != null) {
+ adapter.setMedia(media);
+ adapter.notifyDataSetChanged();
+ if(media == null || media.getChapters() == null || media.getChapters().size() == 0) {
+ setEmptyText(getString(R.string.no_items_label));
+ } else {
+ setEmptyText(null);
+ }
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java
index 856888ee0..1d3fcefba 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java
@@ -33,22 +33,15 @@ public class CoverFragment extends Fragment implements MediaplayerInfoContentFra
public static CoverFragment newInstance(Playable item) {
CoverFragment f = new CoverFragment();
- if (item != null) {
- Bundle args = new Bundle();
- args.putParcelable(ARG_PLAYABLE, item);
- f.setArguments(args);
- }
+ f.media = item;
return f;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- Bundle args = getArguments();
- if (args != null) {
- media = args.getParcelable(ARG_PLAYABLE);
- } else {
- Log.e(TAG, TAG + " was called with invalid arguments");
+ if (media == null) {
+ Log.e(TAG, TAG + " was called without media");
}
}
@@ -98,11 +91,13 @@ public class CoverFragment extends Fragment implements MediaplayerInfoContentFra
@Override
public void onMediaChanged(Playable media) {
- if(!isAdded() || this.media == media) {
+ if(this.media == media) {
return;
}
this.media = media;
- loadMediaInfo();
+ if (isAdded()) {
+ loadMediaInfo();
+ }
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FyydSearchFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FyydSearchFragment.java
new file mode 100644
index 000000000..7c1ec5ec1
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/FyydSearchFragment.java
@@ -0,0 +1,192 @@
+package de.danoeh.antennapod.fragment;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.view.MenuItemCompat;
+import android.support.v7.widget.SearchView;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.GridView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.activity.OnlineFeedViewActivity;
+import de.danoeh.antennapod.adapter.itunes.ItunesAdapter;
+import de.danoeh.antennapod.core.service.download.AntennapodHttpClient;
+import de.danoeh.antennapod.menuhandler.MenuItemUtils;
+import de.mfietz.fyydlin.FyydClient;
+import de.mfietz.fyydlin.FyydResponse;
+import de.mfietz.fyydlin.SearchHit;
+import rx.Subscription;
+import rx.android.schedulers.AndroidSchedulers;
+import rx.schedulers.Schedulers;
+
+import static de.danoeh.antennapod.adapter.itunes.ItunesAdapter.Podcast;
+import static java.util.Collections.emptyList;
+
+public class FyydSearchFragment extends Fragment {
+
+ private static final String TAG = "FyydSearchFragment";
+
+ /**
+ * Adapter responsible with the search results
+ */
+ private ItunesAdapter adapter;
+ private GridView gridView;
+ private ProgressBar progressBar;
+ private TextView txtvError;
+ private Button butRetry;
+ private TextView txtvEmpty;
+
+ private FyydClient client = new FyydClient(AntennapodHttpClient.getHttpClient());
+
+ /**
+ * List of podcasts retreived from the search
+ */
+ private List<Podcast> searchResults;
+ private Subscription subscription;
+
+ /**
+ * Constructor
+ */
+ public FyydSearchFragment() {
+ // Required empty public constructor
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setHasOptionsMenu(true);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Inflate the layout for this fragment
+ View root = inflater.inflate(R.layout.fragment_itunes_search, container, false);
+ gridView = (GridView) root.findViewById(R.id.gridView);
+ adapter = new ItunesAdapter(getActivity(), new ArrayList<>());
+ gridView.setAdapter(adapter);
+
+ //Show information about the podcast when the list item is clicked
+ gridView.setOnItemClickListener((parent, view1, position, id) -> {
+ Podcast podcast = searchResults.get(position);
+ Intent intent = new Intent(getActivity(), OnlineFeedViewActivity.class);
+ intent.putExtra(OnlineFeedViewActivity.ARG_FEEDURL, podcast.feedUrl);
+ intent.putExtra(OnlineFeedViewActivity.ARG_TITLE, podcast.title);
+ startActivity(intent);
+ });
+ progressBar = (ProgressBar) root.findViewById(R.id.progressBar);
+ txtvError = (TextView) root.findViewById(R.id.txtvError);
+ butRetry = (Button) root.findViewById(R.id.butRetry);
+ txtvEmpty = (TextView) root.findViewById(android.R.id.empty);
+
+ return root;
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ if (subscription != null) {
+ subscription.unsubscribe();
+ }
+ adapter = null;
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ super.onCreateOptionsMenu(menu, inflater);
+ inflater.inflate(R.menu.itunes_search, menu);
+ MenuItem searchItem = menu.findItem(R.id.action_search);
+ final SearchView sv = (SearchView) MenuItemCompat.getActionView(searchItem);
+ MenuItemUtils.adjustTextColor(getActivity(), sv);
+ sv.setQueryHint(getString(R.string.search_fyyd_label));
+ sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
+ @Override
+ public boolean onQueryTextSubmit(String s) {
+ sv.clearFocus();
+ search(s);
+ return true;
+ }
+
+ @Override
+ public boolean onQueryTextChange(String s) {
+ return false;
+ }
+ });
+ MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() {
+ @Override
+ public boolean onMenuItemActionExpand(MenuItem item) {
+ return true;
+ }
+
+ @Override
+ public boolean onMenuItemActionCollapse(MenuItem item) {
+ getActivity().getSupportFragmentManager().popBackStack();
+ return true;
+ }
+ });
+ MenuItemCompat.expandActionView(searchItem);
+ }
+
+ private void search(String query) {
+ if (subscription != null) {
+ subscription.unsubscribe();
+ }
+ showOnlyProgressBar();
+ subscription = client.searchPodcasts(query)
+ .subscribeOn(Schedulers.newThread())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(result -> {
+ progressBar.setVisibility(View.GONE);
+ processSearchResult(result);
+ }, error -> {
+ Log.e(TAG, Log.getStackTraceString(error));
+ progressBar.setVisibility(View.GONE);
+ txtvError.setText(error.toString());
+ txtvError.setVisibility(View.VISIBLE);
+ butRetry.setOnClickListener(v -> search(query));
+ butRetry.setVisibility(View.VISIBLE);
+ });
+ }
+
+ private void showOnlyProgressBar() {
+ gridView.setVisibility(View.GONE);
+ txtvError.setVisibility(View.GONE);
+ butRetry.setVisibility(View.GONE);
+ txtvEmpty.setVisibility(View.GONE);
+ progressBar.setVisibility(View.VISIBLE);
+ }
+
+ void processSearchResult(FyydResponse response) {
+ adapter.clear();
+ if (!response.getData().isEmpty()) {
+ adapter.clear();
+ searchResults = new ArrayList<>();
+ for (SearchHit searchHit : response.getData().values()) {
+ Podcast podcast = Podcast.fromSearch(searchHit);
+ searchResults.add(podcast);
+ }
+ } else {
+ searchResults = emptyList();
+ }
+ for(Podcast podcast : searchResults) {
+ adapter.add(podcast);
+ }
+ adapter.notifyDataSetInvalidated();
+ gridView.setVisibility(!searchResults.isEmpty() ? View.VISIBLE : View.GONE);
+ txtvEmpty.setVisibility(searchResults.isEmpty() ? View.VISIBLE : View.GONE);
+ }
+
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
index 89a1a8d50..a0586fe16 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
@@ -185,8 +185,10 @@ public class ItemDescriptionFragment extends Fragment implements MediaplayerInfo
super.onViewCreated(view, savedInstanceState);
Bundle args = getArguments();
if (args.containsKey(ARG_PLAYABLE)) {
- media = args.getParcelable(ARG_PLAYABLE);
- shownotesProvider = media;
+ if (media == null) {
+ media = args.getParcelable(ARG_PLAYABLE);
+ shownotesProvider = media;
+ }
load();
} else if (args.containsKey(ARG_FEEDITEM_ID)) {
long id = getArguments().getLong(ARG_FEEDITEM_ID);
@@ -377,12 +379,14 @@ public class ItemDescriptionFragment extends Fragment implements MediaplayerInfo
@Override
public void onMediaChanged(Playable media) {
- if(this.media == media || webvDescription == null) {
+ if(this.media == media) {
return;
}
this.media = media;
this.shownotesProvider = media;
- load();
+ if (webvDescription != null) {
+ load();
+ }
}
}
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 13f5481e9..75f9c0d35 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java
@@ -67,6 +67,7 @@ import de.danoeh.antennapod.core.util.FeedItemUtil;
import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.gui.MoreContentListFooterUtil;
import de.danoeh.antennapod.dialog.EpisodesApplyActionFragment;
+import de.danoeh.antennapod.dialog.RenameFeedDialog;
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
@@ -99,6 +100,7 @@ public class ItemlistFragment extends ListFragment {
private boolean itemsLoaded = false;
private boolean viewsCreated = false;
+ private boolean headerCreated = false;
private List<Downloader> downloaderList;
@@ -106,6 +108,7 @@ public class ItemlistFragment extends ListFragment {
private boolean isUpdatingFeed;
+ private TextView txtvTitle;
private IconTextView txtvFailure;
private TextView txtvInformation;
@@ -248,6 +251,9 @@ public class ItemlistFragment extends ListFragment {
.newInstance(feed.getItems());
((MainActivity)getActivity()).loadChildFragment(fragment);
return true;
+ case R.id.rename_item:
+ new RenameFeedDialog(getActivity(), feed).show();
+ return true;
case R.id.remove_item:
final FeedRemover remover = new FeedRemover(
getActivity(), feed) {
@@ -415,6 +421,7 @@ public class ItemlistFragment extends ListFragment {
public void update(EventDistributor eventDistributor, Integer arg) {
if ((EVENTS & arg) != 0) {
Log.d(TAG, "Received contentUpdate Intent. arg " + arg);
+ refreshHeaderView();
loadItems();
updateProgressBarVisibility();
}
@@ -460,8 +467,8 @@ public class ItemlistFragment extends ListFragment {
}
private void refreshHeaderView() {
- if (getListView() == null || feed == null) {
- Log.e(TAG, "Unable to setup listview: recyclerView = null or feed = null");
+ if (getListView() == null || feed == null || !headerCreated) {
+ Log.e(TAG, "Unable to refresh header view");
return;
}
if(feed.hasLastUpdateFailed()) {
@@ -469,6 +476,7 @@ public class ItemlistFragment extends ListFragment {
} else {
txtvFailure.setVisibility(View.GONE);
}
+ txtvTitle.setText(feed.getTitle());
if(feed.getItemFilter() != null) {
FeedItemFilter filter = feed.getItemFilter();
if(filter.getValues().length > 0) {
@@ -498,7 +506,7 @@ public class ItemlistFragment extends ListFragment {
View header = inflater.inflate(R.layout.feeditemlist_header, lv, false);
lv.addHeaderView(header);
- TextView txtvTitle = (TextView) header.findViewById(R.id.txtvTitle);
+ 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);
@@ -539,6 +547,7 @@ public class ItemlistFragment extends ListFragment {
startActivity(startIntent);
}
});
+ headerCreated = true;
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java
index b736688b9..db88c070d 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java
@@ -18,9 +18,6 @@ import android.widget.ProgressBar;
import android.widget.TextView;
import com.afollestad.materialdialogs.MaterialDialog;
-import com.squareup.okhttp.OkHttpClient;
-import com.squareup.okhttp.Request;
-import com.squareup.okhttp.Response;
import org.json.JSONArray;
import org.json.JSONException;
@@ -39,6 +36,9 @@ import de.danoeh.antennapod.adapter.itunes.ItunesAdapter;
import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.service.download.AntennapodHttpClient;
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
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 3ddd5245a..01119bcff 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java
@@ -26,6 +26,7 @@ import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.util.FeedItemUtil;
+import de.danoeh.antennapod.dialog.RenameFeedDialog;
import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
@@ -102,7 +103,7 @@ public class SubscriptionFragment extends Fragment {
if(subscription != null) {
subscription.unsubscribe();
}
- subscription = Observable.fromCallable(() -> DBReader.getNavDrawerData())
+ subscription = Observable.fromCallable(DBReader::getNavDrawerData)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
@@ -164,6 +165,9 @@ public class SubscriptionFragment extends Fragment {
.subscribe(result -> loadSubscriptions(),
error -> Log.e(TAG, Log.getStackTraceString(error)));
return true;
+ case R.id.rename_item:
+ new RenameFeedDialog(getActivity(), feed).show();
+ return true;
case R.id.remove_item:
final FeedRemover remover = new FeedRemover(getContext(), feed) {
@Override
diff --git a/app/src/main/java/de/danoeh/antennapod/menuhandler/MenuItemUtils.java b/app/src/main/java/de/danoeh/antennapod/menuhandler/MenuItemUtils.java
index 4c28b197d..ac703e13e 100644
--- a/app/src/main/java/de/danoeh/antennapod/menuhandler/MenuItemUtils.java
+++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/MenuItemUtils.java
@@ -28,6 +28,7 @@ public class MenuItemUtils extends de.danoeh.antennapod.core.menuhandler.MenuIte
}
}
+ @SuppressWarnings("ResourceType")
public static void refreshLockItem(Context context, Menu menu) {
final MenuItem queueLock = menu.findItem(de.danoeh.antennapod.R.id.queue_lock);
int[] lockIcons = new int[] { de.danoeh.antennapod.R.attr.ic_lock_open, de.danoeh.antennapod.R.attr.ic_lock_closed };
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 77764247d..7777af450 100644
--- a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java
+++ b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java
@@ -3,6 +3,7 @@ package de.danoeh.antennapod.preferences;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
+import android.app.ProgressDialog;
import android.app.TimePickerDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
@@ -42,6 +43,8 @@ import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -55,7 +58,10 @@ import de.danoeh.antennapod.activity.MediaplayerActivity;
import de.danoeh.antennapod.activity.PreferenceActivity;
import de.danoeh.antennapod.activity.PreferenceActivityGingerbread;
import de.danoeh.antennapod.activity.StatisticsActivity;
-import de.danoeh.antennapod.asynctask.OpmlExportWorker;
+import de.danoeh.antennapod.asynctask.ExportWorker;
+import de.danoeh.antennapod.core.export.ExportWriter;
+import de.danoeh.antennapod.core.export.html.HtmlWriter;
+import de.danoeh.antennapod.core.export.opml.OpmlWriter;
import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.GpodnetSyncService;
@@ -67,6 +73,10 @@ import de.danoeh.antennapod.dialog.AutoFlattrPreferenceDialog;
import de.danoeh.antennapod.dialog.GpodnetSetHostnameDialog;
import de.danoeh.antennapod.dialog.ProxyDialog;
import de.danoeh.antennapod.dialog.VariableSpeedDialog;
+import rx.Observable;
+import rx.Subscription;
+import rx.android.schedulers.AndroidSchedulers;
+import rx.schedulers.Schedulers;
/**
* Sets up a preference UI that lets the user change user preferences.
@@ -76,55 +86,36 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
private static final String TAG = "PreferenceController";
- public static final String PREF_FLATTR_SETTINGS = "prefFlattrSettings";
- public static final String PREF_FLATTR_AUTH = "pref_flattr_authenticate";
- public static final String PREF_FLATTR_REVOKE = "prefRevokeAccess";
- public static final String PREF_AUTO_FLATTR_PREFS = "prefAutoFlattrPrefs";
- public static final String PREF_OPML_EXPORT = "prefOpmlExport";
- public static final String STATISTICS = "statistics";
- public static final String PREF_ABOUT = "prefAbout";
- public static final String PREF_CHOOSE_DATA_DIR = "prefChooseDataDir";
- public static final String AUTO_DL_PREF_SCREEN = "prefAutoDownloadSettings";
- public static final String PREF_PLAYBACK_SPEED_LAUNCHER = "prefPlaybackSpeedLauncher";
+ private static final String PREF_FLATTR_SETTINGS = "prefFlattrSettings";
+ private static final String PREF_FLATTR_AUTH = "pref_flattr_authenticate";
+ private static final String PREF_FLATTR_REVOKE = "prefRevokeAccess";
+ private static final String PREF_AUTO_FLATTR_PREFS = "prefAutoFlattrPrefs";
+ private static final String PREF_OPML_EXPORT = "prefOpmlExport";
+ private static final String PREF_HTML_EXPORT = "prefHtmlExport";
+ private static final String STATISTICS = "statistics";
+ private static final String PREF_ABOUT = "prefAbout";
+ 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";
- public static final String PREF_GPODNET_LOGIN = "pref_gpodnet_authenticate";
- public static final String PREF_GPODNET_SETLOGIN_INFORMATION = "pref_gpodnet_setlogin_information";
- public static final String PREF_GPODNET_SYNC = "pref_gpodnet_sync";
- public static final String PREF_GPODNET_LOGOUT = "pref_gpodnet_logout";
- public static final String PREF_GPODNET_HOSTNAME = "pref_gpodnet_hostname";
- public static final String PREF_GPODNET_NOTIFICATIONS = "pref_gpodnet_notifications";
- public static final String PREF_EXPANDED_NOTIFICATION = "prefExpandNotify";
- public static final String PREF_PROXY = "prefProxy";
- public static final String PREF_KNOWN_ISSUES = "prefKnownIssues";
- public static final String PREF_FAQ = "prefFaq";
- public static final String PREF_SEND_CRASH_REPORT = "prefSendCrashReport";
-
- private final PreferenceUI ui;
-
- private CheckBoxPreference[] selectedNetworks;
-
+ 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";
+ private static final String PREF_GPODNET_FORCE_FULL_SYNC = "pref_gpodnet_force_full_sync";
+ private static final String PREF_GPODNET_LOGOUT = "pref_gpodnet_logout";
+ private static final String PREF_GPODNET_HOSTNAME = "pref_gpodnet_hostname";
+ private static final String PREF_GPODNET_NOTIFICATIONS = "pref_gpodnet_notifications";
+ private static final String PREF_EXPANDED_NOTIFICATION = "prefExpandNotify";
+ private static final String PREF_PROXY = "prefProxy";
+ private static final String PREF_KNOWN_ISSUES = "prefKnownIssues";
+ private static final String PREF_FAQ = "prefFaq";
+ private static final String PREF_SEND_CRASH_REPORT = "prefSendCrashReport";
private static final String[] EXTERNAL_STORAGE_PERMISSIONS = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE };
private static final int PERMISSION_REQUEST_EXTERNAL_STORAGE = 41;
-
- public PreferenceController(PreferenceUI ui) {
- this.ui = ui;
- PreferenceManager.getDefaultSharedPreferences(ui.getActivity().getApplicationContext())
- .registerOnSharedPreferenceChangeListener(this);
- }
-
- @Override
- public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
- if(key.equals(UserPreferences.PREF_SONIC)) {
- CheckBoxPreference prefSonic = (CheckBoxPreference) ui.findPreference(UserPreferences.PREF_SONIC);
- if(prefSonic != null) {
- prefSonic.setChecked(sharedPreferences.getBoolean(UserPreferences.PREF_SONIC, false));
- }
- }
- }
-
+ private final PreferenceUI ui;
private final SharedPreferences.OnSharedPreferenceChangeListener gpoddernetListener =
(sharedPreferences, key) -> {
if (GpodnetPreferences.PREF_LAST_SYNC_ATTEMPT_TIMESTAMP.equals(key)) {
@@ -132,6 +123,14 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
GpodnetPreferences.getLastSyncAttemptTimestamp());
}
};
+ private CheckBoxPreference[] selectedNetworks;
+ private Subscription subscription;
+
+ public PreferenceController(PreferenceUI ui) {
+ this.ui = ui;
+ PreferenceManager.getDefaultSharedPreferences(ui.getActivity().getApplicationContext())
+ .registerOnSharedPreferenceChangeListener(this);
+ }
/**
* Returns the preference activity that should be used on this device.
@@ -146,6 +145,16 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
}
}
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+ if(key.equals(UserPreferences.PREF_SONIC)) {
+ CheckBoxPreference prefSonic = (CheckBoxPreference) ui.findPreference(UserPreferences.PREF_SONIC);
+ if(prefSonic != null) {
+ prefSonic.setChecked(sharedPreferences.getBoolean(UserPreferences.PREF_SONIC, false));
+ }
+ }
+ }
+
public void onCreate() {
final Activity activity = ui.getActivity();
@@ -181,11 +190,9 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
}
);
ui.findPreference(PreferenceController.PREF_OPML_EXPORT).setOnPreferenceClickListener(
- preference -> {
- new OpmlExportWorker(activity).executeAsync();
- return true;
- }
- );
+ preference -> export(new OpmlWriter()));
+ ui.findPreference(PreferenceController.PREF_HTML_EXPORT).setOnPreferenceClickListener(
+ preference -> export(new HtmlWriter()));
ui.findPreference(PreferenceController.PREF_CHOOSE_DATA_DIR).setOnPreferenceClickListener(
preference -> {
if (Build.VERSION_CODES.KITKAT <= Build.VERSION.SDK_INT &&
@@ -361,6 +368,18 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
toast.show();
return true;
});
+ ui.findPreference(PreferenceController.PREF_GPODNET_FORCE_FULL_SYNC).
+ setOnPreferenceClickListener(preference -> {
+ GpodnetPreferences.setLastSubscriptionSyncTimestamp(0L);
+ GpodnetPreferences.setLastEpisodeActionsSyncTimestamp(0L);
+ GpodnetPreferences.setLastSyncAttempt(false, 0);
+ updateLastGpodnetSyncReport(false, 0);
+ GpodnetSyncService.sendSyncIntent(ui.getActivity().getApplicationContext());
+ Toast toast = Toast.makeText(ui.getActivity(), R.string.pref_gpodnet_sync_started,
+ Toast.LENGTH_SHORT);
+ toast.show();
+ return true;
+ });
ui.findPreference(PreferenceController.PREF_GPODNET_LOGOUT).setOnPreferenceClickListener(
preference -> {
GpodnetPreferences.logout();
@@ -440,6 +459,40 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
setSelectedNetworksEnabled(UserPreferences.isEnableAutodownloadWifiFilter());
}
+ private boolean export(ExportWriter exportWriter) {
+ Context context = ui.getActivity();
+ final ProgressDialog progressDialog = new ProgressDialog(context);
+ progressDialog.setMessage(context.getString(R.string.exporting_label));
+ progressDialog.setIndeterminate(true);
+ progressDialog.show();
+ final AlertDialog.Builder alert = new AlertDialog.Builder(context)
+ .setNeutralButton(android.R.string.ok, (dialog, which) -> dialog.dismiss());
+ Observable<File> observable = new ExportWorker(exportWriter).exportObservable();
+ subscription = observable.subscribeOn(Schedulers.newThread())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(output -> {
+ alert.setTitle(R.string.opml_export_success_title);
+ String message = context.getString(R.string.opml_export_success_sum) + output.toString();
+ alert.setMessage(message);
+ alert.setPositiveButton(R.string.send_label, (dialog, which) -> {
+ Uri outputUri = Uri.fromFile(output);
+ Intent sendIntent = new Intent(Intent.ACTION_SEND);
+ sendIntent.putExtra(Intent.EXTRA_SUBJECT,
+ context.getResources().getText(R.string.opml_export_label));
+ sendIntent.putExtra(Intent.EXTRA_STREAM, outputUri);
+ sendIntent.setType("text/plain");
+ context.startActivity(Intent.createChooser(sendIntent,
+ context.getResources().getText(R.string.send_label)));
+ });
+ alert.create().show();
+ }, error -> {
+ alert.setTitle(R.string.export_error_label);
+ alert.setMessage(error.getMessage());
+ alert.show();
+ }, () -> progressDialog.dismiss());
+ return true;
+ }
+
private void openInBrowser(String url) {
try {
Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
@@ -464,6 +517,12 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
GpodnetPreferences.unregisterOnSharedPreferenceChangeListener(gpoddernetListener);
}
+ public void onStop() {
+ if(subscription != null) {
+ subscription.unsubscribe();
+ }
+ }
+
@SuppressLint("NewApi")
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK &&
@@ -505,6 +564,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
ui.findPreference(PreferenceController.PREF_GPODNET_LOGIN).setEnabled(!loggedIn);
ui.findPreference(PreferenceController.PREF_GPODNET_SETLOGIN_INFORMATION).setEnabled(loggedIn);
ui.findPreference(PreferenceController.PREF_GPODNET_SYNC).setEnabled(loggedIn);
+ ui.findPreference(PreferenceController.PREF_GPODNET_FORCE_FULL_SYNC).setEnabled(loggedIn);
ui.findPreference(PreferenceController.PREF_GPODNET_LOGOUT).setEnabled(loggedIn);
ui.findPreference(PREF_GPODNET_NOTIFICATIONS).setEnabled(loggedIn);
if(loggedIn) {
@@ -524,7 +584,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
private void updateLastGpodnetSyncReport(boolean successful, long lastTime) {
Preference sync = ui.findPreference(PREF_GPODNET_SYNC);
if (lastTime != 0) {
- sync.setSummary(ui.getActivity().getString(R.string.pref_gpodnet_sync_sum) + "\n" +
+ sync.setSummary(ui.getActivity().getString(R.string.pref_gpodnet_sync_changes_sum) + "\n" +
ui.getActivity().getString(R.string.pref_gpodnet_sync_sum_last_sync_line,
ui.getActivity().getString(successful ?
R.string.gpodnetsync_pref_report_successful :
@@ -535,7 +595,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
DateUtils.WEEK_IN_MILLIS,
DateUtils.FORMAT_SHOW_TIME)));
} else {
- sync.setSummary(ui.getActivity().getString(R.string.pref_gpodnet_sync_sum));
+ sync.setSummary(ui.getActivity().getString(R.string.pref_gpodnet_sync_changes_sum));
}
}
@@ -703,6 +763,12 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
List<WifiConfiguration> networks = wifiservice.getConfiguredNetworks();
if (networks != null) {
+ Collections.sort(networks, new Comparator<WifiConfiguration>() {
+ @Override
+ public int compare(WifiConfiguration x, WifiConfiguration y) {
+ return x.SSID.compareTo(y.SSID);
+ }
+ });
selectedNetworks = new CheckBoxPreference[networks.size()];
List<String> prefValues = Arrays.asList(UserPreferences
.getAutodownloadSelectedNetworks());
@@ -787,9 +853,8 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
hiddenDrawerItems.add(NAV_DRAWER_TAGS[which]);
}
});
- builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> {
- UserPreferences.setHiddenDrawerItems(hiddenDrawerItems);
- });
+ builder.setPositiveButton(R.string.confirm_label, (dialog, which) ->
+ UserPreferences.setHiddenDrawerItems(hiddenDrawerItems));
builder.setNegativeButton(R.string.cancel_label, null);
builder.create().show();
}
@@ -833,9 +898,8 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
preferredButtons.remove((Integer) which);
}
});
- builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> {
- UserPreferences.setCompactNotificationButtons(preferredButtons);
- });
+ builder.setPositiveButton(R.string.confirm_label, (dialog, which) ->
+ UserPreferences.setCompactNotificationButtons(preferredButtons));
builder.setNegativeButton(R.string.cancel_label, null);
builder.create().show();
}
diff --git a/app/src/main/play/ast_ES/listing/fulldescription b/app/src/main/play/ast_ES/listing/fulldescription
new file mode 100644
index 000000000..87b477fdc
--- /dev/null
+++ b/app/src/main/play/ast_ES/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/lt/listing/fulldescription b/app/src/main/play/lt/listing/fulldescription
new file mode 100644
index 000000000..87b477fdc
--- /dev/null
+++ b/app/src/main/play/lt/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/te/listing/fulldescription b/app/src/main/play/te/listing/fulldescription
new file mode 100644
index 000000000..87b477fdc
--- /dev/null
+++ b/app/src/main/play/te/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/zh_TW/listing/fulldescription b/app/src/main/play/zh_TW/listing/fulldescription
new file mode 100644
index 000000000..87b477fdc
--- /dev/null
+++ b/app/src/main/play/zh_TW/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-v14/time_dialog.xml b/app/src/main/res/layout-v14/time_dialog.xml
index 06c2cce14..ba4249268 100644
--- a/app/src/main/res/layout-v14/time_dialog.xml
+++ b/app/src/main/res/layout-v14/time_dialog.xml
@@ -33,26 +33,34 @@
</LinearLayout>
<LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dp"
+ android:text="@string/timer_about_to_expire_label"
+ android:textSize="16sp" />
+
+ <CheckBox
+ android:id="@+id/cbShakeToReset"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/shake_to_reset_label" />
+
+ <CheckBox
+ android:id="@+id/cbVibrate"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/timer_vibration_label" />
+
+ <CheckBox
+ android:id="@+id/chAutoEnable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:orientation="vertical">
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
- android:textSize="16sp"
- android:text="@string/timer_about_to_expire_label"/>
-
- <CheckBox android:id="@+id/cbShakeToReset"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/shake_to_reset_label"/>
-
- <CheckBox android:id="@+id/cbVibrate"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/timer_vibration_label"/>
+ android:text="@string/auto_enable_label" />
</LinearLayout>
diff --git a/app/src/main/res/layout/addfeed.xml b/app/src/main/res/layout/addfeed.xml
index dff24c650..33951e060 100644
--- a/app/src/main/res/layout/addfeed.xml
+++ b/app/src/main/res/layout/addfeed.xml
@@ -7,18 +7,18 @@
<LinearLayout
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingTop="8dp"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingBottom="8dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
- android:paddingBottom="8dp"
- android:orientation="vertical">
+ android:paddingTop="8dp">
<TextView
android:id="@+id/txtvPodcastDirectories"
+ style="@style/AntennaPod.TextView.Heading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- style="@style/AntennaPod.TextView.Heading"
android:text="@string/podcastdirectories_label"/>
<TextView
@@ -26,83 +26,73 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/podcastdirectories_descr"
- android:textSize="@dimen/text_size_medium"
- android:layout_marginTop="4dp"/>
+ android:textSize="@dimen/text_size_medium"/>
<Button
android:id="@+id/butSearchItunes"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
+ android:layout_marginTop="4dp"
android:text="@string/search_itunes_label"/>
<Button
+ android:id="@+id/butSearchFyyd"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/search_fyyd_label"/>
+
+ <Button
android:id="@+id/butBrowseGpoddernet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
android:text="@string/browse_gpoddernet_label"/>
- <View
- android:id="@+id/divider1"
- android:layout_width="match_parent"
- android:layout_height="1dp"
- android:layout_margin="16dp"
- android:background="?android:attr/listDivider"/>
+ <View style="@style/Divider"/>
<TextView
android:id="@+id/txtvFeedurl"
+ style="@style/AntennaPod.TextView.Heading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_below="@id/divider1"
- style="@style/AntennaPod.TextView.Heading"
android:text="@string/txtvfeedurl_label"/>
<EditText
android:id="@+id/etxtFeedurl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="4dp"
- android:hint="@string/etxtFeedurlHint"
- android:inputType="textUri"
+ android:cursorVisible="true"
android:focusable="true"
android:focusableInTouchMode="true"
- android:cursorVisible="true"/>
+ android:hint="@string/etxtFeedurlHint"
+ android:inputType="textUri"/>
<Button
android:id="@+id/butConfirm"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
android:text="@string/confirm_label"/>
- <View
- android:id="@+id/divider2"
- android:layout_width="match_parent"
- android:layout_height="1dp"
- android:layout_margin="16dp"
- android:background="?android:attr/listDivider"/>
+ <View style="@style/Divider"/>
<TextView
android:id="@+id/txtvOpmlImport"
+ style="@style/AntennaPod.TextView.Heading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- style="@style/AntennaPod.TextView.Heading"
android:text="@string/opml_import_label"/>
<TextView
android:id="@+id/txtvOpmlImportExpl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="4dp"
- android:textSize="@dimen/text_size_medium"
- android:text="@string/opml_import_txtv_button_lable"/>
+ android:text="@string/opml_import_txtv_button_lable"
+ android:textSize="@dimen/text_size_medium"/>
<Button
android:id="@+id/butOpmlImport"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
+ android:layout_marginTop="4dp"
android:text="@string/opml_import_label"/>
</LinearLayout>
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/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/layout/time_dialog.xml b/app/src/main/res/layout/time_dialog.xml
index b270e82f7..0290ce708 100644
--- a/app/src/main/res/layout/time_dialog.xml
+++ b/app/src/main/res/layout/time_dialog.xml
@@ -36,22 +36,30 @@
android:layout_height="wrap_content"
android:orientation="vertical">
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
- android:textSize="16sp"
- android:text="@string/timer_about_to_expire_label"/>
-
- <CheckBox android:id="@+id/cbShakeToReset"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/shake_to_reset_label"/>
-
- <CheckBox android:id="@+id/cbVibrate"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/timer_vibration_label"/>
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dp"
+ android:text="@string/timer_about_to_expire_label"
+ android:textSize="16sp" />
+
+ <CheckBox
+ android:id="@+id/cbShakeToReset"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/shake_to_reset_label" />
+
+ <CheckBox
+ android:id="@+id/cbVibrate"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/timer_vibration_label" />
+
+ <CheckBox
+ android:id="@+id/chAutoEnable"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/auto_enable_label" />
</LinearLayout>
diff --git a/app/src/main/res/menu/episodes_apply_action_options.xml b/app/src/main/res/menu/episodes_apply_action_options.xml
index 3df88046d..c3f117386 100644
--- a/app/src/main/res/menu/episodes_apply_action_options.xml
+++ b/app/src/main/res/menu/episodes_apply_action_options.xml
@@ -46,6 +46,8 @@
android:title="@string/queued_label"/>
<item android:id="@+id/check_not_queued"
android:title="@string/not_queued_label"/>
+ <item android:id="@+id/check_has_media"
+ android:title="@string/has_media"/>
</menu>
</item>
diff --git a/app/src/main/res/menu/feedlist.xml b/app/src/main/res/menu/feedlist.xml
index ed03c08d6..0646dc70f 100644
--- a/app/src/main/res/menu/feedlist.xml
+++ b/app/src/main/res/menu/feedlist.xml
@@ -66,6 +66,12 @@
</item>
<item
+ android:id="@+id/rename_item"
+ android:menuCategory="container"
+ android:title="@string/rename_feed_label"
+ custom:showAsAction="never" />
+
+ <item
android:id="@+id/remove_item"
android:icon="?attr/content_discard"
android:menuCategory="container"
diff --git a/app/src/main/res/menu/nav_feed_context.xml b/app/src/main/res/menu/nav_feed_context.xml
index 4bf067d25..4da40441f 100644
--- a/app/src/main/res/menu/nav_feed_context.xml
+++ b/app/src/main/res/menu/nav_feed_context.xml
@@ -12,6 +12,11 @@
android:title="@string/mark_all_read_label" />
<item
+ android:id="@+id/rename_item"
+ android:menuCategory="container"
+ android:title="@string/rename_feed_label" />
+
+ <item
android:id="@+id/remove_item"
android:menuCategory="container"
android:title="@string/remove_feed_label" />
diff --git a/app/src/main/res/xml/automotive_app_desc.xml b/app/src/main/res/xml/automotive_app_desc.xml
deleted file mode 100644
index 0a6a3c9fb..000000000
--- a/app/src/main/res/xml/automotive_app_desc.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<automotiveApp>
- <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 2aa736cb2..0f1175ca3 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -118,6 +118,12 @@
android:summary="@string/pref_rewind_sum"
android:title="@string/pref_rewind" />
<de.danoeh.antennapod.preferences.SwitchCompatPreference
+ android:defaultValue="false"
+ android:enabled="true"
+ android:key="prefHardwarePreviousButtonRestarts"
+ android:summary="@string/pref_hardwarePreviousButtonRestarts_sum"
+ android:title="@string/pref_hardwarePreviousButtonRestarts_title"/>
+ <de.danoeh.antennapod.preferences.SwitchCompatPreference
android:defaultValue="true"
android:enabled="true"
android:key="prefFollowQueue"
@@ -162,6 +168,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"
@@ -254,8 +266,12 @@
android:summary="@string/pref_gpodnet_setlogin_information_sum"/>
<Preference
android:key="pref_gpodnet_sync"
- android:title="@string/pref_gpodnet_sync_title"
- android:summary="@string/pref_gpodnet_sync_sum"/>
+ android:title="@string/pref_gpodnet_sync_changes_title"
+ android:summary="@string/pref_gpodnet_sync_changes_sum"/>
+ <Preference
+ android:key="pref_gpodnet_force_full_sync"
+ android:title="@string/pref_gpodnet_full_sync_title"
+ android:summary="@string/pref_gpodnet_full_sync_sum"/>
<Preference
android:key="pref_gpodnet_logout"
android:title="@string/pref_gpodnet_logout_title"/>
@@ -286,6 +302,9 @@
android:key="prefOpmlExport"
android:title="@string/opml_export_label"/>
<Preference
+ android:key="prefHtmlExport"
+ android:title="@string/html_export_label"/>
+ <Preference
android:key="statistics"
android:title="@string/statistics_label"/>
</PreferenceCategory>
diff --git a/app/src/main/templates/about.html b/app/src/main/templates/about.html
index 5c7a3cbd0..400727c46 100644
--- a/app/src/main/templates/about.html
+++ b/app/src/main/templates/about.html
@@ -52,7 +52,7 @@
<p>Created by Daniel Oeh</p>
- <p>Copyright &copy; 2015 AntennaPod Contributors <a href="CONTRIBUTORS.txt">(View)</a></p>
+ <p>Copyright &copy; 2012-@year@ AntennaPod Contributors <a href="CONTRIBUTORS.txt">(View)</a></p>
<p>Licensed under the MIT License <a href="LICENSE.txt">(View)</a></p>
</div>
diff --git a/build.gradle b/build.gradle
index 40963b21d..ba4e7abb9 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,10 +6,10 @@ buildscript {
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.1.2'
- classpath "me.tatarka:gradle-retrolambda:3.2.4"
+ classpath "com.android.tools.build:gradle:2.2.3"
+ classpath "me.tatarka:gradle-retrolambda:3.3.1"
classpath "me.tatarka.retrolambda.projectlombok:lombok.ast:0.2.3.a2"
- classpath 'com.github.triplet.gradle:play-publisher:1.1.4'
+ classpath "com.github.triplet.gradle:play-publisher:1.1.4"
// Exclude the version that the android plugin depends on.
configurations.classpath.exclude group: "com.android.tools.external.lombok"
}
@@ -51,9 +51,9 @@ project.ext {
glideOkhttpIntegrationVersion = "1.4.0"
iconifyVersion = "2.2.2"
jsoupVersion = "1.9.2"
- materialDialogsVersion = "0.8.5.6@aar"
- okhttpVersion = "2.7.5"
- okioVersion = "1.9.0"
+ materialDialogsVersion = "0.8.5.8@aar"
+ okhttpVersion = "3.4.2"
+ okioVersion = "1.11.0"
recyclerviewFlexibledividerVersion = "1.2.6"
robotiumSoloVersion = "5.6.0"
rxAndroidVersion = "1.2.1"
@@ -68,7 +68,7 @@ project.ext {
}
task wrapper(type: Wrapper) {
- gradleVersion = "2.14.1"
+ gradleVersion = "3.2.1"
}
// free build hack: common functions
diff --git a/circle.yml b/circle.yml
index 7e4f735b5..6549e756e 100644
--- a/circle.yml
+++ b/circle.yml
@@ -2,6 +2,8 @@ general:
artifacts:
- app/build/outputs/apk
machine:
+ environment:
+ GRADLE_OPTS: '-Dorg.gradle.jvmargs="-Xmx2048m -XX:+HeapDumpOnOutOfMemoryError"'
java:
version: oraclejdk8
dependencies:
@@ -16,4 +18,5 @@ dependencies:
test:
override:
- - ./gradlew assembleDebug -PdisablePreDex \ No newline at end of file
+ - ./gradlew assembleDebug -PdisablePreDex:
+ timeout: 1800
diff --git a/core/build.gradle b/core/build.gradle
index d440a163f..c2ddd24da 100644
--- a/core/build.gradle
+++ b/core/build.gradle
@@ -56,9 +56,9 @@ dependencies {
compile "com.jayway.android.robotium:robotium-solo:$robotiumSoloVersion"
compile "org.jsoup:jsoup:$jsoupVersion"
compile "com.github.bumptech.glide:glide:$glideVersion"
- compile "com.github.bumptech.glide:okhttp-integration:$glideOkhttpIntegrationVersion"
- compile "com.squareup.okhttp:okhttp:$okhttpVersion"
- compile "com.squareup.okhttp:okhttp-urlconnection:$okhttpVersion"
+ compile "com.github.bumptech.glide:okhttp3-integration:$glideOkhttpIntegrationVersion@aar"
+ compile "com.squareup.okhttp3:okhttp:$okhttpVersion"
+ compile "com.squareup.okhttp3:okhttp-urlconnection:$okhttpVersion"
compile "com.squareup.okio:okio:$okioVersion"
compile "com.nineoldandroids:library:2.4.0"
compile "de.greenrobot:eventbus:$eventbusVersion"
diff --git a/core/src/free/java/de/danoeh/antennapod/core/ClientConfig.java b/core/src/free/java/de/danoeh/antennapod/core/ClientConfig.java
index eb2e6fc9e..88ae6d6bc 100644
--- a/core/src/free/java/de/danoeh/antennapod/core/ClientConfig.java
+++ b/core/src/free/java/de/danoeh/antennapod/core/ClientConfig.java
@@ -3,6 +3,7 @@ package de.danoeh.antennapod.core;
import android.content.Context;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
+import de.danoeh.antennapod.core.preferences.SleepTimerPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.danoeh.antennapod.core.util.NetworkUtils;
@@ -43,7 +44,7 @@ public class ClientConfig {
UpdateManager.init(context);
PlaybackPreferences.init(context);
NetworkUtils.init(context);
-// CastManager.init(context);
+ SleepTimerPreferences.init(context);
initialized = true;
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/asynctask/FeedRemover.java b/core/src/main/java/de/danoeh/antennapod/core/asynctask/FeedRemover.java
index e475e696c..67c460e78 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/asynctask/FeedRemover.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/asynctask/FeedRemover.java
@@ -38,10 +38,11 @@ public class FeedRemover extends AsyncTask<Void, Void, Void> {
@Override
protected void onPostExecute(Void result) {
- dialog.dismiss();
+ if(dialog != null && dialog.isShowing()) {
+ dialog.dismiss();
+ }
if(skipOnCompletion) {
- context.sendBroadcast(new Intent(
- PlaybackService.ACTION_SKIP_CURRENT_EPISODE));
+ context.sendBroadcast(new Intent(PlaybackService.ACTION_SKIP_CURRENT_EPISODE));
}
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java b/core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java
index 982015314..80ce6cf56 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java
@@ -8,6 +8,7 @@ import android.content.Context;
import android.os.ParcelFileDescriptor;
import android.util.Log;
+import org.apache.commons.io.IOUtils;
import org.xmlpull.v1.XmlPullParserException;
import java.io.ByteArrayOutputStream;
@@ -27,10 +28,10 @@ import java.util.ArrayList;
import java.util.Arrays;
import de.danoeh.antennapod.core.BuildConfig;
+import de.danoeh.antennapod.core.export.opml.OpmlElement;
+import de.danoeh.antennapod.core.export.opml.OpmlReader;
+import de.danoeh.antennapod.core.export.opml.OpmlWriter;
import de.danoeh.antennapod.core.feed.Feed;
-import de.danoeh.antennapod.core.opml.OpmlElement;
-import de.danoeh.antennapod.core.opml.OpmlReader;
-import de.danoeh.antennapod.core.opml.OpmlWriter;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DownloadRequestException;
import de.danoeh.antennapod.core.storage.DownloadRequester;
@@ -56,7 +57,9 @@ public class OpmlBackupAgent extends BackupAgentHelper {
}
}
- /** Class for backing up and restoring the OPML file. */
+ /**
+ * Class for backing up and restoring the OPML file.
+ */
private static class OpmlBackupHelper implements BackupHelper {
private static final String TAG = "OpmlBackupHelper";
@@ -64,7 +67,9 @@ public class OpmlBackupAgent extends BackupAgentHelper {
private final Context mContext;
- /** Checksum of restored OPML file */
+ /**
+ * Checksum of restored OPML file
+ */
private byte[] mChecksum;
public OpmlBackupHelper(Context context) {
@@ -170,12 +175,7 @@ public class OpmlBackupAgent extends BackupAgentHelper {
} catch (IOException e) {
Log.e(TAG, "Failed to restore OPML backup", e);
} finally {
- if (reader != null) {
- try {
- reader.close();
- } catch (IOException e) {
- }
- }
+ IOUtils.closeQuietly(reader);
}
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/event/MessageEvent.java b/core/src/main/java/de/danoeh/antennapod/core/event/MessageEvent.java
new file mode 100644
index 000000000..9fc488fbc
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/event/MessageEvent.java
@@ -0,0 +1,21 @@
+package de.danoeh.antennapod.core.event;
+
+import android.support.annotation.Nullable;
+
+public class MessageEvent {
+
+ public final String message;
+
+ @Nullable
+ public final Runnable action;
+
+ public MessageEvent(String message) {
+ this(message, null);
+ }
+
+ public MessageEvent(String message, Runnable action) {
+ this.message = message;
+ this.action = action;
+ }
+
+}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/export/CommonSymbols.java b/core/src/main/java/de/danoeh/antennapod/core/export/CommonSymbols.java
new file mode 100644
index 000000000..3ed251047
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/export/CommonSymbols.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package de.danoeh.antennapod.core.export;
+
+public class CommonSymbols {
+
+ public static final String HEAD = "head";
+ public static final String BODY = "body";
+ public static final String TITLE = "title";
+
+ public static final String XML_FEATURE_INDENT_OUTPUT = "http://xmlpull.org/v1/doc/features.html#indent-output";
+
+}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/export/ExportWriter.java b/core/src/main/java/de/danoeh/antennapod/core/export/ExportWriter.java
new file mode 100644
index 000000000..d6a187b21
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/export/ExportWriter.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package de.danoeh.antennapod.core.export;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.List;
+
+import de.danoeh.antennapod.core.feed.Feed;
+
+public interface ExportWriter {
+
+ void writeDocument(List<Feed> feeds, Writer writer)
+ throws IllegalArgumentException, IllegalStateException, IOException;
+
+ String fileExtension();
+
+}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/export/html/HtmlSymbols.java b/core/src/main/java/de/danoeh/antennapod/core/export/html/HtmlSymbols.java
new file mode 100644
index 000000000..b8807a686
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/export/html/HtmlSymbols.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package de.danoeh.antennapod.core.export.html;
+
+import de.danoeh.antennapod.core.export.CommonSymbols;
+
+class HtmlSymbols extends CommonSymbols {
+
+ static final String HTML = "html";
+
+ static final String ORDERED_LIST = "ol";
+ static final String LIST_ITEM = "li";
+
+ static String HEADING = "h1";
+
+ static final String LINK = "a";
+ static final String LINK_DESTINATION = "href";
+
+}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/export/html/HtmlWriter.java b/core/src/main/java/de/danoeh/antennapod/core/export/html/HtmlWriter.java
new file mode 100644
index 000000000..c24b39812
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/export/html/HtmlWriter.java
@@ -0,0 +1,82 @@
+package de.danoeh.antennapod.core.export.html;
+
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.Xml;
+
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.List;
+
+import de.danoeh.antennapod.core.export.ExportWriter;
+import de.danoeh.antennapod.core.feed.Feed;
+
+/** Writes HTML documents. */
+public class HtmlWriter implements ExportWriter {
+
+ private static final String TAG = "HtmlWriter";
+ private static final String ENCODING = "UTF-8";
+ private static final String HTML_TITLE = "AntennaPod Subscriptions";
+
+ /**
+ * Takes a list of feeds and a writer and writes those into an HTML
+ * document.
+ *
+ * @throws IOException
+ * @throws IllegalStateException
+ * @throws IllegalArgumentException
+ */
+ @Override
+ public void writeDocument(List<Feed> feeds, Writer writer)
+ throws IllegalArgumentException, IllegalStateException, IOException {
+ Log.d(TAG, "Starting to write document");
+ XmlSerializer xs = Xml.newSerializer();
+ xs.setFeature(HtmlSymbols.XML_FEATURE_INDENT_OUTPUT, true);
+ xs.setOutput(writer);
+
+ xs.startDocument(ENCODING, false);
+ xs.startTag(null, HtmlSymbols.HTML);
+ xs.startTag(null, HtmlSymbols.HEAD);
+ xs.startTag(null, HtmlSymbols.TITLE);
+ xs.text(HTML_TITLE);
+ xs.endTag(null, HtmlSymbols.TITLE);
+ xs.endTag(null, HtmlSymbols.HEAD);
+
+ xs.startTag(null, HtmlSymbols.BODY);
+ xs.startTag(null, HtmlSymbols.HEADING);
+ xs.text(HTML_TITLE);
+ xs.endTag(null, HtmlSymbols.HEADING);
+ xs.startTag(null, HtmlSymbols.ORDERED_LIST);
+ for (Feed feed : feeds) {
+ xs.startTag(null, HtmlSymbols.LIST_ITEM);
+ xs.text(feed.getTitle());
+ if (!TextUtils.isEmpty(feed.getLink())) {
+ xs.text(" [");
+ xs.startTag(null, HtmlSymbols.LINK);
+ xs.attribute(null, HtmlSymbols.LINK_DESTINATION, feed.getLink());
+ xs.text("Website");
+ xs.endTag(null, HtmlSymbols.LINK);
+ xs.text("]");
+ }
+ xs.text(" [");
+ xs.startTag(null, HtmlSymbols.LINK);
+ xs.attribute(null, HtmlSymbols.LINK_DESTINATION, feed.getDownload_url());
+ xs.text("Feed");
+ xs.endTag(null, HtmlSymbols.LINK);
+ xs.text("]");
+ xs.endTag(null, HtmlSymbols.LIST_ITEM);
+ }
+ xs.endTag(null, HtmlSymbols.ORDERED_LIST);
+ xs.endTag(null, HtmlSymbols.BODY);
+ xs.endTag(null, HtmlSymbols.HTML);
+ xs.endDocument();
+ Log.d(TAG, "Finished writing document");
+ }
+
+ public String fileExtension() {
+ return "html";
+ }
+
+}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/opml/OpmlElement.java b/core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlElement.java
index 8d0a4a842..61eb4d0c9 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/opml/OpmlElement.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlElement.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.core.opml;
+package de.danoeh.antennapod.core.export.opml;
/** Represents a single feed in an OPML file. */
public class OpmlElement {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/opml/OpmlReader.java b/core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlReader.java
index 17afc7904..a17fedd7d 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/opml/OpmlReader.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlReader.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.core.opml;
+package de.danoeh.antennapod.core.export.opml;
import android.util.Log;
diff --git a/core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlSymbols.java b/core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlSymbols.java
new file mode 100644
index 000000000..40b0e23b8
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlSymbols.java
@@ -0,0 +1,21 @@
+package de.danoeh.antennapod.core.export.opml;
+
+import de.danoeh.antennapod.core.export.CommonSymbols;
+
+/** Contains symbols for reading and writing OPML documents. */
+public final class OpmlSymbols extends CommonSymbols {
+
+ public static final String OPML = "opml";
+ static final String OUTLINE = "outline";
+ static final String TEXT = "text";
+ static final String XMLURL = "xmlUrl";
+ static final String HTMLURL = "htmlUrl";
+ static final String TYPE = "type";
+ static final String VERSION = "version";
+ static final String DATE_CREATED = "dateCreated";
+
+ private OpmlSymbols() {
+
+ }
+
+}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/opml/OpmlWriter.java b/core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlWriter.java
index 673c602df..fd0922f72 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/opml/OpmlWriter.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlWriter.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.core.opml;
+package de.danoeh.antennapod.core.export.opml;
import android.util.Log;
import android.util.Xml;
@@ -10,11 +10,13 @@ import java.io.Writer;
import java.util.Date;
import java.util.List;
+import de.danoeh.antennapod.core.export.ExportWriter;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.util.DateUtils;
/** Writes OPML documents. */
-public class OpmlWriter {
+public class OpmlWriter implements ExportWriter {
+
private static final String TAG = "OpmlWriter";
private static final String ENCODING = "UTF-8";
private static final String OPML_VERSION = "2.0";
@@ -28,40 +30,29 @@ public class OpmlWriter {
* @throws IllegalStateException
* @throws IllegalArgumentException
*/
+ @Override
public void writeDocument(List<Feed> feeds, Writer writer)
throws IllegalArgumentException, IllegalStateException, IOException {
Log.d(TAG, "Starting to write document");
XmlSerializer xs = Xml.newSerializer();
+ xs.setFeature(OpmlSymbols.XML_FEATURE_INDENT_OUTPUT, true);
xs.setOutput(writer);
xs.startDocument(ENCODING, false);
- xs.text("\n");
xs.startTag(null, OpmlSymbols.OPML);
xs.attribute(null, OpmlSymbols.VERSION, OPML_VERSION);
- xs.text("\n");
- xs.text(" ");
xs.startTag(null, OpmlSymbols.HEAD);
- xs.text("\n");
- xs.text(" ");
xs.startTag(null, OpmlSymbols.TITLE);
xs.text(OPML_TITLE);
xs.endTag(null, OpmlSymbols.TITLE);
- xs.text("\n");
- xs.text(" ");
xs.startTag(null, OpmlSymbols.DATE_CREATED);
xs.text(DateUtils.formatRFC822Date(new Date()));
xs.endTag(null, OpmlSymbols.DATE_CREATED);
- xs.text("\n");
- xs.text(" ");
xs.endTag(null, OpmlSymbols.HEAD);
- xs.text("\n");
- xs.text(" ");
xs.startTag(null, OpmlSymbols.BODY);
- xs.text("\n");
for (Feed feed : feeds) {
- xs.text(" ");
xs.startTag(null, OpmlSymbols.OUTLINE);
xs.attribute(null, OpmlSymbols.TEXT, feed.getTitle());
xs.attribute(null, OpmlSymbols.TITLE, feed.getTitle());
@@ -73,14 +64,15 @@ public class OpmlWriter {
xs.attribute(null, OpmlSymbols.HTMLURL, feed.getLink());
}
xs.endTag(null, OpmlSymbols.OUTLINE);
- xs.text("\n");
}
- xs.text(" ");
xs.endTag(null, OpmlSymbols.BODY);
- xs.text("\n");
xs.endTag(null, OpmlSymbols.OPML);
- xs.text("\n");
xs.endDocument();
Log.d(TAG, "Finished writing document");
}
+
+ public String fileExtension() {
+ return "opml";
+ }
+
}
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 bb0724d66..ac23f3d3d 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
@@ -26,7 +26,11 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource {
public static final String TYPE_RSS091 = "rss";
public static final String TYPE_ATOM1 = "atom";
- private String title;
+ /* title as defined by the feed */
+ private String feedTitle;
+ /* custom title set by the user */
+ private String customTitle;
+
/**
* Contains 'id'-element in Atom feed.
*/
@@ -92,13 +96,14 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource {
/**
* This constructor is used for restoring a feed from the database.
*/
- public Feed(long id, String lastUpdate, String title, String link, String description, String paymentLink,
+ public Feed(long id, String lastUpdate, String title, String customTitle, String link, String description, String paymentLink,
String author, String language, String type, String feedIdentifier, FeedImage image, String fileUrl,
String downloadUrl, boolean downloaded, FlattrStatus status, boolean paged, String nextPageLink,
String filter, boolean lastUpdateFailed) {
super(fileUrl, downloadUrl, downloaded);
this.id = id;
- this.title = title;
+ this.feedTitle = title;
+ this.customTitle = customTitle;
this.lastUpdate = lastUpdate;
this.link = link;
this.description = description;
@@ -126,7 +131,7 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource {
public Feed(long id, String lastUpdate, String title, String link, String description, String paymentLink,
String author, String language, String type, String feedIdentifier, FeedImage image, String fileUrl,
String downloadUrl, boolean downloaded) {
- this(id, lastUpdate, title, link, description, paymentLink, author, language, type, feedIdentifier, image,
+ this(id, lastUpdate, title, null, link, description, paymentLink, author, language, type, feedIdentifier, image,
fileUrl, downloadUrl, downloaded, new FlattrStatus(), false, null, null, false);
}
@@ -154,7 +159,7 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource {
*/
public Feed(String url, String lastUpdate, String title) {
this(url, lastUpdate);
- this.title = title;
+ this.feedTitle = title;
this.flattrStatus = new FlattrStatus();
}
@@ -171,6 +176,7 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource {
int indexId = cursor.getColumnIndex(PodDBAdapter.KEY_ID);
int indexLastUpdate = cursor.getColumnIndex(PodDBAdapter.KEY_LASTUPDATE);
int indexTitle = cursor.getColumnIndex(PodDBAdapter.KEY_TITLE);
+ int indexCustomTitle = cursor.getColumnIndex(PodDBAdapter.KEY_CUSTOM_TITLE);
int indexLink = cursor.getColumnIndex(PodDBAdapter.KEY_LINK);
int indexDescription = cursor.getColumnIndex(PodDBAdapter.KEY_DESCRIPTION);
int indexPaymentLink = cursor.getColumnIndex(PodDBAdapter.KEY_PAYMENT_LINK);
@@ -191,6 +197,7 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource {
cursor.getLong(indexId),
cursor.getString(indexLastUpdate),
cursor.getString(indexTitle),
+ cursor.getString(indexCustomTitle),
cursor.getString(indexLink),
cursor.getString(indexDescription),
cursor.getString(indexPaymentLink),
@@ -268,8 +275,8 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource {
return feedIdentifier;
} else if (download_url != null && !download_url.isEmpty()) {
return download_url;
- } else if (title != null && !title.isEmpty()) {
- return title;
+ } else if (feedTitle != null && !feedTitle.isEmpty()) {
+ return feedTitle;
} else {
return link;
}
@@ -277,8 +284,8 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource {
@Override
public String getHumanReadableIdentifier() {
- if (title != null) {
- return title;
+ if (feedTitle != null) {
+ return feedTitle;
} else {
return download_url;
}
@@ -287,8 +294,8 @@ 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.title != null) {
- title = other.title;
+ if (other.feedTitle != null) {
+ feedTitle = other.feedTitle;
}
if (other.feedIdentifier != null) {
feedIdentifier = other.feedIdentifier;
@@ -323,7 +330,7 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource {
if (super.compareWithOther(other)) {
return true;
}
- if (!TextUtils.equals(title, other.title)) {
+ if (!TextUtils.equals(feedTitle, other.feedTitle)) {
return true;
}
if (other.feedIdentifier != null) {
@@ -384,11 +391,28 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource {
}
public String getTitle() {
- return title;
+ return !TextUtils.isEmpty(customTitle) ? customTitle : feedTitle;
}
public void setTitle(String title) {
- this.title = title;
+ this.feedTitle = title;
+ }
+
+ public String getFeedTitle() {
+ return this.feedTitle;
+ }
+
+ @Nullable
+ public String getCustomTitle() {
+ return this.customTitle;
+ }
+
+ public void setCustomTitle(String customTitle) {
+ if(customTitle == null || customTitle.equals(feedTitle)) {
+ this.customTitle = null;
+ } else {
+ this.customTitle = customTitle;
+ }
}
public String getLink() {
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 2481645e0..ee7a738d0 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
@@ -1,6 +1,7 @@
package de.danoeh.antennapod.core.feed;
import android.database.Cursor;
+import android.support.annotation.Nullable;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
@@ -269,6 +270,7 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr
}
}
+ @Nullable
public FeedMedia getMedia() {
return media;
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItemFilter.java b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItemFilter.java
index 9d8f4adf8..200153876 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItemFilter.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItemFilter.java
@@ -18,6 +18,7 @@ public class FeedItemFilter {
private boolean showNotQueued = false;
private boolean showDownloaded = false;
private boolean showNotDownloaded = false;
+ private boolean showHasMedia = false;
public FeedItemFilter(String properties) {
this(TextUtils.split(properties, ","));
@@ -49,6 +50,9 @@ public class FeedItemFilter {
case "not_downloaded":
showNotDownloaded = true;
break;
+ case "has_media":
+ showHasMedia = true;
+ break;
}
}
}
@@ -82,6 +86,8 @@ public class FeedItemFilter {
if (showDownloaded && !downloaded) continue;
if (showNotDownloaded && downloaded) continue;
+ if (showHasMedia && !item.hasMedia()) continue;
+
// If the item reaches here, it meets all criteria
result.add(item);
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/glide/ApOkHttpUrlLoader.java b/core/src/main/java/de/danoeh/antennapod/core/glide/ApOkHttpUrlLoader.java
index 762e92286..8ca9faa0d 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/glide/ApOkHttpUrlLoader.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/glide/ApOkHttpUrlLoader.java
@@ -4,15 +4,12 @@ import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
-import com.bumptech.glide.integration.okhttp.OkHttpStreamFetcher;
+import com.bumptech.glide.integration.okhttp3.OkHttpStreamFetcher;
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.model.GenericLoaderFactory;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.load.model.ModelLoader;
import com.bumptech.glide.load.model.ModelLoaderFactory;
-import com.squareup.okhttp.Interceptor;
-import com.squareup.okhttp.OkHttpClient;
-import com.squareup.okhttp.Response;
import java.io.IOException;
import java.io.InputStream;
@@ -22,9 +19,13 @@ import de.danoeh.antennapod.core.service.download.AntennapodHttpClient;
import de.danoeh.antennapod.core.service.download.HttpDownloader;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.util.NetworkUtils;
+import okhttp3.Interceptor;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
/**
- * @see com.bumptech.glide.integration.okhttp.OkHttpUrlLoader
+ * @see com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader
*/
public class ApOkHttpUrlLoader implements ModelLoader<String, InputStream> {
@@ -42,9 +43,10 @@ public class ApOkHttpUrlLoader implements ModelLoader<String, InputStream> {
if (internalClient == null) {
synchronized (Factory.class) {
if (internalClient == null) {
- internalClient = AntennapodHttpClient.newHttpClient();
- internalClient.interceptors().add(new NetworkAllowanceInterceptor());
- internalClient.interceptors().add(new BasicAuthenticationInterceptor());
+ OkHttpClient.Builder builder = AntennapodHttpClient.newBuilder();
+ builder.interceptors().add(new NetworkAllowanceInterceptor());
+ builder.interceptors().add(new BasicAuthenticationInterceptor());
+ internalClient = builder.build();
}
}
}
@@ -113,8 +115,8 @@ public class ApOkHttpUrlLoader implements ModelLoader<String, InputStream> {
@Override
public Response intercept(Chain chain) throws IOException {
- com.squareup.okhttp.Request request = chain.request();
- String url = request.urlString();
+ Request request = chain.request();
+ String url = request.url().toString();
String authentication = DBReader.getImageAuthentication(url);
if(TextUtils.isEmpty(authentication)) {
@@ -125,7 +127,7 @@ public class ApOkHttpUrlLoader implements ModelLoader<String, InputStream> {
// add authentication
String[] auth = authentication.split(":");
String credentials = HttpDownloader.encodeCredentials(auth[0], auth[1], "ISO-8859-1");
- com.squareup.okhttp.Request newRequest = request
+ Request newRequest = request
.newBuilder()
.addHeader("Authorization", credentials)
.build();
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 9f716e546..0218b103a 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
@@ -1,15 +1,6 @@
package de.danoeh.antennapod.core.gpoddernet;
import android.support.annotation.NonNull;
-
-import com.squareup.okhttp.Credentials;
-import com.squareup.okhttp.MediaType;
-import com.squareup.okhttp.OkHttpClient;
-import com.squareup.okhttp.Request;
-import com.squareup.okhttp.RequestBody;
-import com.squareup.okhttp.Response;
-import com.squareup.okhttp.ResponseBody;
-
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -38,6 +29,13 @@ import de.danoeh.antennapod.core.gpoddernet.model.GpodnetTag;
import de.danoeh.antennapod.core.gpoddernet.model.GpodnetUploadChangesResponse;
import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
import de.danoeh.antennapod.core.service.download.AntennapodHttpClient;
+import okhttp3.Credentials;
+import okhttp3.MediaType;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import okhttp3.Response;
+import okhttp3.ResponseBody;
/**
* Communicates with the gpodder.net service.
@@ -570,15 +568,7 @@ public class GpodnetService {
e.printStackTrace();
throw new GpodnetServiceException(e);
} finally {
- if (response != null && body != null) {
- try {
- body.close();
- } catch (IOException e) {
- e.printStackTrace();
- throw new GpodnetServiceException(e);
- }
- }
-
+ body.close();
}
return responseString;
}
@@ -605,12 +595,7 @@ public class GpodnetService {
throw new GpodnetServiceException(e);
} finally {
if (body != null) {
- try {
- body.close();
- } catch (IOException e) {
- e.printStackTrace();
- throw new GpodnetServiceException(e);
- }
+ body.close();
}
}
return result;
@@ -619,12 +604,7 @@ public class GpodnetService {
private String getStringFromResponseBody(@NonNull ResponseBody body)
throws GpodnetServiceException {
ByteArrayOutputStream outputStream;
- int contentLength = 0;
- try {
- contentLength = (int) body.contentLength();
- } catch (IOException ignore) {
- // ignore
- }
+ int contentLength = (int) body.contentLength();
if (contentLength > 0) {
outputStream = new ByteArrayOutputStream(contentLength);
} else {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/opml/OpmlSymbols.java b/core/src/main/java/de/danoeh/antennapod/core/opml/OpmlSymbols.java
deleted file mode 100644
index c973713cb..000000000
--- a/core/src/main/java/de/danoeh/antennapod/core/opml/OpmlSymbols.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package de.danoeh.antennapod.core.opml;
-
-/** Contains symbols for reading and writing OPML documents. */
-public final class OpmlSymbols {
-
- public static final String OPML = "opml";
- public static final String BODY = "body";
- public static final String OUTLINE = "outline";
- public static final String TEXT = "text";
- public static final String XMLURL = "xmlUrl";
- public static final String HTMLURL = "htmlUrl";
- public static final String TYPE = "type";
- public static final String VERSION = "version";
- public static final String HEAD = "head";
- public static final String TITLE = "title";
- public static final String DATE_CREATED = "dateCreated";
-
- private OpmlSymbols() {
-
- }
-
-}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/preferences/SleepTimerPreferences.java b/core/src/main/java/de/danoeh/antennapod/core/preferences/SleepTimerPreferences.java
new file mode 100644
index 000000000..b7ed890f5
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/preferences/SleepTimerPreferences.java
@@ -0,0 +1,80 @@
+package de.danoeh.antennapod.core.preferences;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.support.annotation.NonNull;
+import android.util.Log;
+
+import java.util.concurrent.TimeUnit;
+
+public class SleepTimerPreferences {
+
+ private static final String TAG = "SleepTimerPreferences";
+
+ private static final String PREF_NAME = "SleepTimerDialog";
+ private static final String PREF_VALUE = "LastValue";
+ private static final String PREF_TIME_UNIT = "LastTimeUnit";
+ private static final String PREF_VIBRATE = "Vibrate";
+ private static final String PREF_SHAKE_TO_RESET = "ShakeToReset";
+ private static final String PREF_AUTO_ENABLE = "AutoEnable";
+
+ private static final TimeUnit[] UNITS = { TimeUnit.SECONDS, TimeUnit.MINUTES, TimeUnit.HOURS };
+
+ private static final String DEFAULT_VALUE = "15";
+ private static final int DEFAULT_TIME_UNIT = 1;
+
+ private static Context context;
+ private static SharedPreferences prefs;
+
+ /**
+ * Sets up the UserPreferences class.
+ *
+ * @throws IllegalArgumentException if context is null
+ */
+ public static void init(@NonNull Context context) {
+ Log.d(TAG, "Creating new instance of SleepTimerPreferences");
+ SleepTimerPreferences.prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
+ }
+
+ public static void setLastTimer(String value, int timeUnit) {
+ prefs.edit().putString(PREF_VALUE, value).putInt(PREF_TIME_UNIT, timeUnit).apply();
+ }
+
+ public static String lastTimerValue() {
+ return prefs.getString(PREF_VALUE, DEFAULT_VALUE);
+ }
+
+ public static int lastTimerTimeUnit() {
+ return prefs.getInt(PREF_TIME_UNIT, DEFAULT_TIME_UNIT);
+ }
+
+ public static long timerMillis() {
+ long value = Long.parseLong(lastTimerValue());
+ return UNITS[lastTimerTimeUnit()].toMillis(value);
+ }
+
+ public static void setVibrate(boolean vibrate) {
+ prefs.edit().putBoolean(PREF_VIBRATE, vibrate).apply();
+ }
+
+ public static boolean vibrate() {
+ return prefs.getBoolean(PREF_VIBRATE, true);
+ }
+
+ public static void setShakeToReset(boolean shakeToReset) {
+ prefs.edit().putBoolean(PREF_SHAKE_TO_RESET, shakeToReset).apply();
+ }
+
+ public static boolean shakeToReset() {
+ return prefs.getBoolean(PREF_SHAKE_TO_RESET, true);
+ }
+
+ public static void setAutoEnable(boolean autoEnable) {
+ prefs.edit().putBoolean(PREF_AUTO_ENABLE, autoEnable).apply();
+ }
+
+ public static boolean autoEnable() {
+ return prefs.getBoolean(PREF_AUTO_ENABLE, false);
+ }
+
+}
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 04b06d148..016b6c446 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
@@ -56,7 +56,6 @@ public class UserPreferences {
public static final String PREF_LOCKSCREEN_BACKGROUND = "prefLockscreenBackground";
public static final String PREF_SHOW_DOWNLOAD_REPORT = "prefShowDownloadReport";
-
// Queue
public static final String PREF_QUEUE_ADD_TO_FRONT = "prefQueueAddToFront";
@@ -65,6 +64,7 @@ public class UserPreferences {
public static final String PREF_UNPAUSE_ON_HEADSET_RECONNECT = "prefUnpauseOnHeadsetReconnect";
public static final String PREF_UNPAUSE_ON_BLUETOOTH_RECONNECT = "prefUnpauseOnBluetoothReconnect";
public static final String PREF_HARDWARE_FOWARD_BUTTON_SKIPS = "prefHardwareForwardButtonSkips";
+ public static final String PREF_HARDWARE_PREVIOUS_BUTTON_RESTARTS = "prefHardwarePreviousButtonRestarts";
public static final String PREF_FOLLOW_QUEUE = "prefFollowQueue";
public static final String PREF_SKIP_KEEPS_EPISODE = "prefSkipKeepsEpisode";
public static final String PREF_AUTO_DELETE = "prefAutoDelete";
@@ -74,6 +74,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";
@@ -122,13 +123,14 @@ public class UserPreferences {
private static final int NOTIFICATION_BUTTON_FAST_FORWARD = 1;
private static final int NOTIFICATION_BUTTON_SKIP = 2;
private static int EPISODE_CACHE_SIZE_UNLIMITED = -1;
- public static int FEED_ORDER_COUNTER = 0;
- public static int FEED_ORDER_ALPHABETICAL = 1;
- public static int FEED_ORDER_LAST_UPDATE = 2;
- public static int FEED_COUNTER_SHOW_NEW_UNPLAYED_SUM = 0;
- public static int FEED_COUNTER_SHOW_NEW = 1;
- public static int FEED_COUNTER_SHOW_UNPLAYED = 2;
- public static int FEED_COUNTER_SHOW_NONE = 3;
+ 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_COUNTER_SHOW_NEW_UNPLAYED_SUM = 0;
+ public static final int FEED_COUNTER_SHOW_NEW = 1;
+ public static final int FEED_COUNTER_SHOW_UNPLAYED = 2;
+ public static final int FEED_COUNTER_SHOW_NONE = 3;
+ public static final int FEED_COUNTER_SHOW_DOWNLOADED = 4;
private static Context context;
private static SharedPreferences prefs;
@@ -257,11 +259,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);
}
@@ -282,6 +283,10 @@ public class UserPreferences {
return prefs.getBoolean(PREF_HARDWARE_FOWARD_BUTTON_SKIPS, false);
}
+ public static boolean shouldHardwarePreviousButtonRestart() {
+ return prefs.getBoolean(PREF_HARDWARE_PREVIOUS_BUTTON_RESTARTS, false);
+ }
+
public static boolean isFollowQueue() {
return prefs.getBoolean(PREF_FOLLOW_QUEUE, true);
@@ -332,7 +337,10 @@ public class UserPreferences {
}
-
+ /*
+ * Returns update interval in milliseconds; value 0 means that auto update is disabled
+ * or feeds are updated at a certain time of day
+ */
public static long getUpdateInterval() {
String updateInterval = prefs.getString(PREF_UPDATE_INTERVAL, "0");
if(!updateInterval.contains(":")) {
@@ -754,12 +762,12 @@ public class UserPreferences {
if (timeOfDay.length == 2) {
restartUpdateTimeOfDayAlarm(timeOfDay[0], timeOfDay[1]);
} else {
- long hours = getUpdateInterval();
- long startTrigger = hours;
+ long milliseconds = getUpdateInterval();
+ long startTrigger = milliseconds;
if (now) {
startTrigger = TimeUnit.SECONDS.toMillis(10);
}
- restartUpdateIntervalAlarm(startTrigger, hours);
+ restartUpdateIntervalAlarm(startTrigger, milliseconds);
}
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/AntennapodHttpClient.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/AntennapodHttpClient.java
index 5dd1e2dfa..eb28050f0 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/download/AntennapodHttpClient.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/AntennapodHttpClient.java
@@ -5,12 +5,6 @@ import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;
-import com.squareup.okhttp.Credentials;
-import com.squareup.okhttp.OkHttpClient;
-import com.squareup.okhttp.Request;
-import com.squareup.okhttp.Response;
-import com.squareup.okhttp.internal.http.StatusLine;
-
import java.io.IOException;
import java.net.CookieManager;
import java.net.CookiePolicy;
@@ -20,16 +14,27 @@ import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Socket;
import java.net.SocketAddress;
-import java.net.URL;
import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBWriter;
+import okhttp3.Credentials;
+import okhttp3.HttpUrl;
+import okhttp3.JavaNetCookieJar;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+import okhttp3.internal.http.StatusLine;
/**
* Provides access to a HttpClient singleton.
@@ -50,13 +55,13 @@ public class AntennapodHttpClient {
*/
public static synchronized OkHttpClient getHttpClient() {
if (httpClient == null) {
- httpClient = newHttpClient();
+ httpClient = newBuilder().build();
}
return httpClient;
}
public static synchronized void reinit() {
- httpClient = newHttpClient();
+ httpClient = newBuilder().build();
}
/**
@@ -67,33 +72,33 @@ public class AntennapodHttpClient {
* @return http client
*/
@NonNull
- public static OkHttpClient newHttpClient() {
+ public static OkHttpClient.Builder newBuilder() {
Log.d(TAG, "Creating new instance of HTTP client");
System.setProperty("http.maxConnections", String.valueOf(MAX_CONNECTIONS));
- OkHttpClient client = new OkHttpClient();
+ OkHttpClient.Builder builder = new OkHttpClient.Builder();
// detect 301 Moved permanently and 308 Permanent Redirect
- client.networkInterceptors().add(chain -> {
+ builder.networkInterceptors().add(chain -> {
Request request = chain.request();
Response response = chain.proceed(request);
if (response.code() == HttpURLConnection.HTTP_MOVED_PERM ||
response.code() == StatusLine.HTTP_PERM_REDIRECT) {
String location = response.header("Location");
if (location.startsWith("/")) { // URL is not absolute, but relative
- URL url = request.url();
- location = url.getProtocol() + "://" + url.getHost() + location;
+ HttpUrl url = request.url();
+ location = url.scheme() + "://" + url.host() + location;
} else if (!location.toLowerCase().startsWith("http://") &&
!location.toLowerCase().startsWith("https://")) {
// Reference is relative to current path
- URL url = request.url();
- String path = url.getPath();
+ HttpUrl url = request.url();
+ String path = url.encodedPath();
String newPath = path.substring(0, path.lastIndexOf("/") + 1) + location;
- location = url.getProtocol() + "://" + url.getHost() + newPath;
+ location = url.scheme() + "://" + url.host() + newPath;
}
try {
- DBWriter.updateFeedDownloadURL(request.urlString(), location).get();
+ DBWriter.updateFeedDownloadURL(request.url().toString(), location).get();
} catch (Exception e) {
Log.e(TAG, Log.getStackTraceString(e));
}
@@ -104,26 +109,26 @@ public class AntennapodHttpClient {
// set cookie handler
CookieManager cm = new CookieManager();
cm.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER);
- client.setCookieHandler(cm);
+ builder.cookieJar(new JavaNetCookieJar(cm));
// set timeouts
- client.setConnectTimeout(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS);
- client.setReadTimeout(READ_TIMEOUT, TimeUnit.MILLISECONDS);
- client.setWriteTimeout(READ_TIMEOUT, TimeUnit.MILLISECONDS);
+ builder.connectTimeout(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS);
+ builder.readTimeout(READ_TIMEOUT, TimeUnit.MILLISECONDS);
+ builder.writeTimeout(READ_TIMEOUT, TimeUnit.MILLISECONDS);
// configure redirects
- client.setFollowRedirects(true);
- client.setFollowSslRedirects(true);
+ builder.followRedirects(true);
+ builder.followSslRedirects(true);
ProxyConfig config = UserPreferences.getProxyConfig();
if (config.type != Proxy.Type.DIRECT) {
int port = config.port > 0 ? config.port : ProxyConfig.DEFAULT_PORT;
SocketAddress address = InetSocketAddress.createUnresolved(config.host, port);
Proxy proxy = new Proxy(config.type, address);
- client.setProxy(proxy);
+ builder.proxy(proxy);
if (!TextUtils.isEmpty(config.username)) {
String credentials = Credentials.basic(config.username, config.password);
- client.interceptors().add(chain -> {
+ builder.interceptors().add(chain -> {
Request request = chain.request().newBuilder()
.header("Proxy-Authorization", credentials).build();
return chain.proceed(request);
@@ -131,9 +136,9 @@ public class AntennapodHttpClient {
}
}
if(16 <= Build.VERSION.SDK_INT && Build.VERSION.SDK_INT < 21) {
- client.setSslSocketFactory(new CustomSslSocketFactory());
+ builder.sslSocketFactory(new CustomSslSocketFactory(), trustManager());
}
- return client;
+ return builder;
}
/**
@@ -146,6 +151,23 @@ public class AntennapodHttpClient {
}
}
+ private static X509TrustManager trustManager() {
+ try {
+ TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
+ TrustManagerFactory.getDefaultAlgorithm());
+ trustManagerFactory.init((KeyStore) null);
+ TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
+ if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
+ throw new IllegalStateException("Unexpected default trust managers:"
+ + Arrays.toString(trustManagers));
+ }
+ return (X509TrustManager) trustManagers[0];
+ } catch (Exception e) {
+ Log.e(TAG, Log.getStackTraceString(e));
+ return null;
+ }
+ }
+
private static class CustomSslSocketFactory extends SSLSocketFactory {
private SSLSocketFactory factory;
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..9ac459394 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
@@ -842,11 +842,14 @@ 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);
@@ -1048,7 +1051,8 @@ public class DownloadService extends Service {
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) {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java
index 99456b756..b409a419a 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java
@@ -2,21 +2,7 @@ package de.danoeh.antennapod.core.service.download;
import android.text.TextUtils;
import android.util.Log;
-import com.squareup.okhttp.Interceptor;
-import com.squareup.okhttp.OkHttpClient;
-import com.squareup.okhttp.Protocol;
-import com.squareup.okhttp.Request;
-import com.squareup.okhttp.Response;
-import com.squareup.okhttp.ResponseBody;
-import de.danoeh.antennapod.core.ClientConfig;
-import de.danoeh.antennapod.core.R;
-import de.danoeh.antennapod.core.feed.FeedImage;
-import de.danoeh.antennapod.core.feed.FeedMedia;
-import de.danoeh.antennapod.core.util.DateUtils;
-import de.danoeh.antennapod.core.util.DownloadError;
-import de.danoeh.antennapod.core.util.StorageUtils;
-import de.danoeh.antennapod.core.util.URIUtil;
-import okio.ByteString;
+
import org.apache.commons.io.IOUtils;
import java.io.BufferedInputStream;
@@ -32,6 +18,22 @@ import java.net.UnknownHostException;
import java.util.Collections;
import java.util.Date;
+import de.danoeh.antennapod.core.ClientConfig;
+import de.danoeh.antennapod.core.R;
+import de.danoeh.antennapod.core.feed.FeedImage;
+import de.danoeh.antennapod.core.feed.FeedMedia;
+import de.danoeh.antennapod.core.util.DateUtils;
+import de.danoeh.antennapod.core.util.DownloadError;
+import de.danoeh.antennapod.core.util.StorageUtils;
+import de.danoeh.antennapod.core.util.URIUtil;
+import okhttp3.Interceptor;
+import okhttp3.OkHttpClient;
+import okhttp3.Protocol;
+import okhttp3.Request;
+import okhttp3.Response;
+import okhttp3.ResponseBody;
+import okio.ByteString;
+
public class HttpDownloader extends Downloader {
private static final String TAG = "HttpDownloader";
@@ -57,8 +59,9 @@ public class HttpDownloader extends Downloader {
}
}
- OkHttpClient httpClient = AntennapodHttpClient.newHttpClient();
- httpClient.interceptors().add(new BasicAuthorizationInterceptor(request));
+ OkHttpClient.Builder httpClientBuilder = AntennapodHttpClient.newBuilder();
+ httpClientBuilder.interceptors().add(new BasicAuthorizationInterceptor(request));
+ OkHttpClient httpClient = httpClientBuilder.build();
RandomAccessFile out = null;
InputStream connection;
ResponseBody responseBody = null;
@@ -103,7 +106,9 @@ public class HttpDownloader extends Downloader {
} catch (IOException e) {
Log.e(TAG, e.toString());
if (e.getMessage().contains("PROTOCOL_ERROR")) {
- httpClient.setProtocols(Collections.singletonList(Protocol.HTTP_1_1));
+ httpClient = httpClient.newBuilder()
+ .protocols(Collections.singletonList(Protocol.HTTP_1_1))
+ .build();
response = httpClient.newCall(httpReq.build()).execute();
} else {
throw e;
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 0871758d0..f395dfb32 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
@@ -146,7 +146,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
if (!media.getIdentifier().equals(playable.getIdentifier())) {
final Playable oldMedia = media;
- executor.submit(() -> callback.onPostPlayback(oldMedia, false, true));
+ executor.submit(() -> callback.onPostPlayback(oldMedia, false, false, true));
}
setPlayerStatus(PlayerStatus.INDETERMINATE, null);
@@ -383,6 +383,9 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
statusBeforeSeeking = playerStatus;
setPlayerStatus(PlayerStatus.SEEKING, media, getPosition());
mediaPlayer.seekTo(t);
+ if (statusBeforeSeeking == PlayerStatus.PREPARED) {
+ media.setPosition(t);
+ }
try {
seekLatch.await(3, TimeUnit.SECONDS);
} catch (InterruptedException e) {
@@ -755,7 +758,8 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
@Override
- protected Future<?> endPlayback(final boolean wasSkipped, final boolean shouldContinue, final boolean toStoppedState) {
+ protected Future<?> endPlayback(final boolean hasEnded, final boolean wasSkipped,
+ final boolean shouldContinue, final boolean toStoppedState) {
return executor.submit(() -> {
playerLock.lock();
releaseWifiLockIfNecessary();
@@ -813,7 +817,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
}
final boolean hasNext = nextMedia != null;
- executor.submit(() -> callback.onPostPlayback(currentMedia, !wasSkipped, hasNext));
+ executor.submit(() -> callback.onPostPlayback(currentMedia, hasEnded, wasSkipped, hasNext));
} else if (isPlaying) {
callback.onPlaybackPause(currentMedia, currentMedia.getPosition());
}
@@ -848,27 +852,24 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
}
private IPlayer setMediaPlayerListeners(IPlayer mp) {
- if (mp != null && media != null) {
- if (media.getMediaType() == MediaType.AUDIO) {
- ((AudioPlayer) mp)
- .setOnCompletionListener(audioCompletionListener);
- ((AudioPlayer) mp)
- .setOnSeekCompleteListener(audioSeekCompleteListener);
- ((AudioPlayer) mp).setOnErrorListener(audioErrorListener);
- ((AudioPlayer) mp)
- .setOnBufferingUpdateListener(audioBufferingUpdateListener);
- ((AudioPlayer) mp).setOnInfoListener(audioInfoListener);
- ((AudioPlayer) mp).setOnSpeedAdjustmentAvailableChangedListener(audioSetSpeedAbilityListener);
- } else {
- ((VideoPlayer) mp)
- .setOnCompletionListener(videoCompletionListener);
- ((VideoPlayer) mp)
- .setOnSeekCompleteListener(videoSeekCompleteListener);
- ((VideoPlayer) mp).setOnErrorListener(videoErrorListener);
- ((VideoPlayer) mp)
- .setOnBufferingUpdateListener(videoBufferingUpdateListener);
- ((VideoPlayer) mp).setOnInfoListener(videoInfoListener);
- }
+ if (mp == null || media == null) {
+ return mp;
+ }
+ if (media.getMediaType() == MediaType.VIDEO) {
+ VideoPlayer vp = (VideoPlayer) mp;
+ vp.setOnCompletionListener(videoCompletionListener);
+ vp.setOnSeekCompleteListener(videoSeekCompleteListener);
+ vp.setOnErrorListener(videoErrorListener);
+ vp.setOnBufferingUpdateListener(videoBufferingUpdateListener);
+ vp.setOnInfoListener(videoInfoListener);
+ } else {
+ AudioPlayer ap = (AudioPlayer) mp;
+ ap.setOnCompletionListener(audioCompletionListener);
+ ap.setOnSeekCompleteListener(audioSeekCompleteListener);
+ ap.setOnErrorListener(audioErrorListener);
+ ap.setOnBufferingUpdateListener(audioBufferingUpdateListener);
+ ap.setOnInfoListener(audioInfoListener);
+ ap.setOnSpeedAdjustmentAvailableChangedListener(audioSetSpeedAbilityListener);
}
return mp;
}
@@ -880,7 +881,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
mp -> genericOnCompletion();
private void genericOnCompletion() {
- endPlayback(false, true, true);
+ endPlayback(true, false, true, true);
}
private final MediaPlayer.OnBufferingUpdateListener audioBufferingUpdateListener =
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 f425d7181..ebab2cbec 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
@@ -47,12 +47,14 @@ import java.util.List;
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.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.feed.MediaType;
import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
+import de.danoeh.antennapod.core.preferences.SleepTimerPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.receiver.MediaButtonReceiver;
import de.danoeh.antennapod.core.storage.DBReader;
@@ -62,6 +64,7 @@ import de.danoeh.antennapod.core.util.IntList;
import de.danoeh.antennapod.core.util.QueueAccess;
import de.danoeh.antennapod.core.util.playback.ExternalMedia;
import de.danoeh.antennapod.core.util.playback.Playable;
+import de.greenrobot.event.EventBus;
/**
* Controls the MediaPlayer that plays a FeedMedia-file
@@ -298,7 +301,10 @@ public class PlaybackService extends MediaBrowserServiceCompat {
List<MediaSessionCompat.QueueItem> queueItems = new ArrayList<>();
try {
for (FeedItem feedItem : taskManager.getQueue()) {
- queueItems.add(new MediaSessionCompat.QueueItem(feedItem.getMedia().getMediaItem().getDescription(), feedItem.getId()));
+ if(feedItem.getMedia() != null) {
+ MediaDescriptionCompat mediaDescription = feedItem.getMedia().getMediaItem().getDescription();
+ queueItems.add(new MediaSessionCompat.QueueItem(mediaDescription, feedItem.getId()));
+ }
}
mediaSession.setQueue(queueItems);
} catch (InterruptedException e) {
@@ -478,6 +484,14 @@ public class PlaybackService extends MediaBrowserServiceCompat {
mediaPlayer.seekDelta(UserPreferences.getFastForwardSecs() * 1000);
break;
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
+ if(UserPreferences.shouldHardwarePreviousButtonRestart()) {
+ // user wants to restart current episode
+ mediaPlayer.seekTo(0);
+ } else {
+ // user wants to rewind current episode
+ mediaPlayer.seekDelta(-UserPreferences.getRewindSecs() * 1000);
+ }
+ break;
case KeyEvent.KEYCODE_MEDIA_REWIND:
mediaPlayer.seekDelta(-UserPreferences.getRewindSecs() * 1000);
break;
@@ -597,6 +611,12 @@ public class PlaybackService extends MediaBrowserServiceCompat {
writePlayerStatusPlaybackPreferences();
setupNotification(newInfo);
started = true;
+ // set sleep timer if auto-enabled
+ if(newInfo.oldPlayerStatus != null && newInfo.oldPlayerStatus != PlayerStatus.SEEKING &&
+ SleepTimerPreferences.autoEnable() && !sleepTimerActive()) {
+ setSleepTimer(SleepTimerPreferences.timerMillis(), SleepTimerPreferences.shakeToReset(),
+ SleepTimerPreferences.vibrate());
+ }
break;
case ERROR:
@@ -669,8 +689,9 @@ public class PlaybackService extends MediaBrowserServiceCompat {
}
@Override
- public void onPostPlayback(@NonNull Playable media, boolean ended, boolean playingNext) {
- PlaybackService.this.onPostPlayback(media, ended, playingNext);
+ public void onPostPlayback(@NonNull Playable media, boolean ended, boolean skipped,
+ boolean playingNext) {
+ PlaybackService.this.onPostPlayback(media, ended, skipped, playingNext);
}
@Override
@@ -768,16 +789,20 @@ public class PlaybackService extends MediaBrowserServiceCompat {
* Even though these tasks aren't supposed to be resource intensive, a good practice is to
* usually call this method on a background thread.
*
- * @param playable the media object that was playing. It is assumed that its position property
- * was updated before this method was called.
- * @param ended if true, it signals that {@param playable} was played until its end.
- * In such case, the position property of the media becomes irrelevant for most of
- * the tasks (although it's still a good practice to keep it accurate).
- * @param playingNext if true, it means another media object is being loaded in place of this one.
+ * @param playable the media object that was playing. It is assumed that its position
+ * property was updated before this method was called.
+ * @param ended if true, it signals that {@param playable} was played until its end.
+ * In such case, the position property of the media becomes irrelevant for
+ * most of the tasks (although it's still a good practice to keep it
+ * accurate).
+ * @param skipped if the user pressed a skip >| button.
+ * @param playingNext if true, it means another media object is being loaded in place of this
+ * one.
* Instances when we'd set it to false would be when we're not following the
* queue or when the queue has ended.
*/
- private void onPostPlayback(final Playable playable, boolean ended, boolean playingNext) {
+ private void onPostPlayback(final Playable playable, boolean ended, boolean skipped,
+ boolean playingNext) {
if (playable == null) {
Log.e(TAG, "Cannot do post-playback processing: media was null");
return;
@@ -808,7 +833,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
if (item != null) {
if (ended || smartMarkAsPlayed ||
- !UserPreferences.shouldSkipKeepEpisode()) {
+ (skipped && !UserPreferences.shouldSkipKeepEpisode())) {
// only mark the item as played if we're not keeping it anyways
DBWriter.markItemPlayed(item, FeedItem.PLAYED, ended);
try {
@@ -829,7 +854,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
}
}
- if (ended || playingNext) {
+ if (ended || skipped || playingNext) {
DBWriter.addItemToPlaybackHistory(media);
}
}
@@ -838,11 +863,14 @@ public class PlaybackService extends MediaBrowserServiceCompat {
Log.d(TAG, "Setting sleep timer to " + Long.toString(waitingTime) + " milliseconds");
taskManager.setSleepTimer(waitingTime, shakeToReset, vibrate);
sendNotificationBroadcast(NOTIFICATION_TYPE_SLEEPTIMER_UPDATE, 0);
+ EventBus.getDefault().post(new MessageEvent(getString(R.string.sleep_timer_enabled_label),
+ () -> disableSleepTimer()));
}
public void disableSleepTimer() {
taskManager.disableSleepTimer();
sendNotificationBroadcast(NOTIFICATION_TYPE_SLEEPTIMER_UPDATE, 0);
+ EventBus.getDefault().post(new MessageEvent(getString(R.string.sleep_timer_disabled_label)));
}
private void writePlaybackPreferencesNoMediaPlaying() {
@@ -996,13 +1024,37 @@ public class PlaybackService extends MediaBrowserServiceCompat {
state = PlaybackStateCompat.STATE_NONE;
}
sessionState.setState(state, mediaPlayer.getPosition(), mediaPlayer.getPlaybackSpeed());
- sessionState.setActions(PlaybackStateCompat.ACTION_PLAY_PAUSE
+ long capabilities = PlaybackStateCompat.ACTION_PLAY_PAUSE
| PlaybackStateCompat.ACTION_REWIND
| PlaybackStateCompat.ACTION_FAST_FORWARD
- | PlaybackStateCompat.ACTION_SKIP_TO_NEXT);
+ | PlaybackStateCompat.ACTION_SKIP_TO_NEXT;
+
+ if (useSkipToPreviousForRewindInLockscreen()) {
+ // Workaround to fool Android so that Lockscreen will expose a skip-to-previous button,
+ // which will be used for rewind.
+ // The workaround is used for pre Lollipop (Androidv5) devices.
+ // For Androidv5+, lockscreen widges are really notifications (compact),
+ // with an independent codepath
+ //
+ // @see #sessionCallback in the backing callback, skipToPrevious implementation
+ // is actually the same as rewind. So no new inconsistency is created.
+ // @see #setupNotification() for the method to create Androidv5+ lockscreen UI
+ // with notification (compact)
+ capabilities = capabilities | PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS;
+ }
+
+ sessionState.setActions(capabilities);
mediaSession.setPlaybackState(sessionState.build());
}
+ private static boolean useSkipToPreviousForRewindInLockscreen() {
+ // showRewindOnCompactNotification() corresponds to the "Set Lockscreen Buttons"
+ // Settings in UI.
+ // Hence, from user perspective, he/she is setting the buttons for Lockscreen
+ return ( UserPreferences.showRewindOnCompactNotification() &&
+ (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) );
+ }
+
/**
* Used by updateMediaSessionMetadata to load notification data in another thread.
*/
@@ -1050,7 +1102,13 @@ public class PlaybackService extends MediaBrowserServiceCompat {
mediaSession.setSessionActivity(PendingIntent.getActivity(this, 0,
PlaybackService.getPlayerActivityIntent(this),
PendingIntent.FLAG_UPDATE_CURRENT));
- mediaSession.setMetadata(builder.build());
+ try {
+ mediaSession.setMetadata(builder.build());
+ } catch (OutOfMemoryError e) {
+ Log.e(TAG, "Setting media session metadata", e);
+ builder.putBitmap(MediaMetadataCompat.METADATA_KEY_ART, null);
+ mediaSession.setMetadata(builder.build());
+ }
}
};
@@ -1285,7 +1343,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
if (info.playable != null) {
Intent i = new Intent(whatChanged);
- i.putExtra("id", 1);
+ i.putExtra("id", 1L);
i.putExtra("artist", "");
i.putExtra("album", info.playable.getFeedTitle());
i.putExtra("track", info.playable.getEpisodeTitle());
@@ -1294,8 +1352,8 @@ public class PlaybackService extends MediaBrowserServiceCompat {
if (queue != null) {
i.putExtra("ListSize", queue.size());
}
- i.putExtra("duration", info.playable.getDuration());
- i.putExtra("position", info.playable.getPosition());
+ i.putExtra("duration", (long) info.playable.getDuration());
+ i.putExtra("position", (long) info.playable.getPosition());
sendBroadcast(i);
}
}
@@ -1375,7 +1433,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
* Pauses playback if PREF_PAUSE_ON_HEADSET_DISCONNECT was set to true.
*/
private void pauseIfPauseOnDisconnect() {
- if (UserPreferences.isPauseOnHeadsetDisconnect()) {
+ if (UserPreferences.isPauseOnHeadsetDisconnect() && !isCasting()) {
if (mediaPlayer.getPlayerStatus() == PlayerStatus.PLAYING) {
transientPause = true;
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java
index aec059ca0..393019fd1 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java
@@ -29,9 +29,10 @@ public abstract class PlaybackServiceMediaPlayer {
/**
* Return value of some PSMP methods if the method call failed.
*/
- public static final int INVALID_TIME = -1;
+ static final int INVALID_TIME = -1;
- protected volatile PlayerStatus playerStatus;
+ volatile PlayerStatus oldPlayerStatus;
+ volatile PlayerStatus playerStatus;
/**
* A wifi-lock that is acquired if the media file is being streamed.
@@ -41,8 +42,8 @@ public abstract class PlaybackServiceMediaPlayer {
protected final PSMPCallback callback;
protected final Context context;
- public PlaybackServiceMediaPlayer(@NonNull Context context,
- @NonNull PSMPCallback callback){
+ PlaybackServiceMediaPlayer(@NonNull Context context,
+ @NonNull PSMPCallback callback){
this.context = context;
this.callback = callback;
@@ -204,7 +205,7 @@ public abstract class PlaybackServiceMediaPlayer {
* @return The PSMPInfo object.
*/
public final synchronized PSMPInfo getPSMPInfo() {
- return new PSMPInfo(playerStatus, getPlayable());
+ return new PSMPInfo(oldPlayerStatus, playerStatus, getPlayable());
}
/**
@@ -228,32 +229,35 @@ public abstract class PlaybackServiceMediaPlayer {
protected abstract void setPlayable(Playable playable);
public void skip() {
- endPlayback(true, true, true);
+ endPlayback(false, true, true, true);
}
/**
* Ends playback of current media (if any) and moves into INDETERMINATE state, unless
* {@param toStoppedState} is set to true, in which case it moves into STOPPED state.
*
- * @see #endPlayback(boolean, boolean, boolean)
+ * @see #endPlayback(boolean, boolean, boolean, boolean)
*/
public Future<?> stopPlayback(boolean toStoppedState) {
- return endPlayback(true, false, toStoppedState);
+ return endPlayback(false, false, false, toStoppedState);
}
/**
* Internal method that handles end of playback.
*
- * Currently, it has 4 use cases:
+ * Currently, it has 5 use cases:
* <ul>
- * <li>Media playback has completed: call with (false, true, true)</li>
- * <li>User asks to skip to next episode: call with (true, true, true)</li>
- * <li>Stopping the media player: call with (true, false, true)</li>
- * <li>We want to change the media player implementation: call with (true, false, false)</li>
+ * <li>Media playback has completed: call with (true, false, true, true)</li>
+ * <li>User asks to skip to next episode: call with (false, true, true, true)</li>
+ * <li>Skipping to next episode due to playback error: call with (false, false, true, true)</li>
+ * <li>Stopping the media player: call with (false, false, false, true)</li>
+ * <li>We want to change the media player implementation: call with (false, false, false, false)</li>
* </ul>
*
- * @param wasSkipped If true, we assume the current media's playback has ended, for
+ * @param hasEnded If true, we assume the current media's playback has ended, for
* purposes of post playback processing.
+ * @param wasSkipped Whether the user chose to skip the episode (by pressing the skip
+ * button).
* @param shouldContinue If true, the media player should try to load, and possibly play,
* the next item, based on the user preferences and whether such item
* exists.
@@ -264,14 +268,15 @@ public abstract class PlaybackServiceMediaPlayer {
*
* @return a Future, just for the purpose of tracking its execution.
*/
- protected abstract Future<?> endPlayback(boolean wasSkipped, boolean shouldContinue, boolean toStoppedState);
+ protected abstract Future<?> endPlayback(boolean hasEnded, boolean wasSkipped,
+ boolean shouldContinue, boolean toStoppedState);
/**
* @return {@code true} if the WifiLock feature should be used, {@code false} otherwise.
*/
protected abstract boolean shouldLockWifi();
- protected final synchronized void acquireWifiLockIfNecessary() {
+ final synchronized void acquireWifiLockIfNecessary() {
if (shouldLockWifi()) {
if (wifiLock == null) {
wifiLock = ((WifiManager) context.getSystemService(Context.WIFI_SERVICE))
@@ -282,7 +287,7 @@ public abstract class PlaybackServiceMediaPlayer {
}
}
- protected final synchronized void releaseWifiLockIfNecessary() {
+ final synchronized void releaseWifiLockIfNecessary() {
if (wifiLock != null && wifiLock.isHeld()) {
wifiLock.release();
}
@@ -303,29 +308,28 @@ public abstract class PlaybackServiceMediaPlayer {
* @param position The position to be set to the current Playable object in case playback started or paused.
* Will be ignored if given the value of {@link #INVALID_TIME}.
*/
- protected final synchronized void setPlayerStatus(@NonNull PlayerStatus newStatus, Playable newMedia, int position) {
+ final synchronized void setPlayerStatus(@NonNull PlayerStatus newStatus, Playable newMedia, int position) {
Log.d(TAG, this.getClass().getSimpleName() + ": Setting player status to " + newStatus);
- PlayerStatus oldStatus = playerStatus;
-
+ this.oldPlayerStatus = playerStatus;
this.playerStatus = newStatus;
setPlayable(newMedia);
if (newMedia != null && newStatus != PlayerStatus.INDETERMINATE) {
- if (oldStatus == PlayerStatus.PLAYING && newStatus != PlayerStatus.PLAYING) {
+ if (oldPlayerStatus == PlayerStatus.PLAYING && newStatus != PlayerStatus.PLAYING) {
callback.onPlaybackPause(newMedia, position);
- } else if (oldStatus != PlayerStatus.PLAYING && newStatus == PlayerStatus.PLAYING) {
+ } else if (oldPlayerStatus != PlayerStatus.PLAYING && newStatus == PlayerStatus.PLAYING) {
callback.onPlaybackStart(newMedia, position);
}
}
- callback.statusChanged(new PSMPInfo(playerStatus, getPlayable()));
+ callback.statusChanged(new PSMPInfo(oldPlayerStatus, playerStatus, getPlayable()));
}
/**
* @see #setPlayerStatus(PlayerStatus, Playable, int)
*/
- protected final void setPlayerStatus(@NonNull PlayerStatus newStatus, Playable newMedia) {
+ final void setPlayerStatus(@NonNull PlayerStatus newStatus, Playable newMedia) {
setPlayerStatus(newStatus, newMedia, INVALID_TIME);
}
@@ -346,7 +350,7 @@ public abstract class PlaybackServiceMediaPlayer {
boolean onMediaPlayerError(Object inObj, int what, int extra);
- void onPostPlayback(@NonNull Playable media, boolean ended, boolean playingNext);
+ void onPostPlayback(@NonNull Playable media, boolean ended, boolean skipped, boolean playingNext);
void onPlaybackStart(@NonNull Playable playable, int position);
@@ -361,10 +365,12 @@ public abstract class PlaybackServiceMediaPlayer {
* Holds information about a PSMP object.
*/
public static class PSMPInfo {
+ public PlayerStatus oldPlayerStatus;
public PlayerStatus playerStatus;
public Playable playable;
- public PSMPInfo(PlayerStatus playerStatus, Playable playable) {
+ PSMPInfo(PlayerStatus oldPlayerStatus, PlayerStatus playerStatus, Playable playable) {
+ this.oldPlayerStatus = oldPlayerStatus;
this.playerStatus = playerStatus;
this.playable = playable;
}
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 9a7b2c852..1d57d902c 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
@@ -1063,7 +1063,7 @@ public final class DBReader {
// reverse natural order: podcast with most unplayed episodes first
return -1;
} else if(counterLhs == counterRhs) {
- return lhs.getTitle().compareTo(rhs.getTitle());
+ return lhs.getTitle().compareToIgnoreCase(rhs.getTitle());
} else {
return 1;
}
@@ -1077,7 +1077,7 @@ public final class DBReader {
} else if(t2 == null) {
return -1;
} else {
- return t1.toLowerCase().compareTo(t2.toLowerCase());
+ return t1.compareToIgnoreCase(t2);
}
};
} else {
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 d17b815ff..4d442aac2 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
@@ -2,6 +2,7 @@ package de.danoeh.antennapod.core.storage;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.database.Cursor;
import android.util.Log;
@@ -16,7 +17,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
-import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import de.danoeh.antennapod.core.ClientConfig;
@@ -27,21 +28,29 @@ 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.FeedPreferences;
+import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.GpodnetSyncService;
import de.danoeh.antennapod.core.service.download.DownloadStatus;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
+import de.danoeh.antennapod.core.util.Converter;
import de.danoeh.antennapod.core.util.DownloadError;
import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.comparator.FeedItemPubdateComparator;
import de.danoeh.antennapod.core.util.exception.MediaFileNotFoundException;
import de.danoeh.antennapod.core.util.flattr.FlattrUtils;
+import static android.content.Context.MODE_PRIVATE;
+import static android.provider.Contacts.SettingsColumns.KEY;
+
/**
* Provides methods for doing common tasks that use DBReader and DBWriter.
*/
public final class DBTasks {
private static final String TAG = "DBTasks";
+ public static final String PREF_NAME = "dbtasks";
+ private static final String PREF_LAST_REFRESH = "last_refresh";
+
/**
* Executor service used by the autodownloadUndownloadedEpisodes method.
*/
@@ -162,6 +171,9 @@ public final class DBTasks {
}
isRefreshing.set(false);
+ SharedPreferences prefs = context.getSharedPreferences(PREF_NAME, MODE_PRIVATE);
+ prefs.edit().putLong(PREF_LAST_REFRESH, System.currentTimeMillis()).apply();
+
if (FlattrUtils.hasToken()) {
Log.d(TAG, "Flattring all pending things.");
new FlattrClickWorker(context).executeAsync(); // flattr pending things
@@ -313,6 +325,31 @@ public final class DBTasks {
DownloadRequester.getInstance().downloadFeed(context, f, loadAllPages, force);
}
+ /*
+ * Checks if the app should refresh all feeds, i.e. if the last auto refresh failed.
+ *
+ * The feeds are only refreshed if an update interval or time of day is set and the last
+ * (successful) refresh was before the last interval or more than a day ago, respectively.
+ */
+ public static void checkShouldRefreshFeeds(Context context) {
+ long interval = 0;
+ if(UserPreferences.getUpdateInterval() > 0) {
+ interval = UserPreferences.getUpdateInterval();
+ } else if(UserPreferences.getUpdateTimeOfDay().length > 0){
+ interval = TimeUnit.DAYS.toMillis(1);
+ }
+ if(interval == 0) { // auto refresh is disabled
+ return;
+ }
+ SharedPreferences prefs = context.getSharedPreferences(PREF_NAME, MODE_PRIVATE);
+ long lastRefresh = prefs.getLong(PREF_LAST_REFRESH, 0);
+ Log.d(TAG, "last refresh: " + Converter.getDurationStringLocalized(context,
+ System.currentTimeMillis() - lastRefresh) + " ago");
+ if(lastRefresh <= System.currentTimeMillis() - interval) {
+ DBTasks.refreshAllFeeds(context, null);
+ }
+ }
+
/**
* Notifies the database about a missing FeedMedia file. This method will correct the FeedMedia object's values in the
* DB and send a FeedUpdateBroadcast.
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 8e007019f..563d80da0 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
@@ -884,6 +884,17 @@ public class DBWriter {
});
}
+ public static Future<?> setFeedCustomTitle(Feed feed) {
+ return dbExec.submit(() -> {
+ PodDBAdapter adapter = PodDBAdapter.getInstance();
+ adapter.open();
+ adapter.setFeedCustomTitle(feed.getId(), feed.getCustomTitle());
+ adapter.close();
+ EventDistributor.getInstance().sendFeedUpdateBroadcast();
+ });
+ }
+
+
/**
* format an url for querying the database
* (postfix a / and apply percent-encoding)
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..48e574069 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;
@@ -51,15 +53,17 @@ public class FeedSearcher {
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 +71,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 7631d26d5..ff003550c 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
@@ -42,12 +42,12 @@ import de.greenrobot.event.EventBus;
public class PodDBAdapter {
private static final String TAG = "PodDBAdapter";
- public static final String DATABASE_NAME = "Antennapod.db";
+ private static final String DATABASE_NAME = "Antennapod.db";
/**
* Maximum number of arguments for IN-operator.
*/
- public static final int IN_OPERATOR_MAXIMUM = 800;
+ private static final int IN_OPERATOR_MAXIMUM = 800;
/**
* Maximum number of entries per search request.
@@ -57,6 +57,7 @@ public class PodDBAdapter {
// Key-constants
public static final String KEY_ID = "id";
public static final String KEY_TITLE = "title";
+ public static final String KEY_CUSTOM_TITLE = "custom_title";
public static final String KEY_NAME = "name";
public static final String KEY_LINK = "link";
public static final String KEY_DESCRIPTION = "description";
@@ -109,14 +110,14 @@ public class PodDBAdapter {
public static final String KEY_EXCLUDE_FILTER = "exclude_filter";
// Table names
- public static final String TABLE_NAME_FEEDS = "Feeds";
- public static final String TABLE_NAME_FEED_ITEMS = "FeedItems";
- public static final String TABLE_NAME_FEED_IMAGES = "FeedImages";
- public static final String TABLE_NAME_FEED_MEDIA = "FeedMedia";
- public static final String TABLE_NAME_DOWNLOAD_LOG = "DownloadLog";
- public static final String TABLE_NAME_QUEUE = "Queue";
- public static final String TABLE_NAME_SIMPLECHAPTERS = "SimpleChapters";
- public static final String TABLE_NAME_FAVORITES = "Favorites";
+ private static final String TABLE_NAME_FEEDS = "Feeds";
+ private static final String TABLE_NAME_FEED_ITEMS = "FeedItems";
+ private static final String TABLE_NAME_FEED_IMAGES = "FeedImages";
+ private static final String TABLE_NAME_FEED_MEDIA = "FeedMedia";
+ private static final String TABLE_NAME_DOWNLOAD_LOG = "DownloadLog";
+ private static final String TABLE_NAME_QUEUE = "Queue";
+ private static final String TABLE_NAME_SIMPLECHAPTERS = "SimpleChapters";
+ private static final String TABLE_NAME_FAVORITES = "Favorites";
// SQL Statements for creating new tables
private static final String TABLE_PRIMARY_KEY = KEY_ID
@@ -124,7 +125,7 @@ public class PodDBAdapter {
public static final String CREATE_TABLE_FEEDS = "CREATE TABLE "
+ TABLE_NAME_FEEDS + " (" + TABLE_PRIMARY_KEY + KEY_TITLE
- + " TEXT," + KEY_FILE_URL + " TEXT," + KEY_DOWNLOAD_URL + " TEXT,"
+ + " TEXT," + KEY_CUSTOM_TITLE + " TEXT," + KEY_FILE_URL + " TEXT," + KEY_DOWNLOAD_URL + " TEXT,"
+ KEY_DOWNLOADED + " INTEGER," + KEY_LINK + " TEXT,"
+ KEY_DESCRIPTION + " TEXT," + KEY_PAYMENT_LINK + " TEXT,"
+ KEY_LASTUPDATE + " TEXT," + KEY_LANGUAGE + " TEXT," + KEY_AUTHOR
@@ -225,6 +226,7 @@ public class PodDBAdapter {
private static final String[] FEED_SEL_STD = {
TABLE_NAME_FEEDS + "." + KEY_ID,
TABLE_NAME_FEEDS + "." + KEY_TITLE,
+ TABLE_NAME_FEEDS + "." + KEY_CUSTOM_TITLE,
TABLE_NAME_FEEDS + "." + KEY_FILE_URL,
TABLE_NAME_FEEDS + "." + KEY_DOWNLOAD_URL,
TABLE_NAME_FEEDS + "." + KEY_DOWNLOADED,
@@ -363,7 +365,7 @@ public class PodDBAdapter {
*/
public long setFeed(Feed feed) {
ContentValues values = new ContentValues();
- values.put(KEY_TITLE, feed.getTitle());
+ values.put(KEY_TITLE, feed.getFeedTitle());
values.put(KEY_LINK, feed.getLink());
values.put(KEY_DESCRIPTION, feed.getDescription());
values.put(KEY_PAYMENT_LINK, feed.getPaymentLink());
@@ -854,6 +856,12 @@ public class PodDBAdapter {
db.execSQL(sql);
}
+ void setFeedCustomTitle(long feedId, String customTitle) {
+ ContentValues values = new ContentValues();
+ values.put(KEY_CUSTOM_TITLE, customTitle);
+ db.update(TABLE_NAME_FEEDS, values, KEY_ID + "=?", new String[]{String.valueOf(feedId)});
+ }
+
/**
* Inserts or updates a download status.
*/
@@ -1436,15 +1444,24 @@ public class PodDBAdapter {
public final LongIntMap getFeedCounters(long... feedIds) {
int setting = UserPreferences.getFeedCounterSetting();
String whereRead;
- if(setting == UserPreferences.FEED_COUNTER_SHOW_NEW_UNPLAYED_SUM) {
- whereRead = "(" + KEY_READ + "=" + FeedItem.NEW
- + " OR " + KEY_READ + "=" + FeedItem.UNPLAYED + ")";
- } else if(setting == UserPreferences.FEED_COUNTER_SHOW_NEW) {
- whereRead = KEY_READ + "=" + FeedItem.NEW;
- } else if(setting == UserPreferences.FEED_COUNTER_SHOW_UNPLAYED) {
- whereRead = KEY_READ + "=" + FeedItem.UNPLAYED;
- } else { // NONE
- return new LongIntMap(0);
+ switch(setting) {
+ case UserPreferences.FEED_COUNTER_SHOW_NEW_UNPLAYED_SUM:
+ whereRead = "(" + KEY_READ + "=" + FeedItem.NEW +
+ " OR " + KEY_READ + "=" + FeedItem.UNPLAYED + ")";
+ break;
+ case UserPreferences.FEED_COUNTER_SHOW_NEW:
+ whereRead = KEY_READ + "=" + FeedItem.NEW;
+ break;
+ case UserPreferences.FEED_COUNTER_SHOW_UNPLAYED:
+ whereRead = KEY_READ + "=" + FeedItem.UNPLAYED;
+ break;
+ case UserPreferences.FEED_COUNTER_SHOW_DOWNLOADED:
+ whereRead = KEY_DOWNLOADED + "=1";
+ break;
+ case UserPreferences.FEED_COUNTER_SHOW_NONE:
+ // deliberate fall-through
+ default: // NONE
+ return new LongIntMap(0);
}
// work around TextUtils.join wanting only boxed items
@@ -1459,8 +1476,10 @@ public class PodDBAdapter {
builder.deleteCharAt(builder.length() - 1);
}
- final String query = "SELECT " + KEY_FEED + ", COUNT(" + KEY_ID + ") AS count "
+ final String query = "SELECT " + KEY_FEED + ", COUNT(" + TABLE_NAME_FEED_ITEMS + "." + KEY_ID + ") AS count "
+ " FROM " + TABLE_NAME_FEED_ITEMS
+ + " LEFT JOIN " + TABLE_NAME_FEED_MEDIA + " ON "
+ + TABLE_NAME_FEED_ITEMS + "." + KEY_ID + "=" + TABLE_NAME_FEED_MEDIA + "." + KEY_FEEDITEM
+ " WHERE " + KEY_FEED + " IN (" + builder.toString() + ") "
+ " AND " + whereRead + " GROUP BY " + KEY_FEED;
@@ -1617,7 +1636,7 @@ public class PodDBAdapter {
*/
private static class PodDBHelper extends SQLiteOpenHelper {
- private static final int VERSION = 1050004;
+ private static final int VERSION = 1060200;
private Context context;
@@ -1913,6 +1932,10 @@ public class PodDBAdapter {
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS
+" SET " + PodDBAdapter.KEY_LASTUPDATE + "=NULL");
}
+ if(oldVersion < 1060200) {
+ db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
+ + " ADD COLUMN " + PodDBAdapter.KEY_CUSTOM_TITLE + " TEXT");
+ }
EventBus.getDefault().post(ProgressEvent.end());
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/SyndHandler.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/SyndHandler.java
index 47503dee4..ae91c0743 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/SyndHandler.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/SyndHandler.java
@@ -6,7 +6,6 @@ import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
-import de.danoeh.antennapod.core.BuildConfig;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.syndication.namespace.NSContent;
import de.danoeh.antennapod.core.syndication.namespace.NSDublinCore;
@@ -86,34 +85,28 @@ public class SyndHandler extends DefaultHandler {
state.defaultNamespaces.push(new NSAtom());
} else if (prefix.equals(NSAtom.NSTAG)) {
state.namespaces.put(uri, new NSAtom());
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Recognized Atom namespace");
+ Log.d(TAG, "Recognized Atom namespace");
}
} else if (uri.equals(NSContent.NSURI)
&& prefix.equals(NSContent.NSTAG)) {
state.namespaces.put(uri, new NSContent());
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Recognized Content namespace");
+ Log.d(TAG, "Recognized Content namespace");
} else if (uri.equals(NSITunes.NSURI)
&& prefix.equals(NSITunes.NSTAG)) {
state.namespaces.put(uri, new NSITunes());
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Recognized ITunes namespace");
+ Log.d(TAG, "Recognized ITunes namespace");
} else if (uri.equals(NSSimpleChapters.NSURI)
&& prefix.matches(NSSimpleChapters.NSTAG)) {
state.namespaces.put(uri, new NSSimpleChapters());
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Recognized SimpleChapters namespace");
+ Log.d(TAG, "Recognized SimpleChapters namespace");
} else if (uri.equals(NSMedia.NSURI)
&& prefix.equals(NSMedia.NSTAG)) {
state.namespaces.put(uri, new NSMedia());
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Recognized media namespace");
+ Log.d(TAG, "Recognized media namespace");
} else if (uri.equals(NSDublinCore.NSURI)
&& prefix.equals(NSDublinCore.NSTAG)) {
state.namespaces.put(uri, new NSDublinCore());
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Recognized DublinCore namespace");
+ Log.d(TAG, "Recognized DublinCore namespace");
}
}
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSMedia.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSMedia.java
index 839e2ae0c..f2cfc2e57 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSMedia.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSMedia.java
@@ -26,6 +26,11 @@ public class NSMedia extends Namespace {
private static final String MIME_TYPE = "type";
private static final String DURATION = "duration";
private static final String DEFAULT = "isDefault";
+ private static final String MEDIUM = "medium";
+
+ private static final String MEDIUM_IMAGE = "image";
+ private static final String MEDIUM_AUDIO = "audio";
+ private static final String MEDIUM_VIDEO = "video";
private static final String IMAGE = "thumbnail";
private static final String IMAGE_URL = "url";
@@ -40,20 +45,31 @@ public class NSMedia extends Namespace {
String url = attributes.getValue(DOWNLOAD_URL);
String type = attributes.getValue(MIME_TYPE);
String defaultStr = attributes.getValue(DEFAULT);
- boolean validType;
+ String medium = attributes.getValue(MEDIUM);
+ boolean validTypeMedia = false;
+ boolean validTypeImage = false;
boolean isDefault = "true".equals(defaultStr);
- if (SyndTypeUtils.enclosureTypeValid(type)) {
- validType = true;
+ if (MEDIUM_AUDIO.equals(medium) || MEDIUM_VIDEO.equals(medium)) {
+ validTypeMedia = true;
+ } else if (MEDIUM_IMAGE.equals(medium)) {
+ validTypeImage = true;
} else {
- type = SyndTypeUtils.getValidMimeTypeFromUrl(url);
- validType = type != null;
+ if (type == null) {
+ type = SyndTypeUtils.getMimeTypeFromUrl(url);
+ }
+
+ if (SyndTypeUtils.enclosureTypeValid(type)) {
+ validTypeMedia = true;
+ } else if (SyndTypeUtils.imageTypeValid(type)) {
+ validTypeImage = true;
+ }
}
if (state.getCurrentItem() != null &&
(state.getCurrentItem().getMedia() == null || isDefault) &&
- url != null && validType) {
+ url != null && validTypeMedia) {
long size = 0;
String sizeStr = attributes.getValue(SIZE);
try {
@@ -77,6 +93,12 @@ public class NSMedia extends Namespace {
media.setDuration(durationMs);
}
state.getCurrentItem().setMedia(media);
+ } else if (state.getCurrentItem() != null && url != null && validTypeImage) {
+ FeedImage image = new FeedImage();
+ image.setDownload_url(url);
+ image.setOwner(state.getCurrentItem());
+
+ state.getCurrentItem().setImage(image);
}
} else if (IMAGE.equals(localName)) {
String url = attributes.getValue(IMAGE_URL);
diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSRSS20.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSRSS20.java
index a5ca9d6f4..3d752df76 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSRSS20.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSRSS20.java
@@ -20,25 +20,27 @@ import de.danoeh.antennapod.core.util.DateUtils;
*
*/
public class NSRSS20 extends Namespace {
- private static final String TAG = "NSRSS20";
- public static final String NSTAG = "rss";
- public static final String NSURI = "";
- public static final String CHANNEL = "channel";
+ private static final String TAG = "NSRSS20";
+
+ private static final String NSTAG = "rss";
+ private static final String NSURI = "";
+
+ public static final String CHANNEL = "channel";
public static final String ITEM = "item";
- public static final String GUID = "guid";
- public static final String TITLE = "title";
- public static final String LINK = "link";
- public static final String DESCR = "description";
- public static final String PUBDATE = "pubDate";
- public static final String ENCLOSURE = "enclosure";
- public static final String IMAGE = "image";
- public static final String URL = "url";
- public static final String LANGUAGE = "language";
-
- public static final String ENC_URL = "url";
- public static final String ENC_LEN = "length";
- public static final String ENC_TYPE = "type";
+ private static final String GUID = "guid";
+ private static final String TITLE = "title";
+ private static final String LINK = "link";
+ private static final String DESCR = "description";
+ private static final String PUBDATE = "pubDate";
+ private static final String ENCLOSURE = "enclosure";
+ private static final String IMAGE = "image";
+ private static final String URL = "url";
+ private static final String LANGUAGE = "language";
+
+ private static final String ENC_URL = "url";
+ private static final String ENC_LEN = "length";
+ private static final String ENC_TYPE = "type";
@Override
public SyndElement handleElementStart(String localName, HandlerState state,
@@ -51,15 +53,16 @@ public class NSRSS20 extends Namespace {
} else if (ENCLOSURE.equals(localName)) {
String type = attributes.getValue(ENC_TYPE);
String url = attributes.getValue(ENC_URL);
- boolean validType;
- if(SyndTypeUtils.enclosureTypeValid(type)) {
- validType = true;
- } else {
- type = type = SyndTypeUtils.getValidMimeTypeFromUrl(url);
- validType = type != null;
- }
- if (state.getCurrentItem() != null && state.getCurrentItem().getMedia() == null &&
- validType) {
+
+ boolean validType = SyndTypeUtils.enclosureTypeValid(type);
+ if(!validType) {
+ type = SyndTypeUtils.getMimeTypeFromUrl(url);
+ validType = SyndTypeUtils.enclosureTypeValid(type);
+ }
+
+ boolean validUrl = !TextUtils.isEmpty(url);
+ if (state.getCurrentItem() != null && state.getCurrentItem().getMedia() == null &&
+ validType && validUrl) {
long size = 0;
try {
size = Long.parseLong(attributes.getValue(ENC_LEN));
@@ -70,8 +73,8 @@ public class NSRSS20 extends Namespace {
} catch (NumberFormatException e) {
Log.d(TAG, "Length attribute could not be parsed.");
}
- state.getCurrentItem().setMedia(
- new FeedMedia(state.getCurrentItem(), url, size, type));
+ FeedMedia media = new FeedMedia(state.getCurrentItem(), url, size, type);
+ state.getCurrentItem().setMedia(media);
}
} else if (IMAGE.equals(localName)) {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/atom/NSAtom.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/atom/NSAtom.java
index 52b05aa98..cfb20d578 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/atom/NSAtom.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/atom/NSAtom.java
@@ -30,6 +30,7 @@ public class NSAtom extends Namespace {
private static final String AUTHOR = "author";
private static final String AUTHOR_NAME = "name";
private static final String CONTENT = "content";
+ private static final String SUMMARY = "summary";
private static final String IMAGE_LOGO = "logo";
private static final String IMAGE_ICON = "icon";
private static final String SUBTITLE = "subtitle";
@@ -44,6 +45,7 @@ public class NSAtom extends Namespace {
private static final String LINK_LENGTH = "length";
// rel-values
private static final String LINK_REL_ALTERNATE = "alternate";
+ private static final String LINK_REL_ARCHIVES = "archives";
private static final String LINK_REL_ENCLOSURE = "enclosure";
private static final String LINK_REL_PAYMENT = "payment";
private static final String LINK_REL_RELATED = "related";
@@ -59,8 +61,8 @@ public class NSAtom extends Namespace {
/**
* Regexp to test whether an Element is a Text Element.
*/
- private static final String isText = TITLE + "|" + CONTENT + "|" + "|"
- + SUBTITLE;
+ private static final String isText = TITLE + "|" + CONTENT + "|"
+ + SUBTITLE + "|" + SUMMARY;
public static final String isFeed = FEED + "|" + NSRSS20.CHANNEL;
public static final String isFeedItem = ENTRY + "|" + NSRSS20.ITEM;
@@ -93,14 +95,12 @@ public class NSAtom extends Namespace {
Log.d(TAG, "Length attribute could not be parsed.");
}
String type = attributes.getValue(LINK_TYPE);
- boolean validType;
- if(SyndTypeUtils.enclosureTypeValid(type)) {
- validType = true;
- } else {
- type = SyndTypeUtils.getValidMimeTypeFromUrl(href);
- validType = type != null;
+
+ if (type == null) {
+ type = SyndTypeUtils.getMimeTypeFromUrl(href);
}
- if (validType) {
+
+ if(SyndTypeUtils.enclosureTypeValid(type)) {
FeedItem currItem = state.getCurrentItem();
if(currItem != null && !currItem.hasMedia()) {
currItem.setMedia(new FeedMedia(currItem, href, size, type));
@@ -129,6 +129,17 @@ public class NSAtom extends Namespace {
}
state.addAlternateFeedUrl(title, href);
}
+ } else if (LINK_REL_ARCHIVES.equals(rel) && state.getFeed() != null) {
+ String type = attributes.getValue(LINK_TYPE);
+ if (LINK_TYPE_ATOM.equals(type) || LINK_TYPE_RSS.equals(type)) {
+ String title = attributes.getValue(LINK_TITLE);
+ if (TextUtils.isEmpty(title)) {
+ title = href;
+ }
+ state.addAlternateFeedUrl(title, href);
+ } else if (LINK_TYPE_HTML.equals(type) || LINK_TYPE_XHTML.equals(type)) {
+ //A Link such as to a directory such as iTunes
+ }
} else if (LINK_REL_PAYMENT.equals(rel) && state.getFeed() != null) {
state.getFeed().setPaymentLink(href);
} else if (LINK_REL_NEXT.equals(rel) && state.getFeed() != null) {
@@ -191,6 +202,9 @@ public class NSAtom extends Namespace {
} else if (CONTENT.equals(top) && ENTRY.equals(second) && textElement != null &&
state.getCurrentItem() != null) {
state.getCurrentItem().setDescription(textElement.getProcessedContent());
+ } else if (SUMMARY.equals(top) && ENTRY.equals(second) && textElement != null &&
+ state.getCurrentItem() != null && state.getCurrentItem().getDescription() == null) {
+ state.getCurrentItem().setDescription(textElement.getProcessedContent());
} else if (UPDATED.equals(top) && ENTRY.equals(second) && state.getCurrentItem() != null &&
state.getCurrentItem().getPubDate() == null) {
state.getCurrentItem().setPubDate(DateUtils.parse(content));
@@ -200,9 +214,13 @@ public class NSAtom extends Namespace {
state.getFeed().setImage(new FeedImage(state.getFeed(), content, null));
} else if (IMAGE_ICON.equals(top) && state.getFeed() != null) {
state.getFeed().setImage(new FeedImage(state.getFeed(), content, null));
- } else if (AUTHOR.equals(second) && state.getFeed() != null) {
- if (AUTHOR_NAME.equals(top)) {
+ } else if (AUTHOR_NAME.equals(top) && AUTHOR.equals(second) &&
+ state.getFeed() != null && state.getCurrentItem() == null) {
+ String currentName = state.getFeed().getAuthor();
+ if (currentName == null) {
state.getFeed().setAuthor(content);
+ } else {
+ state.getFeed().setAuthor(currentName + ", " + content);
}
}
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/util/SyndTypeUtils.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/util/SyndTypeUtils.java
index d228b9ef7..1d564ab0e 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/syndication/util/SyndTypeUtils.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/syndication/util/SyndTypeUtils.java
@@ -1,13 +1,22 @@
package de.danoeh.antennapod.core.syndication.util;
+import android.text.TextUtils;
import android.webkit.MimeTypeMap;
+
import org.apache.commons.io.FilenameUtils;
+import java.util.Arrays;
+
/** Utility class for handling MIME-Types of enclosures */
public class SyndTypeUtils {
- private static final String VALID_MIMETYPE = "audio/.*" + "|" + "video/.*"
- + "|" + "application/ogg";
+ private static final String VALID_MEDIA_MIMETYPE = TextUtils.join("|", Arrays.asList(
+ "audio/.*",
+ "video/.*",
+ "application/ogg",
+ "application/octet-stream"));
+
+ private static final String VALID_IMAGE_MIMETYPE = "image/.*";
private SyndTypeUtils() {
@@ -17,9 +26,17 @@ public class SyndTypeUtils {
if (type == null) {
return false;
} else {
- return type.matches(VALID_MIMETYPE);
+ return type.matches(VALID_MEDIA_MIMETYPE);
}
}
+ public static boolean imageTypeValid(String type) {
+ if (type == null) {
+ return false;
+ } else {
+ return type.matches(VALID_IMAGE_MIMETYPE);
+ }
+ }
+
/**
* Should be used if mime-type of enclosure tag is not supported. This
@@ -27,15 +44,27 @@ public class SyndTypeUtils {
* the type is not supported, this method will return null.
*/
public static String getValidMimeTypeFromUrl(String url) {
- if (url != null) {
- String extension = FilenameUtils.getExtension(url);
- if (extension != null) {
- String type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
- if (type != null && enclosureTypeValid(type)) {
- return type;
- }
- }
+ String type = getMimeTypeFromUrl(url);
+ if (enclosureTypeValid(type)) {
+ return type;
+ } else {
+ return null;
}
- return null;
+ }
+
+ /**
+ * Should be used if mime-type of enclosure tag is not supported. This
+ * method will return the mime-type of the file extension.
+ */
+ public static String getMimeTypeFromUrl(String url) {
+ if (url == null) {
+ return null;
+ }
+ String extension = FilenameUtils.getExtension(url);
+ if (extension == null) {
+ return null;
+ }
+
+ return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/NetworkUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/NetworkUtils.java
index 43158c471..1717bde0e 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/NetworkUtils.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/NetworkUtils.java
@@ -8,11 +8,6 @@ import android.net.wifi.WifiManager;
import android.support.v4.net.ConnectivityManagerCompat;
import android.text.TextUtils;
import android.util.Log;
-
-import com.squareup.okhttp.OkHttpClient;
-import com.squareup.okhttp.Request;
-import com.squareup.okhttp.Response;
-
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
@@ -22,6 +17,9 @@ import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.download.AntennapodHttpClient;
import de.danoeh.antennapod.core.storage.DBWriter;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
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 13aadf027..6251cc4a0 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
@@ -216,7 +216,7 @@ public abstract class PlaybackController {
Intent serviceIntent = new Intent(activity, PlaybackService.class);
serviceIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, media);
serviceIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED, false);
- serviceIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY, false);
+ serviceIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY, true);
boolean fileExists = media.localFileAvailable();
boolean lastIsStream = PlaybackPreferences.getCurrentEpisodeIsStream();
if (!fileExists && !lastIsStream && media instanceof FeedMedia) {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/syndication/HtmlToPlainText.java b/core/src/main/java/de/danoeh/antennapod/core/util/syndication/HtmlToPlainText.java
new file mode 100644
index 000000000..bd40f398d
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/syndication/HtmlToPlainText.java
@@ -0,0 +1,89 @@
+package de.danoeh.antennapod.core.util.syndication;
+
+import org.jsoup.helper.StringUtil;
+import org.jsoup.nodes.Element;
+import org.jsoup.nodes.Node;
+import org.jsoup.nodes.TextNode;
+import org.jsoup.select.NodeTraversor;
+import org.jsoup.select.NodeVisitor;
+
+/**
+ * This class is based on <code>HtmlToPlainText</code> from jsoup's examples package.
+ *
+ * HTML to plain-text. This example program demonstrates the use of jsoup to convert HTML input to lightly-formatted
+ * plain-text. That is divergent from the general goal of jsoup's .text() methods, which is to get clean data from a
+ * scrape.
+ * <p>
+ * Note that this is a fairly simplistic formatter -- for real world use you'll want to embrace and extend.
+ * </p>
+ * <p>
+ * To invoke from the command line, assuming you've downloaded the jsoup jar to your current directory:</p>
+ * <p><code>java -cp jsoup.jar org.jsoup.examples.HtmlToPlainText url [selector]</code></p>
+ * where <i>url</i> is the URL to fetch, and <i>selector</i> is an optional CSS selector.
+ *
+ * @author Jonathan Hedley, jonathan@hedley.net
+ * @author AntennaPod open source community
+ */
+public class HtmlToPlainText {
+
+ /**
+ * Format an Element to plain-text
+ * @param element the root element to format
+ * @return formatted text
+ */
+ public String getPlainText(Element element) {
+ FormattingVisitor formatter = new FormattingVisitor();
+ NodeTraversor traversor = new NodeTraversor(formatter);
+ traversor.traverse(element); // walk the DOM, and call .head() and .tail() for each node
+
+ return formatter.toString();
+ }
+
+ // the formatting rules, implemented in a breadth-first DOM traverse
+ private class FormattingVisitor implements NodeVisitor {
+
+ private StringBuilder accum = new StringBuilder(); // holds the accumulated text
+
+ // hit when the node is first seen
+ public void head(Node node, int depth) {
+ String name = node.nodeName();
+ if (node instanceof TextNode) {
+ append(((TextNode) node).text()); // TextNodes carry all user-readable text in the DOM.
+ }
+ else if (name.equals("li")) {
+ append("\n * ");
+ }
+ else if (name.equals("dt")) {
+ append(" ");
+ }
+ else if (StringUtil.in(name, "p", "h1", "h2", "h3", "h4", "h5", "tr")) {
+ append("\n");
+ }
+ }
+
+ // hit when all of the node's children (if any) have been visited
+ public void tail(Node node, int depth) {
+ String name = node.nodeName();
+ if (StringUtil.in(name, "br", "dd", "dt", "p", "h1", "h2", "h3", "h4", "h5")) {
+ append("\n");
+ } else if (name.equals("a")) {
+ append(String.format(" <%s>", node.absUrl("href")));
+ }
+ }
+
+ // appends text to the string builder with a simple word wrap method
+ private void append(String text) {
+ if (text.equals(" ") &&
+ (accum.length() == 0 || StringUtil.in(accum.substring(accum.length() - 1), " ", "\n"))) {
+ return; // don't accumulate long runs of empty spaces
+ }
+
+ accum.append(text);
+ }
+
+ @Override
+ public String toString() {
+ return accum.toString();
+ }
+ }
+}
diff --git a/core/src/main/res/drawable/bg_splash.xml b/core/src/main/res/drawable/bg_splash.xml
new file mode 100644
index 000000000..dd66e3083
--- /dev/null
+++ b/core/src/main/res/drawable/bg_splash.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item
+ android:drawable="@color/overlay_dark"/>
+
+ <item>
+ <bitmap
+ android:gravity="center"
+ android:src="@drawable/ic_launcher"/>
+ </item>
+
+</layer-list> \ No newline at end of file
diff --git a/core/src/main/res/values-az/strings.xml b/core/src/main/res/values-az/strings.xml
index 668c7ddc6..68e3c9de5 100644
--- a/core/src/main/res/values-az/strings.xml
+++ b/core/src/main/res/values-az/strings.xml
@@ -155,8 +155,6 @@
<string name="pref_rewind_sum">Geri düyməsinə tıklandığında geri tullanmaq üçün saniyə sayı özelleştirin</string>
<!--Auto-Flattr dialog-->
<!--Search-->
- <string name="search_hint">Kanalları və ya epizodları axtar</string>
- <string name="found_in_shownotes_label">Təsvirlərdə tapıldı</string>
<string name="found_in_chapters_label">Fəsillərdə tapıldı</string>
<string name="search_status_no_results">Heç nə tapılmadı</string>
<string name="search_label">Axtar</string>
diff --git a/core/src/main/res/values-b+ast/strings.xml b/core/src/main/res/values-b+ast/strings.xml
new file mode 100644
index 000000000..ad96d9f0f
--- /dev/null
+++ b/core/src/main/res/values-b+ast/strings.xml
@@ -0,0 +1,354 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<resources xmlns:tools="http://schemas.android.com/tools">
+ <!--Activitiy and fragment titles-->
+ <string name="feeds_label">Feeds</string>
+ <string name="statistics_label">Estadístiques</string>
+ <string name="add_feed_label">Amestar podcast</string>
+ <string name="episodes_label">Episodios</string>
+ <string name="all_episodes_short_label">Too</string>
+ <string name="favorite_episodes_label">Favoritos</string>
+ <string name="new_label">Nuevo</string>
+ <string name="settings_label">Axustes</string>
+ <string name="add_new_feed_label">Amestar podcast</string>
+ <string name="downloads_label">Descargues</string>
+ <string name="downloads_running_label">N\'execución</string>
+ <string name="downloads_completed_label">Completóse</string>
+ <string name="downloads_log_label">Rexistru</string>
+ <string name="subscriptions_label">Soscripciones</string>
+ <string name="subscriptions_list_label">Llistáu de soscripciones</string>
+ <string name="cancel_download_label">Encaboxar\ndescarga</string>
+ <string name="playback_history_label">Historial de reproducción</string>
+ <string name="gpodnet_main_label">gpodder.net</string>
+ <string name="gpodnet_auth_label">Aniciu de sesión de gpodder.net</string>
+ <string name="free_space_label">%1$s llibres</string>
+ <string name="episode_cache_full_title">Enllenóse la caché d\'episodios</string>
+ <string name="episode_cache_full_message">Algamóse la llende de la caché d\'episodios. Pues aumentar el tamañu de la caché n\'Axustes.</string>
+ <!--Statistics fragment-->
+ <string name="total_time_listened_to_podcasts">Tiempu total de podcasts reproducíos.</string>
+ <string name="statistics_details_dialog">%1$d de %2$d episodios aniciaos.\n\nReproducíos %3$s de %4$s.</string>
+ <!--Main activity-->
+ <string name="drawer_open">Abrir menú</string>
+ <string name="drawer_close">Zarrar menú</string>
+ <string name="drawer_preferences">Preferencies del caxón</string>
+ <string name="drawer_feed_order_unplayed_episodes">Ordenar pel contador</string>
+ <string name="drawer_feed_order_alphabetical">Ordenar alfabéticamente</string>
+ <string name="drawer_feed_order_last_update">Ordenar pela data d\'espublización</string>
+ <string name="drawer_feed_counter_new_unplayed">Númberu de episodios nuevos ensin reproducir</string>
+ <string name="drawer_feed_counter_new">Númberu d\'episodios nuevos</string>
+ <string name="drawer_feed_counter_unplayed">Númberos d\'episodios ensin reproducir</string>
+ <string name="drawer_feed_counter_downloaded">Númberu d\'episodios baxaos</string>
+ <string name="drawer_feed_counter_none">Dengún</string>
+ <!--Webview actions-->
+ <string name="open_in_browser_label">Abrir nel restolador</string>
+ <string name="copy_url_label">Copiar URL</string>
+ <string name="share_url_label">Compartir URL</string>
+ <string name="copied_url_msg">Copióse la URL al cartafueyu</string>
+ <string name="go_to_position_label">Dir a esta posición</string>
+ <!--Playback history-->
+ <string name="clear_history_label">Llimpiar historial</string>
+ <!--Other-->
+ <string name="confirm_label">Confirmar</string>
+ <string name="cancel_label">Encaboxar</string>
+ <string name="yes">Sí</string>
+ <string name="no">Non</string>
+ <string name="reset">Reafitar</string>
+ <string name="author_label">Autor</string>
+ <string name="language_label">Llingua</string>
+ <string name="url_label">URL</string>
+ <string name="podcast_settings_label">Axustes</string>
+ <string name="cover_label">Semeya</string>
+ <string name="error_label">Fallu</string>
+ <string name="error_msg_prefix">Asocedió un fallu:</string>
+ <string name="refresh_label">Refrescar</string>
+ <string name="external_storage_error_msg">Nun hai disponible dengún almacenamientu esternu. Asegúrate que ta montáu pa que l\'aplicación puea furrular afayadizamente.</string>
+ <string name="chapters_label">Capítulos</string>
+ <string name="description_label">Descripción</string>
+ <string name="most_recent_prefix">Episodiu más recién:\u0020</string>
+ <string name="episodes_suffix">\u0020episodios</string>
+ <string name="length_prefix">Llargor:\u0020</string>
+ <string name="size_prefix">Tamañu:\u0020</string>
+ <string name="processing_label">Procesando</string>
+ <string name="loading_label">Cargando...</string>
+ <string name="save_username_password_label">Guardar nome d\'usuariu y contraseña</string>
+ <string name="close_label">Zarrar</string>
+ <string name="retry_label">Retentar</string>
+ <string name="auto_download_label">Incluyir en descargues automátiques</string>
+ <string name="auto_download_apply_to_items_title">Aplicar a episodios previos</string>
+ <string name="parallel_downloads_suffix">\u0020descargues paraleles</string>
+ <string name="feed_auto_download_always">Siempres</string>
+ <string name="feed_auto_download_never">Enxamás</string>
+ <string name="send_label">Unviar...</string>
+ <string name="episode_cleanup_never">Enxamás</string>
+ <string name="episode_cleanup_queue_removal">Al nun tar na cola</string>
+ <string name="episode_cleanup_after_listening">Dempués de finar</string>
+ <plurals name="episode_cleanup_days_after_listening">
+ <item quantity="one">1 día dempués de finar</item>
+ <item quantity="other">%d díes dempués de finar</item>
+ </plurals>
+ <!--'Add Feed' Activity labels-->
+ <string name="feedurl_label">URL del feed</string>
+ <string name="etxtFeedurlHint">www.exemplu.com/feed</string>
+ <string name="txtvfeedurl_label">Amestar podcast pola URL</string>
+ <string name="podcastdirectories_label">Alcontrar podcast nel direutoriu</string>
+ <string name="podcastdirectories_descr">Pa podcasts nuevos, pues guetar n\'iTunes o fyyd, o restolar gpodder.net per nome, estaya o sonadía.</string>
+ <string name="browse_gpoddernet_label">Restolar gpodder.net</string>
+ <!--Actions on feeds-->
+ <string name="mark_all_read_label">Marcar too ccomo reproducío</string>
+ <string name="mark_all_read_msg">Conseñáronse tolos episodios como reproducíos</string>
+ <string name="mark_all_read_confirmation_msg">Confirma que quies conseñar tolos episodios como reproducíos, por favor.</string>
+ <string name="mark_all_read_feed_confirmation_msg">Confirma que quies conseñar tolos episodios nesti feed como reproducíos, por favor.</string>
+ <string name="mark_all_seen_label">Conseñar too como visto</string>
+ <string name="mark_all_seen_msg">Conseñáronse tolos episodios como vistos</string>
+ <string name="mark_all_seen_confirmation_msg">Confirma que quies conseñar tolos episodios como vistos.</string>
+ <string name="show_info_label">Amosar información</string>
+ <string name="rename_feed_label">Renomar podcast</string>
+ <string name="remove_feed_label">Desaniciar podcast</string>
+ <string name="share_label">Compartir...</string>
+ <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>
+ <string name="episode_actions">Aplicar aiciones</string>
+ <string name="hide_unplayed_episodes_label">Ensin reproducir</string>
+ <string name="hide_paused_episodes_label">Posóse</string>
+ <string name="hide_played_episodes_label">Reprodúxose</string>
+ <string name="hide_queued_episodes_label">Na cola</string>
+ <string name="hide_downloaded_episodes_label">Baxóse</string>
+ <string name="hide_not_downloaded_episodes_label">Nun se baxó</string>
+ <string name="hide_has_media_label">Tien medios</string>
+ <string name="filtered_label">Peñéróse</string>
+ <string name="open_podcast">Abrir podcast</string>
+ <!--actions on feeditems-->
+ <string name="download_label">Baxar</string>
+ <string name="play_label">Reproducir</string>
+ <string name="pause_label">Posar</string>
+ <string name="stop_label">Parar</string>
+ <string name="remove_label">Desaniciar</string>
+ <string name="delete_label">Desaniciar</string>
+ <string name="remove_episode_lable">Desaniciar episodiu</string>
+ <string name="marked_as_seen_label">Conseñóse como vistu</string>
+ <string name="mark_read_label">Conseñar como reproducíu</string>
+ <string name="marked_as_read_label">Conseñóse como reproducíu</string>
+ <string name="mark_unread_label">Conseñar como non reproducíu</string>
+ <string name="add_to_queue_label">Amestar a la cola</string>
+ <string name="added_to_queue_label">Amestóse a la cola</string>
+ <string name="remove_from_queue_label">Desaniciar de la cola</string>
+ <string name="add_to_favorite_label">Amestar a favoritos</string>
+ <string name="added_to_favorites">Amestóse a favoritos</string>
+ <string name="remove_from_favorite_label">Desaniciar de favoritos</string>
+ <string name="removed_from_favorites">Desanicióse de favoritos</string>
+ <string name="visit_website_label">Visitar sitiu web</string>
+ <string name="skip_episode_label">Saltar episodiu</string>
+ <string name="activate_auto_download">Activar descarga automática</string>
+ <string name="deactivate_auto_download">Desactivar descarga automática</string>
+ <string name="reset_position">Reaniciar posición de reproducción</string>
+ <string name="removed_item">Desanicióse l\'elementu</string>
+ <!--Download messages and labels-->
+ <string name="download_failed">falló</string>
+ <string name="download_pending">Descarga pendiente</string>
+ <string name="download_running">Descarga n\'execución</string>
+ <string name="download_error_device_not_found">Nun s\'alcontró\'l preséu d\'almacenamientu</string>
+ <string name="download_error_insufficient_space">Espaciu insuficiente</string>
+ <string name="download_error_file_error">Fallu de ficheru</string>
+ <string name="download_error_http_data_error">Fallu de datos HTTP</string>
+ <string name="download_error_error_unknown">Fallu desconocíu</string>
+ <string name="download_error_parser_exception">Esceición del analizador</string>
+ <string name="download_error_unsupported_type">Triba non sofitada de feed</string>
+ <string name="download_error_connection_error">Fallu de conexón</string>
+ <string name="download_error_unknown_host">Agospiu desconocíu</string>
+ <string name="download_error_unauthorized">Fallu d\'autenticación</string>
+ <string name="download_error_file_type_type">Fallu de triba de ficheru</string>
+ <string name="download_error_forbidden">Prohibío</string>
+ <string name="cancel_all_downloads_label">Encaboxar toles descargues</string>
+ <string name="download_canceled_msg">Encaboxóse la descarga</string>
+ <string name="download_canceled_autodownload_enabled_msg">Encaboxóse la descarga\nDesabilitóse la <i>auto-descarga</i> pa esti elementu</string>
+ <string name="download_report_title">Les descargues completáronse con fallos</string>
+ <string name="download_report_content_title">Informe de descarga</string>
+ <string name="download_error_malformed_url">URL mal formada</string>
+ <string name="download_error_io_error">Fallu d\'ES</string>
+ <string name="download_error_request_error">Fallu de solicitú</string>
+ <string name="download_error_db_access">Fallu d\'accesu a la base de datos</string>
+ <plurals name="downloads_left">
+ <item quantity="one">%d descarga restante</item>
+ <item quantity="other">%d descargues restantes</item>
+ </plurals>
+ <string name="downloads_processing">Procesando descargues</string>
+ <string name="download_notification_title">Baxando datos del podcast</string>
+ <string name="download_report_content">%1$d descargues esitoses, %2$d fallaron</string>
+ <string name="download_log_title_unknown">Títulu desconocíu</string>
+ <string name="download_type_feed">Feed</string>
+ <string name="download_type_media">Triba de mediu</string>
+ <string name="download_type_image">Imaxe</string>
+ <string name="download_request_error_dialog_message_prefix">Asocedió un fallu al tentar de baxar el ficheru:\u0020</string>
+ <string name="authentication_notification_title">Ríquese l\'autenticación</string>
+ <string name="authentication_notification_msg">El recursu que solicitesti rique un nome d\'usuariu y una contraseña</string>
+ <string name="confirm_mobile_download_dialog_title">Confirmar descarga móvil</string>
+ <string name="confirm_mobile_download_dialog_message_not_in_queue">Deshabilitóse n\'axustes la descarga pente datos móviles.\n\nPues escoyer ente amestar l\'episodiu a la cola o permitir la descarga temporal.\n\n<small>La to escoyeta recordaráse 10 minutos</small></string>
+ <string name="confirm_mobile_download_dialog_message">Deshabilitóse n\'axustes la descarga pente datos móviles.\n\n¿Quies permitir la descarga temporal?\n\n<small>La to escoyeta recordaráse 10 minutos</small></string>
+ <string name="confirm_mobile_download_dialog_only_add_to_queue">Poner na cola</string>
+ <string name="confirm_mobile_download_dialog_enable_temporarily">Pemitir temporalmente</string>
+ <!--Mediaplayer messages-->
+ <string name="player_error_msg">¡Fallu!</string>
+ <string name="player_stopped_msg">Nun hai medios en reproducción</string>
+ <string name="player_preparing_msg">Tresnando</string>
+ <string name="player_ready_msg">Preparáu</string>
+ <string name="playback_error_server_died">Morrió\'l servidor</string>
+ <string name="playback_error_unknown">Fallu desconocíu</string>
+ <string name="no_media_playing_label">Nun hai medios en reproducción</string>
+ <string name="player_buffering_msg">Atroxando nel búfer</string>
+ <string name="playbackservice_notification_title">Reproduciendo podcast</string>
+ <string name="unknown_media_key">AntennaPod - Clave desconocida de medios: %1$d</string>
+ <!--Queue operations-->
+ <string name="lock_queue">Bloquiar cola</string>
+ <string name="unlock_queue">Desbloquiar cola</string>
+ <string name="queue_locked">Bloquióse la cola</string>
+ <string name="queue_unlocked">Desbloquióse la cola</string>
+ <string name="clear_queue_label">Llimpiar cola</string>
+ <string name="undo">Desfacer</string>
+ <string name="removed_from_queue">Desanicióse l\'elementu</string>
+ <string name="move_to_top_label">Xubir</string>
+ <string name="move_to_bottom_label">Baxar</string>
+ <string name="sort">Ordenar</string>
+ <string name="date">Data</string>
+ <string name="duration">Duración</string>
+ <string name="episode_title">Títulu d\'episodiu</string>
+ <string name="feed_title">Títulu del feed</string>
+ <string name="ascending">Ascendente</string>
+ <string name="descending">Descendente</string>
+ <string name="clear_queue_confirmation_msg">Confirma que quies llimpiar la tola de TOLO episodios nella, por favor.</string>
+ <!--Flattr-->
+ <string name="flattr_auth_label">Aniciu de sesión de Flattr</string>
+ <string name="flattr_auth_explanation">Primi\'l botón d\'embaxo pa entamar el procesu d\'autenticación. Amosaráse la pantalla d\'aniciu de sesión de Flattr y pidirásete que-y deas permisu a AntennaPod pa facer flattr a coses. Dempués d\'eso, volverás a esta pantalla automáticamente.</string>
+ <string name="authenticate_label">Autenticar</string>
+ <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="authenticate_now_label">Autenticar</string>
+ <!--Flattr-->
+ <!--Variable Speed-->
+ <string name="download_plugin_label">Baxar complementu</string>
+ <string name="no_playback_plugin_title">Nun s\'instaló\'l complementu</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="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_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_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>
+ <string name="pref_followQueue_title">Reproducción continua</string>
+ <string name="pref_mobileUpdate_sum">Permite los anovamientos pente la conexón de datos móviles</string>
+ <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_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_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_showDownloadReport_title">Amosar informe de descarga</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_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>
+ <!--Auto-Flattr dialog-->
+ <!--Search-->
+ <!--OPML import and export-->
+ <string name="start_import_label">Aniciar importación</string>
+ <string name="opml_import_label">Importación d\'OPML</string>
+ <string name="opml_directory_error">¡Fallu!</string>
+ <string name="reading_opml_label">Lleendo\'l ficheru OPML</string>
+ <string name="opml_reader_error">Asocedió un fallu entrín se lleía\'l documentu OPML:</string>
+ <string name="opml_import_error_no_file">¡Nun s\'esbillaron ficheros!</string>
+ <string name="select_all_label">Esbillar too</string>
+ <string name="deselect_all_label">Nun esbillar nada</string>
+ <string name="select_options_label">Esbillar...</string>
+ <string name="opml_export_label">Esportación d\'OPML</string>
+ <string name="html_export_label">Esportación de HTML</string>
+ <string name="exporting_label">Esportando...</string>
+ <string name="export_error_label">Fallu d\'esportación</string>
+ <string name="opml_import_ask_read_permission">Ríquese l\'accesu al almacenamientu internu pa lleer el ficheru OPML</string>
+ <!--Sleep timer-->
+ <string name="timer_vibration_label">Vibrar</string>
+ <string name="time_seconds">segundos</string>
+ <string name="time_minutes">minutos</string>
+ <string name="time_hours">hores</string>
+ <!--gpodder.net-->
+ <string name="gpodnet_taglist_header">ESTAYES</string>
+ <string name="gpodnet_toplist_header">DESTACAO</string>
+ <string name="gpodnet_suggestions_header">SUXERENCIES</string>
+ <string name="username_label">Nome d\'usuariu</string>
+ <string name="password_label">Contraseña</string>
+ <string name="gpodnetauth_device_title">Esbilla de preséu</string>
+ <string name="gpodnetauth_device_descr">Crea un preséu nuevu pa usalu cola to cuente de gpodder.net o escueyi ún esistente:</string>
+ <string name="gpodnetauth_device_deviceID">ID de preséu:\u0020</string>
+ <string name="gpodnetauth_device_butCreateNewDevice">Crear preséu nuevu</string>
+ <string name="gpodnetauth_device_chooseExistingDevice">Escoyer preséu esistente:</string>
+ <string name="gpodnetauth_device_errorEmpty">La ID del preséu nun ha tar balera</string>
+ <string name="gpodnetauth_device_errorAlreadyUsed">La ID del preséu yá ta n\'usu</string>
+ <string name="gpodnetauth_device_butChoose">Escoyer</string>
+ <string name="gpodnetauth_finish_butgomainscreen">Dir a la pantalla principal</string>
+ <string name="gpodnetsync_auth_error_title">Fallu d\'autenticación de gpodder.net</string>
+ <string name="gpodnetsync_error_descr">Asocedió un fallu na sincronización:\u0020</string>
+ <!--Directory chooser-->
+ <string name="selected_folder_label">Carpeta esbillada:</string>
+ <string name="create_folder_label">Crear carpeta</string>
+ <string name="choose_data_directory_permission_rationale">Ríquese l\'accesu al almacenamientu esternu pa camudar la carpeta de datos</string>
+ <string name="create_folder_msg">¿Crear carpeta nueva col nome «%1$s»?</string>
+ <string name="create_folder_success">Creóse la carpeta nueva</string>
+ <string name="create_folder_error_no_write_access">Nun pue escribise a esta carpeta</string>
+ <string name="create_folder_error_already_exists">Yá esiste la carpeta</string>
+ <string name="create_folder_error">Nun pudo crease la carpeta</string>
+ <string name="folder_not_empty_dialog_title">La carpeta nun ta balera</string>
+ <!--Online feed view-->
+ <string name="downloading_label">Baxando...</string>
+ <!--Content descriptions for image buttons-->
+ <string name="rewind_label">Rebobinar</string>
+ <string name="fast_forward_label">Avance rápidu</string>
+ <string name="media_type_audio_label">Audiu</string>
+ <string name="media_type_video_label">Videu</string>
+ <!--Feed information screen-->
+ <string name="authentication_label">Autenticación</string>
+ <!--Progress information-->
+ <!--AntennaPodSP-->
+ <!--Episodes apply actions-->
+ <string name="all_label">Too</string>
+ <string name="selected_all_label">Esbilláronse tolos episodios</string>
+ <!--Sort-->
+ <!--Rating dialog-->
+ <string name="rating_title">¿Préstate AntennaPod?</string>
+ <string name="rating_message">Agradeceriemos que valores a AntennaPod si pues y quies.</string>
+ <string name="rating_never_label">Dexáime solu</string>
+ <string name="rating_later_label">Recordáimelo más sero</string>
+ <string name="rating_now_label">¡Sí, vamos facelo!</string>
+ <!--Audio controls-->
+ <string name="audio_controls">Controles d\'audiu</string>
+ <string name="playback_speed">Velocidá de reproducción</string>
+ <string name="volume">Volume</string>
+ <string name="left_short">I</string>
+ <string name="right_short">D</string>
+ <string name="audio_effects">Efeutos d\'audiu</string>
+ <!--proxy settings-->
+ <string name="proxy_type_label">Triba</string>
+ <string name="host_label">Agospiu</string>
+ <string name="port_label">Puertu</string>
+ <string name="optional_hint">(Opcional)</string>
+ <string name="proxy_checking">Comprobando...</string>
+ <!--Casting-->
+ <!--<string name="cast_failed_to_connect">Could not connect to the device</string>-->
+</resources>
diff --git a/core/src/main/res/values-ca-rES/strings.xml b/core/src/main/res/values-ca-rES/strings.xml
index 28dfeb6e8..4b0bf218c 100644
--- a/core/src/main/res/values-ca-rES/strings.xml
+++ b/core/src/main/res/values-ca-rES/strings.xml
@@ -1,8 +1,31 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources xmlns:tools="http://schemas.android.com/tools">
<!--Activitiy and fragment titles-->
+ <string name="statistics_label">Estadístiques</string>
+ <string name="add_feed_label">Afegir Podcast</string>
+ <string name="episodes_label">Episodis</string>
+ <string name="all_episodes_short_label">Tots</string>
+ <string name="favorite_episodes_label">Preferits</string>
+ <string name="new_label">Nous</string>
+ <string name="settings_label">Ajustaments</string>
+ <string name="add_new_feed_label">Afegir Podcast</string>
+ <string name="downloads_label">Descàrregues</string>
+ <string name="downloads_running_label">Actius</string>
+ <string name="downloads_completed_label">Finalitzats</string>
+ <string name="downloads_log_label">Log</string>
+ <string name="subscriptions_label">Subscripcions</string>
+ <string name="subscriptions_list_label">Llista de subscripcions</string>
+ <string name="playback_history_label">Historial de Reproducció</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 lliures</string>
+ <string name="episode_cache_full_title">Cache d´episodis ple</string>
<!--Statistics fragment-->
<!--Main activity-->
+ <string name="drawer_feed_order_alphabetical">Ordenar alfabeticament</string>
+ <string name="drawer_feed_order_last_update">Ordenar per data de publicacio</string>
+ <string name="drawer_feed_counter_new_unplayed">Nombre d´episodis nous mes nombre d´episodis no reproduits</string>
+ <string name="drawer_feed_counter_new">Nombre de episodis nous</string>
<!--Webview actions-->
<!--Playback history-->
<!--Other-->
diff --git a/core/src/main/res/values-ca/strings.xml b/core/src/main/res/values-ca/strings.xml
index 83114b9f4..fa9ec6cfd 100644
--- a/core/src/main/res/values-ca/strings.xml
+++ b/core/src/main/res/values-ca/strings.xml
@@ -85,7 +85,6 @@
<string name="etxtFeedurlHint">URL, canal o lloc web</string>
<string name="txtvfeedurl_label">Afegeix podcast amb l\'URL</string>
<string name="podcastdirectories_label">Cerca podcast al directori</string>
- <string name="podcastdirectories_descr">Podeu cercar nous podcasts al directori de gpodder.net mitjançant el seu nom, categoria o popularitat.</string>
<string name="browse_gpoddernet_label">Navega gpodder.net</string>
<!--Actions on feeds-->
<string name="mark_all_read_label">Marca-ho tot com a llegit</string>
@@ -359,8 +358,6 @@
<string name="auto_flattr_ater_beginning">Comparteix per Flattr l\'episodi en haver-ne iniciat la reproducció</string>
<string name="auto_flattr_ater_end">Comparteix per Flattr l\'episodi en acabar-se\'n la reproducció</string>
<!--Search-->
- <string name="search_hint">Cerca canals o episodis</string>
- <string name="found_in_shownotes_label">Trobat a notes del programa</string>
<string name="found_in_chapters_label">Trobat als capítols</string>
<string name="search_status_no_results">No s\'ha trobat cap resultat</string>
<string name="search_label">Cerca</string>
diff --git a/core/src/main/res/values-cs-rCZ/strings.xml b/core/src/main/res/values-cs-rCZ/strings.xml
index 0e6cfdfe4..6f9f94781 100644
--- a/core/src/main/res/values-cs-rCZ/strings.xml
+++ b/core/src/main/res/values-cs-rCZ/strings.xml
@@ -94,7 +94,6 @@
<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">Můžete vyhledávat nové podcasty podle jména, kategorie nebo popularity v seznamu gpodder.net.</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>
@@ -345,8 +344,6 @@
<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_title">Synchronizovat nyní</string>
- <string name="pref_gpodnet_sync_sum">Synchronizovat odběry a stav epizod s gpodder.net</string>
<string name="pref_gpodnet_sync_started">Synchronizace spuštěna</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_playback_speed_title">Rychlosti přehrávání</string>
@@ -360,6 +357,9 @@
<string name="pref_persistNotify_title">Pevné ovládání přehrávání</string>
<string name="pref_persistNotify_sum">Zachovat upozornění a ovládání na obrazovce uzamčení i při pozastaveném přehrávání.</string>
<string name="pref_compact_notification_buttons_title">Nastavení tlačítek uzamčené obrazovky</string>
+ <string name="pref_compact_notification_buttons_sum">Změnit tlačítka ovládání na obrazovce uzamčení. Tlačítka přehrát/pozastavit jsou vždy zobrazena.</string>
+ <string name="pref_compact_notification_buttons_dialog_title">Vybrat maximálně %1$d položek</string>
+ <string name="pref_compact_notification_buttons_dialog_error">Lze vybrat maximálně %1$d položek.</string>
<string name="pref_lockscreen_background_title">Nastavit pozadí uzamčené obrazovky</string>
<string name="pref_lockscreen_background_sum">Nastavit pozadí uzamčené obrazovky na obrázek aktuální epizody. Jako vedlejší efekt zobrazí toto nastavení obrázek i v aplikacích třetích stran. </string>
<string name="pref_showDownloadReport_title">Zobrazit report stahování</string>
@@ -385,14 +385,14 @@
<string name="pref_cast_title">Chromecast podpora</string>
<string name="pref_rewind_sum">Přizpůsobte počet sekund ke skoku zpět při klepnutí na tlačítko převíjení</string>
<string name="pref_fast_forward_sum">Přizpůsobit počet sekund skok dopředu při klepnutí na tlačítko rychle vpřed</string>
+ <string name="pref_cast_message_play_flavor">Povolit podporu vzdáleného přehrávání médií na Cast přístrojích (jako třeba Chromecast, Audio Speakers nebo Android TV)</string>
+ <string name="pref_cast_message_free_flavor">Chromecast vyžaduje proprietární knihovny třetích stran, které jsou vypnuty v této verzi AntennaPod</string>
<!--Auto-Flattr dialog-->
<string name="auto_flattr_enable">Povolit automatické flattrování</string>
<string name="auto_flattr_after_percent">Flattrovat díl jakmile bude odehráno %d procent</string>
<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 kanály a epizody</string>
- <string name="found_in_shownotes_label">Nalezeno v poznámkách k show</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>
@@ -467,6 +467,7 @@
<string name="gpodnetauth_device_chooseExistingDevice">Vybrat existující zařízení:</string>
<string name="gpodnetauth_device_errorEmpty">ID zařízení nesmí být prázdné</string>
<string name="gpodnetauth_device_errorAlreadyUsed">ID zařízení je již obsazeno</string>
+ <string name="gpodnetauth_device_caption_errorEmpty">Titulek nesmí být prázdný</string>
<string name="gpodnetauth_device_butChoose">Vybrat</string>
<string name="gpodnetauth_finish_title">Úspěšně přihlášeno!</string>
<string name="gpodnetauth_finish_descr">Gratulujeme! Váš gpodder.net účet je nyní úspěšně propojen s vaším zařízením. AntennaPod bude automaticky synchronizovat odebírané podcasty s nastaveným účtem na gpodder.net.</string>
@@ -582,8 +583,14 @@
<!--Casting-->
<string name="cast_media_route_menu_title">Přehrát na...</string>
<string name="cast_disconnect_label">Odpojit sezení vysílání</string>
+ <string name="cast_not_castable">Vybraná média nejsou kompatibilní s přehrávacím přístrojem</string>
+ <string name="cast_failed_to_play">Selhalo spuštění přehrávání média</string>
+ <string name="cast_failed_to_stop">Selhalo zastavení přehrávání média</string>
+ <string name="cast_failed_to_pause">Selhalo pozastavení přehrávání média</string>
<!--<string name="cast_failed_to_connect">Could not connect to the device</string>-->
<string name="cast_failed_setting_volume">Selhalo nastavení hlasitosti</string>
+ <string name="cast_failed_no_connection">Není dostupné připojení k přehrávacímu přístroji</string>
+ <string name="cast_failed_no_connection_trans">Došlo ke ztrátě připojení k přehrávacímu přístroji. Aplikace se pokouší znovu připojit, pokud to bude možné. Počkejte několik sekund a zkuste znovu.</string>
<string name="cast_failed_perform_action">Selhalo provedení akce</string>
<string name="cast_failed_status_request">Selhala synchronizace s vysílačem</string>
<string name="cast_failed_seek">Selhal posun na novou pozici na vysílači</string>
diff --git a/core/src/main/res/values-da/strings.xml b/core/src/main/res/values-da/strings.xml
index 245db6f7d..a64fa68bf 100644
--- a/core/src/main/res/values-da/strings.xml
+++ b/core/src/main/res/values-da/strings.xml
@@ -54,7 +54,6 @@
<string name="etxtFeedurlHint">URL af feed eller webside</string>
<string name="txtvfeedurl_label">Tilføj Podcast med URL</string>
<string name="podcastdirectories_label">Find podcast i mappen</string>
- <string name="podcastdirectories_descr">Du kan søge efter nye podcasts efter navn, kategori eller popularitet i gpodder.net biblioteket</string>
<string name="browse_gpoddernet_label">Gennemse gpodder.net</string>
<!--Actions on feeds-->
<string name="mark_all_read_label">Marker alle som læst</string>
@@ -234,8 +233,6 @@
<string name="auto_flattr_ater_beginning">Flattr episoder når afspilning starter</string>
<string name="auto_flattr_ater_end">Flattr episoder når afspilning slutter</string>
<!--Search-->
- <string name="search_hint">Søg efter feeds eller episoder</string>
- <string name="found_in_shownotes_label">Funder i showets noter</string>
<string name="found_in_chapters_label">Fundet i kapitler</string>
<string name="search_status_no_results">Fandt ingen resultater</string>
<string name="search_label">Søg</string>
diff --git a/core/src/main/res/values-de/strings.xml b/core/src/main/res/values-de/strings.xml
index aaadccded..0f820b047 100644
--- a/core/src/main/res/values-de/strings.xml
+++ b/core/src/main/res/values-de/strings.xml
@@ -92,7 +92,6 @@
<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">Bei gpodder.net kannst du neue Podcasts nach Name, Kategorie oder Popularität suchen. Oder suche bei iTunes.</string>
<string name="browse_gpoddernet_label">gpodder.net durchsuchen</string>
<!--Actions on feeds-->
<string name="mark_all_read_label">Alle als gespielt markieren</string>
@@ -342,8 +341,6 @@
<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_title">Jetzt synchronisieren</string>
- <string name="pref_gpodnet_sync_sum">Synchronisiere Abonnements und Episodenstatus mit gpodder.net</string>
<string name="pref_gpodnet_sync_started">Synchronisation starten</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_playback_speed_title">Wiedergabegeschwindigkeiten</string>
@@ -386,15 +383,13 @@
<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_rewind_sum">Passen Sie die Anzahl der Sekunden rückwärts zu springen, wenn die Rücklauf -Taste angeklickt wird</string>
<string name="pref_fast_forward_sum">Passen Sie die Anzahl der Sekunden nach vorne zu springen, wenn die Schnellvorlauf -Taste angeklickt wird</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>
<!--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 Feeds oder Episoden</string>
- <string name="found_in_shownotes_label">In Sendungsnotizen gefunden</string>
<string name="found_in_chapters_label">In Kapiteln gefunden</string>
<string name="search_status_no_results">Keine Ergebnisse gefunden</string>
<string name="search_label">Suche</string>
diff --git a/core/src/main/res/values-el/strings.xml b/core/src/main/res/values-el/strings.xml
index 3e855165e..867dd49c6 100644
--- a/core/src/main/res/values-el/strings.xml
+++ b/core/src/main/res/values-el/strings.xml
@@ -2,15 +2,21 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!--Activitiy and fragment titles-->
<string name="feeds_label">Ροές</string>
+ <string name="statistics_label">Στατιστικά</string>
+ <string name="add_feed_label">Προσθήκη Podcast</string>
<string name="episodes_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="add_new_feed_label">Προσθήκη Podcast</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="cancel_download_label">Ακύρωση\nΛήψης</string>
<string name="playback_history_label">Ιστορικό Αναπαραγωγής</string>
<string name="gpodnet_main_label">gpodder.net</string>
<string name="gpodnet_auth_label">gpodder.net Σύνδεση</string>
@@ -58,7 +64,6 @@
<string name="feedurl_label">URL της Ροής</string>
<string name="etxtFeedurlHint">www.example.com/feed</string>
<string name="txtvfeedurl_label">Προσθήκη Podcast με τη διεύθυνση URL</string>
- <string name="podcastdirectories_descr">Μπορείτε να ψάξετε για νέα podcast από το όνομα, κατηγορία ή δημοτικότητα στον κατάλογο του iTunes.</string>
<string name="browse_gpoddernet_label">Περιήγηση στο gpodder.net</string>
<!--Actions on feeds-->
<string name="show_info_label">Εμφάνιση πληροφοριών</string>
@@ -233,8 +238,6 @@
<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>
@@ -321,7 +324,7 @@
<string name="media_type_audio_label">Ήχος</string>
<string name="media_type_video_label">Βίντεο</string>
<string name="navigate_upwards_label">Πλοήγηση προς τα πάνω</string>
- <string name="status_downloading_label">Το επεισόδιο γίνεται λήφθετε</string>
+ <string name="status_downloading_label">Λήψη επεισοδίου</string>
<string name="in_queue_label">Το επεισόδιο είναι στη σειρά αναμονής</string>
<string name="drag_handle_content_description">Σύρετε για να αλλάξετε τη θέση αυτού του στοιχείου</string>
<string name="load_next_page_label">Τοποθέτηση επόμενης σελίδας</string>
@@ -334,7 +337,7 @@
<string name="search_itunes_label">iTunes Αναζήτηση</string>
<!--Episodes apply actions-->
<string name="all_label">Όλα</string>
- <string name="downloaded_label">Ειλημμένα</string>
+ <string name="downloaded_label">Λήψεις</string>
<!--Sort-->
<!--Rating dialog-->
<!--Audio controls-->
diff --git a/core/src/main/res/values-es-rES/strings.xml b/core/src/main/res/values-es-rES/strings.xml
index e00a8b672..8eea1641f 100644
--- a/core/src/main/res/values-es-rES/strings.xml
+++ b/core/src/main/res/values-es-rES/strings.xml
@@ -183,8 +183,6 @@
<string name="pref_fast_forward_sum">Personalizar el número de segundos para saltar hacia adelante cuando se hace clic en el botón de avance rápido</string>
<!--Auto-Flattr dialog-->
<!--Search-->
- <string name="search_hint">Buscar canales o episodios</string>
- <string name="found_in_shownotes_label">Encontrado en las notas del programa</string>
<string name="found_in_chapters_label">Encontrado en los capítulos</string>
<string name="search_status_no_results">No se han encontrado resultados</string>
<string name="search_label">Buscar</string>
diff --git a/core/src/main/res/values-es/strings.xml b/core/src/main/res/values-es/strings.xml
index 3653c1b60..821d9ae2b 100644
--- a/core/src/main/res/values-es/strings.xml
+++ b/core/src/main/res/values-es/strings.xml
@@ -36,6 +36,7 @@
<string name="drawer_feed_counter_new_unplayed">Cantidad de episodios nuevos y no escuchados</string>
<string name="drawer_feed_counter_new">Cantidad de episodios nuevos</string>
<string name="drawer_feed_counter_unplayed">Cantidad de episodios no escuchados</string>
+ <string name="drawer_feed_counter_downloaded">Cantidad de episodios descargados</string>
<string name="drawer_feed_counter_none">Ninguno</string>
<!--Webview actions-->
<string name="open_in_browser_label">Abrir en el navegador</string>
@@ -50,6 +51,7 @@
<string name="cancel_label">Cancelar</string>
<string name="yes">Sí</string>
<string name="no">No</string>
+ <string name="reset">Resetear</string>
<string name="author_label">Autor</string>
<string name="language_label">Idioma</string>
<string name="url_label">URL</string>
@@ -92,7 +94,7 @@
<string name="etxtFeedurlHint">www.ejemplo.com/feed</string>
<string name="txtvfeedurl_label">Añadir podcast por URL</string>
<string name="podcastdirectories_label">Buscar podcast en directorio</string>
- <string name="podcastdirectories_descr">Es posible buscar podcasts nuevos por nombre, categoría o popularidad en el directorio de gpodder.net.</string>
+ <string name="podcastdirectories_descr">Para podcasts nuevos, puedes buscar en iTunes o fyyd, o explorar gpodder.net por nombre, categoría o popularidad.</string>
<string name="browse_gpoddernet_label">Explorar gpodder.net</string>
<!--Actions on feeds-->
<string name="mark_all_read_label">Marcar todos como escuchado</string>
@@ -100,7 +102,10 @@
<string name="mark_all_read_confirmation_msg">Confirme que quiere marcar todos los episodios como escuchados.</string>
<string name="mark_all_read_feed_confirmation_msg">Confirme que quiere marcar todos los episodios de este canal como escuchados.</string>
<string name="mark_all_seen_label">Marcar todos como vistos</string>
+ <string name="mark_all_seen_msg">Marcar todos los episodios como vistos</string>
+ <string name="mark_all_seen_confirmation_msg">Por favor confirma que quieres marcar todos los episodios como vistos.</string>
<string name="show_info_label">Información del programa</string>
+ <string name="rename_feed_label">Renombrar Podcast</string>
<string name="remove_feed_label">Eliminar podcast</string>
<string name="share_label">Compartir…</string>
<string name="share_link_label">Compartir el enlace de la web</string>
@@ -120,6 +125,7 @@
<string name="hide_not_queued_episodes_label">No en cola</string>
<string name="hide_downloaded_episodes_label">Descargados</string>
<string name="hide_not_downloaded_episodes_label">No descargados</string>
+ <string name="hide_has_media_label">Tiene multimedia</string>
<string name="filtered_label">Filtrados</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Error en última actualización</string>
<string name="open_podcast">Abrir Podcast</string>
@@ -130,6 +136,7 @@
<string name="stop_label">Detener</string>
<string name="stream_label">Transmitir</string>
<string name="remove_label">Quitar</string>
+ <string name="delete_label">Borrar</string>
<string name="remove_episode_lable">Quitar episodio</string>
<string name="marked_as_seen_label">Marcar como visto</string>
<string name="mark_read_label">Marcar como escuchado</string>
@@ -276,6 +283,8 @@
<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>
<string name="pref_followQueue_sum">Saltar al siguiente elemento de la cola al acabar la reproducción</string>
<string name="pref_auto_delete_sum">Borrar episodio cuando finalice la reproducción</string>
<string name="pref_auto_delete_title">Eliminar automáticamente</string>
@@ -342,10 +351,16 @@
<string name="pref_gpodnet_logout_toast">Ha cerrado la sesión correctamente.</string>
<string name="pref_gpodnet_setlogin_information_title">Cambiar información de acceso</string>
<string name="pref_gpodnet_setlogin_information_sum">Modificar datos de inicio de sesión en gpodder.net.</string>
- <string name="pref_gpodnet_sync_title">Sincronizar ahora</string>
- <string name="pref_gpodnet_sync_sum">Sincronizar suscripciones y estados con gpodder.net</string>
+ <string name="pref_gpodnet_sync_changes_title">Sincronizar cambios ahora</string>
+ <string name="pref_gpodnet_sync_changes_sum">Sincronizar cambios del estado de subscripción y episodio con gpodder.net.</string>
+ <string name="pref_gpodnet_full_sync_title">Sincronización completa ahora</string>
+ <string name="pref_gpodnet_full_sync_sum">Sincronizar el estado de todas las suscripciones y estados de episodio con gpodder.net.</string>
+ <string name="pref_gpodnet_sync_sum_last_sync_line">Último intento de sincronización: %1$s (%2$s)</string>
<string name="pref_gpodnet_sync_started">Comenzó sincronización</string>
+ <string name="pref_gpodnet_full_sync_started">Comenzó sincronización completa</string>
<string name="pref_gpodnet_login_status"><![CDATA[Autenticado como <i>%1$s</i> con dispositivo <i>%2$s</i>]]></string>
+ <string name="pref_gpodnet_notifications_title">Mostrar notificaciones de errores de sincronización</string>
+ <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>
@@ -395,12 +410,13 @@
<string name="auto_flattr_ater_beginning">Hacer Flattr del episodio al comenzar la reproducción</string>
<string name="auto_flattr_ater_end">Hacer Flattr del episodio al terminar la reproducción</string>
<!--Search-->
- <string name="search_hint">Buscar canales o episodios</string>
- <string name="found_in_shownotes_label">Encontrado en las notas del programa</string>
+ <string name="search_hint">Buscar episodios</string>
+ <string name="found_in_shownotes_label">Encontrado en las notas del show</string>
<string name="found_in_chapters_label">Encontrado en los capítulos</string>
<string name="search_status_no_results">No se han encontrado resultados</string>
<string name="search_label">Buscar</string>
<string name="found_in_title_label">Encontrado en el título</string>
+ <string name="no_results_for_query">No se han encontrado resultados para \"%1$s\"</string>
<!--OPML import and export-->
<string name="opml_import_txtv_button_lable">Los archivos OPML le permiten migrar sus podcasts de una aplicación a otra.</string>
<string name="opml_import_option">Opción %1$d</string>
@@ -419,6 +435,7 @@
<string name="choose_file_from_filesystem">Desde el sistema de ficheros local</string>
<string name="choose_file_from_external_application">Usar aplicación externa</string>
<string name="opml_export_label">Exportar a OPML</string>
+ <string name="html_export_label">Exportar a HTML</string>
<string name="exporting_label">Exportando…</string>
<string name="export_error_label">Error en la exportación</string>
<string name="opml_export_success_title">Exportación a OPML exitosa</string>
@@ -449,6 +466,9 @@
<item quantity="one">1 hora</item>
<item quantity="other">%d horas</item>
</plurals>
+ <string name="auto_enable_label">Auto-habilitar</string>
+ <string name="sleep_timer_enabled_label">Temporizador de sueño habilitado</string>
+ <string name="sleep_timer_disabled_label">Temporizador de sueño deshabilitado</string>
<!--gpodder.net-->
<string name="gpodnet_taglist_header">CATEGORÍAS</string>
<string name="gpodnet_toplist_header">MEJORES PODCASTS</string>
@@ -478,6 +498,8 @@
<string name="gpodnetsync_auth_error_descr">Usuario o contraseña incorrectos</string>
<string name="gpodnetsync_error_title">Error de sincronización de gpodder.net</string>
<string name="gpodnetsync_error_descr">Ocurrió un error de sincronización:\u0020</string>
+ <string name="gpodnetsync_pref_report_successful">Exitoso</string>
+ <string name="gpodnetsync_pref_report_failed">Fallido</string>
<!--Directory chooser-->
<string name="selected_folder_label">Carpeta seleccionada</string>
<string name="create_folder_label">Crear carpeta</string>
@@ -530,6 +552,7 @@
<string name="sp_apps_importing_feeds_msg">Importando subscripciones de aplicaciones de uso específico...</string>
<string name="search_itunes_label">Buscar en iTunes</string>
<string name="filter">Filtro</string>
+ <string name="search_fyyd_label">Buscar fyyd</string>
<!--Episodes apply actions-->
<string name="all_label">Todo</string>
<string name="selected_all_label">Seleccionados todos los episodios</string>
@@ -547,6 +570,8 @@
<string name="selected_queued_label">Seleccionados episodios en cola</string>
<string name="not_queued_label">No en cola</string>
<string name="selected_not_queued_label">Seleccionados episodios no en cola</string>
+ <string name="has_media">Tiene multimedia</string>
+ <string name="selected_has_media_label">Seleccionar episodios con multimedia</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-et/strings.xml b/core/src/main/res/values-et/strings.xml
index c2f84138e..cb7478a3f 100644
--- a/core/src/main/res/values-et/strings.xml
+++ b/core/src/main/res/values-et/strings.xml
@@ -14,6 +14,8 @@
<string name="downloads_running_label">Käimas</string>
<string name="downloads_completed_label">Lõpetatud</string>
<string name="downloads_log_label">Logi</string>
+ <string name="subscriptions_label">Tellimused</string>
+ <string name="subscriptions_list_label">Tellimuste nimekiri</string>
<string name="cancel_download_label">Tühista\nLaadi alla</string>
<string name="playback_history_label">Esitamise ajalugu</string>
<string name="gpodnet_main_label">gpodder.net</string>
@@ -68,7 +70,9 @@
<string name="retry_label">Proovi uuesti</string>
<string name="auto_download_label">Kaasa heli allalaadimises</string>
<string name="auto_download_apply_to_items_title">Rakenda eelmistele saadetele</string>
+ <string name="auto_delete_label">Saadeta automaatne kustutamine</string>
<string name="parallel_downloads_suffix">\u0020samaaegset allalaadimist</string>
+ <string name="feed_auto_download_global">Üldine vaikeväärtus</string>
<string name="feed_auto_download_always">Alati</string>
<string name="feed_auto_download_never">Mitte kunagi</string>
<string name="send_label">Saada...</string>
@@ -194,7 +198,6 @@
<string name="move_to_top_label">Liiguta üles</string>
<string name="move_to_bottom_label">Liiguta alla</string>
<string name="sort">Sorteeri</string>
- <string name="alpha">Tähestiku järgi</string>
<string name="date">Kuupäeva järgi</string>
<string name="duration">Kestuse järgi</string>
<string name="ascending">Kasvavalt</string>
@@ -273,7 +276,6 @@
<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_title">Sünkroniseeri 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>
@@ -301,8 +303,6 @@
<string name="pref_fast_forward_sum">Kohanda mitu sekundit hüpata edasi, kui kiiresti edasi Klõpsamise</string>
<!--Auto-Flattr dialog-->
<!--Search-->
- <string name="search_hint">Uudisvoogude või saadete otsing</string>
- <string name="found_in_shownotes_label">Leitud 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>
diff --git a/core/src/main/res/values-fr/strings.xml b/core/src/main/res/values-fr/strings.xml
index 8912c79f6..262aa9322 100644
--- a/core/src/main/res/values-fr/strings.xml
+++ b/core/src/main/res/values-fr/strings.xml
@@ -36,6 +36,7 @@
<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>
+ <string name="drawer_feed_counter_downloaded">Nombre d\'épisodes téléchargés</string>
<string name="drawer_feed_counter_none">Aucun</string>
<!--Webview actions-->
<string name="open_in_browser_label">Ouvrir dans le navigateur</string>
@@ -50,6 +51,7 @@
<string name="cancel_label">Annuler</string>
<string name="yes">Oui</string>
<string name="no">Non</string>
+ <string name="reset">Reset</string>
<string name="author_label">Auteur</string>
<string name="language_label">Langue</string>
<string name="url_label">URL</string>
@@ -92,7 +94,7 @@
<string name="etxtFeedurlHint">URL du flux</string>
<string name="txtvfeedurl_label">Ajouter un podcast par son URL</string>
<string name="podcastdirectories_label">Trouver le podcast dans la bibliothèque</string>
- <string name="podcastdirectories_descr">Vous pouvez chercher de nouveaux podcasts en filtrant par nom, catégorie ou popularité dans la bibliothèque gpodder.net, ou sur l\'iTunes Store.</string>
+ <string name="podcastdirectories_descr">Pour de nouveaux podcasts vous pouvez chercher iTunes ou fyyd ou parcourir gpodder.net par nom, catégorie ou popularité.</string>
<string name="browse_gpoddernet_label">Chercher sur gpodder.net</string>
<!--Actions on feeds-->
<string name="mark_all_read_label">Marquer tous les épisodes comme lus</string>
@@ -100,7 +102,10 @@
<string name="mark_all_read_confirmation_msg">Confirmer le marquage de tous les épisode comme lus</string>
<string name="mark_all_read_feed_confirmation_msg">Confirmer le marquage de tous les épisode de ce flux comme lus</string>
<string name="mark_all_seen_label">Marquer tout les épisodes comme vus</string>
+ <string name="mark_all_seen_msg">Tous les épisodes ont été marqués vus</string>
+ <string name="mark_all_seen_confirmation_msg">Merci de confirmer que vous voulez marquer tous les épisodes vus.</string>
<string name="show_info_label">Voir les détails</string>
+ <string name="rename_feed_label">Renommer le podcast</string>
<string name="remove_feed_label">Supprimer le podcast</string>
<string name="share_label">Partager...</string>
<string name="share_link_label">Partager un lien vers le site</string>
@@ -120,6 +125,7 @@
<string name="hide_not_queued_episodes_label">Pas 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>
<string name="filtered_label">Filtré</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} La dernière mise à jour a échoué</string>
<string name="open_podcast">Ouvrir Podcast</string>
@@ -130,6 +136,7 @@
<string name="stop_label">Stop</string>
<string name="stream_label">Lire en ligne</string>
<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="mark_read_label">Marquer comme lu</string>
@@ -276,6 +283,8 @@
<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_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>
@@ -342,10 +351,16 @@
<string name="pref_gpodnet_logout_toast">Vous êtes maintenant déconnecté</string>
<string name="pref_gpodnet_setlogin_information_title">Modifier les informations de connexion</string>
<string name="pref_gpodnet_setlogin_information_sum">Modifier les information de connexion pour votre compte gpodder.net</string>
- <string name="pref_gpodnet_sync_title">Synchroniser maintenant</string>
- <string name="pref_gpodnet_sync_sum">Synchroniser les abonnements et l\'état de lecture avec gpodder.net</string>
+ <string name="pref_gpodnet_sync_changes_title">Synchroniser maintenant</string>
+ <string name="pref_gpodnet_sync_changes_sum">Synchroniser l\'état des abonnements et des épisodes avec gpodder.net</string>
+ <string name="pref_gpodnet_full_sync_title">Tout synchroniser maintenant</string>
+ <string name="pref_gpodnet_full_sync_sum">Synchroniser tous les abonnements et tous les états des épisodes avec gpodder.net.</string>
+ <string name="pref_gpodnet_sync_sum_last_sync_line">Dernière tentative de synchronisation : %1$s (%2$s)</string>
<string name="pref_gpodnet_sync_started">Synchronisation démarrée</string>
+ <string name="pref_gpodnet_full_sync_started">Synchronisation totale commencée</string>
<string name="pref_gpodnet_login_status"><![CDATA[Connecté comme <i>%1$s</i> avec l\'appareil <i>%2$s</i>]]></string>
+ <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>
@@ -382,7 +397,7 @@
<string name="pref_faq">FAQ</string>
<string name="pref_known_issues">Problèmes connus</string>
<string name="pref_no_browser_found">Aucun navigateur trouvé.</string>
- <string name="pref_cast_title">Chromecast support</string>
+ <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_rewind_sum">Personnaliser le nombre de secondes pour sauter vers l\'arrière lorsque le bouton de rembobinage est cliqué</string>
@@ -393,12 +408,13 @@
<string name="auto_flattr_ater_beginning">Lancer le paiement flattr d\'un épisode dès que la lecture commence</string>
<string name="auto_flattr_ater_end">Lancer le paiement flattr d\'un épisode à la fin de la lecture</string>
<!--Search-->
- <string name="search_hint">Chercher des flux ou épisodes</string>
- <string name="found_in_shownotes_label">Trouvé dans les notes</string>
+ <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="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>
+ <string name="no_results_for_query">Aucun résultat trouvé pour \"%1$s\"</string>
<!--OPML import and export-->
<string name="opml_import_txtv_button_lable">Les fichiers OPML vous permettent d\'exporter vos podcasts d\'un logiciel à un autre.</string>
<string name="opml_import_option">Option %1$d</string>
@@ -417,6 +433,7 @@
<string name="choose_file_from_filesystem">Depuis le système de fichier local</string>
<string name="choose_file_from_external_application">Utiliser une application tierce</string>
<string name="opml_export_label">Exportation OPML</string>
+ <string name="html_export_label">Export HTML</string>
<string name="exporting_label">Export en cours...</string>
<string name="export_error_label">Erreur d\'exportation</string>
<string name="opml_export_success_title">Exportation OPML réussie.</string>
@@ -447,6 +464,9 @@
<item quantity="one">1 heure</item>
<item quantity="other">%d heures</item>
</plurals>
+ <string name="auto_enable_label">Activation automatique</string>
+ <string name="sleep_timer_enabled_label">Arrêt automatique activé</string>
+ <string name="sleep_timer_disabled_label">Arrêt automatique désactivé</string>
<!--gpodder.net-->
<string name="gpodnet_taglist_header">CATEGORIES</string>
<string name="gpodnet_toplist_header">PODCASTS POPULAIRES</string>
@@ -476,6 +496,8 @@
<string name="gpodnetsync_auth_error_descr">Problème d\'identifiant et/ou de mot de passe</string>
<string name="gpodnetsync_error_title">Problème de synchronisation avec gpodder.net</string>
<string name="gpodnetsync_error_descr">Une erreur est apparue lors de la synchronisation :\u0020</string>
+ <string name="gpodnetsync_pref_report_successful">Réussie</string>
+ <string name="gpodnetsync_pref_report_failed">Échoué</string>
<!--Directory chooser-->
<string name="selected_folder_label">Répertoire choisi :</string>
<string name="create_folder_label">Créer répertoire</string>
@@ -528,6 +550,7 @@
<string name="sp_apps_importing_feeds_msg">Importation des abonnements à partir d\'applications à usage unique...</string>
<string name="search_itunes_label">Chercher sur iTunes</string>
<string name="filter">Filtrer</string>
+ <string name="search_fyyd_label">Chercher fyyd</string>
<!--Episodes apply actions-->
<string name="all_label">Tout</string>
<string name="selected_all_label">Tous les épisodes ont été sélectionné</string>
@@ -545,6 +568,8 @@
<string name="selected_queued_label">Episodes présents dans la liste de lecture sélectionnés</string>
<string name="not_queued_label">Hors liste de lecture</string>
<string name="selected_not_queued_label">Episodes absents de la liste de lecture sélectionnés</string>
+ <string name="has_media">À des médias</string>
+ <string name="selected_has_media_label">Sélectionner les épisodes avec des médias</string>
<!--Sort-->
<string name="sort_title_a_z">Titre (A \u2192 Z)</string>
<string name="sort_title_z_a">Titre (Z \u2192 A)</string>
@@ -588,11 +613,11 @@
<string name="cast_failed_to_pause">Échec de mise en pause du média</string>
<!--<string name="cast_failed_to_connect">Could not connect to the device</string>-->
<string name="cast_failed_setting_volume">Échec de réglage du volume</string>
- <string name="cast_failed_no_connection">Aucune connexion à l\'appareil Cast existe</string>
+ <string name="cast_failed_no_connection">Aucune connexion à l\'appareil Cast n\'existe</string>
<string name="cast_failed_no_connection_trans">La connexion à l\'appareil cast a été perdu. L\'application tente de rétablir la connexion. Veuillez patienter quelques secondes et réessayer.</string>
<string name="cast_failed_perform_action">Échec de l\'action</string>
<string name="cast_failed_status_request">Échec de la synchronisation avec l\'appareil cast</string>
<string name="cast_failed_seek">Échec de la recherche de la nouvelle position sur l\'appareil cast</string>
- <string name="cast_failed_receiver_player_error">Le lecteur de réception à rencontrer une grave erreur</string>
+ <string name="cast_failed_receiver_player_error">Le lecteur de réception a rencontré une grave erreur</string>
<string name="cast_failed_media_error_skipping">Erreur de lecture du média. Passage au suivant...</string>
</resources>
diff --git a/core/src/main/res/values-hi-rIN/strings.xml b/core/src/main/res/values-hi-rIN/strings.xml
index 2488875a3..4e65c3855 100644
--- a/core/src/main/res/values-hi-rIN/strings.xml
+++ b/core/src/main/res/values-hi-rIN/strings.xml
@@ -189,8 +189,6 @@
<string name="pref_rewind_sum">पीछे की ओर कूद करने के लिए सेकंड की संख्या अनुकूलित जब उल्टा बटन क्लिक किया जाता है</string>
<!--Auto-Flattr dialog-->
<!--Search-->
- <string name="search_hint">फ़ीड या एपिसोड के लिए खोज</string>
- <string name="found_in_shownotes_label">Shownotes में मिला</string>
<string name="found_in_chapters_label">अध्यायों में मिला</string>
<string name="search_status_no_results">कोई परिणाम नहीं मिले</string>
<string name="search_label">खोज</string>
diff --git a/core/src/main/res/values-hu/strings.xml b/core/src/main/res/values-hu/strings.xml
index 28dfeb6e8..e370a2229 100644
--- a/core/src/main/res/values-hu/strings.xml
+++ b/core/src/main/res/values-hu/strings.xml
@@ -1,11 +1,61 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources xmlns:tools="http://schemas.android.com/tools">
<!--Activitiy and fragment titles-->
+ <string name="statistics_label">Statisztika</string>
+ <string name="add_feed_label">Podcast hozzáadása</string>
+ <string name="episodes_label">Epizódok</string>
+ <string name="all_episodes_short_label">Mind</string>
+ <string name="favorite_episodes_label">Kedvencek</string>
+ <string name="new_label">Új</string>
+ <string name="settings_label">Beállítások</string>
+ <string name="add_new_feed_label">Podcast hozzáadása</string>
+ <string name="downloads_label">Letöltések</string>
+ <string name="downloads_running_label">Futó</string>
+ <string name="downloads_completed_label">Befejezett</string>
+ <string name="downloads_log_label">Napló</string>
+ <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>
<!--Statistics fragment-->
<!--Main activity-->
+ <string name="drawer_open">Menü megnyitása</string>
+ <string name="drawer_close">Menü bezárása</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>
<!--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>
<!--Playback history-->
<!--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="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="refresh_label">Frissítés</string>
+ <string name="chapters_label">Fejezetek</string>
+ <string name="description_label">Leírás</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_delete_label">Epizód automatikus törlése</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>
<!--'Add Feed' Activity labels-->
<!--Actions on feeds-->
<!--actions on feeditems-->
diff --git a/core/src/main/res/values-id/strings.xml b/core/src/main/res/values-id/strings.xml
index 383605ded..743812a58 100644
--- a/core/src/main/res/values-id/strings.xml
+++ b/core/src/main/res/values-id/strings.xml
@@ -95,7 +95,6 @@
<string name="pref_update_interval_hours_singular">jam</string>
<string name="pref_gpodnet_authenticate_title">Masuk</string>
<string name="pref_gpodnet_logout_title">Keluar</string>
- <string name="pref_gpodnet_sync_title">Sinkronkan sekarang</string>
<string name="pref_gpodnet_sync_started">Sinkronkan dimulai</string>
<!--Auto-Flattr dialog-->
<!--Search-->
diff --git a/core/src/main/res/values-it-rIT/strings.xml b/core/src/main/res/values-it-rIT/strings.xml
index cdb80cdc3..f1d94e3d4 100644
--- a/core/src/main/res/values-it-rIT/strings.xml
+++ b/core/src/main/res/values-it-rIT/strings.xml
@@ -86,7 +86,6 @@
<string name="etxtFeedurlHint">www.example.com/feed</string>
<string name="txtvfeedurl_label">Aggiungi un Podcast tramite URL</string>
<string name="podcastdirectories_label">Trova un podcast nella directory</string>
- <string name="podcastdirectories_descr">Puoi cercare dei nuovi podcast in base al nome, alla categoria o alla popolarità nella directory di gpodder.net.</string>
<string name="browse_gpoddernet_label">Esplora gpodder.net</string>
<!--Actions on feeds-->
<string name="mark_all_read_label">Segna tutti come riprodotti</string>
@@ -209,8 +208,11 @@
<string name="sort">Ordina</string>
<string name="date">Per data</string>
<string name="duration">Per durata</string>
+ <string name="episode_title">Titolo episodio</string>
+ <string name="feed_title">Titolo feed</string>
<string name="ascending">In ordine crescente</string>
<string name="descending">In ordine decrescente</string>
+ <string name="clear_queue_confirmation_msg">Per favore conferma che vuoi rimuovere dalla coda TUTTI gli episodi in essa presenti.</string>
<!--Flattr-->
<string name="flattr_auth_label">Accesso a Flattr</string>
<string name="flattr_auth_explanation">Premi il tasto seguente per iniziare il processo di autenticazione. Sarai trasferito alla pagina di login di flattr sul tuo browser e ti sarà richiesto di garantire ad AntennaPod il permesso di effettuare microdonazioni. Dopo la tua autorizzazione, sarai riportato alla seguente schermata in modo automatico.</string>
@@ -247,6 +249,7 @@
<string name="no_feeds_label">Non sei ancora abbonato a nessun feed.</string>
<string name="no_chapters_label">Questo episodio non ha capitoli.</string>
<!--Preferences-->
+ <string name="storage_pref">Memoria</string>
<string name="project_pref">Progetto</string>
<string name="other_pref">Altro</string>
<string name="about_pref">Informazioni</string>
@@ -257,6 +260,7 @@
<string name="pref_followQueue_sum">Passa al prossimo episodio in coda quanto si completa una riproduzione</string>
<string name="pref_auto_delete_sum">Elimina l\'episodio quando viene completata la riproduzione</string>
<string name="pref_auto_delete_title">Elimina automaticamente</string>
+ <string name="pref_skip_keeps_episodes_title">Manteni gli Episodi Saltati</string>
<string name="playback_pref">Riproduzione</string>
<string name="network_pref">Rete</string>
<string name="pref_autoUpdateIntervallOrTime_Disable">Disabilita</string>
@@ -268,6 +272,7 @@
<string name="pref_downloadMediaOnWifiOnly_title">Download dei media su WiFi</string>
<string name="pref_pauseOnHeadsetDisconnect_title">Disconnessione cuffie</string>
<string name="pref_unpauseOnHeadsetReconnect_title">Riconnetti le cuffie</string>
+ <string name="pref_unpauseOnBluetoothReconnect_title">Riconnessione Bluetooth</string>
<string name="pref_mobileUpdate_title">Update su rete mobile</string>
<string name="pref_mobileUpdate_sum">Permetti gli aggiornamenti tramite connessione dati mobile</string>
<string name="refreshing_label">Aggiornamento</string>
@@ -282,6 +287,7 @@
<string name="pref_auto_flattr_sum">Configura l\'esecuzione automatica di Flattr</string>
<string name="user_interface_label">Interfaccia utente</string>
<string name="pref_set_theme_title">Seleziona il tema</string>
+ <string name="pref_nav_drawer_feed_order_title">Imposta l\'ordine delle Iscrizioni</string>
<string name="pref_set_theme_sum">Cambia l\'aspetto di AntennaPod</string>
<string name="pref_automatic_download_title">Download automatico</string>
<string name="pref_automatic_download_sum">Configura il download automatico degli episodi</string>
@@ -303,7 +309,6 @@
<string name="pref_gpodnet_logout_toast">Logout effettuato</string>
<string name="pref_gpodnet_setlogin_information_title">Cambia le informazioni di login</string>
<string name="pref_gpodnet_setlogin_information_sum">Cambia le informazioni di login per il tuo account gpodder.net.</string>
- <string name="pref_gpodnet_sync_title">Sincronizza ora</string>
<string name="pref_gpodnet_sync_started">Sincronizzazione avviata</string>
<string name="pref_playback_speed_title">Velocità di riproduzione</string>
<string name="pref_playback_speed_sum">Personalizza le velocità disponibili per la riproduzione audio a velocità variabile</string>
@@ -332,8 +337,6 @@
<string name="auto_flattr_ater_beginning">Carica l\'episodio su Flattr appena comincia la riproduzione</string>
<string name="auto_flattr_ater_end">Carica l\'episodio su Flattr appena finisce la riproduzione</string>
<!--Search-->
- <string name="search_hint">Cerca dei feed o degli episodi</string>
- <string name="found_in_shownotes_label">Trovato nelle note dell\'episodio</string>
<string name="found_in_chapters_label">Trovato nei capitoli</string>
<string name="search_status_no_results">Nessun risultato trovato</string>
<string name="search_label">Ricerca</string>
@@ -469,6 +472,8 @@
<string name="rating_later_label">Ricordamelo più tardi</string>
<!--Audio controls-->
<string name="volume">Volume</string>
+ <string name="left_short">L</string>
+ <string name="right_short">R</string>
<string name="audio_effects">Effetti Audio</string>
<!--proxy settings-->
<string name="proxy_type_label">Tipo</string>
diff --git a/core/src/main/res/values-it/strings.xml b/core/src/main/res/values-it/strings.xml
index 3ea99889e..30e8ab66a 100644
--- a/core/src/main/res/values-it/strings.xml
+++ b/core/src/main/res/values-it/strings.xml
@@ -67,7 +67,6 @@
<string name="feedurl_label">URL del feed</string>
<string name="etxtFeedurlHint">www.example.com/feed</string>
<string name="txtvfeedurl_label">Aggiungi un podcast inserendo un URL</string>
- <string name="podcastdirectories_descr">Puoi cercare nuovi podcast per nome, categoria o popolarità su gpodder.net, oppure sull\'iTunes store.</string>
<string name="browse_gpoddernet_label">Esplora gpodder.net</string>
<!--Actions on feeds-->
<string name="mark_all_read_label">Segna tutti come riprodotti</string>
@@ -196,7 +195,6 @@
<string name="pref_fast_forward_sum">Personalizzare il numero di secondi per saltare in avanti quando il pulsante di avanzamento rapido viene cliccato</string>
<!--Auto-Flattr dialog-->
<!--Search-->
- <string name="search_hint">Cerca dei feed o degli episodi</string>
<string name="found_in_chapters_label">Trovato nei capitoli</string>
<string name="search_status_no_results">Nessun risultato trovato</string>
<string name="search_label">Cerca</string>
diff --git a/core/src/main/res/values-iw-rIL/strings.xml b/core/src/main/res/values-iw-rIL/strings.xml
index 9206bd2e7..34ebc4848 100644
--- a/core/src/main/res/values-iw-rIL/strings.xml
+++ b/core/src/main/res/values-iw-rIL/strings.xml
@@ -2,8 +2,10 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!--Activitiy and fragment titles-->
<string name="feeds_label">הזנות</string>
+ <string name="statistics_label">סטטיסטיקות</string>
<string name="add_feed_label">הוסף פודקאסט</string>
<string name="episodes_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>
@@ -20,6 +22,8 @@
<!--Main activity-->
<string name="drawer_open">פתח תפריט</string>
<string name="drawer_close">סגור תפריט</string>
+ <string name="drawer_feed_order_alphabetical">מיין בסדר אלפביתי</string>
+ <string name="drawer_feed_order_last_update">מיין לפי תאריך פרסום</string>
<!--Webview actions-->
<string name="open_in_browser_label">פתח בדפדפן</string>
<string name="copy_url_label">העתק כתובת אתר</string>
@@ -35,6 +39,7 @@
<string name="no">לא</string>
<string name="author_label">מחבר</string>
<string name="language_label">שפה</string>
+ <string name="url_label">כתובת</string>
<string name="podcast_settings_label">הגדרות</string>
<string name="cover_label">תמונה</string>
<string name="error_label">שגיאה</string>
@@ -49,6 +54,7 @@
<string name="length_prefix">אורך:\u0020</string>
<string name="size_prefix">גודל:\u0020</string>
<string name="processing_label">מעבד</string>
+ <string name="loading_label">טוען...</string>
<string name="save_username_password_label">שמור שם משתמש וססמה</string>
<string name="close_label">סגור</string>
<string name="retry_label">נסה שוב</string>
@@ -62,7 +68,6 @@
<string name="etxtFeedurlHint">כתובת של הזנה או אתר אינטרנט</string>
<string name="txtvfeedurl_label">הוסף פודקאסט לפי כתובת אתר</string>
<string name="podcastdirectories_label">חפש פודקאסט בספריה</string>
- <string name="podcastdirectories_descr">אפשר לחפש פודקסטים חדשים לפי בשם, קטגוריה או פופולריות בספריית gpodder.net.</string>
<string name="browse_gpoddernet_label">עיין בgpodder.net</string>
<!--Actions on feeds-->
<string name="mark_all_read_label">סמן הכל כנקרא</string>
@@ -253,8 +258,6 @@
<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>
diff --git a/core/src/main/res/values-ja/strings.xml b/core/src/main/res/values-ja/strings.xml
index e323f69fb..e1cf513a2 100644
--- a/core/src/main/res/values-ja/strings.xml
+++ b/core/src/main/res/values-ja/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,7 +93,7 @@
<string name="etxtFeedurlHint">フィードまたはWebサイトのURL</string>
<string name="txtvfeedurl_label">URLでポッドキャストを追加</string>
<string name="podcastdirectories_label">ディレクトリでポッドキャストを検索</string>
- <string name="podcastdirectories_descr">名前、カテゴリや人気で、gpodder.netディレクトリ内の新しいポッドキャストを検索することができます。</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>
@@ -99,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">Webサイトのリンクを共有</string>
@@ -119,6 +124,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>
@@ -129,6 +135,7 @@
<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="mark_read_label">再生済としてマーク</string>
@@ -274,6 +281,8 @@
<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>
@@ -340,10 +349,16 @@
<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_title">今すぐ同期</string>
- <string name="pref_gpodnet_sync_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>
@@ -389,12 +404,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="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>
@@ -413,6 +429,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>
@@ -440,6 +457,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>
@@ -469,6 +489,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>
@@ -523,6 +545,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>
@@ -540,6 +563,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-kn-rIN/strings.xml b/core/src/main/res/values-kn-rIN/strings.xml
index 26de5a2fb..118b28979 100644
--- a/core/src/main/res/values-kn-rIN/strings.xml
+++ b/core/src/main/res/values-kn-rIN/strings.xml
@@ -82,8 +82,6 @@
<string name="user_interface_label">ಬಳಕೆದಾರ ಸಂಪರ್ಕಸಾಧನ</string>
<!--Auto-Flattr dialog-->
<!--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>
diff --git a/core/src/main/res/values-ko/strings.xml b/core/src/main/res/values-ko/strings.xml
index 2eb9c1bf3..a16de306f 100644
--- a/core/src/main/res/values-ko/strings.xml
+++ b/core/src/main/res/values-ko/strings.xml
@@ -91,7 +91,6 @@
<string name="etxtFeedurlHint">피드의 URL 또는 홈페이지</string>
<string name="txtvfeedurl_label">URL로 팟캐스트를 추가</string>
<string name="podcastdirectories_label">디렉터리에서 팟캐스트 찾기</string>
- <string name="podcastdirectories_descr">gpodder.net 디렉터리에서 이름, 분류, 인기에 따라 새 팟캐스트를 검색할 수 있고, iTunes 스토어에서 검색할 수도 있습니다.</string>
<string name="browse_gpoddernet_label">gpodder.net 둘러보기</string>
<!--Actions on feeds-->
<string name="mark_all_read_label">모두 재생했다고 표시</string>
@@ -130,6 +129,7 @@
<string name="stream_label">스트리밍</string>
<string name="remove_label">제거</string>
<string name="remove_episode_lable">에피소드 제거</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>
@@ -216,6 +216,8 @@
<string name="sort">정렬</string>
<string name="date">날짜</string>
<string name="duration">기간</string>
+ <string name="episode_title">에피소드 제목</string>
+ <string name="feed_title">피드 제목</string>
<string name="ascending">오름차순</string>
<string name="descending">내림차순</string>
<string name="clear_queue_confirmation_msg">내부의 모든 에피소드 대기열을 지울지 확인하십시오.</string>
@@ -337,8 +339,6 @@
<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_title">지금 동기화</string>
- <string name="pref_gpodnet_sync_sum">gpodder.net의 구독과 에피소드 상태 동기화</string>
<string name="pref_gpodnet_sync_started">동기화 시작함</string>
<string name="pref_gpodnet_login_status"><![CDATA[<i>%1$s</i> 사용자로 로그인, <i>%2$s</i> 장치]]></string>
<string name="pref_playback_speed_title">재생 속도</string>
@@ -380,14 +380,14 @@
<string name="pref_cast_title">크롬캐스트 지원</string>
<string name="pref_rewind_sum">되감기 버튼을 클릭하면 뒤로 이동 (초)을 정의</string>
<string name="pref_fast_forward_sum">빨리 감기 버튼을 클릭 할 때 앞으로 이동 (초)을 정의</string>
+ <string name="pref_cast_message_play_flavor">캐스트 장치의 원격 미디어 재생 기능 사용 (예: 크롬캐스트, 안드로이드 TV의 오디오 스피커)</string>
+ <string name="pref_cast_message_free_flavor">크롬캐스트는 서드파티 라이브러리가 필요하지만, 이 버전의 안테나팟에서는 사용하지 않게 되어 있습니다.</string>
<!--Auto-Flattr dialog-->
<string name="auto_flattr_enable">자동 flattr 사용</string>
<string name="auto_flattr_after_percent">%d 퍼센트를 재생하면 에피소드에 flattr합니다</string>
<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>
@@ -520,21 +520,21 @@
<string name="filter">필터</string>
<!--Episodes apply actions-->
<string name="all_label">모두</string>
- <string name="selected_all_label">모든 에피소드 선택</string>
+ <string name="selected_all_label">모든 에피소드 선택함</string>
<string name="none_label">없음</string>
- <string name="deselected_all_label">모든 에피소드 선택 해제</string>
+ <string name="deselected_all_label">모든 에피소드 선택 해제함</string>
<string name="played_label">재생함</string>
- <string name="selected_played_label">재생 에피소드 선택</string>
+ <string name="selected_played_label">재생한 에피소드 선택함</string>
<string name="unplayed_label">재생 안 함</string>
- <string name="selected_unplayed_label">재생 안 한 에피소드 선택</string>
+ <string name="selected_unplayed_label">재생 안 한 에피소드 선택함</string>
<string name="downloaded_label">다운로드함</string>
- <string name="selected_downloaded_label">다운로드한 에피소드 선택</string>
+ <string name="selected_downloaded_label">다운로드한 에피소드 선택함</string>
<string name="not_downloaded_label">다운로드 안 함</string>
- <string name="selected_not_downloaded_label">다운로드 안 한 에피소드 선택</string>
+ <string name="selected_not_downloaded_label">다운로드 안 한 에피소드 선택함</string>
<string name="queued_label">대기열에 있음</string>
- <string name="selected_queued_label">선택한 대기열의 에피소드</string>
+ <string name="selected_queued_label">대기열의 에피소드 선택함</string>
<string name="not_queued_label">대기열에 없음</string>
- <string name="selected_not_queued_label">선택한 대기열 외의 에피소드</string>
+ <string name="selected_not_queued_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
new file mode 100644
index 000000000..798715fb3
--- /dev/null
+++ b/core/src/main/res/values-lt/strings.xml
@@ -0,0 +1,153 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<resources xmlns:tools="http://schemas.android.com/tools">
+ <!--Activitiy and fragment titles-->
+ <string name="feeds_label">Sklaidos kanalai</string>
+ <string name="statistics_label">Statistika</string>
+ <string name="add_feed_label">Pridėti tinklalaidę</string>
+ <string name="episodes_label">Epizodai</string>
+ <string name="all_episodes_short_label">Visi</string>
+ <string name="favorite_episodes_label">Mėgstamiausi</string>
+ <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_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="gpodnet_main_label">gpodder.net</string>
+ <string name="gpodnet_auth_label">gpodder.net prisijungimas</string>
+ <!--Statistics fragment-->
+ <!--Main activity-->
+ <string name="drawer_open">Atverti meniu</string>
+ <string name="drawer_close">Uždaryti meniu</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>
+ <!--Playback history-->
+ <string name="clear_history_label">Išvalyti istoriją</string>
+ <!--Other-->
+ <string name="confirm_label">Patvirtinti</string>
+ <string name="cancel_label">Atšaukti</string>
+ <string name="yes">Taip</string>
+ <string name="no">Ne</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="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="description_label">Aprašymas</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="retry_label">Bandyti vėl</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>
+ <!--'Add Feed' Activity labels-->
+ <string name="feedurl_label">Sklaidos kanalo URL</string>
+ <!--Actions on feeds-->
+ <string name="show_info_label">Rodyti informaciją</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="hide_episodes_title">Slėpti epizodus</string>
+ <string name="open_podcast">Atverti tinklalaidę</string>
+ <!--actions on feeditems-->
+ <string name="download_label">Atsisiųsti</string>
+ <string name="play_label">Atkurti</string>
+ <string name="pause_label">Pristabdyti</string>
+ <string name="stop_label">Sustabdyti</string>
+ <string name="remove_label">Pašalinti</string>
+ <string name="remove_episode_lable">Pašalinti epizodą</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="skip_episode_label">Praleisti epizodą</string>
+ <!--Download messages and labels-->
+ <string name="download_successful">sėkmingi</string>
+ <string name="download_failed">nepavyko</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="cancel_all_downloads_label">Atšaukti visus atsiuntimus</string>
+ <string name="download_report_content_title">Atsiuntimų ataskaita</string>
+ <string name="download_error_request_error">Užklausos klaida</string>
+ <string name="download_notification_title">Atsiunčiami tinklalaidės duomenys</string>
+ <string name="download_type_feed">Sklaidos kanalas</string>
+ <string name="authentication_notification_title">Reikalinga autentifikacija</string>
+ <string name="confirm_mobile_download_dialog_only_add_to_queue">Pridėti į eilę</string>
+ <!--Mediaplayer messages-->
+ <string name="player_error_msg">Klaida!</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>
+ <!--Flattr-->
+ <string name="action_forbidden_title">Veiksmas uždraustas</string>
+ <!--Flattr-->
+ <!--Variable Speed-->
+ <!--Empty list labels-->
+ <!--Preferences-->
+ <string name="project_pref">Projektas</string>
+ <string name="other_pref">Kita</string>
+ <string name="about_pref">Apie</string>
+ <string name="queue_label">Eilė</string>
+ <string name="services_label">Paslaugos</string>
+ <string name="flattr_label">Flattr</string>
+ <string name="playback_pref">Atkūrimas</string>
+ <string name="network_pref">Tinklas</string>
+ <string name="user_interface_label">Vartotojo sąsaja</string>
+ <string name="pref_set_theme_title">Pasirinkti temą</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_gpodnet_logout_title">Atsijungti</string>
+ <string name="pref_gpodnet_logout_toast">Sėkmingai atsijungta</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_faq">DUK</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="opml_directory_error">KLAIDA!</string>
+ <!--Sleep timer-->
+ <!--gpodder.net-->
+ <string name="username_label">Vartotojo vardas</string>
+ <string name="gpodnetsync_auth_error_descr">Neteisingas vartotojo vardas ar slaptažodis</string>
+ <!--Directory chooser-->
+ <!--Online feed view-->
+ <!--Content descriptions for image buttons-->
+ <!--Feed information screen-->
+ <!--Progress information-->
+ <!--AntennaPodSP-->
+ <!--Episodes apply actions-->
+ <!--Sort-->
+ <!--Rating dialog-->
+ <!--Audio controls-->
+ <string name="playback_speed">Atkūrimo sparta</string>
+ <string name="left_short">K</string>
+ <string name="right_short">D</string>
+ <!--proxy settings-->
+ <!--Casting-->
+ <!--<string name="cast_failed_to_connect">Could not connect to the device</string>-->
+</resources>
diff --git a/core/src/main/res/values-nb/strings.xml b/core/src/main/res/values-nb/strings.xml
index a23955813..e92bc9bce 100644
--- a/core/src/main/res/values-nb/strings.xml
+++ b/core/src/main/res/values-nb/strings.xml
@@ -81,7 +81,6 @@
<string name="etxtFeedurlHint">www.example.com/feed</string>
<string name="txtvfeedurl_label">Legg til en podcast via URL</string>
<string name="podcastdirectories_label">Finn podcast i katalog</string>
- <string name="podcastdirectories_descr">Du kan søke etter nye podcaster på navn, kategori eller popularitet i gpodder.nets katalog eller på iTunes.</string>
<string name="browse_gpoddernet_label">Bla gjennom gpodder.net</string>
<!--Actions on feeds-->
<string name="mark_all_read_label">Marker alle som avspilt</string>
@@ -339,8 +338,6 @@
<string name="auto_flattr_ater_beginning">Flattre episode når avspillingen starter</string>
<string name="auto_flattr_ater_end">Flattre episode når avspillingen tar slutt</string>
<!--Search-->
- <string name="search_hint">Søk etter strømmer eller episoder</string>
- <string name="found_in_shownotes_label">Funnet i shownotater</string>
<string name="found_in_chapters_label">Funnet i kapitler</string>
<string name="search_status_no_results">Ingen resultater ble funnet</string>
<string name="search_label">Søk</string>
diff --git a/core/src/main/res/values-nl/strings.xml b/core/src/main/res/values-nl/strings.xml
index 72d1fca90..1a45e2612 100644
--- a/core/src/main/res/values-nl/strings.xml
+++ b/core/src/main/res/values-nl/strings.xml
@@ -32,10 +32,11 @@
<string name="drawer_preferences">Menu voorkeuren</string>
<string name="drawer_feed_order_unplayed_episodes">Op aantal afleveringen</string>
<string name="drawer_feed_order_alphabetical">Op alfabetische volgorde</string>
- <string name="drawer_feed_order_last_update">Op datum van feed-update</string>
+ <string name="drawer_feed_order_last_update">Op datum van publicatie</string>
<string name="drawer_feed_counter_new_unplayed">Aantal nieuwe plus onbeluisterde afleveringen</string>
<string name="drawer_feed_counter_new">Aantal nieuwe afleveringen</string>
<string name="drawer_feed_counter_unplayed">Aantal onbeluisterde afleveringen</string>
+ <string name="drawer_feed_counter_downloaded">Aantal gedownloade afleveringen</string>
<string name="drawer_feed_counter_none">Geen (alfabetisch sorteren)</string>
<!--Webview actions-->
<string name="open_in_browser_label">In de browser openen</string>
@@ -50,6 +51,7 @@
<string name="cancel_label">Annuleren</string>
<string name="yes">Ja</string>
<string name="no">Nee</string>
+ <string name="reset">Reset</string>
<string name="author_label">Auteur</string>
<string name="language_label">Taal</string>
<string name="url_label">URL</string>
@@ -100,7 +102,10 @@
<string name="mark_all_read_confirmation_msg">Bevestig aub dat u alle afleveringen als afgespeeld wilt markeren.</string>
<string name="mark_all_read_feed_confirmation_msg">Bevestig aub dat u alle afleveringen van deze feed als afgespeeld wilt markeren.</string>
<string name="mark_all_seen_label">\'Nieuw\' label van alle afleveringen verwijderen.</string>
+ <string name="mark_all_seen_msg">\'Nieuw\' label van alle afleveringen verwijderend</string>
+ <string name="mark_all_seen_confirmation_msg">Bevestig aub dat u het \'nieuw\' label van alle afleveringen wilt verwijderen.</string>
<string name="show_info_label">Toon informatie</string>
+ <string name="rename_feed_label">Podcast hernoemen</string>
<string name="remove_feed_label">Podcast verwijderen</string>
<string name="share_label">Delen…</string>
<string name="share_link_label">Link van de aflevering delen</string>
@@ -120,6 +125,7 @@
<string name="hide_not_queued_episodes_label">Niet in de wachtrij</string>
<string name="hide_downloaded_episodes_label">Gedownload</string>
<string name="hide_not_downloaded_episodes_label">Niet gedownload</string>
+ <string name="hide_has_media_label">Bevat media</string>
<string name="filtered_label">Gefilterd</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Laatste vernieuwing mislukt</string>
<string name="open_podcast">Open podcast</string>
@@ -130,7 +136,9 @@
<string name="stop_label">Stop</string>
<string name="stream_label">Stream</string>
<string name="remove_label">Verwijderen</string>
+ <string name="delete_label">Verwijderen</string>
<string name="remove_episode_lable">Aflevering(en) verwijderen</string>
+ <string name="marked_as_seen_label">Verwijder \'nieuw\' label</string>
<string name="mark_read_label">Als afgespeeld markeren</string>
<string name="marked_as_read_label">Als afgespeeld gemarkeerd</string>
<string name="mark_unread_label">Als niet afgespeeld markeren</string>
@@ -218,6 +226,8 @@
<string name="sort">Sorteren</string>
<string name="date">Datum</string>
<string name="duration">Lengte</string>
+ <string name="episode_title">Afleveringtitel</string>
+ <string name="feed_title">Feed-titel</string>
<string name="ascending">Oplopend</string>
<string name="descending">Aflopend</string>
<string name="clear_queue_confirmation_msg">Bevestig aub dat u alle afleveringen uit de wachtrij wilt verwijderen</string>
@@ -273,6 +283,8 @@
<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>
<string name="pref_followQueue_sum">Volgende item in de wachtrij afspelen als de aflevering voltooid is</string>
<string name="pref_auto_delete_sum">Afleveringen verwijderen als ze zijn afgespeeld</string>
<string name="pref_auto_delete_title">Automatisch verwijderen</string>
@@ -339,10 +351,16 @@
<string name="pref_gpodnet_logout_toast">Uitlog was succesvol</string>
<string name="pref_gpodnet_setlogin_information_title">Aanmeldingsgegevens wijzigen</string>
<string name="pref_gpodnet_setlogin_information_sum">Wijzig de aanmeldingsgegevens van je gpodder.net account.</string>
- <string name="pref_gpodnet_sync_title">Nu synchroniseren</string>
- <string name="pref_gpodnet_sync_sum">Synchroniseer abonnementen en aflevering-status met gpodder.net</string>
+ <string name="pref_gpodnet_sync_changes_title">Wijzigingen nu synchroniseren</string>
+ <string name="pref_gpodnet_sync_changes_sum">Synchroniseer veranderde abonnementen en aflevering-statussen met gpodder.net</string>
+ <string name="pref_gpodnet_full_sync_title">Nu alles synchroniseren</string>
+ <string name="pref_gpodnet_full_sync_sum">Synchroniseer alle abonnementen en aflevering-statussen met gpodder.net</string>
+ <string name="pref_gpodnet_sync_sum_last_sync_line">Laatste synchronisatie: %1$s (%2$s)</string>
<string name="pref_gpodnet_sync_started">Synchroniseren gestart</string>
+ <string name="pref_gpodnet_full_sync_started">Volledige synchronisatie gestart</string>
<string name="pref_gpodnet_login_status"><![CDATA[Ingelogd als <i>%1$s</i> met apparaat <i>%2$s</i>]]></string>
+ <string name="pref_gpodnet_notifications_title">Toon synchronisatiefouten in melding</string>
+ <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>
@@ -382,18 +400,21 @@
<string name="pref_cast_title">Chromecast</string>
<string name="pref_rewind_sum">Pas het aantal seconden achteruit springen wanneer het terugspoelen knop wordt geklikt</string>
<string name="pref_fast_forward_sum">Pas het aantal seconden om vooruit te springen wanneer de fast forward knop wordt geklikt</string>
+ <string name="pref_cast_message_play_flavor">Ondersteuning activeren voor draadloos afspelen via Cast apparaten (zoals Chromecast, Audio speakers en Android TV)</string>
+ <string name="pref_cast_message_free_flavor">Voor Chromecast is software van derden vereist die niet beschikbaar zijn in deze versie van AntennaPod</string>
<!--Auto-Flattr dialog-->
<string name="auto_flattr_enable">Automatisch flattr\'en aanzetten</string>
<string name="auto_flattr_after_percent">Flattr een aflevering zodra %d procent is afgespeeld</string>
<string name="auto_flattr_ater_beginning">Flattr de aflevering bij afspelen</string>
<string name="auto_flattr_ater_end">Flattr aflevering als afspelen is gestopt</string>
<!--Search-->
- <string name="search_hint">Feeds of afleveringen zoeken</string>
+ <string name="search_hint">Zoeken naar afleveringen</string>
<string name="found_in_shownotes_label">Gevonden in de shownotes</string>
<string name="found_in_chapters_label">Gevonden in hoofdstukken</string>
<string name="search_status_no_results">Er zijn geen resultaten gevonden</string>
<string name="search_label">Zoeken</string>
<string name="found_in_title_label">Gevonden in de titel</string>
+ <string name="no_results_for_query">Geen resultaten gevonden voor \"%1$s\"</string>
<!--OPML import and export-->
<string name="opml_import_txtv_button_lable">Met OPML-bestanden kan je podcasts van de ene naar de andere podcatcher verplaatsen.</string>
<string name="opml_import_option">Optie %1$d</string>
@@ -412,6 +433,7 @@
<string name="choose_file_from_filesystem">Via bestandsbeheer</string>
<string name="choose_file_from_external_application">Via externe app</string>
<string name="opml_export_label">OPML export</string>
+ <string name="html_export_label">HTML export</string>
<string name="exporting_label">Exporteren…</string>
<string name="export_error_label">Export fout</string>
<string name="opml_export_success_title">OPML bestand succesvol geëxporteerd.</string>
@@ -442,6 +464,9 @@
<item quantity="one">1 uur</item>
<item quantity="other">%d uur</item>
</plurals>
+ <string name="auto_enable_label">Automatisch inschakelen</string>
+ <string name="sleep_timer_enabled_label">Slaap timer ingeschakeld</string>
+ <string name="sleep_timer_disabled_label">Slaap timer uitgeschakeld</string>
<!--gpodder.net-->
<string name="gpodnet_taglist_header">CATEGORIEËN</string>
<string name="gpodnet_toplist_header">TOP PODCASTS</string>
@@ -471,6 +496,8 @@
<string name="gpodnetsync_auth_error_descr">Ongeldig gebruikersnaam of wachtwoord</string>
<string name="gpodnetsync_error_title">gpodder.net synchronisatie fout</string>
<string name="gpodnetsync_error_descr">Er is een fout opgetreden tijdens het synchroniseren:\u0020</string>
+ <string name="gpodnetsync_pref_report_successful">Succesvol</string>
+ <string name="gpodnetsync_pref_report_failed">Gefaald</string>
<!--Directory chooser-->
<string name="selected_folder_label">Geselecteerde map:</string>
<string name="create_folder_label">Map aanmaken</string>
@@ -523,6 +550,7 @@
<string name="sp_apps_importing_feeds_msg">Abonnementen aan het importeren vanuit single-purpose apps...</string>
<string name="search_itunes_label">Zoeken in iTunes</string>
<string name="filter">Filter</string>
+ <string name="search_fyyd_label">Fyyd doorzoeken</string>
<!--Episodes apply actions-->
<string name="all_label">Alle</string>
<string name="selected_all_label">Alle afleveringen selecteren</string>
@@ -540,6 +568,8 @@
<string name="selected_queued_label">Afleveringen in de wachtrij selecteren</string>
<string name="not_queued_label">Niet in de wachtrij</string>
<string name="selected_not_queued_label">Afleveringen geselecteerd die niet in de wachtrij staan</string>
+ <string name="has_media">Bevat media</string>
+ <string name="selected_has_media_label">Geselecteerde afleveringen met media</string>
<!--Sort-->
<string name="sort_title_a_z">Titel (A \u2192 Z)</string>
<string name="sort_title_z_a">Titel (A \u2192 A)</string>
@@ -576,6 +606,7 @@
<string name="proxy_port_invalid_error">Poortnummer ongeldig</string>
<!--Casting-->
<string name="cast_media_route_menu_title">Afspelen op…</string>
+ <string name="cast_disconnect_label">Cast loskoppelen</string>
<string name="cast_not_castable">Dit bestand kan niet afgespeeld woorden door het Cast apparaat</string>
<string name="cast_failed_to_play">Starten van afspelen is mislukt</string>
<string name="cast_failed_to_stop">Stoppen van afspelen is mislukt</string>
@@ -587,5 +618,6 @@
<string name="cast_failed_perform_action">Het uitvoeren van de actie is mislukt</string>
<string name="cast_failed_status_request">Het synchroniseren met het Cast apparaat is mislukt</string>
<string name="cast_failed_seek">Het opzoeken van het nieuwe tijdstip op het Cast apparaat is mislukt</string>
+ <string name="cast_failed_receiver_player_error">Ernstige fout opgetreden bij het afspelende Cast apparaat</string>
<string name="cast_failed_media_error_skipping">Er was een fout bij het afspelen; de aflevering wordt overgeslagen…</string>
</resources>
diff --git a/core/src/main/res/values-no-rNB/strings.xml b/core/src/main/res/values-no-rNB/strings.xml
index 98c292d47..298def87f 100644
--- a/core/src/main/res/values-no-rNB/strings.xml
+++ b/core/src/main/res/values-no-rNB/strings.xml
@@ -81,7 +81,6 @@
<string name="etxtFeedurlHint">www.example.com/feed</string>
<string name="txtvfeedurl_label">Legg til en podcast via URL</string>
<string name="podcastdirectories_label">Finn podcast i katalog</string>
- <string name="podcastdirectories_descr">Du kan søke etter nye podcaster på navn, kategori eller popularitet i gpodder.nets katalog eller på iTunes.</string>
<string name="browse_gpoddernet_label">Bla gjennom gpodder.net</string>
<!--Actions on feeds-->
<string name="mark_all_read_label">Marker alle som avspilt</string>
@@ -339,8 +338,6 @@
<string name="auto_flattr_ater_beginning">Flattre episode når avspillingen starter</string>
<string name="auto_flattr_ater_end">Flattre episode når avspillingen tar slutt</string>
<!--Search-->
- <string name="search_hint">Søk etter strømmer eller episoder</string>
- <string name="found_in_shownotes_label">Funnet i shownotater</string>
<string name="found_in_chapters_label">Funnet i kapitler</string>
<string name="search_status_no_results">Ingen resultater ble funnet</string>
<string name="search_label">Søk</string>
diff --git a/core/src/main/res/values-pl-rPL/strings.xml b/core/src/main/res/values-pl-rPL/strings.xml
index 80674a0ae..b9df0eb41 100644
--- a/core/src/main/res/values-pl-rPL/strings.xml
+++ b/core/src/main/res/values-pl-rPL/strings.xml
@@ -2,6 +2,7 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!--Activitiy and fragment titles-->
<string name="feeds_label">Kanały</string>
+ <string name="statistics_label">Statystyki</string>
<string name="add_feed_label">Dodaj podcast</string>
<string name="episodes_label">Odcinki</string>
<string name="all_episodes_short_label">Wszystkie</string>
@@ -13,11 +14,18 @@
<string name="downloads_running_label">W toku</string>
<string name="downloads_completed_label">Ukończone</string>
<string name="downloads_log_label">Dziennik</string>
+ <string name="subscriptions_label">Subskrypcje</string>
+ <string name="subscriptions_list_label">Lista subskrypcji</string>
<string name="cancel_download_label">Anuluj pobieranie</string>
<string name="playback_history_label">Historia odtwarzania</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 wolnego miejsca</string>
+ <string name="episode_cache_full_title">Pełna pamięć cache</string>
+ <string name="episode_cache_full_message">Limit pamięci cache został osiągnięty. Możesz zwiększyć pojemność cache w ustawieniach aplikacji.</string>
<!--Statistics fragment-->
+ <string name="total_time_listened_to_podcasts">Całkowity czas trwania podcastów:</string>
+ <string name="statistics_details_dialog">%1$d z %2$d odcinków rozpoczęto.\n\nZagrano %3$s z %4$s.</string>
<!--Main activity-->
<string name="drawer_open">Otwórz menu</string>
<string name="drawer_close">Zamknij menu</string>
@@ -44,6 +52,7 @@
<string name="no">Nie</string>
<string name="author_label">Autor</string>
<string name="language_label">Język</string>
+ <string name="url_label">URL</string>
<string name="podcast_settings_label">Ustawienia</string>
<string name="cover_label">Obraz</string>
<string name="error_label">Błąd</string>
@@ -58,15 +67,19 @@
<string name="length_prefix">Długość:\u0020</string>
<string name="size_prefix">Rozmiar:\u0020</string>
<string name="processing_label">Przetwarzanie</string>
+ <string name="loading_label">Ładowanie</string>
<string name="save_username_password_label">Zapisz nazwę użytkownika i hasło</string>
<string name="close_label">Zamknij</string>
<string name="retry_label">Spróbuj ponownie</string>
<string name="auto_download_label">Dołącz do automatycznego pobierania</string>
<string name="auto_download_apply_to_items_title">Zastosuj do poprzednich odcinków</string>
<string name="auto_download_apply_to_items_message">Nowe ustawienie <i>automatycznego pobierania</i> zostanie zastosowane do nowych odcinków.\n Czy chcesz zastosować je także do odcinków opublikowanych wcześniej?</string>
+ <string name="auto_delete_label">Automatyczne usuwanie odcinków</string>
<string name="parallel_downloads_suffix">\u0020równoległych pobierań</string>
+ <string name="feed_auto_download_global">Globalnie domyślnie</string>
<string name="feed_auto_download_always">Zawsze</string>
<string name="feed_auto_download_never">Nigdy</string>
+ <string name="send_label">Wyślij...</string>
<string name="episode_cleanup_never">Nigdy</string>
<string name="episode_cleanup_queue_removal">Kiedy nie są w kolejce</string>
<string name="episode_cleanup_after_listening">Po odtworzeniu</string>
@@ -80,21 +93,26 @@
<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</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>
<string name="mark_all_read_msg">Wszystkie odcinki zaznaczono jako odtworzone</string>
+ <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="show_info_label">Pokaż informacje</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>
<string name="share_link_with_position_label">Udostępnij link z aktualną pozycją</string>
<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>
+ <string name="episode_actions">Zatwierdź czynności</string>
<string name="hide_unplayed_episodes_label">Nieodtworzone</string>
<string name="hide_paused_episodes_label">Zatrzymane</string>
<string name="hide_played_episodes_label">Odtworzone</string>
@@ -102,6 +120,9 @@
<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="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>
<!--actions on feeditems-->
<string name="download_label">Pobierz</string>
<string name="play_label">Odtwórz</string>
@@ -110,6 +131,7 @@
<string name="stream_label">Strumień</string>
<string name="remove_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>
<string name="marked_as_read_label">Oznaczone jako odtworzone</string>
<string name="mark_unread_label">Oznacz jako nieodtworzone</string>
@@ -117,12 +139,15 @@
<string name="added_to_queue_label">Dodano do Kolejki</string>
<string name="remove_from_queue_label">Usuń z kolejki</string>
<string name="add_to_favorite_label">Dodaj do Ulubionych</string>
+ <string name="added_to_favorites">Dodaj do ulubionych</string>
<string name="remove_from_favorite_label">Usuń z Ulubionych</string>
+ <string name="removed_from_favorites">Usunięto z ulubionych</string>
<string name="visit_website_label">Odwiedź stronę</string>
<string name="support_label">Wspomóż na Flattr</string>
<string name="skip_episode_label">Pomiń odcinek</string>
<string name="activate_auto_download">Włącz automatyczne pobieranie</string>
<string name="deactivate_auto_download">Wyłącz automatyczne pobieranie</string>
+ <string name="reset_position">Zresetowano pozycję odtwarzania</string>
<string name="removed_item">Pozycja usunięta</string>
<!--Download messages and labels-->
<string name="download_successful">Operacja zakończona sukcesem</string>
@@ -139,14 +164,22 @@
<string name="download_error_connection_error">Błąd połączenia</string>
<string name="download_error_unknown_host">Nieznany host</string>
<string name="download_error_unauthorized">Błąd autoryzacji</string>
+ <string name="download_error_file_type_type">Błąd rodzaju pliku</string>
+ <string name="download_error_forbidden">Zabronione</string>
<string name="cancel_all_downloads_label">Anuluj wszystkie pobierania</string>
<string name="download_canceled_msg">Pobieranie anulowane</string>
+ <string name="download_canceled_autodownload_enabled_msg">Pobieranie zatrzymane\nWyłączone <i>Automatyczne pobieranie</i> dla tego elementu</string>
<string name="download_report_title">Pobieranie ukończone</string>
<string name="download_report_content_title">Raport pobierania</string>
<string name="download_error_malformed_url">Niepoprawny adres</string>
<string name="download_error_io_error">Błąd wejścia/wyjścia</string>
<string name="download_error_request_error">Błąd żądania</string>
<string name="download_error_db_access">Błąd dostępu do bazy danych</string>
+ <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="other">%d elementów zostało do pobrania</item>
+ </plurals>
<string name="downloads_processing">Przetwarzanie pobranych</string>
<string name="download_notification_title">Pobieranie danych podcastu</string>
<string name="download_report_content">%1$d pobierania poprawne, %2$d nieudane</string>
@@ -177,6 +210,8 @@
<!--Queue operations-->
<string name="lock_queue">Zablokuj Kolejkę</string>
<string name="unlock_queue">Odblokuj Kolejkę</string>
+ <string name="queue_locked">Kolejka zablokowana</string>
+ <string name="queue_unlocked">Kolejka odblokowana</string>
<string name="clear_queue_label">Wyczyść kolejkę</string>
<string name="undo">Cofnij</string>
<string name="removed_from_queue">Element usunięty</string>
@@ -185,6 +220,8 @@
<string name="sort">Sortuj</string>
<string name="date">Według daty</string>
<string name="duration">Według długości</string>
+ <string name="episode_title">Tytuł odcinka</string>
+ <string name="feed_title">Tytuł kanału</string>
<string name="ascending">Rosnąco</string>
<string name="descending">Malejąco</string>
<string name="clear_queue_confirmation_msg">Potwierdź usunięcie WSZYSTKICH pozycji z kolejki</string>
@@ -217,17 +254,24 @@
<!--Variable Speed-->
<string name="download_plugin_label">Pobierz wtyczkę</string>
<string name="no_playback_plugin_title">Wtyczka nie zainstalowana</string>
+ <string name="no_playback_plugin_or_sonic_msg">Dla odtwarzania w różnych prędkościach zalecamy odblokowania wbudowanego odtwarzacza Sonic [Android 4.1+].\n\nW innym przypadku możesz użycz zewnętrznego dodatku. <i>Prestissimo</i> ze Sklepu Play.\nAntennaPod nie ponosi odpowiedzialności za problemy z Prestissimo, powinny one być zgłaszane do właściciela dodatku.</string>
<string name="set_playback_speed_label">Prędkość odtwarzania</string>
+ <string name="enable_sonic">Włącz Sonic</string>
<!--Empty list labels-->
<string name="no_items_label">Brak elementów na tej liście.</string>
<string name="no_feeds_label">Nie subskrybowałeś jeszcze żadnego kanału.</string>
+ <string name="no_chapters_label">Ten odcinek nie ma rozdziałów.</string>
+ <string name="no_shownotes_label">Ten epizod nie ma notatek.</string>
<!--Preferences-->
+ <string name="storage_pref">Pamięć</string>
+ <string name="project_pref">Projekt</string>
<string name="other_pref">Inne</string>
<string name="about_pref">O...</string>
<string name="queue_label">Kolejka</string>
<string name="services_label">Usługi</string>
<string name="flattr_label">Flattr</string>
<string name="pref_episode_cleanup_title">Usuwanie odcinków</string>
+ <string name="pref_episode_cleanup_summary">Odcinki niebędące w kolejce i niebędące na liście ulubiobych powinny nadawać się do usunięcia, jeśli Automatyczne Pobieranie potrzebuje miejsca na nowe odcinki.</string>
<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>
@@ -242,6 +286,14 @@
<string name="pref_skip_keeps_episodes_title">Zachowaj pominięte odcinki</string>
<string name="playback_pref">Odtwarzanie</string>
<string name="network_pref">Sieć</string>
+ <string name="pref_autoUpdateIntervallOrTime_title">Częstotliwość aktualizacji lub Czas dnia</string>
+ <string name="pref_autoUpdateIntervallOrTime_sum">Określ częstotliwość albo konkretny czas dnia automatycznego odświeżania kanałów lub je wyłącz</string>
+ <string name="pref_autoUpdateIntervallOrTime_message">Możesz ustawić <i>częstotliwość</i> na przykład \"co 2 godziny\", ustawić konretny <i>czas dnia</i> na przykład \"7:00\" albo <i>wyłączyć</i> automatyczne aktualizacje.\n\n<small>Uwaga: Czas aktualizacji nie jest ścisły. Możesz napotkać małe opóźnienia.</small></string>
+ <string name="pref_autoUpdateIntervallOrTime_Disable">Zablokuj</string>
+ <string name="pref_autoUpdateIntervallOrTime_Interval">Ustaw częstotliwość</string>
+ <string name="pref_autoUpdateIntervallOrTime_TimeOfDay">Ustaw czas dnia</string>
+ <string name="pref_autoUpdateIntervallOrTime_every">każdy %1$s</string>
+ <string name="pref_autoUpdateIntervallOrTime_at">o %1$s</string>
<string name="pref_downloadMediaOnWifiOnly_sum">Pobieraj pliki tylko przez WiFi</string>
<string name="pref_followQueue_title">Odtwarzanie ciągłe</string>
<string name="pref_downloadMediaOnWifiOnly_title">WiFi media pobrane</string>
@@ -291,15 +343,24 @@
<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_started">Synchronizacja uruchomiona</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_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>
<string name="pref_expandNotify_sum">Zawsze rozwijaj powiadomienie żeby pokazać przyciski odtwarzacza.</string>
<string name="pref_persistNotify_title">Stałe przyciski odtwarzacza</string>
<string name="pref_persistNotify_sum">Utrzymuj powiadomienie i przyciski odtwarzania na ekranie blokady gdy odtwarzanie jest wstrzymane.</string>
+ <string name="pref_compact_notification_buttons_title">Ustaw przyciski ekranu blokowania</string>
+ <string name="pref_compact_notification_buttons_sum">Zmień przyciski odtwarzania na ekranie blokowania. Przyciski odtwórz/zatrzymaj są zawsze uwzględnione.</string>
+ <string name="pref_compact_notification_buttons_dialog_title">Wybierz maksimum z %1$d przedmiotów</string>
+ <string name="pref_compact_notification_buttons_dialog_error">Możesz tylko wybrać maksimum z %1$d przedmiotów.</string>
<string name="pref_lockscreen_background_title">Ustaw tło ekranu blokady</string>
+ <string name="pref_lockscreen_background_sum">Ustaw tło ekranu blokowania na aktualny obraz odcinka. W efekcie będzie zawsze pokazywał obraz w innych aplikacjach.</string>
<string name="pref_showDownloadReport_title">Pokaż raport z pobierania</string>
<string name="pref_showDownloadReport_sum">Jeżeli pobieranie się nie powiedzie, pokaż raport ze szczegółami błędu.</string>
<string name="pref_expand_notify_unsupport_toast">Android starszy niż 4.1 nie wspiera rozszerzonych powiadomień.</string>
@@ -315,32 +376,49 @@
<string name="pref_sonic_title">Odtwarzacz mediów Sonic</string>
<string name="pref_rewind_sum">Dostosuj liczbę sekund, aby przejść do tyłu po naciśnięciu przycisku przewijania kliknięciu</string>
<string name="pref_fast_forward_sum">Dostosuj liczbę sekund, aby przejść do przodu, gdy szybko do przodu kliknięciu przycisku</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>
+ <string name="pref_proxy_sum">Ustaw proxy sieciowe</string>
+ <string name="pref_faq">Najczęściej zadawane pytania</string>
+ <string name="pref_known_issues">Znane problemy</string>
+ <string name="pref_no_browser_found">Nie znaleziono przeglądarki.</string>
+ <string name="pref_cast_title">Obsługa Chromecast</string>
+ <string name="pref_cast_message_play_flavor">Uruchom obsługę dla zdalnego odtwarzania mediów na innych urządzeniach (takich jak Chromecast, Audio Speakers albo Android TV)</string>
+ <string name="pref_cast_message_free_flavor">Chromecast wymagadodatkowych bibliotek, które są zablokowane w tej wersji AntennaPod</string>
<!--Auto-Flattr dialog-->
<string name="auto_flattr_enable">Włącz automatyczne wspieranie na flattr.</string>
<string name="auto_flattr_after_percent">Z-flattr-uj odcinki odegrane %d procentach.</string>
<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 kanałów lub odcinków</string>
- <string name="found_in_shownotes_label">Znaleziono w notatkach</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>
<!--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>
+ <string name="opml_import_explanation_1">Wybierz konkretą ścieżkę z lokalnego systemu plików.</string>
<string name="opml_import_explanation_2">Użyj zewnętrznej aplikacji takiej jak Dropbox, Google Drive lub ulubionego menedżera plików, aby otworzyć plik OPML.</string>
+ <string name="opml_import_explanation_3">Wiele aplikacji takich jak Google Mail, Dropbox, Google Drive i większość menedżerów plików potrafi <i>otworzyć</i>pliki OPML <i>przy użyciu</i>AntennaPod</string>
<string name="start_import_label">Rozpocznij import</string>
<string name="opml_import_label">Import OPML</string>
<string name="opml_directory_error">BŁĄD!</string>
<string name="reading_opml_label">Odczytuję plik OPML</string>
+ <string name="opml_reader_error">Wystąpił błąd podczas odczytywania pliku OPML:</string>
+ <string name="opml_import_error_no_file">Nie wbrano pliku!</string>
<string name="select_all_label">Zaznacz wszystko</string>
<string name="deselect_all_label">Odznacz wszystko</string>
+ <string name="select_options_label">Wybierz...</string>
+ <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="exporting_label">Eksportowanie...</string>
<string name="export_error_label">Błąd eksportu</string>
<string name="opml_export_success_title">Eksport OPML udany.</string>
<string name="opml_export_success_sum">Plik .opml został zapisany do:\u0020</string>
+ <string name="opml_import_ask_read_permission">Dostęp do zewnętrznej pamięci jest potrzebny do odczytywania plików OPML</string>
<!--Sleep timer-->
<string name="set_sleeptimer_label">Ustaw czas do wyłączenia</string>
<string name="disable_sleeptimer_label">Wyłącz wyłącznik czasowy</string>
@@ -389,6 +467,7 @@ https://gpodder.net/register/</string>
<string name="gpodnetauth_device_chooseExistingDevice">Wybierz istniejące urządzenie:</string>
<string name="gpodnetauth_device_errorEmpty">Identyfikator urządzenia nie może być pusty</string>
<string name="gpodnetauth_device_errorAlreadyUsed">Identyfikator urządzenia w użyciu</string>
+ <string name="gpodnetauth_device_caption_errorEmpty">Pole nie może być puste</string>
<string name="gpodnetauth_device_butChoose">Wybierz</string>
<string name="gpodnetauth_finish_title">Logowanie zakończone sukcesem!</string>
<string name="gpodnetauth_finish_descr">Gratulacje! Twoje konto na gpodder.net jest połączone z urządzeniem. AntennaPod będzie automatycznie synchronizować subskrypcje na urządzeniu z kontem na gpodder.net. </string>
@@ -403,6 +482,7 @@ https://gpodder.net/register/</string>
<string name="create_folder_label">Utwórz folder</string>
<string name="choose_data_directory">Wybierz folder danych</string>
<string name="choose_data_directory_message">Wybierz główny folder dla danych. AntennaPod utworzy odpowiednie podkatalogi.</string>
+ <string name="choose_data_directory_permission_rationale">Dostęp do pamięci zewnętrznej jest wymagany do zmiany folderu danych.</string>
<string name="create_folder_msg">Utworzyć nowy folder o nazwie \"%1$s\"?</string>
<string name="create_folder_success">Utworzono nowy folder</string>
<string name="create_folder_error_no_write_access">Nie można zapisać do tego folderu</string>
@@ -422,6 +502,7 @@ https://gpodder.net/register/</string>
<!--Online feed view-->
<string name="subscribe_label">Subskrybuj</string>
<string name="subscribed_label">Subskrybowane</string>
+ <string name="downloading_label">Pobieranie...</string>
<!--Content descriptions for image buttons-->
<string name="rewind_label">Cofnij</string>
<string name="fast_forward_label">Przewiń</string>
@@ -435,11 +516,19 @@ https://gpodder.net/register/</string>
<!--Feed information screen-->
<string name="authentication_label">Autoryzacja</string>
<string name="authentication_descr">Zmień swoją nazwę użytkownika oraz hasło dla tego podcastu i jego odcinków</string>
+ <string name="auto_download_settings_label">Ustawienia automatycznego pobierania</string>
+ <string name="episode_filters_label">Filtr odcinków</string>
+ <string name="episode_filters_description">Wykaz terminów używanych aby zdecydować, czy odcinek powinien być włączony lub wyłączony podczas automatycznego pobierania.</string>
+ <string name="episode_filters_include">Włączając</string>
+ <string name="episode_filters_exclude">Wyłączając</string>
+ <string name="episode_filters_hint">Pojedyncze słowa \n\"Kilka słów\"</string>
+ <string name="keep_updated">Utrzymuj zaktualizowane</string>
<!--Progress information-->
<string name="progress_upgrading_database">Aktualizacja bazy danych</string>
<!--AntennaPodSP-->
<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>
<!--Episodes apply actions-->
<string name="all_label">Wszystkie</string>
<string name="selected_all_label">Zaznaczono wszystkie odcinki</string>
@@ -453,6 +542,10 @@ https://gpodder.net/register/</string>
<string name="selected_downloaded_label">Zaznaczono pobrane odcinki</string>
<string name="not_downloaded_label">Nie pobrane</string>
<string name="selected_not_downloaded_label">Zaznaczono niepobrane odcinki</string>
+ <string name="queued_label">W kolejce</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>
<!--Sort-->
<string name="sort_title_a_z">Tytuł (A \u2192 Z)</string>
<string name="sort_title_z_a">Tytuł (Z \u2192 A)</string>
@@ -467,7 +560,40 @@ https://gpodder.net/register/</string>
<string name="rating_later_label">Przypomnij później</string>
<string name="rating_now_label">Pewnie, zróbmy to!</string>
<!--Audio controls-->
+ <string name="audio_controls">Sterowanie audio</string>
+ <string name="playback_speed">Prędkość odtwarzania</string>
+ <string name="volume">Głośność</string>
+ <string name="left_short">Lewy</string>
+ <string name="right_short">Prawy</string>
+ <string name="audio_effects">Efekty audio</string>
+ <string name="stereo_to_mono">Downmix: Stereo na mono</string>
+ <string name="sonic_only">Tylko Sonic</string>
<!--proxy settings-->
+ <string name="proxy_type_label">Typ</string>
+ <string name="host_label">Host</string>
+ <string name="port_label">Port</string>
+ <string name="optional_hint">(Dodatkowe)</string>
+ <string name="proxy_test_label">Test</string>
+ <string name="proxy_checking">Sprawdzanie...</string>
+ <string name="proxy_test_successful">Test zakończony powodzeniem</string>
+ <string name="proxy_test_failed">Test zakończony niepowodzeniem</string>
+ <string name="proxy_host_empty_error">Host nie może być pusty!</string>
+ <string name="proxy_host_invalid_error">Host nie jest prawidłowym adresem IP albo domeną</string>
+ <string name="proxy_port_invalid_error">Błędny port</string>
<!--Casting-->
+ <string name="cast_media_route_menu_title">Odtwarzaj na...</string>
+ <string name="cast_disconnect_label">Rozłącz sesję</string>
+ <string name="cast_not_castable">Wybrane media nie są kompatybilne z urządzeniem nadającym.</string>
+ <string name="cast_failed_to_play">Wystąpił błąd podczas uruchamiania odtwarzania</string>
+ <string name="cast_failed_to_stop">Wystąpił błąd podczas zatrzymywania odtwarzania</string>
+ <string name="cast_failed_to_pause">Wystąpił błąd podczas pauzowania odtwarzania</string>
<!--<string name="cast_failed_to_connect">Could not connect to the device</string>-->
+ <string name="cast_failed_setting_volume">Wystąpił błąd podczas zmiany poziomu głośności</string>
+ <string name="cast_failed_no_connection">Brak połączenia z urządzeniem nadającym</string>
+ <string name="cast_failed_no_connection_trans">Połączenie z urządzeniem nadającym zostało przerwane. Aplikacja próbuje przywrócić połączenie, jeśli jest to możliwe. Proszę poczekać kilka sekund i spróbować ponownie.</string>
+ <string name="cast_failed_perform_action">Błąd podczas wykonywania akcji.</string>
+ <string name="cast_failed_status_request">Wystąpił błąd podczas synchronizacji z urządzeniem nadającym.</string>
+ <string name="cast_failed_seek">Wystąpił błąd podczas szukania nowej pozycji na urządzeniu nadającym.</string>
+ <string name="cast_failed_receiver_player_error">Urządzenie odbierające napotkało poważny problem</string>
+ <string name="cast_failed_media_error_skipping">Błąd podczas odtwarzania, pomijanie...</string>
</resources>
diff --git a/core/src/main/res/values-pt-rBR/strings.xml b/core/src/main/res/values-pt-rBR/strings.xml
index 76b807360..921252966 100644
--- a/core/src/main/res/values-pt-rBR/strings.xml
+++ b/core/src/main/res/values-pt-rBR/strings.xml
@@ -12,20 +12,20 @@
<string name="add_new_feed_label">Adicionar podcast</string>
<string name="downloads_label">Downloads</string>
<string name="downloads_running_label">Rodando</string>
- <string name="downloads_completed_label">Completado</string>
+ <string name="downloads_completed_label">Finalizado</string>
<string name="downloads_log_label">Log</string>
<string name="subscriptions_label">Assinaturas</string>
<string name="subscriptions_list_label">Lista de Assinaturas</string>
- <string name="cancel_download_label">Cancelar Download</string>
+ <string name="cancel_download_label">Cancelar\nDownload</string>
<string name="playback_history_label">Histórico de reprodução</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 livre</string>
- <string name="episode_cache_full_title">Cache de episódio completo</string>
+ <string name="free_space_label">%1$s livre(s)</string>
+ <string name="episode_cache_full_title">Cache de episódios cheio</string>
<string name="episode_cache_full_message">O limite de cache de episódios foi alcançado. Você pode aumentar o tamanho do cache em Configurações.</string>
<!--Statistics fragment-->
- <string name="total_time_listened_to_podcasts">Tempo total de podcasts escutados:</string>
- <string name="statistics_details_dialog">%1$d de %2$d episódios iniciados.\n\nEscutados %3$s de %4$s.</string>
+ <string name="total_time_listened_to_podcasts">Tempo total de podcasts reproduzidos:</string>
+ <string name="statistics_details_dialog">%1$d de %2$d episódios iniciados.\n\nReproduzidos %3$s de %4$s.</string>
<!--Main activity-->
<string name="drawer_open">Abrir menu</string>
<string name="drawer_close">Fechar menu</string>
@@ -33,9 +33,9 @@
<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_counter_new_unplayed">Número de episódios novos e não escutados ainda</string>
+ <string name="drawer_feed_counter_new_unplayed">Número de episódios novos e não reproduzidos</string>
<string name="drawer_feed_counter_new">Numero de novos episódios</string>
- <string name="drawer_feed_counter_unplayed">Número de episódios não escutados</string>
+ <string name="drawer_feed_counter_unplayed">Número de episódios não reproduzidos</string>
<string name="drawer_feed_counter_none">Nenhum</string>
<!--Webview actions-->
<string name="open_in_browser_label">Abrir no navegador</string>
@@ -72,11 +72,11 @@
<string name="close_label">Fechar</string>
<string name="retry_label">Tentar novamente</string>
<string name="auto_download_label">Incluir em downloads automáticos</string>
- <string name="auto_download_apply_to_items_title">Aplicar a episódios anteriores</string>
- <string name="auto_download_apply_to_items_message">A nova <i>Download Automático</i> configuração irá se aplicar automaticamente a novos episódios.\nVocê quer aplicá-la a aos episódios anteriores?</string>
+ <string name="auto_download_apply_to_items_title">Aplicar aos episódios anteriores</string>
+ <string name="auto_download_apply_to_items_message">A nova configuração de <i>Download Automático</i> será aplicada automaticamente a novos episódios.\nVocê deseja aplicá-la aos episódios anteriores?</string>
<string name="auto_delete_label">Apagar episódio automaticamente</string>
<string name="parallel_downloads_suffix">\u0020 downloads paralelos</string>
- <string name="feed_auto_download_global">configurações globais</string>
+ <string name="feed_auto_download_global">Padrão global</string>
<string name="feed_auto_download_always">Sempre</string>
<string name="feed_auto_download_never">Nunca</string>
<string name="send_label">Enviar...</string>
@@ -89,40 +89,39 @@
</plurals>
<!--'Add Feed' Activity labels-->
<string name="feedurl_label">URL do Feed</string>
- <string name="etxtFeedurlHint">www.example.com/feed</string>
+ <string name="etxtFeedurlHint">www.exemplo.com/feed</string>
<string name="txtvfeedurl_label">Adicionar podcast por URL</string>
<string name="podcastdirectories_label">Procurar Podcast na Pasta</string>
- <string name="podcastdirectories_descr">Você pode buscar novos episódios por nome, categoria ou popularidade no gpodder.net, ou buscar no iTunes.</string>
- <string name="browse_gpoddernet_label">Listar no gpodder.net</string>
+ <string name="browse_gpoddernet_label">Pesquisar no gpodder.net</string>
<!--Actions on feeds-->
- <string name="mark_all_read_label">Marcar todos como lido</string>
- <string name="mark_all_read_msg">Marcar todos Episódios como lidos</string>
- <string name="mark_all_read_confirmation_msg">Por favor, confirme que você quer marcar todos os episódios como já tocados.</string>
- <string name="mark_all_read_feed_confirmation_msg">Por favor confirme se você quer marcar todos os episódios deste feed como já tocados.</string>
- <string name="mark_all_seen_label">Marcar todos como lido</string>
+ <string name="mark_all_read_label">Marcar todos como reproduzidos</string>
+ <string name="mark_all_read_msg">Marcar todos Episódios como reproduzidos</string>
+ <string name="mark_all_read_confirmation_msg">Por favor, confirme que você deseja marcar todos os episódios como já reproduzidos.</string>
+ <string name="mark_all_read_feed_confirmation_msg">Por favor confirme se você deseja marcar todos os episódios deste feed como já reproduzidos.</string>
+ <string name="mark_all_seen_label">Marcar todos como vistos</string>
<string name="show_info_label">Mostrar informação</string>
<string name="remove_feed_label">Remover Podcast</string>
<string name="share_label">Compartilhar...</string>
- <string name="share_link_label">Compartilhar link do site</string>
- <string name="share_link_with_position_label">Compartilhar link com posição</string>
+ <string name="share_link_label">Compartilhar Link</string>
+ <string name="share_link_with_position_label">Compartilhar Link com posição</string>
<string name="share_feed_url_label">Compartilhar Link do Feed</string>
- <string name="share_item_url_label">Compartilhar Link 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="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>
<string name="episode_actions">Aplicar ações</string>
- <string name="hide_unplayed_episodes_label">Não lido</string>
+ <string name="hide_unplayed_episodes_label">Não reproduzido</string>
<string name="hide_paused_episodes_label">Pausado</string>
- <string name="hide_played_episodes_label">Lido</string>
+ <string name="hide_played_episodes_label">Reproduzido</string>
<string name="hide_queued_episodes_label">Enfileirado</string>
<string name="hide_not_queued_episodes_label">Não enfileirado</string>
<string name="hide_downloaded_episodes_label">Baixado</string>
<string name="hide_not_downloaded_episodes_label">Não baixado</string>
<string name="filtered_label">Filtrado</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Última Atualização falhou</string>
- <string name="open_podcast">Podcast Aberto</string>
+ <string name="open_podcast">Abrir Podcast</string>
<!--actions on feeditems-->
<string name="download_label">Download</string>
<string name="play_label">Reproduzir</string>
@@ -132,9 +131,9 @@
<string name="remove_label">Remover</string>
<string name="remove_episode_lable">Remover Episódio</string>
<string name="marked_as_seen_label">Marcar como visto</string>
- <string name="mark_read_label">Marcar como lido</string>
- <string name="marked_as_read_label">Marcado como lido</string>
- <string name="mark_unread_label">Marcar como não lido</string>
+ <string name="mark_read_label">Marcar como reproduzido</string>
+ <string name="marked_as_read_label">Marcado como reproduzido</string>
+ <string name="mark_unread_label">Marcar como não reproduzido</string>
<string name="add_to_queue_label">Adicionar à fila</string>
<string name="added_to_queue_label">Adicionado à fila</string>
<string name="remove_from_queue_label">Remover da fila</string>
@@ -169,7 +168,7 @@
<string name="cancel_all_downloads_label">Cancelar todos os downloads</string>
<string name="download_canceled_msg">Download cancelado</string>
<string name="download_canceled_autodownload_enabled_msg">Download cancelado\nDesabilitado <i>Download Automático</i> para este item</string>
- <string name="download_report_title">Downloads finalizados</string>
+ <string name="download_report_title">Downloads finalizados com erro(s)</string>
<string name="download_report_content_title">Reportar Download</string>
<string name="download_error_malformed_url">URL inválida</string>
<string name="download_error_io_error">Erro de IO</string>
@@ -188,11 +187,11 @@
<string name="download_type_image">Imagem</string>
<string name="download_request_error_dialog_message_prefix">Ocorreu um erro durante download do arquivo:\u0020</string>
<string name="authentication_notification_title">Autenticação requerida</string>
- <string name="authentication_notification_msg">O recurso que você requisitou requer um usuário e uma senha</string>
- <string name="confirm_mobile_download_dialog_title">Confirmar Download Mobile</string>
- <string name="confirm_mobile_download_dialog_message_not_in_queue">Baixar sobre plano de dados foi desabilitado nas configurações.\n\nVocê pode escolher entre apenas adicionar o episódio na fila ou você pode permitir o download temporáriamente.\n\n<small>Sua escolha será lembrada por 10 minutos.</small></string>
- <string name="confirm_mobile_download_dialog_message">Baixar sobre plano de dados foi desabilitado em configurações.\n\n Você quer permitir o download temporáriamente?\n\n<small>Sua escolha será lembrada por 10 minutos</small></string>
- <string name="confirm_mobile_download_dialog_only_add_to_queue">Enfileirados</string>
+ <string name="authentication_notification_msg">O recurso que você solicitou requer um usuário e uma senha</string>
+ <string name="confirm_mobile_download_dialog_title">Confirmar Download utilizando dados móveis</string>
+ <string name="confirm_mobile_download_dialog_message_not_in_queue">O download utilizando plano de dados foi desabilitado nas configurações.\n\nVocê pode escolher entre apenas adicionar o episódio na fila ou você pode permitir o download temporáriamente.\n\n<small>Sua escolha será lembrada por 10 minutos.</small></string>
+ <string name="confirm_mobile_download_dialog_message">O download sobre plano de dados foi desabilitado nas configurações.\n\n Você deseja permitir o download temporáriamente?\n\n<small>Sua escolha será lembrada por 10 minutos</small></string>
+ <string name="confirm_mobile_download_dialog_only_add_to_queue">Adicionar à fila</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">Permitir temporariamente</string>
<!--Mediaplayer messages-->
<string name="player_error_msg">Erro!</string>
@@ -223,7 +222,7 @@
<string name="feed_title">Titulo do Feed</string>
<string name="ascending">Crescente</string>
<string name="descending">Decrescente</string>
- <string name="clear_queue_confirmation_msg">Por favor confirme que você quer limpar a fila de TODOS eposódios</string>
+ <string name="clear_queue_confirmation_msg">Por favor confirme que você deseja limpar TODOS episódios da fila</string>
<!--Flattr-->
<string name="flattr_auth_label">Logar no Flattr</string>
<string name="flattr_auth_explanation">Pressione o botão abaixo para iniciar o processo de autenticação. Você será direcionado para a tela de login do Flattr, que pedirá autorização para que o AntennaPod utilize o Flattr. Após conceder a permissão, você retornará a esta tela automaticamente.</string>
@@ -260,7 +259,7 @@
<string name="no_items_label">Não existem itens nesta lista.</string>
<string name="no_feeds_label">Você ainda não assinou nenhum feed.</string>
<string name="no_chapters_label">Este episódio não possui capítulos</string>
- <string name="no_shownotes_label">Este episódio não possui notas de apresentação</string>
+ <string name="no_shownotes_label">Este episódio não possui notas.</string>
<!--Preferences-->
<string name="storage_pref">Armazenamento</string>
<string name="project_pref">Projeto</string>
@@ -270,24 +269,24 @@
<string name="services_label">Serviços</string>
<string name="flattr_label">Flattr</string>
<string name="pref_episode_cleanup_title">Limpar Episódio</string>
- <string name="pref_episode_cleanup_summary">Episódios que não foram enfileirados e não foram favoritados deveriam ser elegídos para remoção se o Auto Download precisar de espaço para novos episódios</string>
- <string name="pref_pauseOnDisconnect_sum">Pausar a exibição quando phones de ouvidos ou bluetooth forem disconectados</string>
- <string name="pref_unpauseOnHeadsetReconnect_sum">Continuar a exibição quando os fones de ouvido forem reconectados</string>
- <string name="pref_unpauseOnBluetoothReconnect_sum">Continuar a exibição quando o bluetooth reconectar</string>
+ <string name="pref_episode_cleanup_summary">Episódios que não estão na fila e não estão nos favoritos podem ser removidos se o Download Automático precisar de espaço para novos episódios</string>
+ <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 rápido</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 exibição for concluída</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 escutados </string>
- <string name="pref_smart_mark_as_played_title">Inteligentemente marcar como escutado </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>
<string name="network_pref">Rede</string>
- <string name="pref_autoUpdateIntervallOrTime_title">Intervado de atualização ou Tempo do dia</string>
- <string name="pref_autoUpdateIntervallOrTime_sum">Especifique um intervalo ou um tempo específico do dia para atualizar os seus feed automaticamente</string>
- <string name="pref_autoUpdateIntervallOrTime_message">Você pode configurar um <i>intervalo</i> como \"cada 2 horas\", configurar um específico <i>horário do dia</i> como \"7:00 AM\" ou <i>desabilitar</i> atualizações automaticas completamente.\n\n<small>Observe: Horários de atualização não são precisos. Você deve considar um possível atraso.</small></string>
+ <string name="pref_autoUpdateIntervallOrTime_title">Atualizar intervalo ou momento do dia</string>
+ <string name="pref_autoUpdateIntervallOrTime_sum">Especificar um intervalo ou um momento específico do dia para atualizar os seus feeds automaticamente</string>
+ <string name="pref_autoUpdateIntervallOrTime_message">Você pode configurar um <i>intervalo</i> como \"cada 2 horas\", configurar um <i>horário do dia</i> específico como \"7:00 AM\" ou <i>desabilitar</i> atualizações automaticas completamente.\n\n<small>Observe: Horários de atualização não são precisos. Você deve considar um possível atraso.</small></string>
<string name="pref_autoUpdateIntervallOrTime_Disable">Desabilitar</string>
<string name="pref_autoUpdateIntervallOrTime_Interval">Configurar Intervalo</string>
<string name="pref_autoUpdateIntervallOrTime_TimeOfDay">Configurar Tempo do dia</string>
@@ -298,7 +297,7 @@
<string name="pref_downloadMediaOnWifiOnly_title">Download de mídia via WiFi</string>
<string name="pref_pauseOnHeadsetDisconnect_title">Fones de ouvido desconectados</string>
<string name="pref_unpauseOnHeadsetReconnect_title">Fones de ouvido reconectados</string>
- <string name="pref_unpauseOnBluetoothReconnect_title">Bluetooth reconectados</string>
+ <string name="pref_unpauseOnBluetoothReconnect_title">Bluetooth reconectado</string>
<string name="pref_mobileUpdate_title">Atualizações via Rede de Dados Celular</string>
<string name="pref_mobileUpdate_sum">Permite atualizações quando conectado na rede de dados celular</string>
<string name="refreshing_label">Atualizando</string>
@@ -315,8 +314,8 @@
<string name="pref_set_theme_title">Selecionar tema</string>
<string name="pref_nav_drawer_title">Customizar Gaveta de Navegação</string>
<string name="pref_nav_drawer_sum">Customizar a aparencia da gaveta de navegação.</string>
- <string name="pref_nav_drawer_items_title">Configurar items a Gaveta de Navegação</string>
- <string name="pref_nav_drawer_items_sum">Escolher quais items irão aparecer na gaveta de navegação.</string>
+ <string name="pref_nav_drawer_items_title">Configurar itens da Gaveta de Navegação</string>
+ <string name="pref_nav_drawer_items_sum">Escolher quais itens irão aparecer na gaveta de navegação.</string>
<string name="pref_nav_drawer_feed_order_title">Configurar Ordem de Assinaturas</string>
<string name="pref_nav_drawer_feed_order_sum">Mudar a ordem de suas assinaturas</string>
<string name="pref_nav_drawer_feed_counter_title">Configurar um contador de assinaturas</string>
@@ -342,8 +341,6 @@
<string name="pref_gpodnet_logout_toast">Saiu com sucesso</string>
<string name="pref_gpodnet_setlogin_information_title">Alterar informações de login</string>
<string name="pref_gpodnet_setlogin_information_sum">Alterar informações de login da sua conta gpodder.net</string>
- <string name="pref_gpodnet_sync_title">Sincronizar agora</string>
- <string name="pref_gpodnet_sync_sum">Sincronizar assinaturas e estados dos episódios com gpodder.net</string>
<string name="pref_gpodnet_sync_started">Sincronização iniciada</string>
<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>
@@ -366,7 +363,7 @@
<string name="pref_showDownloadReport_sum">Se os downloads falharem, gerar um relatório que mostra os detalhes da falha.</string>
<string name="pref_expand_notify_unsupport_toast">Versões do Android inferiores a 4.1 não suportam notificações expansíveis</string>
<string name="pref_queueAddToFront_sum">Adicionar um novo episódio para a frente da fila.</string>
- <string name="pref_queueAddToFront_title">Enfileirar para a frente</string>
+ <string name="pref_queueAddToFront_title">Adicionar ao topo da fila</string>
<string name="pref_smart_mark_as_played_disabled">Desabilitado</string>
<string name="pref_image_cache_size_title">Tamanho da Imagem em Cache</string>
<string name="pref_image_cache_size_sum">Tamanho do cache de disco para imagens.</string>
@@ -379,7 +376,7 @@
<string name="pref_current_value">Valor atual: %1$s</string>
<string name="pref_proxy_title">Proxy</string>
<string name="pref_proxy_sum">Configurar um proxy da rede</string>
- <string name="pref_faq">FAQ</string>
+ <string name="pref_faq">Perguntas Frequentes</string>
<string name="pref_known_issues">Problemas conhecidos</string>
<string name="pref_no_browser_found">Nenhum navegador web encontrado.</string>
<string name="pref_cast_title">Suporte ao Chromecast</string>
@@ -393,8 +390,6 @@
<string name="auto_flattr_ater_beginning">Episódio Flattr quando a repodução iniciar</string>
<string name="auto_flattr_ater_end">Episódio Flattr quando a reprodução finalizar</string>
<!--Search-->
- <string name="search_hint">Procurar por Feeds ou Episódios</string>
- <string name="found_in_shownotes_label">Encontrado nas notas do podcast</string>
<string name="found_in_chapters_label">Encontrado nos capítulos</string>
<string name="search_status_no_results">Nenhum resultado encontrado</string>
<string name="search_label">Pesquisar</string>
@@ -480,7 +475,7 @@
<string name="selected_folder_label">Selecionar pasta:</string>
<string name="create_folder_label">Criar pasta</string>
<string name="choose_data_directory">Escolher pasta de dados</string>
- <string name="choose_data_directory_message">Por favor escolha a base do seu repositório de dados. O AntennaPode irá criar os sub-diretórios apropriados.</string>
+ <string name="choose_data_directory_message">Por favor escolha a raiz da sua pasta de dados. O AntennaPod irá criar os sub-diretórios apropriados.</string>
<string name="choose_data_directory_permission_rationale">Acesso ao armazenamento externo é necessário para mudar o repositório de dados</string>
<string name="create_folder_msg">Criar nova pasta com o nome \"%1$s\"?</string>
<string name="create_folder_success">Nova pasta criada</string>
@@ -497,7 +492,7 @@
<string name="pref_pausePlaybackForFocusLoss_title">Pausar em interrupções</string>
<string name="pref_resumeAfterCall_sum">Continuar a reprodução depois que uma ligação telefonica for concluida</string>
<string name="pref_resumeAfterCall_title">Continuar após ligação</string>
- <string name="pref_restart_required">AntennaPode deve ser reiniciado para que esta mudanças tenha efeito.</string>
+ <string name="pref_restart_required">AntennaPod deve ser reiniciado para que esta mudanças tenha efeito.</string>
<!--Online feed view-->
<string name="subscribe_label">Assinar</string>
<string name="subscribed_label">Assinado</string>
@@ -510,7 +505,7 @@
<string name="navigate_upwards_label">Navegar para cima</string>
<string name="status_downloading_label">O epísódio está sendo baixado</string>
<string name="in_queue_label">Episódio está na fila</string>
- <string name="drag_handle_content_description">Arrastar para mudar a posição deste item</string>
+ <string name="drag_handle_content_description">Arraste para mudar a posição deste item</string>
<string name="load_next_page_label">Carregar a próxima página</string>
<!--Feed information screen-->
<string name="authentication_label">Autenticação</string>
@@ -523,9 +518,9 @@
<string name="episode_filters_hint">Única palavra \n\"Múltiplas palavras\"</string>
<string name="keep_updated">Manter Atualizado</string>
<!--Progress information-->
- <string name="progress_upgrading_database">Atualizar o banco de dados</string>
+ <string name="progress_upgrading_database">Atualizando o banco de dados</string>
<!--AntennaPodSP-->
- <string name="sp_apps_importing_feeds_msg">Importar assinaturas de aplicativos de finalidade única...</string>
+ <string name="sp_apps_importing_feeds_msg">Importando assinaturas de aplicativos de finalidade única...</string>
<string name="search_itunes_label">Procurar no iTunes</string>
<string name="filter">Filtrar</string>
<!--Episodes apply actions-->
@@ -533,18 +528,18 @@
<string name="selected_all_label">Selecionar todos Episódios</string>
<string name="none_label">Nenhum</string>
<string name="deselected_all_label">Desmarcar todos Episódios</string>
- <string name="played_label">Tocado</string>
- <string name="selected_played_label">Selecionar episódios tocados</string>
- <string name="unplayed_label">Não tocado</string>
- <string name="selected_unplayed_label">Selecionar episódios não tocados</string>
+ <string name="played_label">Reproduzido</string>
+ <string name="selected_played_label">Selecionar episódios reproduzidos</string>
+ <string name="unplayed_label">Não reproduzido</string>
+ <string name="selected_unplayed_label">Selecionar episódios não reproduzidos</string>
<string name="downloaded_label">Baixados</string>
- <string name="selected_downloaded_label">Selecionar episódios baixados</string>
- <string name="not_downloaded_label">Não baixado</string>
- <string name="selected_not_downloaded_label">Selecionar episídios não baixados</string>
+ <string name="selected_downloaded_label">Episódios baixados selecionados</string>
+ <string name="not_downloaded_label">Não baixados</string>
+ <string name="selected_not_downloaded_label">Episídios não baixados selecionados</string>
<string name="queued_label">Enfileirado</string>
- <string name="selected_queued_label">Selecionar episódios enfileirados</string>
+ <string name="selected_queued_label">Episódios enfileirados selecionados</string>
<string name="not_queued_label">Não enfileirado</string>
- <string name="selected_not_queued_label">Selecionar episódios não enfileirados</string>
+ <string name="selected_not_queued_label">Episódios não enfileirados selecionados</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>
@@ -557,7 +552,7 @@
<string name="rating_message">Nós gostaríamos que você dedicasse um tempo para avaliar o AntennaPod.</string>
<string name="rating_never_label">Me deixe em paz</string>
<string name="rating_later_label">Lembre-me mais tarde</string>
- <string name="rating_now_label">Claro, deixe-me fazer isso!</string>
+ <string name="rating_now_label">Claro, vamos fazer isso!</string>
<!--Audio controls-->
<string name="audio_controls">Controles de Àudio</string>
<string name="playback_speed">Velocidade da Reprodução</string>
@@ -577,22 +572,22 @@
<string name="proxy_test_successful">Teste realizado com sucesso</string>
<string name="proxy_test_failed">Teste falhou</string>
<string name="proxy_host_empty_error">Host não pode ser vazio</string>
- <string name="proxy_host_invalid_error">Host não possui um endereço de IP válido ou dominio</string>
+ <string name="proxy_host_invalid_error">Host não possui um endereço de IP ou domínio válidos</string>
<string name="proxy_port_invalid_error">Porta inválida</string>
<!--Casting-->
- <string name="cast_media_route_menu_title">Tocar em...</string>
+ <string name="cast_media_route_menu_title">Reproduzir em...</string>
<string name="cast_disconnect_label">Desconectar a sessão do cast</string>
- <string name="cast_not_castable">A mídia selecionada não é compatível com o dispositivo cast</string>
+ <string name="cast_not_castable">A mídia selecionada não é compatível com o dispositivo em cast</string>
<string name="cast_failed_to_play">Falha ao iniciar a reprodução da mídia</string>
<string name="cast_failed_to_stop">Falha ao parar a reprodução da mídia</string>
<string name="cast_failed_to_pause">Falha ao pausar a reprodução da mídia</string>
<!--<string name="cast_failed_to_connect">Could not connect to the device</string>-->
<string name="cast_failed_setting_volume">Falha ao configurar o volume</string>
<string name="cast_failed_no_connection">Sem conexão com o dispositivo cast</string>
- <string name="cast_failed_no_connection_trans">A conexão com o dispositivo cast foi perdida. A aplicação está tentando re-estabelecer a coneção, se possivel. Por favor espere por alguns segundos e tente novamente.</string>
+ <string name="cast_failed_no_connection_trans">A conexão com o dispositivo cast foi perdida. A aplicação está tentando reestabelecer a conexão. Por favor espere por alguns segundos e tente novamente.</string>
<string name="cast_failed_perform_action">Falha ao executar a ação</string>
<string name="cast_failed_status_request">Falha ao sincronizar com o dispositivo cast</string>
<string name="cast_failed_seek">Falha ao buscar uma nova posição no dispositivo cast</string>
- <string name="cast_failed_receiver_player_error">O receptor de reprodução encontrou um erro no servidor</string>
- <string name="cast_failed_media_error_skipping">Erro ao tocar a mídia. Pulando...</string>
+ <string name="cast_failed_receiver_player_error">O receptor de reprodução encontrou um erro grave</string>
+ <string name="cast_failed_media_error_skipping">Erro ao reproduzir mídia. Pulando...</string>
</resources>
diff --git a/core/src/main/res/values-pt/strings.xml b/core/src/main/res/values-pt/strings.xml
index d1b080cb4..329d89e52 100644
--- a/core/src/main/res/values-pt/strings.xml
+++ b/core/src/main/res/values-pt/strings.xml
@@ -36,6 +36,7 @@
<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>
+ <string name="drawer_feed_counter_downloaded">Número de episódios descarregados</string>
<string name="drawer_feed_counter_none">Nenhum</string>
<!--Webview actions-->
<string name="open_in_browser_label">Abrir no navegador</string>
@@ -50,6 +51,7 @@
<string name="cancel_label">Cancelar</string>
<string name="yes">Sim</string>
<string name="no">Não</string>
+ <string name="reset">Repor</string>
<string name="author_label">Autor</string>
<string name="language_label">Idioma</string>
<string name="url_label">URL</string>
@@ -92,7 +94,7 @@
<string name="etxtFeedurlHint">URL da fonte ou do sítio web</string>
<string name="txtvfeedurl_label">Adicionar podcast via URL</string>
<string name="podcastdirectories_label">Localizar podcasts no diretório</string>
- <string name="podcastdirectories_descr">Pode procurar por novos podcasts no gPodder.net e também na loja iTunes. Pode pesquisar por nome, categoria e popularidade.</string>
+ <string name="podcastdirectories_descr">Para novos podcasts, pode pesquisar no iTunes ou no fyyd. Também pode explorar no gpoder.net por nome, categoria ou popularidade.</string>
<string name="browse_gpoddernet_label">Procurar no gPodder.net</string>
<!--Actions on feeds-->
<string name="mark_all_read_label">Marcar tudo como reproduzido</string>
@@ -100,7 +102,10 @@
<string name="mark_all_read_confirmation_msg">Tem a certeza de que deseja marcar todos os episódios como reproduzidos?</string>
<string name="mark_all_read_feed_confirmation_msg">Tem a certeza de que deseja marcar todos os episódios desta fonte como reproduzidos?</string>
<string name="mark_all_seen_label">Marcar tudo como visto</string>
+ <string name="mark_all_seen_msg">Marcar todos os episódios como vistos</string>
+ <string name="mark_all_seen_confirmation_msg">Confirma de que deseja marcar todos os episódios como vistos?</string>
<string name="show_info_label">Mostrar informações</string>
+ <string name="rename_feed_label">Renomear podcast</string>
<string name="remove_feed_label">Remover podcast</string>
<string name="share_label">Partilhar...</string>
<string name="share_link_label">Partilhar ligação</string>
@@ -130,6 +135,7 @@
<string name="stop_label">Parar</string>
<string name="stream_label">Emitir</string>
<string name="remove_label">Remover</string>
+ <string name="delete_label">Apagar</string>
<string name="remove_episode_lable">Remover episódio</string>
<string name="marked_as_seen_label">Marcar como visto</string>
<string name="mark_read_label">Marcar como reproduzido</string>
@@ -276,6 +282,8 @@
<string name="pref_unpauseOnBluetoothReconnect_sum">Continuar reprodução ao estabelecer a ligação bluetooth</string>
<string name="pref_hardwareForwardButtonSkips_title">Botão para avançar</string>
<string name="pref_hardwareForwardButtonSkips_sum">Ao premir o botão Avançar, ir para o episódio seguinte em vez de avançar a reprodução</string>
+ <string name="pref_hardwarePreviousButtonRestarts_title">Botão Anterior para reiniciar</string>
+ <string name="pref_hardwarePreviousButtonRestarts_sum">Ao premir o botão do telefone, reiniciar o episódio atual em vez de recuar para o episódio anterior</string>
<string name="pref_followQueue_sum">Ir para a episódio seguinte ao terminar a reprodução</string>
<string name="pref_auto_delete_sum">Apagar episódio ao terminar a reprodução</string>
<string name="pref_auto_delete_title">Eliminação automática</string>
@@ -342,10 +350,16 @@
<string name="pref_gpodnet_logout_toast">Sessão terminada</string>
<string name="pref_gpodnet_setlogin_information_title">Alterar informação de acesso</string>
<string name="pref_gpodnet_setlogin_information_sum">Alterar a informação de acesso à sua conta gpodder.net</string>
- <string name="pref_gpodnet_sync_title">Sincronizar agora</string>
- <string name="pref_gpodnet_sync_sum">Sincronizar subscrições e estado dos episódios com o gpodder.net</string>
+ <string name="pref_gpodnet_sync_changes_title">Sincronizar alterações</string>
+ <string name="pref_gpodnet_sync_changes_sum">Sincronizar subscrição e estado do episódio com o gpodder.net.</string>
+ <string name="pref_gpodnet_full_sync_title">Sincronização total</string>
+ <string name="pref_gpodnet_full_sync_sum">Sincronizar todas as subscrições e estados dos episódios com o gpodder.net.</string>
+ <string name="pref_gpodnet_sync_sum_last_sync_line">Última tentativa de sincronização: %1$s (%2$s)</string>
<string name="pref_gpodnet_sync_started">Sincronização iniciada</string>
+ <string name="pref_gpodnet_full_sync_started">Sincronização iniciada</string>
<string name="pref_gpodnet_login_status"><![CDATA[Sessão iniciada como <i>%1$s</i> com o dispositivo <i>%2$s</i>]]></string>
+ <string name="pref_gpodnet_notifications_title">Mostrar erros de sincronização</string>
+ <string name="pref_gpodnet_notifications_sum">Esta definição não é aplicável aos erros de autenticação.</string>
<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>
@@ -391,12 +405,13 @@
<string name="auto_flattr_ater_beginning">Flattr de episodios ao iniciar a reprodução</string>
<string name="auto_flattr_ater_end">Flattr de episódios ao terminar a reprodução</string>
<!--Search-->
- <string name="search_hint">Pesquisar fontes ou episódios</string>
+ <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="search_status_no_results">Nenhum resultado</string>
<string name="search_label">Pesquisar</string>
<string name="found_in_title_label">Encontrado no título</string>
+ <string name="no_results_for_query">Não existem resultados para \"%1$s\"</string>
<!--OPML import and export-->
<string name="opml_import_txtv_button_lable">Os ficheiros OPML permitem-lhe mover os podcasts entre aplicações</string>
<string name="opml_import_option">Opção %1$d</string>
@@ -415,6 +430,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="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>
@@ -445,6 +461,9 @@
<item quantity="one">1 hora</item>
<item quantity="other">%d horas</item>
</plurals>
+ <string name="auto_enable_label">Ativar automaticamente</string>
+ <string name="sleep_timer_enabled_label">Temporizador ativado</string>
+ <string name="sleep_timer_disabled_label">Temporizador desativado</string>
<!--gpodder.net-->
<string name="gpodnet_taglist_header">Categorias</string>
<string name="gpodnet_toplist_header">Melhores</string>
@@ -474,6 +493,8 @@
<string name="gpodnetsync_auth_error_descr">Utilizador ou palavra-passe inválida</string>
<string name="gpodnetsync_error_title">Erro de sincronização gpodder.net</string>
<string name="gpodnetsync_error_descr">Ocorreu um erro ao sincronizar:\u0020</string>
+ <string name="gpodnetsync_pref_report_successful">Sucesso</string>
+ <string name="gpodnetsync_pref_report_failed">Falha</string>
<!--Directory chooser-->
<string name="selected_folder_label">Diretório escolhido:</string>
<string name="create_folder_label">Criar pasta</string>
@@ -528,6 +549,7 @@
<string name="sp_apps_importing_feeds_msg">Importar subscrições de aplicações single-purpose...</string>
<string name="search_itunes_label">Pesquisar no iTunes</string>
<string name="filter">Filtro</string>
+ <string name="search_fyyd_label">Pesquisar no fyyd</string>
<!--Episodes apply actions-->
<string name="all_label">Todos</string>
<string name="selected_all_label">Marcar todos os episódios</string>
diff --git a/core/src/main/res/values-ro-rRO/strings.xml b/core/src/main/res/values-ro-rRO/strings.xml
index d5c77eabb..7965920fd 100644
--- a/core/src/main/res/values-ro-rRO/strings.xml
+++ b/core/src/main/res/values-ro-rRO/strings.xml
@@ -164,8 +164,6 @@
<string name="pref_rewind_sum">Personaliza numărul de secunde pentru a sări înapoi atunci când butonul de derulare înapoi se face clic</string>
<!--Auto-Flattr dialog-->
<!--Search-->
- <string name="search_hint">Caută feeduri sau episoade</string>
- <string name="found_in_shownotes_label">Găsit în notițe</string>
<string name="found_in_chapters_label">Găsit în capitole</string>
<string name="search_status_no_results">Nu s-a găsit nici un rezultat</string>
<string name="search_label">Caută</string>
diff --git a/core/src/main/res/values-ru/strings.xml b/core/src/main/res/values-ru/strings.xml
index 15973243e..6c86d1ab5 100644
--- a/core/src/main/res/values-ru/strings.xml
+++ b/core/src/main/res/values-ru/strings.xml
@@ -94,7 +94,6 @@
<string name="etxtFeedurlHint">www.example.com/feed</string>
<string name="txtvfeedurl_label">Добавить подкаст по URL</string>
<string name="podcastdirectories_label">Найти подкаст в каталоге</string>
- <string name="podcastdirectories_descr">Вы можете искать новые подкасты по имени, категории или популярности в каталоге gpodder.net и в магазине iTunes.</string>
<string name="browse_gpoddernet_label">Просмотр gpodder.net</string>
<!--Actions on feeds-->
<string name="mark_all_read_label">Отметить как прослушанное</string>
@@ -133,6 +132,7 @@
<string name="stream_label">Воспроизвести из сети</string>
<string name="remove_label">Удалить</string>
<string name="remove_episode_lable">Удалить выпуск</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>
@@ -222,6 +222,8 @@
<string name="sort">Сортировать</string>
<string name="date">По дате</string>
<string name="duration">По продолжительности</string>
+ <string name="episode_title">Название выпуска</string>
+ <string name="feed_title">Название канала</string>
<string name="ascending">По возрастанию</string>
<string name="descending">По убыванию</string>
<string name="clear_queue_confirmation_msg">Подтвердите, что хотите очистить очередь от ВСЕХ эпизодов.</string>
@@ -343,8 +345,6 @@
<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_title">Синхронизировать</string>
- <string name="pref_gpodnet_sync_sum">Синхронизировать подписки и статус выпусков с сервисом gpodder.net</string>
<string name="pref_gpodnet_sync_started">Синхронизация запущена</string>
<string name="pref_gpodnet_login_status"><![CDATA[Вход как <i>%1$s</i> с устройства <i>%2$s</i>]]></string>
<string name="pref_playback_speed_title">Скорость воспроизведения</string>
@@ -354,8 +354,8 @@
<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_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>
@@ -364,10 +364,10 @@
<string name="pref_lockscreen_background_title">Выбрать фон экрана блокировки</string>
<string name="pref_lockscreen_background_sum">Изменяет фон экрана блокировки на обложку выпуска. Кроме того показывает обложку в сторонних приложениях.</string>
<string name="pref_showDownloadReport_title">Показывать отчёт о загрузках</string>
- <string name="pref_showDownloadReport_sum">Если загрузка не удается, показывать отчет с подробностями об ошибке.</string>
+ <string name="pref_showDownloadReport_sum">Если загрузка не удаётся, показывать отчёт с подробностями об ошибке.</string>
<string name="pref_expand_notify_unsupport_toast">Версии Android ниже 4.1 не поддерживают расширенные уведомления.</string>
- <string name="pref_queueAddToFront_sum">Добавлять новые выпуски в начало очереди.</string>
- <string name="pref_queueAddToFront_title">В начало очереди.</string>
+ <string name="pref_queueAddToFront_sum">Добавлять новые выпуски в начало очереди</string>
+ <string name="pref_queueAddToFront_title">В начало очереди</string>
<string name="pref_smart_mark_as_played_disabled">Отключено</string>
<string name="pref_image_cache_size_title">Размер кэша для изображений</string>
<string name="pref_image_cache_size_sum">Размер дискового кэша для изображений</string>
@@ -386,14 +386,14 @@
<string name="pref_cast_title">Поддержка Chromecast</string>
<string name="pref_rewind_sum">Настроить количество секунд для перехода назад, когда кнопка перемотки нажата</string>
<string name="pref_fast_forward_sum">Настроить количество секунд, чтобы перейти вперед, когда кнопка перемотки вперед нажата</string>
+ <string name="pref_cast_message_play_flavor">Включить поддержку удалённого воспроизведения на устройствах с Google Cast (таких как Chromecast, динамики или ТВ на ОС Android)</string>
+ <string name="pref_cast_message_free_flavor">Для работы Chromecast требуются собственнические библиотеки третьей стороны, которые не включены в данную версию AntennaPod</string>
<!--Auto-Flattr dialog-->
<string name="auto_flattr_enable">Включить автоматическую поддержку через Flattr</string>
<string name="auto_flattr_after_percent">Поддерживать через Flattr эпизоды, прослушанные на %d процентов</string>
<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>
diff --git a/core/src/main/res/values-sv-rSE/strings.xml b/core/src/main/res/values-sv-rSE/strings.xml
index 5461a9a76..c4be14ce8 100644
--- a/core/src/main/res/values-sv-rSE/strings.xml
+++ b/core/src/main/res/values-sv-rSE/strings.xml
@@ -92,7 +92,6 @@
<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">Du kan söka efter podcasts baserat på namn, kategori eller populäritet med tjänsten gpodder.net eller på iTunes Store.</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>
@@ -342,8 +341,6 @@
<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_title">Synkronisera nu</string>
- <string name="pref_gpodnet_sync_sum">Synkronisera prenumerationer och episodtillstånd med gpodder.net</string>
<string name="pref_gpodnet_sync_started">Synkronisering startad</string>
<string name="pref_gpodnet_login_status"><![CDATA[Inloggad som <i>%1$s</i> med enhet <i>%2$s</i>]]></string>
<string name="pref_playback_speed_title">Uppspelningshastigheter</string>
@@ -393,8 +390,6 @@
<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 flöden eller episoder</string>
- <string name="found_in_shownotes_label">Hittad i shownotes</string>
<string name="found_in_chapters_label">Hittad i kapitel</string>
<string name="search_status_no_results">Inga resultat hittades</string>
<string name="search_label">Sök</string>
diff --git a/core/src/main/res/values-te/strings.xml b/core/src/main/res/values-te/strings.xml
new file mode 100644
index 000000000..28dfeb6e8
--- /dev/null
+++ b/core/src/main/res/values-te/strings.xml
@@ -0,0 +1,38 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<resources xmlns:tools="http://schemas.android.com/tools">
+ <!--Activitiy and fragment titles-->
+ <!--Statistics fragment-->
+ <!--Main activity-->
+ <!--Webview actions-->
+ <!--Playback history-->
+ <!--Other-->
+ <!--'Add Feed' Activity labels-->
+ <!--Actions on feeds-->
+ <!--actions on feeditems-->
+ <!--Download messages and labels-->
+ <!--Mediaplayer messages-->
+ <!--Queue operations-->
+ <!--Flattr-->
+ <!--Flattr-->
+ <!--Variable Speed-->
+ <!--Empty list labels-->
+ <!--Preferences-->
+ <!--Auto-Flattr dialog-->
+ <!--Search-->
+ <!--OPML import and export-->
+ <!--Sleep timer-->
+ <!--gpodder.net-->
+ <!--Directory chooser-->
+ <!--Online feed view-->
+ <!--Content descriptions for image buttons-->
+ <!--Feed information screen-->
+ <!--Progress information-->
+ <!--AntennaPodSP-->
+ <!--Episodes apply actions-->
+ <!--Sort-->
+ <!--Rating dialog-->
+ <!--Audio controls-->
+ <!--proxy settings-->
+ <!--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 c82511511..e917df895 100644
--- a/core/src/main/res/values-tr/strings.xml
+++ b/core/src/main/res/values-tr/strings.xml
@@ -2,6 +2,7 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!--Activitiy and fragment titles-->
<string name="feeds_label">Beslemeler</string>
+ <string name="statistics_label">İstatistikler</string>
<string name="add_feed_label">Cep yayını ekle</string>
<string name="episodes_label">Bölümler</string>
<string name="all_episodes_short_label">Tümü</string>
@@ -13,11 +14,15 @@
<string name="downloads_running_label">Çalışıyor</string>
<string name="downloads_completed_label">Tamamlandı</string>
<string name="downloads_log_label">Günlük</string>
+ <string name="subscriptions_label">Abonelikler</string>
+ <string name="subscriptions_list_label">Abonelik Listesi</string>
<string name="cancel_download_label">İndirmeyi İptal Et</string>
<string name="playback_history_label">Çalma geçmişi</string>
<string name="gpodnet_main_label">gpodder.net</string>
<string name="gpodnet_auth_label">gpodder.net giriş</string>
+ <string name="free_space_label">%1$s ücretsiz</string>
<!--Statistics fragment-->
+ <string name="total_time_listened_to_podcasts">Toplam cep yayını çalma zamanı:</string>
<!--Main activity-->
<string name="drawer_open">Münüyü aç</string>
<string name="drawer_close">Menüyü kapat</string>
@@ -59,6 +64,7 @@
<string name="length_prefix">Uzunluk:\u0020</string>
<string name="size_prefix">Boyut:\u0020</string>
<string name="processing_label">İşleniyor</string>
+ <string name="loading_label">Yükleniyor...</string>
<string name="save_username_password_label">Kullanıcı adı ve şifreyi kaydet</string>
<string name="close_label">Kapat</string>
<string name="retry_label">Yeniden dene</string>
@@ -67,6 +73,7 @@
<string name="parallel_downloads_suffix">\u0020paralel indirmeler</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>
<string name="episode_cleanup_never">Hiçbir zaman</string>
<string name="episode_cleanup_queue_removal">Sırada değilse</string>
<string name="episode_cleanup_after_listening">Bittikten sonra</string>
@@ -79,7 +86,6 @@
<string name="etxtFeedurlHint">www.example.com/feed</string>
<string name="txtvfeedurl_label">URL ile cep yayını ekle</string>
<string name="podcastdirectories_label">Dizinde cep yayını bul</string>
- <string name="podcastdirectories_descr">gdpodder.net dizininde yeni cep yayınlarını isme, kategoriye veya popülerliğe göre arayabilirsiniz veya iTunes mağazasında arama yapabilirsiniz.</string>
<string name="browse_gpoddernet_label">gpodder.net\'e gözat</string>
<!--Actions on feeds-->
<string name="mark_all_read_label">Hepsini oynatıldı olarak işaretle</string>
@@ -89,6 +95,7 @@
<string name="mark_all_seen_label">Hepsini görüldü olarak işaretle</string>
<string name="show_info_label">Bilgiyi göster</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>
@@ -121,7 +128,9 @@
<string name="added_to_queue_label">Kuyruğa Eklendi</string>
<string name="remove_from_queue_label">Kuyruktan Kaldır</string>
<string name="add_to_favorite_label">Favorilere Ekle</string>
+ <string name="added_to_favorites">Favorilere Eklendi</string>
<string name="remove_from_favorite_label">Favorilerden Kaldır</string>
+ <string name="removed_from_favorites">Favorilerden Kaldırıldı</string>
<string name="visit_website_label">Siteyi Ziyaret Et</string>
<string name="support_label">Flattr ile destekle</string>
<string name="skip_episode_label">Bölümü atla</string>
@@ -153,6 +162,10 @@
<string name="download_error_io_error">G/Ç Hatası</string>
<string name="download_error_request_error">İstek hatası</string>
<string name="download_error_db_access">Veritabanı erişim hatası</string>
+ <plurals name="downloads_left">
+ <item quantity="one">%d indirme kaldı</item>
+ <item quantity="other">%d indirme kaldı</item>
+ </plurals>
<string name="downloads_processing">İndirmeler işleniyor</string>
<string name="download_notification_title">Cep yayını verileri indiriliyor</string>
<string name="download_report_content">%1$d indirme başarılı, %2$d başarısız</string>
@@ -229,6 +242,8 @@
<string name="no_items_label">Bu listede hiç öge yok.</string>
<string name="no_feeds_label">Henüz hiçbir beslemeye abone değilsiniz.</string>
<!--Preferences-->
+ <string name="storage_pref">Depolama</string>
+ <string name="project_pref">Proje</string>
<string name="other_pref">Diğer</string>
<string name="about_pref">Hakkında</string>
<string name="queue_label">Kuyruk</string>
@@ -319,14 +334,13 @@
<string name="pref_sonic_title">Sonic ortam yürütücüsü</string>
<string name="pref_rewind_sum">Geri sarma düğmesi tıklandığında geriye atlamak için saniye sayısını özelleştirin</string>
<string name="pref_fast_forward_sum">Hızlı ileri sar düğmesi tıklandığında öne atlamak için saniye sayısını özelleştirin</string>
+ <string name="pref_faq">SSS</string>
<!--Auto-Flattr dialog-->
<string name="auto_flattr_enable">Otomatik Flattr\'lamayı etkinleştir</string>
<string name="auto_flattr_after_percent">Bölümün yüzde %d kısmı oynatıldığında Flattr\'la</string>
<string name="auto_flattr_ater_beginning">Oynatma başladığında bölümü Flattr\'la</string>
<string name="auto_flattr_ater_end">Oynatma bittiğinde bölümü Flattr\'la</string>
<!--Search-->
- <string name="search_hint">Besleme veya Bölüm Ara</string>
- <string name="found_in_shownotes_label">Nolarda bulundu</string>
<string name="found_in_chapters_label">Kısımlarda bulundu</string>
<string name="search_status_no_results">Sonuç bulunamadı</string>
<string name="search_label">Ara</string>
@@ -472,6 +486,9 @@
<string name="rating_now_label">Evet, şimdi yapalım!</string>
<!--Audio controls-->
<!--proxy settings-->
+ <string name="proxy_test_label">Test</string>
+ <string name="proxy_test_successful">Test başarılı</string>
+ <string name="proxy_test_failed">Test başarısız</string>
<!--Casting-->
<!--<string name="cast_failed_to_connect">Could not connect to the device</string>-->
</resources>
diff --git a/core/src/main/res/values-uk-rUA/strings.xml b/core/src/main/res/values-uk-rUA/strings.xml
index 255629ffa..6d2393614 100644
--- a/core/src/main/res/values-uk-rUA/strings.xml
+++ b/core/src/main/res/values-uk-rUA/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>
@@ -93,7 +95,7 @@
<string name="etxtFeedurlHint">URL канала або сайта</string>
<string name="txtvfeedurl_label">Додати подкаст за URL</string>
<string name="podcastdirectories_label">Знайти подкаст в каталозі</string>
- <string name="podcastdirectories_descr">В каталозі gpodder.net можливий пошук за назвою, категорією або популярністю.</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>
@@ -101,7 +103,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">Поділитися URL сайту</string>
@@ -121,6 +126,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,7 +137,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="mark_read_label">Позначити як граний</string>
<string name="marked_as_read_label">Позначено як граний</string>
<string name="mark_unread_label">Позначити як не граний</string>
@@ -220,6 +228,8 @@
<string name="sort">Впорядкувати</string>
<string name="date">За датою</string>
<string name="duration">За тривалістю</string>
+ <string name="episode_title">Назва епізода</string>
+ <string name="feed_title">Назва канала</string>
<string name="ascending">За зростанням</string>
<string name="descending">За спаданням</string>
<string name="clear_queue_confirmation_msg">Будь ласка, підтвердіть що ви бажаєте вилучити всі епізоди з черги.</string>
@@ -275,6 +285,8 @@
<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>
@@ -341,10 +353,16 @@
<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_title">Cинхронізувати зараз</string>
- <string name="pref_gpodnet_sync_sum">Cинхронізувати підписки та стан епізодів з сервісом 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">Cинхронізація почалась</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>
@@ -384,18 +402,21 @@
<string name="pref_cast_title">Підтримка для Chromecast</string>
<string name="pref_rewind_sum">Налаштувати кількість секунд для переходу назад, коли кнопка перемотування натиснута</string>
<string name="pref_fast_forward_sum">Налаштувати кількість секунд, щоб перейти вперед, коли кнопка перемотування вперед натиснута</string>
+ <string name="pref_cast_message_play_flavor">Включити підтримку програвання на таких пристроях як Chromecast або Android TV</string>
+ <string name="pref_cast_message_free_flavor">Для підтримки Chromecast потрібні бібліотеки які не включені в цю версію AntennaPod</string>
<!--Auto-Flattr dialog-->
<string name="auto_flattr_enable">Включити автоматичне заохочення авторів через сервіс flattr</string>
<string name="auto_flattr_after_percent">Заохотити автора через Flattr щойно %d відсотків епізода було відтворено</string>
<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="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>
@@ -414,6 +435,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>
@@ -447,6 +469,9 @@
<item quantity="few">%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>
@@ -466,6 +491,7 @@
<string name="gpodnetauth_device_chooseExistingDevice">Вибрати існуючий пристрій</string>
<string name="gpodnetauth_device_errorEmpty">ID пристрою не можете бути пустим</string>
<string name="gpodnetauth_device_errorAlreadyUsed">Таке ID пристрою вже є</string>
+ <string name="gpodnetauth_device_caption_errorEmpty">Підпис не повинен бути пустим</string>
<string name="gpodnetauth_device_butChoose">Обрати</string>
<string name="gpodnetauth_finish_title">Успішно зайшли</string>
<string name="gpodnetauth_finish_descr">Поздоровляємо! Ваш обліковий запис на gpodder.net зараз пов\'язаний за вашим пристроєм</string>
@@ -475,6 +501,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>
@@ -527,6 +555,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>
@@ -544,6 +573,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>
@@ -575,7 +606,23 @@
<string name="proxy_checking">Перевіряється...</string>
<string name="proxy_test_successful">Протестовано успішно</string>
<string name="proxy_test_failed">Протестовано з помилками</string>
+ <string name="proxy_host_empty_error">Хост не може бути пустим</string>
+ <string name="proxy_host_invalid_error">Хост не є правильною IP-адресою або доменним ім’ям</string>
<string name="proxy_port_invalid_error">Неправильний порт</string>
<!--Casting-->
+ <string name="cast_media_route_menu_title">Грати на…</string>
+ <string name="cast_disconnect_label">Від’єднатись від пристроя програвання</string>
+ <string name="cast_not_castable">Обраний файл не сумісний з пристроєм програвання</string>
+ <string name="cast_failed_to_play">Помилка програвання файла</string>
+ <string name="cast_failed_to_stop">Помилка спроби зупинки програвання</string>
+ <string name="cast_failed_to_pause">Помилка спроби призупинення програвання</string>
<!--<string name="cast_failed_to_connect">Could not connect to the device</string>-->
+ <string name="cast_failed_setting_volume">Помилка встановлення гучності</string>
+ <string name="cast_failed_no_connection">Немає з’єднання з пристроєм програвання</string>
+ <string name="cast_failed_no_connection_trans">Зв’язок з пристроєм програвання втрачено. Програма намагається поновити зв’язок, якщо це можливо. Будь ласка зачекайте кілька секунд і спробуйте знов.</string>
+ <string name="cast_failed_perform_action">Помилка виконання дії</string>
+ <string name="cast_failed_status_request">Помилка синхронизації з пристроєм програвання</string>
+ <string name="cast_failed_seek">Помилка перехода на нову позицію програвання на пристрої.</string>
+ <string name="cast_failed_receiver_player_error">Серйозна помилка програвання на пристрої</string>
+ <string name="cast_failed_media_error_skipping">Помилка програвання файла. Пропускаю...</string>
</resources>
diff --git a/core/src/main/res/values-zh-rCN/strings.xml b/core/src/main/res/values-zh-rCN/strings.xml
index e08bb5991..6011235c1 100644
--- a/core/src/main/res/values-zh-rCN/strings.xml
+++ b/core/src/main/res/values-zh-rCN/strings.xml
@@ -2,6 +2,7 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!--Activitiy and fragment titles-->
<string name="feeds_label">订阅</string>
+ <string name="statistics_label">统计</string>
<string name="add_feed_label">添加播客</string>
<string name="episodes_label">曲目</string>
<string name="all_episodes_short_label">全部</string>
@@ -13,14 +14,18 @@
<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="cancel_download_label">取消下载</string>
<string name="playback_history_label">播放历史</string>
<string name="gpodnet_main_label">gpodder.net</string>
<string name="gpodnet_auth_label">gpodder.net 登录</string>
+ <string name="free_space_label">%1$s可用</string>
<string name="episode_cache_full_title">曲目缓存已满</string>
<string name="episode_cache_full_message">已达到曲目缓存限制,可以在设置中提高缓存大小。</string>
<!--Statistics fragment-->
<string name="total_time_listened_to_podcasts">总播放时长:</string>
+ <string name="statistics_details_dialog">%1$d out of %2$d episodes started.\n\nPlayed %3$s out of %4$s.</string>
<!--Main activity-->
<string name="drawer_open">打开菜单</string>
<string name="drawer_close">关闭菜单</string>
@@ -68,7 +73,9 @@
<string name="retry_label">重试</string>
<string name="auto_download_label">包含到自动下载</string>
<string name="auto_download_apply_to_items_title"> 应用到之前的曲目中</string>
+ <string name="auto_delete_label">自动删除剧集</string>
<string name="parallel_downloads_suffix">\u0020 并行下载</string>
+ <string name="feed_auto_download_global">全局默认</string>
<string name="feed_auto_download_always"> 总是</string>
<string name="feed_auto_download_never">从不</string>
<string name="send_label">发送</string>
@@ -83,7 +90,6 @@
<string name="etxtFeedurlHint">www.example.com/feed</string>
<string name="txtvfeedurl_label">添加播客 URL</string>
<string name="podcastdirectories_label">从目录中寻找播客</string>
- <string name="podcastdirectories_descr">您可以在 gpodder.net 通过名称、类别或热门来搜索新播客</string>
<string name="browse_gpoddernet_label">浏览 gpodder.net</string>
<!--Actions on feeds-->
<string name="mark_all_read_label">全部标识已读</string>
@@ -97,6 +103,8 @@
<string name="share_link_label">分享网站链接</string>
<string name="share_link_with_position_label">分享网站链接与位置</string>
<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>
@@ -111,7 +119,7 @@
<string name="hide_not_downloaded_episodes_label">未下载</string>
<string name="filtered_label">已过滤的</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} 上次刷新失败</string>
- <string name="open_podcast">打开博客</string>
+ <string name="open_podcast">打开播客</string>
<!--actions on feeditems-->
<string name="download_label">下载</string>
<string name="play_label">播放</string>
@@ -120,6 +128,7 @@
<string name="stream_label">流媒体</string>
<string name="remove_label">删除</string>
<string name="remove_episode_lable">移除曲目</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>
@@ -153,6 +162,7 @@
<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_forbidden">禁用的</string>
<string name="cancel_all_downloads_label">取消所有下载</string>
<string name="download_canceled_msg">已取消下载</string>
<string name="download_canceled_autodownload_enabled_msg">已取消下载\n对该曲目禁用<i>自动下载</i></string>
@@ -176,6 +186,7 @@
<string name="authentication_notification_title">需要认证</string>
<string name="authentication_notification_msg">您所请求的资源需要用户名和密码</string>
<string name="confirm_mobile_download_dialog_title">确认手机下载</string>
+ <string name="confirm_mobile_download_dialog_only_add_to_queue">队列</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">暂时允许</string>
<!--Mediaplayer messages-->
<string name="player_error_msg">错误!</string>
@@ -202,6 +213,8 @@
<string name="sort">排序</string>
<string name="date">按日期</string>
<string name="duration">按时长</string>
+ <string name="episode_title">剧集标题</string>
+ <string name="feed_title">订阅标题</string>
<string name="ascending">升序</string>
<string name="descending">降序</string>
<string name="clear_queue_confirmation_msg">请确认您要清除队列中的全部曲目</string>
@@ -235,11 +248,15 @@
<string name="download_plugin_label">插件下载</string>
<string name="no_playback_plugin_title">插件没有安装</string>
<string name="set_playback_speed_label">播放速度</string>
+ <string name="enable_sonic">允许声音</string>
<!--Empty list labels-->
<string name="no_items_label">列表为空.</string>
<string name="no_feeds_label">还没有任何订阅.</string>
<string name="no_chapters_label">此曲目没有章节信息</string>
+ <string name="no_shownotes_label">本集不包含展示信息</string>
<!--Preferences-->
+ <string name="storage_pref">存储</string>
+ <string name="project_pref">项目</string>
<string name="other_pref">其他</string>
<string name="about_pref">关于</string>
<string name="queue_label">播放列表</string>
@@ -313,7 +330,6 @@
<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_title">正在同步</string>
<string name="pref_gpodnet_sync_started">已开始同步</string>
<string name="pref_playback_speed_title">播放速度</string>
<string name="pref_playback_speed_sum">自定义音频播放速度</string>
@@ -324,6 +340,9 @@
<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_dialog_title">选择%1$d中的最大值</string>
+ <string name="pref_compact_notification_buttons_dialog_error">你只能选择%1$d中的最大值</string>
<string name="pref_lockscreen_background_title">设置锁屏背景</string>
<string name="pref_showDownloadReport_title">显示下载报告</string>
<string name="pref_showDownloadReport_sum">如果下载失败,生成一份显示详细失败信息的报告。</string>
@@ -337,19 +356,21 @@
<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>
+ <string name="pref_faq">FAQ</string>
<string name="pref_known_issues">已知问题</string>
<string name="pref_rewind_sum">自定义的秒数向后跳转点击快退按钮时</string>
<string name="pref_fast_forward_sum">自定义的秒数向前跳单击快进按钮时</string>
+ <string name="pref_no_browser_found">无网络浏览器</string>
+ <string name="pref_cast_title">Chromecast 支持</string>
<!--Auto-Flattr dialog-->
<string name="auto_flattr_enable">启用自动 flattring</string>
<string name="auto_flattr_after_percent">当播放到百分之%d时Flattr改曲目</string>
<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>
@@ -376,6 +397,7 @@
<string name="export_error_label">导出出错</string>
<string name="opml_export_success_title">OPML 导出成功.</string>
<string name="opml_export_success_sum">.opml 文件已保存到:\u0020</string>
+ <string name="opml_import_ask_read_permission">访问外部存储需要读取OPML文件</string>
<!--Sleep timer-->
<string name="set_sleeptimer_label">设置休眠计时器</string>
<string name="disable_sleeptimer_label">禁用休眠计时器</string>
@@ -430,6 +452,7 @@
<string name="selected_folder_label">已选文件夹:</string>
<string name="create_folder_label">穿件文件夹</string>
<string name="choose_data_directory">选择数据文件夹</string>
+ <string name="choose_data_directory_permission_rationale">访问外部存储需要</string>
<string name="create_folder_msg">确实创建 \"%1$s\" 文件夹?</string>
<string name="create_folder_success">创建新文件夹</string>
<string name="create_folder_error_no_write_access">本文件夹不能写入</string>
@@ -500,6 +523,7 @@
<string name="sort_duration_long_short">时长 (长 \u2192 短)</string>
<!--Rating dialog-->
<string name="rating_title">喜欢 AntennaPod?</string>
+ <string name="rating_message">如您能在百忙之外抽时间评价一下AntennaPod,我们感激不尽.</string>
<string name="rating_never_label">请勿打扰</string>
<string name="rating_later_label">稍后提醒</string>
<string name="rating_now_label">好的, 就这样!</string>
@@ -510,6 +534,7 @@
<string name="left_short">L</string>
<string name="right_short">R</string>
<string name="audio_effects">音频效果</string>
+ <string name="sonic_only">仅声音</string>
<!--proxy settings-->
<string name="proxy_type_label">类型</string>
<string name="host_label">主机地址</string>
@@ -519,7 +544,11 @@
<string name="proxy_checking">正在测试</string>
<string name="proxy_test_successful">测试成功</string>
<string name="proxy_test_failed">测试失败</string>
+ <string name="proxy_host_empty_error">主机地址不能为空</string>
+ <string name="proxy_host_invalid_error">主机地址为无效的IP地址或域名</string>
<string name="proxy_port_invalid_error">端口不可用</string>
<!--Casting-->
<!--<string name="cast_failed_to_connect">Could not connect to the device</string>-->
+ <string name="cast_failed_setting_volume">音量设置失败</string>
+ <string name="cast_failed_media_error_skipping">媒体播放出错.跳转中...</string>
</resources>
diff --git a/core/src/main/res/values-zh-rTW/strings.xml b/core/src/main/res/values-zh-rTW/strings.xml
new file mode 100644
index 000000000..28dfeb6e8
--- /dev/null
+++ b/core/src/main/res/values-zh-rTW/strings.xml
@@ -0,0 +1,38 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<resources xmlns:tools="http://schemas.android.com/tools">
+ <!--Activitiy and fragment titles-->
+ <!--Statistics fragment-->
+ <!--Main activity-->
+ <!--Webview actions-->
+ <!--Playback history-->
+ <!--Other-->
+ <!--'Add Feed' Activity labels-->
+ <!--Actions on feeds-->
+ <!--actions on feeditems-->
+ <!--Download messages and labels-->
+ <!--Mediaplayer messages-->
+ <!--Queue operations-->
+ <!--Flattr-->
+ <!--Flattr-->
+ <!--Variable Speed-->
+ <!--Empty list labels-->
+ <!--Preferences-->
+ <!--Auto-Flattr dialog-->
+ <!--Search-->
+ <!--OPML import and export-->
+ <!--Sleep timer-->
+ <!--gpodder.net-->
+ <!--Directory chooser-->
+ <!--Online feed view-->
+ <!--Content descriptions for image buttons-->
+ <!--Feed information screen-->
+ <!--Progress information-->
+ <!--AntennaPodSP-->
+ <!--Episodes apply actions-->
+ <!--Sort-->
+ <!--Rating dialog-->
+ <!--Audio controls-->
+ <!--proxy settings-->
+ <!--Casting-->
+ <!--<string name="cast_failed_to_connect">Could not connect to the device</string>-->
+</resources>
diff --git a/core/src/main/res/values/arrays.xml b/core/src/main/res/values/arrays.xml
index fba22b985..133a3ed6e 100644
--- a/core/src/main/res/values/arrays.xml
+++ b/core/src/main/res/values/arrays.xml
@@ -168,12 +168,14 @@
<item>@string/drawer_feed_counter_new_unplayed</item>
<item>@string/drawer_feed_counter_new</item>
<item>@string/drawer_feed_counter_unplayed</item>
+ <item>@string/drawer_feed_counter_downloaded</item>
<item>@string/drawer_feed_counter_none</item>
</string-array>
<string-array name="nav_drawer_feed_counter_values">
<item>0</item>
<item>1</item>
<item>2</item>
+ <item>4</item>
<item>3</item>
</string-array>
@@ -185,6 +187,7 @@
<item>@string/hide_not_queued_episodes_label</item>
<item>@string/hide_downloaded_episodes_label</item>
<item>@string/hide_not_downloaded_episodes_label</item>
+ <item>@string/hide_has_media_label</item>
</string-array>
<string-array name="episode_filter_values">
@@ -195,6 +198,7 @@
<item>not_queued</item>
<item>downloaded</item>
<item>not_downloaded</item>
+ <item>has_media</item>
</string-array>
<string-array name="image_cache_size_options">
diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml
index 3a0b1277d..8b508e9eb 100644
--- a/core/src/main/res/values/strings.xml
+++ b/core/src/main/res/values/strings.xml
@@ -42,6 +42,7 @@
<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>
+ <string name="drawer_feed_counter_downloaded">Number of downloaded episodes</string>
<string name="drawer_feed_counter_none">None</string>
<!-- Webview actions -->
@@ -59,6 +60,7 @@
<string name="cancel_label">Cancel</string>
<string name="yes">Yes</string>
<string name="no">No</string>
+ <string name="reset">Reset</string>
<string name="author_label">Author</string>
<string name="language_label">Language</string>
<string name="url_label">URL</string>
@@ -102,7 +104,7 @@
<string name="etxtFeedurlHint">www.example.com/feed</string>
<string name="txtvfeedurl_label">Add Podcast by URL</string>
<string name="podcastdirectories_label">Find Podcast in Directory</string>
- <string name="podcastdirectories_descr">You can search for new podcasts by name, category or popularity in the gpodder.net directory, or search the iTunes store.</string>
+ <string name="podcastdirectories_descr">For new podcasts, you can search iTunes or fyyd, or browse gpodder.net by name, category or popularity.</string>
<string name="browse_gpoddernet_label">Browse gpodder.net</string>
<!-- Actions on feeds -->
@@ -111,7 +113,10 @@
<string name="mark_all_read_confirmation_msg">Please confirm that you want to mark all episodes as being played.</string>
<string name="mark_all_read_feed_confirmation_msg">Please confirm that you want to mark all episodes in this feed as being played.</string>
<string name="mark_all_seen_label">Mark all as seen</string>
+ <string name="mark_all_seen_msg">Marked all Episodes as seen</string>
+ <string name="mark_all_seen_confirmation_msg">Please confirm that you want to mark all episodes as seen.</string>
<string name="show_info_label">Show information</string>
+ <string name="rename_feed_label">Rename Podcast</string>
<string name="remove_feed_label">Remove Podcast</string>
<string name="share_label">Share&#8230;</string>
<string name="share_link_label">Share Link</string>
@@ -131,6 +136,7 @@
<string name="hide_not_queued_episodes_label">Not queued</string>
<string name="hide_downloaded_episodes_label">Downloaded</string>
<string name="hide_not_downloaded_episodes_label">Not downloaded</string>
+ <string name="hide_has_media_label">Has media</string>
<string name="filtered_label">Filtered</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Last Refresh failed</string>
<string name="open_podcast">Open Podcast</string>
@@ -298,6 +304,8 @@
<string name="pref_unpauseOnBluetoothReconnect_sum">Resume playback when bluetooth reconnects</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>
<string name="pref_followQueue_sum">Jump to next queue item when playback completes</string>
<string name="pref_auto_delete_sum">Delete episode when playback completes</string>
<string name="pref_auto_delete_title">Auto Delete</string>
@@ -364,10 +372,13 @@
<string name="pref_gpodnet_logout_toast">Logout was successful</string>
<string name="pref_gpodnet_setlogin_information_title">Change login information</string>
<string name="pref_gpodnet_setlogin_information_sum">Change the login information for your gpodder.net account.</string>
- <string name="pref_gpodnet_sync_title">Sync now</string>
- <string name="pref_gpodnet_sync_sum">Sync subscriptions and episode states with gpodder.net.</string>
+ <string name="pref_gpodnet_sync_changes_title">Sync changes now</string>
+ <string name="pref_gpodnet_sync_changes_sum">Sync subscription and episode state changes with gpodder.net.</string>
+ <string name="pref_gpodnet_full_sync_title">Full sync now</string>
+ <string name="pref_gpodnet_full_sync_sum">Sync all subscriptions and episode states with gpodder.net.</string>
<string name="pref_gpodnet_sync_sum_last_sync_line">Last sync attempt: %1$s (%2$s)</string>
<string name="pref_gpodnet_sync_started">Sync started</string>
+ <string name="pref_gpodnet_full_sync_started">Full sync started</string>
<string name="pref_gpodnet_login_status"><![CDATA[Logged in as <i>%1$s</i> with device <i>%2$s</i>]]></string>
<string name="pref_gpodnet_notifications_title">Show sync error notifications</string>
<string name="pref_gpodnet_notifications_sum">This setting does not apply to authentication errors.</string>
@@ -412,6 +423,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 Dowloaded</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>
@@ -445,6 +458,7 @@
<string name="choose_file_from_filesystem">From local filesystem</string>
<string name="choose_file_from_external_application">Use external application</string>
<string name="opml_export_label">OPML export</string>
+ <string name="html_export_label">HTML export</string>
<string name="exporting_label">Exporting&#8230;</string>
<string name="export_error_label">Export error</string>
<string name="opml_export_success_title">OPML Export successful.</string>
@@ -476,6 +490,9 @@
<item quantity="one">1 hour</item>
<item quantity="other">%d hours</item>
</plurals>
+ <string name="auto_enable_label">Auto-enable</string>
+ <string name="sleep_timer_enabled_label">Sleep timer enabled</string>
+ <string name="sleep_timer_disabled_label">Sleep timer disabled</string>
<!-- gpodder.net -->
<string name="gpodnet_taglist_header">CATEGORIES</string>
@@ -569,6 +586,8 @@
<string name="search_itunes_label">Search iTunes</string>
<string name="filter">Filter</string>
+
+ <string name="search_fyyd_label">Search fyyd</string>
<!-- Episodes apply actions -->
<string name="all_label">All</string>
@@ -587,6 +606,8 @@
<string name="selected_queued_label">Selected queued Episodes</string>
<string name="not_queued_label">Not queued</string>
<string name="selected_not_queued_label">Selected not queued Episodes</string>
+ <string name="has_media">Has media</string>
+ <string name="selected_has_media_label">Selected episodes with media</string>
<!-- Sort -->
<string name="sort_title_a_z">Title (A \u2192 Z)</string>
diff --git a/core/src/main/res/values/styles.xml b/core/src/main/res/values/styles.xml
index 6a4dc4781..4f228f8f1 100644
--- a/core/src/main/res/values/styles.xml
+++ b/core/src/main/res/values/styles.xml
@@ -239,6 +239,10 @@
<item name="attr/ic_cast_disconnect">@drawable/ic_cast_disconnect_white_36dp</item>
</style>
+ <style name="Theme.AntennaPod.Dark.Splash" parent="Theme.AppCompat.NoActionBar">
+ <item name="android:windowBackground">@drawable/bg_splash</item>
+ </style>
+
<style name="Theme.AntennaPod.VideoPlayer" parent="@style/Theme.AntennaPod.Dark">
<item name="windowActionBarOverlay">true</item>
</style>
@@ -285,6 +289,16 @@
<item name="textAllCaps">false</item>
</style>
+ <style name="Divider">
+ <item name="android:layout_width">match_parent</item>
+ <item name="android:layout_height">1dp</item>
+ <item name="android:layout_marginTop">8dp</item>
+ <item name="android:layout_marginLeft">16dp</item>
+ <item name="android:layout_marginRight">16dp</item>
+ <item name="android:layout_marginBottom">8dp</item>
+ <item name="android:background">?android:attr/listDivider</item>
+ </style>
+
<style name="AntennaPod.Dialog.Light" parent="Theme.AppCompat.Light.Dialog">
<item name="colorAccent">@color/holo_blue_light</item>
</style>
diff --git a/core/src/play/java/de/danoeh/antennapod/core/ClientConfig.java b/core/src/play/java/de/danoeh/antennapod/core/ClientConfig.java
index 3dfd6ea65..f12f1d806 100644
--- a/core/src/play/java/de/danoeh/antennapod/core/ClientConfig.java
+++ b/core/src/play/java/de/danoeh/antennapod/core/ClientConfig.java
@@ -4,6 +4,7 @@ import android.content.Context;
import de.danoeh.antennapod.core.cast.CastManager;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
+import de.danoeh.antennapod.core.preferences.SleepTimerPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.danoeh.antennapod.core.util.NetworkUtils;
@@ -45,6 +46,7 @@ public class ClientConfig {
PlaybackPreferences.init(context);
NetworkUtils.init(context);
CastManager.init(context);
+ SleepTimerPreferences.init(context);
initialized = true;
}
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 c7428947b..0f493e63e 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
@@ -131,7 +131,8 @@ public class PlaybackServiceFlavorHelper {
info = mediaPlayer.getPSMPInfo();
}
if (info == null) {
- info = new PlaybackServiceMediaPlayer.PSMPInfo(PlayerStatus.STOPPED, null);
+ info = new PlaybackServiceMediaPlayer.PSMPInfo(PlayerStatus.INDETERMINATE,
+ PlayerStatus.STOPPED, null);
}
switchMediaPlayer(new LocalPSMP(context, callback.getMediaPlayerCallback()),
info, true);
@@ -166,7 +167,7 @@ public class PlaybackServiceFlavorHelper {
}
}
if (info == null) {
- info = new PlaybackServiceMediaPlayer.PSMPInfo(PlayerStatus.STOPPED, null);
+ info = new PlaybackServiceMediaPlayer.PSMPInfo(PlayerStatus.INDETERMINATE, PlayerStatus.STOPPED, null);
}
callback.sendNotificationBroadcast(PlaybackService.NOTIFICATION_TYPE_RELOAD,
PlaybackService.EXTRA_CODE_CAST);
diff --git a/core/src/play/java/de/danoeh/antennapod/core/service/playback/RemotePSMP.java b/core/src/play/java/de/danoeh/antennapod/core/service/playback/RemotePSMP.java
index ea95ea894..79e058d0c 100644
--- a/core/src/play/java/de/danoeh/antennapod/core/service/playback/RemotePSMP.java
+++ b/core/src/play/java/de/danoeh/antennapod/core/service/playback/RemotePSMP.java
@@ -123,7 +123,8 @@ public class RemotePSMP extends PlaybackServiceMediaPlayer {
}
if (playbackEnded) {
// This is an unconventional thing to occur...
- endPlayback(true, true, true);
+ Log.w(TAG, "Somehow, Chromecast went from playing directly to standby mode");
+ endPlayback(false, false, true, true);
}
}
@@ -239,7 +240,7 @@ public class RemotePSMP extends PlaybackServiceMediaPlayer {
if (position >= 0) {
oldMedia.setPosition(position);
}
- callback.onPostPlayback(oldMedia, false, false);
+ callback.onPostPlayback(oldMedia, false, false, false);
}
// onPlaybackEnded pretty much takes care of updating the UI
return;
@@ -261,13 +262,13 @@ public class RemotePSMP extends PlaybackServiceMediaPlayer {
if (mediaChanged && currentMedia != null) {
media = currentMedia;
}
- endPlayback(false, true, true);
+ endPlayback(true, false, true, true);
return;
case MediaStatus.IDLE_REASON_ERROR:
Log.w(TAG, "Got an error status from the Chromecast. Skipping, if possible, to the next episode...");
callback.onMediaPlayerInfo(CAST_ERROR_PRIORITY_HIGH,
R.string.cast_failed_media_error_skipping);
- endPlayback(true, true, true);
+ endPlayback(false, false, true, true);
return;
}
break;
@@ -282,7 +283,7 @@ public class RemotePSMP extends PlaybackServiceMediaPlayer {
if (mediaChanged) {
callback.onMediaChanged(true);
if (oldMedia != null) {
- callback.onPostPlayback(oldMedia, false, currentMedia != null);
+ callback.onPostPlayback(oldMedia, false, false, currentMedia != null);
}
}
}
@@ -334,7 +335,7 @@ public class RemotePSMP extends PlaybackServiceMediaPlayer {
}
if (!media.getIdentifier().equals(playable.getIdentifier())) {
final Playable oldMedia = media;
- callback.onPostPlayback(oldMedia, false, true);
+ callback.onPostPlayback(oldMedia, false, false, true);
}
setPlayerStatus(PlayerStatus.INDETERMINATE, null);
@@ -599,7 +600,8 @@ public class RemotePSMP extends PlaybackServiceMediaPlayer {
}
@Override
- protected Future<?> endPlayback(boolean wasSkipped, boolean shouldContinue, boolean toStoppedState) {
+ protected Future<?> endPlayback(boolean hasEnded, boolean wasSkipped, boolean shouldContinue,
+ boolean toStoppedState) {
Log.d(TAG, "endPlayback() called");
boolean isPlaying = playerStatus == PlayerStatus.PLAYING;
if (playerStatus != PlayerStatus.INDETERMINATE) {
@@ -647,7 +649,7 @@ public class RemotePSMP extends PlaybackServiceMediaPlayer {
}
if (shouldPostProcess) {
// Otherwise we rely on the chromecast callback to tell us the playback has stopped.
- callback.onPostPlayback(currentMedia, !wasSkipped, nextMedia != null);
+ callback.onPostPlayback(currentMedia, hasEnded, wasSkipped, nextMedia != null);
}
} else if (isPlaying) {
callback.onPlaybackPause(currentMedia,
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 3baa851b2..51288f9c2 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 513d88f91..708d4146c 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Thu Aug 04 19:57:05 CEST 2016
+#Sun Apr 09 19:45:51 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-bin.zip
diff --git a/gradlew b/gradlew
index 27309d923..4453ccea3 100755
--- a/gradlew
+++ b/gradlew
@@ -1,4 +1,4 @@
-#!/usr/bin/env bash
+#!/usr/bin/env sh
##############################################################################
##
@@ -154,11 +154,19 @@ if $cygwin ; then
esac
fi
-# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
-function splitJvmOpts() {
- JVM_OPTS=("$@")
+# Escape application args
+save ( ) {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
}
-eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
-JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+APP_ARGS=$(save "$@")
-exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
index f6d5974e7..e95643d6a 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -49,7 +49,6 @@ goto fail
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
-if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
@@ -60,11 +59,6 @@ set _SKIP=2
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
-goto execute
-
-:4NT_args
-@rem Get arguments from the 4NT Shell from JP Software
-set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line