diff options
540 files changed, 9697 insertions, 8364 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml index bec559ed2..6bac87a46 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -21,7 +21,10 @@ jobs: - v1-android- - run: - command: ./gradlew assembleDebug :core:testPlayDebugUnitTest -PdisablePreDex + # To build release, we need to create a temporary keystore that can be used to sign the app + command: | + keytool -noprompt -genkey -v -keystore "app/keystore" -alias alias -storepass password -keypass password -keyalg RSA -validity 10 -dname "CN=antennapod.org, OU=dummy, O=dummy, L=dummy, S=dummy, C=US" + ./gradlew assemblePlayRelease :core:testPlayReleaseUnitTest -PdisablePreDex no_output_timeout: 1800 - store_artifacts: diff --git a/.classpath b/.classpath deleted file mode 100644 index 3a0c88fe4..000000000 --- a/.classpath +++ /dev/null @@ -1,9 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<classpath> - <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/> - <classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/> - <classpathentry kind="src" path="src"/> - <classpathentry kind="src" path="gen"/> - <classpathentry kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/> - <classpathentry kind="output" path="bin/classes"/> -</classpath> diff --git a/.project b/.project deleted file mode 100644 index b3b010772..000000000 --- a/.project +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<projectDescription> - <name>AntennaPod</name> - <comment></comment> - <projects> - </projects> - <buildSpec> - <buildCommand> - <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name> - <arguments> - </arguments> - </buildCommand> - <buildCommand> - <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name> - <arguments> - </arguments> - </buildCommand> - <buildCommand> - <name>org.eclipse.jdt.core.javabuilder</name> - <arguments> - </arguments> - </buildCommand> - <buildCommand> - <name>com.android.ide.eclipse.adt.ApkBuilder</name> - <arguments> - </arguments> - </buildCommand> - </buildSpec> - <natures> - <nature>com.android.ide.eclipse.adt.AndroidNature</nature> - <nature>org.eclipse.jdt.core.javanature</nature> - </natures> -</projectDescription> diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 6677e0cd1..000000000 --- a/.travis.yml +++ /dev/null @@ -1,17 +0,0 @@ -language: android -jdk: oraclejdk7 - -env: - matrix: - - ANDROID_SDKS=android-19,sysimg-19 ANDROID_TARGET=android-19 ANDROID_ABI=armeabi-v7a -before_install: - - echo no | android create avd --force -n test -t $ANDROID_TARGET --abi $ANDROID_ABI - - emulator -avd test -no-skin -no-audio -no-window & - - cp src/de/danoeh/antennapod/util/flattr/FlattrConfig.java.example src/de/danoeh/antennapod/util/flattr/FlattrConfig.java - -before_script: - - chmod -R 777 ./ci/wait_for_emulator.sh - - ./ci/wait_for_emulator.sh - -script: - - gradle connectedAndroidTest diff --git a/.tx/config b/.tx/config index 0659eaff4..922e5c070 100644 --- a/.tx/config +++ b/.tx/config @@ -1,7 +1,7 @@ [main] host = https://www.transifex.com -[antennapod.english] +[antennapod.core-values] source_file = core/src/main/res/values/strings.xml source_lang = en trans.ast_ES = core/src/main/res/values-b+ast/strings.xml @@ -25,14 +25,14 @@ trans.he_IL = core/src/main/res/values-iw-rIL/strings.xml trans.hi_IN = core/src/main/res/values-hi-rIN/strings.xml trans.hu = core/src/main/res/values-hu/strings.xml trans.id = core/src/main/res/values-id/strings.xml -trans.it = core/src/main/res/values-it/strings.xml -trans.it_IT = core/src/main/res/values-it-rIT/strings.xml +trans.it_IT = core/src/main/res/values-it/strings.xml trans.is = core/src/main/res/values-is-rIS/strings.xml 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.mk = core/src/main/res/values-mk/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 @@ -58,16 +58,75 @@ trans.zh_TW = core/src/main/res/values-zh-rTW/strings.xml trans.zh_HK = core/src/main/res/values-zh-rHK/strings.xml [antennapod.description] -file_filter = app/src/main/play/<lang>/listing/fulldescription source_file = app/src/main/play/en-US/listing/fulldescription source_lang = en +trans.ar = app/src/main/play/ar/listing/fulldescription +trans.az = app/src/main/play/az-AZ/listing/fulldescription +trans.bg = app/src/main/play/bg/listing/fulldescription +trans.ca = app/src/main/play/ca/listing/fulldescription +trans.cs = app/src/main/play/cs-CZ/listing/fulldescription +trans.da = app/src/main/play/da-DK/listing/fulldescription +trans.de = app/src/main/play/de-DE/listing/fulldescription +trans.el = app/src/main/play/el-GR/listing/fulldescription +trans.es = app/src/main/play/es-ES/listing/fulldescription +trans.et = app/src/main/play/et/listing/fulldescription +trans.fa = app/src/main/play/fa/listing/fulldescription +trans.fr = app/src/main/play/fr-FR/listing/fulldescription +trans.gl = app/src/main/play/gl-ES/listing/fulldescription +trans.hi_IN = app/src/main/play/hi-IN/listing/fulldescription +trans.hu = app/src/main/play/hu-HU/listing/fulldescription +trans.it_IT = app/src/main/play/it-IT/listing/fulldescription +trans.iw = app/src/main/play/iw-IL/listing/fulldescription +trans.ja = app/src/main/play/ja-JP/listing/fulldescription +trans.ko = app/src/main/play/ko-KR/listing/fulldescription +trans.lt = app/src/main/play/lt/listing/fulldescription +trans.nl = app/src/main/play/nl-NL/listing/fulldescription +trans.pl_PL = app/src/main/play/pl-PL/listing/fulldescription +trans.pt_BR = app/src/main/play/pt-BR/listing/fulldescription +trans.pt_PT = app/src/main/play/pt-PT/listing/fulldescription +trans.ro_RO = app/src/main/play/ro/listing/fulldescription +trans.ru_RU = app/src/main/play/ru-RU/listing/fulldescription +trans.sl_SI = app/src/main/play/sl/listing/fulldescription +trans.sv_SE = app/src/main/play/sv-SE/listing/fulldescription +trans.tr = app/src/main/play/tr-TR/listing/fulldescription +trans.uk_UA = app/src/main/play/uk/listing/fulldescription +trans.vi = app/src/main/play/vi/listing/fulldescription +trans.zh_CN = app/src/main/play/zh-CN/listing/fulldescription +trans.zh_TW = app/src/main/play/zh-TW/listing/fulldescription [antennapod.shortdescription] -file_filter = app/src/main/play/<lang>/listing/shortdescription source_file = app/src/main/play/en-US/listing/shortdescription source_lang = en - -[antennapod.changelog] -file_filter = app/src/main/play/<lang>/whatsnew -source_file = app/src/main/play/en-US/whatsnew -source_lang = en +trans.ar = app/src/main/play/ar/listing/shortdescription +trans.az = app/src/main/play/az-AZ/listing/shortdescription +trans.bg = app/src/main/play/bg/listing/shortdescription +trans.ca = app/src/main/play/ca/listing/shortdescription +trans.cs = app/src/main/play/cs-CZ/listing/shortdescription +trans.da = app/src/main/play/da-DK/listing/shortdescription +trans.de = app/src/main/play/de-DE/listing/shortdescription +trans.el = app/src/main/play/el-GR/listing/shortdescription +trans.es = app/src/main/play/es-ES/listing/shortdescription +trans.et = app/src/main/play/et/listing/shortdescription +trans.fa = app/src/main/play/fa/listing/shortdescription +trans.fr = app/src/main/play/fr-FR/listing/shortdescription +trans.gl = app/src/main/play/gl-ES/listing/shortdescription +trans.hi_IN = app/src/main/play/hi-IN/listing/shortdescription +trans.hu = app/src/main/play/hu-HU/listing/shortdescription +trans.it_IT = app/src/main/play/it-IT/listing/shortdescription +trans.iw = app/src/main/play/iw-IL/listing/shortdescription +trans.ja = app/src/main/play/ja-JP/listing/shortdescription +trans.ko = app/src/main/play/ko-KR/listing/shortdescription +trans.lt = app/src/main/play/lt/listing/shortdescription +trans.nl = app/src/main/play/nl-NL/listing/shortdescription +trans.pl_PL = app/src/main/play/pl-PL/listing/shortdescription +trans.pt_BR = app/src/main/play/pt-BR/listing/shortdescription +trans.pt_PT = app/src/main/play/pt-PT/listing/shortdescription +trans.ro_RO = app/src/main/play/ro/listing/shortdescription +trans.ru_RU = app/src/main/play/ru-RU/listing/shortdescription +trans.sl_SI = app/src/main/play/sl/listing/shortdescription +trans.sv_SE = app/src/main/play/sv-SE/listing/shortdescription +trans.tr = app/src/main/play/tr-TR/listing/shortdescription +trans.uk_UA = app/src/main/play/uk/listing/shortdescription +trans.vi = app/src/main/play/vi/listing/shortdescription +trans.zh_CN = app/src/main/play/zh-CN/listing/shortdescription +trans.zh_TW = app/src/main/play/zh-TW/listing/shortdescription diff --git a/CHANGELOG.md b/CHANGELOG.md index a050dd9c9..2899d1fd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,25 @@ Change Log ========== + +Version 1.7.1 +------------- + +* Fix for database corruption + +Version 1.7.0 +------------- + +* NEW ExoPlayer (experimental) +* Fix for Bluetooth Forward (Oreo) +* Preference redesign + search +* Notification improvements +* Different screens for feed info and settings +* Sort Queue with Random or Smart Shuffle +* True Black Theme for AMOLED +* Improvements to feed parsing +* Fix for app being killed by Android Oreo + Version 1.6.5 ------------- diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 837c412c5..891a9784c 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -1,107 +1,168 @@ DEVELOPERS ========== +Alan Orth Alexander Terczka +alifeflow +amhokies +Anders Bo Rasmussen Andrew Gaul Andrey Krutov Anthony Lieuallen axq +brad ByteHamster +Cameron Banga Christian Ludwig Christopher Szucko +Cj Malone Colin Willson +Cédric Cabessa +Danial Klimkin Daniel Oeh David Carver David Reiss Dean Brettle dethstar +Dirk Mueller Domingos Lopes drabux +egsavage +EirikV Eoin Mcloughlin +eraymond Ercan Erden +Falko Lehmann +Hannes Achleitner +hannesa2 Hanno Zulla heckler01 Holger Jeromin +Humberto Fraga +InsidE James Falcon +Jan Niehusmann +Jens Klingenberg Jens Müller Johan LieseÌn +Kaligule Katrin Leinweber -keunes +Kevin Dalley Koen Glotzbach +kroegerama +Kurian Vithayathil LatinSuD Lee Yeong Khang lightonflux ligi +Luis Cruz +Marc Lasson Martin Fietz Martin Olsson mat tso +mateoeh +Matthew Gaffen Matthias Schütz +Maurice Gilden +Meir Schwarz Michael Kaiser Michael Scarito Mike Chelen +minusf +MolarAmbiguity Mounir Lamouri +mr-intj Nis Wechselberg +Oliver Crow +orelogo Paul Ortyl +Raghul +Raghul Jagannathan recalculated Ross Harrison +Sam Lee Sam Whited +saqura +Selivanov Pavel +Serge Seth Golub +sevenmaster +Shantana Hardy Simon Danner Simon Rutishauser Simon Schubert +Soso Tughushi +Spencer Visick Stefan Mitrik Terence Eden Tim Butram Tobias Preuss Tom Hennen +Tom Tom tommy watson +tuxayo twiceyuan Udi Finkelstein +VarunBarad volhol Volker Hollich WangYun William Seemann +ydinath TRANSLATORS =========== -Arabic: abuzar3.khalid, iDemo -Azerbaijani: phoenixar -Catalan: dvd1985, javiercoll, xc70 -Catalan (Spain): javiercoll -Chinese (China): bebeauties38, dudeG, Felix2yu, gaohongyuan, Guaidaodl, linxiangyu, molisiye, tupunco, wongsyrone, yangyang, YogaGuru +Arabic: abdelrahman.fahem93, abdunnasir, abuzar3.khalid, desha, iDemo, mohamedagamy, msahouli, nabilMaghura +Asturian (Spain): enolp +Azerbaijani: danieloeh, kotfenix +Bulgarian: solusitor +Catalan: dvd1985, exort12, javiercoll, lambdani, marcmetallextrem, xc70 +Catalan (Spain): 00c0c0, javiercoll +Chinese: dillonbecker, RainSlide, xukeek, yangyang +Chinese (China): bebeauties38, domingos86, dudeG, ErlichLiu, Felix2yu, gaohongyuan, Guaidaodl, Huck0, iconteral, jhxie, kavdx, kyleehee, linxiangyu, molisiye, owen8877, RainSlide, stellaxuyi, tupunco, wi24rd, wongsyrone, xukeek, yangyang, yiqiok, YogaGuru +Chinese (Taiwan): gugod, nigelinux, pggdt, ymhuang0808 Czech (Czech Republic): elich, Hanzmeister, mcepl, petnek, svetlemodry -Danish: CasperHN -Dutch: e2jk, glotzbach, rwv +Danish: CasperHN, jhertel +Dutch: e2jk, glotzbach, rwv, Vistaus English: mfietz, sterylmreep +Estonian: Eraser Finnish: danieloeh -French: cactux, ChaoticMind, clombion, e2jk, lacouture, Matth78, mfietz, repat, sterylmreep, vcariven -German: 112358, altegedanken, bitsunited, ChaoticMind, Chaquotay, dab0015, DJaeger, HolgerJeromin, kalei, lohmann, mfietz, nilso, picsel2, repat, SAPlayer, schafia, ypid -Greek: AlexanderKanetakis -Hebrew (Israel): amir.dafnyman -Hindi (India): purple.coder, siddhusengar -Hungarian: glatz.balazs, naren93 -Indonesian: luke137, silvanael16 -Italian: aalex70, apanontin, Guybrush88, theloca95 -Italian (Italy): aalex70, apanontin, Guybrush88, m.chinni, theloca95 +French: cactux, ChaoticMind, clombion, e2jk, lacouture, Matth78, mfietz, Poussinou, PRIMOKORN, repat, sterylmreep, TacoTheDank, Tilwa, vcariven, whenrow +Galician: antiparvos, pikamoku, Raichely +German: 112358, altegedanken, barilla, bitsunited, Buggi, ceving, ChaoticMind, Chaquotay, dab0015, dadosch, DerSilly, DJaeger, elkangaroo, enz, fidel, finsterwalder, Foso, GNi33, HolgerJeromin, kalei, lohmann, LostInWeb, mfietz, nilso, repat, SAPlayer, schafia, Schroedingberg, sevenmaster, sucaml, Teaspoon, theonlytruth, weltenwort, Wyrrrd, ypid +Greek: antonist, danieloeh, hua2016s, MSavoritias, pavlosv +Hebrew (Israel): amir.dafnyman, E1i9, mongoose4004, pinkasey, rellieberman, Yaron, הלוי11 +Hindi (India): nmabhinandan, purple.coder, siddhusengar +Hungarian: glatz.balazs, lna91, naren93, tszauer, ttyborg42 +Icelandic: marthjod +Indonesian: jff, luke137, rezafaiza, silvanael16 +Italian: aalex70, allin, apanontin, Bonnee, giuseppep, Guybrush88, marco_pag, neonsoftware, sevenmaster, theloca95 +Italian (Italy): aalex70, allin, apanontin, Bonnee, buongiorgio, giuseppep, Guybrush88, m.chinni, neonsoftware, nixxo, sevenmaster, theloca95 Japanese: Naofumi, RACER1, sh3llc4t, TranslatorG Kannada (India): thejeshgn -Korean: changwoo, halcyonest, seungrye, skcha +Korean: changwoo, seungrye, skcha Korean (South Korea): changwoo, seungrye +Lithuanian: naglis +Macedonian: krisfremen Norwegian: hakonanes, timbast -Norwegian BokmÃ¥l: hakonanes -Norwegian BokmÃ¥l (Norway): hakonanes, kongk, swordfighter, timbast -Polish: Iwangelion, maniexx, thedead4fun -Polish (Poland): Iwangelion, lomapur, maniexx, Mephistofeles, shark103, tyle -Portuguese: emansije, smarquespt -Portuguese (Brazil): alexupits, edman, Firmino, lipefire, lucasmotacr, mbaltar, rogervezaro, SamWilliam, silvanael16 -Romanian (Romania): corneliu.e, fuzzmz -Russian (Russia): astra1, Duke_Raven, mercutiy, null, overmind88, phoenixar, s.chebotar, skvheadless, whereisthetea, zhenya97 -Spanish: coperfix, dvd1985, Fitoschido, frandavid100, javiercoll, LatinSuD, tres.14159 -Spanish (Spain): dvd1985, e2jk, frandavid100 -Swedish (Sweden): albin.brantin, Bio, bpnilsson, ChaoticMind, Lumen, nilso, SharpMelon, TwoD -Turkish: basarancaner, brsata, overbite -Ukrainian (Ukraine): older, zhenya97 -Vietnamese: ppanhh, vietnamesel10n +Norwegian BokmÃ¥l: corkie, hakonanes +Norwegian BokmÃ¥l (Norway): corkie, hakonanes, kongk, timbast +Persian: ahangarha, F7D +Polish: Iwangelion, maniexx, mfloryan, thedead4fun +Polish (Poland): d6210809, Iwangelion, lomapur, mandlus, maniexx, Mephistofeles, shark103, tyle +Portuguese: domingos86, emansije, smarquespt +Portuguese (Brazil): alexupits, alysonborges, arua, caioau, carlo_valente, castrors, deandreamatias, edman, Firmino, jackmiras, Junin, lipefire, lluccia, lucasmotacr, mbaltar, rogervezaro, RubeensVinicius, SamWilliam, silvanael16 +Romanian (Romania): corneliu.e, fuzzmz, ralienpp +Russian (Russia): astra1, btimofeev, Duke_Raven, GaynullinDima, MegMasters98, mercutiy, null, overmind88, s.chebotar, shams4real, skvheadless, un_logic, whereisthetea, zhenya97 +Slovenian (Slovenia): panter23 +Spanish: AleksSyntek, coperfix, deandreamatias, domingos86, dvd1985, Fitoschido, frandavid100, hard_ware, javiercoll, Juanmuto, lambdani, LatinSuD, leogrignafini, palopezv, TacoTheDank, tres.14159, wakutiteo +Spanish (Spain): dvd1985, e2jk, frandavid100, hard_ware, palopezv, Raichely, TacoTheDank +Swahili (Kenya): BonfaceKilz +Swedish (Sweden): albin.brantin, Bio, bpnilsson, ChaoticMind, jony08, nilso, SharpMelon, TwoD +Telugu: veeven +Turkish: basarancaner, brsata, Erdy, golcuk, overbite +Ukrainian (Ukraine): older, sergiyr, zhenya97 +Vietnamese: abnvolk, nguyenvui, ppanhh, vietnamesel10n Vietnamese (Vietnam): bizover @@ -5,7 +5,7 @@ This is the official repository of AntennaPod, the easy-to-use, flexible and ope [<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png" alt="Get it on Google Play" height="90">](https://play.google.com/store/apps/details?id=de.danoeh.antennapod) -[<img src="https://f-droid.org/badge/get-it-on.png" +[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" alt="Get it on F-Droid" height="90">](https://f-droid.org/app/de.danoeh.antennapod) diff --git a/app/build.gradle b/app/build.gradle index 6c8abbdff..3299ab715 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,49 +1,27 @@ -import org.apache.tools.ant.filters.ReplaceTokens +plugins { + id('com.github.triplet.play') version '2.0.0' +} apply plugin: "com.android.application" -apply plugin: 'com.github.triplet.play' apply plugin: 'com.getkeepsafe.dexcount' -repositories { - maven { url "https://jitpack.io" } - mavenCentral() -} - -buildscript { - repositories { - jcenter() - } - dependencies { - classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.8.2' - } -} - -def getMyVersionName() { - def parsedManifestXml = (new XmlSlurper()) - .parse("${projectDir}/src/main/AndroidManifest.xml") - .declareNamespace(android: "http://schemas.android.com/apk/res/android") - return parsedManifestXml."@android:versionName" -} - -def getMyVersionCode() { - def parsedManifestXml = (new XmlSlurper()) - .parse("${projectDir}/src/main/AndroidManifest.xml") - .declareNamespace(android: "http://schemas.android.com/apk/res/android") - return parsedManifestXml."@android:versionCode".toInteger() -} +import org.apache.tools.ant.filters.ReplaceTokens android { compileSdkVersion rootProject.ext.compileSdkVersion - buildToolsVersion rootProject.ext.buildToolsVersion defaultConfig { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled true - versionCode getMyVersionCode() - versionName "${getMyVersionName()}" + vectorDrawables.useSupportLibrary true + // Version code schema: + // "1.2.3-SNAPSHOT" -> 1020300 + // "1.2.3-RC4" -> 1020304 + versionCode 1070196 + versionName "1.7.1" testApplicationId "de.test.antennapod" - testInstrumentationRunner "de.test.antennapod.AntennaPodTestRunner" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" generatedDensities = [] } @@ -95,7 +73,7 @@ android { release { resValue "string", "provider_authority", "de.danoeh.antennapod.provider" minifyEnabled true - proguardFile "proguard.cfg" + proguardFiles getDefaultProguardFile('proguard-android.txt'), "proguard.cfg" signingConfig signingConfigs.releaseConfig buildConfigField STRING, FLATTR_APP_KEY, mFlattrAppKey buildConfigField STRING, FLATTR_APP_SECRET, mFlattrAppSecret @@ -120,6 +98,10 @@ android { additionalParameters "--no-version-vectors" } + testOptions { + animationsDisabled = true + } + flavorDimensions "market" productFlavors { free { @@ -150,6 +132,7 @@ dependencies { implementation "com.android.support:gridlayout-v7:$supportVersion" implementation "com.android.support:percent:$supportVersion" implementation "com.android.support:recyclerview-v7:$supportVersion" + compileOnly 'com.google.android.wearable:wearable:2.2.0' implementation "org.apache.commons:commons-lang3:$commonslangVersion" implementation("org.shredzone.flattr4j:flattr4j-core:$flattr4jVersion") { exclude group: "org.json", module: "json" @@ -157,14 +140,14 @@ dependencies { implementation "commons-io:commons-io:$commonsioVersion" implementation "org.jsoup:jsoup:$jsoupVersion" implementation "com.github.bumptech.glide:glide:$glideVersion" + annotationProcessor "com.github.bumptech.glide:compiler:$glideVersion" implementation "com.squareup.okhttp3:okhttp:$okhttpVersion" implementation "com.squareup.okhttp3:okhttp-urlconnection:$okhttpVersion" implementation "com.squareup.okio:okio:$okioVersion" implementation "de.greenrobot:eventbus:$eventbusVersion" - implementation "io.reactivex:rxandroid:$rxAndroidVersion" - implementation "io.reactivex:rxjava:$rxJavaVersion" - // And ProGuard rules for RxJava! - implementation "com.artemzin.rxjava:proguard-rules:$rxJavaRulesVersion" + implementation "io.reactivex.rxjava2:rxandroid:$rxAndroidVersion" + implementation "io.reactivex.rxjava2:rxjava:$rxJavaVersion" + implementation "com.joanzapata.iconify:android-iconify-fontawesome:$iconifyVersion" implementation "com.joanzapata.iconify:android-iconify-material:$iconifyVersion" implementation("com.afollestad.material-dialogs:commons:$materialDialogsVersion") { @@ -176,18 +159,33 @@ dependencies { } implementation "com.github.shts:TriangleLabelView:$triangleLabelViewVersion" + implementation 'com.leinardi.android:speed-dial:1.0.2' // 1.0.2 uses support 27.1.1 ; newer versions use 28.0.0; implementation "com.github.AntennaPod:AntennaPod-AudioPlayer:$audioPlayerVersion" - implementation 'com.github.mfietz:fyydlin:v0.3' - implementation 'com.github.ByteHamster:SearchPreference:v1.0.8' + implementation 'com.github.mfietz:fyydlin:v0.4.2' + implementation 'com.github.ByteHamster:SearchPreference:v1.2.5' + implementation "org.awaitility:awaitility:$awaitilityVersion" androidTestImplementation "com.jayway.android.robotium:robotium-solo:$robotiumSoloVersion" + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-contrib:3.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-intents:3.0.2' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test:rules:1.0.2' } play { - serviceAccountEmail = '522080222319-compute@developer.gserviceaccount.com' - pk12File = file('../serviceaccount-c3d7d0f61387.p12') + if (project.hasProperty("antennaPodServiceAccountEmail")) { + serviceAccountEmail = antennaPodServiceAccountEmail + } else { + serviceAccountEmail = '522080222319-compute@developer.gserviceaccount.com' + } + if (project.hasProperty("antennaPodPk12File")) { + serviceAccountCredentials = file(antennaPodPk12File) + } else { + serviceAccountCredentials = file('../serviceaccount-c3d7d0f61387.p12') + } } // about.html is templatized so that we can automatically insert @@ -217,10 +215,3 @@ task copyTextFiles(type: Copy) { preBuild.dependsOn filterAbout, copyTextFiles -allprojects { - gradle.projectsEvaluated { - tasks.withType(JavaCompile) { - options.compilerArgs << "-Xlint" << "-Xlint:-deprecation" << "-Xlint:-serial" - } - } -} diff --git a/app/proguard.cfg b/app/proguard.cfg index 01b1708f7..6df2ae9bf 100644 --- a/app/proguard.cfg +++ b/app/proguard.cfg @@ -53,8 +53,12 @@ public *; } +# for okhttp -dontwarn okhttp3.** -dontwarn okio.** +-dontwarn javax.annotation.** +-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase +-dontwarn org.codehaus.mojo.animal_sniffer.* # for RxJava: -dontwarn sun.misc.Unsafe @@ -71,8 +75,6 @@ -dontwarn android.support.v7.** -dontwarn com.google.android.wearable.** --keepattributes *Annotation* - -keep class org.shredzone.flattr4j.** { *; } -dontwarn org.shredzone.flattr4j.** @@ -94,16 +96,19 @@ -keepclassmembers class ** { public void onEvent*(**); } +-keep class de.danoeh.antennapod.core.event.* # android-iconify -keep class com.joanzapata.** { *; } # Glide -keep public class * implements com.bumptech.glide.module.GlideModule --keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** { - **[] $VALUES; - public *; +-keep public class * extends com.bumptech.glide.module.AppGlideModule +-keep public enum com.bumptech.glide.load.ImageHeaderParser$** { + **[] $VALUES; + public *; } +-dontwarn com.bumptech.glide.load.resource.bitmap.VideoDecoder # for ViewPageIndicator problems (https://github.com/JakeWharton/ViewPagerIndicator/issues/366): -dontwarn com.viewpagerindicator.LinePageIndicator @@ -125,3 +130,13 @@ -keep class com.squareup.moshi.** { *; } -keep interface com.squareup.moshi.** { *; } -keep public class retrofit2.adapter.rxjava.RxJavaCallAdapterFactory { *; } + +# awaitility +-dontwarn java.beans.BeanInfo +-dontwarn java.beans.Introspector +-dontwarn java.beans.IntrospectionException +-dontwarn java.beans.PropertyDescriptor +-dontwarn java.lang.management.ManagementFactory +-dontwarn java.lang.management.ThreadInfo +-dontwarn java.lang.management.ThreadMXBean + diff --git a/app/sampledata/episodes.json b/app/sampledata/episodes.json new file mode 100644 index 000000000..209cbf180 --- /dev/null +++ b/app/sampledata/episodes.json @@ -0,0 +1,34 @@ +{ + "data": [ + { + "title": "FLOSS Weekly 482: PyPI", + "status_label": "NEW", + "duration": "00:52:40", + "published_at": "2. May" + }, + { + "title": "FLOSS Weekly 479: Pidgin", + "status_label": " ", + "duration": "01:08:08", + "published_at": "11. Apr" + }, + { + "title": "Linux Outlaws 370 - Stay Free, Stay Open Source", + "status_label": "NEW", + "duration": "02:52:51", + "published_at": "29. Dec 2014" + }, + { + "title": "Linux Outlaws 368 - The Dark Ages of Free Software", + "status_label": " ", + "duration": "02:26:54", + "published_at": "14. Dec 2014" + }, + { + "title": "Linux Outlaws 365 - Last Stand", + "status_label": " ", + "duration": "00:39:59", + "published_at": "3. Nov 2014" + } + ] +} diff --git a/app/sampledata/inplaylist b/app/sampledata/inplaylist new file mode 100644 index 000000000..e78406d75 --- /dev/null +++ b/app/sampledata/inplaylist @@ -0,0 +1,2 @@ +@null +@drawable/ic_list_grey600_24dp
\ No newline at end of file diff --git a/app/sampledata/secondaryaction b/app/sampledata/secondaryaction new file mode 100644 index 000000000..26083bc9c --- /dev/null +++ b/app/sampledata/secondaryaction @@ -0,0 +1,3 @@ +@drawable/ic_play_arrow_grey600_36dp +@drawable/ic_file_download_grey600_24dp +@drawable/ic_cancel_grey600_24dp
\ No newline at end of file diff --git a/app/src/androidTest/java/de/test/antennapod/AntennaPodTestRunner.java b/app/src/androidTest/java/de/test/antennapod/AntennaPodTestRunner.java deleted file mode 100644 index c321e6494..000000000 --- a/app/src/androidTest/java/de/test/antennapod/AntennaPodTestRunner.java +++ /dev/null @@ -1,18 +0,0 @@ -package de.test.antennapod; - -import android.test.InstrumentationTestRunner; -import android.test.suitebuilder.TestSuiteBuilder; - -import junit.framework.TestSuite; - -public class AntennaPodTestRunner extends InstrumentationTestRunner { - - @Override - public TestSuite getAllTests() { - return new TestSuiteBuilder(AntennaPodTestRunner.class) - .includeAllPackagesUnderHere() - .excludePackages("de.test.antennapod.gpodnet") - .build(); - } - -} diff --git a/app/src/androidTest/java/de/test/antennapod/NthMatcher.java b/app/src/androidTest/java/de/test/antennapod/NthMatcher.java new file mode 100644 index 000000000..f9ecacda5 --- /dev/null +++ b/app/src/androidTest/java/de/test/antennapod/NthMatcher.java @@ -0,0 +1,38 @@ +package de.test.antennapod; + +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.hamcrest.Matcher; + +import java.util.concurrent.atomic.AtomicInteger; + +public class NthMatcher { + public static <T> Matcher<T> first(final Matcher<T> matcher) { + return nth(matcher, 1); + } + + public static <T> Matcher<T> second(final Matcher<T> matcher) { + return nth(matcher, 2); + } + + private static <T> Matcher<T> nth(final Matcher<T> matcher, final int index) { + return new BaseMatcher<T>() { + AtomicInteger count = new AtomicInteger(0); + + @Override + public boolean matches(final Object item) { + if (matcher.matches(item)) { + if (count.incrementAndGet() == index) { + return true; + } + } + return false; + } + + @Override + public void describeTo(final Description description) { + description.appendText("should return first matching item"); + } + }; + } +} diff --git a/app/src/androidTest/java/de/test/antennapod/feed/FeedItemTest.java b/app/src/androidTest/java/de/test/antennapod/feed/FeedItemTest.java index db463132d..ced0d7a28 100644 --- a/app/src/androidTest/java/de/test/antennapod/feed/FeedItemTest.java +++ b/app/src/androidTest/java/de/test/antennapod/feed/FeedItemTest.java @@ -1,6 +1,7 @@ package de.test.antennapod.feed; import android.test.AndroidTestCase; + import de.danoeh.antennapod.core.feed.FeedItem; public class FeedItemTest extends AndroidTestCase { diff --git a/app/src/androidTest/java/de/test/antennapod/gpodnet/GPodnetServiceTest.java b/app/src/androidTest/java/de/test/antennapod/gpodnet/GPodnetServiceTest.java index a880c330b..91e31e73c 100644 --- a/app/src/androidTest/java/de/test/antennapod/gpodnet/GPodnetServiceTest.java +++ b/app/src/androidTest/java/de/test/antennapod/gpodnet/GPodnetServiceTest.java @@ -1,43 +1,43 @@ package de.test.antennapod.gpodnet; -import android.test.AndroidTestCase; - import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import android.support.test.runner.AndroidJUnit4; import de.danoeh.antennapod.core.gpoddernet.GpodnetService; import de.danoeh.antennapod.core.gpoddernet.GpodnetServiceException; import de.danoeh.antennapod.core.gpoddernet.model.GpodnetDevice; import de.danoeh.antennapod.core.gpoddernet.model.GpodnetTag; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; import static java.util.Collections.singletonList; /** * Test class for GpodnetService */ -public class GPodnetServiceTest extends AndroidTestCase { +@Ignore +@RunWith(AndroidJUnit4.class) +public class GPodnetServiceTest { private GpodnetService service; private static final String USER = ""; private static final String PW = ""; - @Override - protected void setUp() throws Exception { - super.setUp(); + @Before + protected void setUp() { service = new GpodnetService(); } - @Override - protected void tearDown() throws Exception { - super.tearDown(); - } - private void authenticate() throws GpodnetServiceException { service.authenticate(USER, PW); } + @Test public void testUploadSubscription() throws GpodnetServiceException { authenticate(); ArrayList<String> l = new ArrayList<>(); @@ -45,6 +45,7 @@ public class GPodnetServiceTest extends AndroidTestCase { service.uploadSubscriptions(USER, "radio", l); } + @Test public void testUploadSubscription2() throws GpodnetServiceException { authenticate(); ArrayList<String> l = new ArrayList<>(); @@ -53,6 +54,7 @@ public class GPodnetServiceTest extends AndroidTestCase { service.uploadSubscriptions(USER, "radio", l); } + @Test public void testUploadChanges() throws GpodnetServiceException { authenticate(); String[] URLS = {"http://bitsundso.de/feed", "http://gamesundso.de/feed", "http://cre.fm/feed/mp3/", "http://freakshow.fm/feed/m4a/"}; @@ -63,53 +65,63 @@ public class GPodnetServiceTest extends AndroidTestCase { service.uploadChanges(USER, "radio", added, removed); } + @Test public void testGetSubscriptionChanges() throws GpodnetServiceException { authenticate(); service.getSubscriptionChanges(USER, "radio", 1362322610L); } + @Test public void testGetSubscriptionsOfUser() throws GpodnetServiceException { authenticate(); service.getSubscriptionsOfUser(USER); } + @Test public void testGetSubscriptionsOfDevice() throws GpodnetServiceException { authenticate(); service.getSubscriptionsOfDevice(USER, "radio"); } + @Test public void testConfigureDevices() throws GpodnetServiceException { authenticate(); service.configureDevice(USER, "foo", "This is an updated caption", GpodnetDevice.DeviceType.LAPTOP); } + @Test public void testGetDevices() throws GpodnetServiceException { authenticate(); service.getDevices(USER); } + @Test public void testGetSuggestions() throws GpodnetServiceException { authenticate(); service.getSuggestions(10); } + @Test public void testTags() throws GpodnetServiceException { service.getTopTags(20); } + @Test public void testPodcastForTags() throws GpodnetServiceException { List<GpodnetTag> tags = service.getTopTags(20); service.getPodcastsForTag(tags.get(1), 10); } + @Test public void testSearch() throws GpodnetServiceException { service.searchPodcasts("linux", 64); } + @Test public void testToplist() throws GpodnetServiceException { service.getPodcastToplist(10); } diff --git a/app/src/androidTest/java/de/test/antennapod/handler/FeedHandlerTest.java b/app/src/androidTest/java/de/test/antennapod/handler/FeedHandlerTest.java index 39abe4b7a..9419d2318 100644 --- a/app/src/androidTest/java/de/test/antennapod/handler/FeedHandlerTest.java +++ b/app/src/androidTest/java/de/test/antennapod/handler/FeedHandlerTest.java @@ -1,6 +1,7 @@ package de.test.antennapod.handler; import android.content.Context; +import android.support.test.InstrumentationRegistry; import android.test.InstrumentationTestCase; import org.xml.sax.SAXException; @@ -17,7 +18,6 @@ import javax.xml.parsers.ParserConfigurationException; import de.danoeh.antennapod.core.feed.Chapter; import de.danoeh.antennapod.core.feed.Feed; -import de.danoeh.antennapod.core.feed.FeedImage; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.syndication.handler.FeedHandler; @@ -37,7 +37,7 @@ public class FeedHandlerTest extends InstrumentationTestCase { protected void setUp() throws Exception { super.setUp(); - Context context = getInstrumentation().getContext(); + Context context = InstrumentationRegistry.getTargetContext(); File destDir = context.getExternalFilesDir(FEEDS_DIR); assertNotNull(destDir); @@ -82,15 +82,7 @@ public class FeedHandlerTest extends InstrumentationTestCase { assertEquals(feed.getLink(), parsedFeed.getLink()); assertEquals(feed.getDescription(), parsedFeed.getDescription()); assertEquals(feed.getPaymentLink(), parsedFeed.getPaymentLink()); - - if (feed.getImage() != null) { - FeedImage image = feed.getImage(); - FeedImage parsedImage = parsedFeed.getImage(); - assertNotNull(parsedImage); - - assertEquals(image.getTitle(), parsedImage.getTitle()); - assertEquals(image.getDownload_url(), parsedImage.getDownload_url()); - } + assertEquals(feed.getImageUrl(), parsedFeed.getImageUrl()); if (feed.getItems() != null) { assertNotNull(parsedFeed.getItems()); @@ -119,14 +111,7 @@ public class FeedHandlerTest extends InstrumentationTestCase { assertEquals(media.getMime_type(), parsedMedia.getMime_type()); } - if (item.hasItemImage()) { - assertTrue(parsedItem.hasItemImage()); - FeedImage image = item.getImage(); - FeedImage parsedImage = parsedItem.getImage(); - - assertEquals(image.getTitle(), parsedImage.getTitle()); - assertEquals(image.getDownload_url(), parsedImage.getDownload_url()); - } + assertEquals(item.getImageUrl(), parsedFeed.getImageUrl()); if (item.getChapters() != null) { assertNotNull(parsedItem.getChapters()); @@ -158,12 +143,8 @@ public class FeedHandlerTest extends InstrumentationTestCase { } private Feed createTestFeed(int numItems, boolean withImage, boolean withFeedMedia, boolean withChapters) { - FeedImage image = null; - if (withImage) { - image = new FeedImage(0, "image", null, "http://example.com/picture", false); - } Feed feed = new Feed(0, null, "title", "http://example.com", "This is the description", - "http://example.com/payment", "Daniel", "en", null, "http://example.com/feed", image, file.getAbsolutePath(), + "http://example.com/payment", "Daniel", "en", null, "http://example.com/feed", "http://example.com/picture", file.getAbsolutePath(), "http://example.com/feed", true); feed.setItems(new ArrayList<>()); diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java index 93a9408b7..9cd7689ba 100644 --- a/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java +++ b/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java @@ -5,7 +5,6 @@ import android.test.FlakyTest; import android.test.InstrumentationTestCase; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.List; 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 c9c715a86..a577e5e36 100644 --- a/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java +++ b/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java @@ -21,6 +21,7 @@ import de.danoeh.antennapod.core.util.flattr.FlattrStatus; */ class DBTestUtils { + private DBTestUtils(){} /** * Use this method when tests don't involve chapters. */ diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java index b1cc807ea..27d76116d 100644 --- a/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java +++ b/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java @@ -1,10 +1,14 @@ package de.test.antennapod.storage; import android.content.Context; +import android.content.SharedPreferences; import android.database.Cursor; +import android.preference.PreferenceManager; import android.test.InstrumentationTestCase; import android.util.Log; +import org.awaitility.Awaitility; + import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -15,15 +19,14 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import de.danoeh.antennapod.core.feed.Chapter; import de.danoeh.antennapod.core.feed.Feed; -import de.danoeh.antennapod.core.feed.FeedImage; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; -import de.danoeh.antennapod.core.feed.SimpleChapter; +import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.storage.PodDBAdapter; +import de.danoeh.antennapod.core.util.Consumer; /** * Test class for DBWriter @@ -58,6 +61,12 @@ public class DBWriterTest extends InstrumentationTestCase { PodDBAdapter adapter = PodDBAdapter.getInstance(); adapter.open(); adapter.close(); + + Context context = getInstrumentation().getTargetContext(); + SharedPreferences.Editor prefEdit = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext()).edit(); + prefEdit.putBoolean(UserPreferences.PREF_DELETE_REMOVES_FROM_QUEUE, true).commit(); + + UserPreferences.init(context); } public void testSetFeedMediaPlaybackInformation() @@ -124,89 +133,54 @@ public class DBWriterTest extends InstrumentationTestCase { assertNull(media.getFile_url()); } - public void testDeleteFeed() throws IOException, ExecutionException, InterruptedException, TimeoutException { - File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER); - assertNotNull(destFolder); - - Feed feed = new Feed("url", null, "title"); - feed.setItems(new ArrayList<>()); + public void testDeleteFeedMediaOfItemRemoveFromQueue() + throws IOException, ExecutionException, InterruptedException, TimeoutException { + assertTrue(UserPreferences.shouldDeleteRemoveFromQueue()); - // create Feed image - File imgFile = new File(destFolder, "image"); - assertTrue(imgFile.createNewFile()); - FeedImage image = new FeedImage(0, "image", imgFile.getAbsolutePath(), "url", true); - image.setOwner(feed); - feed.setImage(image); + File dest = new File(getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER), "testFile"); - List<File> itemFiles = new ArrayList<>(); - // create items with downloaded media files - for (int i = 0; i < 10; i++) { - FeedItem item = new FeedItem(0, "Item " + i, "Item" + i, "url", new Date(), FeedItem.PLAYED, feed, true); - feed.getItems().add(item); + assertTrue(dest.createNewFile()); - File enc = new File(destFolder, "file " + i); - assertTrue(enc.createNewFile()); - itemFiles.add(enc); + Feed feed = new Feed("url", null, "title"); + List<FeedItem> items = new ArrayList<>(); + List<FeedItem> queue = new ArrayList<>(); + feed.setItems(items); + FeedItem item = new FeedItem(0, "Item", "Item", "url", new Date(), FeedItem.UNPLAYED, feed); - FeedMedia media = new FeedMedia(0, item, 1, 1, 1, "mime_type", enc.getAbsolutePath(), "download_url", true, null, 0, 0); - item.setMedia(media); + FeedMedia media = new FeedMedia(0, item, 1, 1, 1, "mime_type", dest.getAbsolutePath(), "download_url", true, null, 0, 0); + item.setMedia(media); - item.setChapters(new ArrayList<>()); - item.getChapters().add(new SimpleChapter(0, "item " + i, item, "example.com")); - } + items.add(item); + queue.add(item); PodDBAdapter adapter = PodDBAdapter.getInstance(); adapter.open(); adapter.setCompleteFeed(feed); + adapter.setQueue(queue); adapter.close(); + assertTrue(media.getId() != 0); + assertTrue(item.getId() != 0); + queue = DBReader.getQueue(); + assertTrue(queue.size() != 0); - assertTrue(feed.getId() != 0); - assertTrue(feed.getImage().getId() != 0); - for (FeedItem item : feed.getItems()) { - assertTrue(item.getId() != 0); - assertTrue(item.getMedia().getId() != 0); - assertTrue(item.getChapters().get(0).getId() != 0); - } - - DBWriter.deleteFeed(getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS); - - // check if files still exist - assertFalse(imgFile.exists()); - for (File f : itemFiles) { - assertFalse(f.exists()); - } - - adapter = PodDBAdapter.getInstance(); - adapter.open(); - Cursor c = adapter.getFeedCursor(feed.getId()); - assertEquals(0, c.getCount()); - c.close(); - c = adapter.getImageCursor(String.valueOf(image.getId())); - assertEquals(0, c.getCount()); - c.close(); - for (FeedItem item : feed.getItems()) { - c = adapter.getFeedItemCursor(String.valueOf(item.getId())); - assertEquals(0, c.getCount()); - c.close(); - c = adapter.getSingleFeedMediaCursor(item.getMedia().getId()); - assertEquals(0, c.getCount()); - c.close(); - c = adapter.getSimpleChaptersOfFeedItemCursor(item); - assertEquals(0, c.getCount()); - c.close(); - } - adapter.close(); + DBWriter.deleteFeedMediaOfItem(getInstrumentation().getTargetContext(), media.getId()); + Awaitility.await().until(() -> dest.exists() == false); + media = DBReader.getFeedMedia(media.getId()); + assertNotNull(media); + assertFalse(dest.exists()); + assertFalse(media.isDownloaded()); + assertNull(media.getFile_url()); + queue = DBReader.getQueue(); + assertTrue(queue.size() == 0); } - public void testDeleteFeedNoImage() throws ExecutionException, InterruptedException, IOException, TimeoutException { + public void testDeleteFeed() throws ExecutionException, InterruptedException, IOException, TimeoutException { File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER); assertNotNull(destFolder); Feed feed = new Feed("url", null, "title"); feed.setItems(new ArrayList<>()); - feed.setImage(null); - List<File> itemFiles = new ArrayList<>(); // create items with downloaded media files for (int i = 0; i < 10; i++) { @@ -261,13 +235,7 @@ public class DBWriterTest extends InstrumentationTestCase { Feed feed = new Feed("url", null, "title"); feed.setItems(null); - - // create Feed image - File imgFile = new File(destFolder, "image"); - assertTrue(imgFile.createNewFile()); - FeedImage image = new FeedImage(0, "image", imgFile.getAbsolutePath(), "url", true); - image.setOwner(feed); - feed.setImage(image); + feed.setImageUrl("url"); PodDBAdapter adapter = PodDBAdapter.getInstance(); adapter.open(); @@ -275,21 +243,14 @@ public class DBWriterTest extends InstrumentationTestCase { adapter.close(); assertTrue(feed.getId() != 0); - assertTrue(feed.getImage().getId() != 0); DBWriter.deleteFeed(getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS); - // check if files still exist - assertFalse(imgFile.exists()); - adapter = PodDBAdapter.getInstance(); adapter.open(); Cursor c = adapter.getFeedCursor(feed.getId()); assertTrue(c.getCount() == 0); c.close(); - c = adapter.getImageCursor(String.valueOf(image.getId())); - assertTrue(c.getCount() == 0); - c.close(); adapter.close(); } @@ -300,12 +261,7 @@ public class DBWriterTest extends InstrumentationTestCase { Feed feed = new Feed("url", null, "title"); feed.setItems(new ArrayList<>()); - // create Feed image - File imgFile = new File(destFolder, "image"); - assertTrue(imgFile.createNewFile()); - FeedImage image = new FeedImage(0, "image", imgFile.getAbsolutePath(), "url", true); - image.setOwner(feed); - feed.setImage(image); + feed.setImageUrl("url"); // create items for (int i = 0; i < 10; i++) { @@ -320,87 +276,22 @@ public class DBWriterTest extends InstrumentationTestCase { adapter.close(); assertTrue(feed.getId() != 0); - assertTrue(feed.getImage().getId() != 0); - for (FeedItem item : feed.getItems()) { - assertTrue(item.getId() != 0); - } - - DBWriter.deleteFeed(getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS); - - // check if files still exist - assertFalse(imgFile.exists()); - - adapter = PodDBAdapter.getInstance(); - adapter.open(); - Cursor c = adapter.getFeedCursor(feed.getId()); - assertTrue(c.getCount() == 0); - c.close(); - c = adapter.getImageCursor(String.valueOf(image.getId())); - assertTrue(c.getCount() == 0); - c.close(); - for (FeedItem item : feed.getItems()) { - c = adapter.getFeedItemCursor(String.valueOf(item.getId())); - assertTrue(c.getCount() == 0); - c.close(); - } - adapter.close(); - } - - public void testDeleteFeedWithItemImages() throws InterruptedException, ExecutionException, TimeoutException, IOException { - File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER); - assertNotNull(destFolder); - - Feed feed = new Feed("url", null, "title"); - feed.setItems(new ArrayList<>()); - - // create Feed image - File imgFile = new File(destFolder, "image"); - assertTrue(imgFile.createNewFile()); - FeedImage image = new FeedImage(0, "image", imgFile.getAbsolutePath(), "url", true); - image.setOwner(feed); - feed.setImage(image); - - // create items with images - for (int i = 0; i < 10; i++) { - FeedItem item = new FeedItem(0, "Item " + i, "Item" + i, "url", new Date(), FeedItem.PLAYED, feed); - feed.getItems().add(item); - File itemImageFile = new File(destFolder, "item-image-" + i); - FeedImage itemImage = new FeedImage(0, "item-image" + i, itemImageFile.getAbsolutePath(), "url", true); - item.setImage(itemImage); - } - - PodDBAdapter adapter = PodDBAdapter.getInstance(); - adapter.open(); - adapter.setCompleteFeed(feed); - adapter.close(); - - assertTrue(feed.getId() != 0); - assertTrue(feed.getImage().getId() != 0); for (FeedItem item : feed.getItems()) { assertTrue(item.getId() != 0); - assertTrue(item.getImage().getId() != 0); } DBWriter.deleteFeed(getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS); - // check if files still exist - assertFalse(imgFile.exists()); adapter = PodDBAdapter.getInstance(); adapter.open(); Cursor c = adapter.getFeedCursor(feed.getId()); assertTrue(c.getCount() == 0); c.close(); - c = adapter.getImageCursor(String.valueOf(image.getId())); - assertTrue(c.getCount() == 0); - c.close(); for (FeedItem item : feed.getItems()) { c = adapter.getFeedItemCursor(String.valueOf(item.getId())); assertTrue(c.getCount() == 0); c.close(); - c = adapter.getImageCursor(String.valueOf(item.getImage().getId())); - assertEquals(0, c.getCount()); - c.close(); } adapter.close(); } @@ -412,11 +303,7 @@ public class DBWriterTest extends InstrumentationTestCase { Feed feed = new Feed("url", null, "title"); feed.setItems(new ArrayList<>()); - // create Feed image - File imgFile = new File(destFolder, "image"); - FeedImage image = new FeedImage(0, "image", imgFile.getAbsolutePath(), "url", true); - image.setOwner(feed); - feed.setImage(image); + feed.setImageUrl("url"); List<File> itemFiles = new ArrayList<>(); // create items with downloaded media files @@ -437,7 +324,6 @@ public class DBWriterTest extends InstrumentationTestCase { adapter.close(); assertTrue(feed.getId() != 0); - assertTrue(feed.getImage().getId() != 0); for (FeedItem item : feed.getItems()) { assertTrue(item.getId() != 0); assertTrue(item.getMedia().getId() != 0); @@ -460,9 +346,6 @@ public class DBWriterTest extends InstrumentationTestCase { Cursor c = adapter.getFeedCursor(feed.getId()); assertTrue(c.getCount() == 0); c.close(); - c = adapter.getImageCursor(String.valueOf(image.getId())); - assertTrue(c.getCount() == 0); - c.close(); for (FeedItem item : feed.getItems()) { c = adapter.getFeedItemCursor(String.valueOf(item.getId())); assertTrue(c.getCount() == 0); @@ -484,11 +367,7 @@ public class DBWriterTest extends InstrumentationTestCase { Feed feed = new Feed("url", null, "title"); feed.setItems(new ArrayList<>()); - // create Feed image - File imgFile = new File(destFolder, "image"); - FeedImage image = new FeedImage(0, "image", imgFile.getAbsolutePath(), "url", true); - image.setOwner(feed); - feed.setImage(image); + feed.setImageUrl("url"); List<File> itemFiles = new ArrayList<>(); // create items with downloaded media files @@ -509,7 +388,6 @@ public class DBWriterTest extends InstrumentationTestCase { adapter.close(); assertTrue(feed.getId() != 0); - assertTrue(feed.getImage().getId() != 0); for (FeedItem item : feed.getItems()) { assertTrue(item.getId() != 0); assertTrue(item.getMedia().getId() != 0); @@ -522,9 +400,6 @@ public class DBWriterTest extends InstrumentationTestCase { Cursor c = adapter.getFeedCursor(feed.getId()); assertTrue(c.getCount() == 0); c.close(); - c = adapter.getImageCursor(String.valueOf(image.getId())); - assertTrue(c.getCount() == 0); - c.close(); for (FeedItem item : feed.getItems()) { c = adapter.getFeedItemCursor(String.valueOf(item.getId())); assertTrue(c.getCount() == 0); @@ -700,29 +575,16 @@ public class DBWriterTest extends InstrumentationTestCase { public void testRemoveQueueItem() throws InterruptedException, ExecutionException, TimeoutException { final int NUM_ITEMS = 10; final Context context = getInstrumentation().getTargetContext(); - Feed feed = new Feed("url", null, "title"); - feed.setItems(new ArrayList<>()); - for (int i = 0; i < NUM_ITEMS; i++) { - FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.PLAYED, feed); - feed.getItems().add(item); - } - - PodDBAdapter adapter = PodDBAdapter.getInstance(); - adapter.open(); - adapter.setCompleteFeed(feed); - adapter.close(); + Feed feed = createTestFeed(NUM_ITEMS); - for (FeedItem item : feed.getItems()) { - assertTrue(item.getId() != 0); - } for (int removeIndex = 0; removeIndex < NUM_ITEMS; removeIndex++) { final FeedItem item = feed.getItems().get(removeIndex); - adapter = PodDBAdapter.getInstance(); + PodDBAdapter adapter = PodDBAdapter.getInstance(); adapter.open(); adapter.setQueue(feed.getItems()); adapter.close(); - DBWriter.removeQueueItem(context, item, false).get(TIMEOUT, TimeUnit.SECONDS); + DBWriter.removeQueueItem(context, false, item).get(TIMEOUT, TimeUnit.SECONDS); adapter = PodDBAdapter.getInstance(); adapter.open(); Cursor queue = adapter.getQueueIDCursor(); @@ -742,6 +604,43 @@ public class DBWriterTest extends InstrumentationTestCase { } } + public void testRemoveQueueItemMultipleItems() throws InterruptedException, ExecutionException, TimeoutException { + // Setup test data + // + final int NUM_ITEMS = 5; + final int NUM_IN_QUEUE = NUM_ITEMS - 1; // the last one not in queue for boundary condition + final Context context = getInstrumentation().getTargetContext(); + Feed feed = createTestFeed(NUM_ITEMS); + + List<FeedItem> itemsToAdd = feed.getItems().subList(0, NUM_IN_QUEUE); + withPodDB(adapter -> adapter.setQueue(itemsToAdd) ); + + // Actual tests + // + + // Use array rather than List to make codes more succinct + Long[] itemIds = toItemIds(feed.getItems()).toArray(new Long[0]); + + DBWriter.removeQueueItem(context, false, + itemIds[1], itemIds[3]).get(TIMEOUT, TimeUnit.SECONDS); + assertQueueByItemIds("Average case - 2 items removed successfully", + itemIds[0], itemIds[2]); + + DBWriter.removeQueueItem(context, false).get(TIMEOUT, TimeUnit.SECONDS); + assertQueueByItemIds("Boundary case - no items supplied. queue should see no change", + itemIds[0], itemIds[2]); + + DBWriter.removeQueueItem(context, false, + itemIds[0], itemIds[4], -1L).get(TIMEOUT, TimeUnit.SECONDS); + assertQueueByItemIds("Boundary case - items not in queue ignored", + itemIds[2]); + + DBWriter.removeQueueItem(context, false, + itemIds[2], -1L).get(TIMEOUT, TimeUnit.SECONDS); + assertQueueByItemIds("Boundary case - invalid itemIds ignored"); // the queue is empty + + } + public void testMoveQueueItem() throws InterruptedException, ExecutionException, TimeoutException { final int NUM_ITEMS = 10; Feed feed = new Feed("url", null, "title"); @@ -839,4 +738,53 @@ public class DBWriterTest extends InstrumentationTestCase { assertTrue(item.isPlayed()); } } + + private static Feed createTestFeed(int numItems) { + Feed feed = new Feed("url", null, "title"); + feed.setItems(new ArrayList<>()); + for (int i = 0; i < numItems; i++) { + FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.PLAYED, feed); + feed.getItems().add(item); + } + + withPodDB(adapter -> adapter.setCompleteFeed(feed)); + + for (FeedItem item : feed.getItems()) { + assertTrue(item.getId() != 0); + } + return feed; + } + + private static void withPodDB(Consumer<PodDBAdapter> action) { + PodDBAdapter adapter = PodDBAdapter.getInstance(); + try { + adapter.open(); + action.accept(adapter); + } finally { + adapter.close(); + } + } + + private static void assertQueueByItemIds( + String message, + long... itemIdsExpected + ) { + List<FeedItem> queue = DBReader.getQueue(); + List<Long> itemIdsActualList = toItemIds(queue); + List<Long> itemIdsExpectedList = new ArrayList<Long>(itemIdsExpected.length); + for (long id : itemIdsExpected) { + itemIdsExpectedList.add(id); + } + + assertEquals(message, itemIdsExpectedList, itemIdsActualList); + } + + private static List<Long> toItemIds(List<FeedItem> items) { + List<Long> itemIds = new ArrayList<Long>(items.size()); + for(FeedItem item : items) { + itemIds.add(item.getId()); + } + return itemIds; + } + } diff --git a/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java b/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java index 6156da926..9a60b04b8 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java @@ -2,16 +2,14 @@ package de.test.antennapod.ui; import android.content.Context; import android.content.SharedPreferences; -import android.test.ActivityInstrumentationTestCase2; -import android.test.FlakyTest; +import android.support.test.espresso.contrib.DrawerActions; +import android.support.test.espresso.intent.Intents; +import android.support.test.filters.FlakyTest; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; import android.widget.ListView; - import com.robotium.solo.Solo; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - +import com.robotium.solo.Timeout; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.activity.OnlineFeedViewActivity; @@ -23,25 +21,46 @@ import de.danoeh.antennapod.fragment.DownloadsFragment; import de.danoeh.antennapod.fragment.EpisodesFragment; import de.danoeh.antennapod.fragment.PlaybackHistoryFragment; import de.danoeh.antennapod.fragment.QueueFragment; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static android.support.test.InstrumentationRegistry.getInstrumentation; +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.action.ViewActions.click; +import static android.support.test.espresso.action.ViewActions.longClick; +import static android.support.test.espresso.intent.Intents.intended; +import static android.support.test.espresso.intent.matcher.IntentMatchers.hasComponent; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static android.support.test.espresso.matcher.ViewMatchers.withText; +import static de.test.antennapod.NthMatcher.first; +import static junit.framework.TestCase.assertTrue; +import static org.junit.Assert.assertEquals; /** * User interface tests for MainActivity */ -public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> { +@RunWith(AndroidJUnit4.class) +public class MainActivityTest { private Solo solo; private UITestUtils uiTestUtils; - private SharedPreferences prefs; - public MainActivityTest() { - super(MainActivity.class); - } + @Rule + public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class); - @Override - protected void setUp() throws Exception { - super.setUp(); - Context context = getInstrumentation().getTargetContext(); + @Before + public void setUp() throws IOException { + Intents.init(); + Context context = mActivityRule.getActivity(); uiTestUtils = new UITestUtils(context); uiTestUtils.setup(); @@ -54,30 +73,26 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv // override first launch preference // do this BEFORE calling getActivity()! - prefs = getInstrumentation().getTargetContext().getSharedPreferences(MainActivity.PREF_NAME, Context.MODE_PRIVATE); + prefs = context.getSharedPreferences(MainActivity.PREF_NAME, Context.MODE_PRIVATE); prefs.edit().putBoolean(MainActivity.PREF_IS_FIRST_LAUNCH, false).commit(); - solo = new Solo(getInstrumentation(), getActivity()); + solo = new Solo(getInstrumentation(), mActivityRule.getActivity()); } - @Override - protected void tearDown() throws Exception { + @After + public void tearDown() throws Exception { uiTestUtils.tearDown(); solo.finishOpenedActivities(); - + Intents.release(); PodDBAdapter.deleteDatabase(); - - // reset preferences prefs.edit().clear().commit(); - - super.tearDown(); } private void openNavDrawer() { - solo.clickOnImageButton(0); - getInstrumentation().waitForIdleSync(); + onView(withId(R.id.drawer_layout)).perform(DrawerActions.open()); } + @Test public void testAddFeed() throws Exception { uiTestUtils.addHostedFeedData(); final Feed feed = uiTestUtils.hostedFeeds.get(0); @@ -89,10 +104,12 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv solo.waitForView(R.id.butSubscribe); assertEquals(solo.getString(R.string.subscribe_label), solo.getButton(0).getText().toString()); solo.clickOnButton(0); - solo.waitForText(solo.getString(R.string.subscribed_label)); + assertTrue(solo.waitForText(solo.getString(R.string.open_podcast), 0, Timeout.getLargeTimeout(), false)); } - @FlakyTest(tolerance = 3) + + @Test + @FlakyTest public void testClickNavDrawer() throws Exception { uiTestUtils.addLocalFeedData(false); @@ -150,57 +167,60 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv return ((MainActivity) solo.getCurrentActivity()).getSupportActionBar().getTitle().toString(); } - @SuppressWarnings("unchecked") - @FlakyTest(tolerance = 3) + + @Test + @FlakyTest public void testGoToPreferences() { openNavDrawer(); - solo.clickOnText(solo.getString(R.string.settings_label)); - solo.waitForActivity(PreferenceActivity.class); + onView(withText(R.string.settings_label)).perform(click()); + intended(hasComponent(PreferenceActivity.class.getName())); } + @Test public void testDrawerPreferencesHideSomeElements() { UserPreferences.setHiddenDrawerItems(new ArrayList<>()); openNavDrawer(); - solo.clickLongOnText(solo.getString(R.string.queue_label)); - solo.waitForDialogToOpen(); - solo.clickOnText(solo.getString(R.string.episodes_label)); - solo.clickOnText(solo.getString(R.string.playback_history_label)); - solo.clickOnText(solo.getString(R.string.confirm_label)); - solo.waitForDialogToClose(); + onView(first(withText(R.string.queue_label))).perform(longClick()); + onView(withText(R.string.episodes_label)).perform(click()); + onView(withText(R.string.playback_history_label)).perform(click()); + onView(withText(R.string.confirm_label)).perform(click()); + List<String> hidden = UserPreferences.getHiddenDrawerItems(); assertEquals(2, hidden.size()); assertTrue(hidden.contains(EpisodesFragment.TAG)); assertTrue(hidden.contains(PlaybackHistoryFragment.TAG)); } + @Test public void testDrawerPreferencesUnhideSomeElements() { List<String> hidden = Arrays.asList(PlaybackHistoryFragment.TAG, DownloadsFragment.TAG); UserPreferences.setHiddenDrawerItems(hidden); openNavDrawer(); - solo.clickLongOnText(solo.getString(R.string.queue_label)); - solo.waitForDialogToOpen(); - solo.clickOnText(solo.getString(R.string.downloads_label)); - solo.clickOnText(solo.getString(R.string.queue_label)); - solo.clickOnText(solo.getString(R.string.confirm_label)); - solo.waitForDialogToClose(); + onView(first(withText(R.string.queue_label))).perform(longClick()); + + onView(withText(R.string.downloads_label)).perform(click()); + onView(withText(R.string.queue_label)).perform(click()); + onView(withText(R.string.confirm_label)).perform(click()); + hidden = UserPreferences.getHiddenDrawerItems(); assertEquals(2, hidden.size()); assertTrue(hidden.contains(QueueFragment.TAG)); assertTrue(hidden.contains(PlaybackHistoryFragment.TAG)); } + + @Test public void testDrawerPreferencesHideAllElements() { UserPreferences.setHiddenDrawerItems(new ArrayList<>()); - String[] titles = getInstrumentation().getTargetContext().getResources().getStringArray(R.array.nav_drawer_titles); + String[] titles = mActivityRule.getActivity().getResources().getStringArray(R.array.nav_drawer_titles); openNavDrawer(); - solo.clickLongOnText(solo.getString(R.string.queue_label)); - solo.waitForDialogToOpen(); + onView(first(withText(R.string.queue_label))).perform(longClick()); for (String title : titles) { - solo.clickOnText(title); + onView(first(withText(title))).perform(click()); } - solo.clickOnText(solo.getString(R.string.confirm_label)); - solo.waitForDialogToClose(); + onView(withText(R.string.confirm_label)).perform(click()); + List<String> hidden = UserPreferences.getHiddenDrawerItems(); assertEquals(titles.length, hidden.size()); for (String tag : MainActivity.NAV_DRAWER_TAGS) { @@ -208,21 +228,85 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv } } + @Test public void testDrawerPreferencesHideCurrentElement() { UserPreferences.setHiddenDrawerItems(new ArrayList<>()); - openNavDrawer(); - String downloads = solo.getString(R.string.downloads_label); - solo.clickOnText(downloads); - solo.waitForView(android.R.id.list); + onView(withText(R.string.downloads_label)).perform(click()); openNavDrawer(); - solo.clickLongOnText(downloads); - solo.waitForDialogToOpen(); - solo.clickOnText(downloads); - solo.clickOnText(solo.getString(R.string.confirm_label)); - solo.waitForDialogToClose(); + + onView(first(withText(R.string.queue_label))).perform(longClick()); + onView(first(withText(R.string.downloads_label))).perform(click()); + onView(withText(R.string.confirm_label)).perform(click()); + List<String> hidden = UserPreferences.getHiddenDrawerItems(); assertEquals(1, hidden.size()); assertTrue(hidden.contains(DownloadsFragment.TAG)); } + + @Test + public void testBackButtonBehaviorGoToPage() { + openNavDrawer(); + solo.clickOnText(solo.getString(R.string.settings_label)); + solo.clickOnText(solo.getString(R.string.user_interface_label)); + solo.clickOnText(solo.getString(R.string.pref_back_button_behavior_title)); + solo.clickOnText(solo.getString(R.string.back_button_go_to_page)); + solo.waitForDialogToOpen(); + solo.clickOnText(solo.getString(R.string.subscriptions_label)); + solo.clickOnText(solo.getString(R.string.confirm_label)); + solo.goBackToActivity(MainActivity.class.getSimpleName()); + solo.goBack(); + assertEquals(solo.getString(R.string.subscriptions_label), getActionbarTitle()); + } + + @Test + public void testBackButtonBehaviorOpenDrawer() { + openNavDrawer(); + solo.clickOnText(solo.getString(R.string.settings_label)); + solo.clickOnText(solo.getString(R.string.user_interface_label)); + solo.clickOnText(solo.getString(R.string.pref_back_button_behavior_title)); + solo.clickOnText(solo.getString(R.string.back_button_open_drawer)); + solo.goBackToActivity(MainActivity.class.getSimpleName()); + solo.goBack(); + assertTrue(((MainActivity)solo.getCurrentActivity()).isDrawerOpen()); + } + + @Test + public void testBackButtonBehaviorDoubleTap() { + openNavDrawer(); + solo.clickOnText(solo.getString(R.string.settings_label)); + solo.clickOnText(solo.getString(R.string.user_interface_label)); + solo.clickOnText(solo.getString(R.string.pref_back_button_behavior_title)); + solo.clickOnText(solo.getString(R.string.back_button_double_tap)); + solo.goBackToActivity(MainActivity.class.getSimpleName()); + solo.goBack(); + solo.goBack(); + assertTrue(solo.getCurrentActivity().isFinishing()); + } + + @Test + public void testBackButtonBehaviorPrompt() { + openNavDrawer(); + solo.clickOnText(solo.getString(R.string.settings_label)); + solo.clickOnText(solo.getString(R.string.user_interface_label)); + solo.clickOnText(solo.getString(R.string.pref_back_button_behavior_title)); + solo.clickOnText(solo.getString(R.string.back_button_show_prompt)); + solo.goBackToActivity(MainActivity.class.getSimpleName()); + solo.goBack(); + solo.clickOnText(solo.getString(R.string.yes)); + solo.waitForDialogToClose(); + assertTrue(solo.getCurrentActivity().isFinishing()); + } + + @Test + public void testBackButtonBehaviorDefault() { + openNavDrawer(); + solo.clickOnText(solo.getString(R.string.settings_label)); + solo.clickOnText(solo.getString(R.string.user_interface_label)); + solo.clickOnText(solo.getString(R.string.pref_back_button_behavior_title)); + solo.clickOnText(solo.getString(R.string.back_button_default)); + solo.goBackToActivity(MainActivity.class.getSimpleName()); + solo.goBack(); + assertTrue(solo.getCurrentActivity().isFinishing()); + } } diff --git a/app/src/androidTest/java/de/test/antennapod/ui/PlaybackSonicTest.java b/app/src/androidTest/java/de/test/antennapod/ui/PlaybackSonicTest.java index 293ed2848..55ed998bb 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/PlaybackSonicTest.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/PlaybackSonicTest.java @@ -59,7 +59,7 @@ public class PlaybackSonicTest extends ActivityInstrumentationTestCase2<MainActi .clear() .putBoolean(UserPreferences.PREF_UNPAUSE_ON_HEADSET_RECONNECT, false) .putBoolean(UserPreferences.PREF_PAUSE_ON_HEADSET_DISCONNECT, false) - .putBoolean(UserPreferences.PREF_SONIC, true) + .putString(UserPreferences.PREF_MEDIA_PLAYER, "sonic") .commit(); solo = new Solo(getInstrumentation(), getActivity()); diff --git a/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java b/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java index 9a5ea437c..d934bf3e2 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java @@ -1,12 +1,23 @@ package de.test.antennapod.ui; -import android.content.Context; +import android.content.SharedPreferences; import android.content.res.Resources; -import android.test.ActivityInstrumentationTestCase2; +import android.preference.PreferenceManager; +import android.support.test.espresso.contrib.RecyclerViewActions; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; +import android.view.View; import com.robotium.solo.Solo; import com.robotium.solo.Timeout; +import org.hamcrest.Matcher; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + import java.util.Arrays; import java.util.concurrent.TimeUnit; @@ -17,36 +28,48 @@ import de.danoeh.antennapod.core.storage.APCleanupAlgorithm; import de.danoeh.antennapod.core.storage.APNullCleanupAlgorithm; import de.danoeh.antennapod.core.storage.APQueueCleanupAlgorithm; import de.danoeh.antennapod.core.storage.EpisodeCleanupAlgorithm; - -public class PreferencesTest extends ActivityInstrumentationTestCase2<PreferenceActivity> { - - private static final String TAG = "PreferencesTest"; - +import de.danoeh.antennapod.fragment.EpisodesFragment; +import de.danoeh.antennapod.fragment.QueueFragment; +import de.danoeh.antennapod.fragment.SubscriptionFragment; + +import static android.support.test.InstrumentationRegistry.getInstrumentation; +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.action.ViewActions.click; +import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static android.support.test.espresso.matcher.ViewMatchers.withText; +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertTrue; + +@RunWith(AndroidJUnit4.class) +public class PreferencesTest { private Solo solo; - private Context context; private Resources res; + private SharedPreferences prefs; - public PreferencesTest() { - super(PreferenceActivity.class); - } + @Rule + public ActivityTestRule<PreferenceActivity> mActivityRule = new ActivityTestRule<>(PreferenceActivity.class); - @Override - public void setUp() throws Exception { - super.setUp(); - solo = new Solo(getInstrumentation(), getActivity()); + @Before + public void setUp() { + solo = new Solo(getInstrumentation(), mActivityRule.getActivity()); Timeout.setSmallTimeout(500); Timeout.setLargeTimeout(1000); - context = getInstrumentation().getTargetContext(); - res = getActivity().getResources(); - UserPreferences.init(context); + res = mActivityRule.getActivity().getResources(); + UserPreferences.init(mActivityRule.getActivity()); + + prefs = PreferenceManager.getDefaultSharedPreferences(mActivityRule.getActivity()); + prefs.edit().clear(); + prefs.edit().putBoolean(UserPreferences.PREF_ENABLE_AUTODL, true).commit(); } - @Override - public void tearDown() throws Exception { + @After + public void tearDown() { solo.finishOpenedActivities(); - super.tearDown(); + prefs.edit().clear(); } + @Test public void testSwitchTheme() { final int theme = UserPreferences.getTheme(); int otherTheme; @@ -55,13 +78,13 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference } else { otherTheme = R.string.pref_theme_title_light; } - solo.clickOnText(solo.getString(R.string.user_interface_label)); - solo.clickOnText(solo.getString(R.string.pref_set_theme_title)); - solo.waitForDialogToOpen(); - solo.clickOnText(solo.getString(otherTheme)); + clickPreference(withText(R.string.user_interface_label)); + clickPreference(withText(R.string.pref_set_theme_title)); + onView(withText(otherTheme)).perform(click()); assertTrue(solo.waitForCondition(() -> UserPreferences.getTheme() != theme, Timeout.getLargeTimeout())); } + @Test public void testSwitchThemeBack() { final int theme = UserPreferences.getTheme(); int otherTheme; @@ -70,33 +93,23 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference } else { otherTheme = R.string.pref_theme_title_light; } - solo.clickOnText(solo.getString(R.string.user_interface_label)); - solo.clickOnText(solo.getString(R.string.pref_set_theme_title)); - solo.waitForDialogToOpen(1000); - solo.clickOnText(solo.getString(otherTheme)); + clickPreference(withText(R.string.user_interface_label)); + clickPreference(withText(R.string.pref_set_theme_title)); + onView(withText(otherTheme)).perform(click()); assertTrue(solo.waitForCondition(() -> UserPreferences.getTheme() != theme, Timeout.getLargeTimeout())); } - public void testExpandNotification() { - solo.clickOnText(solo.getString(R.string.user_interface_label)); - final int priority = UserPreferences.getNotifyPriority(); - solo.clickOnText(solo.getString(R.string.pref_expandNotify_title)); - assertTrue(solo.waitForCondition(() -> priority != UserPreferences.getNotifyPriority(), Timeout.getLargeTimeout())); - solo.clickOnText(solo.getString(R.string.pref_expandNotify_title)); - assertTrue(solo.waitForCondition(() -> priority == UserPreferences.getNotifyPriority(), Timeout.getLargeTimeout())); - } - + @Test public void testEnablePersistentPlaybackControls() { - solo.clickOnText(solo.getString(R.string.user_interface_label)); final boolean persistNotify = UserPreferences.isPersistNotify(); - solo.scrollDown(); - solo.scrollDown(); - solo.clickOnText(solo.getString(R.string.pref_persistNotify_title)); + clickPreference(withText(R.string.user_interface_label)); + clickPreference(withText(R.string.pref_persistNotify_title)); assertTrue(solo.waitForCondition(() -> persistNotify != UserPreferences.isPersistNotify(), Timeout.getLargeTimeout())); - solo.clickOnText(solo.getString(R.string.pref_persistNotify_title)); + clickPreference(withText(R.string.pref_persistNotify_title)); assertTrue(solo.waitForCondition(() -> persistNotify == UserPreferences.isPersistNotify(), Timeout.getLargeTimeout())); } + @Test public void testSetLockscreenButtons() { solo.clickOnText(solo.getString(R.string.user_interface_label)); solo.scrollDown(); @@ -123,6 +136,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference assertTrue(solo.waitForCondition(() -> !UserPreferences.showSkipOnCompactNotification(), Timeout.getLargeTimeout())); } + @Test public void testEnqueueAtFront() { solo.clickOnText(solo.getString(R.string.playback_pref)); final boolean enqueueAtFront = UserPreferences.enqueueAtFront(); @@ -134,6 +148,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference assertTrue(solo.waitForCondition(() -> enqueueAtFront == UserPreferences.enqueueAtFront(), Timeout.getLargeTimeout())); } + @Test public void testHeadPhonesDisconnect() { solo.clickOnText(solo.getString(R.string.playback_pref)); final boolean pauseOnHeadsetDisconnect = UserPreferences.isPauseOnHeadsetDisconnect(); @@ -143,6 +158,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference assertTrue(solo.waitForCondition(() -> pauseOnHeadsetDisconnect == UserPreferences.isPauseOnHeadsetDisconnect(), Timeout.getLargeTimeout())); } + @Test public void testHeadPhonesReconnect() { solo.clickOnText(solo.getString(R.string.playback_pref)); if(UserPreferences.isPauseOnHeadsetDisconnect() == false) { @@ -156,6 +172,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference assertTrue(solo.waitForCondition(() -> unpauseOnHeadsetReconnect == UserPreferences.isUnpauseOnHeadsetReconnect(), Timeout.getLargeTimeout())); } + @Test public void testBluetoothReconnect() { solo.clickOnText(solo.getString(R.string.playback_pref)); if(UserPreferences.isPauseOnHeadsetDisconnect() == false) { @@ -169,6 +186,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference assertTrue(solo.waitForCondition(() -> unpauseOnBluetoothReconnect == UserPreferences.isUnpauseOnBluetoothReconnect(), Timeout.getLargeTimeout())); } + @Test public void testContinuousPlayback() { solo.clickOnText(solo.getString(R.string.playback_pref)); final boolean continuousPlayback = UserPreferences.isFollowQueue(); @@ -180,6 +198,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference assertTrue(solo.waitForCondition(() -> continuousPlayback == UserPreferences.isFollowQueue(), Timeout.getLargeTimeout())); } + @Test public void testAutoDelete() { solo.clickOnText(solo.getString(R.string.storage_pref)); final boolean autoDelete = UserPreferences.isAutoDelete(); @@ -189,17 +208,15 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference assertTrue(solo.waitForCondition(() -> autoDelete == UserPreferences.isAutoDelete(), Timeout.getLargeTimeout())); } + @Test public void testPlaybackSpeeds() { - solo.clickOnText(solo.getString(R.string.playback_pref)); - solo.scrollDown(); - solo.scrollDown(); - solo.clickOnText(solo.getString(R.string.pref_playback_speed_title)); - solo.waitForDialogToOpen(1000); + clickPreference(withText(R.string.playback_pref)); + clickPreference(withText(R.string.pref_playback_speed_title)); assertTrue(solo.searchText(res.getStringArray(R.array.playback_speed_values)[0])); - solo.clickOnText(solo.getString(R.string.cancel_label)); - solo.waitForDialogToClose(1000); + onView(withText(R.string.cancel_label)).perform(click()); } + @Test public void testPauseForInterruptions() { solo.clickOnText(solo.getString(R.string.playback_pref)); final boolean pauseForFocusLoss = UserPreferences.shouldPauseForFocusLoss(); @@ -209,6 +226,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference assertTrue(solo.waitForCondition(() -> pauseForFocusLoss == UserPreferences.shouldPauseForFocusLoss(), Timeout.getLargeTimeout())); } + @Test public void testDisableUpdateInterval() { solo.clickOnText(solo.getString(R.string.network_pref)); solo.clickOnText(solo.getString(R.string.pref_autoUpdateIntervallOrTime_sum)); @@ -217,31 +235,31 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference assertTrue(solo.waitForCondition(() -> UserPreferences.getUpdateInterval() == 0, 1000)); } + @Test public void testSetUpdateInterval() { - solo.clickOnText(solo.getString(R.string.network_pref)); - solo.clickOnText(solo.getString(R.string.pref_autoUpdateIntervallOrTime_title)); - solo.waitForDialogToOpen(); - solo.clickOnText(solo.getString(R.string.pref_autoUpdateIntervallOrTime_Interval)); - solo.waitForDialogToOpen(); + clickPreference(withText(R.string.network_pref)); + clickPreference(withText(R.string.pref_autoUpdateIntervallOrTime_title)); + onView(withText(R.string.pref_autoUpdateIntervallOrTime_Interval)).perform(click()); String search = "12 " + solo.getString(R.string.pref_update_interval_hours_plural); - solo.clickOnText(search); - solo.waitForDialogToClose(); + onView(withText(search)).perform(click()); assertTrue(solo.waitForCondition(() -> UserPreferences.getUpdateInterval() == TimeUnit.HOURS.toMillis(12), Timeout.getLargeTimeout())); } + @Test public void testMobileUpdates() { - solo.clickOnText(solo.getString(R.string.network_pref)); + clickPreference(withText(R.string.network_pref)); final boolean mobileUpdates = UserPreferences.isAllowMobileUpdate(); - solo.clickOnText(solo.getString(R.string.pref_mobileUpdate_title)); + clickPreference(withText(R.string.pref_mobileUpdate_title)); assertTrue(solo.waitForCondition(() -> mobileUpdates != UserPreferences.isAllowMobileUpdate(), Timeout.getLargeTimeout())); - solo.clickOnText(solo.getString(R.string.pref_mobileUpdate_title)); + clickPreference(withText(R.string.pref_mobileUpdate_title)); assertTrue(solo.waitForCondition(() -> mobileUpdates == UserPreferences.isAllowMobileUpdate(), Timeout.getLargeTimeout())); } + @Test public void testSetSequentialDownload() { - solo.clickOnText(solo.getString(R.string.network_pref)); - solo.clickOnText(solo.getString(R.string.pref_parallel_downloads_title)); + clickPreference(withText(R.string.network_pref)); + clickPreference(withText(R.string.pref_parallel_downloads_title)); solo.waitForDialogToOpen(); solo.clearEditText(0); solo.enterText(0, "1"); @@ -249,9 +267,10 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference assertTrue(solo.waitForCondition(() -> UserPreferences.getParallelDownloads() == 1, Timeout.getLargeTimeout())); } + @Test public void testSetParallelDownloads() { - solo.clickOnText(solo.getString(R.string.network_pref)); - solo.clickOnText(solo.getString(R.string.pref_parallel_downloads_title)); + clickPreference(withText(R.string.network_pref)); + clickPreference(withText(R.string.pref_parallel_downloads_title)); solo.waitForDialogToOpen(); solo.clearEditText(0); solo.enterText(0, "10"); @@ -259,50 +278,50 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference assertTrue(solo.waitForCondition(() -> UserPreferences.getParallelDownloads() == 10, Timeout.getLargeTimeout())); } + @Test public void testSetParallelDownloadsInvalidInput() { - solo.clickOnText(solo.getString(R.string.network_pref)); - solo.clickOnText(solo.getString(R.string.pref_parallel_downloads_title)); + clickPreference(withText(R.string.network_pref)); + clickPreference(withText(R.string.pref_parallel_downloads_title)); solo.waitForDialogToOpen(); solo.clearEditText(0); solo.enterText(0, "0"); - assertEquals("1", solo.getEditText(0).getText().toString()); + assertEquals("", solo.getEditText(0).getText().toString()); solo.clearEditText(0); solo.enterText(0, "100"); - assertEquals("50", solo.getEditText(0).getText().toString()); + assertEquals("", solo.getEditText(0).getText().toString()); } + @Test public void testSetEpisodeCache() { String[] entries = res.getStringArray(R.array.episode_cache_size_entries); String[] values = res.getStringArray(R.array.episode_cache_size_values); String entry = entries[entries.length/2]; final int value = Integer.valueOf(values[values.length/2]); - solo.clickOnText(solo.getString(R.string.network_pref)); - solo.clickOnText(solo.getString(R.string.pref_automatic_download_title)); - solo.waitForText(solo.getString(R.string.pref_automatic_download_title)); - solo.clickOnText(solo.getString(R.string.pref_episode_cache_title)); + clickPreference(withText(R.string.network_pref)); + clickPreference(withText(R.string.pref_automatic_download_title)); + clickPreference(withText(R.string.pref_episode_cache_title)); solo.waitForDialogToOpen(); solo.clickOnText(entry); assertTrue(solo.waitForCondition(() -> UserPreferences.getEpisodeCacheSize() == value, Timeout.getLargeTimeout())); } + @Test public void testSetEpisodeCacheMin() { String[] entries = res.getStringArray(R.array.episode_cache_size_entries); String[] values = res.getStringArray(R.array.episode_cache_size_values); String minEntry = entries[0]; final int minValue = Integer.valueOf(values[0]); - solo.clickOnText(solo.getString(R.string.network_pref)); - solo.clickOnText(solo.getString(R.string.pref_automatic_download_title)); - solo.waitForText(solo.getString(R.string.pref_automatic_download_title)); - if(!UserPreferences.isEnableAutodownload()) { - solo.clickOnText(solo.getString(R.string.pref_automatic_download_title)); - } - solo.clickOnText(solo.getString(R.string.pref_episode_cache_title)); + + clickPreference(withText(R.string.network_pref)); + clickPreference(withText(R.string.pref_automatic_download_title)); + clickPreference(withText(R.string.pref_episode_cache_title)); solo.waitForDialogToOpen(1000); solo.scrollUp(); solo.clickOnText(minEntry); assertTrue(solo.waitForCondition(() -> UserPreferences.getEpisodeCacheSize() == minValue, Timeout.getLargeTimeout())); } + @Test public void testSetEpisodeCacheMax() { String[] entries = res.getStringArray(R.array.episode_cache_size_entries); String[] values = res.getStringArray(R.array.episode_cache_size_values); @@ -311,24 +330,22 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference solo.clickOnText(solo.getString(R.string.network_pref)); solo.clickOnText(solo.getString(R.string.pref_automatic_download_title)); solo.waitForText(solo.getString(R.string.pref_automatic_download_title)); - if(!UserPreferences.isEnableAutodownload()) { - solo.clickOnText(solo.getString(R.string.pref_automatic_download_title)); - } solo.clickOnText(solo.getString(R.string.pref_episode_cache_title)); solo.waitForDialogToOpen(); solo.clickOnText(maxEntry); assertTrue(solo.waitForCondition(() -> UserPreferences.getEpisodeCacheSize() == maxValue, Timeout.getLargeTimeout())); } + @Test public void testAutomaticDownload() { final boolean automaticDownload = UserPreferences.isEnableAutodownload(); - solo.clickOnText(solo.getString(R.string.network_pref)); - solo.clickOnText(solo.getString(R.string.pref_automatic_download_title)); - solo.waitForText(solo.getString(R.string.pref_automatic_download_title)); - solo.clickOnText(solo.getString(R.string.pref_automatic_download_title)); + clickPreference(withText(R.string.network_pref)); + clickPreference(withText(R.string.pref_automatic_download_title)); + clickPreference(withText(R.string.pref_automatic_download_title)); + assertTrue(solo.waitForCondition(() -> automaticDownload != UserPreferences.isEnableAutodownload(), Timeout.getLargeTimeout())); if(UserPreferences.isEnableAutodownload() == false) { - solo.clickOnText(solo.getString(R.string.pref_automatic_download_title)); + clickPreference(withText(R.string.pref_automatic_download_title)); } assertTrue(solo.waitForCondition(() -> UserPreferences.isEnableAutodownload() == true, Timeout.getLargeTimeout())); final boolean enableAutodownloadOnBattery = UserPreferences.isEnableAutodownloadOnBattery(); @@ -343,6 +360,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference assertTrue(solo.waitForCondition(() -> enableWifiFilter == UserPreferences.isEnableAutodownloadWifiFilter(), Timeout.getLargeTimeout())); } + @Test public void testEpisodeCleanupQueueOnly() { solo.clickOnText(solo.getString(R.string.network_pref)); solo.clickOnText(solo.getString(R.string.pref_automatic_download_title)); @@ -356,6 +374,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference Timeout.getLargeTimeout())); } + @Test public void testEpisodeCleanupNeverAlg() { solo.clickOnText(solo.getString(R.string.network_pref)); solo.clickOnText(solo.getString(R.string.pref_automatic_download_title)); @@ -369,6 +388,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference Timeout.getLargeTimeout())); } + @Test public void testEpisodeCleanupClassic() { solo.clickOnText(solo.getString(R.string.network_pref)); solo.clickOnText(solo.getString(R.string.pref_automatic_download_title)); @@ -379,39 +399,39 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference EpisodeCleanupAlgorithm alg = UserPreferences.getEpisodeCleanupAlgorithm(); if (alg instanceof APCleanupAlgorithm) { APCleanupAlgorithm cleanupAlg = (APCleanupAlgorithm)alg; - return cleanupAlg.getNumberOfDaysAfterPlayback() == 0; + return cleanupAlg.getNumberOfHoursAfterPlayback() == 0; } return false; }, Timeout.getLargeTimeout())); } + @Test public void testEpisodeCleanupNumDays() { - solo.clickOnText(solo.getString(R.string.network_pref)); - solo.clickOnText(solo.getString(R.string.pref_automatic_download_title)); - solo.clickOnText(solo.getString(R.string.pref_episode_cleanup_title)); - solo.waitForText(solo.getString(R.string.episode_cleanup_after_listening)); - solo.clickOnText("5"); + clickPreference(withText(R.string.network_pref)); + clickPreference(withText(R.string.pref_automatic_download_title)); + clickPreference(withText(R.string.pref_episode_cleanup_title)); + solo.waitForDialogToOpen(); + String search = res.getQuantityString(R.plurals.episode_cleanup_days_after_listening, 5, 5); + onView(withText(search)).perform(click()); assertTrue(solo.waitForCondition(() -> { EpisodeCleanupAlgorithm alg = UserPreferences.getEpisodeCleanupAlgorithm(); if (alg instanceof APCleanupAlgorithm) { APCleanupAlgorithm cleanupAlg = (APCleanupAlgorithm)alg; - return cleanupAlg.getNumberOfDaysAfterPlayback() == 5; + return cleanupAlg.getNumberOfHoursAfterPlayback() == 120; // 5 days } return false; }, Timeout.getLargeTimeout())); } - + @Test public void testRewindChange() { int seconds = UserPreferences.getRewindSecs(); int deltas[] = res.getIntArray(R.array.seek_delta_values); - solo.clickOnText(solo.getString(R.string.playback_pref)); - solo.scrollDown(); - solo.scrollDown(); - solo.clickOnText(solo.getString(R.string.pref_rewind)); + clickPreference(withText(R.string.playback_pref)); + clickPreference(withText(R.string.pref_rewind)); solo.waitForDialogToOpen(); int currentIndex = Arrays.binarySearch(deltas, seconds); @@ -419,24 +439,22 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference // Find next value (wrapping around to next) int newIndex = (currentIndex + 1) % deltas.length; - - solo.clickOnText(String.valueOf(deltas[newIndex]) + " seconds"); - solo.clickOnButton("Confirm"); + onView(withText(String.valueOf(deltas[newIndex]) + " seconds")).perform(click()); + onView(withText("Confirm")).perform(click()); solo.waitForDialogToClose(); assertTrue(solo.waitForCondition(() -> UserPreferences.getRewindSecs() == deltas[newIndex], Timeout.getLargeTimeout())); } + @Test public void testFastForwardChange() { - solo.clickOnText(solo.getString(R.string.playback_pref)); - solo.scrollDown(); - solo.scrollDown(); + clickPreference(withText(R.string.playback_pref)); for (int i = 2; i > 0; i--) { // repeat twice to catch any error where fastforward is tracking rewind int seconds = UserPreferences.getFastForwardSecs(); int deltas[] = res.getIntArray(R.array.seek_delta_values); - solo.clickOnText(solo.getString(R.string.pref_fast_forward)); + clickPreference(withText(R.string.pref_fast_forward)); solo.waitForDialogToOpen(); int currentIndex = Arrays.binarySearch(deltas, seconds); @@ -445,12 +463,66 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference // Find next value (wrapping around to next) int newIndex = (currentIndex + 1) % deltas.length; - solo.clickOnText(String.valueOf(deltas[newIndex]) + " seconds"); - solo.clickOnButton("Confirm"); + onView(withText(String.valueOf(deltas[newIndex]) + " seconds")).perform(click()); + onView(withText("Confirm")).perform(click()); solo.waitForDialogToClose(); assertTrue(solo.waitForCondition(() -> UserPreferences.getFastForwardSecs() == deltas[newIndex], Timeout.getLargeTimeout())); } } + + @Test + public void testBackButtonBehaviorGoToPageSelector() { + clickPreference(withText(R.string.user_interface_label)); + clickPreference(withText(R.string.pref_back_button_behavior_title)); + solo.waitForDialogToOpen(); + solo.clickOnText(solo.getString(R.string.back_button_go_to_page)); + solo.waitForDialogToOpen(); + solo.clickOnText(solo.getString(R.string.queue_label)); + solo.clickOnText(solo.getString(R.string.confirm_label)); + assertTrue(solo.waitForCondition(() -> UserPreferences.getBackButtonBehavior() == UserPreferences.BackButtonBehavior.GO_TO_PAGE, + Timeout.getLargeTimeout())); + assertTrue(solo.waitForCondition(() -> UserPreferences.getBackButtonGoToPage().equals(QueueFragment.TAG), + Timeout.getLargeTimeout())); + clickPreference(withText(R.string.pref_back_button_behavior_title)); + solo.waitForDialogToOpen(); + solo.clickOnText(solo.getString(R.string.back_button_go_to_page)); + solo.waitForDialogToOpen(); + solo.clickOnText(solo.getString(R.string.episodes_label)); + solo.clickOnText(solo.getString(R.string.confirm_label)); + assertTrue(solo.waitForCondition(() -> UserPreferences.getBackButtonBehavior() == UserPreferences.BackButtonBehavior.GO_TO_PAGE, + Timeout.getLargeTimeout())); + assertTrue(solo.waitForCondition(() -> UserPreferences.getBackButtonGoToPage().equals(EpisodesFragment.TAG), + Timeout.getLargeTimeout())); + clickPreference(withText(R.string.pref_back_button_behavior_title)); + solo.waitForDialogToOpen(); + solo.clickOnText(solo.getString(R.string.back_button_go_to_page)); + solo.waitForDialogToOpen(); + solo.clickOnText(solo.getString(R.string.subscriptions_label)); + solo.clickOnText(solo.getString(R.string.confirm_label)); + assertTrue(solo.waitForCondition(() -> UserPreferences.getBackButtonBehavior() == UserPreferences.BackButtonBehavior.GO_TO_PAGE, + Timeout.getLargeTimeout())); + assertTrue(solo.waitForCondition(() -> UserPreferences.getBackButtonGoToPage().equals(SubscriptionFragment.TAG), + Timeout.getLargeTimeout())); + } + + @Test + public void testDeleteRemovesFromQueue() { + clickPreference(withText(R.string.storage_pref)); + if (!UserPreferences.shouldDeleteRemoveFromQueue()) { + clickPreference(withText(R.string.pref_delete_removes_from_queue_title)); + assertTrue(solo.waitForCondition(UserPreferences::shouldDeleteRemoveFromQueue, Timeout.getLargeTimeout())); + } + final boolean deleteRemovesFromQueue = UserPreferences.shouldDeleteRemoveFromQueue(); + solo.clickOnText(solo.getString(R.string.pref_delete_removes_from_queue_title)); + assertTrue(solo.waitForCondition(() -> deleteRemovesFromQueue != UserPreferences.shouldDeleteRemoveFromQueue(), Timeout.getLargeTimeout())); + solo.clickOnText(solo.getString(R.string.pref_delete_removes_from_queue_title)); + assertTrue(solo.waitForCondition(() -> deleteRemovesFromQueue == UserPreferences.shouldDeleteRemoveFromQueue(), Timeout.getLargeTimeout())); + } + + private void clickPreference(Matcher<View> matcher) { + onView(withId(R.id.list)) + .perform(RecyclerViewActions.actionOnItem(hasDescendant(matcher), click())); + } } diff --git a/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java b/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java index 3af22af9d..ff5374268 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java @@ -22,7 +22,6 @@ import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.core.event.QueueEvent; import de.danoeh.antennapod.core.feed.EventDistributor; import de.danoeh.antennapod.core.feed.Feed; -import de.danoeh.antennapod.core.feed.FeedImage; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.storage.PodDBAdapter; @@ -136,12 +135,9 @@ class UITestUtils { public void addHostedFeedData() throws IOException { if (feedDataHosted) throw new IllegalStateException("addHostedFeedData was called twice on the same instance"); for (int i = 0; i < NUM_FEEDS; i++) { - File bitmapFile = newBitmapFile("image" + i); - FeedImage image = new FeedImage(0, "image " + i, null, hostFile(bitmapFile), false); Feed feed = new Feed(0, null, "Title " + i, "http://example.com/" + i, "Description of feed " + i, - "http://example.com/pay/feed" + i, "author " + i, "en", Feed.TYPE_RSS2, "feed" + i, image, null, + "http://example.com/pay/feed" + i, "author " + i, "en", Feed.TYPE_RSS2, "feed" + i, null, null, "http://example.com/feed/src/" + i, false); - image.setOwner(feed); // create items List<FeedItem> items = new ArrayList<>(); @@ -187,12 +183,6 @@ class UITestUtils { List<FeedItem> queue = new ArrayList<>(); for (Feed feed : hostedFeeds) { feed.setDownloaded(true); - if (feed.getImage() != null) { - FeedImage image = feed.getImage(); - int fileId = Integer.parseInt(StringUtils.substringAfter(image.getDownload_url(), "files/")); - image.setFile_url(server.accessFile(fileId).getAbsolutePath()); - image.setDownloaded(true); - } if (downloadEpisodes) { for (FeedItem item : feed.getItems()) { if (item.hasMedia()) { diff --git a/app/src/androidTest/java/de/test/antennapod/ui/UITestUtilsTest.java b/app/src/androidTest/java/de/test/antennapod/ui/UITestUtilsTest.java index 53fd7d7fd..45ba472ff 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/UITestUtilsTest.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/UITestUtilsTest.java @@ -38,9 +38,6 @@ public class UITestUtilsTest extends InstrumentationTestCase { for (Feed feed : feeds) { testUrlReachable(feed.getDownload_url()); - if (feed.getImage() != null) { - testUrlReachable(feed.getImage().getDownload_url()); - } for (FeedItem item : feed.getItems()) { if (item.hasMedia()) { testUrlReachable(item.getMedia().getDownload_url()); @@ -66,9 +63,6 @@ public class UITestUtilsTest extends InstrumentationTestCase { for (Feed feed : uiTestUtils.hostedFeeds) { assertTrue(feed.getId() != 0); - if (feed.getImage() != null) { - assertTrue(feed.getImage().getId() != 0); - } for (FeedItem item : feed.getItems()) { assertTrue(item.getId() != 0); if (item.hasMedia()) { diff --git a/app/src/androidTest/java/de/test/antennapod/util/ConverterTest.java b/app/src/androidTest/java/de/test/antennapod/util/ConverterTest.java deleted file mode 100644 index 47fca41ba..000000000 --- a/app/src/androidTest/java/de/test/antennapod/util/ConverterTest.java +++ /dev/null @@ -1,35 +0,0 @@ -package de.test.antennapod.util; - -import android.test.AndroidTestCase; - -import de.danoeh.antennapod.core.util.Converter; - -/** - * Test class for converter - */ -public class ConverterTest extends AndroidTestCase { - - public void testGetDurationStringLong() throws Exception { - String expected = "13:05:10"; - int input = 47110000; - assertEquals(expected, Converter.getDurationStringLong(input)); - } - - public void testGetDurationStringShort() throws Exception { - String expected = "13:05"; - int input = 47110000; - assertEquals(expected, Converter.getDurationStringShort(input)); - } - - public void testDurationStringLongToMs() throws Exception { - String input = "01:20:30"; - long expected = 4830000; - assertEquals(expected, Converter.durationStringLongToMs(input)); - } - - public void testDurationStringShortToMs() throws Exception { - String input = "8:30"; - long expected = 30600000; - assertEquals(expected, Converter.durationStringShortToMs(input)); - } -} diff --git a/app/src/androidTest/java/de/test/antennapod/util/playback/TimelineTest.java b/app/src/androidTest/java/de/test/antennapod/util/playback/TimelineTest.java index 7e535e12c..4bef14cd9 100644 --- a/app/src/androidTest/java/de/test/antennapod/util/playback/TimelineTest.java +++ b/app/src/androidTest/java/de/test/antennapod/util/playback/TimelineTest.java @@ -30,12 +30,12 @@ public class TimelineTest extends InstrumentationTestCase { context = getInstrumentation().getTargetContext(); } - private Playable newTestPlayable(List<Chapter> chapters, String shownotes) { + private Playable newTestPlayable(List<Chapter> chapters, String shownotes, int duration) { FeedItem item = new FeedItem(0, "Item", "item-id", "http://example.com/item", new Date(), FeedItem.PLAYED, null); item.setChapters(chapters); item.setContentEncoded(shownotes); FeedMedia media = new FeedMedia(item, "http://example.com/episode", 100, "audio/mp3"); - media.setDuration(Integer.MAX_VALUE); + media.setDuration(duration); item.setMedia(media); return media; } @@ -44,7 +44,17 @@ public class TimelineTest extends InstrumentationTestCase { final String timeStr = "10:11:12"; final long time = 3600 * 1000 * 10 + 60 * 1000 * 11 + 12 * 1000; - Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStr + " here.</p>"); + Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStr + " here.</p>", Integer.MAX_VALUE); + Timeline t = new Timeline(context, p); + String res = t.processShownotes(true); + checkLinkCorrect(res, new long[]{time}, new String[]{timeStr}); + } + + public void testProcessShownotesAddTimecodeHHMMSSMoreThen24HoursNoChapters() throws Exception { + final String timeStr = "25:00:00"; + final long time = 25 * 60 * 60 * 1000; + + Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStr + " here.</p>", Integer.MAX_VALUE); Timeline t = new Timeline(context, p); String res = t.processShownotes(true); checkLinkCorrect(res, new long[]{time}, new String[]{timeStr}); @@ -54,17 +64,67 @@ public class TimelineTest extends InstrumentationTestCase { final String timeStr = "10:11"; final long time = 3600 * 1000 * 10 + 60 * 1000 * 11; - Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStr + " here.</p>"); + Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStr + " here.</p>", Integer.MAX_VALUE); + Timeline t = new Timeline(context, p); + String res = t.processShownotes(true); + checkLinkCorrect(res, new long[]{time}, new String[]{timeStr}); + } + + public void testProcessShownotesAddTimecodeMMSSNoChapters() throws Exception { + final String timeStr = "10:11"; + final long time = 10 * 60 * 1000 + 11 * 1000; + + Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStr + " here.</p>", 11 * 60 * 1000); Timeline t = new Timeline(context, p); String res = t.processShownotes(true); checkLinkCorrect(res, new long[]{time}, new String[]{timeStr}); } + public void testProcessShownotesAddTimecodeHMMSSNoChapters() throws Exception { + final String timeStr = "2:11:12"; + final long time = 2 * 60 * 60 * 1000 + 11 * 60 * 1000 + 12 * 1000; + + Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStr + " here.</p>", Integer.MAX_VALUE); + Timeline t = new Timeline(context, p); + String res = t.processShownotes(true); + checkLinkCorrect(res, new long[]{time}, new String[]{timeStr}); + } + + public void testProcessShownotesAddTimecodeMSSNoChapters() throws Exception { + final String timeStr = "1:12"; + final long time = 60 * 1000 + 12 * 1000; + + Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStr + " here.</p>", 2 * 60 * 1000); + Timeline t = new Timeline(context, p); + String res = t.processShownotes(true); + checkLinkCorrect(res, new long[]{time}, new String[]{timeStr}); + } + + public void testProcessShownotesAddTimecodeMultipleFormatsNoChapters() throws Exception { + final String[] timeStrings = new String[]{ "10:12", "1:10:12" }; + + Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStrings[0] + " here. Hey look another one " + timeStrings[1] + " here!</p>", 2 * 60 * 60 * 1000); + Timeline t = new Timeline(context, p); + String res = t.processShownotes(true); + checkLinkCorrect(res, new long[]{ 10 * 60 * 1000 + 12 * 1000, 60 * 60 * 1000 + 10 * 60 * 1000 + 12 * 1000 }, timeStrings); + } + + public void testProcessShownotesAddTimecodeMultipleShortFormatNoChapters() throws Exception { + + // One of these timecodes fits as HH:MM and one does not so both should be parsed as MM:SS. + final String[] timeStrings = new String[]{ "10:12", "2:12" }; + + Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStrings[0] + " here. Hey look another one " + timeStrings[1] + " here!</p>", 3 * 60 * 60 * 1000); + Timeline t = new Timeline(context, p); + String res = t.processShownotes(true); + checkLinkCorrect(res, new long[]{ 10 * 60 * 1000 + 12 * 1000, 2 * 60 * 1000 + 12 * 1000 }, timeStrings); + } + public void testProcessShownotesAddTimecodeParentheses() throws Exception { final String timeStr = "10:11"; final long time = 3600 * 1000 * 10 + 60 * 1000 * 11; - Playable p = newTestPlayable(null, "<p> Some test text with a timecode (" + timeStr + ") here.</p>"); + Playable p = newTestPlayable(null, "<p> Some test text with a timecode (" + timeStr + ") here.</p>", Integer.MAX_VALUE); Timeline t = new Timeline(context, p); String res = t.processShownotes(true); checkLinkCorrect(res, new long[]{time}, new String[]{timeStr}); @@ -74,7 +134,7 @@ public class TimelineTest extends InstrumentationTestCase { final String timeStr = "10:11"; final long time = 3600 * 1000 * 10 + 60 * 1000 * 11; - Playable p = newTestPlayable(null, "<p> Some test text with a timecode [" + timeStr + "] here.</p>"); + Playable p = newTestPlayable(null, "<p> Some test text with a timecode [" + timeStr + "] here.</p>", Integer.MAX_VALUE); Timeline t = new Timeline(context, p); String res = t.processShownotes(true); checkLinkCorrect(res, new long[]{time}, new String[]{timeStr}); @@ -84,12 +144,27 @@ public class TimelineTest extends InstrumentationTestCase { final String timeStr = "10:11"; final long time = 3600 * 1000 * 10 + 60 * 1000 * 11; - Playable p = newTestPlayable(null, "<p> Some test text with a timecode <" + timeStr + "> here.</p>"); + Playable p = newTestPlayable(null, "<p> Some test text with a timecode <" + timeStr + "> here.</p>", Integer.MAX_VALUE); Timeline t = new Timeline(context, p); String res = t.processShownotes(true); checkLinkCorrect(res, new long[]{time}, new String[]{timeStr}); } + public void testProcessShownotesAndInvalidTimecode() throws Exception { + final String[] timeStrs = new String[] {"2:1", "0:0", "000", "00", "00:000"}; + + StringBuilder shownotes = new StringBuilder("<p> Some test text with timecodes "); + for (String timeStr : timeStrs) { + shownotes.append(timeStr).append(" "); + } + shownotes.append("here.</p>"); + + Playable p = newTestPlayable(null, shownotes.toString(), Integer.MAX_VALUE); + Timeline t = new Timeline(context, p); + String res = t.processShownotes(true); + checkLinkCorrect(res, new long[0], new String[0]); + } + private void checkLinkCorrect(String res, long[] timecodes, String[] timecodeStr) { assertNotNull(res); Document d = Jsoup.parse(res); diff --git a/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/AtomGenerator.java b/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/AtomGenerator.java index afe15f1b2..8d2408b45 100644 --- a/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/AtomGenerator.java +++ b/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/AtomGenerator.java @@ -56,6 +56,11 @@ public class AtomGenerator implements FeedGenerator{ xml.text(feed.getDescription()); xml.endTag(null, "subtitle"); } + if (feed.getImageUrl() != null) { + xml.startTag(null, "logo"); + xml.text(feed.getImageUrl()); + xml.endTag(null, "logo"); + } if (feed.getPaymentLink() != null) { GeneratorUtil.addPaymentLink(xml, feed.getPaymentLink(), false); diff --git a/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/GeneratorUtil.java b/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/GeneratorUtil.java index 7f6f0fb0f..89542d222 100644 --- a/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/GeneratorUtil.java +++ b/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/GeneratorUtil.java @@ -8,6 +8,7 @@ import java.io.IOException; * Utility methods for FeedGenerator */ class GeneratorUtil { + private GeneratorUtil(){} public static void addPaymentLink(XmlSerializer xml, String paymentLink, boolean withNamespace) throws IOException { String ns = (withNamespace) ? "http://www.w3.org/2005/Atom" : null; diff --git a/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/RSS2Generator.java b/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/RSS2Generator.java index f2d53799d..5f8b4d18c 100644 --- a/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/RSS2Generator.java +++ b/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/RSS2Generator.java @@ -54,6 +54,13 @@ public class RSS2Generator implements FeedGenerator{ xml.text(feed.getLanguage()); xml.endTag(null, "language"); } + if (feed.getImageUrl() != null) { + xml.startTag(null, "image"); + xml.startTag(null, "url"); + xml.text(feed.getImageUrl()); + xml.endTag(null, "url"); + xml.endTag(null, "image"); + } if (feed.getPaymentLink() != null) { GeneratorUtil.addPaymentLink(xml, feed.getPaymentLink(), true); diff --git a/app/src/free/play b/app/src/free/play new file mode 120000 index 000000000..e9d641154 --- /dev/null +++ b/app/src/free/play @@ -0,0 +1 @@ +../main/play
\ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c7541cb59..216afc6b7 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,14 +1,8 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="de.danoeh.antennapod" - android:installLocation="auto" - android:versionCode="1060595" - android:versionName="1.6.5"> - <!-- - Version code schema: - "1.2.3-SNAPSHOT" -> 1020300 - "1.2.3-RC4" -> 1020304 - --> + android:installLocation="auto"> + <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WAKE_LOCK"/> @@ -47,10 +41,13 @@ <activity android:name=".activity.SplashActivity" - android:configChanges="keyboardHidden|orientation|screenSize" - android:launchMode="singleTask" android:label="@string/app_name" + android:configChanges="keyboardHidden|orientation|screenSize" android:theme="@style/Theme.AntennaPod.Dark.Splash"> + <!-- android:launchMode="singleTask" removed for #2948, so that + when app is launched again, the app will go to the last activity users use + (if the app has been used recently, e.g., last 30 minutes), + rather than always go to MainActivity (launched by SplashActivity here) --> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> @@ -392,10 +389,6 @@ </provider> <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> diff --git a/app/src/main/assets/LICENSE_SIL.txt b/app/src/main/assets/LICENSE_SIL.txt new file mode 100644 index 000000000..f5ed6fa72 --- /dev/null +++ b/app/src/main/assets/LICENSE_SIL.txt @@ -0,0 +1,91 @@ +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE.
\ No newline at end of file diff --git a/app/src/main/assets/logo.png b/app/src/main/assets/logo.png Binary files differindex d0e988a6d..3b5261b28 100755 --- a/app/src/main/assets/logo.png +++ b/app/src/main/assets/logo.png diff --git a/app/src/main/java/de/danoeh/antennapod/PodcastApp.java b/app/src/main/java/de/danoeh/antennapod/PodcastApp.java index 3abf7557a..fde9af16f 100644 --- a/app/src/main/java/de/danoeh/antennapod/PodcastApp.java +++ b/app/src/main/java/de/danoeh/antennapod/PodcastApp.java @@ -20,7 +20,7 @@ public class PodcastApp extends Application { try { Class.forName("de.danoeh.antennapod.config.ClientConfigurator"); } catch (Exception e) { - throw new RuntimeException("ClientConfigurator not found"); + throw new RuntimeException("ClientConfigurator not found", e); } } diff --git a/app/src/main/java/de/danoeh/antennapod/activity/AboutActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/AboutActivity.java index 4d9b50073..ecfdf24b0 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/AboutActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/AboutActivity.java @@ -21,10 +21,10 @@ import java.nio.charset.Charset; import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.preferences.UserPreferences; -import rx.Single; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; +import io.reactivex.Single; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; /** * Displays the 'about' screen @@ -35,7 +35,7 @@ public class AboutActivity extends AppCompatActivity { private WebView webView; private LinearLayout webViewContainer; - private Subscription subscription; + private Disposable disposable; @Override protected void onCreate(Bundle savedInstanceState) { @@ -43,8 +43,8 @@ public class AboutActivity extends AppCompatActivity { super.onCreate(savedInstanceState); getSupportActionBar().setDisplayShowHomeEnabled(true); setContentView(R.layout.about); - webViewContainer = (LinearLayout) findViewById(R.id.webViewContainer); - webView = (WebView) findViewById(R.id.webViewAbout); + webViewContainer = findViewById(R.id.webViewContainer); + webView = findViewById(R.id.webViewAbout); webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE); if (UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { @@ -69,13 +69,16 @@ public class AboutActivity extends AppCompatActivity { } private void loadAsset(String filename) { - subscription = Single.create(subscriber -> { + disposable = Single.create(subscriber -> { InputStream input = null; try { TypedArray res = AboutActivity.this.getTheme().obtainStyledAttributes( - new int[] { android.R.attr.textColorPrimary }); - int colorResource = res.getColor(0, 0); - String colorString = String.format("#%06X", 0xFFFFFF & colorResource); + new int[] { R.attr.about_screen_font_color, R.attr.about_screen_background, + R.attr.about_screen_card_background, R.attr.about_screen_card_border}); + String fontColor = String.format("#%06X", 0xFFFFFF & res.getColor(0, 0)); + String backgroundColor = String.format("#%06X", 0xFFFFFF & res.getColor(1, 0)); + String cardBackground = String.format("#%06X", 0xFFFFFF & res.getColor(2, 0)); + String cardBorder = String.format("#%06X", 0xFFFFFF & res.getColor(3, 0)); res.recycle(); input = getAssets().open(filename); String webViewData = IOUtils.toString(input, Charset.defaultCharset()); @@ -92,7 +95,7 @@ public class AboutActivity extends AppCompatActivity { " src: url('file:///android_asset/Roboto-Light.ttf');" + " }" + " * {" + - " color: %s;" + + " color: @fontcolor@;" + " font-family: roboto-Light;" + " font-size: 8pt;" + " }" + @@ -100,7 +103,10 @@ public class AboutActivity extends AppCompatActivity { "</head><body><p>" + webViewData + "</p></body></html>"; webViewData = webViewData.replace("\n", "<br/>"); } - webViewData = String.format(webViewData, colorString); + webViewData = webViewData.replace("@fontcolor@", fontColor); + webViewData = webViewData.replace("@background@", backgroundColor); + webViewData = webViewData.replace("@card_background@", cardBackground); + webViewData = webViewData.replace("@card_border@", cardBorder); subscriber.onSuccess(webViewData); } catch (IOException e) { Log.e(TAG, Log.getStackTraceString(e)); @@ -109,7 +115,7 @@ public class AboutActivity extends AppCompatActivity { IOUtils.closeQuietly(input); } }) - .subscribeOn(Schedulers.newThread()) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( webViewData -> @@ -140,8 +146,8 @@ public class AboutActivity extends AppCompatActivity { @Override protected void onDestroy() { super.onDestroy(); - if(subscription != null) { - subscription.unsubscribe(); + if (disposable != null) { + disposable.dispose(); } if (webViewContainer != null && webView != null) { webViewContainer.removeAllViews(); diff --git a/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java index 207aec20f..67dda01cf 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java @@ -12,8 +12,6 @@ import java.util.concurrent.atomic.AtomicBoolean; import de.danoeh.antennapod.core.feed.MediaType; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.service.playback.PlaybackService; -import de.danoeh.antennapod.core.util.playback.ExternalMedia; -import de.danoeh.antennapod.core.util.playback.PlaybackServiceStarter; import de.danoeh.antennapod.dialog.VariableSpeedDialog; /** @@ -28,20 +26,7 @@ public class AudioplayerActivity extends MediaplayerInfoActivity { protected void onResume() { super.onResume(); if (TextUtils.equals(getIntent().getAction(), Intent.ACTION_VIEW)) { - Intent intent = getIntent(); - if (intent.getData() == null) { - return; - } - Log.d(TAG, "Received VIEW intent: " + intent.getData().getPath()); - ExternalMedia media = new ExternalMedia(intent.getData().getPath(), - MediaType.AUDIO); - - new PlaybackServiceStarter(this, media) - .startWhenPrepared(true) - .shouldStream(false) - .prepareImmediately(true) - .start(); - + playExternalMedia(getIntent(), MediaType.AUDIO); } else if (PlaybackService.isCasting()) { Intent intent = PlaybackService.getPlayerActivityIntent(this); if (intent.getComponent() != null && diff --git a/app/src/main/java/de/danoeh/antennapod/activity/DirectoryChooserActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/DirectoryChooserActivity.java index 390d4cef8..33def125e 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/DirectoryChooserActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/DirectoryChooserActivity.java @@ -64,11 +64,11 @@ public class DirectoryChooserActivity extends AppCompatActivity { getSupportActionBar().setDisplayHomeAsUpEnabled(true); setContentView(R.layout.directory_chooser); - butConfirm = (Button) findViewById(R.id.butConfirm); - butCancel = (Button) findViewById(R.id.butCancel); - butNavUp = (ImageButton) findViewById(R.id.butNavUp); - txtvSelectedFolder = (TextView) findViewById(R.id.txtvSelectedFolder); - listDirectories = (ListView) findViewById(R.id.directory_list); + butConfirm = findViewById(R.id.butConfirm); + butCancel = findViewById(R.id.butCancel); + butNavUp = findViewById(R.id.butNavUp); + txtvSelectedFolder = findViewById(R.id.txtvSelectedFolder); + listDirectories = findViewById(R.id.directory_list); butConfirm.setOnClickListener(new OnClickListener() { diff --git a/app/src/main/java/de/danoeh/antennapod/activity/DownloadAuthenticationActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/DownloadAuthenticationActivity.java index e726afaec..5e04d743d 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/DownloadAuthenticationActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/DownloadAuthenticationActivity.java @@ -49,11 +49,11 @@ public class DownloadAuthenticationActivity extends AppCompatActivity { } setContentView(R.layout.download_authentication_activity); - TextView txtvDescription = (TextView) findViewById(R.id.txtvDescription); - etxtUsername = (EditText) findViewById(R.id.etxtUsername); - etxtPassword = (EditText) findViewById(R.id.etxtPassword); - Button butConfirm = (Button) findViewById(R.id.butConfirm); - Button butCancel = (Button) findViewById(R.id.butCancel); + TextView txtvDescription = findViewById(R.id.txtvDescription); + etxtUsername = findViewById(R.id.etxtUsername); + etxtPassword = findViewById(R.id.etxtPassword); + Button butConfirm = findViewById(R.id.butConfirm); + Button butCancel = findViewById(R.id.butCancel); Validate.isTrue(getIntent().hasExtra(ARG_DOWNLOAD_REQUEST), "Download request missing"); DownloadRequest request = getIntent().getParcelableExtra(ARG_DOWNLOAD_REQUEST); 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 6b1272b01..bfa694e5c 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java @@ -16,8 +16,15 @@ import android.view.View; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; + import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; 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.DownloadRequestErrorDialogCreator; import de.danoeh.antennapod.core.feed.Feed; @@ -30,13 +37,11 @@ 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 org.apache.commons.lang3.StringUtils; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; -import rx.Observable; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; +import io.reactivex.Maybe; +import io.reactivex.MaybeOnSubscribe; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; /** * Displays information about a feed. @@ -56,7 +61,7 @@ public class FeedInfoActivity extends AppCompatActivity { private TextView txtvAuthor; private TextView txtvUrl; - private Subscription subscription; + private Disposable disposable; private final View.OnClickListener copyUrlToClipboard = new View.OnClickListener() { @@ -82,52 +87,57 @@ public class FeedInfoActivity extends AppCompatActivity { getSupportActionBar().setDisplayHomeAsUpEnabled(true); long feedId = getIntent().getLongExtra(EXTRA_FEED_ID, -1); - imgvCover = (ImageView) findViewById(R.id.imgvCover); - txtvTitle = (TextView) findViewById(R.id.txtvTitle); - TextView txtvAuthorHeader = (TextView) findViewById(R.id.txtvAuthor); - ImageView imgvBackground = (ImageView) findViewById(R.id.imgvBackground); + imgvCover = findViewById(R.id.imgvCover); + txtvTitle = findViewById(R.id.txtvTitle); + TextView txtvAuthorHeader = findViewById(R.id.txtvAuthor); + ImageView imgvBackground = findViewById(R.id.imgvBackground); findViewById(R.id.butShowInfo).setVisibility(View.INVISIBLE); findViewById(R.id.butShowSettings).setVisibility(View.INVISIBLE); // https://github.com/bumptech/glide/issues/529 imgvBackground.setColorFilter(new LightingColorFilter(0xff828282, 0x000000)); - 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.txtvDetailsAuthor); - txtvUrl = (TextView) findViewById(R.id.txtvUrl); + txtvDescription = findViewById(R.id.txtvDescription); + lblLanguage = findViewById(R.id.lblLanguage); + txtvLanguage = findViewById(R.id.txtvLanguage); + lblAuthor = findViewById(R.id.lblAuthor); + txtvAuthor = findViewById(R.id.txtvDetailsAuthor); + txtvUrl = findViewById(R.id.txtvUrl); txtvUrl.setOnClickListener(copyUrlToClipboard); - subscription = Observable.fromCallable(()-> DBReader.getFeed(feedId)) - .subscribeOn(Schedulers.newThread()) + disposable = Maybe.create((MaybeOnSubscribe<Feed>) emitter -> { + Feed feed = DBReader.getFeed(feedId); + if (feed != null) { + emitter.onSuccess(feed); + } else { + emitter.onComplete(); + } + }) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { - if (result == null) { - Log.e(TAG, "Activity was started with invalid arguments"); - finish(); - } feed = result; Log.d(TAG, "Language is " + feed.getLanguage()); Log.d(TAG, "Author is " + feed.getAuthor()); Log.d(TAG, "URL is " + feed.getDownload_url()); Glide.with(FeedInfoActivity.this) .load(feed.getImageLocation()) - .placeholder(R.color.light_gray) - .error(R.color.light_gray) - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .fitCenter() - .dontAnimate() + .apply(new RequestOptions() + .placeholder(R.color.light_gray) + .error(R.color.light_gray) + .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) + .fitCenter() + .dontAnimate()) .into(imgvCover); Glide.with(FeedInfoActivity.this) .load(feed.getImageLocation()) - .placeholder(R.color.image_readability_tint) - .error(R.color.image_readability_tint) - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .transform(new FastBlurTransformation(FeedInfoActivity.this)) - .dontAnimate() + .apply(new RequestOptions() + .placeholder(R.color.image_readability_tint) + .error(R.color.image_readability_tint) + .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) + .transform(new FastBlurTransformation()) + .dontAnimate()) .into(imgvBackground); txtvTitle.setText(feed.getTitle()); @@ -164,14 +174,17 @@ public class FeedInfoActivity extends AppCompatActivity { }, error -> { Log.d(TAG, Log.getStackTraceString(error)); finish(); + }, () -> { + Log.e(TAG, "Activity was started with invalid arguments"); + finish(); }); } @Override public void onDestroy() { super.onDestroy(); - if(subscription != null) { - subscription.unsubscribe(); + if (disposable != null) { + disposable.dispose(); } } diff --git a/app/src/main/java/de/danoeh/antennapod/activity/FeedSettingsActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/FeedSettingsActivity.java index 5e15585a5..4698ed90e 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/FeedSettingsActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/FeedSettingsActivity.java @@ -1,6 +1,5 @@ package de.danoeh.antennapod.activity; -import android.content.ClipData; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; @@ -24,8 +23,10 @@ import android.widget.ImageView; import android.widget.RadioButton; import android.widget.Spinner; import android.widget.TextView; -import android.widget.Toast; + import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; + import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.dialog.ConfirmationDialog; import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator; @@ -40,10 +41,11 @@ 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.menuhandler.FeedMenuHandler; -import rx.Observable; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; +import io.reactivex.Maybe; +import io.reactivex.MaybeOnSubscribe; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; /** * Displays information about a feed. @@ -67,23 +69,7 @@ public class FeedSettingsActivity extends AppCompatActivity { private Spinner spnAutoDelete; private boolean filterInclude = true; - private Subscription subscription; - - - private final View.OnClickListener copyUrlToClipboard = new View.OnClickListener() { - @Override - public void onClick(View v) { - if(feed != null && feed.getDownload_url() != null) { - String url = feed.getDownload_url(); - ClipData clipData = ClipData.newPlainText(url, url); - android.content.ClipboardManager cm = (android.content.ClipboardManager) FeedSettingsActivity.this - .getSystemService(Context.CLIPBOARD_SERVICE); - cm.setPrimaryClip(clipData); - Toast t = Toast.makeText(FeedSettingsActivity.this, R.string.copied_url_msg, Toast.LENGTH_SHORT); - t.show(); - } - } - }; + private Disposable disposable; private boolean authInfoChanged = false; @@ -127,57 +113,62 @@ public class FeedSettingsActivity extends AppCompatActivity { getSupportActionBar().setDisplayHomeAsUpEnabled(true); long feedId = getIntent().getLongExtra(EXTRA_FEED_ID, -1); - imgvCover = (ImageView) findViewById(R.id.imgvCover); - txtvTitle = (TextView) findViewById(R.id.txtvTitle); - TextView txtvAuthorHeader = (TextView) findViewById(R.id.txtvAuthor); - ImageView imgvBackground = (ImageView) findViewById(R.id.imgvBackground); + imgvCover = findViewById(R.id.imgvCover); + txtvTitle = findViewById(R.id.txtvTitle); + TextView txtvAuthorHeader = findViewById(R.id.txtvAuthor); + ImageView imgvBackground = findViewById(R.id.imgvBackground); findViewById(R.id.butShowInfo).setVisibility(View.INVISIBLE); findViewById(R.id.butShowSettings).setVisibility(View.INVISIBLE); // https://github.com/bumptech/glide/issues/529 imgvBackground.setColorFilter(new LightingColorFilter(0xff828282, 0x000000)); - cbxAutoDownload = (CheckBox) findViewById(R.id.cbxAutoDownload); - cbxKeepUpdated = (CheckBox) findViewById(R.id.cbxKeepUpdated); - spnAutoDelete = (Spinner) findViewById(R.id.spnAutoDelete); - etxtUsername = (EditText) findViewById(R.id.etxtUsername); - etxtPassword = (EditText) findViewById(R.id.etxtPassword); - etxtFilterText = (EditText) findViewById(R.id.etxtEpisodeFilterText); - rdoFilterInclude = (RadioButton) findViewById(R.id.radio_filter_include); + cbxAutoDownload = findViewById(R.id.cbxAutoDownload); + cbxKeepUpdated = findViewById(R.id.cbxKeepUpdated); + spnAutoDelete = findViewById(R.id.spnAutoDelete); + etxtUsername = findViewById(R.id.etxtUsername); + etxtPassword = findViewById(R.id.etxtPassword); + etxtFilterText = findViewById(R.id.etxtEpisodeFilterText); + rdoFilterInclude = findViewById(R.id.radio_filter_include); rdoFilterInclude.setOnClickListener(v -> { filterInclude = true; filterTextChanged = true; }); - rdoFilterExclude = (RadioButton) findViewById(R.id.radio_filter_exclude); + rdoFilterExclude = findViewById(R.id.radio_filter_exclude); rdoFilterExclude.setOnClickListener(v -> { filterInclude = false; filterTextChanged = true; }); - subscription = Observable.fromCallable(()-> DBReader.getFeed(feedId)) - .subscribeOn(Schedulers.newThread()) + disposable = Maybe.create((MaybeOnSubscribe<Feed>) emitter -> { + Feed feed = DBReader.getFeed(feedId); + if (feed != null) { + emitter.onSuccess(feed); + } else { + emitter.onComplete(); + } + }) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { - if (result == null) { - Log.e(TAG, "Activity was started with invalid arguments"); - finish(); - } feed = result; FeedPreferences prefs = feed.getPreferences(); Glide.with(FeedSettingsActivity.this) .load(feed.getImageLocation()) - .placeholder(R.color.light_gray) - .error(R.color.light_gray) - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .fitCenter() - .dontAnimate() + .apply(new RequestOptions() + .placeholder(R.color.light_gray) + .error(R.color.light_gray) + .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) + .fitCenter() + .dontAnimate()) .into(imgvCover); Glide.with(FeedSettingsActivity.this) .load(feed.getImageLocation()) - .placeholder(R.color.image_readability_tint) - .error(R.color.image_readability_tint) - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .transform(new FastBlurTransformation(FeedSettingsActivity.this)) - .dontAnimate() + .apply(new RequestOptions() + .placeholder(R.color.image_readability_tint) + .error(R.color.image_readability_tint) + .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) + .transform(new FastBlurTransformation()) + .dontAnimate()) .into(imgvBackground); txtvTitle.setText(feed.getTitle()); @@ -259,6 +250,9 @@ public class FeedSettingsActivity extends AppCompatActivity { }, error -> { Log.d(TAG, Log.getStackTraceString(error)); finish(); + }, () -> { + Log.e(TAG, "Activity was started with invalid arguments"); + finish(); }); } @@ -296,8 +290,8 @@ public class FeedSettingsActivity extends AppCompatActivity { @Override public void onDestroy() { super.onDestroy(); - if(subscription != null) { - subscription.unsubscribe(); + if (disposable != null) { + disposable.dispose(); } } diff --git a/app/src/main/java/de/danoeh/antennapod/activity/FlattrAuthActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/FlattrAuthActivity.java index 26352f58f..2b4384a02 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/FlattrAuthActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/FlattrAuthActivity.java @@ -41,9 +41,9 @@ public class FlattrAuthActivity extends AppCompatActivity { if (BuildConfig.DEBUG) Log.d(TAG, "Activity created"); getSupportActionBar().setDisplayHomeAsUpEnabled(true); setContentView(R.layout.flattr_auth); - txtvExplanation = (TextView) findViewById(R.id.txtvExplanation); - butAuthenticate = (Button) findViewById(R.id.but_authenticate); - butReturn = (Button) findViewById(R.id.but_return_home); + txtvExplanation = findViewById(R.id.txtvExplanation); + butAuthenticate = findViewById(R.id.but_authenticate); + butReturn = findViewById(R.id.but_return_home); butReturn.setOnClickListener(v -> { Intent intent = new Intent(FlattrAuthActivity.this, MainActivity.class); diff --git a/app/src/main/java/de/danoeh/antennapod/activity/ImportExportActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/ImportExportActivity.java index 91462bce9..e6c9c37cc 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/ImportExportActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/ImportExportActivity.java @@ -13,9 +13,7 @@ import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.MenuItem; -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.core.preferences.UserPreferences; -import de.danoeh.antennapod.core.storage.PodDBAdapter; + import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; @@ -26,6 +24,10 @@ import java.io.IOException; import java.io.InputStream; import java.nio.channels.FileChannel; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.core.preferences.UserPreferences; +import de.danoeh.antennapod.core.storage.PodDBAdapter; + /** * Displays the 'import/export' screen */ 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 294ab5af8..9f4fbe271 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java @@ -27,11 +27,10 @@ import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; +import android.widget.Toast; import com.bumptech.glide.Glide; -import de.danoeh.antennapod.core.event.ServiceEvent; -import de.danoeh.antennapod.core.util.gui.NotificationUtils; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.Validate; @@ -44,17 +43,20 @@ 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.event.ServiceEvent; import de.danoeh.antennapod.core.feed.EventDistributor; import de.danoeh.antennapod.core.feed.Feed; 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.IntentUtils; import de.danoeh.antennapod.core.util.StorageUtils; +import de.danoeh.antennapod.core.util.download.AutoUpdateManager; +import de.danoeh.antennapod.core.util.gui.NotificationUtils; import de.danoeh.antennapod.dialog.RatingDialog; import de.danoeh.antennapod.dialog.RenameFeedDialog; import de.danoeh.antennapod.fragment.AddFeedFragment; @@ -67,10 +69,10 @@ import de.danoeh.antennapod.fragment.QueueFragment; import de.danoeh.antennapod.fragment.SubscriptionFragment; import de.danoeh.antennapod.menuhandler.NavDrawerActivity; import de.greenrobot.event.EventBus; -import rx.Observable; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; +import io.reactivex.Observable; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; /** * The activity that is shown when the user launches the app. @@ -120,7 +122,9 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi private ProgressDialog pd; - private Subscription subscription; + private Disposable disposable; + + private long lastBackButtonPressTime = 0; @Override public void onCreate(Bundle savedInstanceState) { @@ -129,7 +133,7 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi StorageUtils.checkStorageAvailability(this); setContentView(R.layout.main); - toolbar = (Toolbar) findViewById(R.id.toolbar); + toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { @@ -141,8 +145,8 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi currentTitle = getTitle(); - drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); - navList = (ListView) findViewById(R.id.nav_list); + drawerLayout = findViewById(R.id.drawer_layout); + navList = findViewById(R.id.nav_list); navDrawer = findViewById(R.id.nav_layout); drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.drawer_open, R.string.drawer_close); @@ -470,7 +474,7 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi protected void onResume() { super.onResume(); StorageUtils.checkStorageAvailability(this); - DBTasks.checkShouldRefreshFeeds(getApplicationContext()); + AutoUpdateManager.checkShouldRefreshFeeds(getApplicationContext()); Intent intent = getIntent(); if (intent.hasExtra(EXTRA_FEED_ID) || @@ -487,8 +491,8 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi super.onStop(); EventDistributor.getInstance().unregister(contentUpdate); EventBus.getDefault().unregister(this); - if(subscription != null) { - subscription.unsubscribe(); + if (disposable != null) { + disposable.dispose(); } if(pd != null) { pd.dismiss(); @@ -627,8 +631,7 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi remover.skipOnCompletion = true; int playerStatus = PlaybackPreferences.getCurrentPlayerStatus(); if(playerStatus == PlaybackPreferences.PLAYER_STATUS_PLAYING) { - sendBroadcast(new Intent( - PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE)); + IntentUtils.sendLocalBroadcast(MainActivity.this, PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE); } } remover.executeAsync(); @@ -643,10 +646,40 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi @Override public void onBackPressed() { - if(isDrawerOpen()) { + if (isDrawerOpen()) { drawerLayout.closeDrawer(navDrawer); - } else { + } else if (getSupportFragmentManager().getBackStackEntryCount() != 0) { super.onBackPressed(); + } else { + switch (UserPreferences.getBackButtonBehavior()) { + case OPEN_DRAWER: + drawerLayout.openDrawer(navDrawer); + break; + case SHOW_PROMPT: + new AlertDialog.Builder(this) + .setMessage(R.string.close_prompt) + .setPositiveButton(R.string.yes, (dialogInterface, i) -> MainActivity.super.onBackPressed()) + .setNegativeButton(R.string.no, null) + .setCancelable(false) + .show(); + break; + case DOUBLE_TAP: + if (lastBackButtonPressTime < System.currentTimeMillis() - 2000) { + Toast.makeText(this, R.string.double_tap_toast, Toast.LENGTH_SHORT).show(); + lastBackButtonPressTime = System.currentTimeMillis(); + } else { + super.onBackPressed(); + } + break; + case GO_TO_PAGE: + if (getLastNavFragment().equals(UserPreferences.getBackButtonGoToPage())) { + super.onBackPressed(); + } else { + loadFragment(UserPreferences.getBackButtonGoToPage(), null); + } + break; + default: super.onBackPressed(); + } } } @@ -717,8 +750,8 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi }; private void loadData() { - subscription = Observable.fromCallable(DBReader::getNavDrawerData) - .subscribeOn(Schedulers.newThread()) + disposable = Observable.fromCallable(DBReader::getNavDrawerData) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { boolean handleIntent = (navDrawerData == null); diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java index 091f8daab..f3b83638d 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java @@ -1,9 +1,11 @@ package de.danoeh.antennapod.activity; +import android.Manifest; import android.annotation.TargetApi; import android.app.Activity; import android.content.Intent; import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.content.res.TypedArray; import android.graphics.Color; import android.graphics.PixelFormat; @@ -11,7 +13,9 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.support.annotation.Nullable; +import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityOptionsCompat; +import android.support.v4.content.ContextCompat; import android.support.v7.app.AlertDialog; import android.util.Log; import android.view.Menu; @@ -37,28 +41,33 @@ import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.event.ServiceEvent; 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.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.Consumer; import de.danoeh.antennapod.core.util.Converter; import de.danoeh.antennapod.core.util.FeedItemUtil; import de.danoeh.antennapod.core.util.Flavors; +import de.danoeh.antennapod.core.util.Function; +import de.danoeh.antennapod.core.util.IntentUtils; import de.danoeh.antennapod.core.util.ShareUtils; import de.danoeh.antennapod.core.util.StorageUtils; import de.danoeh.antennapod.core.util.Supplier; import de.danoeh.antennapod.core.util.gui.PictureInPictureUtil; +import de.danoeh.antennapod.core.util.playback.ExternalMedia; import de.danoeh.antennapod.core.util.playback.MediaPlayerError; import de.danoeh.antennapod.core.util.playback.Playable; import de.danoeh.antennapod.core.util.playback.PlaybackController; +import de.danoeh.antennapod.core.util.playback.PlaybackServiceStarter; import de.danoeh.antennapod.dialog.SleepTimerDialog; import de.danoeh.antennapod.dialog.VariableSpeedDialog; -import rx.Observable; -import rx.android.schedulers.AndroidSchedulers; -import rx.functions.Action1; -import rx.functions.Func1; -import rx.schedulers.Schedulers; +import io.reactivex.Observable; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; /** @@ -69,6 +78,10 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements private static final String TAG = "MediaplayerActivity"; private static final String PREFS = "MediaPlayerActivityPreferences"; private static final String PREF_SHOW_TIME_LEFT = "showTimeLeft"; + private static final int REQUEST_CODE_STORAGE = 42; + private static final float PLAYBACK_SPEED_STEP = 0.05f; + private static final float DEFAULT_MIN_PLAYBACK_SPEED = 0.5f; + private static final float DEFAULT_MAX_PLAYBACK_SPEED = 2.5f; PlaybackController controller; @@ -86,6 +99,8 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements private boolean isFavorite = false; + private Disposable disposable; + private PlaybackController newPlaybackController() { return new PlaybackController(this, false) { @@ -222,8 +237,9 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements Log.d(TAG, "onCreate()"); StorageUtils.checkStorageAvailability(this); - orientation = getResources().getConfiguration().orientation; getWindow().setFormat(PixelFormat.TRANSPARENT); + setupGUI(); + loadMediaInfo(); } @Override @@ -256,15 +272,10 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements private void onBufferUpdate(float progress) { if (sbPosition != null) { - sbPosition.setSecondaryProgress((int) progress * sbPosition.getMax()); + sbPosition.setSecondaryProgress((int) (progress * sbPosition.getMax())); } } - /** - * Current screen orientation. - */ - private int orientation; - @Override protected void onStart() { super.onStart(); @@ -272,8 +283,6 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements controller.release(); } controller = newPlaybackController(); - setupGUI(); - loadMediaInfo(); onPositionObserverUpdate(); } @@ -284,6 +293,9 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements controller.release(); controller = null; // prevent leak } + if (disposable != null) { + disposable.dispose(); + } super.onStop(); } @@ -460,7 +472,7 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements final Button butDecSpeed = (Button) dialog.findViewById(R.id.butDecSpeed); butDecSpeed.setOnClickListener(v -> { if(controller != null && controller.canSetPlaybackSpeed()) { - barPlaybackSpeed.setProgress(barPlaybackSpeed.getProgress() - 2); + barPlaybackSpeed.setProgress(barPlaybackSpeed.getProgress() - 1); } else { VariableSpeedDialog.showGetPluginDialog(this); } @@ -468,7 +480,7 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements final Button butIncSpeed = (Button) dialog.findViewById(R.id.butIncSpeed); butIncSpeed.setOnClickListener(v -> { if(controller != null && controller.canSetPlaybackSpeed()) { - barPlaybackSpeed.setProgress(barPlaybackSpeed.getProgress() + 2); + barPlaybackSpeed.setProgress(barPlaybackSpeed.getProgress() + 1); } else { VariableSpeedDialog.showGetPluginDialog(this); } @@ -483,12 +495,20 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements UserPreferences.setPlaybackSpeed(String.valueOf(currentSpeed)); } + String[] availableSpeeds = UserPreferences.getPlaybackSpeedArray(); + final float minPlaybackSpeed = availableSpeeds.length > 1 ? + Float.valueOf(availableSpeeds[0]) : DEFAULT_MIN_PLAYBACK_SPEED; + float maxPlaybackSpeed = availableSpeeds.length > 1 ? + Float.valueOf(availableSpeeds[availableSpeeds.length - 1]) : DEFAULT_MAX_PLAYBACK_SPEED; + int progressMax = (int) ((maxPlaybackSpeed - minPlaybackSpeed) / PLAYBACK_SPEED_STEP); + barPlaybackSpeed.setMax(progressMax); + txtvPlaybackSpeed.setText(String.format("%.2fx", currentSpeed)); barPlaybackSpeed.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if(controller != null && controller.canSetPlaybackSpeed()) { - float playbackSpeed = (progress + 10) / 20.0f; + float playbackSpeed = progress * PLAYBACK_SPEED_STEP + minPlaybackSpeed; controller.setPlaybackSpeed(playbackSpeed); String speedPref = String.format(Locale.US, "%.2f", playbackSpeed); UserPreferences.setPlaybackSpeed(speedPref); @@ -496,7 +516,8 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements txtvPlaybackSpeed.setText(speedStr); } else if(fromUser) { float speed = Float.valueOf(UserPreferences.getPlaybackSpeed()); - barPlaybackSpeed.post(() -> barPlaybackSpeed.setProgress((int) (20 * speed) - 10)); + barPlaybackSpeed.post(() -> barPlaybackSpeed.setProgress( + (int) ((speed - minPlaybackSpeed) / PLAYBACK_SPEED_STEP))); } } @@ -511,7 +532,7 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements public void onStopTrackingTouch(SeekBar seekBar) { } }); - barPlaybackSpeed.setProgress((int) (20 * currentSpeed) - 10); + barPlaybackSpeed.setProgress((int) ((currentSpeed - minPlaybackSpeed) / PLAYBACK_SPEED_STEP)); final SeekBar barLeftVolume = (SeekBar) dialog.findViewById(R.id.volume_left); barLeftVolume.setProgress(UserPreferences.getLeftVolumePercentage()); @@ -525,6 +546,22 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements stereoToMono.setText(stereoToMono.getText() + " [" + sonicOnly + "]"); } + if (UserPreferences.useExoplayer()) { + barRightVolume.setEnabled(false); + } + + final CheckBox skipSilence = (CheckBox) dialog.findViewById(R.id.skipSilence); + skipSilence.setChecked(UserPreferences.isSkipSilence()); + if (!UserPreferences.useExoplayer()) { + skipSilence.setEnabled(false); + String exoplayerOnly = getString(R.string.exoplayer_only); + skipSilence.setText(skipSilence.getText() + " [" + exoplayerOnly + "]"); + } + skipSilence.setOnCheckedChangeListener((buttonView, isChecked) -> { + UserPreferences.setSkipSilence(isChecked); + controller.setSkipSilence(isChecked); + }); + barLeftVolume.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { @@ -635,7 +672,6 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements if (controller != null) { controller.init(); } - } } @@ -690,7 +726,6 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements if(controller == null || controller.getMedia() == null) { return false; } - Playable media = controller.getMedia(); SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE); showTimeLeft = prefs.getBoolean(PREF_SHOW_TIME_LEFT, false); onPositionObserverUpdate(); @@ -722,8 +757,8 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements R.string.pref_rewind); private final Supplier<Integer> getPrefSecsFn; - private final Func1<MediaplayerActivity, TextView> getTextViewFn; - private final Action1<Integer> setPrefSecsFn; + private final Function<MediaplayerActivity, TextView> getTextViewFn; + private final Consumer<Integer> setPrefSecsFn; private final int titleResourceID; /** @@ -735,7 +770,7 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements * @param setPrefSecsFn Handle to function that sets the preference (setting) for the skip delta value (and optionally updates the button label with the current values) * @param titleResourceID ID of the resource string with the title for a view */ - SkipDirection(Supplier<Integer> getPrefSecsFn, Func1<MediaplayerActivity, TextView> getTextViewFn, Action1<Integer> setPrefSecsFn, int titleResourceID) { + SkipDirection(Supplier<Integer> getPrefSecsFn, Function<MediaplayerActivity, TextView> getTextViewFn, Consumer<Integer> setPrefSecsFn, int titleResourceID) { this.getPrefSecsFn = getPrefSecsFn; this.getTextViewFn = getTextViewFn; this.setPrefSecsFn = setPrefSecsFn; @@ -754,10 +789,10 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements * @param activity MediaplyerActivity that contains textview to update the display of the skip delta setting (or null if nothing to update) */ public void setPrefSkipSeconds(int seconds, @Nullable Activity activity) { - setPrefSecsFn.call(seconds); + setPrefSecsFn.accept(seconds); if (activity != null && activity instanceof MediaplayerActivity) { - TextView tv = getTextViewFn.call((MediaplayerActivity)activity); + TextView tv = getTextViewFn.apply((MediaplayerActivity)activity); if (tv != null) tv.setText(String.valueOf(seconds)); } } @@ -795,13 +830,13 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements void setupGUI() { setContentView(getContentViewResourceId()); - sbPosition = (SeekBar) findViewById(R.id.sbPosition); - txtvPosition = (TextView) findViewById(R.id.txtvPosition); + sbPosition = findViewById(R.id.sbPosition); + txtvPosition = findViewById(R.id.txtvPosition); SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE); showTimeLeft = prefs.getBoolean(PREF_SHOW_TIME_LEFT, false); Log.d("timeleft", showTimeLeft ? "true" : "false"); - txtvLength = (TextView) findViewById(R.id.txtvLength); + txtvLength = findViewById(R.id.txtvLength); if (txtvLength != null) { txtvLength.setOnClickListener(v -> { showTimeLeft = !showTimeLeft; @@ -825,18 +860,18 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements }); } - butRev = (ImageButton) findViewById(R.id.butRev); - txtvRev = (TextView) findViewById(R.id.txtvRev); + butRev = findViewById(R.id.butRev); + txtvRev = findViewById(R.id.txtvRev); if (txtvRev != null) { txtvRev.setText(String.valueOf(UserPreferences.getRewindSecs())); } - butPlay = (ImageButton) findViewById(R.id.butPlay); - butFF = (ImageButton) findViewById(R.id.butFF); - txtvFF = (TextView) findViewById(R.id.txtvFF); + butPlay = findViewById(R.id.butPlay); + butFF = findViewById(R.id.butFF); + txtvFF = findViewById(R.id.txtvFF); if (txtvFF != null) { txtvFF.setText(String.valueOf(UserPreferences.getFastForwardSecs())); } - butSkip = (ImageButton) findViewById(R.id.butSkip); + butSkip = findViewById(R.id.butSkip); // SEEKBAR SETUP @@ -863,7 +898,8 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements } if (butSkip != null) { - butSkip.setOnClickListener(v -> sendBroadcast(new Intent(PlaybackService.ACTION_SKIP_CURRENT_EPISODE))); + butSkip.setOnClickListener(v -> + IntentUtils.sendLocalBroadcast(MediaplayerActivity.this, PlaybackService.ACTION_SKIP_CURRENT_EPISODE)); } } @@ -937,22 +973,62 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements private void checkFavorite() { Playable playable = controller.getMedia(); - if (playable != null && playable instanceof FeedMedia) { - FeedItem feedItem = ((FeedMedia) playable).getItem(); - if (feedItem != null) { - Observable.fromCallable(() -> DBReader.getFeedItem(feedItem.getId())) - .subscribeOn(Schedulers.newThread()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe( - item -> { - boolean isFav = item.isTagged(FeedItem.TAG_FAVORITE); - if (isFavorite != isFav) { - isFavorite = isFav; - invalidateOptionsMenu(); - } - }, error -> Log.e(TAG, Log.getStackTraceString(error))); + if (!(playable instanceof FeedMedia)) { + return; + } + FeedItem feedItem = ((FeedMedia) playable).getItem(); + if (feedItem == null) { + return; + } + if (disposable != null) { + disposable.dispose(); + } + disposable = Observable.fromCallable(() -> DBReader.getFeedItem(feedItem.getId())) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + item -> { + boolean isFav = item.isTagged(FeedItem.TAG_FAVORITE); + if (isFavorite != isFav) { + isFavorite = isFav; + invalidateOptionsMenu(); + } + }, error -> Log.e(TAG, Log.getStackTraceString(error))); + } + + void playExternalMedia(Intent intent, MediaType type) { + if (intent == null || intent.getData() == null) { + return; + } + if (Build.VERSION.SDK_INT >= 23 + && ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) + != PackageManager.PERMISSION_GRANTED) { + + if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE)) { + Toast.makeText(this, R.string.needs_storage_permission, Toast.LENGTH_LONG).show(); + } else { + ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, + REQUEST_CODE_STORAGE); } + return; } + + Log.d(TAG, "Received VIEW intent: " + intent.getData().getPath()); + ExternalMedia media = new ExternalMedia(intent.getData().getPath(), type); + + new PlaybackServiceStarter(this, media) + .startWhenPrepared(true) + .shouldStream(false) + .prepareImmediately(true) + .start(); } + @Override + public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { + if (requestCode == REQUEST_CODE_STORAGE) { + if (grantResults.length <= 0 || grantResults[0] != PackageManager.PERMISSION_GRANTED) { + Toast.makeText(this, R.string.needs_storage_permission, Toast.LENGTH_LONG).show(); + } + } + } } 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 f3ed1cb62..3db00edc9 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java @@ -46,8 +46,9 @@ 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.IntentUtils; +import de.danoeh.antennapod.core.util.download.AutoUpdateManager; import de.danoeh.antennapod.core.util.playback.Playable; import de.danoeh.antennapod.core.util.playback.PlaybackController; import de.danoeh.antennapod.dialog.RenameFeedDialog; @@ -62,10 +63,10 @@ import de.danoeh.antennapod.fragment.QueueFragment; import de.danoeh.antennapod.fragment.SubscriptionFragment; import de.danoeh.antennapod.menuhandler.NavDrawerActivity; import de.greenrobot.event.EventBus; -import rx.Observable; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; +import io.reactivex.Observable; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; /** * Activity for playing files that do not require a video surface. @@ -105,7 +106,7 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem private ViewPager pager; private MediaplayerInfoPagerAdapter pagerAdapter; - private Subscription subscription; + private Disposable disposable; @Override protected void onPause() { @@ -126,8 +127,8 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem if(pagerAdapter != null) { pagerAdapter.setController(null); } - if(subscription != null) { - subscription.unsubscribe(); + if (disposable != null) { + disposable.dispose(); } EventDistributor.getInstance().unregister(contentUpdate); saveCurrentFragment(); @@ -186,7 +187,7 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem pagerAdapter.onMediaChanged(media); pagerAdapter.setController(controller); } - DBTasks.checkShouldRefreshFeeds(getApplicationContext()); + AutoUpdateManager.checkShouldRefreshFeeds(getApplicationContext()); EventDistributor.getInstance().register(contentUpdate); EventBus.getDefault().register(this); @@ -226,18 +227,18 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem @Override protected void setupGUI() { super.setupGUI(); - Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setTitle(""); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { findViewById(R.id.shadow).setVisibility(View.GONE); - AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.appBar); + AppBarLayout appBarLayout = findViewById(R.id.appBar); float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4, getResources().getDisplayMetrics()); appBarLayout.setElevation(px); } - drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); - navList = (ListView) findViewById(R.id.nav_list); + drawerLayout = findViewById(R.id.drawer_layout); + navList = findViewById(R.id.nav_list); navDrawer = findViewById(R.id.nav_layout); drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.drawer_open, R.string.drawer_close); @@ -273,14 +274,15 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem startActivity(new Intent(MediaplayerInfoActivity.this, PreferenceActivity.class)); }); - butPlaybackSpeed = (Button) findViewById(R.id.butPlaybackSpeed); - butCastDisconnect = (ImageButton) findViewById(R.id.butCastDisconnect); + butPlaybackSpeed = findViewById(R.id.butPlaybackSpeed); + butCastDisconnect = findViewById(R.id.butCastDisconnect); - pager = (ViewPager) findViewById(R.id.pager); + pager = findViewById(R.id.pager); + pager.setOffscreenPageLimit(3); pagerAdapter = new MediaplayerInfoPagerAdapter(getSupportFragmentManager(), media); pagerAdapter.setController(controller); pager.setAdapter(pagerAdapter); - CirclePageIndicator pageIndicator = (CirclePageIndicator) findViewById(R.id.page_indicator); + CirclePageIndicator pageIndicator = findViewById(R.id.page_indicator); pageIndicator.setViewPager(pager); loadLastFragment(); pager.onSaveInstanceState(); @@ -356,7 +358,7 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem @Override public boolean onOptionsItemSelected(MenuItem item) { - return drawerToggle != null && drawerToggle.onOptionsItemSelected(item) || super.onOptionsItemSelected(item); + return (drawerToggle != null && drawerToggle.onOptionsItemSelected(item)) || super.onOptionsItemSelected(item); } @Override @@ -413,8 +415,7 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem Log.d(TAG, "Currently playing episode is about to be deleted, skipping"); remover.skipOnCompletion = true; if(controller.getStatus() == PlayerStatus.PLAYING) { - sendBroadcast(new Intent( - PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE)); + IntentUtils.sendLocalBroadcast(MediaplayerInfoActivity.this, PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE); } } } @@ -472,8 +473,8 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem private DBReader.NavDrawerData navDrawerData; private void loadData() { - subscription = Observable.fromCallable(DBReader::getNavDrawerData) - .subscribeOn(Schedulers.newThread()) + disposable = Observable.fromCallable(DBReader::getNavDrawerData) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { navDrawerData = result; 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 f859f5466..145908e97 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java @@ -5,6 +5,7 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.annotation.UiThread; import android.support.v4.app.NavUtils; import android.support.v7.app.ActionBar; @@ -27,6 +28,7 @@ import android.widget.Spinner; import android.widget.TextView; import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; import org.apache.commons.lang3.StringUtils; import org.jsoup.Jsoup; @@ -56,19 +58,21 @@ import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DownloadRequestException; import de.danoeh.antennapod.core.storage.DownloadRequester; import de.danoeh.antennapod.core.syndication.handler.FeedHandler; +import de.danoeh.antennapod.core.syndication.handler.FeedHandlerResult; import de.danoeh.antennapod.core.syndication.handler.UnsupportedFeedtypeException; import de.danoeh.antennapod.core.util.DownloadError; import de.danoeh.antennapod.core.util.FileNameGenerator; +import de.danoeh.antennapod.core.util.Optional; 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; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; +import io.reactivex.Observable; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; /** * Downloads a feed from a feed URL and parses it. Subclasses can display the @@ -97,15 +101,15 @@ public class OnlineFeedViewActivity extends AppCompatActivity { private Button subscribeButton; - private Subscription download; - private Subscription parser; - private Subscription updater; + private Disposable download; + private Disposable parser; + private Disposable updater; private final 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) - .subscribeOn(Schedulers.newThread()) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( feeds -> { @@ -139,26 +143,33 @@ public class OnlineFeedViewActivity extends AppCompatActivity { StorageUtils.checkStorageAvailability(this); - final String feedUrl; + String feedUrl = null; if (getIntent().hasExtra(ARG_FEEDURL)) { feedUrl = getIntent().getStringExtra(ARG_FEEDURL); } else if (TextUtils.equals(getIntent().getAction(), Intent.ACTION_SEND) || TextUtils.equals(getIntent().getAction(), Intent.ACTION_VIEW)) { - feedUrl = (TextUtils.equals(getIntent().getAction(), Intent.ACTION_SEND)) + feedUrl = TextUtils.equals(getIntent().getAction(), Intent.ACTION_SEND) ? getIntent().getStringExtra(Intent.EXTRA_TEXT) : getIntent().getDataString(); if (actionBar != null) { actionBar.setTitle(R.string.add_feed_label); } - } else { - throw new IllegalArgumentException("Activity must be started with feedurl argument!"); } - Log.d(TAG, "Activity was started with url " + feedUrl); - setLoadingLayout(); - if (savedInstanceState == null) { - startFeedDownload(feedUrl, null, null); + if (feedUrl == null) { + Log.e(TAG, "feedUrl is null."); + new AlertDialog.Builder(OnlineFeedViewActivity.this). + setNeutralButton(android.R.string.ok, + (dialog, which) -> finish()). + setTitle(R.string.error_label). + setMessage(R.string.null_value_podcast_error).create().show(); } else { - startFeedDownload(feedUrl, savedInstanceState.getString("username"), savedInstanceState.getString("password")); + Log.d(TAG, "Activity was started with url " + feedUrl); + setLoadingLayout(); + if (savedInstanceState == null) { + startFeedDownload(feedUrl, null, null); + } else { + startFeedDownload(feedUrl, savedInstanceState.getString("username"), savedInstanceState.getString("password")); + } } } @@ -212,13 +223,13 @@ public class OnlineFeedViewActivity extends AppCompatActivity { public void onDestroy() { super.onDestroy(); if(updater != null) { - updater.unsubscribe(); + updater.dispose(); } if(download != null) { - download.unsubscribe(); + download.dispose(); } if(parser != null) { - parser.unsubscribe(); + parser.dispose(); } } @@ -273,18 +284,13 @@ public class OnlineFeedViewActivity extends AppCompatActivity { downloader.call(); return downloader.getResult(); }) - .subscribeOn(Schedulers.newThread()) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(this::checkDownloadResult, error -> Log.e(TAG, Log.getStackTraceString(error))); } - private void checkDownloadResult(DownloadStatus status) { - if (status == null) { - Log.wtf(TAG, "DownloadStatus returned by Downloader was null"); - finish(); - return; - } + private void checkDownloadResult(@NonNull DownloadStatus status) { if (status.isCancelled()) { return; } @@ -306,35 +312,17 @@ public class OnlineFeedViewActivity extends AppCompatActivity { } private void parseFeed() { - if (feed == null || feed.getFile_url() == null && feed.isDownloaded()) { + if (feed == null || (feed.getFile_url() == null && feed.isDownloaded())) { throw new IllegalStateException("feed must be non-null and downloaded when parseFeed is called"); } Log.d(TAG, "Parsing feed"); - parser = Observable.fromCallable(() -> { - FeedHandler handler = new FeedHandler(); - try { - return handler.parseFeed(feed); - } catch (UnsupportedFeedtypeException e) { - Log.d(TAG, "Unsupported feed type detected"); - if (TextUtils.equals("html", e.getRootElement().toLowerCase())) { - showFeedDiscoveryDialog(new File(feed.getFile_url()), feed.getDownload_url()); - return null; - } else { - throw e; - } - } catch (Exception e) { - Log.e(TAG, Log.getStackTraceString(e)); - throw e; - } finally { - boolean rc = new File(feed.getFile_url()).delete(); - Log.d(TAG, "Deleted feed source file. Result: " + rc); - } - }) - .subscribeOn(Schedulers.newThread()) + parser = Observable.fromCallable(this::doParseFeed) + .subscribeOn(Schedulers.computation()) .observeOn(AndroidSchedulers.mainThread()) - .subscribe(result -> { - if(result != null) { + .subscribe(optionalResult -> { + if(optionalResult.isPresent()) { + FeedHandlerResult result = optionalResult.get(); beforeShowFeedInformation(result.feed); showFeedInformation(result.feed, result.alternateFeedUrls); } @@ -342,9 +330,37 @@ public class OnlineFeedViewActivity extends AppCompatActivity { String errorMsg = DownloadError.ERROR_PARSER_EXCEPTION.getErrorString( OnlineFeedViewActivity.this) + " (" + error.getMessage() + ")"; showErrorDialog(errorMsg); + Log.d(TAG, "Feed parser exception: " + Log.getStackTraceString(error)); }); } + @NonNull + private Optional<FeedHandlerResult> doParseFeed() throws Exception { + FeedHandler handler = new FeedHandler(); + try { + return Optional.of(handler.parseFeed(feed)); + } catch (UnsupportedFeedtypeException e) { + Log.d(TAG, "Unsupported feed type detected"); + if ("html".equalsIgnoreCase(e.getRootElement())) { + boolean dialogShown = showFeedDiscoveryDialog(new File(feed.getFile_url()), feed.getDownload_url()); + if (dialogShown) { + return Optional.empty(); + } else { + Log.d(TAG, "Supplied feed is an HTML web page that has no references to any feed"); + throw e; + } + } else { + throw e; + } + } catch (Exception e) { + Log.e(TAG, Log.getStackTraceString(e)); + throw e; + } finally { + boolean rc = new File(feed.getFile_url()).delete(); + Log.d(TAG, "Deleted feed source file. Result: " + rc); + } + } + /** * Called after the feed has been downloaded and parsed and before showFeedInformation is called. * This method is executed on a background thread @@ -378,29 +394,30 @@ public class OnlineFeedViewActivity extends AppCompatActivity { this.feed = feed; this.selectedDownloadUrl = feed.getDownload_url(); EventDistributor.getInstance().register(listener); - ListView listView = (ListView) findViewById(R.id.listview); + ListView listView = findViewById(R.id.listview); LayoutInflater inflater = LayoutInflater.from(this); View header = inflater.inflate(R.layout.onlinefeedview_header, listView, false); listView.addHeaderView(header); listView.setAdapter(new FeedItemlistDescriptionAdapter(this, 0, feed.getItems())); - ImageView cover = (ImageView) header.findViewById(R.id.imgvCover); - TextView title = (TextView) header.findViewById(R.id.txtvTitle); - TextView author = (TextView) header.findViewById(R.id.txtvAuthor); - TextView description = (TextView) header.findViewById(R.id.txtvDescription); - Spinner spAlternateUrls = (Spinner) header.findViewById(R.id.spinnerAlternateUrls); + ImageView cover = header.findViewById(R.id.imgvCover); + TextView title = header.findViewById(R.id.txtvTitle); + TextView author = header.findViewById(R.id.txtvAuthor); + TextView description = header.findViewById(R.id.txtvDescription); + Spinner spAlternateUrls = header.findViewById(R.id.spinnerAlternateUrls); - subscribeButton = (Button) header.findViewById(R.id.butSubscribe); + subscribeButton = header.findViewById(R.id.butSubscribe); - if (feed.getImage() != null && StringUtils.isNotBlank(feed.getImage().getDownload_url())) { + if (StringUtils.isNotBlank(feed.getImageUrl())) { Glide.with(this) - .load(feed.getImage().getDownload_url()) - .placeholder(R.color.light_gray) - .error(R.color.light_gray) - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .fitCenter() - .dontAnimate() + .load(feed.getImageUrl()) + .apply(new RequestOptions() + .placeholder(R.color.light_gray) + .error(R.color.light_gray) + .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) + .fitCenter() + .dontAnimate()) .into(cover); } @@ -527,21 +544,25 @@ public class OnlineFeedViewActivity extends AppCompatActivity { } } - private void showFeedDiscoveryDialog(File feedFile, String baseUrl) { + /** + * + * @return true if a FeedDiscoveryDialog is shown, false otherwise (e.g., due to no feed found). + */ + private boolean showFeedDiscoveryDialog(File feedFile, String baseUrl) { FeedDiscoverer fd = new FeedDiscoverer(); final Map<String, String> urlsMap; try { urlsMap = fd.findLinks(feedFile, baseUrl); if (urlsMap == null || urlsMap.isEmpty()) { - return; + return false; } } catch (IOException e) { e.printStackTrace(); - return; + return false; } if (isPaused || isFinishing()) { - return; + return false; } final List<String> titles = new ArrayList<>(); @@ -577,6 +598,7 @@ public class OnlineFeedViewActivity extends AppCompatActivity { } dialog = ab.show(); }); + return true; } private class FeedViewAuthenticationDialog extends AuthenticationDialog { 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 cd375a65a..72759c59c 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/OpmlFeedChooserActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/OpmlFeedChooserActivity.java @@ -39,9 +39,9 @@ public class OpmlFeedChooserActivity extends AppCompatActivity { super.onCreate(savedInstanceState); setContentView(R.layout.opml_selection); - butConfirm = (Button) findViewById(R.id.butConfirm); - butCancel = (Button) findViewById(R.id.butCancel); - feedlist = (ListView) findViewById(R.id.feedlist); + butConfirm = findViewById(R.id.butConfirm); + butCancel = findViewById(R.id.butCancel); + feedlist = findViewById(R.id.feedlist); feedlist.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); listAdapter = new ArrayAdapter<>(this, diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromPathActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromPathActivity.java index ed7ab5d34..a63d3b735 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromPathActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromPathActivity.java @@ -36,16 +36,16 @@ public class OpmlImportFromPathActivity extends OpmlImportBaseActivity { getSupportActionBar().setDisplayHomeAsUpEnabled(true); setContentView(R.layout.opml_import); - final TextView txtvHeaderExplanation1 = (TextView) findViewById(R.id.txtvHeadingExplanation1); - final TextView txtvExplanation1 = (TextView) findViewById(R.id.txtvExplanation1); - final TextView txtvHeaderExplanation2 = (TextView) findViewById(R.id.txtvHeadingExplanation2); - final TextView txtvExplanation2 = (TextView) findViewById(R.id.txtvExplanation2); - final TextView txtvHeaderExplanation3 = (TextView) findViewById(R.id.txtvHeadingExplanation3); + final TextView txtvHeaderExplanation1 = findViewById(R.id.txtvHeadingExplanation1); + final TextView txtvExplanation1 = findViewById(R.id.txtvExplanation1); + final TextView txtvHeaderExplanation2 = findViewById(R.id.txtvHeadingExplanation2); + final TextView txtvExplanation2 = findViewById(R.id.txtvExplanation2); + final TextView txtvHeaderExplanation3 = findViewById(R.id.txtvHeadingExplanation3); - Button butChooseFilesystem = (Button) findViewById(R.id.butChooseFileFromFilesystem); + Button butChooseFilesystem = findViewById(R.id.butChooseFileFromFilesystem); butChooseFilesystem.setOnClickListener(v -> chooseFileFromFilesystem()); - Button butChooseExternal = (Button) findViewById(R.id.butChooseFileFromExternal); + Button butChooseExternal = findViewById(R.id.butChooseFileFromExternal); butChooseExternal.setOnClickListener(v -> chooseFileFromExternal()); int nextOption = 1; 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 b01cf43e4..dc5570dc0 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportHolder.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportHolder.java @@ -14,6 +14,8 @@ import de.danoeh.antennapod.core.export.opml.OpmlElement; */ public class OpmlImportHolder { + private OpmlImportHolder(){} + private static ArrayList<OpmlElement> readElements; public static ArrayList<OpmlElement> getReadElements() { 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 3f005fe36..452e91bd3 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java @@ -12,11 +12,11 @@ import android.view.MenuItem; import android.view.ViewGroup; import android.widget.FrameLayout; -import java.lang.ref.WeakReference; - -import com.bytehamster.lib.preferencesearch.SearchPreference; import com.bytehamster.lib.preferencesearch.SearchPreferenceResult; import com.bytehamster.lib.preferencesearch.SearchPreferenceResultListener; + +import java.lang.ref.WeakReference; + import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.preferences.PreferenceController; diff --git a/app/src/main/java/de/danoeh/antennapod/activity/SplashActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/SplashActivity.java index b92ac8577..52102eee1 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/SplashActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/SplashActivity.java @@ -1,23 +1,51 @@ package de.danoeh.antennapod.activity; import android.content.Intent; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Bundle; import android.support.annotation.Nullable; +import android.support.v4.graphics.drawable.DrawableCompat; import android.support.v7.app.AppCompatActivity; +import android.widget.ProgressBar; + +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.core.storage.PodDBAdapter; +import io.reactivex.Completable; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.schedulers.Schedulers; /** - * Creator: vbarad - * Date: 2016-12-03 - * Project: AntennaPod + * Shows the AntennaPod logo while waiting for the main activity to start */ - public class SplashActivity extends AppCompatActivity { - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.splash); + + ProgressBar progressBar = findViewById(R.id.progressBar); + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + Drawable wrapDrawable = DrawableCompat.wrap(progressBar.getIndeterminateDrawable()); + DrawableCompat.setTint(wrapDrawable, 0xffffffff); + progressBar.setIndeterminateDrawable(DrawableCompat.unwrap(wrapDrawable)); + } else { + progressBar.getIndeterminateDrawable().setColorFilter(0xffffffff, PorterDuff.Mode.SRC_IN); + } - Intent intent = new Intent(this, MainActivity.class); - startActivity(intent); - finish(); - } + Completable.create(subscriber -> { + // Trigger schema updates + PodDBAdapter.getInstance().open(); + PodDBAdapter.getInstance().close(); + subscriber.onComplete(); + }) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(() -> { + Intent intent = new Intent(SplashActivity.this, MainActivity.class); + startActivity(intent); + finish(); + }); + } } diff --git a/app/src/main/java/de/danoeh/antennapod/activity/StatisticsActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/StatisticsActivity.java index b2ff43c43..37199ccf7 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/StatisticsActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/StatisticsActivity.java @@ -20,10 +20,10 @@ import de.danoeh.antennapod.adapter.StatisticsListAdapter; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.util.Converter; -import rx.Observable; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; +import io.reactivex.Observable; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; /** * Displays the 'statistics' screen @@ -35,7 +35,7 @@ public class StatisticsActivity extends AppCompatActivity private static final String PREF_NAME = "StatisticsActivityPrefs"; private static final String PREF_COUNT_ALL = "countAll"; - private Subscription subscription; + private Disposable disposable; private TextView totalTimeTextView; private ListView feedStatisticsList; private ProgressBar progressBar; @@ -53,9 +53,9 @@ public class StatisticsActivity extends AppCompatActivity prefs = getSharedPreferences(PREF_NAME, MODE_PRIVATE); countAll = prefs.getBoolean(PREF_COUNT_ALL, false); - totalTimeTextView = (TextView) findViewById(R.id.total_time); - feedStatisticsList = (ListView) findViewById(R.id.statistics_list); - progressBar = (ProgressBar) findViewById(R.id.progressBar); + totalTimeTextView = findViewById(R.id.total_time); + feedStatisticsList = findViewById(R.id.statistics_list); + progressBar = findViewById(R.id.progressBar); listAdapter = new StatisticsListAdapter(this); listAdapter.setCountAll(countAll); feedStatisticsList.setAdapter(listAdapter); @@ -119,21 +119,19 @@ public class StatisticsActivity extends AppCompatActivity } private void loadStatistics() { - if (subscription != null) { - subscription.unsubscribe(); + if (disposable != null) { + disposable.dispose(); } - subscription = Observable.fromCallable(() -> DBReader.getStatistics(countAll)) - .subscribeOn(Schedulers.newThread()) + disposable = Observable.fromCallable(() -> DBReader.getStatistics(countAll)) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { - if (result != null) { - totalTimeTextView.setText(Converter - .shortLocalizedDuration(this, countAll ? result.totalTimeCountAll : result.totalTime)); - listAdapter.update(result.feedTime); - progressBar.setVisibility(View.GONE); - totalTimeTextView.setVisibility(View.VISIBLE); - feedStatisticsList.setVisibility(View.VISIBLE); - } + totalTimeTextView.setText(Converter + .shortLocalizedDuration(this, countAll ? result.totalTimeCountAll : result.totalTime)); + listAdapter.update(result.feedTime); + progressBar.setVisibility(View.GONE); + totalTimeTextView.setVisibility(View.VISIBLE); + feedStatisticsList.setVisibility(View.VISIBLE); }, error -> Log.e(TAG, Log.getStackTraceString(error))); } diff --git a/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java index a2a49f54e..20e34cc52 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java @@ -42,7 +42,7 @@ public class StorageErrorActivity extends AppCompatActivity { setContentView(R.layout.storage_error); - Button btnChooseDataFolder = (Button) findViewById(R.id.btnChooseDataFolder); + Button btnChooseDataFolder = findViewById(R.id.btnChooseDataFolder); btnChooseDataFolder.setOnClickListener(v -> { if (Build.VERSION_CODES.KITKAT <= Build.VERSION.SDK_INT && Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) { diff --git a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java index c8fb12abc..fa5012b74 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java @@ -8,6 +8,7 @@ import android.os.Bundle; import android.os.Handler; import android.support.v4.view.WindowCompat; import android.support.v7.app.ActionBar; +import android.text.TextUtils; import android.util.Log; import android.util.Pair; import android.view.Menu; @@ -22,20 +23,19 @@ import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.SeekBar; + +import java.lang.ref.WeakReference; +import java.util.concurrent.atomic.AtomicBoolean; + import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.feed.MediaType; 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.util.gui.PictureInPictureUtil; -import de.danoeh.antennapod.core.util.playback.ExternalMedia; import de.danoeh.antennapod.core.util.playback.Playable; -import de.danoeh.antennapod.core.util.playback.PlaybackServiceStarter; import de.danoeh.antennapod.view.AspectRatioVideoView; -import java.lang.ref.WeakReference; -import java.util.concurrent.atomic.AtomicBoolean; - /** * Activity for playing video files. */ @@ -47,6 +47,7 @@ public class VideoplayerActivity extends MediaplayerActivity { */ private boolean videoControlsShowing = true; private boolean videoSurfaceCreated = false; + private boolean playbackStoppedUponExitVideo = false; private boolean destroyingDueToReload = false; private VideoControlsHider videoControlsHider = new VideoControlsHider(this); @@ -77,18 +78,9 @@ public class VideoplayerActivity extends MediaplayerActivity { @Override protected void onResume() { super.onResume(); - if (getIntent().getAction() != null - && getIntent().getAction().equals(Intent.ACTION_VIEW)) { - Intent intent = getIntent(); - Log.d(TAG, "Received VIEW intent: " + intent.getData().getPath()); - ExternalMedia media = new ExternalMedia(intent.getData().getPath(), - MediaType.VIDEO); - - new PlaybackServiceStarter(this, media) - .startWhenPrepared(true) - .shouldStream(false) - .prepareImmediately(true) - .start(); + playbackStoppedUponExitVideo = false; + if (TextUtils.equals(getIntent().getAction(), Intent.ACTION_VIEW)) { + playExternalMedia(getIntent(), MediaType.VIDEO); } else if (PlaybackService.isCasting()) { Intent intent = PlaybackService.getPlayerActivityIntent(this); if (!intent.getComponent().getClassName().equals(VideoplayerActivity.class.getName())) { @@ -101,12 +93,32 @@ public class VideoplayerActivity extends MediaplayerActivity { @Override protected void onStop() { + stopPlaybackIfUserPreferencesSpecified(); // MUST be called before super.onStop(), while it still has member variable controller super.onStop(); if (!PictureInPictureUtil.isInPictureInPictureMode(this)) { videoControlsHider.stop(); } } + void stopPlaybackIfUserPreferencesSpecified() { + // to avoid the method being called twice during leaving Videoplayer + // , which will double-pause the media + // (it is usually first called by surfaceHolderCallback.surfaceDestroyed(), + // then VideoplayerActivity.onStop() , but sometimes VideoplayerActivity.onStop() + // will first be invoked.) + if (playbackStoppedUponExitVideo) { + return; + } + playbackStoppedUponExitVideo = true; + + if (controller != null && !destroyingDueToReload + && UserPreferences.getVideoBackgroundBehavior() + != UserPreferences.VideoBackgroundBehavior.CONTINUE_PLAYING) { + Log.v(TAG, "stop video playback per UserPreference"); + controller.notifyVideoSurfaceAbandoned(); + } + } + @Override public void onUserLeaveHint () { if (!PictureInPictureUtil.isInPictureInPictureMode(this) && UserPreferences.getVideoBackgroundBehavior() @@ -153,11 +165,11 @@ public class VideoplayerActivity extends MediaplayerActivity { } super.setupGUI(); getSupportActionBar().setDisplayHomeAsUpEnabled(true); - controls = (LinearLayout) findViewById(R.id.controls); - videoOverlay = (LinearLayout) findViewById(R.id.overlay); - videoview = (AspectRatioVideoView) findViewById(R.id.videoview); - videoframe = (FrameLayout) findViewById(R.id.videoframe); - progressIndicator = (ProgressBar) findViewById(R.id.progressIndicator); + controls = findViewById(R.id.controls); + videoOverlay = findViewById(R.id.overlay); + videoview = findViewById(R.id.videoview); + videoframe = findViewById(R.id.videoframe); + progressIndicator = findViewById(R.id.progressIndicator); videoview.getHolder().addCallback(surfaceHolderCallback); videoframe.setOnTouchListener(onVideoviewTouched); videoOverlay.setOnTouchListener((view, motionEvent) -> true); // To suppress touches directly below the slider @@ -285,13 +297,12 @@ public class VideoplayerActivity extends MediaplayerActivity { @Override public void surfaceDestroyed(SurfaceHolder holder) { - Log.d(TAG, "Videosurface was destroyed"); + Log.d(TAG, "Videosurface was destroyed." ); + Log.v(TAG, " hasController=" + (controller != null) + + " , destroyingDueToReload=" + destroyingDueToReload + + " , videoBackgroundBehavior=" + UserPreferences.getVideoBackgroundBehavior()); videoSurfaceCreated = false; - if (controller != null && !destroyingDueToReload - && UserPreferences.getVideoBackgroundBehavior() - != UserPreferences.VideoBackgroundBehavior.CONTINUE_PLAYING) { - controller.notifyVideoSurfaceAbandoned(); - } + stopPlaybackIfUserPreferencesSpecified(); } }; diff --git a/app/src/main/java/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java index 8f447ac90..8fcdb4371 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java @@ -45,8 +45,6 @@ import de.danoeh.antennapod.core.service.GpodnetSyncService; public class GpodnetAuthenticationActivity extends AppCompatActivity { private static final String TAG = "GpodnetAuthActivity"; - private static final String CURRENT_STEP = "current_step"; - private ViewFlipper viewFlipper; private static final int STEP_DEFAULT = -1; @@ -72,7 +70,7 @@ public class GpodnetAuthenticationActivity extends AppCompatActivity { setContentView(R.layout.gpodnetauth_activity); service = new GpodnetService(); - viewFlipper = (ViewFlipper) findViewById(R.id.viewflipper); + viewFlipper = findViewById(R.id.viewflipper); LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); views = new View[]{ @@ -109,11 +107,11 @@ public class GpodnetAuthenticationActivity extends AppCompatActivity { } private void setupLoginView(View view) { - final EditText username = (EditText) view.findViewById(R.id.etxtUsername); - final EditText password = (EditText) view.findViewById(R.id.etxtPassword); - final Button login = (Button) view.findViewById(R.id.butLogin); - final TextView txtvError = (TextView) view.findViewById(R.id.txtvError); - final ProgressBar progressBar = (ProgressBar) view.findViewById(R.id.progBarLogin); + final EditText username = view.findViewById(R.id.etxtUsername); + final EditText password = view.findViewById(R.id.etxtPassword); + final Button login = view.findViewById(R.id.butLogin); + final TextView txtvError = view.findViewById(R.id.txtvError); + final ProgressBar progressBar = view.findViewById(R.id.progBarLogin); password.setOnEditorActionListener((v, actionID, event) -> actionID == EditorInfo.IME_ACTION_GO && login.performClick()); @@ -177,13 +175,13 @@ public class GpodnetAuthenticationActivity extends AppCompatActivity { } private void setupDeviceView(View view) { - final EditText deviceID = (EditText) view.findViewById(R.id.etxtDeviceID); - final EditText caption = (EditText) view.findViewById(R.id.etxtCaption); - final Button createNewDevice = (Button) view.findViewById(R.id.butCreateNewDevice); - final Button chooseDevice = (Button) view.findViewById(R.id.butChooseExistingDevice); - final TextView txtvError = (TextView) view.findViewById(R.id.txtvError); - final ProgressBar progBarCreateDevice = (ProgressBar) view.findViewById(R.id.progbarCreateDevice); - final Spinner spinnerDevices = (Spinner) view.findViewById(R.id.spinnerChooseDevice); + final EditText deviceID = view.findViewById(R.id.etxtDeviceID); + final EditText caption = view.findViewById(R.id.etxtCaption); + final Button createNewDevice = view.findViewById(R.id.butCreateNewDevice); + final Button chooseDevice = view.findViewById(R.id.butChooseExistingDevice); + final TextView txtvError = view.findViewById(R.id.txtvError); + final ProgressBar progBarCreateDevice = view.findViewById(R.id.progbarCreateDevice); + final Spinner spinnerDevices = view.findViewById(R.id.spinnerChooseDevice); // load device list @@ -348,8 +346,8 @@ public class GpodnetAuthenticationActivity extends AppCompatActivity { } private void setupFinishView(View view) { - final Button sync = (Button) view.findViewById(R.id.butSyncNow); - final Button back = (Button) view.findViewById(R.id.butGoMainscreen); + final Button sync = view.findViewById(R.id.butSyncNow); + final Button back = view.findViewById(R.id.butGoMainscreen); sync.setOnClickListener(v -> { GpodnetSyncService.sendSyncIntent(GpodnetAuthenticationActivity.this); diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java index 715318db1..0b2b81edb 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java @@ -1,6 +1,7 @@ package de.danoeh.antennapod.adapter; import android.os.Build; +import android.support.annotation.Nullable; import android.support.v4.content.ContextCompat; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.helper.ItemTouchHelper; @@ -19,7 +20,6 @@ import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; -import com.bumptech.glide.Glide; import com.joanzapata.iconify.Iconify; import java.lang.ref.WeakReference; @@ -28,13 +28,12 @@ import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; -import de.danoeh.antennapod.core.glide.ApGlideSettings; -import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.storage.DownloadRequester; import de.danoeh.antennapod.core.util.Converter; import de.danoeh.antennapod.core.util.DateUtils; import de.danoeh.antennapod.core.util.LongList; import de.danoeh.antennapod.core.util.NetworkUtils; +import de.danoeh.antennapod.core.util.ThemeUtils; import de.danoeh.antennapod.fragment.ItemFragment; import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler; @@ -51,7 +50,7 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR private final ActionButtonUtils actionButtonUtils; private final boolean showOnlyNewEpisodes; - private int position = -1; + private FeedItem selectedItem; private final int playingBackGroundColor; private final int normalBackGroundColor; @@ -67,11 +66,7 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR this.actionButtonCallback = actionButtonCallback; this.showOnlyNewEpisodes = showOnlyNewEpisodes; - if(UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) { - playingBackGroundColor = ContextCompat.getColor(mainActivity, R.color.highlight_dark); - } else { - playingBackGroundColor = ContextCompat.getColor(mainActivity, R.color.highlight_light); - } + playingBackGroundColor = ThemeUtils.getColorFromAttr(mainActivity, R.attr.currently_playing_background); normalBackGroundColor = ContextCompat.getColor(mainActivity, android.R.color.transparent); } @@ -80,24 +75,24 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.new_episodes_listitem, parent, false); Holder holder = new Holder(view); - holder.container = (FrameLayout) view.findViewById(R.id.container); - holder.content = (LinearLayout) view.findViewById(R.id.content); - holder.placeholder = (TextView) view.findViewById(R.id.txtvPlaceholder); - holder.title = (TextView) view.findViewById(R.id.txtvTitle); + holder.container = view.findViewById(R.id.container); + holder.content = view.findViewById(R.id.content); + holder.placeholder = view.findViewById(R.id.txtvPlaceholder); + holder.title = view.findViewById(R.id.txtvTitle); if(Build.VERSION.SDK_INT >= 23) { holder.title.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL); } - holder.pubDate = (TextView) view + holder.pubDate = view .findViewById(R.id.txtvPublished); holder.statusUnread = view.findViewById(R.id.statusUnread); - holder.butSecondary = (ImageButton) view + holder.butSecondary = view .findViewById(R.id.butSecondaryAction); - holder.queueStatus = (ImageView) view + holder.queueStatus = view .findViewById(R.id.imgvInPlaylist); - holder.progress = (ProgressBar) view + holder.progress = view .findViewById(R.id.pbar_progress); - holder.cover = (ImageView) view.findViewById(R.id.imgvCover); - holder.txtvDuration = (TextView) view.findViewById(R.id.txtvDuration); + holder.cover = view.findViewById(R.id.imgvCover); + holder.txtvDuration = view.findViewById(R.id.txtvDuration); holder.item = null; holder.mainActivityRef = mainActivityRef; // so we can grab this later @@ -111,7 +106,7 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR final FeedItem item = itemAccess.getItem(position); if (item == null) return; holder.itemView.setOnLongClickListener(v -> { - this.position = holder.getAdapterPosition(); + this.selectedItem = item; return false; }); holder.item = item; @@ -196,12 +191,17 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR holder.butSecondary.setTag(item); holder.butSecondary.setOnClickListener(secondaryActionListener); - Glide.with(mainActivityRef.get()) - .load(item.getImageLocation()) - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .fitCenter() - .dontAnimate() - .into(new CoverTarget(item.getFeed().getImageLocation(), holder.placeholder, holder.cover, mainActivityRef.get())); + new CoverLoader(mainActivityRef.get()) + .withUri(item.getImageLocation()) + .withFallbackUri(item.getFeed().getImageLocation()) + .withPlaceholderView(holder.placeholder) + .withCoverView(holder.cover) + .load(); + } + + @Nullable + public FeedItem getSelectedItem() { + return selectedItem; } @Override @@ -215,16 +215,6 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR return itemAccess.getCount(); } - public FeedItem getItem(int position) { - return itemAccess.getItem(position); - } - - public int getPosition() { - int pos = position; - position = -1; // reset - return pos; - } - private final View.OnClickListener secondaryActionListener = new View.OnClickListener() { @Override public void onClick(View v) { @@ -299,6 +289,8 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR } }; FeedItemMenuHandler.onPrepareMenu(contextMenuInterface, item, true, null); + + contextMenuInterface.setItemVisibility(R.id.mark_as_seen_item, item.isNew()); } } diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java index f55fe72b4..c3fac7e18 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java @@ -19,9 +19,9 @@ import android.widget.TextView; import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.feed.Chapter; -import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.util.ChapterUtils; import de.danoeh.antennapod.core.util.Converter; +import de.danoeh.antennapod.core.util.ThemeUtils; import de.danoeh.antennapod.core.util.playback.Playable; public class ChaptersListAdapter extends ArrayAdapter<Chapter> { @@ -57,12 +57,12 @@ public class ChaptersListAdapter extends ArrayAdapter<Chapter> { convertView = inflater.inflate(R.layout.simplechapter_item, parent, false); holder.view = convertView; - holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); + holder.title = convertView.findViewById(R.id.txtvTitle); defaultTextColor = holder.title.getTextColors().getDefaultColor(); - holder.start = (TextView) convertView.findViewById(R.id.txtvStart); - holder.link = (TextView) convertView.findViewById(R.id.txtvLink); - holder.duration = (TextView) convertView.findViewById(R.id.txtvDuration); - holder.butPlayChapter = (ImageButton) convertView.findViewById(R.id.butPlayChapter); + holder.start = convertView.findViewById(R.id.txtvStart); + holder.link = convertView.findViewById(R.id.txtvLink); + holder.duration = convertView.findViewById(R.id.txtvDuration); + holder.butPlayChapter = convertView.findViewById(R.id.butPlayChapter); convertView.setTag(holder); } else { holder = (Holder) convertView.getTag(); @@ -143,9 +143,7 @@ public class ChaptersListAdapter extends ArrayAdapter<Chapter> { Chapter current = ChapterUtils.getCurrentChapter(media); if (current == sc) { - boolean darkTheme = UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark; - int highlight = darkTheme ? R.color.highlight_dark : R.color.highlight_light; - int playingBackGroundColor = ContextCompat.getColor(getContext(), highlight); + int playingBackGroundColor = ThemeUtils.getColorFromAttr(getContext(), R.attr.currently_playing_background); holder.view.setBackgroundColor(playingBackGroundColor); } else { holder.view.setBackgroundColor(ContextCompat.getColor(getContext(), android.R.color.transparent)); diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/CoverLoader.java b/app/src/main/java/de/danoeh/antennapod/adapter/CoverLoader.java new file mode 100644 index 000000000..54ecdae77 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/adapter/CoverLoader.java @@ -0,0 +1,113 @@ +package de.danoeh.antennapod.adapter; + +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestBuilder; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.CustomViewTarget; + +import java.lang.ref.WeakReference; + +import com.bumptech.glide.request.transition.Transition; +import de.danoeh.antennapod.activity.MainActivity; +import de.danoeh.antennapod.core.glide.ApGlideSettings; + +public class CoverLoader { + private String uri; + private String fallbackUri; + private TextView txtvPlaceholder; + private ImageView imgvCover; + private MainActivity activity; + private int errorResource = -1; + + public CoverLoader(MainActivity activity) { + this.activity = activity; + } + + public CoverLoader withUri(String uri) { + this.uri = uri; + return this; + } + + public CoverLoader withFallbackUri(String uri) { + fallbackUri = uri; + return this; + } + + public CoverLoader withCoverView(ImageView coverView) { + imgvCover = coverView; + return this; + } + + public CoverLoader withError(int errorResource) { + this.errorResource = errorResource; + return this; + } + + public CoverLoader withPlaceholderView(TextView placeholderView) { + txtvPlaceholder = placeholderView; + return this; + } + + public void load() { + RequestOptions options = new RequestOptions() + .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) + .fitCenter() + .dontAnimate(); + + if (errorResource != -1) { + options = options.error(errorResource); + } + + RequestBuilder builder = Glide.with(activity) + .load(uri) + .apply(options); + + if (fallbackUri != null && txtvPlaceholder != null && imgvCover != null) { + builder = builder.error(Glide.with(activity) + .load(fallbackUri) + .apply(options)); + } + + builder.into(new CoverTarget(txtvPlaceholder, imgvCover)); + } + + class CoverTarget extends CustomViewTarget<ImageView, Drawable> { + private final WeakReference<TextView> placeholder; + private final WeakReference<ImageView> cover; + + public CoverTarget(TextView txtvPlaceholder, ImageView imgvCover) { + super(imgvCover); + placeholder = new WeakReference<>(txtvPlaceholder); + cover = new WeakReference<>(imgvCover); + } + + @Override + public void onLoadFailed(Drawable errorDrawable) { + + } + + @Override + public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { + TextView txtvPlaceholder = placeholder.get(); + if (txtvPlaceholder != null) { + txtvPlaceholder.setVisibility(View.INVISIBLE); + } + ImageView ivCover = cover.get(); + ivCover.setImageDrawable(resource); + } + + @Override + protected void onResourceCleared(@Nullable Drawable placeholder) { + ImageView ivCover = cover.get(); + ivCover.setImageDrawable(placeholder); + } + } +}
\ No newline at end of file diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/CoverTarget.java b/app/src/main/java/de/danoeh/antennapod/adapter/CoverTarget.java deleted file mode 100644 index ba6e7b25d..000000000 --- a/app/src/main/java/de/danoeh/antennapod/adapter/CoverTarget.java +++ /dev/null @@ -1,57 +0,0 @@ -package de.danoeh.antennapod.adapter; - -import android.graphics.drawable.Drawable; -import android.view.View; -import android.widget.ImageView; -import android.widget.TextView; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.load.resource.drawable.GlideDrawable; -import com.bumptech.glide.request.animation.GlideAnimation; -import com.bumptech.glide.request.target.GlideDrawableImageViewTarget; - -import java.lang.ref.WeakReference; - -import de.danoeh.antennapod.activity.MainActivity; -import de.danoeh.antennapod.core.glide.ApGlideSettings; - -class CoverTarget extends GlideDrawableImageViewTarget { - - private final WeakReference<String> fallback; - private final WeakReference<TextView> placeholder; - private final WeakReference<ImageView> cover; - private final WeakReference<MainActivity> mainActivity; - - public CoverTarget(String fallbackUri, TextView txtvPlaceholder, ImageView imgvCover, MainActivity activity) { - super(imgvCover); - fallback = new WeakReference<>(fallbackUri); - placeholder = new WeakReference<>(txtvPlaceholder); - cover = new WeakReference<>(imgvCover); - mainActivity = new WeakReference<>(activity); - } - - @Override - public void onLoadFailed(Exception e, Drawable errorDrawable) { - String fallbackUri = fallback.get(); - TextView txtvPlaceholder = placeholder.get(); - ImageView imgvCover = cover.get(); - if (fallbackUri != null && txtvPlaceholder != null && imgvCover != null) { - MainActivity activity = mainActivity.get(); - Glide.with(activity) - .load(fallbackUri) - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .fitCenter() - .dontAnimate() - .into(new CoverTarget(null, txtvPlaceholder, imgvCover, activity)); - } - } - - @Override - public void onResourceReady(GlideDrawable drawable, GlideAnimation<? super GlideDrawable> anim) { - super.onResourceReady(drawable, anim); - TextView txtvPlaceholder = placeholder.get(); - if (txtvPlaceholder != null) { - txtvPlaceholder.setVisibility(View.INVISIBLE); - } - } -} diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java b/app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java index d8f324e8a..f54b9266e 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java @@ -1,12 +1,10 @@ package de.danoeh.antennapod.adapter; import android.content.Context; -import android.content.Intent; import android.widget.Toast; import com.afollestad.materialdialogs.MaterialDialog; -import de.danoeh.antennapod.core.util.playback.PlaybackServiceStarter; import org.apache.commons.lang3.Validate; import de.danoeh.antennapod.R; @@ -20,15 +18,17 @@ import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.storage.DownloadRequestException; import de.danoeh.antennapod.core.storage.DownloadRequester; +import de.danoeh.antennapod.core.util.IntentUtils; import de.danoeh.antennapod.core.util.LongList; import de.danoeh.antennapod.core.util.NetworkUtils; +import de.danoeh.antennapod.core.util.playback.PlaybackServiceStarter; /** * Default implementation of an ActionButtonCallback */ public class DefaultActionButtonCallback implements ActionButtonCallback { - private static final String TAG = "DefaultActionButtonCallback"; + private static final String TAG = "DefaultActionBtnCb"; private final Context context; @@ -82,17 +82,13 @@ public class DefaultActionButtonCallback implements ActionButtonCallback { } } else { // media is downloaded if (media.isCurrentlyPlaying()) { - new PlaybackServiceStarter(context, media) - .startWhenPrepared(true) - .shouldStream(false) - .start(); - context.sendBroadcast(new Intent(PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE)); + IntentUtils.sendLocalBroadcast(context, PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE); } else if (media.isCurrentlyPaused()) { - new PlaybackServiceStarter(context, media) + new PlaybackServiceStarter(context, media) // need to start the service in case it's been stopped by system. .startWhenPrepared(true) .shouldStream(false) .start(); - context.sendBroadcast(new Intent(PlaybackService.ACTION_RESUME_PLAY_CURRENT_EPISODE)); + IntentUtils.sendLocalBroadcast(context, PlaybackService.ACTION_RESUME_PLAY_CURRENT_EPISODE); } else { DBTasks.playMedia(context, media, false, true, false); } diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java index 7c0be47b6..789c01a26 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java @@ -19,7 +19,6 @@ import com.joanzapata.iconify.widget.IconTextView; import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator; import de.danoeh.antennapod.core.feed.Feed; -import de.danoeh.antennapod.core.feed.FeedImage; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.service.download.DownloadStatus; import de.danoeh.antennapod.core.storage.DBReader; @@ -50,15 +49,15 @@ public class DownloadLogAdapter extends BaseAdapter { LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.downloadlog_item, parent, false); - holder.icon = (IconTextView) convertView.findViewById(R.id.txtvIcon); - holder.retry = (IconButton) convertView.findViewById(R.id.btnRetry); - holder.date = (TextView) convertView.findViewById(R.id.txtvDate); - holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); + holder.icon = convertView.findViewById(R.id.txtvIcon); + holder.retry = convertView.findViewById(R.id.btnRetry); + holder.date = convertView.findViewById(R.id.txtvDate); + holder.title = convertView.findViewById(R.id.txtvTitle); if(Build.VERSION.SDK_INT >= 23) { holder.title.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL); } - holder.type = (TextView) convertView.findViewById(R.id.txtvType); - holder.reason = (TextView) convertView.findViewById(R.id.txtvReason); + holder.type = convertView.findViewById(R.id.txtvType); + holder.reason = convertView.findViewById(R.id.txtvReason); convertView.setTag(holder); } else { holder = (Holder) convertView.getTag(); @@ -67,8 +66,6 @@ public class DownloadLogAdapter extends BaseAdapter { holder.type.setText(R.string.download_type_feed); } else if (status.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) { holder.type.setText(R.string.download_type_media); - } else if (status.getFeedfileType() == FeedImage.FEEDFILETYPE_FEEDIMAGE) { - holder.type.setText(R.string.download_type_image); } if (status.getTitle() != null) { holder.title.setText(status.getTitle()); @@ -94,8 +91,7 @@ public class DownloadLogAdapter extends BaseAdapter { } holder.reason.setText(reasonText); holder.reason.setVisibility(View.VISIBLE); - if(status.getFeedfileType() != FeedImage.FEEDFILETYPE_FEEDIMAGE && - !newerWasSuccessful(position, status.getFeedfileType(), status.getFeedfileId())) { + if(!newerWasSuccessful(position, status.getFeedfileType(), status.getFeedfileId())) { holder.retry.setVisibility(View.VISIBLE); holder.retry.setOnClickListener(clickListener); ButtonHolder btnHolder; diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadedEpisodesListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadedEpisodesListAdapter.java index c4f476634..cd636af43 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadedEpisodesListAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadedEpisodesListAdapter.java @@ -13,9 +13,11 @@ import android.widget.TextView; import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.glide.ApGlideSettings; +import de.danoeh.antennapod.core.service.playback.PlaybackService; import de.danoeh.antennapod.core.util.Converter; import de.danoeh.antennapod.core.util.DateUtils; @@ -60,16 +62,16 @@ public class DownloadedEpisodesListAdapter extends BaseAdapter { .getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.downloaded_episodeslist_item, parent, false); - holder.imageView = (ImageView) convertView.findViewById(R.id.imgvImage); - holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); + holder.imageView = convertView.findViewById(R.id.imgvImage); + holder.title = convertView.findViewById(R.id.txtvTitle); if(Build.VERSION.SDK_INT >= 23) { holder.title.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL); } - holder.txtvSize = (TextView) convertView.findViewById(R.id.txtvSize); - holder.queueStatus = (ImageView) convertView.findViewById(R.id.imgvInPlaylist); - holder.pubDate = (TextView) convertView + holder.txtvSize = convertView.findViewById(R.id.txtvSize); + holder.queueStatus = convertView.findViewById(R.id.imgvInPlaylist); + holder.pubDate = convertView .findViewById(R.id.txtvPublished); - holder.butSecondary = (ImageButton) convertView + holder.butSecondary = convertView .findViewById(R.id.butSecondaryAction); convertView.setTag(holder); } else { @@ -78,11 +80,12 @@ public class DownloadedEpisodesListAdapter extends BaseAdapter { Glide.with(context) .load(item.getImageLocation()) - .placeholder(R.color.light_gray) - .error(R.color.light_gray) - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .fitCenter() - .dontAnimate() + .apply(new RequestOptions() + .placeholder(R.color.light_gray) + .error(R.color.light_gray) + .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) + .fitCenter() + .dontAnimate()) .into(holder.imageView); if(item.isPlayed()) { @@ -98,7 +101,7 @@ public class DownloadedEpisodesListAdapter extends BaseAdapter { holder.pubDate.setText(pubDateStr); FeedItem.State state = item.getState(); - if (state == FeedItem.State.PLAYING) { + if (state == FeedItem.State.PLAYING && PlaybackService.isRunning) { holder.butSecondary.setEnabled(false); holder.butSecondary.setAlpha(0.5f); } else { diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadlistAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadlistAdapter.java index 5bc67a95a..b85d1d35d 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadlistAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadlistAdapter.java @@ -59,14 +59,14 @@ public class DownloadlistAdapter extends BaseAdapter { LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.downloadlist_item, parent, false); - holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); - holder.downloaded = (TextView) convertView + holder.title = convertView.findViewById(R.id.txtvTitle); + holder.downloaded = convertView .findViewById(R.id.txtvDownloaded); - holder.percent = (TextView) convertView + holder.percent = convertView .findViewById(R.id.txtvPercent); - holder.progbar = (ProgressBar) convertView + holder.progbar = convertView .findViewById(R.id.progProgress); - holder.butSecondary = (ImageButton) convertView + holder.butSecondary = convertView .findViewById(R.id.butSecondaryAction); convertView.setTag(holder); @@ -121,15 +121,6 @@ public class DownloadlistAdapter extends BaseAdapter { ImageButton butSecondary; } - public int getSelectedItemIndex() { - return selectedItemIndex; - } - - public void setSelectedItemIndex(int selectedItemIndex) { - this.selectedItemIndex = selectedItemIndex; - notifyDataSetChanged(); - } - public interface ItemAccess { int getCount(); 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 e29781be1..738a0a636 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java @@ -21,7 +21,6 @@ import de.danoeh.antennapod.R; 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.preferences.UserPreferences; import de.danoeh.antennapod.core.storage.DownloadRequester; import de.danoeh.antennapod.core.util.DateUtils; import de.danoeh.antennapod.core.util.LongList; @@ -60,11 +59,7 @@ public class FeedItemlistAdapter extends BaseAdapter { this.actionButtonUtils = new ActionButtonUtils(context); this.makePlayedItemsTransparent = makePlayedItemsTransparent; - if(UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) { - playingBackGroundColor = ContextCompat.getColor(context, R.color.highlight_dark); - } else { - playingBackGroundColor = ContextCompat.getColor(context, R.color.highlight_light); - } + playingBackGroundColor = ThemeUtils.getColorFromAttr(context, R.attr.currently_playing_background); normalBackGroundColor = ContextCompat.getColor(context, android.R.color.transparent); } @@ -95,24 +90,24 @@ public class FeedItemlistAdapter extends BaseAdapter { LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.feeditemlist_item, parent, false); - holder.container = (LinearLayout) convertView + holder.container = convertView .findViewById(R.id.container); - holder.title = (TextView) convertView.findViewById(R.id.txtvItemname); + holder.title = convertView.findViewById(R.id.txtvItemname); if(Build.VERSION.SDK_INT >= 23) { holder.title.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL); } - holder.lenSize = (TextView) convertView + holder.lenSize = convertView .findViewById(R.id.txtvLenSize); - holder.butAction = (ImageButton) convertView + holder.butAction = convertView .findViewById(R.id.butSecondaryAction); - holder.published = (TextView) convertView + holder.published = convertView .findViewById(R.id.txtvPublished); - holder.inPlaylist = (ImageView) convertView + holder.inPlaylist = convertView .findViewById(R.id.imgvInPlaylist); - holder.type = (ImageView) convertView.findViewById(R.id.imgvType); + holder.type = convertView.findViewById(R.id.imgvType); holder.statusUnread = convertView .findViewById(R.id.statusUnread); - holder.episodeProgress = (ProgressBar) convertView + holder.episodeProgress = convertView .findViewById(R.id.pbar_episode_progress); convertView.setTag(holder); diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java index 5b205e91f..c10bb7638 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java @@ -34,9 +34,9 @@ public class FeedItemlistDescriptionAdapter extends ArrayAdapter<FeedItem> { LayoutInflater inflater = (LayoutInflater) getContext() .getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.itemdescription_listitem, parent, false); - holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); - holder.pubDate = (TextView) convertView.findViewById(R.id.txtvPubDate); - holder.description = (TextView) convertView.findViewById(R.id.txtvDescription); + holder.title = convertView.findViewById(R.id.txtvTitle); + holder.pubDate = convertView.findViewById(R.id.txtvPubDate); + holder.description = convertView.findViewById(R.id.txtvDescription); convertView.setTag(holder); } else { diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java index 2daa5e70f..be8e52cfc 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java @@ -8,6 +8,7 @@ import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.preference.PreferenceManager; import android.support.v7.app.AlertDialog; +import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -17,6 +18,7 @@ import android.widget.RelativeLayout; import android.widget.TextView; import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; import com.joanzapata.iconify.Iconify; import com.joanzapata.iconify.widget.IconTextView; @@ -212,11 +214,18 @@ public class NavListAdapter extends BaseAdapter v = getFeedView(position, convertView, parent); } if (v != null && viewType != VIEW_TYPE_SECTION_DIVIDER) { - TextView txtvTitle = (TextView) v.findViewById(R.id.txtvTitle); + TextView txtvTitle = v.findViewById(R.id.txtvTitle); + TypedValue typedValue = new TypedValue(); + if (position == itemAccess.getSelectedItemIndex()) { txtvTitle.setTypeface(null, Typeface.BOLD); + v.getContext().getTheme().resolveAttribute(de.danoeh.antennapod.core.R.attr.drawer_activated_color, typedValue, true); + v.setBackgroundResource(typedValue.resourceId); + } else { txtvTitle.setTypeface(null, Typeface.NORMAL); + v.getContext().getTheme().resolveAttribute(de.danoeh.antennapod.core.R.attr.nav_drawer_background, typedValue, true); + v.setBackgroundResource(typedValue.resourceId); } } return v; @@ -235,9 +244,9 @@ public class NavListAdapter extends BaseAdapter convertView = inflater.inflate(R.layout.nav_listitem, parent, false); - holder.image = (ImageView) convertView.findViewById(R.id.imgvCover); - holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); - holder.count = (TextView) convertView.findViewById(R.id.txtvCount); + holder.image = convertView.findViewById(R.id.imgvCover); + holder.title = convertView.findViewById(R.id.txtvTitle); + holder.count = convertView.findViewById(R.id.txtvCount); convertView.setTag(holder); } else { holder = (NavHolder) convertView.getTag(); @@ -325,10 +334,10 @@ public class NavListAdapter extends BaseAdapter convertView = inflater.inflate(R.layout.nav_feedlistitem, parent, false); - holder.image = (ImageView) convertView.findViewById(R.id.imgvCover); - holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); - holder.failure = (IconTextView) convertView.findViewById(R.id.itxtvFailure); - holder.count = (TextView) convertView.findViewById(R.id.txtvCount); + holder.image = convertView.findViewById(R.id.imgvCover); + holder.title = convertView.findViewById(R.id.txtvTitle); + holder.failure = convertView.findViewById(R.id.itxtvFailure); + holder.count = convertView.findViewById(R.id.txtvCount); convertView.setTag(holder); } else { holder = (FeedHolder) convertView.getTag(); @@ -336,11 +345,12 @@ public class NavListAdapter extends BaseAdapter Glide.with(context) .load(feed.getImageLocation()) - .placeholder(R.color.light_gray) - .error(R.color.light_gray) - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .fitCenter() - .dontAnimate() + .apply(new RequestOptions() + .placeholder(R.color.light_gray) + .error(R.color.light_gray) + .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) + .fitCenter() + .dontAnimate()) .into(holder.image); holder.title.setText(feed.getTitle()); diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java index 01dd4c2de..df8cafb9d 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java @@ -23,6 +23,7 @@ import android.widget.ProgressBar; import android.widget.TextView; import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; import com.joanzapata.iconify.Iconify; import org.apache.commons.lang3.ArrayUtils; @@ -40,6 +41,7 @@ import de.danoeh.antennapod.core.util.Converter; import de.danoeh.antennapod.core.util.DateUtils; import de.danoeh.antennapod.core.util.LongList; import de.danoeh.antennapod.core.util.NetworkUtils; +import de.danoeh.antennapod.core.util.ThemeUtils; import de.danoeh.antennapod.fragment.ItemFragment; import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler; @@ -75,11 +77,7 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap this.itemTouchHelper = itemTouchHelper; locked = UserPreferences.isQueueLocked(); - if(UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) { - playingBackGroundColor = ContextCompat.getColor(mainActivity, R.color.highlight_dark); - } else { - playingBackGroundColor = ContextCompat.getColor(mainActivity, R.color.highlight_light); - } + playingBackGroundColor = ThemeUtils.getColorFromAttr(mainActivity, R.attr.currently_playing_background); normalBackGroundColor = ContextCompat.getColor(mainActivity, android.R.color.transparent); } @@ -137,19 +135,19 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap public ViewHolder(View v) { super(v); - container = (FrameLayout) v.findViewById(R.id.container); - dragHandle = (ImageView) v.findViewById(R.id.drag_handle); - placeholder = (TextView) v.findViewById(R.id.txtvPlaceholder); - cover = (ImageView) v.findViewById(R.id.imgvCover); - title = (TextView) v.findViewById(R.id.txtvTitle); + container = v.findViewById(R.id.container); + dragHandle = v.findViewById(R.id.drag_handle); + placeholder = v.findViewById(R.id.txtvPlaceholder); + cover = v.findViewById(R.id.imgvCover); + title = v.findViewById(R.id.txtvTitle); if(Build.VERSION.SDK_INT >= 23) { title.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL); } - pubDate = (TextView) v.findViewById(R.id.txtvPubDate); - progressLeft = (TextView) v.findViewById(R.id.txtvProgressLeft); - progressRight = (TextView) v.findViewById(R.id.txtvProgressRight); - butSecondary = (ImageButton) v.findViewById(R.id.butSecondaryAction); - progressBar = (ProgressBar) v.findViewById(R.id.progressBar); + pubDate = v.findViewById(R.id.txtvPubDate); + progressLeft = v.findViewById(R.id.txtvProgressLeft); + progressRight = v.findViewById(R.id.txtvProgressRight); + butSecondary = v.findViewById(R.id.butSecondaryAction); + progressBar = v.findViewById(R.id.progressBar); v.setTag(this); v.setOnClickListener(this); v.setOnCreateContextMenuListener(this); @@ -294,12 +292,12 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap butSecondary.setTag(item); butSecondary.setOnClickListener(secondaryActionListener); - Glide.with(mainActivity.get()) - .load(item.getImageLocation()) - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .fitCenter() - .dontAnimate() - .into(new CoverTarget(item.getFeed().getImageLocation(), placeholder, cover, mainActivity.get())); + new CoverLoader(mainActivity.get()) + .withUri(item.getImageLocation()) + .withFallbackUri(item.getFeed().getImageLocation()) + .withPlaceholderView(placeholder) + .withCoverView(cover) + .load(); } } diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/SearchlistAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/SearchlistAdapter.java index beb62b3bb..45cb4af87 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/SearchlistAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/SearchlistAdapter.java @@ -12,6 +12,7 @@ import android.widget.TextView; import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.FeedComponent; @@ -61,13 +62,13 @@ public class SearchlistAdapter extends BaseAdapter { .getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.searchlist_item, parent, false); - holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); + holder.title = convertView.findViewById(R.id.txtvTitle); if(Build.VERSION.SDK_INT >= 23) { holder.title.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL); } - holder.cover = (ImageView) convertView + holder.cover = convertView .findViewById(R.id.imgvFeedimage); - holder.subtitle = (TextView) convertView + holder.subtitle = convertView .findViewById(R.id.txtvSubtitle); convertView.setTag(holder); @@ -81,11 +82,12 @@ public class SearchlistAdapter extends BaseAdapter { Glide.with(context) .load(feed.getImageLocation()) - .placeholder(R.color.light_gray) - .error(R.color.light_gray) - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .fitCenter() - .dontAnimate() + .apply(new RequestOptions() + .placeholder(R.color.light_gray) + .error(R.color.light_gray) + .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) + .fitCenter() + .dontAnimate()) .into(holder.cover); } else if (component.getClass() == FeedItem.class) { @@ -100,11 +102,12 @@ public class SearchlistAdapter extends BaseAdapter { Glide.with(context) .load(item.getFeed().getImageLocation()) - .placeholder(R.color.light_gray) - .error(R.color.light_gray) - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .fitCenter() - .dontAnimate() + .apply(new RequestOptions() + .placeholder(R.color.light_gray) + .error(R.color.light_gray) + .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) + .fitCenter() + .dontAnimate()) .into(holder.cover); } diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/StatisticsListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/StatisticsListAdapter.java index 50255c11f..31e82dbe0 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/StatisticsListAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/StatisticsListAdapter.java @@ -13,6 +13,7 @@ import com.bumptech.glide.Glide; import java.util.ArrayList; import java.util.List; +import com.bumptech.glide.request.RequestOptions; import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.glide.ApGlideSettings; @@ -62,9 +63,9 @@ public class StatisticsListAdapter extends BaseAdapter { convertView = inflater.inflate(R.layout.statistics_listitem, parent, false); - holder.image = (ImageView) convertView.findViewById(R.id.imgvCover); - holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); - holder.time = (TextView) convertView.findViewById(R.id.txtvTime); + holder.image = convertView.findViewById(R.id.imgvCover); + holder.title = convertView.findViewById(R.id.txtvTitle); + holder.time = convertView.findViewById(R.id.txtvTime); convertView.setTag(holder); } else { holder = (StatisticsHolder) convertView.getTag(); @@ -72,11 +73,12 @@ public class StatisticsListAdapter extends BaseAdapter { Glide.with(context) .load(feed.getImageLocation()) - .placeholder(R.color.light_gray) - .error(R.color.light_gray) - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .fitCenter() - .dontAnimate() + .apply(new RequestOptions() + .placeholder(R.color.light_gray) + .error(R.color.light_gray) + .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) + .fitCenter() + .dontAnimate()) .into(holder.image); holder.title.setText(feed.getTitle()); diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java index bb76ab501..763dcb57d 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java @@ -14,6 +14,7 @@ import com.bumptech.glide.Glide; import java.lang.ref.WeakReference; +import com.bumptech.glide.request.RequestOptions; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.core.feed.Feed; @@ -89,9 +90,9 @@ public class SubscriptionsAdapter extends BaseAdapter implements AdapterView.OnI LayoutInflater layoutInflater = (LayoutInflater) mainActivityRef.get().getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = layoutInflater.inflate(R.layout.subscription_item, parent, false); - holder.feedTitle = (TextView) convertView.findViewById(R.id.txtvTitle); - holder.imageView = (ImageView) convertView.findViewById(R.id.imgvCover); - holder.count = (TriangleLabelView) convertView.findViewById(R.id.triangleCountView); + holder.feedTitle = convertView.findViewById(R.id.txtvTitle); + holder.imageView = convertView.findViewById(R.id.imgvCover); + holder.count = convertView.findViewById(R.id.triangleCountView); convertView.setTag(holder); @@ -108,7 +109,7 @@ public class SubscriptionsAdapter extends BaseAdapter implements AdapterView.OnI holder.count.setVisibility(View.INVISIBLE); // when this holder is reused, we could else end up with a cover image - Glide.clear(holder.imageView); + Glide.with(mainActivityRef.get()).clear(holder.imageView); return convertView; } @@ -125,13 +126,13 @@ public class SubscriptionsAdapter extends BaseAdapter implements AdapterView.OnI } else { holder.count.setVisibility(View.GONE); } - Glide.with(mainActivityRef.get()) - .load(feed.getImageLocation()) - .error(R.color.light_gray) - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .fitCenter() - .dontAnimate() - .into(new CoverTarget(null, holder.feedTitle, holder.imageView, mainActivityRef.get())); + + new CoverLoader(mainActivityRef.get()) + .withUri(feed.getImageLocation()) + .withPlaceholderView(holder.feedTitle) + .withCoverView(holder.imageView) + .withError(R.color.light_gray) + .load(); return convertView; } diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/gpodnet/PodcastListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/gpodnet/PodcastListAdapter.java index aea3d583f..06c80e173 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/gpodnet/PodcastListAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/gpodnet/PodcastListAdapter.java @@ -10,6 +10,7 @@ import android.widget.TextView; import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; import org.apache.commons.lang3.StringUtils; import java.util.List; @@ -40,10 +41,10 @@ public class PodcastListAdapter extends ArrayAdapter<GpodnetPodcast> { .getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.gpodnet_podcast_listitem, parent, false); - holder.image = (ImageView) convertView.findViewById(R.id.imgvCover); - holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); - holder.subscribers = (TextView) convertView.findViewById(R.id.txtvSubscribers); - holder.url = (TextView) convertView.findViewById(R.id.txtvUrl); + holder.image = convertView.findViewById(R.id.imgvCover); + holder.title = convertView.findViewById(R.id.txtvTitle); + holder.subscribers = convertView.findViewById(R.id.txtvSubscribers); + holder.url = convertView.findViewById(R.id.txtvUrl); convertView.setTag(holder); } else { holder = (Holder) convertView.getTag(); @@ -52,11 +53,12 @@ public class PodcastListAdapter extends ArrayAdapter<GpodnetPodcast> { if (StringUtils.isNotBlank(podcast.getLogoUrl())) { Glide.with(convertView.getContext()) .load(podcast.getLogoUrl()) - .placeholder(R.color.light_gray) - .error(R.color.light_gray) - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .fitCenter() - .dontAnimate() + .apply(new RequestOptions() + .placeholder(R.color.light_gray) + .error(R.color.light_gray) + .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) + .fitCenter() + .dontAnimate()) .into(holder.image); } diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/gpodnet/TagListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/gpodnet/TagListAdapter.java index b4eadefb5..52fca792e 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/gpodnet/TagListAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/gpodnet/TagListAdapter.java @@ -34,8 +34,8 @@ public class TagListAdapter extends ArrayAdapter<GpodnetTag> { .getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.gpodnet_tag_listitem, parent, false); - holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); - holder.usage = (TextView) convertView.findViewById(R.id.txtvUsage); + holder.title = convertView.findViewById(R.id.txtvTitle); + holder.usage = convertView.findViewById(R.id.txtvUsage); convertView.setTag(holder); } else { holder = (Holder) convertView.getTag(); 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 e493a2ecc..2cf17c85f 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 @@ -12,6 +12,8 @@ import android.widget.TextView; import com.bumptech.glide.Glide; import com.bumptech.glide.load.engine.DiskCacheStrategy; +import com.bumptech.glide.request.RequestOptions; +import de.danoeh.antennapod.core.glide.ApGlideSettings; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -80,10 +82,11 @@ public class ItunesAdapter extends ArrayAdapter<ItunesAdapter.Podcast> { //Update the empty imageView with the image from the feed Glide.with(context) .load(podcast.imageUrl) - .placeholder(R.color.light_gray) - .diskCacheStrategy(DiskCacheStrategy.NONE) - .fitCenter() - .dontAnimate() + .apply(new RequestOptions() + .placeholder(R.color.light_gray) + .diskCacheStrategy(DiskCacheStrategy.NONE) + .fitCenter() + .dontAnimate()) .into(viewHolder.coverView); //Feed the grid view @@ -132,7 +135,7 @@ public class ItunesAdapter extends ArrayAdapter<ItunesAdapter.Podcast> { } public static Podcast fromSearch(SearchHit searchHit) { - return new Podcast(searchHit.getTitle(), searchHit.getImageUrl(), searchHit.getXmlUrl()); + return new Podcast(searchHit.getTitle(), searchHit.getThumbImageURL(), searchHit.getXmlUrl()); } /** @@ -182,9 +185,9 @@ public class ItunesAdapter extends ArrayAdapter<ItunesAdapter.Podcast> { * @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); + coverView = view.findViewById(R.id.imgvCover); + titleView = view.findViewById(R.id.txtvTitle); + urlView = 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 index b6cf5cb84..219725b01 100644 --- a/app/src/main/java/de/danoeh/antennapod/asynctask/ExportWorker.java +++ b/app/src/main/java/de/danoeh/antennapod/asynctask/ExportWorker.java @@ -12,7 +12,7 @@ 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; +import io.reactivex.Observable; /** * Writes an OPML file into the export directory in the background. @@ -23,15 +23,15 @@ public class ExportWorker { private static final String TAG = "ExportWorker"; private static final String DEFAULT_OUTPUT_NAME = "antennapod-feeds"; - private final ExportWriter exportWriter; - private final File output; + private final @NonNull ExportWriter exportWriter; + private final @NonNull File output; - public ExportWorker(ExportWriter exportWriter) { + public ExportWorker(@NonNull ExportWriter exportWriter) { this(exportWriter, new File(UserPreferences.getDataFolder(EXPORT_DIR), DEFAULT_OUTPUT_NAME + "." + exportWriter.fileExtension())); } - private ExportWorker(ExportWriter exportWriter, @NonNull File output) { + private ExportWorker(@NonNull ExportWriter exportWriter, @NonNull File output) { this.exportWriter = exportWriter; this.output = output; } @@ -57,7 +57,7 @@ public class ExportWorker { subscriber.onError(e); } } - subscriber.onCompleted(); + subscriber.onComplete(); } }); } diff --git a/app/src/main/java/de/danoeh/antennapod/config/ClientConfigurator.java b/app/src/main/java/de/danoeh/antennapod/config/ClientConfigurator.java index d2498955c..4138738f6 100644 --- a/app/src/main/java/de/danoeh/antennapod/config/ClientConfigurator.java +++ b/app/src/main/java/de/danoeh/antennapod/config/ClientConfigurator.java @@ -8,6 +8,8 @@ import de.danoeh.antennapod.core.ClientConfig; */ class ClientConfigurator { + private ClientConfigurator(){} + static { ClientConfig.USER_AGENT = "AntennaPod/" + BuildConfig.VERSION_NAME; ClientConfig.applicationCallbacks = new ApplicationCallbacksImpl(); diff --git a/app/src/main/java/de/danoeh/antennapod/config/PlaybackServiceCallbacksImpl.java b/app/src/main/java/de/danoeh/antennapod/config/PlaybackServiceCallbacksImpl.java index 83dd3fe9c..eb70d8e0b 100644 --- a/app/src/main/java/de/danoeh/antennapod/config/PlaybackServiceCallbacksImpl.java +++ b/app/src/main/java/de/danoeh/antennapod/config/PlaybackServiceCallbacksImpl.java @@ -2,7 +2,6 @@ package de.danoeh.antennapod.config; import android.content.Context; import android.content.Intent; - import android.os.Build; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.AudioplayerActivity; diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/AuthenticationDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/AuthenticationDialog.java index 6f9e221ec..2c41b8cb8 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/AuthenticationDialog.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/AuthenticationDialog.java @@ -35,11 +35,11 @@ public abstract class AuthenticationDialog extends Dialog { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.authentication_dialog); - final EditText etxtUsername = (EditText) findViewById(R.id.etxtUsername); - final EditText etxtPassword = (EditText) findViewById(R.id.etxtPassword); - final CheckBox saveUsernamePassword = (CheckBox) findViewById(R.id.chkSaveUsernamePassword); - final Button butConfirm = (Button) findViewById(R.id.butConfirm); - final Button butCancel = (Button) findViewById(R.id.butCancel); + final EditText etxtUsername = findViewById(R.id.etxtUsername); + final EditText etxtPassword = findViewById(R.id.etxtPassword); + final CheckBox saveUsernamePassword = findViewById(R.id.chkSaveUsernamePassword); + final Button butConfirm = findViewById(R.id.butConfirm); + final Button butCancel = findViewById(R.id.butCancel); if (titleRes != 0) { setTitle(titleRes); diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/AutoFlattrPreferenceDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/AutoFlattrPreferenceDialog.java index 93425949c..c28342374 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/AutoFlattrPreferenceDialog.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/AutoFlattrPreferenceDialog.java @@ -29,9 +29,9 @@ public class AutoFlattrPreferenceDialog { AlertDialog.Builder builder = new AlertDialog.Builder(activity); @SuppressLint("InflateParams") View view = activity.getLayoutInflater().inflate(R.layout.autoflattr_preference_dialog, null); - final CheckBox chkAutoFlattr = (CheckBox) view.findViewById(R.id.chkAutoFlattr); - final SeekBar skbPercent = (SeekBar) view.findViewById(R.id.skbPercent); - final TextView txtvStatus = (TextView) view.findViewById(R.id.txtvStatus); + final CheckBox chkAutoFlattr = view.findViewById(R.id.chkAutoFlattr); + final SeekBar skbPercent = view.findViewById(R.id.skbPercent); + final TextView txtvStatus = view.findViewById(R.id.txtvStatus); chkAutoFlattr.setChecked(UserPreferences.isAutoFlattr()); skbPercent.setEnabled(chkAutoFlattr.isChecked()); 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 10ce12771..ab9b7fcf5 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java @@ -1,11 +1,20 @@ package de.danoeh.antennapod.dialog; +import android.app.AlertDialog; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; import android.os.Bundle; +import android.support.annotation.IdRes; +import android.support.annotation.NonNull; +import android.support.annotation.PluralsRes; +import android.support.annotation.StringRes; +import android.support.design.widget.Snackbar; import android.support.v4.app.ActivityCompat; import android.support.v4.app.Fragment; import android.support.v4.util.ArrayMap; +import android.support.v7.app.ActionBar; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -13,11 +22,12 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; -import android.widget.Button; import android.widget.ListView; -import android.widget.Toast; + +import com.leinardi.android.speeddial.SpeedDialView; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; @@ -34,22 +44,42 @@ public class EpisodesApplyActionFragment extends Fragment { public static final String TAG = "EpisodeActionFragment"; - private static final int ACTION_QUEUE = 1; - private static final int ACTION_MARK_PLAYED = 2; - private static final int ACTION_MARK_UNPLAYED = 4; - private static final int ACTION_DOWNLOAD = 8; - public static final int ACTION_REMOVE = 16; - private static final int ACTION_ALL = ACTION_QUEUE | ACTION_MARK_PLAYED | ACTION_MARK_UNPLAYED - | ACTION_DOWNLOAD | ACTION_REMOVE; + public static final int ACTION_ADD_TO_QUEUE = 1; + private static final int ACTION_REMOVE_FROM_QUEUE = 2; + private static final int ACTION_MARK_PLAYED = 4; + private static final int ACTION_MARK_UNPLAYED = 8; + private static final int ACTION_DOWNLOAD = 16; + public static final int ACTION_DELETE = 32; + private static final int ACTION_ALL = ACTION_ADD_TO_QUEUE | ACTION_REMOVE_FROM_QUEUE + | ACTION_MARK_PLAYED | ACTION_MARK_UNPLAYED | ACTION_DOWNLOAD | ACTION_DELETE; + + /** + * Specify an action (defined by #flag) 's UI bindings. + * + * Includes: the menu / action item and the actual logic + */ + private class ActionBinding { + int flag; + @IdRes + final int actionItemId; + @NonNull + final Runnable action; + + ActionBinding(int flag, @IdRes int actionItemId, @NonNull Runnable action) { + this.flag = flag; + this.actionItemId = actionItemId; + this.action = action; + } + } + + private final List<? extends ActionBinding> actionBindings; private ListView mListView; private ArrayAdapter<String> mAdapter; - private Button btnAddToQueue; - private Button btnMarkAsPlayed; - private Button btnMarkAsUnplayed; - private Button btnDownload; - private Button btnDelete; + private SpeedDialView mSpeedDialView; + @NonNull + private CharSequence actionBarTitleOriginal = ""; private final Map<Long,FeedItem> idMap = new ArrayMap<>(); private final List<FeedItem> episodes = new ArrayList<>(); @@ -59,6 +89,23 @@ public class EpisodesApplyActionFragment extends Fragment { private MenuItem mSelectToggle; + public EpisodesApplyActionFragment() { + actionBindings = Arrays.asList( + new ActionBinding(ACTION_ADD_TO_QUEUE, + R.id.add_to_queue_batch, this::queueChecked), + new ActionBinding(ACTION_REMOVE_FROM_QUEUE, + R.id.remove_from_queue_batch, this::removeFromQueueChecked), + new ActionBinding(ACTION_MARK_PLAYED, + R.id.mark_read_batch, this::markedCheckedPlayed), + new ActionBinding(ACTION_MARK_UNPLAYED, + R.id.mark_unread_batch, this::markedCheckedUnplayed), + new ActionBinding(ACTION_DOWNLOAD, + R.id.download_batch, this::downloadChecked), + new ActionBinding(ACTION_DELETE, + R.id.delete_batch, this::deleteChecked) + ); + } + public static EpisodesApplyActionFragment newInstance(List<FeedItem> items) { return newInstance(items, ACTION_ALL); } @@ -76,6 +123,7 @@ public class EpisodesApplyActionFragment extends Fragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + setRetainInstance(true); setHasOptionsMenu(true); } @@ -84,7 +132,7 @@ public class EpisodesApplyActionFragment extends Fragment { Bundle savedInstanceState) { View view = inflater.inflate(R.layout.episodes_apply_action_fragment, container, false); - mListView = (ListView) view.findViewById(android.R.id.list); + mListView = view.findViewById(android.R.id.list); mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); mListView.setOnItemClickListener((ListView, view1, position, rowId) -> { long id = episodes.get(position).getId(); @@ -95,63 +143,86 @@ public class EpisodesApplyActionFragment extends Fragment { } refreshCheckboxes(); }); + mListView.setOnItemLongClickListener((adapterView, view12, position, id) -> { + new AlertDialog.Builder(getActivity()) + .setItems(R.array.batch_long_press_options, (dialogInterface, item) -> { + int direction; + if (item == 0) { + direction = -1; + } else { + direction = 1; + } + + int currentPosition = position + direction; + while (currentPosition >= 0 && currentPosition < episodes.size()) { + long id1 = episodes.get(currentPosition).getId(); + if (!checkedIds.contains(id1)) { + checkedIds.add(id1); + } + currentPosition += direction; + } + refreshCheckboxes(); + }).show(); + return true; + }); for(FeedItem episode : episodes) { titles.add(episode.getTitle()); } mAdapter = new ArrayAdapter<>(getActivity(), - android.R.layout.simple_list_item_multiple_choice, titles); + R.layout.simple_list_item_multiple_choice_on_start, titles); mListView.setAdapter(mAdapter); - checkAll(); - int lastVisibleDiv = 0; - btnAddToQueue = (Button) view.findViewById(R.id.btnAddToQueue); - if((actions & ACTION_QUEUE) != 0) { - btnAddToQueue.setOnClickListener(v -> queueChecked()); - lastVisibleDiv = R.id.divider1; - } else { - btnAddToQueue.setVisibility(View.GONE); - view.findViewById(R.id.divider1).setVisibility(View.GONE); - } - btnMarkAsPlayed = (Button) view.findViewById(R.id.btnMarkAsPlayed); - if((actions & ACTION_MARK_PLAYED) != 0) { - btnMarkAsPlayed.setOnClickListener(v -> markedCheckedPlayed()); - lastVisibleDiv = R.id.divider2; - } else { - btnMarkAsPlayed.setVisibility(View.GONE); - view.findViewById(R.id.divider2).setVisibility(View.GONE); - } - btnMarkAsUnplayed = (Button) view.findViewById(R.id.btnMarkAsUnplayed); - if((actions & ACTION_MARK_UNPLAYED) != 0) { - btnMarkAsUnplayed.setOnClickListener(v -> markedCheckedUnplayed()); - lastVisibleDiv = R.id.divider3; - } else { - btnMarkAsUnplayed.setVisibility(View.GONE); - view.findViewById(R.id.divider3).setVisibility(View.GONE); - } - btnDownload = (Button) view.findViewById(R.id.btnDownload); - if((actions & ACTION_DOWNLOAD) != 0) { - btnDownload.setOnClickListener(v -> downloadChecked()); - lastVisibleDiv = R.id.divider4; - } else { - btnDownload.setVisibility(View.GONE); - view.findViewById(R.id.divider4).setVisibility(View.GONE); - } - btnDelete = (Button) view.findViewById(R.id.btnDelete); - if((actions & ACTION_REMOVE) != 0) { - btnDelete.setOnClickListener(v -> deleteChecked()); - } else { - btnDelete.setVisibility(View.GONE); - if(lastVisibleDiv > 0) { - view.findViewById(lastVisibleDiv).setVisibility(View.GONE); + saveActionBarTitle(); // needed when we dynamically change the title based on selection + + // Init action UI (via a FAB Speed Dial) + mSpeedDialView = view.findViewById(R.id.fabSD); + mSpeedDialView.inflate(R.menu.episodes_apply_action_speeddial); + + // show only specified actions, and bind speed dial UIs to the actual logic + for (ActionBinding binding : actionBindings) { + if ((actions & binding.flag) == 0) { + mSpeedDialView.removeActionItemById(binding.actionItemId); } } + mSpeedDialView.setOnActionSelectedListener(actionItem -> { + ActionBinding selectedBinding = null; + for (ActionBinding binding : actionBindings) { + if (actionItem.getId() == binding.actionItemId) { + selectedBinding = binding; + break; + } + } + if (selectedBinding != null) { + selectedBinding.action.run(); + } else { + Log.e(TAG, "Unrecognized speed dial action item. Do nothing. id=" + actionItem.getId()); + } + return true; + }); + + showSpeedDialIfAnyChecked(); + return view; } @Override + public void onStop() { + restoreActionBarTitle(); // it might have been changed to "N selected". Restore original. + super.onStop(); + } + + private void showSpeedDialIfAnyChecked() { + mSpeedDialView.setVisibility(checkedIds.size() > 0 ? View.VISIBLE : View.GONE); + } + + private void hideSpeedDial() { + mSpeedDialView.setVisibility(View.GONE); + } + + @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); inflater.inflate(R.menu.episodes_apply_action_options, menu); @@ -173,11 +244,9 @@ public class EpisodesApplyActionFragment extends Fragment { int[] icon = new int[1]; if (checkedIds.size() == episodes.size()) { - icon[0] = R.attr.ic_check_box; - } else if (checkedIds.size() == 0) { - icon[0] = R.attr.ic_check_box_outline; + icon[0] = R.attr.ic_select_none; } else { - icon[0] = R.attr.ic_indeterminate_check_box; + icon[0] = R.attr.ic_select_all; } TypedArray a = getActivity().obtainStyledAttributes(icon); @@ -189,7 +258,7 @@ public class EpisodesApplyActionFragment extends Fragment { @Override public boolean onOptionsItemSelected(MenuItem item) { - int resId = 0; + @StringRes int resId = 0; switch(item.getItemId()) { case R.id.select_options: return true; @@ -249,7 +318,8 @@ public class EpisodesApplyActionFragment extends Fragment { return true; } if(resId != 0) { - Toast.makeText(getActivity(), resId, Toast.LENGTH_SHORT).show(); + Snackbar.make(getActivity().findViewById(R.id.content), resId, Snackbar.LENGTH_SHORT) + .show(); return true; } else { return false; @@ -387,21 +457,56 @@ public class EpisodesApplyActionFragment extends Fragment { mListView.setItemChecked(i, checked); } ActivityCompat.invalidateOptionsMenu(EpisodesApplyActionFragment.this.getActivity()); + showSpeedDialIfAnyChecked(); + updateActionBarTitle(); + } + + private void saveActionBarTitle() { + ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar(); + if (actionBar != null) { + CharSequence title = actionBar.getTitle(); + if (title == null) { + title = ""; + } + actionBarTitleOriginal = title; + } + } + + private void restoreActionBarTitle() { + ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar(); + if (actionBar != null) { + actionBar.setTitle(actionBarTitleOriginal); + } + } + + private void updateActionBarTitle() { + ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar(); + if (actionBar != null) { + CharSequence title = checkedIds.size() > 0 ? + getString(R.string.num_selected_label, checkedIds.size()) : + actionBarTitleOriginal; + actionBar.setTitle(title); + } } private void queueChecked() { DBWriter.addQueueItem(getActivity(), true, checkedIds.toArray()); - close(); + close(R.plurals.added_to_queue_batch_label, checkedIds.size()); + } + + private void removeFromQueueChecked() { + DBWriter.removeQueueItem(getActivity(), true, checkedIds.toArray()); + close(R.plurals.removed_from_queue_batch_label, checkedIds.size()); } private void markedCheckedPlayed() { DBWriter.markItemPlayed(FeedItem.PLAYED, checkedIds.toArray()); - close(); + close(R.plurals.marked_read_batch_label, checkedIds.size()); } private void markedCheckedUnplayed() { DBWriter.markItemPlayed(FeedItem.UNPLAYED, checkedIds.toArray()); - close(); + close(R.plurals.marked_unread_batch_label, checkedIds.size()); } private void downloadChecked() { @@ -418,7 +523,7 @@ public class EpisodesApplyActionFragment extends Fragment { e.printStackTrace(); DownloadRequestErrorDialogCreator.newRequestErrorDialog(getActivity(), e.getMessage()); } - close(); + close(R.plurals.downloading_batch_label, checkedIds.size()); } private void deleteChecked() { @@ -428,10 +533,18 @@ public class EpisodesApplyActionFragment extends Fragment { DBWriter.deleteFeedMediaOfItem(getActivity(), episode.getMedia().getId()); } } - close(); + close(R.plurals.deleted_episode_batch_label, checkedIds.size()); } - private void close() { + private void close(@PluralsRes int msgId, int numItems) { + if (numItems > 0) { + Snackbar.make(getActivity().findViewById(R.id.content), + getResources().getQuantityString(msgId, numItems, numItems), + Snackbar.LENGTH_LONG + ) + .setAction(android.R.string.ok, v -> {}) + .show(); + } getActivity().getSupportFragmentManager().popBackStack(); } diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/GpodnetSetHostnameDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/GpodnetSetHostnameDialog.java index e64f1e08b..933ced0f9 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/GpodnetSetHostnameDialog.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/GpodnetSetHostnameDialog.java @@ -17,6 +17,9 @@ import de.danoeh.antennapod.core.preferences.GpodnetPreferences; * Creates a dialog that lets the user change the hostname for the gpodder.net service. */ public class GpodnetSetHostnameDialog { + + private GpodnetSetHostnameDialog(){} + private static final String TAG = "GpodnetSetHostnameDialog"; public static AlertDialog createDialog(final Context context) { 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 b9276982a..8f2629b43 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java @@ -29,15 +29,15 @@ 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 io.reactivex.Single; +import io.reactivex.SingleOnSubscribe; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; import okhttp3.Credentials; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; -import rx.Observable; -import rx.Subscriber; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; public class ProxyDialog { @@ -55,7 +55,7 @@ public class ProxyDialog { private boolean testSuccessful = false; private TextView txtvMessage; - private Subscription subscription; + private Disposable disposable; public ProxyDialog(Context context) { this.context = context; @@ -102,7 +102,7 @@ public class ProxyDialog { .autoDismiss(false) .build(); View view = dialog.getCustomView(); - spType = (Spinner) view.findViewById(R.id.spType); + spType = view.findViewById(R.id.spType); String[] types = { Proxy.Type.DIRECT.name(), Proxy.Type.HTTP.name() }; ArrayAdapter<String> adapter = new ArrayAdapter<>(context, android.R.layout.simple_spinner_item, types); @@ -110,22 +110,22 @@ public class ProxyDialog { spType.setAdapter(adapter); ProxyConfig proxyConfig = UserPreferences.getProxyConfig(); spType.setSelection(adapter.getPosition(proxyConfig.type.name())); - etHost = (EditText) view.findViewById(R.id.etHost); + etHost = view.findViewById(R.id.etHost); if(!TextUtils.isEmpty(proxyConfig.host)) { etHost.setText(proxyConfig.host); } etHost.addTextChangedListener(requireTestOnChange); - etPort = (EditText) view.findViewById(R.id.etPort); + etPort = view.findViewById(R.id.etPort); if(proxyConfig.port > 0) { etPort.setText(String.valueOf(proxyConfig.port)); } etPort.addTextChangedListener(requireTestOnChange); - etUsername = (EditText) view.findViewById(R.id.etUsername); + etUsername = view.findViewById(R.id.etUsername); if(!TextUtils.isEmpty(proxyConfig.username)) { etUsername.setText(proxyConfig.username); } etUsername.addTextChangedListener(requireTestOnChange); - etPassword = (EditText) view.findViewById(R.id.etPassword); + etPassword = view.findViewById(R.id.etPassword); if(!TextUtils.isEmpty(proxyConfig.password)) { etPassword.setText(proxyConfig.username); } @@ -146,7 +146,7 @@ public class ProxyDialog { enableSettings(false); } }); - txtvMessage = (TextView) view.findViewById(R.id.txtvMessage); + txtvMessage = view.findViewById(R.id.txtvMessage); checkValidity(); return dialog; } @@ -229,8 +229,8 @@ public class ProxyDialog { } private void test() { - if(subscription != null) { - subscription.unsubscribe(); + if (disposable != null) { + disposable.dispose(); } if(!checkValidity()) { setTestRequired(true); @@ -243,7 +243,7 @@ public class ProxyDialog { txtvMessage.setTextColor(textColorPrimary); txtvMessage.setText("{fa-circle-o-notch spin} " + checking); txtvMessage.setVisibility(View.VISIBLE); - subscription = Observable.create((Observable.OnSubscribe<Response>) subscriber -> { + disposable = Single.create((SingleOnSubscribe<Response>) emitter -> { String type = (String) spType.getSelectedItem(); String host = etHost.getText().toString(); String port = etPort.getText().toString(); @@ -275,13 +275,12 @@ public class ProxyDialog { .build(); try { Response response = client.newCall(request).execute(); - subscriber.onNext(response); + emitter.onSuccess(response); } catch(IOException e) { - subscriber.onError(e); + emitter.onError(e); } - subscriber.onCompleted(); }) - .subscribeOn(Schedulers.newThread()) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( response -> { diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/RatingDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/RatingDialog.java index 72000170e..ece184035 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/RatingDialog.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/RatingDialog.java @@ -17,6 +17,8 @@ import de.danoeh.antennapod.R; public class RatingDialog { + private RatingDialog(){} + private static final String TAG = RatingDialog.class.getSimpleName(); private static final int AFTER_DAYS = 7; 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 be7850495..4b8601ec6 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java @@ -61,11 +61,11 @@ public abstract class SleepTimerDialog { dialog = builder.build(); View view = dialog.getView(); - etxtTime = (EditText) view.findViewById(R.id.etxtTime); - 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 = view.findViewById(R.id.etxtTime); + spTimeUnit = view.findViewById(R.id.spTimeUnit); + cbShakeToReset = view.findViewById(R.id.cbShakeToReset); + cbVibrate = view.findViewById(R.id.cbVibrate); + chAutoEnable = view.findViewById(R.id.chAutoEnable); etxtTime.setText(SleepTimerPreferences.lastTimerValue()); etxtTime.addTextChangedListener(new TextWatcher() { diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java index 6a975fe49..cf9a2907b 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java @@ -52,7 +52,7 @@ public class VariableSpeedDialog { builder.neutralText(R.string.close_label); builder.onPositive((dialog, which) -> { if (Build.VERSION.SDK_INT >= 16) { // just to be safe - UserPreferences.enableSonic(true); + UserPreferences.enableSonic(); if(showSpeedSelector) { showSpeedSelectorDialog(context); } 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 c050221e1..ee2373da8 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java @@ -32,18 +32,18 @@ public class AddFeedFragment extends Fragment { super.onCreateView(inflater, container, savedInstanceState); View root = inflater.inflate(R.layout.addfeed, container, false); - final EditText etxtFeedurl = (EditText) root.findViewById(R.id.etxtFeedurl); + final EditText etxtFeedurl = root.findViewById(R.id.etxtFeedurl); Bundle args = getArguments(); if (args != null && args.getString(ARG_FEED_URL) != null) { 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 = root.findViewById(R.id.butSearchItunes); + Button butBrowserGpoddernet = root.findViewById(R.id.butBrowseGpoddernet); + Button butSearchFyyd = root.findViewById(R.id.butSearchFyyd); + Button butOpmlImport = root.findViewById(R.id.butOpmlImport); + Button butConfirm = root.findViewById(R.id.butConfirm); final MainActivity activity = (MainActivity) getActivity(); activity.getSupportActionBar().setTitle(R.string.add_feed_label); @@ -66,4 +66,15 @@ public class AddFeedFragment extends Fragment { return root; } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setRetainInstance(true); + + // So, we certainly *don't* have an options menu, + // but unless we say we do, old options menus sometimes + // persist. mfietz thinks this causes the ActionBar to be invalidated + setHasOptionsMenu(true); + } } 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 f3846c8a4..20913d414 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java @@ -4,6 +4,9 @@ import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; import android.os.Bundle; +import android.os.Handler; +import android.support.annotation.NonNull; +import android.support.design.widget.Snackbar; import android.support.v4.app.Fragment; import android.support.v4.view.MenuItemCompat; import android.support.v7.widget.LinearLayoutManager; @@ -18,6 +21,7 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.ProgressBar; +import android.widget.TextView; import android.widget.Toast; import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration; @@ -36,22 +40,22 @@ import de.danoeh.antennapod.core.feed.EventDistributor; 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.preferences.UserPreferences; import de.danoeh.antennapod.core.service.download.DownloadService; import de.danoeh.antennapod.core.service.download.Downloader; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.DBWriter; -import de.danoeh.antennapod.core.storage.DownloadRequestException; import de.danoeh.antennapod.core.storage.DownloadRequester; import de.danoeh.antennapod.core.util.FeedItemUtil; import de.danoeh.antennapod.core.util.LongList; import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler; import de.danoeh.antennapod.menuhandler.MenuItemUtils; import de.greenrobot.event.EventBus; -import rx.Observable; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; +import io.reactivex.Observable; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; /** * Shows unread or recently published episodes @@ -72,6 +76,7 @@ public class AllEpisodesFragment extends Fragment { RecyclerView recyclerView; AllEpisodesRecycleAdapter listAdapter; private ProgressBar progLoading; + private View emptyView; List<FeedItem> episodes; private List<Downloader> downloaderList; @@ -82,7 +87,7 @@ public class AllEpisodesFragment extends Fragment { private boolean isUpdatingFeeds; boolean isMenuInvalidationAllowed = false; - Subscription subscription; + Disposable disposable; private LinearLayoutManager layoutManager; boolean showOnlyNewEpisodes() { return false; } @@ -123,8 +128,8 @@ public class AllEpisodesFragment extends Fragment { public void onStop() { super.onStop(); EventDistributor.getInstance().unregister(contentUpdate); - if(subscription != null) { - subscription.unsubscribe(); + if (disposable != null) { + disposable.dispose(); } } @@ -273,17 +278,23 @@ public class AllEpisodesFragment extends Fragment { if(item.getItemId() == R.id.share_item) { return true; // avoids that the position is reset when we need it in the submenu } - int pos = listAdapter.getPosition(); - if(pos < 0) { - return false; - } - FeedItem selectedItem = itemAccess.getItem(pos); + FeedItem selectedItem = listAdapter.getSelectedItem(); if (selectedItem == null) { - Log.i(TAG, "Selected item at position " + pos + " was null, ignoring selection"); + Log.i(TAG, "Selected item was null, ignoring selection"); return super.onContextItemSelected(item); } + // Mark as seen contains UI logic specific to All/New/FavoriteSegments, + // e.g., Undo with Snackbar, + // and is handled by this class rather than the generic FeedItemMenuHandler + // Undo is useful for Mark as seen, given there is no UI to undo it otherwise, + // i.e., there is context menu item for Mark as new + if (R.id.mark_as_seen_item == item.getItemId()) { + markItemAsSeenWithUndo(selectedItem); + return true; + } + return FeedItemMenuHandler.onMenuItemClicked(getActivity(), item.getItemId(), selectedItem); } @@ -301,7 +312,7 @@ public class AllEpisodesFragment extends Fragment { View root = inflater.inflate(fragmentResource, container, false); - recyclerView = (RecyclerView) root.findViewById(android.R.id.list); + recyclerView = root.findViewById(android.R.id.list); RecyclerView.ItemAnimator animator = recyclerView.getItemAnimator(); if (animator instanceof SimpleItemAnimator) { ((SimpleItemAnimator) animator).setSupportsChangeAnimations(false); @@ -311,7 +322,7 @@ public class AllEpisodesFragment extends Fragment { recyclerView.setHasFixedSize(true); recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(getActivity()).build()); - progLoading = (ProgressBar) root.findViewById(R.id.progLoading); + progLoading = root.findViewById(R.id.progLoading); if (!itemsLoaded) { progLoading.setVisibility(View.VISIBLE); @@ -323,17 +334,31 @@ public class AllEpisodesFragment extends Fragment { onFragmentLoaded(); } + emptyView = (View) root.findViewById(R.id.emptyView); + emptyView.setVisibility(View.GONE); + ((TextView)emptyView.findViewById(R.id.emptyViewTitle)).setText(R.string.no_all_episodes_head_label); + ((TextView)emptyView.findViewById(R.id.emptyViewMessage)).setText(R.string.no_all_episodes_label); + return root; } private void onFragmentLoaded() { - if (listAdapter == null) { - MainActivity mainActivity = (MainActivity) getActivity(); - listAdapter = new AllEpisodesRecycleAdapter(mainActivity, itemAccess, - new DefaultActionButtonCallback(mainActivity), showOnlyNewEpisodes()); - listAdapter.setHasStableIds(true); - recyclerView.setAdapter(listAdapter); + if (episodes != null && episodes.size() > 0) { + if (listAdapter == null) { + MainActivity mainActivity = (MainActivity) getActivity(); + listAdapter = new AllEpisodesRecycleAdapter(mainActivity, itemAccess, + new DefaultActionButtonCallback(mainActivity), showOnlyNewEpisodes()); + listAdapter.setHasStableIds(true); + recyclerView.setAdapter(listAdapter); + } + emptyView.setVisibility(View.GONE); + recyclerView.setVisibility(View.VISIBLE); + } else { + listAdapter = null; + recyclerView.setVisibility(View.GONE); + emptyView.setVisibility(View.VISIBLE); } + listAdapter.notifyDataSetChanged(); restoreScrollPosition(); getActivity().supportInvalidateOptionsMenu(); @@ -406,20 +431,26 @@ public class AllEpisodesFragment extends Fragment { public void onEventMainThread(FeedItemEvent event) { Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]"); - if(episodes == null || listAdapter == null) { + if (episodes == null || listAdapter == null) { return; } - for(int i=0, size = event.items.size(); i < size; i++) { - FeedItem item = event.items.get(i); + for (FeedItem item : event.items) { int pos = FeedItemUtil.indexOfItemWithId(episodes, item.getId()); - if(pos >= 0) { + if (pos >= 0) { episodes.remove(pos); - episodes.add(pos, item); - listAdapter.notifyItemChanged(pos); + if (shouldUpdatedItemRemainInList(item)) { + episodes.add(pos, item); + listAdapter.notifyItemChanged(pos); + } else { + listAdapter.notifyItemRemoved(pos); + } } } } + protected boolean shouldUpdatedItemRemainInList(FeedItem item) { + return true; + } public void onEventMainThread(DownloadEvent event) { Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]"); @@ -454,31 +485,63 @@ public class AllEpisodesFragment extends Fragment { } void loadItems() { - if(subscription != null) { - subscription.unsubscribe(); + if (disposable != null) { + disposable.dispose(); } if (viewsCreated && !itemsLoaded) { recyclerView.setVisibility(View.GONE); + emptyView.setVisibility(View.GONE); progLoading.setVisibility(View.VISIBLE); } - subscription = Observable.fromCallable(this::loadData) - .subscribeOn(Schedulers.newThread()) + disposable = Observable.fromCallable(this::loadData) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(data -> { recyclerView.setVisibility(View.VISIBLE); progLoading.setVisibility(View.GONE); - if (data != null) { - episodes = data; - itemsLoaded = true; - if (viewsCreated) { - onFragmentLoaded(); - } + episodes = data; + itemsLoaded = true; + if (viewsCreated) { + onFragmentLoaded(); } }, error -> Log.e(TAG, Log.getStackTraceString(error))); } + @NonNull List<FeedItem> loadData() { return DBReader.getRecentlyPublishedEpisodes(RECENT_EPISODES_LIMIT); } + void markItemAsSeenWithUndo(FeedItem item) { + if (item == null) { + return; + } + + Log.d(TAG, "markItemAsSeenWithUndo(" + item.getId() + ")"); + if (disposable != null) { + disposable.dispose(); + } + // we're marking it as unplayed since the user didn't actually play it + // but they don't want it considered 'NEW' anymore + DBWriter.markItemPlayed(FeedItem.UNPLAYED, item.getId()); + + final Handler h = new Handler(getActivity().getMainLooper()); + final Runnable r = () -> { + FeedMedia media = item.getMedia(); + if (media != null && media.hasAlmostEnded() && UserPreferences.isAutoDelete()) { + DBWriter.deleteFeedMediaOfItem(getActivity(), media.getId()); + } + }; + + Snackbar snackbar = Snackbar.make(getView(), getString(R.string.marked_as_seen_label), + Snackbar.LENGTH_LONG); + snackbar.setAction(getString(R.string.undo), v -> { + DBWriter.markItemPlayed(FeedItem.NEW, item.getId()); + // don't forget to cancel the thing that's going to remove the media + h.removeCallbacks(r); + }); + snackbar.show(); + h.postDelayed(r, (int)Math.ceil(snackbar.getDuration() * 1.05f)); + } + } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java index f59bc88bf..b52fd444f 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java @@ -1,8 +1,6 @@ package de.danoeh.antennapod.fragment; import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Color; import android.os.Bundle; import android.support.v4.app.ListFragment; import android.util.Log; @@ -12,9 +10,6 @@ import android.view.MenuItem; import android.view.View; import android.widget.ListView; -import com.joanzapata.iconify.IconDrawable; -import com.joanzapata.iconify.fonts.FontAwesomeIcons; - import java.util.List; import de.danoeh.antennapod.R; @@ -22,15 +17,15 @@ import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.adapter.DownloadedEpisodesListAdapter; import de.danoeh.antennapod.core.feed.EventDistributor; import de.danoeh.antennapod.core.feed.FeedItem; -import de.danoeh.antennapod.core.preferences.UserPreferences; 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.EpisodesApplyActionFragment; -import rx.Observable; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; +import de.danoeh.antennapod.view.EmptyViewHandler; +import io.reactivex.Observable; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; /** * Displays all running downloads and provides a button to delete them @@ -48,7 +43,7 @@ public class CompletedDownloadsFragment extends ListFragment { private boolean viewCreated = false; - private Subscription subscription; + private Disposable disposable; @Override public void onCreate(Bundle savedInstanceState) { @@ -67,16 +62,16 @@ public class CompletedDownloadsFragment extends ListFragment { public void onStop() { super.onStop(); EventDistributor.getInstance().unregister(contentUpdate); - if(subscription != null) { - subscription.unsubscribe(); + if (disposable != null) { + disposable.dispose(); } } @Override public void onDetach() { super.onDetach(); - if(subscription != null) { - subscription.unsubscribe(); + if (disposable != null) { + disposable.dispose(); } } @@ -85,8 +80,8 @@ public class CompletedDownloadsFragment extends ListFragment { super.onDestroyView(); listAdapter = null; viewCreated = false; - if(subscription != null) { - subscription.unsubscribe(); + if (disposable != null) { + disposable.dispose(); } } @@ -112,6 +107,11 @@ public class CompletedDownloadsFragment extends ListFragment { if (items != null && getActivity() != null) { onFragmentLoaded(); } + + EmptyViewHandler emptyView = new EmptyViewHandler(getActivity()); + emptyView.setTitle(R.string.no_comp_downloads_head_label); + emptyView.setMessage(R.string.no_comp_downloads_label); + emptyView.attachToListView(getListView()); } @Override @@ -149,7 +149,7 @@ public class CompletedDownloadsFragment extends ListFragment { switch (item.getItemId()) { case R.id.episode_actions: EpisodesApplyActionFragment fragment = EpisodesApplyActionFragment - .newInstance(items, EpisodesApplyActionFragment.ACTION_REMOVE); + .newInstance(items, EpisodesApplyActionFragment.ACTION_DELETE | EpisodesApplyActionFragment.ACTION_ADD_TO_QUEUE); ((MainActivity) getActivity()).loadChildFragment(fragment); return true; default: @@ -188,21 +188,19 @@ public class CompletedDownloadsFragment extends ListFragment { }; private void loadItems() { - if(subscription != null) { - subscription.unsubscribe(); + if (disposable != null) { + disposable.dispose(); } if (items == null && viewCreated) { setListShown(false); } - subscription = Observable.fromCallable(DBReader::getDownloadedItems) - .subscribeOn(Schedulers.newThread()) + disposable = Observable.fromCallable(DBReader::getDownloadedItems) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { - if (result != null) { - items = result; - if (viewCreated && getActivity() != null) { - onFragmentLoaded(); - } + items = result; + if (viewCreated && getActivity() != null) { + onFragmentLoaded(); } }, error -> Log.e(TAG, Log.getStackTraceString(error))); } 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 1d3fcefba..ef65a5755 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java @@ -11,6 +11,7 @@ import android.widget.TextView; import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MediaplayerInfoActivity.MediaplayerInfoContentFragment; import de.danoeh.antennapod.core.glide.ApGlideSettings; @@ -22,7 +23,6 @@ import de.danoeh.antennapod.core.util.playback.Playable; public class CoverFragment extends Fragment implements MediaplayerInfoContentFragment { private static final String TAG = "CoverFragment"; - private static final String ARG_PLAYABLE = "arg.playable"; private Playable media; @@ -48,10 +48,11 @@ public class CoverFragment extends Fragment implements MediaplayerInfoContentFra @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + setRetainInstance(true); root = inflater.inflate(R.layout.cover_fragment, container, false); - txtvPodcastTitle = (TextView) root.findViewById(R.id.txtvPodcastTitle); - txtvEpisodeTitle = (TextView) root.findViewById(R.id.txtvEpisodeTitle); - imgvCover = (ImageView) root.findViewById(R.id.imgvCover); + txtvPodcastTitle = root.findViewById(R.id.txtvPodcastTitle); + txtvEpisodeTitle = root.findViewById(R.id.txtvEpisodeTitle); + imgvCover = root.findViewById(R.id.imgvCover); return root; } @@ -61,9 +62,10 @@ public class CoverFragment extends Fragment implements MediaplayerInfoContentFra txtvEpisodeTitle.setText(media.getEpisodeTitle()); Glide.with(this) .load(media.getImageLocation()) - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .dontAnimate() - .fitCenter() + .apply(new RequestOptions() + .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) + .dontAnimate() + .fitCenter()) .into(imgvCover); } else { Log.w(TAG, "loadMediaInfo was called while media was null"); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java index ae9c60f65..973772049 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java @@ -12,21 +12,23 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.widget.ListView; +import android.widget.TextView; import java.util.List; -import android.widget.TextView; import de.danoeh.antennapod.R; import de.danoeh.antennapod.adapter.DownloadLogAdapter; import de.danoeh.antennapod.core.feed.EventDistributor; +import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.service.download.DownloadStatus; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBWriter; -import rx.Observable; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; +import de.danoeh.antennapod.view.EmptyViewHandler; +import io.reactivex.Observable; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; /** * Shows the download log @@ -41,7 +43,7 @@ public class DownloadLogFragment extends ListFragment { private boolean viewsCreated = false; private boolean itemsLoaded = false; - private Subscription subscription; + private Disposable disposable; @Override public void onStart() { @@ -55,8 +57,8 @@ public class DownloadLogFragment extends ListFragment { public void onStop() { super.onStop(); EventDistributor.getInstance().unregister(contentUpdate); - if(subscription != null) { - subscription.unsubscribe(); + if(disposable != null) { + disposable.dispose(); } } @@ -74,6 +76,12 @@ public class DownloadLogFragment extends ListFragment { if (itemsLoaded) { onFragmentLoaded(); } + + EmptyViewHandler emptyView = new EmptyViewHandler(getActivity()); + emptyView.setTitle(R.string.no_log_downloads_head_label); + emptyView.setMessage(R.string.no_log_downloads_label); + emptyView.attachToListView(getListView()); + } private void onFragmentLoaded() { @@ -93,10 +101,18 @@ public class DownloadLogFragment extends ListFragment { DownloadStatus status = adapter.getItem(position); String url = "unknown"; String message = getString(R.string.download_successful); - FeedMedia media = DBReader.getFeedMedia(status.getFeedfileId()); - if (media != null) { - url = media.getDownload_url(); + if (status.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) { + FeedMedia media = DBReader.getFeedMedia(status.getFeedfileId()); + if (media != null) { + url = media.getDownload_url(); + } + } else if (status.getFeedfileType() == Feed.FEEDFILETYPE_FEED) { + Feed feed = DBReader.getFeed(status.getFeedfileId()); + if (feed != null) { + url = feed.getDownload_url(); + } } + if (!status.isSuccessful()) { message = status.getReasonDetailed(); } @@ -178,11 +194,11 @@ public class DownloadLogFragment extends ListFragment { } private void loadItems() { - if(subscription != null) { - subscription.unsubscribe(); + if(disposable != null) { + disposable.dispose(); } - subscription = Observable.fromCallable(DBReader::getDownloadLog) - .subscribeOn(Schedulers.newThread()) + disposable = Observable.fromCallable(DBReader::getDownloadLog) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { if (result != null) { diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadsFragment.java index 9c4d00e31..aa6029c84 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadsFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadsFragment.java @@ -38,12 +38,12 @@ public class DownloadsFragment extends Fragment { super.onCreateView(inflater, container, savedInstanceState); View root = inflater.inflate(R.layout.pager_fragment, container, false); - viewPager = (ViewPager)root.findViewById(R.id.viewpager); + viewPager = root.findViewById(R.id.viewpager); DownloadsPagerAdapter pagerAdapter = new DownloadsPagerAdapter(getChildFragmentManager(), getResources()); viewPager.setAdapter(pagerAdapter); // Give the TabLayout the ViewPager - tabLayout = (TabLayout) root.findViewById(R.id.sliding_tabs); + tabLayout = root.findViewById(R.id.sliding_tabs); tabLayout.setupWithViewPager(viewPager); return root; diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesFragment.java index 417ecff89..0610bfd24 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesFragment.java @@ -46,11 +46,11 @@ public class EpisodesFragment extends Fragment { ((MainActivity) getActivity()).getSupportActionBar().setTitle(R.string.episodes_label); View rootView = inflater.inflate(R.layout.pager_fragment, container, false); - viewPager = (ViewPager)rootView.findViewById(R.id.viewpager); + viewPager = rootView.findViewById(R.id.viewpager); viewPager.setAdapter(new EpisodesPagerAdapter(getChildFragmentManager(), getResources())); // Give the TabLayout the ViewPager - tabLayout = (TabLayout) rootView.findViewById(R.id.sliding_tabs); + tabLayout = rootView.findViewById(R.id.sliding_tabs); tabLayout.setupWithViewPager(viewPager); return rootView; diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java index b072aeaf2..de2f04590 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java @@ -16,13 +16,17 @@ import android.widget.TextView; import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.feed.MediaType; import de.danoeh.antennapod.core.glide.ApGlideSettings; import de.danoeh.antennapod.core.service.playback.PlaybackService; -import de.danoeh.antennapod.core.util.Converter; import de.danoeh.antennapod.core.util.playback.Playable; import de.danoeh.antennapod.core.util.playback.PlaybackController; +import io.reactivex.Maybe; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; /** * Fragment which is supposed to be displayed outside of the MediaplayerActivity @@ -38,6 +42,7 @@ public class ExternalPlayerFragment extends Fragment { private TextView mFeedName; private ProgressBar mProgressBar; private PlaybackController controller; + private Disposable disposable; public ExternalPlayerFragment() { super(); @@ -48,12 +53,12 @@ public class ExternalPlayerFragment extends Fragment { Bundle savedInstanceState) { View root = inflater.inflate(R.layout.external_player_fragment, container, false); - fragmentLayout = (ViewGroup) root.findViewById(R.id.fragmentLayout); - imgvCover = (ImageView) root.findViewById(R.id.imgvCover); - txtvTitle = (TextView) root.findViewById(R.id.txtvTitle); - butPlay = (ImageButton) root.findViewById(R.id.butPlay); - mFeedName = (TextView) root.findViewById(R.id.txtvAuthor); - mProgressBar = (ProgressBar) root.findViewById(R.id.episodeProgress); + fragmentLayout = root.findViewById(R.id.fragmentLayout); + imgvCover = root.findViewById(R.id.imgvCover); + txtvTitle = root.findViewById(R.id.txtvTitle); + butPlay = root.findViewById(R.id.butPlay); + mFeedName = root.findViewById(R.id.txtvAuthor); + mProgressBar = root.findViewById(R.id.episodeProgress); fragmentLayout.setOnClickListener(v -> { Log.d(TAG, "layoutInfo was clicked"); @@ -78,7 +83,7 @@ public class ExternalPlayerFragment extends Fragment { super.onActivityCreated(savedInstanceState); controller = setupPlaybackController(); butPlay.setOnClickListener(v -> { - if(controller != null) { + if (controller != null) { controller.playPause(); } }); @@ -127,8 +132,9 @@ public class ExternalPlayerFragment extends Fragment { @Override public void onResume() { super.onResume(); - controller.init(); onPositionObserverUpdate(); + + controller.init(); } @Override @@ -138,6 +144,9 @@ public class ExternalPlayerFragment extends Fragment { if (controller != null) { controller.release(); } + if (disposable != null) { + disposable.dispose(); + } } @Override @@ -158,7 +167,7 @@ public class ExternalPlayerFragment extends Fragment { controller = setupPlaybackController(); if (butPlay != null) { butPlay.setOnClickListener(v -> { - if(controller != null) { + if (controller != null) { controller.playPause(); } }); @@ -173,7 +182,25 @@ public class ExternalPlayerFragment extends Fragment { return false; } - Playable media = controller.getMedia(); + if (disposable != null) { + disposable.dispose(); + } + disposable = Maybe.create(emitter -> { + Playable media = controller.getMedia(); + if (media != null) { + emitter.onSuccess(media); + } else { + emitter.onComplete(); + } + }) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(media -> updateUi((Playable) media), + error -> Log.e(TAG, Log.getStackTraceString(error))); + return true; + } + + private void updateUi(Playable media) { if (media != null) { txtvTitle.setText(media.getEpisodeTitle()); mFeedName.setText(media.getFeedTitle()); @@ -181,11 +208,12 @@ public class ExternalPlayerFragment extends Fragment { Glide.with(getActivity()) .load(media.getImageLocation()) - .placeholder(R.color.light_gray) - .error(R.color.light_gray) - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .fitCenter() - .dontAnimate() + .apply(new RequestOptions() + .placeholder(R.color.light_gray) + .error(R.color.light_gray) + .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) + .fitCenter() + .dontAnimate()) .into(imgvCover); fragmentLayout.setVisibility(View.VISIBLE); @@ -194,18 +222,11 @@ public class ExternalPlayerFragment extends Fragment { } else { butPlay.setVisibility(View.VISIBLE); } - return true; } else { - Log.w(TAG, "loadMediaInfo was called while the media object of playbackService was null!"); - return false; + Log.w(TAG, "loadMediaInfo was called while the media object of playbackService was null!"); } } - private String getPositionString(int position, int duration) { - return Converter.getDurationStringLong(position) + " / " - + Converter.getDurationStringLong(duration); - } - public PlaybackController getPlaybackControllerTestingOnly() { return controller; } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java index 76d19d61c..cda89bbd3 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java @@ -8,6 +8,7 @@ import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.TextView; import java.util.List; @@ -50,6 +51,8 @@ public class FavoriteEpisodesFragment extends AllEpisodesFragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View root = super.onCreateViewHelper(inflater, container, savedInstanceState, R.layout.all_episodes_fragment); + ((TextView)root.findViewById(R.id.emptyViewTitle)).setText(R.string.no_fav_episodes_head_label); + ((TextView)root.findViewById(R.id.emptyViewMessage)).setText(R.string.no_fav_episodes_label); ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) { @Override @@ -62,8 +65,8 @@ public class FavoriteEpisodesFragment extends AllEpisodesFragment { AllEpisodesRecycleAdapter.Holder holder = (AllEpisodesRecycleAdapter.Holder)viewHolder; Log.d(TAG, "remove(" + holder.getItemId() + ")"); - if (subscription != null) { - subscription.unsubscribe(); + if (disposable != null) { + disposable.dispose(); } FeedItem item = holder.getFeedItem(); if (item != null) { diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FyydSearchFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FyydSearchFragment.java index 6ee9ce467..dadc596e2 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/FyydSearchFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/FyydSearchFragment.java @@ -28,9 +28,9 @@ 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 io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; import static de.danoeh.antennapod.adapter.itunes.ItunesAdapter.Podcast; import static java.util.Collections.emptyList; @@ -55,7 +55,7 @@ public class FyydSearchFragment extends Fragment { * List of podcasts retreived from the search */ private List<Podcast> searchResults; - private Subscription subscription; + private Disposable disposable; /** * Constructor @@ -75,7 +75,7 @@ public class FyydSearchFragment extends Fragment { 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); + gridView = root.findViewById(R.id.gridView); adapter = new ItunesAdapter(getActivity(), new ArrayList<>()); gridView.setAdapter(adapter); @@ -87,10 +87,10 @@ public class FyydSearchFragment extends Fragment { 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); + progressBar = root.findViewById(R.id.progressBar); + txtvError = root.findViewById(R.id.txtvError); + butRetry = root.findViewById(R.id.butRetry); + txtvEmpty = root.findViewById(android.R.id.empty); return root; } @@ -98,8 +98,8 @@ public class FyydSearchFragment extends Fragment { @Override public void onDestroy() { super.onDestroy(); - if (subscription != null) { - subscription.unsubscribe(); + if (disposable != null) { + disposable.dispose(); } adapter = null; } @@ -141,12 +141,12 @@ public class FyydSearchFragment extends Fragment { } private void search(String query) { - if (subscription != null) { - subscription.unsubscribe(); + if (disposable != null) { + disposable.dispose(); } showOnlyProgressBar(); - subscription = client.searchPodcasts(query) - .subscribeOn(Schedulers.newThread()) + disposable = client.searchPodcasts(query, 10) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { progressBar.setVisibility(View.GONE); @@ -174,7 +174,7 @@ public class FyydSearchFragment extends Fragment { if (!response.getData().isEmpty()) { adapter.clear(); searchResults = new ArrayList<>(); - for (SearchHit searchHit : response.getData().values()) { + for (SearchHit searchHit : response.getData()) { Podcast podcast = Podcast.fromSearch(searchHit); searchResults.add(podcast); } 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 417af6133..0faf450aa 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java @@ -11,6 +11,7 @@ import android.content.res.TypedArray; import android.graphics.Color; import android.net.Uri; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.v4.app.Fragment; import android.util.Log; import android.view.ContextMenu; @@ -39,10 +40,10 @@ import de.danoeh.antennapod.core.util.ShownotesProvider; import de.danoeh.antennapod.core.util.playback.Playable; import de.danoeh.antennapod.core.util.playback.PlaybackController; import de.danoeh.antennapod.core.util.playback.Timeline; -import rx.Observable; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; +import io.reactivex.Observable; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; /** * Displays the description of a Playable object in a Webview. @@ -66,7 +67,7 @@ public class ItemDescriptionFragment extends Fragment implements MediaplayerInfo private ShownotesProvider shownotesProvider; private Playable media; - private Subscription webViewLoader; + private Disposable webViewLoader; /** * URL that was selected via long-press. @@ -113,10 +114,13 @@ public class ItemDescriptionFragment extends Fragment implements MediaplayerInfo Log.d(TAG, "Creating view"); webvDescription = new WebView(getActivity().getApplicationContext()); webvDescription.setLayerType(View.LAYER_TYPE_SOFTWARE, null); + TypedArray ta = getActivity().getTheme().obtainStyledAttributes(new int[] {android.R.attr.colorBackground}); - int backgroundColor = ta.getColor(0, UserPreferences.getTheme() == - R.style.Theme_AntennaPod_Dark ? Color.BLACK : Color.WHITE); + boolean black = UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark + || UserPreferences.getTheme() == R.style.Theme_AntennaPod_TrueBlack; + int backgroundColor = ta.getColor(0, black ? Color.BLACK : Color.WHITE); + ta.recycle(); webvDescription.setBackgroundColor(backgroundColor); if (!NetworkUtils.networkAvailable()) { @@ -164,7 +168,7 @@ public class ItemDescriptionFragment extends Fragment implements MediaplayerInfo super.onDestroy(); Log.d(TAG, "Fragment destroyed"); if (webViewLoader != null) { - webViewLoader.unsubscribe(); + webViewLoader.dispose(); } if (webvDescription != null) { webvDescription.removeAllViews(); @@ -195,7 +199,7 @@ public class ItemDescriptionFragment extends Fragment implements MediaplayerInfo } else if (args.containsKey(ARG_FEEDITEM_ID)) { long id = getArguments().getLong(ARG_FEEDITEM_ID); Observable.defer(() -> Observable.just(DBReader.getFeedItem(id))) - .subscribeOn(Schedulers.newThread()) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(feedItem -> { shownotesProvider = feedItem; @@ -295,21 +299,22 @@ public class ItemDescriptionFragment extends Fragment implements MediaplayerInfo private void load() { Log.d(TAG, "load()"); if(webViewLoader != null) { - webViewLoader.unsubscribe(); + webViewLoader.dispose(); } if(shownotesProvider == null) { return; } - webViewLoader = Observable.defer(() -> Observable.just(loadData())) - .subscribeOn(Schedulers.newThread()) + webViewLoader = Observable.fromCallable(this::loadData) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(data -> { - webvDescription.loadDataWithBaseURL(null, data, "text/html", + webvDescription.loadDataWithBaseURL("https://127.0.0.1", data, "text/html", "utf-8", "about:blank"); Log.d(TAG, "Webview loaded"); }, error -> Log.e(TAG, Log.getStackTraceString(error))); } + @NonNull private String loadData() { Timeline timeline = new Timeline(getActivity(), shownotesProvider); return timeline.processShownotes(highlightTimecodes); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java index 6b589493b..e114ef405 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java @@ -31,11 +31,10 @@ import android.widget.TextView; import android.widget.Toast; import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; import com.joanzapata.iconify.Iconify; import com.joanzapata.iconify.widget.IconButton; -import de.danoeh.antennapod.core.service.playback.PlaybackService; -import de.danoeh.antennapod.core.util.NetworkUtils; import org.apache.commons.lang3.ArrayUtils; import java.util.List; @@ -53,26 +52,27 @@ import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.glide.ApGlideSettings; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.service.download.Downloader; +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.storage.DownloadRequestException; import de.danoeh.antennapod.core.storage.DownloadRequester; import de.danoeh.antennapod.core.util.Converter; import de.danoeh.antennapod.core.util.DateUtils; import de.danoeh.antennapod.core.util.Flavors; import de.danoeh.antennapod.core.util.IntentUtils; import de.danoeh.antennapod.core.util.LongList; +import de.danoeh.antennapod.core.util.NetworkUtils; import de.danoeh.antennapod.core.util.ShareUtils; import de.danoeh.antennapod.core.util.playback.Timeline; import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler; import de.danoeh.antennapod.view.OnSwipeGesture; import de.danoeh.antennapod.view.SwipeGestureDetector; import de.greenrobot.event.EventBus; -import rx.Observable; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; +import io.reactivex.Observable; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; /** * Displays information about a FeedItem and actions. @@ -135,7 +135,7 @@ public class ItemFragment extends Fragment implements OnSwipeGesture { private IconButton butAction2; private Menu popupMenu; - private Subscription subscription; + private Disposable disposable; /** * URL that was selected via long-press. @@ -166,26 +166,27 @@ public class ItemFragment extends Fragment implements OnSwipeGesture { super.onCreateView(inflater, container, savedInstanceState); View layout = inflater.inflate(R.layout.feeditem_fragment, container, false); - root = (ViewGroup) layout.findViewById(R.id.content_root); + root = layout.findViewById(R.id.content_root); - LinearLayout header = (LinearLayout) root.findViewById(R.id.header); + LinearLayout header = root.findViewById(R.id.header); if(feedItems.length > 0) { header.setOnTouchListener((v, event) -> headerGestureDetector.onTouchEvent(event)); } - txtvPodcast = (TextView) layout.findViewById(R.id.txtvPodcast); + txtvPodcast = layout.findViewById(R.id.txtvPodcast); txtvPodcast.setOnClickListener(v -> openPodcast()); - txtvTitle = (TextView) layout.findViewById(R.id.txtvTitle); + txtvTitle = layout.findViewById(R.id.txtvTitle); if(Build.VERSION.SDK_INT >= 23) { txtvTitle.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL); } - txtvDuration = (TextView) layout.findViewById(R.id.txtvDuration); - txtvPublished = (TextView) layout.findViewById(R.id.txtvPublished); + txtvDuration = layout.findViewById(R.id.txtvDuration); + txtvPublished = layout.findViewById(R.id.txtvPublished); if (Build.VERSION.SDK_INT >= 14) { // ellipsize is causing problems on old versions, see #448 txtvTitle.setEllipsize(TextUtils.TruncateAt.END); } - webvDescription = (WebView) layout.findViewById(R.id.webvDescription); - if (UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) { + webvDescription = layout.findViewById(R.id.webvDescription); + if (UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark || + UserPreferences.getTheme() == R.style.Theme_AntennaPod_TrueBlack) { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { webvDescription.setLayerType(View.LAYER_TYPE_SOFTWARE, null); } @@ -215,12 +216,12 @@ public class ItemFragment extends Fragment implements OnSwipeGesture { }); registerForContextMenu(webvDescription); - imgvCover = (ImageView) layout.findViewById(R.id.imgvCover); + imgvCover = layout.findViewById(R.id.imgvCover); imgvCover.setOnClickListener(v -> openPodcast()); - progbarDownload = (ProgressBar) layout.findViewById(R.id.progbarDownload); - progbarLoading = (ProgressBar) layout.findViewById(R.id.progbarLoading); - butAction1 = (IconButton) layout.findViewById(R.id.butAction1); - butAction2 = (IconButton) layout.findViewById(R.id.butAction2); + progbarDownload = layout.findViewById(R.id.progbarDownload); + progbarLoading = layout.findViewById(R.id.progbarLoading); + butAction1 = layout.findViewById(R.id.butAction1); + butAction2 = layout.findViewById(R.id.butAction2); butAction1.setOnClickListener(v -> { if (item == null) { @@ -285,8 +286,8 @@ public class ItemFragment extends Fragment implements OnSwipeGesture { @Override public void onDestroyView() { super.onDestroyView(); - if(subscription != null) { - subscription.unsubscribe(); + if(disposable != null) { + disposable.dispose(); } if (webvDescription != null && root != null) { root.removeView(webvDescription); @@ -357,7 +358,7 @@ public class ItemFragment extends Fragment implements OnSwipeGesture { private void onFragmentLoaded() { if (webviewData != null) { - webvDescription.loadDataWithBaseURL(null, webviewData, "text/html", "utf-8", "about:blank"); + webvDescription.loadDataWithBaseURL("https://127.0.0.1", webviewData, "text/html", "utf-8", "about:blank"); } updateAppearance(); } @@ -378,11 +379,12 @@ public class ItemFragment extends Fragment implements OnSwipeGesture { Glide.with(getActivity()) .load(item.getImageLocation()) - .placeholder(R.color.light_gray) - .error(R.color.light_gray) - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .fitCenter() - .dontAnimate() + .apply(new RequestOptions() + .placeholder(R.color.light_gray) + .error(R.color.light_gray) + .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) + .fitCenter() + .dontAnimate()) .into(imgvCover); progbarDownload.setVisibility(View.GONE); @@ -435,7 +437,7 @@ public class ItemFragment extends Fragment implements OnSwipeGesture { } FeedItem.State state = item.getState(); - if (butAction2Text == R.string.delete_label && state == FeedItem.State.PLAYING) { + if (butAction2Text == R.string.delete_label && state == FeedItem.State.PLAYING && PlaybackService.isRunning) { butAction2.setEnabled(false); butAction2.setAlpha(0.5f); } else { @@ -571,12 +573,12 @@ public class ItemFragment extends Fragment implements OnSwipeGesture { }; private void load() { - if(subscription != null) { - subscription.unsubscribe(); + if(disposable != null) { + disposable.dispose(); } progbarLoading.setVisibility(View.VISIBLE); - subscription = Observable.fromCallable(this::loadInBackground) - .subscribeOn(Schedulers.newThread()) + disposable = Observable.fromCallable(this::loadInBackground) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { progbarLoading.setVisibility(View.GONE); @@ -586,6 +588,7 @@ public class ItemFragment extends Fragment implements OnSwipeGesture { }, error -> Log.e(TAG, Log.getStackTraceString(error))); } + @Nullable private FeedItem loadInBackground() { FeedItem feedItem = DBReader.getFeedItem(feedItems[feedItemPos]); if (feedItem != null) { 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 83d6f9615..dfd9ac924 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java @@ -4,10 +4,9 @@ import android.annotation.SuppressLint; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; -import android.content.res.TypedArray; -import android.graphics.Color; import android.graphics.LightingColorFilter; import android.os.Bundle; +import android.support.annotation.Nullable; import android.support.v4.app.ListFragment; import android.support.v4.view.MenuItemCompat; import android.support.v7.widget.SearchView; @@ -26,18 +25,17 @@ import android.widget.RelativeLayout; import android.widget.TextView; import com.bumptech.glide.Glide; -import com.joanzapata.iconify.IconDrawable; +import com.bumptech.glide.request.RequestOptions; import com.joanzapata.iconify.Iconify; -import com.joanzapata.iconify.fonts.FontAwesomeIcons; import com.joanzapata.iconify.widget.IconTextView; -import de.danoeh.antennapod.activity.FeedSettingsActivity; import org.apache.commons.lang3.Validate; import java.util.List; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.FeedInfoActivity; +import de.danoeh.antennapod.activity.FeedSettingsActivity; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.adapter.DefaultActionButtonCallback; import de.danoeh.antennapod.adapter.FeedItemlistAdapter; @@ -55,7 +53,6 @@ import de.danoeh.antennapod.core.feed.FeedItemFilter; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.glide.ApGlideSettings; import de.danoeh.antennapod.core.glide.FastBlurTransformation; -import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.service.download.DownloadService; import de.danoeh.antennapod.core.service.download.Downloader; import de.danoeh.antennapod.core.storage.DBReader; @@ -71,10 +68,10 @@ import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler; import de.danoeh.antennapod.menuhandler.FeedMenuHandler; import de.danoeh.antennapod.menuhandler.MenuItemUtils; import de.greenrobot.event.EventBus; -import rx.Observable; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; +import io.reactivex.Observable; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; /** * Displays a list of FeedItems. @@ -114,7 +111,7 @@ public class ItemlistFragment extends ListFragment { private TextView txtvInformation; - private Subscription subscription; + private Disposable disposable; /** * Creates new ItemlistFragment which shows the Feeditems of a specific @@ -165,8 +162,8 @@ public class ItemlistFragment extends ListFragment { super.onPause(); EventDistributor.getInstance().unregister(contentUpdate); EventBus.getDefault().unregister(this); - if(subscription != null) { - subscription.unsubscribe(); + if(disposable != null) { + disposable.dispose(); } } @@ -417,13 +414,10 @@ public class ItemlistFragment extends ListFragment { } - private boolean insideOnFragmentLoaded = false; - private void onFragmentLoaded() { if(!isVisible()) { return; } - insideOnFragmentLoaded = true; if (adapter == null) { setListAdapter(null); setupHeaderView(); @@ -440,9 +434,6 @@ public class ItemlistFragment extends ListFragment { if (feed != null && feed.getNextPageLink() == null && listFooter != null) { getListView().removeFooterView(listFooter.getRoot()); } - - insideOnFragmentLoaded = false; - } private void refreshHeaderView() { @@ -486,14 +477,14 @@ public class ItemlistFragment extends ListFragment { View header = inflater.inflate(R.layout.feeditemlist_header, lv, false); lv.addHeaderView(header); - txtvTitle = (TextView) header.findViewById(R.id.txtvTitle); - TextView txtvAuthor = (TextView) header.findViewById(R.id.txtvAuthor); - imgvBackground = (ImageView) header.findViewById(R.id.imgvBackground); - imgvCover = (ImageView) header.findViewById(R.id.imgvCover); - ImageButton butShowInfo = (ImageButton) header.findViewById(R.id.butShowInfo); - ImageButton butShowSettings = (ImageButton) header.findViewById(R.id.butShowSettings); - txtvInformation = (TextView) header.findViewById(R.id.txtvInformation); - txtvFailure = (IconTextView) header.findViewById(R.id.txtvFailure); + txtvTitle = header.findViewById(R.id.txtvTitle); + TextView txtvAuthor = header.findViewById(R.id.txtvAuthor); + imgvBackground = header.findViewById(R.id.imgvBackground); + imgvCover = header.findViewById(R.id.imgvCover); + ImageButton butShowInfo = header.findViewById(R.id.butShowInfo); + ImageButton butShowSettings = header.findViewById(R.id.butShowSettings); + txtvInformation = header.findViewById(R.id.txtvInformation); + txtvFailure = header.findViewById(R.id.txtvFailure); txtvTitle.setText(feed.getTitle()); txtvAuthor.setText(feed.getAuthor()); @@ -529,20 +520,22 @@ public class ItemlistFragment extends ListFragment { private void loadFeedImage() { Glide.with(getActivity()) .load(feed.getImageLocation()) - .placeholder(R.color.image_readability_tint) - .error(R.color.image_readability_tint) - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .transform(new FastBlurTransformation(getActivity())) - .dontAnimate() + .apply(new RequestOptions() + .placeholder(R.color.image_readability_tint) + .error(R.color.image_readability_tint) + .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) + .transform(new FastBlurTransformation()) + .dontAnimate()) .into(imgvBackground); Glide.with(getActivity()) .load(feed.getImageLocation()) - .placeholder(R.color.light_gray) - .error(R.color.light_gray) - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .fitCenter() - .dontAnimate() + .apply(new RequestOptions() + .placeholder(R.color.light_gray) + .error(R.color.light_gray) + .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) + .fitCenter() + .dontAnimate()) .into(imgvCover); } @@ -618,23 +611,22 @@ public class ItemlistFragment extends ListFragment { private void loadItems() { - if(subscription != null) { - subscription.unsubscribe(); + if(disposable != null) { + disposable.dispose(); } - subscription = Observable.fromCallable(this::loadData) - .subscribeOn(Schedulers.newThread()) + disposable = Observable.fromCallable(this::loadData) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { - if (result != null) { - feed = result; - itemsLoaded = true; - if (viewsCreated) { - onFragmentLoaded(); - } + feed = result; + itemsLoaded = true; + if (viewsCreated) { + onFragmentLoaded(); } }, error -> Log.e(TAG, Log.getStackTraceString(error))); } + @Nullable private Feed loadData() { Feed feed = DBReader.getFeed(feedID); DBReader.loadAdditionalFeedItemListData(feed.getItems()); 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 08610c1f3..486727313 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java @@ -36,13 +36,14 @@ 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 io.reactivex.Single; +import io.reactivex.SingleOnSubscribe; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; -import rx.Observable; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; import static de.danoeh.antennapod.adapter.itunes.ItunesAdapter.Podcast; @@ -69,7 +70,7 @@ public class ItunesSearchFragment extends Fragment { */ private List<Podcast> searchResults; private List<Podcast> topList; - private Subscription subscription; + private Disposable disposable; /** * Replace adapter data with provided search results from SearchTask. @@ -109,7 +110,7 @@ public class ItunesSearchFragment extends Fragment { 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); + gridView = root.findViewById(R.id.gridView); adapter = new ItunesAdapter(getActivity(), new ArrayList<>()); gridView.setAdapter(adapter); @@ -127,7 +128,7 @@ public class ItunesSearchFragment extends Fragment { } else { gridView.setVisibility(View.GONE); progressBar.setVisibility(View.VISIBLE); - subscription = Observable.create((Observable.OnSubscribe<String>) subscriber -> { + disposable = Single.create((SingleOnSubscribe<String>) emitter -> { OkHttpClient client = AntennapodHttpClient.getHttpClient(); Request.Builder httpReq = new Request.Builder() .url(podcast.feedUrl) @@ -139,17 +140,16 @@ public class ItunesSearchFragment extends Fragment { JSONObject result = new JSONObject(resultString); JSONObject results = result.getJSONArray("results").getJSONObject(0); String feedUrl = results.getString("feedUrl"); - subscriber.onNext(feedUrl); + emitter.onSuccess(feedUrl); } else { String prefix = getString(R.string.error_msg_prefix); - subscriber.onError(new IOException(prefix + response)); + emitter.onError(new IOException(prefix + response)); } } catch (IOException | JSONException e) { - subscriber.onError(e); + emitter.onError(e); } - subscriber.onCompleted(); }) - .subscribeOn(Schedulers.newThread()) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(feedUrl -> { progressBar.setVisibility(View.GONE); @@ -170,10 +170,10 @@ public class ItunesSearchFragment extends Fragment { }); } }); - 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); + progressBar = root.findViewById(R.id.progressBar); + txtvError = root.findViewById(R.id.txtvError); + butRetry = root.findViewById(R.id.butRetry); + txtvEmpty = root.findViewById(android.R.id.empty); loadToplist(); @@ -183,8 +183,8 @@ public class ItunesSearchFragment extends Fragment { @Override public void onDestroy() { super.onDestroy(); - if (subscription != null) { - subscription.unsubscribe(); + if (disposable != null) { + disposable.dispose(); } adapter = null; } @@ -228,15 +228,15 @@ public class ItunesSearchFragment extends Fragment { } private void loadToplist() { - if (subscription != null) { - subscription.unsubscribe(); + if (disposable != null) { + disposable.dispose(); } gridView.setVisibility(View.GONE); txtvError.setVisibility(View.GONE); butRetry.setVisibility(View.GONE); txtvEmpty.setVisibility(View.GONE); progressBar.setVisibility(View.VISIBLE); - subscription = Observable.create((Observable.OnSubscribe<List<Podcast>>) subscriber -> { + disposable = Single.create((SingleOnSubscribe<List<Podcast>>) emitter -> { String lang = Locale.getDefault().getLanguage(); String url = "https://itunes.apple.com/" + lang + "/rss/toppodcasts/limit=25/explicit=true/json"; OkHttpClient client = AntennapodHttpClient.getHttpClient(); @@ -268,15 +268,14 @@ public class ItunesSearchFragment extends Fragment { } else { String prefix = getString(R.string.error_msg_prefix); - subscriber.onError(new IOException(prefix + response)); + emitter.onError(new IOException(prefix + response)); } } catch (IOException | JSONException e) { - subscriber.onError(e); + emitter.onError(e); } - subscriber.onNext(results); - subscriber.onCompleted(); + emitter.onSuccess(results); }) - .subscribeOn(Schedulers.newThread()) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(podcasts -> { progressBar.setVisibility(View.GONE); @@ -293,15 +292,15 @@ public class ItunesSearchFragment extends Fragment { } private void search(String query) { - if (subscription != null) { - subscription.unsubscribe(); + if (disposable != null) { + disposable.dispose(); } gridView.setVisibility(View.GONE); txtvError.setVisibility(View.GONE); butRetry.setVisibility(View.GONE); txtvEmpty.setVisibility(View.GONE); progressBar.setVisibility(View.VISIBLE); - subscription = rx.Observable.create((Observable.OnSubscribe<List<Podcast>>) subscriber -> { + disposable = Single.create((SingleOnSubscribe<List<Podcast>>) subscriber -> { String encodedQuery = null; try { encodedQuery = URLEncoder.encode(query, "UTF-8"); @@ -312,8 +311,7 @@ public class ItunesSearchFragment extends Fragment { encodedQuery = query; // failsafe } - //Spaces in the query need to be replaced with '+' character. - String formattedUrl = String.format(API_URL, query).replace(' ', '+'); + String formattedUrl = String.format(API_URL, encodedQuery); OkHttpClient client = AntennapodHttpClient.getHttpClient(); Request.Builder httpReq = new Request.Builder() @@ -341,10 +339,9 @@ public class ItunesSearchFragment extends Fragment { } catch (IOException | JSONException e) { subscriber.onError(e); } - subscriber.onNext(podcasts); - subscriber.onCompleted(); + subscriber.onSuccess(podcasts); }) - .subscribeOn(Schedulers.newThread()) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(podcasts -> { progressBar.setVisibility(View.GONE); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java index c136eb6ae..c2b61bf75 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java @@ -1,25 +1,19 @@ package de.danoeh.antennapod.fragment; import android.os.Bundle; -import android.os.Handler; -import android.support.design.widget.Snackbar; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.helper.ItemTouchHelper; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - +import android.widget.TextView; import java.util.List; - import de.danoeh.antennapod.R; import de.danoeh.antennapod.adapter.AllEpisodesRecycleAdapter; import de.danoeh.antennapod.core.event.FeedItemEvent; import de.danoeh.antennapod.core.feed.FeedItem; -import de.danoeh.antennapod.core.feed.FeedMedia; -import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.storage.DBReader; -import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.util.FeedItemUtil; @@ -31,9 +25,7 @@ import de.danoeh.antennapod.core.util.FeedItemUtil; public class NewEpisodesFragment extends AllEpisodesFragment { public static final String TAG = "NewEpisodesFragment"; - private static final String PREF_NAME = "PrefNewEpisodesFragment"; - @Override protected boolean showOnlyNewEpisodes() { return true; } @@ -46,24 +38,16 @@ public class NewEpisodesFragment extends AllEpisodesFragment { } @Override - public void onEventMainThread(FeedItemEvent event) { - Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]"); - if(episodes == null) { - return; - } - for(FeedItem item : event.items) { - int pos = FeedItemUtil.indexOfItemWithId(episodes, item.getId()); - if(pos >= 0 && item.isTagged(FeedItem.TAG_QUEUE)) { - episodes.remove(pos); - listAdapter.notifyItemRemoved(pos); - } - } + protected boolean shouldUpdatedItemRemainInList(FeedItem item) { + return item.isNew(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View root = super.onCreateViewHelper(inflater, container, savedInstanceState, R.layout.all_episodes_fragment); + ((TextView)root.findViewById(R.id.emptyViewTitle)).setText(R.string.no_new_episodes_head_label); + ((TextView)root.findViewById(R.id.emptyViewMessage)).setText(R.string.no_new_episodes_label); ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) { @Override @@ -74,33 +58,7 @@ public class NewEpisodesFragment extends AllEpisodesFragment { @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) { AllEpisodesRecycleAdapter.Holder holder = (AllEpisodesRecycleAdapter.Holder)viewHolder; - - Log.d(TAG, "remove(" + holder.getItemId() + ")"); - if (subscription != null) { - subscription.unsubscribe(); - } - FeedItem item = holder.getFeedItem(); - // we're marking it as unplayed since the user didn't actually play it - // but they don't want it considered 'NEW' anymore - DBWriter.markItemPlayed(FeedItem.UNPLAYED, item.getId()); - - final Handler h = new Handler(getActivity().getMainLooper()); - final Runnable r = () -> { - FeedMedia media = item.getMedia(); - if (media != null && media.hasAlmostEnded() && UserPreferences.isAutoDelete()) { - DBWriter.deleteFeedMediaOfItem(getActivity(), media.getId()); - } - }; - - Snackbar snackbar = Snackbar.make(root, getString(R.string.marked_as_seen_label), - Snackbar.LENGTH_LONG); - snackbar.setAction(getString(R.string.undo), v -> { - DBWriter.markItemPlayed(FeedItem.NEW, item.getId()); - // don't forget to cancel the thing that's going to remove the media - h.removeCallbacks(r); - }); - snackbar.show(); - h.postDelayed(r, (int)Math.ceil(snackbar.getDuration() * 1.05f)); + markItemAsSeenWithUndo(holder.getFeedItem()); } @Override diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java index fb6280021..e8f35b180 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java @@ -3,6 +3,7 @@ package de.danoeh.antennapod.fragment; import android.content.Context; import android.content.res.TypedArray; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.v4.app.ListFragment; import android.support.v4.view.MenuItemCompat; import android.util.Log; @@ -29,11 +30,12 @@ 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.core.util.LongList; +import de.danoeh.antennapod.view.EmptyViewHandler; import de.greenrobot.event.EventBus; -import rx.Observable; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; +import io.reactivex.Observable; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; public class PlaybackHistoryFragment extends ListFragment { @@ -50,7 +52,7 @@ public class PlaybackHistoryFragment extends ListFragment { private List<Downloader> downloaderList; - private Subscription subscription; + private Disposable disposable; @Override public void onAttach(Context context) { @@ -81,6 +83,12 @@ public class PlaybackHistoryFragment extends ListFragment { if (itemsLoaded) { onFragmentLoaded(); } + + EmptyViewHandler emptyView = new EmptyViewHandler(getActivity()); + emptyView.setTitle(R.string.no_history_head_label); + emptyView.setMessage(R.string.no_history_label); + emptyView.attachToListView(getListView()); + } @@ -107,16 +115,16 @@ public class PlaybackHistoryFragment extends ListFragment { public void onStop() { super.onStop(); EventDistributor.getInstance().unregister(contentUpdate); - if(subscription != null) { - subscription.unsubscribe(); + if(disposable != null) { + disposable.dispose(); } } @Override public void onDetach() { super.onDetach(); - if(subscription != null) { - subscription.unsubscribe(); + if(disposable != null) { + disposable.dispose(); } } @@ -269,11 +277,11 @@ public class PlaybackHistoryFragment extends ListFragment { }; private void loadItems() { - if(subscription != null) { - subscription.unsubscribe(); + if(disposable != null) { + disposable.dispose(); } - subscription = Observable.fromCallable(this::loadData) - .subscribeOn(Schedulers.newThread()) + disposable = Observable.fromCallable(this::loadData) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { if (result != null) { @@ -286,6 +294,7 @@ public class PlaybackHistoryFragment extends ListFragment { }, error -> Log.e(TAG, Log.getStackTraceString(error))); } + @NonNull private List<FeedItem> loadData() { List<FeedItem> history = DBReader.getPlaybackHistory(); DBReader.loadAdditionalFeedItemListData(history); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java index bae77d58b..873612fd6 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java @@ -21,7 +21,6 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ProgressBar; import android.widget.TextView; -import android.widget.Toast; import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration; @@ -46,7 +45,6 @@ import de.danoeh.antennapod.core.service.download.Downloader; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.DBWriter; -import de.danoeh.antennapod.core.storage.DownloadRequestException; import de.danoeh.antennapod.core.storage.DownloadRequester; import de.danoeh.antennapod.core.util.Converter; import de.danoeh.antennapod.core.util.FeedItemUtil; @@ -55,10 +53,10 @@ import de.danoeh.antennapod.core.util.QueueSorter; import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler; import de.danoeh.antennapod.menuhandler.MenuItemUtils; import de.greenrobot.event.EventBus; -import rx.Observable; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; +import io.reactivex.Observable; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; /** * Shows all items in the queue @@ -74,7 +72,7 @@ public class QueueFragment extends Fragment { private TextView infoBar; private RecyclerView recyclerView; private QueueRecyclerAdapter recyclerAdapter; - private TextView txtvEmpty; + private View emptyView; private ProgressBar progLoading; private List<FeedItem> queue; @@ -86,7 +84,7 @@ public class QueueFragment extends Fragment { private static final String PREF_SCROLL_POSITION = "scroll_position"; private static final String PREF_SCROLL_OFFSET = "scroll_offset"; - private Subscription subscription; + private Disposable disposable; private LinearLayoutManager layoutManager; private ItemTouchHelper itemTouchHelper; @@ -120,8 +118,8 @@ public class QueueFragment extends Fragment { saveScrollPosition(); EventDistributor.getInstance().unregister(contentUpdate); EventBus.getDefault().unregister(this); - if(subscription != null) { - subscription.unsubscribe(); + if(disposable != null) { + disposable.dispose(); } } @@ -382,8 +380,8 @@ public class QueueFragment extends Fragment { ((MainActivity) getActivity()).getSupportActionBar().setTitle(R.string.queue_label); View root = inflater.inflate(R.layout.queue_fragment, container, false); - infoBar = (TextView) root.findViewById(R.id.info_bar); - recyclerView = (RecyclerView) root.findViewById(R.id.recyclerView); + infoBar = root.findViewById(R.id.info_bar); + recyclerView = root.findViewById(R.id.recyclerView); RecyclerView.ItemAnimator animator = recyclerView.getItemAnimator(); if (animator instanceof SimpleItemAnimator) { ((SimpleItemAnimator) animator).setSupportsChangeAnimations(false); @@ -425,15 +423,15 @@ public class QueueFragment extends Fragment { @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { - if(subscription != null) { - subscription.unsubscribe(); + if(disposable != null) { + disposable.dispose(); } final int position = viewHolder.getAdapterPosition(); Log.d(TAG, "remove(" + position + ")"); final FeedItem item = queue.get(position); final boolean isRead = item.isPlayed(); DBWriter.markItemPlayed(FeedItem.PLAYED, false, item.getId()); - DBWriter.removeQueueItem(getActivity(), item, true); + DBWriter.removeQueueItem(getActivity(), true, item); Snackbar snackbar = Snackbar.make(root, getString(R.string.marked_as_read_label), Snackbar.LENGTH_LONG); snackbar.setAction(getString(R.string.undo), v -> { DBWriter.addQueueItemAt(getActivity(), item.getId(), position, false); @@ -489,35 +487,39 @@ public class QueueFragment extends Fragment { private void reallyMoved(int from, int to) { // Write drag operation to database - Log.d(TAG, "Write to database move(" + dragFrom + ", " + dragTo + ")"); - DBWriter.moveQueueItem(dragFrom, dragTo, true); + Log.d(TAG, "Write to database move(" + from + ", " + to + ")"); + DBWriter.moveQueueItem(from, to, true); } } ); itemTouchHelper.attachToRecyclerView(recyclerView); + //empty view + emptyView = (View) root.findViewById(R.id.emptyView); + emptyView.setVisibility(View.GONE); + ((TextView)emptyView.findViewById(R.id.emptyViewTitle)).setText(R.string.no_items_header_label); + ((TextView)emptyView.findViewById(R.id.emptyViewMessage)).setText(R.string.no_items_label); - txtvEmpty = (TextView) root.findViewById(android.R.id.empty); - txtvEmpty.setVisibility(View.GONE); - progLoading = (ProgressBar) root.findViewById(R.id.progLoading); + progLoading = root.findViewById(R.id.progLoading); progLoading.setVisibility(View.VISIBLE); return root; } private void onFragmentLoaded(final boolean restoreScrollPosition) { - if (recyclerAdapter == null) { - MainActivity activity = (MainActivity) getActivity(); - recyclerAdapter = new QueueRecyclerAdapter(activity, itemAccess, - new DefaultActionButtonCallback(activity), itemTouchHelper); - recyclerAdapter.setHasStableIds(true); - recyclerView.setAdapter(recyclerAdapter); - } - if(queue == null || queue.size() == 0) { - recyclerView.setVisibility(View.GONE); - txtvEmpty.setVisibility(View.VISIBLE); - } else { - txtvEmpty.setVisibility(View.GONE); + if (queue != null && queue.size() > 0) { + if (recyclerAdapter == null) { + MainActivity activity = (MainActivity) getActivity(); + recyclerAdapter = new QueueRecyclerAdapter(activity, itemAccess, + new DefaultActionButtonCallback(activity), itemTouchHelper); + recyclerAdapter.setHasStableIds(true); + recyclerView.setAdapter(recyclerAdapter); + } + emptyView.setVisibility(View.GONE); recyclerView.setVisibility(View.VISIBLE); + } else { + recyclerAdapter = null; + recyclerView.setVisibility(View.GONE); + emptyView.setVisibility(View.VISIBLE); } if (restoreScrollPosition) { @@ -535,9 +537,12 @@ public class QueueFragment extends Fragment { String info = queue.size() + getString(R.string.episodes_suffix); if(queue.size() > 0) { long timeLeft = 0; + float playbackSpeed = Float.valueOf(UserPreferences.getPlaybackSpeed()); for(FeedItem item : queue) { if(item.getMedia() != null) { - timeLeft += item.getMedia().getDuration() - item.getMedia().getPosition(); + timeLeft += + (long) ((item.getMedia().getDuration() - item.getMedia().getPosition()) + / playbackSpeed); } } info += " \u2022 "; @@ -622,25 +627,23 @@ public class QueueFragment extends Fragment { private void loadItems(final boolean restoreScrollPosition) { Log.d(TAG, "loadItems()"); - if(subscription != null) { - subscription.unsubscribe(); + if(disposable != null) { + disposable.dispose(); } if (queue == null) { recyclerView.setVisibility(View.GONE); - txtvEmpty.setVisibility(View.GONE); + emptyView.setVisibility(View.GONE); progLoading.setVisibility(View.VISIBLE); } - subscription = Observable.fromCallable(DBReader::getQueue) - .subscribeOn(Schedulers.newThread()) + disposable = Observable.fromCallable(DBReader::getQueue) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(items -> { - if(items != null) { - progLoading.setVisibility(View.GONE); - queue = items; - onFragmentLoaded(restoreScrollPosition); - if(recyclerAdapter != null) { - recyclerAdapter.notifyDataSetChanged(); - } + progLoading.setVisibility(View.GONE); + queue = items; + onFragmentLoaded(restoreScrollPosition); + if(recyclerAdapter != null) { + recyclerAdapter.notifyDataSetChanged(); } }, error -> Log.e(TAG, Log.getStackTraceString(error))); } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java index 66c59b7f7..3c40b542c 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java @@ -20,6 +20,7 @@ import de.danoeh.antennapod.core.service.download.Downloader; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.storage.DownloadRequester; +import de.danoeh.antennapod.view.EmptyViewHandler; import de.greenrobot.event.EventBus; /** @@ -44,6 +45,12 @@ public class RunningDownloadsFragment extends ListFragment { adapter = new DownloadlistAdapter(getActivity(), itemAccess); setListAdapter(adapter); + + EmptyViewHandler emptyView = new EmptyViewHandler(getActivity()); + emptyView.setTitle(R.string.no_run_downloads_head_label); + emptyView.setMessage(R.string.no_run_downloads_label); + emptyView.attachToListView(getListView()); + } @Override diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java index f64b4c20a..1d7ac8824 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java @@ -2,6 +2,7 @@ package de.danoeh.antennapod.fragment; import android.content.Context; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.v4.app.ListFragment; import android.support.v4.view.MenuItemCompat; import android.support.v7.app.AppCompatActivity; @@ -24,10 +25,10 @@ import de.danoeh.antennapod.core.feed.FeedComponent; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.SearchResult; import de.danoeh.antennapod.core.storage.FeedSearcher; -import rx.Observable; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; +import io.reactivex.Observable; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; /** * Performs a search operation on all feeds or one specific feed and displays the search result. @@ -44,7 +45,7 @@ public class SearchFragment extends ListFragment { private boolean viewCreated = false; private boolean itemsLoaded = false; - private Subscription subscription; + private Disposable disposable; /** * Create a new SearchFragment that searches all feeds. @@ -85,8 +86,8 @@ public class SearchFragment extends ListFragment { @Override public void onStop() { super.onStop(); - if(subscription != null) { - subscription.unsubscribe(); + if(disposable != null) { + disposable.dispose(); } EventDistributor.getInstance().unregister(contentUpdate); } @@ -94,8 +95,8 @@ public class SearchFragment extends ListFragment { @Override public void onDetach() { super.onDetach(); - if(subscription != null) { - subscription.unsubscribe(); + if(disposable != null) { + disposable.dispose(); } } @@ -205,26 +206,25 @@ public class SearchFragment extends ListFragment { private void search() { - if(subscription != null) { - subscription.unsubscribe(); + if(disposable != null) { + disposable.dispose(); } if (viewCreated && !itemsLoaded) { setListShown(false); } - subscription = Observable.fromCallable(this::performSearch) - .subscribeOn(Schedulers.newThread()) + disposable = Observable.fromCallable(this::performSearch) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { - if (result != null) { - itemsLoaded = true; - searchResults = result; - if (viewCreated) { - onFragmentLoaded(); - } + itemsLoaded = true; + searchResults = result; + if (viewCreated) { + onFragmentLoaded(); } }, error -> Log.e(TAG, Log.getStackTraceString(error))); } + @NonNull private List<SearchResult> performSearch() { Bundle args = getArguments(); String query = args.getString(ARG_QUERY); 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 1247aacbb..5f09be8ce 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java @@ -1,7 +1,6 @@ package de.danoeh.antennapod.fragment; import android.content.DialogInterface; -import android.content.Intent; import android.os.Bundle; import android.support.v4.app.Fragment; import android.util.Log; @@ -26,11 +25,12 @@ 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.core.util.IntentUtils; import de.danoeh.antennapod.dialog.RenameFeedDialog; -import rx.Observable; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; +import io.reactivex.Observable; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; /** * Fragment for displaying feed subscriptions @@ -48,7 +48,7 @@ public class SubscriptionFragment extends Fragment { private int mPosition = -1; - private Subscription subscription; + private Disposable disposable; public SubscriptionFragment() { } @@ -68,7 +68,7 @@ public class SubscriptionFragment extends Fragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View root = inflater.inflate(R.layout.fragment_subscriptions, container, false); - subscriptionGridLayout = (GridView) root.findViewById(R.id.subscriptions_grid); + subscriptionGridLayout = root.findViewById(R.id.subscriptions_grid); registerForContextMenu(subscriptionGridLayout); return root; } @@ -94,17 +94,17 @@ public class SubscriptionFragment extends Fragment { @Override public void onDestroy() { super.onDestroy(); - if(subscription != null) { - subscription.unsubscribe(); + if(disposable != null) { + disposable.dispose(); } } private void loadSubscriptions() { - if(subscription != null) { - subscription.unsubscribe(); + if(disposable != null) { + disposable.dispose(); } - subscription = Observable.fromCallable(DBReader::getNavDrawerData) - .subscribeOn(Schedulers.newThread()) + disposable = Observable.fromCallable(DBReader::getNavDrawerData) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { navDrawerData = result; @@ -161,7 +161,7 @@ public class SubscriptionFragment extends Fragment { dialog.dismiss(); Observable.fromCallable(() -> DBWriter.markFeedSeen(feed.getId())) - .subscribeOn(Schedulers.newThread()) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> loadSubscriptions(), error -> Log.e(TAG, Log.getStackTraceString(error))); @@ -178,7 +178,7 @@ public class SubscriptionFragment extends Fragment { public void onConfirmButtonPressed(DialogInterface dialog) { dialog.dismiss(); Observable.fromCallable(() -> DBWriter.markFeedRead(feed.getId())) - .subscribeOn(Schedulers.newThread()) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> loadSubscriptions(), error -> Log.e(TAG, Log.getStackTraceString(error))); @@ -211,8 +211,8 @@ public class SubscriptionFragment extends Fragment { remover.skipOnCompletion = true; int playerStatus = PlaybackPreferences.getCurrentPlayerStatus(); if(playerStatus == PlaybackPreferences.PLAYER_STATUS_PLAYING) { - getActivity().sendBroadcast(new Intent( - PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE)); + IntentUtils.sendLocalBroadcast(getContext(), PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE); + } } remover.executeAsync(); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/GpodnetMainFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/GpodnetMainFragment.java index b48027668..4dc114f9b 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/GpodnetMainFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/GpodnetMainFragment.java @@ -31,12 +31,12 @@ public class GpodnetMainFragment extends Fragment { super.onCreateView(inflater, container, savedInstanceState); View root = inflater.inflate(R.layout.pager_fragment, container, false); - viewPager = (ViewPager)root.findViewById(R.id.viewpager); + viewPager = root.findViewById(R.id.viewpager); GpodnetPagerAdapter pagerAdapter = new GpodnetPagerAdapter(getChildFragmentManager(), getResources()); viewPager.setAdapter(pagerAdapter); // Give the TabLayout the ViewPager - tabLayout = (TabLayout) root.findViewById(R.id.sliding_tabs); + tabLayout = root.findViewById(R.id.sliding_tabs); tabLayout.setupWithViewPager(viewPager); return root; diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java index 055358c64..49851ebb4 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java @@ -78,10 +78,10 @@ public abstract class PodcastListFragment extends Fragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View root = inflater.inflate(R.layout.gpodnet_podcast_list, container, false); - gridView = (GridView) root.findViewById(R.id.gridView); - progressBar = (ProgressBar) root.findViewById(R.id.progressBar); - txtvError = (TextView) root.findViewById(R.id.txtvError); - butRetry = (Button) root.findViewById(R.id.butRetry); + gridView = root.findViewById(R.id.gridView); + progressBar = root.findViewById(R.id.progressBar); + txtvError = root.findViewById(R.id.txtvError); + butRetry = root.findViewById(R.id.butRetry); gridView.setOnItemClickListener((parent, view, position, id) -> onPodcastSelected((GpodnetPodcast) gridView.getAdapter().getItem(position))); diff --git a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java index de47ee5e4..3f8d88af7 100644 --- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java +++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java @@ -101,7 +101,8 @@ public class FeedItemMenuHandler { mi.setItemVisibility(R.id.share_download_url_with_position_item, false); } - mi.setItemVisibility(R.id.share_file, hasMedia && selectedItem.getMedia().fileExists()); + boolean fileDownloaded = hasMedia && selectedItem.getMedia().fileExists(); + mi.setItemVisibility(R.id.share_file, fileDownloaded); if (selectedItem.isPlayed()) { mi.setItemVisibility(R.id.mark_read_item, false); @@ -130,6 +131,8 @@ public class FeedItemMenuHandler { mi.setItemVisibility(R.id.add_to_favorites_item, !isFavorite); mi.setItemVisibility(R.id.remove_from_favorites_item, isFavorite); + mi.setItemVisibility(R.id.remove_item, fileDownloaded); + return true; } @@ -158,7 +161,7 @@ public class FeedItemMenuHandler { FeedItem selectedItem) { switch (menuItemId) { case R.id.skip_episode_item: - context.sendBroadcast(new Intent(PlaybackService.ACTION_SKIP_CURRENT_EPISODE)); + IntentUtils.sendLocalBroadcast(context, PlaybackService.ACTION_SKIP_CURRENT_EPISODE); break; case R.id.remove_item: DBWriter.deleteFeedMediaOfItem(context, selectedItem.getMedia().getId()); @@ -196,7 +199,7 @@ public class FeedItemMenuHandler { DBWriter.addQueueItem(context, selectedItem); break; case R.id.remove_from_queue_item: - DBWriter.removeQueueItem(context, selectedItem, true); + DBWriter.removeQueueItem(context, true, selectedItem); break; case R.id.add_to_favorites_item: DBWriter.addFavoriteItem(selectedItem); diff --git a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java index ab7d0e7c6..bd4fe9bcf 100644 --- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java +++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java @@ -30,6 +30,9 @@ import de.danoeh.antennapod.core.util.ShareUtils; * Handles interactions with the FeedItemMenu. */ public class FeedMenuHandler { + + private FeedMenuHandler(){ } + private static final String TAG = "FeedMenuHandler"; public static boolean onCreateOptionsMenu(MenuInflater inflater, Menu menu) { 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 ac703e13e..7b9fcad9b 100644 --- a/app/src/main/java/de/danoeh/antennapod/menuhandler/MenuItemUtils.java +++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/MenuItemUtils.java @@ -19,8 +19,9 @@ public class MenuItemUtils extends de.danoeh.antennapod.core.menuhandler.MenuIte public static void adjustTextColor(Context context, SearchView sv) { if(Build.VERSION.SDK_INT < 14) { - EditText searchEditText = (EditText) sv.findViewById(R.id.search_src_text); - if(UserPreferences.getTheme() == de.danoeh.antennapod.R.style.Theme_AntennaPod_Dark) { + EditText searchEditText = sv.findViewById(R.id.search_src_text); + if (UserPreferences.getTheme() == de.danoeh.antennapod.R.style.Theme_AntennaPod_Dark + || UserPreferences.getTheme() == R.style.Theme_AntennaPod_TrueBlack) { searchEditText.setTextColor(Color.WHITE); } else { searchEditText.setTextColor(Color.BLACK); diff --git a/app/src/main/java/de/danoeh/antennapod/preferences/MasterSwitchPreference.java b/app/src/main/java/de/danoeh/antennapod/preferences/MasterSwitchPreference.java index e500267fe..b810cbfa6 100644 --- a/app/src/main/java/de/danoeh/antennapod/preferences/MasterSwitchPreference.java +++ b/app/src/main/java/de/danoeh/antennapod/preferences/MasterSwitchPreference.java @@ -9,6 +9,7 @@ import android.support.v7.preference.PreferenceViewHolder; import android.util.AttributeSet; import android.util.TypedValue; import android.widget.TextView; + import de.danoeh.antennapod.R; public class MasterSwitchPreference extends SwitchPreference { diff --git a/app/src/main/java/de/danoeh/antennapod/preferences/NumberPickerPreference.java b/app/src/main/java/de/danoeh/antennapod/preferences/NumberPickerPreference.java new file mode 100644 index 000000000..50e76838c --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/preferences/NumberPickerPreference.java @@ -0,0 +1,107 @@ +package de.danoeh.antennapod.preferences; + +import android.app.AlertDialog; +import android.content.Context; +import android.support.v7.preference.Preference; +import android.text.InputFilter; +import android.util.AttributeSet; +import android.view.View; +import android.view.WindowManager; +import android.widget.EditText; + +import de.danoeh.antennapod.R; + +public class NumberPickerPreference extends Preference { + private Context context; + private int defaultValue = 0; + private int minValue = 0; + private int maxValue = Integer.MAX_VALUE; + + public NumberPickerPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + init(context, attrs); + } + + public NumberPickerPreference(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context, attrs); + } + + public NumberPickerPreference(Context context, AttributeSet attrs) { + super(context, attrs); + init(context, attrs); + } + + public NumberPickerPreference(Context context) { + super(context); + this.context = context; + } + + private void init(Context context, AttributeSet attrs) { + this.context = context; + + for (int i = 0; i < attrs.getAttributeCount(); i++) { + String name = attrs.getAttributeName(i); + String value = attrs.getAttributeValue(i); + switch (name) { + case "defaultValue": + defaultValue = Integer.parseInt(value); + break; + case "minValue": + minValue = Integer.parseInt(value); + break; + case "maxValue": + maxValue = Integer.parseInt(value); + break; + } + } + } + + @Override + protected void onClick() { + super.onClick(); + + View view = View.inflate(context, R.layout.numberpicker, null); + EditText number = view.findViewById(R.id.number); + number.setText(getSharedPreferences().getString(getKey(), ""+defaultValue)); + number.setFilters(new InputFilter[]{(source, start, end, dest, dstart, dend) -> { + try { + String newVal = dest.toString().substring(0, dstart) + dest.toString().substring(dend); + newVal = newVal.substring(0, dstart) + source.toString() + newVal.substring(dstart); + int input = Integer.parseInt(newVal); + if (input >= minValue && input <= maxValue) { + return null; + } + } catch (NumberFormatException nfe) { + nfe.printStackTrace(); + } + return ""; + }}); + + AlertDialog dialog = new AlertDialog.Builder(context) + .setTitle(getTitle()) + .setView(view) + .setNegativeButton(android.R.string.cancel, null) + .setPositiveButton(android.R.string.ok, (dialogInterface, i) -> { + try { + String numberString = number.getText().toString(); + int value = Integer.parseInt(numberString); + + if (value < minValue || value > maxValue) { + return; + } + + getSharedPreferences().edit().putString(getKey(), "" + value).apply(); + + if (getOnPreferenceChangeListener() != null) { + getOnPreferenceChangeListener().onPreferenceChange(this, value); + } + } catch (NumberFormatException e) { + // Do not set value + } + }) + .create(); + dialog.show(); + dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); + } +} 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 9bb0edeb2..a157a2cfa 100644 --- a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java +++ b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java @@ -36,24 +36,9 @@ import android.widget.ListView; import android.widget.Toast; import com.afollestad.materialdialogs.MaterialDialog; - import com.bytehamster.lib.preferencesearch.SearchConfiguration; import com.bytehamster.lib.preferencesearch.SearchPreference; -import de.danoeh.antennapod.activity.AboutActivity; -import de.danoeh.antennapod.activity.ImportExportActivity; -import de.danoeh.antennapod.activity.MediaplayerActivity; -import de.danoeh.antennapod.activity.OpmlImportFromPathActivity; -import de.danoeh.antennapod.activity.PreferenceActivity; -import de.danoeh.antennapod.activity.StatisticsActivity; -import de.danoeh.antennapod.core.export.html.HtmlWriter; -import de.danoeh.antennapod.core.export.opml.OpmlWriter; -import de.danoeh.antennapod.core.service.GpodnetSyncService; -import de.danoeh.antennapod.dialog.AuthenticationDialog; -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 de.danoeh.antennapod.core.util.gui.PictureInPictureUtil; + import org.apache.commons.lang3.ArrayUtils; import java.io.File; @@ -67,18 +52,33 @@ import java.util.concurrent.TimeUnit; import de.danoeh.antennapod.CrashReportWriter; import de.danoeh.antennapod.R; +import de.danoeh.antennapod.activity.AboutActivity; import de.danoeh.antennapod.activity.DirectoryChooserActivity; +import de.danoeh.antennapod.activity.ImportExportActivity; import de.danoeh.antennapod.activity.MainActivity; +import de.danoeh.antennapod.activity.MediaplayerActivity; +import de.danoeh.antennapod.activity.OpmlImportFromPathActivity; +import de.danoeh.antennapod.activity.PreferenceActivity; +import de.danoeh.antennapod.activity.StatisticsActivity; 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; import de.danoeh.antennapod.core.util.flattr.FlattrUtils; +import de.danoeh.antennapod.core.util.gui.PictureInPictureUtil; +import de.danoeh.antennapod.dialog.AuthenticationDialog; +import de.danoeh.antennapod.dialog.AutoFlattrPreferenceDialog; import de.danoeh.antennapod.dialog.ChooseDataFolderDialog; -import rx.Observable; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; +import de.danoeh.antennapod.dialog.GpodnetSetHostnameDialog; +import de.danoeh.antennapod.dialog.ProxyDialog; +import de.danoeh.antennapod.dialog.VariableSpeedDialog; +import io.reactivex.Observable; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; import static de.danoeh.antennapod.activity.PreferenceActivity.PARAM_RESOURCE; @@ -137,7 +137,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc } }; private CheckBoxPreference[] selectedNetworks; - private Subscription subscription; + private Disposable disposable; public PreferenceController(PreferenceUI ui) { this.ui = ui; @@ -147,12 +147,7 @@ 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)); - } - } + } @@ -167,7 +162,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc break; case R.xml.preferences_autodownload: setupAutoDownloadScreen(); - buildAutodownloadSelectedNetworsPreference(); + buildAutodownloadSelectedNetworksPreference(); setSelectedNetworksEnabled(UserPreferences.isEnableAutodownloadWifiFilter()); buildEpisodeCleanupPreference(); break; @@ -232,6 +227,33 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc return true; }); + ui.findPreference(UserPreferences.PREF_BACK_BUTTON_BEHAVIOR) + .setOnPreferenceChangeListener((preference, newValue) -> { + if (newValue.equals("page")) { + final Context context = ui.getActivity(); + final String[] navTitles = context.getResources().getStringArray(R.array.back_button_go_to_pages); + final String[] navTags = context.getResources().getStringArray(R.array.back_button_go_to_pages_tags); + final String choice[] = { UserPreferences.getBackButtonGoToPage() }; + + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setTitle(R.string.back_button_go_to_page_title); + builder.setSingleChoiceItems(navTitles, ArrayUtils.indexOf(navTags, UserPreferences.getBackButtonGoToPage()), (dialogInterface, i) -> { + if (i >= 0) { + choice[0] = navTags[i]; + } + }); + builder.setPositiveButton(R.string.confirm_label, (dialogInterface, i) -> UserPreferences.setBackButtonGoToPage(choice[0])); + builder.setNegativeButton(R.string.cancel_label, null); + builder.create().show(); + return true; + } else { + return true; + } + }); + + if (Build.VERSION.SDK_INT >= 26) { + ui.findPreference(UserPreferences.PREF_EXPANDED_NOTIFICATION).setVisible(false); + } } private void setupStorageScreen() { @@ -467,18 +489,10 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc ui.findPreference(UserPreferences.PREF_PARALLEL_DOWNLOADS) .setOnPreferenceChangeListener( (preference, o) -> { - if (o instanceof String) { - try { - int value = Integer.parseInt((String) o); - if (1 <= value && value <= 50) { - setParallelDownloadsText(value); - return true; - } - } catch (NumberFormatException e) { - return false; - } + if (o instanceof Integer) { + setParallelDownloadsText((Integer) o); } - return false; + return true; } ); // validate and set correct value: number of downloads between 1 and 50 (inclusive) @@ -567,31 +581,24 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc config.setFragmentContainerViewId(R.id.content); config.setBreadcrumbsEnabled(true); - config.index() - .addBreadcrumb(getTitleOfPage(R.xml.preferences_user_interface)) - .addFile(R.xml.preferences_user_interface); - config.index() - .addBreadcrumb(getTitleOfPage(R.xml.preferences_playback)) - .addFile(R.xml.preferences_playback); - config.index() - .addBreadcrumb(getTitleOfPage(R.xml.preferences_network)) - .addFile(R.xml.preferences_network); - config.index() - .addBreadcrumb(getTitleOfPage(R.xml.preferences_storage)) - .addFile(R.xml.preferences_storage); - config.index() + config.index(R.xml.preferences_user_interface) + .addBreadcrumb(getTitleOfPage(R.xml.preferences_user_interface)); + config.index(R.xml.preferences_playback) + .addBreadcrumb(getTitleOfPage(R.xml.preferences_playback)); + config.index(R.xml.preferences_network) + .addBreadcrumb(getTitleOfPage(R.xml.preferences_network)); + config.index(R.xml.preferences_storage) + .addBreadcrumb(getTitleOfPage(R.xml.preferences_storage)); + config.index(R.xml.preferences_autodownload) .addBreadcrumb(getTitleOfPage(R.xml.preferences_network)) .addBreadcrumb(R.string.automation) - .addBreadcrumb(getTitleOfPage(R.xml.preferences_autodownload)) - .addFile(R.xml.preferences_autodownload); - config.index() + .addBreadcrumb(getTitleOfPage(R.xml.preferences_autodownload)); + config.index(R.xml.preferences_gpodder) .addBreadcrumb(getTitleOfPage(R.xml.preferences_integrations)) - .addBreadcrumb(getTitleOfPage(R.xml.preferences_gpodder)) - .addFile(R.xml.preferences_gpodder); - config.index() + .addBreadcrumb(getTitleOfPage(R.xml.preferences_gpodder)); + config.index(R.xml.preferences_flattr) .addBreadcrumb(getTitleOfPage(R.xml.preferences_integrations)) - .addBreadcrumb(getTitleOfPage(R.xml.preferences_flattr)) - .addFile(R.xml.preferences_flattr); + .addBreadcrumb(getTitleOfPage(R.xml.preferences_flattr)); } public PreferenceFragmentCompat openScreen(int preferences, AppCompatActivity activity) { @@ -637,7 +644,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc 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()) + disposable = observable.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(output -> { alert.setTitle(R.string.export_success_title); @@ -645,7 +652,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc alert.setMessage(message); alert.setPositiveButton(R.string.send_label, (dialog, which) -> { Uri fileUri = FileProvider.getUriForFile(context.getApplicationContext(), - "de.danoeh.antennapod.provider", output); + context.getString(R.string.provider_authority), output); Intent sendIntent = new Intent(Intent.ACTION_SEND); sendIntent.putExtra(Intent.EXTRA_SUBJECT, context.getResources().getText(R.string.opml_export_label)); @@ -715,8 +722,8 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc } public void unsubscribeExportSubscription() { - if (subscription != null) { - subscription.unsubscribe(); + if (disposable != null) { + disposable.dispose(); } } @@ -832,8 +839,11 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc entries[x] = res.getString(R.string.episode_cleanup_never); } else if (v == 0) { entries[x] = res.getString(R.string.episode_cleanup_after_listening); + } else if (v > 0 && v < 24) { + entries[x] = res.getQuantityString(R.plurals.episode_cleanup_hours_after_listening, v, v); } else { - entries[x] = res.getQuantityString(R.plurals.episode_cleanup_days_after_listening, v, v); + int numDays = (int)(v / 24); // assume underlying value will be NOT fraction of days, e.g., 36 (hours) + entries[x] = res.getQuantityString(R.plurals.episode_cleanup_days_after_listening, numDays, numDays); } } pref.setEntries(entries); @@ -891,11 +901,10 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc } private void checkSonicItemVisibility() { - if (Build.VERSION.SDK_INT >= 16) { - ui.findPreference(UserPreferences.PREF_SONIC).setEnabled(true); - } else { - Preference prefSonic = ui.findPreference(UserPreferences.PREF_SONIC); - prefSonic.setSummary("[Android 4.1+]\n" + prefSonic.getSummary()); + if (Build.VERSION.SDK_INT < 16) { + ListPreference p = (ListPreference) ui.findPreference(UserPreferences.PREF_MEDIA_PLAYER); + p.setEntries(R.array.media_player_options_no_sonic); + p.setEntryValues(R.array.media_player_values_no_sonic); } } @@ -959,7 +968,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc return val == null ? "" : val; } - private void buildAutodownloadSelectedNetworsPreference() { + private void buildAutodownloadSelectedNetworksPreference() { final Activity activity = ui.getActivity(); if (selectedNetworks != null) { diff --git a/app/src/main/java/de/danoeh/antennapod/spa/SPAUtil.java b/app/src/main/java/de/danoeh/antennapod/spa/SPAUtil.java index 75cbd8b5a..03958508d 100644 --- a/app/src/main/java/de/danoeh/antennapod/spa/SPAUtil.java +++ b/app/src/main/java/de/danoeh/antennapod/spa/SPAUtil.java @@ -33,7 +33,7 @@ public class SPAUtil { * sent before. */ public static synchronized boolean sendSPAppsQueryFeedsIntent(Context context) { - if (context == null) throw new IllegalArgumentException("context = null"); + assert context != null : "context = null"; final Context appContext = context.getApplicationContext(); if (appContext == null) { Log.wtf(TAG, "Unable to get application context"); diff --git a/app/src/main/java/de/danoeh/antennapod/view/EmptyViewHandler.java b/app/src/main/java/de/danoeh/antennapod/view/EmptyViewHandler.java new file mode 100644 index 000000000..e3fd63235 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/view/EmptyViewHandler.java @@ -0,0 +1,59 @@ +package de.danoeh.antennapod.view;
+
+import android.app.Activity;
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import de.danoeh.antennapod.R;
+
+public class EmptyViewHandler extends View {
+ private Activity activity;
+ private int title;
+ private int message;
+
+ public EmptyViewHandler(Context context) {
+ super(context);
+ this.setActivity((Activity) context);
+ }
+
+ public int getTitle() {
+ return title;
+ }
+
+ public void setTitle(int title) {
+ this.title = title;
+ }
+
+ public int getMessage() {
+ return message;
+ }
+
+ public void setMessage(int message) {
+ this.message = message;
+ }
+
+ public void attachToListView(ListView listView){
+
+ View emptyView = getActivity().getLayoutInflater().inflate(R.layout.empty_view_layout, null);
+ ((ViewGroup) listView.getParent()).addView(emptyView);
+ listView.setEmptyView(emptyView);
+
+ TextView tvTitle = (TextView) emptyView.findViewById(R.id.emptyViewTitle);
+ tvTitle.setText(title);
+
+ TextView tvMessage = (TextView) emptyView.findViewById(R.id.emptyViewMessage);
+ tvMessage.setText(message);
+
+ }
+
+ public Activity getActivity() {
+ return activity;
+ }
+
+ public void setActivity(Activity activity) {
+ this.activity = activity;
+ }
+}
diff --git a/app/src/main/play/ar/listing/fulldescription b/app/src/main/play/ar/listing/fulldescription index 87b477fdc..27abb5532 100644 --- a/app/src/main/play/ar/listing/fulldescription +++ b/app/src/main/play/ar/listing/fulldescription @@ -1,4 +1,4 @@ -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> +AntennaPod هو مدير للبودكاست واللاعب الذي ÙŠØªÙŠØ Ù„Ùƒ الوصول الÙوري إلى ملايين البودكاست المجانية والمدÙوعة ØŒ من البودكاسترات المستقلة إلى دور النشر الكبيرة مثل بي بي سي ØŒ إن بي آر وسي إن إن. يمكنك إضاÙØ© واستيراد وتصدير خلاصاتهم الخالية من المتاعب باستخدام قاعدة بيانات بودكاست iTunes أو ملÙات OPML أو عناوين URL RSS بسيطة. يمكنك توÙير الجهد واستخدام طاقة البطارية واستخدام البيانات المتنقلة مع عناصر تØكم تلقائية قوية لتنزيل الØلقات (Øدد الأوقات والÙترات الزمنية وشبكات WiFi) ÙˆØذ٠الØلقات (استنادًا إلى إعداداتك المÙضلة وتأخير الإعدادات).<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. diff --git a/app/src/main/play/ar/listing/shortdescription b/app/src/main/play/ar/listing/shortdescription new file mode 100644 index 000000000..7afb5a62d --- /dev/null +++ b/app/src/main/play/ar/listing/shortdescription @@ -0,0 +1 @@ +Easy-to-use, flexible and open-source podcast & radio manager and player
\ No newline at end of file diff --git a/app/src/main/play/ar/listing/title b/app/src/main/play/ar/listing/title new file mode 100644 index 000000000..6c7c64cfc --- /dev/null +++ b/app/src/main/play/ar/listing/title @@ -0,0 +1 @@ +AntennaPod diff --git a/app/src/main/play/ast_ES/listing/fulldescription b/app/src/main/play/ast_ES/listing/fulldescription deleted file mode 100644 index 87b477fdc..000000000 --- a/app/src/main/play/ast_ES/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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> -• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -CONTROL THE SYSTEM<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• 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/az/listing/fulldescription b/app/src/main/play/az/listing/fulldescription deleted file mode 100644 index 87b477fdc..000000000 --- a/app/src/main/play/az/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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> -• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -CONTROL THE SYSTEM<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• 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/bg/listing/shortdescription b/app/src/main/play/bg/listing/shortdescription new file mode 100644 index 000000000..7afb5a62d --- /dev/null +++ b/app/src/main/play/bg/listing/shortdescription @@ -0,0 +1 @@ +Easy-to-use, flexible and open-source podcast & radio manager and player
\ No newline at end of file diff --git a/app/src/main/play/bg/listing/title b/app/src/main/play/bg/listing/title new file mode 100644 index 000000000..6c7c64cfc --- /dev/null +++ b/app/src/main/play/bg/listing/title @@ -0,0 +1 @@ +AntennaPod diff --git a/app/src/main/play/ca/listing/title b/app/src/main/play/ca/listing/title index 31552f353..6c7c64cfc 100644 --- a/app/src/main/play/ca/listing/title +++ b/app/src/main/play/ca/listing/title @@ -1 +1 @@ -AntennaPod
\ No newline at end of file +AntennaPod diff --git a/app/src/main/play/ca_ES/listing/fulldescription b/app/src/main/play/ca_ES/listing/fulldescription deleted file mode 100644 index 87b477fdc..000000000 --- a/app/src/main/play/ca_ES/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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> -• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -CONTROL THE SYSTEM<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• 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/cs-CZ/listing/title b/app/src/main/play/cs-CZ/listing/title index 31552f353..6c7c64cfc 100644 --- a/app/src/main/play/cs-CZ/listing/title +++ b/app/src/main/play/cs-CZ/listing/title @@ -1 +1 @@ -AntennaPod
\ No newline at end of file +AntennaPod diff --git a/app/src/main/play/cs_CZ/listing/fulldescription b/app/src/main/play/cs_CZ/listing/fulldescription deleted file mode 100644 index 4e15342ee..000000000 --- a/app/src/main/play/cs_CZ/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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> -• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -CONTROL THE SYSTEM<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• PoužÃvejte AntennaPod ve vlastnÃm jazyce (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• Back-up your subscriptions with the gPodder.net integration and OPML export - -<b>PÅ™idejte se ke komunitÄ› AntennaPod!</b><br> -AntennaPod je aktivnÄ› vyvÃjen dobrovolnÃky. Můžete pÅ™ispÄ›t také svým kódem nebo komentáři! - -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 - -Máte dotaz nebo chcete poslat svůj názor? -https://twitter.com/@AntennaPod - -PÅ™eklady jsou spravovány pomocà služby Transifex:<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/da-DK/listing/fulldescription b/app/src/main/play/da-DK/listing/fulldescription index 1d19da2e8..8f48ef070 100644 --- a/app/src/main/play/da-DK/listing/fulldescription +++ b/app/src/main/play/da-DK/listing/fulldescription @@ -1,20 +1,43 @@ -AntennaPod er en open-source podcast afspiller for Android 2.3.3 og nyere. Den tilbyder alle basale features du forventer fra en podcastafspiller, som streaming og download af episoder, opdaterer automatisk feeds eller tilføjer dem automatisk i en kø så du kan høre dem senere. Derudover lader AntennaPod dig flattr podcasts og episoder inde i appen. - -Indtil nu er følgende features blevet implementeret: - -* Download og Streaming af episoder -* Variabel afspilningshastighed (kræver Presto Sound Library eller Prestissimo) -* Understøttelse af Atom og RSS feeds -* Understøttelse af password-beskyttede feeds og episoder -* Support for searching iTunes listings -* OPML import og eksport -* Flattr integration inkluderer automatisk flattring -* Afspiller widget -* Søg -* Automatisk opdatering af feeds -* Automatisk download af nye episoder -* Sleep timer -* Adgang til gpodder.net's podcast bibliotek -* Synkronisering af abonnementer med gpodder.net's service -* Understøtter af MP3 kapitler, VorbisComment kapitler and Podlove Simple Chapters -* Understøtter side-delte feeds (http://podlove.org/paged-feeds/)
\ No newline at end of file +AntennaPod er en app til hÃ¥ndtering og afspilning af podcasts. Den giver dig øjeblikkelig adgang til millioner af gratis og betalte podcasts, fra uafhængige podcastere til store udgivere som BBC, NPR, CNN og DR. Tilføj, importer og eksporter deres feeds problemfrit ved hjælp af iTunes-podcastdatabasen, OPML-filer eller enkle RSS-webadresser. Spar kræfter, batteristrøm og mobilt dataforbrug med kraftfulde automatiske styringsværktøjer til at hente udsendelser (angiv tidspunkter, tidsintervaller og udvalgte wi-fi-netværk) og sletning af episoder (baseret pÃ¥ dine foretrukne udsendelser og forsinkelsesindstillinger).<br> +Men vigtigst af alt: Hent, stream eller sæt udsendelser i kø og nyd dem pÃ¥ den mÃ¥de du kan lide med justerbare hastigheder, kapitelunderstøttelse og en søvntimer. Du kan endda vise din pÃ¥skønnelse over for indholdsskaberne med vores Flattr-integration. + +AntennaPod er lavet af en podcast-entusiast og er gratis og fri i alle betydninger: open source, ingen udgifter, ingen reklamer. + +<b>Alle funktioner:</b><br> +IMPORTER, ORGANISER OG AFSPIL<br> +• Tilføj og importer feeds via iTunes- og gpodder.net-oversigterne, OPML-filer og RSS- eller Atom-links<br> +• HÃ¥ndter afspilning fra hvor som helst: widget pÃ¥ startskærmen, systemnotifikation, samt hovedtelefon- og bluetooth-styring<br> +• Lyt pÃ¥ din egen mÃ¥de med justerbar afspilningshastighed, kapitelunderstøttelse (MP3, VorbisComment og Podlove), erindring af afspilningsposition og en avanceret søvntimer (ryst for at nulstille, sænke lydstyrken og afspille langsommere)<br> +• TilgÃ¥ feeds og udsendelser beskyttet med adgangskode<br> +• Brug sideinddelte feeds (www.podlove.org/paged-feeds) + +HOLD STYR PÃ…, DEL OG ANERKEND<br> +• Hold styr pÃ¥ det bedste af det bedste ved at markere udsendelser som foretrukne<br> +• Find en bestemt udsendelse via afspilningshistorikken eller ved at søge (titler og beskrivelser)<br> +• Del udsendelser og feeds via avancerede valgmuligheder for sociale medier, gpodder.net-tjenesterne og OPML-eksport<br> +• Støt indholdsskabere med Flattr-integration, inklusive automatisk flattring + +STYR SYSTEMET<br> +• Tag styring over automatiseret hentning: vælg feeds, udeluk mobile netværk, vælg specifikke wi-fi-netvæk, kræv at telefonen oplader og indstil tidspunkter eller tidsintervaller +• HÃ¥ndter lagerforbruget ved at indstille antallet af udsendelser, der skal gemmes, smart sletning (baseret pÃ¥ dine foretrukne og afspilningsstatus) og ved at vælge den lagerplacering, du foretrækker<br> +• Brug AntennaPod pÃ¥ dit eget sprog (EN, DE, DA, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> +• Tilpas appen til dit miljø med det lyse eller mørke tema<br> +• Sikkerhedskopier dine abonnementer med gpodder.net-integrationen og OPML-eksport + +<b>Bliv en del af AntennaPod-fællesskabet!</b><br> +AntennaPod er under aktiv udvikling af frivillige. Du kan ogsÃ¥ bidrage, enten med kode eller kommentarer! + +GitHub er stedet for forslag tli ny funktionalitet, fejlrapporter og kodebidrag:<br> +https://www.github.com/AntennaPod/AntennaPod + +Vores Google-gruppe er stedet til at dele dine ideer, foretrukne podcast-øjeblikke og taknemmelighed til alle de frivillige:<br> +https://groups.google.com/forum/#!forum/antennapod + +Har du et spørgsmÃ¥l eller vil du give os en tilbagemelding? +https://twitter.com/@AntennaPod + +Transifex er stedet, hvis du vil hjælpe med oversættelser:<br> +https://www.transifex.com/antennapod/antennapod + +Prøv vores beta-testprogram for at fÃ¥ de nyeste funktioner først:<br> +https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/da-DK/listing/title b/app/src/main/play/da-DK/listing/title index 31552f353..6c7c64cfc 100644 --- a/app/src/main/play/da-DK/listing/title +++ b/app/src/main/play/da-DK/listing/title @@ -1 +1 @@ -AntennaPod
\ No newline at end of file +AntennaPod diff --git a/app/src/main/play/da/listing/fulldescription b/app/src/main/play/da/listing/fulldescription deleted file mode 100644 index 241066fd4..000000000 --- a/app/src/main/play/da/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -AntennaPod er en app til hÃ¥ndtering og afspilning af podcasts. Den giver dig øjeblikkelig adgang til millioner af gratis og betalte podcasts, fra uafhængige podcastere til store udgivere som BBC, NPR, CNN og DR. Tilføj, importer og eksporter deres feeds problemfrit ved hjælp af iTunes-podcastdatabasen, OPML-filer eller enkle RSS-webadresser. Spar kræfter, batteristrøm og mobilt dataforbrug med kraftfulde automatiske styringsværktøjer til at hente udsendelser (angiv tidspunkter, tidsintervaller og udvalgte wi-fi-netværk) og sletning af episoder (baseret pÃ¥ dine foretrukne udsendelser og forsinkelsesindstillinger).<br> -Men vigtigst af alt: Hent, stream eller sæt udsendelser i kø og nyd dem pÃ¥ den mÃ¥de du kan lide med justerbare hastigheder, kapitelunderstøttelse og en søvntimer. Du kan endda vise din pÃ¥skønnelse over for indholdsskaberne med vores Flattr-integration. - -AntennaPod er lavet af en podcast-entusiast og er gratis og fri i alle betydninger: open source, ingen udgifter, ingen reklamer. - -<b>Alle funktioner:</b><br> -IMPORTER, ORGANISER OG AFSPIL<br> -• Tilføj og importer feeds via iTunes- og gpodder.net-oversigterne, OPML-filer og RSS- eller Atom-links<br> -• HÃ¥ndter afspilning fra hvor som helst: widget pÃ¥ startskærmen, systemnotifikation, samt hovedtelefon- og bluetooth-styring<br> -• Lyt pÃ¥ din egen mÃ¥de med justerbar afspilningshastighed, kapitelunderstøttelse (MP3, VorbisComment og Podlove), erindring af afspilningsposition og en avanceret søvntimer (ryst for at nulstille, sænke lydstyrken og afspille langsommere)<br> -• TilgÃ¥ feeds og udsendelser beskyttet med adgangskode<br> -• Brug sideinddelte feeds (www.podlove.org/paged-feeds) - -HOLD STYR PÃ…, DEL OG ANERKEND<br> -• Hold styr pÃ¥ det bedste af det bedste ved at markere udsendelser som foretrukne<br> -• Find en bestemt udsendelse via afspilningshistorikken eller ved at søge (titler og beskrivelser)<br> -• Del udsendelser og feeds via avancerede valgmuligheder for sociale medier, gpodder.net-tjenesterne og OPML-eksport<br> -• Støt indholdsskabere med Flattr-integration, inklusive automatisk flattring - -STYR SYSTEMET<br> -• Tag styring over automatiseret hentning: vælg feeds, udeluk mobile netværk, vælg specifikke wi-fi-netvæk, kræv at telefonen oplader og indstil tidspunkter eller tidsintervaller -• HÃ¥ndter lagerforbruget ved at indstille antallet af udsendelser, der skal gemmes, smart sletning (baseret pÃ¥ dine foretrukne og afspilningsstatus) og ved at vælge den lagerplacering, du foretrækker<br> -• Brug AntennaPod pÃ¥ dit eget sprog (EN, DE, DA, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Tilpas appen til dit miljø med det lyse og mørke tema<br> -• Sikkerhedskopier dine abonnementer med gpodder.net-integrationen og OPML-eksport - -<b>Bliv en del af AntennaPod-fællesskabet!</b><br> -AntennaPod er under aktiv udvikling af frivillige. Du kan ogsÃ¥ bidrage, med kode eller kommentarer! - -GitHub er stedet for forslag tli ny funktionalitet, fejlrapporter og kodebidrag:<br> -https://www.github.com/AntennaPod/AntennaPod - -Vores Google-gruppe er stedet til at dele dine ideer, foretrukne podcast-øjeblikke og taknemmelighed til alle de frivillige:<br> -https://groups.google.com/forum/#!forum/antennapod - -Har du et spørgsmÃ¥l eller vil du give os en tilbagemelding? -https://twitter.com/@AntennaPod - -Transifex er stedet, hvis du vil hjælpe med oversættelser:<br> -https://www.transifex.com/antennapod/antennapod - -Prøv vores beta-testprogram for at fÃ¥ de nyeste funktioner først:<br> -https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/de-DE/listing/fulldescription b/app/src/main/play/de-DE/listing/fulldescription index c2299c44f..0e09c5c29 100644 --- a/app/src/main/play/de-DE/listing/fulldescription +++ b/app/src/main/play/de-DE/listing/fulldescription @@ -1,20 +1,43 @@ -AntennaPod ist ein Open-Source Podcastmanager für Android 2.3.3+. Er bietet alle grundlegenden Funktionen, die Sie von einem Podcatcher erwarten. Dazu gehören das Streaming und Herunterladen von Episoden, alle Feeds automatisch zu aktualisieren oder sie einer Warteschlange hinzuzufügen, um sie später zu hören. Darüber hinaus können Sie mit AntennaPod Podcasts und Episoden aus der App heraus flattrn. - -Bisher sind folgende Funktionen eingebaut: - -* Herunterladen und Streamen von Episoden -Variable Abspielgeschwindigkeit (benötigt Presto Sound Library oder Prestissimo) -* Unterstützung von Atom- und RSS-Feeds -* Unterstützung für Passwort-geschützte Feeds und Episoden -* Unterstützung für Auflistungen die in iTunes gesucht werden -* OPML-Import und -Export -* Flattr-Integration, einschließlich automatischem Flattrn -* Player-Homescreen-Widget -* Suche -* Automatische Feed-Aktualisierungen -* Automatisches Herunterladen von neuen Episoden -* Schlummerfunktion -* Zugang zum gpodder.net-Verzeichnis hinzugefügt -* Option zum Synchronisieren der Podcast-Abonnements mit dem gpodder.net-Service hinzugefügt -* Unterstützt Kapitelmarken in MP3 und VorbisComment, sowie Podlove Simple Chapters -* Unterstützt Paged Feeds (http://podlove.org/paged-feeds/)
\ No newline at end of file +AntennaPod ist ein Podcast-Manager und -Player, der Dir unmittelbar Zugriff auf Millionen von freien und kostenpflichtigen Podcasts ermöglicht, angefangen von unabhängigen Podcastern bis hin zu großen Rundfunkanstalten wie BBC, NPR und CNN. Abonniere, importiere und exportiere deine Feeds mühelos mit Hilfe des iTunes-Verzeichnisses, OPML-Dateien oder einfachen RSS-URLs. Reduziere Aufwand, Stromverbrauch und Datenverbrauch durch die Kontrolle der Downloads (bestimmte Uhrzeiten, Intervalle, WiFi-Netze) und des Löschens von Episoden (basierend auf deinen Favoriten und weiteren Einstellungen).<br> +Aber am wichtigsten: Downloade, streame oder füge Episoden zur Abspielliste hinzu und genieße sie mit einstellbarer Abspielgeschwindigkeit, Unterstützung von Kapiteln und Schlummerfunktion. Mit Flattr kannst du den Podcastern sogar deine Wertschätzung zeigen. + +AntennaPod ist, von Podcast-Enthusiasten gemacht, frei im Sinne des Wortes: Open Source, keine Kosten, keine Werbung. + +<b>Alle Funktionen:</b><br> +IMPORTIERE, ORGANISIERE UND HÖRE<br> +• Importiere oder füge Feeds über das iTunes und gPodder.net Verzeichnis, OMPL Dateien und RSS oder Atom Links hinzu. +• Bediene die Wiedergabe von überall: Homescreen-Widget, Benachrichtigung und Koopfhörer- und Bluetooth-Bedienelementen<br> +• Genieße das Zuhören auf deine Art mit einstellbarer Abspielgeschwindigkeit, der Unterstützung von Kapiteln (MP3, OGG, Podlove) und ausgereifter Schlummerfunktion (durch Schütteln zurücksetzen, Lautstärke verringern und Geschwindigkeit verlangsamen) +• Greife auf Passwort-geschützte Feeds und Episoden zu<br> +• Nutze den Vorteil von Paged Feeds (http://www.podlove.org/paged-feeds) + +ORDNE, TEILE & GENIEßE +• Bleib an den Besten der Besten dran, indem Du Episoden als Favoriten markierst<br> +• Finde Episoden durch die Liste zuletzt gespielter Episoden oder durch Suche in Titel und Shownotes +• Teile Episoden and Feeds über soziale Medien, E-Mail, den gPodder.net-Dienst oder als OPML-Export +• Unterstütze die Autoren von Inhalten mit Flattr (inklusive automatischem Flattren) + +STEUER DAS SYSTEM<br> +• Kontrolliere automatisches Herunterladen: Wähle Feeds aus, schließe mobile Netze aus, suche bestimmte WiFi-Netze aus, setze voraus, dass das Smartphone geladen wird und lege Zeitpunkte oder Intervalle fest<br> +• Verwalte deinen Speicherplatz durch das Festlegen der Anzahl gespeicherter Episoden, schlaues Löschen und durch Auswahl des Speicherortes<br> +• Benutze AntennaPod in deiner Sprache (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> +• Passe das Aussehen mit dem hellen oder dunklen Theme an<br> +• Sichere deine Abonnements mit gPodder.net oder über den OPML-Export + +<b>Tritt der AntennaPod-Community bei!</b><br> +AntennaPod wird aktiv von Freiwilligen weiterentwickelt. Auch du kannst bei der Entwicklung mit Quellcode oder Kommentaren mitwirken! + +Wir verwenden GitHub für Funktionswünsche (Feature Requests), Fehlerberichte (Bug Reports) und zum Beisteuern von Code (Code Contributions). +https://www.github.com/AntennaPod/AntennaPod + +Teile deine Idee und Lieblingspodcastmomente und äußere Deine Dankbarkeit gegenüber allen Freiwilligen in unserer Google Group:<br> +https://groups.google.com/forum/#!forum/antennapod (Englisch) + +Du hast eine Frage oder willst uns Feedback geben? +https://twitter.com/@AntennaPod + +Mit Transifex kannst du uns beim Ãœbersetzen helfen:<br> +https://www.transifex.com/antennapod/antennapod + +Probiere unser Beta-Testing-Programm aus, um die neusten Funktionen als Erster zu erhalten:<br> +https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/de-DE/listing/title b/app/src/main/play/de-DE/listing/title index 31552f353..6c7c64cfc 100644 --- a/app/src/main/play/de-DE/listing/title +++ b/app/src/main/play/de-DE/listing/title @@ -1 +1 @@ -AntennaPod
\ No newline at end of file +AntennaPod diff --git a/app/src/main/play/de/listing/fulldescription b/app/src/main/play/de/listing/fulldescription deleted file mode 100644 index e5d7ec72a..000000000 --- a/app/src/main/play/de/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -AntennaPod ist ein Podcast-Manager und -Player, der Dir unmittelbar Zugriff auf Millionen von freien und bezahlten Podcasts ermöglicht, angefangen von unabhängigen Podcastern zu großen Rundfunkanstalten oder Hörfunksendern wie BBC, NPR und CNN. Abonniere, importiere und exportiere deine Feeds mühelos mit Hilfe des iTunes-Verzeichnisses, OPML-Dateien oder einfachen RSS-URLs. Reduziere Aufwand, Stromverbrauch und Datenverbrauch durch die Kontrolle der Downloads (bestimmte Uhrzeiten, Intervalle, WiFi-Netze) und des Löschens von Episoden (basierend auf deinen Favoriten und weiteren Einstellungen).<br> -Aber am wichtigsten: Downloade, streame oder füge Episoden zur Abspielliste hinzu und genieße sie mit einstellbarer Abspielgeschwindigkeit, Unterstützung von Kapiteln und Schlummerfunktion. Mit Flattr kannst du den Podcastern sogar deine Wertschätzung zeigen. - -AntennaPod ist, von Podcast-Enthusiasten gemacht, frei im Sinne des Wortes: Open Source, keine Kosten, keine Werbung. - -<b>Alle Funktionen:</b><br> -IMPORTIERE, ORGANISIERE UND HÖRE<br> -• Importiere oder füge Feeds über das iTunes und gPodder.net Verzeichnis, OMPL Dateien und RSS oder Atom Links hinzu. -• Bediene die Wiedergabe von überall: Homescreen-Widget, Benachrichtigung und Koopfhörer- und Bluetooth-Bedienelementen<br> -• Genieße das Zuhören auf deine Art mit einstellbarer Abspielgeschwindigkeit, der Unterstützung von Kapiteln (MP3, OGG, Podlove) und ausgereifter Schlummerfunktion (durch Schütteln zurücksetzen, Lautstärke verringern und Geschwindigkeit verlangsamen) -• Greife auf Passwort-geschützte Feeds und Episoden zu<br> -• Nutze den Vorteil von Paged Feeds (http://www.podlove.org/paged-feeds) - -ORDNE, TEILE & GENIEßE -• Bleib an den Besten der Besten dran, indem Du Episoden als Favoriten markierst<br> -• Finde Episoden durch die Liste zuletzt gespielter Episoden oder durch Suche in Titel und Shownotes -• Teile Episoden and Feeds über soziale Medien, E-Mail, den gPodder.net-Dienst oder als OPML-Export -• Unterstütze die Autoren von Inhalten mit Flattr (inklusive automatischem Flattren) - -STEUER DAS SYSTEM<br> -• Kontrolliere automatisches Herunterladen: Wähle Feeds aus, schließe mobile Netze aus, suche bestimmte WiFi-Netze aus, setze voraus, dass das Smartphone geladen wird und lege Zeitpunkte oder Intervalle fest<br> -• Verwalte deinen Speicherplatz durch das Festlegen der Anzahl gespeicherter Episoden, schlaues Löschen und durch Auswahl des Speicherortes<br> -• Benutze AntennaPod in deiner Sprache (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Passe das Aussehen mit dem hellen oder dunklen Theme an<br> -• Sichere deine Abonnements mit gPodder.net oder über den OPML-Export - -<b>Trete der AntennaPod-Community bei!</b><br> -AntennaPod wird aktiv von Freiwilligen weiterentwickelt. Auch du kannst bei der Entwicklung mit Quellcode oder Kommentaren mitwirken! - -Wir verwenden GitHub für Funktionswünsche (Feature Requests), Fehlerberichte (Bug Reports) und zum Beisteuern von Code (Code Contributions). -https://www.github.com/AntennaPod/AntennaPod - -Teile deine Idee und Lieblingspodcastmomente und äußere Deine Dankbarkeit gegenüber allen Freiwilligen in unserer Google Group:<br> -https://groups.google.com/forum/#!forum/antennapod (Englisch) - -Du hast eine Frage oder willst uns Feedback geben? -https://twitter.com/@AntennaPod - -Mit Transifex kannst du uns beim Ãœbersetzen helfen:<br> -https://www.transifex.com/antennapod/antennapod - -Probiere unser Beta-Testing-Programm aus, um die neusten Funktionen als Erster zu erhalten:<br> -https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/el-GR/listing/fulldescription b/app/src/main/play/el-GR/listing/fulldescription new file mode 100644 index 000000000..f0ec3ae38 --- /dev/null +++ b/app/src/main/play/el-GR/listing/fulldescription @@ -0,0 +1,43 @@ +Το Antennapod είναι μία εφαÏμογή διαχείÏισης και εκτÎλεσης podcasts που σας δίνει άμεση Ï€Ïόσβαση σε εκατομμÏÏια δωÏεάν και επί πληÏωμή podcasts, από ανεξάÏτητους podcasters Îως μεγάλους εκδοτικοÏÏ‚ οίκους όπως το BBC, NPR και CNN. ΜποÏείτε εÏκολα να Ï€ÏοσθÎσετε, να εισάγετε και να εξάγετε τις ÏοÎÏ‚ τους χÏησιμοποιώντας τη βάση δεδομÎνων podcast του iTunes, αÏχεία OPML ή απλά RSS URLs. Γλυτώστε Ï€Ïοσπάθεια, μπαταÏία και χÏήση δεδομÎνων κινητής τηλεφωνίας με ισχυÏÎÏ‚ Ïυθμίσεις αυτοματισμών για λήψη επεισοδίων (οÏίστε τους χÏόνους, τα διαστήματα και τα δίκτυα WiFi) και σβήστε επεισόδια (με βάση τα αγαπημÎνα σας και τις Ïυθμίσεις καθυστÎÏησης).<br> +Αλλά το πλÎον σημαντικό: Κατεβάστε, κάντε stream ή βάλτε στη σειÏά επεισόδια και απολαÏστε τα όπως επιθυμήτε με Ïυθμιζόμενη ταχÏτητα αναπαÏαγωγής, υποστήÏιξη κεφάλαιων και χÏονόμετÏο απενεÏγοποίησης. ΜποÏείτε ακόμη και να δείξετε την αγάπη σας στους δημιουÏγοÏÏ‚ πεÏιεχομÎνου μÎσω της ενσωμάτωσης του Flattr. + +ΦτιαγμÎνο από λάτÏη των podcast, το AntennaPod είναι ελεÏθεÏο με όλες τις Îννοιες της λÎξης: Î±Î½Î¿Î¹ÎºÏ„Î¿Ï Î»Î¿Î³Î¹ÏƒÎ¼Î¹ÎºÎ¿Ï, χωÏίς κόστη, χωÏίς διαφημίσεις. + +<b>Όλα τα χαÏακτηÏιστικά:</b><br> +ΕΙΣΑΓΩΓΉ, ΟΡΓΆÎΩΣΗ ΚΑΙ ΕΚΤΈΛΕΣΗ<br> +• Î ÏοσθÎστε και εισάγετε ÏοÎÏ‚ μÎσω των φακÎλων του iTunes και του gPodder.net, αÏχείων OPML και RSS ή συνδÎσμους Atom<br> +• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> +• 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> +• Access password-protected feeds and episodes<br> +• Take advantage of paged feeds (www.podlove.org/paged-feeds) + +KEEP TRACK, SHARE & APPRECIATE<br> +• Keep track of the best of the best by marking episodes as favourites<br> +• Find that one episode through the playback history or by searching (titles and shownotes)<br> +• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> +• Support content creators with Flattr integration including automatic flattring + +CONTROL THE SYSTEM<br> +• 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> +• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> +• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> +• Adapt to your environment using the light and dark theme<br> +• Back-up your subscriptions with the gPodder.net integration and OPML export + +<b>Ενταχθείτε στη κοινότητα του AntennaPod!</b><br> +Το AntennaPod βÏίσκεται υπό ενεÏγή ανάπτυξη από εθελοντÎÏ‚. ΜποÏείτε και εσείς να συνεισφÎÏετε, με κώδικα ή με κάποιο σχόλιο. + +Το Github είναι το μÎÏος να επισκεφθείτε για να ζητήσετε καινοÏÏια χαÏακτηÏιστικά, να αναφÎÏετε σφάλματα και για συνεισφοÏά κώδικα:<br> +https://www.github.com/AntennaPod/AntennaPod + +Το Google Group μας είναι το μÎÏος να μοιÏαστείτε τις ιδÎες σας, τις αγαπημÎνες σας στιγμÎÏ‚ ενασχόλησης με τα podcasts και ευγνωμοσÏνη σε όλους τους εθελοντÎÏ‚:<br> +https://groups.google.com/forum/#!forum/antennapod + +Έχετε κάποια εÏώτηση ή θÎλετε να μας δώσετε κάποια ανατÏοφοδότηση; +https://twitter.com/@AntennaPod + +Το Transifex είναι το μÎÏος για να βοηθήσετε με τις μεταφÏάσεις:<br> +https://www.transifex.com/antennapod/antennapod + +ΕλÎγξτε το Ï€ÏόγÏαμμά μας Beta Testing για να λαμβάνετε τα τελευταία χαÏακτηÏιστικά Ï€Ïώτοι:<br> +https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/el-GR/listing/shortdescription b/app/src/main/play/el-GR/listing/shortdescription new file mode 100644 index 000000000..7afb5a62d --- /dev/null +++ b/app/src/main/play/el-GR/listing/shortdescription @@ -0,0 +1 @@ +Easy-to-use, flexible and open-source podcast & radio manager and player
\ No newline at end of file diff --git a/app/src/main/play/el-GR/listing/title b/app/src/main/play/el-GR/listing/title new file mode 100644 index 000000000..6c7c64cfc --- /dev/null +++ b/app/src/main/play/el-GR/listing/title @@ -0,0 +1 @@ +AntennaPod diff --git a/app/src/main/play/el/listing/fulldescription b/app/src/main/play/el/listing/fulldescription deleted file mode 100644 index 87b477fdc..000000000 --- a/app/src/main/play/el/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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> -• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -CONTROL THE SYSTEM<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• 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/en-US/listing/fulldescription b/app/src/main/play/en-US/listing/fulldescription index 87b477fdc..2f5b4b2ff 100644 --- a/app/src/main/play/en-US/listing/fulldescription +++ b/app/src/main/play/en-US/listing/fulldescription @@ -1,4 +1,4 @@ -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> +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 on 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. @@ -40,4 +40,4 @@ 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 +https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod diff --git a/app/src/main/play/en-US/listing/shortdescription b/app/src/main/play/en-US/listing/shortdescription index 7afb5a62d..acf136ae9 100644 --- a/app/src/main/play/en-US/listing/shortdescription +++ b/app/src/main/play/en-US/listing/shortdescription @@ -1 +1 @@ -Easy-to-use, flexible and open-source podcast & radio manager and player
\ No newline at end of file +Easy-to-use, flexible and open-source podcast manager and player diff --git a/app/src/main/play/es-ES/listing/fulldescription b/app/src/main/play/es-ES/listing/fulldescription index 5cc6c5bf5..b1a87b434 100644 --- a/app/src/main/play/es-ES/listing/fulldescription +++ b/app/src/main/play/es-ES/listing/fulldescription @@ -1,40 +1,43 @@ -AntennaPod is un gestor y reproductor de podcast que te da acceso instantáneo a millones de podcast gratuitos y de pago, desde podcasters independientes a grandes estaciones como la BBC, NPR y CNN. Agrega, importa y exporta las fuentes de manera sencilla usando el listado de iTunes, archivos OPML o las URL de tipo RSS. Ahorra esfuerzo, baterÃa y datos con los controles de descarga (a horas o intervalos especÃficos, o redes WiFi) y de borrado de episodios (basado en favoritos y ajustes de tiempo).<br> -Y lo más importante: descarga, escucha en stream y disfrutalos como quieras con velocidad de reproducción variable, soporte para capÃtulos y temporizador de sueño. Incluso puedes mostrar tu gratitud a los creadores de contenido mediante Flattr. +AntennaPod es un administrador y reproductor de pódcast que te da acceso instantáneo a millones de pódcast gratuitos y de pago, desde editores independientes a grandes editoriales como la BBC, NPR y CNN. Agrega, importa y exporta tus fuentes sin complicaciones usando la base de datos de pódcast de iTunes, archivos OPML o las URL de tipo RSS. Ahorra esfuerzo, energÃa de la baterÃa y uso de datos móviles con potentes controles de automatización para descargar episodios (especifica horarios, intervalos y redes wifi) y elimina episodios (según tus favoritos y la configuración de retardo).<br> +Y lo más importante: descarga, escucha en continuo o pon en cola los episodios y disfrútalos como quieras con velocidades de reproducción ajustables, soporte de capÃtulos y temporizador de apagado. Incluso puedes mostrar tu gratitud a los creadores de contenido mediante Flattr. -Hecho por entusiastas del podcasting, AntennaPod es libre, gratuito y sin publicidad. +Creado por entusiastas del pódcast, AntennaPod es libre en todos los sentidos: código abierto, gratuito y sin publicidad. -<b>CaracterÃsticas:</b><br> +<b>Todas las caracterÃsticas:</b><br> IMPORTAR, ORGANIZAR Y REPRODUCIR<br> -• Añadir e importar feeds mediante los directorios iTunes o gPodder.net, archivos OPML y los enlaces RSS y Atom<br> -• Gestiona la reproducción desde cualquier parte: widget, notificación del sistema y controles de auricular y bluetooth<br> -• Disfruta escuchando a tu manera ajustando la velocidad de reproducción, con soporte para capÃtulos (MP3, VorbisComment y Podlove), recordando la posición de reproducción y un temporizador de sueño (agita para reiniciar, bajada de volumen y ralentización)<br> -• Accede a feeds y episodios protegidos con contraseña<br> -• Accede a feeds paginados (www.podlove.org/paged-feeds) - -RECUERDA, COMPARTE Y APRECIA -• Ten localizado lo mejor de lo mejor marcando episodios como favoritos<br> -• Encuentra ese episodio consultando el histórico o buscándolo (por tÃtulo o por notas de episodio)<br> -• Comparte episodios feeds con opciones avanzadas de redes sociales, email, servicios gPodder.net y exportación OPML<br> -• Ayuda a los creadores de contenido con la integración Flatter, siendo posible hacer Flattr automático +• Añade e importa fuentes mediante los directorios de iTunes y gPodder.net, archivos OPML y enlaces RSS o Atom<br> +• Administra la reproducción desde cualquier parte: control en pantalla de inicio, notificación del sistema y controles de auricular y bluetooth<br> +• Disfruta escuchando a tu manera con velocidad de reproducción ajustable, soporte de capÃtulos (MP3, VorbisComment y Podlove), recordatorio del punto de reproducción y el temporizador de sueño avanzado (agita para restablecer, bajar el volumen y disminuir la velocidad de reproducción)<br> +• Accede a fuentes y episodios protegidos con contraseña<br> +• Aprovecha las fuentes paginadas (www.podlove.org/paged-feeds) + +MANTÉN UN SEGUIMIENTO, COMPARTE Y APRECIA +• Haz un seguimiento de lo mejor de lo mejor marcando episodios como favoritos<br> +• Encuentra ese episodio a través del historial de reproducción o por búsqueda (tÃtulos y notas de episodios)<br> +• Comparte episodios y fuentes a través de las avanzadas redes sociales y opciones de correo electrónico, los servicios de gPodder.net y la exportación OPML<br> +• Ayuda a los creadores de contenido con la integración de Flattr, incluso automáticamente CONTROLA EL SISTEMA<br> -• Toma el control de la descarga automática: elige los feeds, excluye las redes móviles, elige redes WiFi especÃficas, hazlo sólo si el teléfono está cargando o a ciertas horas o intervalos<br> -• Gestiona el almacenamiento configurando la cantidad de episodios en caché, configura borrado inteligente (basado en favoritos y el estado de reproducción) y eligiendo tu ubicación favorita<br> +• Controla las descargas automáticas: elige las fuentes, excluye las redes móviles, selecciona redes wifi especÃficas, o solo cuando el teléfono se esté cargando y establece horarios o intervalos<br> +• Administra el almacenamiento configurando la cantidad de episodios almacenados, el borrado inteligente (según tus favoritos y el estado de reproducción) y selecciona tu ubicación preferida<br> • Usa AntennaPod en tu idioma (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> • Adáptate a tu entorno usando el tema claro u oscuro<br> -• Haz backup de tus suscripciones usando gPodder.net o exportando a OPML +• Haz una copia de seguridad de tus suscripciones con la integración de gPodder.net y la exportación OPML <b>¡Únete a la comunidad AntennaPod!</b><br> AntennaPod está en continuo desarrollo por voluntarios. ¡Tú también puedes contribuir, con tu código o con tus comentarios! GitHub es el sitio que debes visitar para solicitar caracterÃsticas nuevas, reportar fallos y contribuir con código<br> -www.github.com/AntennaPod/AntennaPod +https://www.github.com/AntennaPod/AntennaPod -Nuestro Grupo de Google es el sitio para compartir tus ideas, tus momentos favoritos de podcasting y tu gratitud a los voluntarios:<br> +Nuestro Grupo de Google es el sitio para compartir tus ideas, momentos favoritos de tus pódcast y tu gratitud a los voluntarios:<br> https://groups.google.com/forum/#!forum/antennapod +¿Tienes una pregunta o quieres darnos tu opinión? +https://twitter.com/@AntennaPod + Transifex es el sitio para ayudar con las traducciones:<br> -www.transifex.com/antennapod/antennapod +https://www.transifex.com/antennapod/antennapod -Echa un vistazo a nuestro programa de Beta Testing para ser el primero en usar las nuevas caracterÃsticas:<br> -www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file +Echa un vistazo a nuestro programa de pruebas Beta y ser el primero en usar las nuevas caracterÃsticas:<br> +https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/es-ES/listing/shortdescription b/app/src/main/play/es-ES/listing/shortdescription index e5b6ace85..37723ed99 100644 --- a/app/src/main/play/es-ES/listing/shortdescription +++ b/app/src/main/play/es-ES/listing/shortdescription @@ -1 +1 @@ -Reproductor y gestor de podcast de código abierto, flexible y fácil de usar
\ No newline at end of file +Gestor y reproductor de radio y pódcast fácil, flexible y de código abierto
\ No newline at end of file diff --git a/app/src/main/play/es-ES/listing/title b/app/src/main/play/es-ES/listing/title index 31552f353..6c7c64cfc 100644 --- a/app/src/main/play/es-ES/listing/title +++ b/app/src/main/play/es-ES/listing/title @@ -1 +1 @@ -AntennaPod
\ No newline at end of file +AntennaPod diff --git a/app/src/main/play/es/listing/fulldescription b/app/src/main/play/es/listing/fulldescription deleted file mode 100644 index 2f1c8861a..000000000 --- a/app/src/main/play/es/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -AntennaPod is un gestor y reproductor de podcast que te da acceso instantáneo a millones de podcast gratuitos y de pago, desde podcasters independientes a grandes estaciones como la BBC, NPR y CNN. Agrega, importa y exporta las fuentes de manera sencilla usando el listado de iTunes, archivos OPML o las URL de tipo RSS. Ahorra esfuerzo, baterÃa y datos con los controles de descarga (a horas o intervalos especÃficos, o redes WiFi) y de borrado de episodios (basado en favoritos y ajustes de tiempo).<br> -Y lo más importante: descarga, escucha en stream y disfrutalos como quieras con velocidad de reproducción variable, soporte para capÃtulos y temporizador de sueño. Incluso puedes mostrar tu gratitud a los creadores de contenido mediante Flattr. - -Hecho por entusiastas del podcasting, AntennaPod es libre, gratuito y sin publicidad. - -<b>CaracterÃsticas:</b><br> -IMPORTAR, ORGANIZAR Y REPRODUCIR<br> -• Añadir e importar feeds mediante los directorios iTunes o gPodder.net, archivos OPML y los enlaces RSS y Atom<br> -• Gestiona la reproducción desde cualquier parte: widget, notificación del sistema y controles de auricular y bluetooth<br> -• Disfruta escuchando a tu manera ajustando la velocidad de reproducción, con soporte para capÃtulos (MP3, VorbisComment y Podlove), recordando la posición de reproducción y un temporizador de sueño (agita para reiniciar, bajada de volumen y ralentización)<br> -• Accede a feeds y episodios protegidos con contraseña<br> -• Accede a feeds paginados (www.podlove.org/paged-feeds) - -RECUERDA, COMPARTE Y APRECIA -• Ten localizado lo mejor de lo mejor marcando episodios como favoritos<br> -• Encuentra ese episodio consultando el histórico o buscándolo (por tÃtulo o por notas de episodio)<br> -• Comparte episodios feeds con opciones avanzadas de redes sociales, email, servicios gPodder.net y exportación OPML<br> -• Ayuda a los creadores de contenido con la integración Flatter, siendo posible hacer Flattr automático - -CONTROLA EL SISTEMA<br> -• Toma el control de la descarga automática: elige los feeds, excluye las redes móviles, elige redes WiFi especÃficas, hazlo sólo si el teléfono está cargando o a ciertas horas o intervalos<br> -• Gestiona el almacenamiento configurando la cantidad de episodios en caché, configura borrado inteligente (basado en favoritos y el estado de reproducción) y eligiendo tu ubicación favorita<br> -• Usa AntennaPod en tu idioma (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adáptate a tu entorno usando el tema claro u oscuro<br> -• Haz backup de tus suscripciones usando gPodder.net o exportando a OPML - -<b>¡Únete a la comunidad AntennaPod!</b><br> -AntennaPod está en continuo desarrollo por voluntarios. ¡Tú también puedes contribuir, con tu código o con tus comentarios! - -GitHub es el sitio que debes visitar para solicitar caracterÃsticas nuevas, reportar fallos y contribuir con código<br> -https://www.github.com/AntennaPod/AntennaPod - -Nuestro Grupo de Google es el sitio para compartir tus ideas, tus momentos favoritos de podcasting y tu gratitud a los voluntarios:<br> -https://groups.google.com/forum/#!forum/antennapod - -¿Tienes una pregunta o quieres darnos tu opinión? -https://twitter.com/@AntennaPod - -Transifex es el sitio para ayudar con las traducciones:<br> -https://www.transifex.com/antennapod/antennapod - -Echa un vistazo a nuestro programa de Beta Testing para ser el primero en usar las nuevas caracterÃsticas:<br> -https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/es_ES/listing/fulldescription b/app/src/main/play/es_ES/listing/fulldescription deleted file mode 100644 index 1ce12e3b4..000000000 --- a/app/src/main/play/es_ES/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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> -• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -CONTROL THE SYSTEM<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• Back-up your subscriptions with the gPodder.net integration and OPML export - -<b>¡Únete a la comunidad de AntennaPod!</b><br> -AntennaPod is under active development by volunteers. You can contribute too, with code or with comment! - -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/et/listing/shortdescription b/app/src/main/play/et/listing/shortdescription new file mode 100644 index 000000000..7afb5a62d --- /dev/null +++ b/app/src/main/play/et/listing/shortdescription @@ -0,0 +1 @@ +Easy-to-use, flexible and open-source podcast & radio manager and player
\ No newline at end of file diff --git a/app/src/main/play/et/listing/title b/app/src/main/play/et/listing/title new file mode 100644 index 000000000..6c7c64cfc --- /dev/null +++ b/app/src/main/play/et/listing/title @@ -0,0 +1 @@ +AntennaPod diff --git a/app/src/main/play/fa/listing/shortdescription b/app/src/main/play/fa/listing/shortdescription new file mode 100644 index 000000000..7afb5a62d --- /dev/null +++ b/app/src/main/play/fa/listing/shortdescription @@ -0,0 +1 @@ +Easy-to-use, flexible and open-source podcast & radio manager and player
\ No newline at end of file diff --git a/app/src/main/play/fa/listing/title b/app/src/main/play/fa/listing/title new file mode 100644 index 000000000..6c7c64cfc --- /dev/null +++ b/app/src/main/play/fa/listing/title @@ -0,0 +1 @@ +AntennaPod diff --git a/app/src/main/play/fi/listing/fulldescription b/app/src/main/play/fi/listing/fulldescription deleted file mode 100644 index 87b477fdc..000000000 --- a/app/src/main/play/fi/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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> -• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -CONTROL THE SYSTEM<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• 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/fr-FR/listing/fulldescription b/app/src/main/play/fr-FR/listing/fulldescription index 61177b28a..372e1da60 100644 --- a/app/src/main/play/fr-FR/listing/fulldescription +++ b/app/src/main/play/fr-FR/listing/fulldescription @@ -1,40 +1,43 @@ -AntennaPod est un lecteur et gestionnaire de podcast permettant l'accès à des millions de podcast gratuits ou payants produit aussi bien par des podcasters indépendants que de gros éditeurs comme la BBC, NPR ou CNN. Ajoutez, importez et exportez leurs flux facilement à partir d'ITunes, de fichiers OPML ou simplement à partir de liens RSS. Économisez votre temps, votre batterie et votre consommation internet grâce à une automatisation puissante des téléchargements (quand, à quel rythme et à partir de quel réseau wifi) et de la suppression des épisodes (à partir d'un certains temps ou des favoris)<br> -Encore plus important : téléchargez, streamez ou mettez dans votre liste de lecture vos épisodes et écoutez les à votre manière grâce à une vitesse de lecture réglable, au support des chapitres et une fonction de mise en veille automatique. Vous pouvez même montrer votre appréciation aux créateurs de contenu avec notre intégration de Flattr. +AntennaPod est un lecteur et gestionnaire de podcast permettant l'accès à des millions de podcast gratuits ou payants produit aussi bien par des podcasters indépendants que de gros éditeurs comme la BBC, NPR ou CNN. Ajoutez, importez et exportez leurs flux facilement à partir d'ITunes, de fichiers OPML ou simplement à partir de liens RSS. Gagnez du temps, préservez votre batterie et consommation internet grâce à une automatisation puissante des téléchargements (date, fréquence, choix du réseau WiFi, etc...) et des suppressions d’épisodes écoutés (selon vos critères)<br> +Avant tout : téléchargez, streamez ou ajoutez à la liste de lecture vos épisodes et écoutez les comme vous voulez grâce au réglage de vitesse de lecture, au support des chapitres et au minuteur d'arrêt. Vous pouvez même montrer votre appréciation aux créateurs de contenu avec notre intégration de Flattr. -Programmé par des fans de podcast, AntennaPod est gratuit dans tous les sens du terme : open source, aucun cout et pas de publicité. +Conçu par des fans de podcast, AntennaPod est gratuit dans tous les sens du terme : open source, gratuit et sans publicité. <b>Caractéristiques complètes :</b><br> -Importer, gérer et écouter<br> -• Ajouter et importer à partir d'iTunes, gPodder.net, de fichiers OPML ou de liens RSS ou Atom<br> -• Gérez la lecture de n'importe où : widget sur l'écran d'accueil, notification système, commande casque ou bluetooth<br> -• Ecoutez à votre façon grâce à une vitesse de lecture réglable, au support des chapitres (MP3, VorbisComment et Podlove), enregistrement de la position de lecture et une mise en veille automatique puissante (secouer pour prolonger le minuteur, baisse du volume et ralentissement de la lecture)<br> +IMPORTER, GÉRER ET ÉCOUTER<br> +• Ajouter et importer à partir d'iTunes, gPodder.net, fichiers OPML, liens RSS ou Atom<br> +• Gérez la lecture de n'importe où : widget sur l'écran d'accueil, notification système, commande casque ou Bluetooth<br> +• Écoutez à votre façon grâce à une vitesse de lecture réglable, au support des chapitres (MP3, VorbisComment et Podlove), à l'enregistrement de la position de lecture et à une mise en veille automatique puissante (secouez pour prolonger le minuteur, baisser le volume et ralentir la lecture)<br> • Accès aux flux et épisodes protégés par mot de passe<br> -• Tirez profit des flux à plusieurs pages (www.podlove.org/paged-feeds) +• Tirez profit des flux paginés (www.podlove.org/paged-feeds) -GARDEZ TRACE, PARTAGEZ & APPRECIEZ<br> -• Gardez trace des meilleurs épisodes en les marquant comme favoris<br> -• Retrouvez un épisode à partir de l'historique de lecture ou en cherchant (les titres et les commentaires des épisodes)<br> -• Partagez vos épisodes ou flux à travers des options de réseaux sociaux et email avancées, du service gPodder.net ou par des exports OPML<br> +SUIVEZ, PARTAGEZ & PROFITEZ<br> +• Marquer les meilleurs épisodes en tant que favoris<br> +• Retrouvez un épisode à partir de l'historique de lecture ou en recherchant parmi les titres et commentaires des épisodes précédents<br> +• Partagez vos épisodes et flux sur les réseaux sociaux, par email, sur gPodder.net ou en les exportant au format OPML<br> • Soutenez les créateurs de contenu avec l'intégration à Flattr et la possibilité de flatter automatiquement CONTRÔLER LE SYSTÈME<br> -• Prenez le contrôle avec l'automatisation des téléchargements : choisissez les flux, empêchez l'utilisation du réseau mobile, sélectionnez les réseaux WIFI à utiliser, exigez que le téléphone soit en train de charger et spécifiez quand ou à quel rythme<br> -• Gérez l'espace de stockage en paramétrant le nombre d'épisodes à garder, de leurs suppressions automatique (à partir de vos favoris et du statut de lecture) et de l'emplacement où les enregistrer<br> +• Prenez le contrôle en automatisant vos téléchargements : choix des flux, restriction de la connexion mobile, sélection du réseau WIFI à utiliser, uniquement durant la recharge et spécifiez la fréquence de mise à jour vous-même<br> +• Gérez l'espace de stockage en paramétrant le nombre d'épisodes à garder, leur suppression automatique (en fonction de vos favoris et de leur statut) et leur emplacement sur le disque<br> • Utilisez AntennaPod dans votre langue (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adaptez à votre environnement avec un thème clair ou sombre<br> -• Sauvegardez vos abonnements avec l'intération à gPodder.net ou des exports OPML +• Choix d'un thème clair ou sombre selon vos préférences<br> +• Sauvegardez vos abonnements avec l’intégration à gPodder.net et les exports OPML <b>Rejoignez la communauté d'AntennaPod !</b><br> -AntennaPod est développé activement par des volontaires. Vous pouvez aussi contribuer avec du code ou des commentaires ! +AntennaPod est développé activement par des volontaires. Vous pouvez aussi contribuer avec du code, des traductions ou des commentaires ! GitHub est l'endroit où aller pour demander de nouvelles options, faire part de bug ou pour contribuer au code :<br> -www.github.com/AntennaPod/AntennaPod +https://www.github.com/AntennaPod/AntennaPod -Notre groupe Google est l'endroit où aller pour partager vos idées, moments préférés de podcast et vos remerciements aux volontaires :<br> +Rejoignez notre Google Group pour partager vos idées, podcast préférés et vos remerciements à tous les bénévoles :<br> https://groups.google.com/forum/#!forum/antennapod -Transifex est le lieu où vous pouvez aider à la traduction :<br> -www.transifex.com/antennapod/antennapod +Vous avez une question ou des suggestions ? +https://twitter.com/@AntennaPod + +Retrouvez nous sur Transifex pour contribuer à la traduction de cette app :<br> +https://www.transifex.com/antennapod/antennapod Jetez un coup d’œil à notre programme de version Beta pour bénéficier des dernières options :<br> -www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file +https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/fr-FR/listing/shortdescription b/app/src/main/play/fr-FR/listing/shortdescription index 61c3c7e20..93944d272 100644 --- a/app/src/main/play/fr-FR/listing/shortdescription +++ b/app/src/main/play/fr-FR/listing/shortdescription @@ -1 +1 @@ -Un lecteur et gestionnaire de podcast facile à utiliser et flexible
\ No newline at end of file +Un lecteur de podcast simple et flexible
\ No newline at end of file diff --git a/app/src/main/play/fr-FR/listing/title b/app/src/main/play/fr-FR/listing/title index 31552f353..6c7c64cfc 100644 --- a/app/src/main/play/fr-FR/listing/title +++ b/app/src/main/play/fr-FR/listing/title @@ -1 +1 @@ -AntennaPod
\ No newline at end of file +AntennaPod diff --git a/app/src/main/play/fr/listing/fulldescription b/app/src/main/play/fr/listing/fulldescription deleted file mode 100644 index 372e1da60..000000000 --- a/app/src/main/play/fr/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -AntennaPod est un lecteur et gestionnaire de podcast permettant l'accès à des millions de podcast gratuits ou payants produit aussi bien par des podcasters indépendants que de gros éditeurs comme la BBC, NPR ou CNN. Ajoutez, importez et exportez leurs flux facilement à partir d'ITunes, de fichiers OPML ou simplement à partir de liens RSS. Gagnez du temps, préservez votre batterie et consommation internet grâce à une automatisation puissante des téléchargements (date, fréquence, choix du réseau WiFi, etc...) et des suppressions d’épisodes écoutés (selon vos critères)<br> -Avant tout : téléchargez, streamez ou ajoutez à la liste de lecture vos épisodes et écoutez les comme vous voulez grâce au réglage de vitesse de lecture, au support des chapitres et au minuteur d'arrêt. Vous pouvez même montrer votre appréciation aux créateurs de contenu avec notre intégration de Flattr. - -Conçu par des fans de podcast, AntennaPod est gratuit dans tous les sens du terme : open source, gratuit et sans publicité. - -<b>Caractéristiques complètes :</b><br> -IMPORTER, GÉRER ET ÉCOUTER<br> -• Ajouter et importer à partir d'iTunes, gPodder.net, fichiers OPML, liens RSS ou Atom<br> -• Gérez la lecture de n'importe où : widget sur l'écran d'accueil, notification système, commande casque ou Bluetooth<br> -• Écoutez à votre façon grâce à une vitesse de lecture réglable, au support des chapitres (MP3, VorbisComment et Podlove), à l'enregistrement de la position de lecture et à une mise en veille automatique puissante (secouez pour prolonger le minuteur, baisser le volume et ralentir la lecture)<br> -• Accès aux flux et épisodes protégés par mot de passe<br> -• Tirez profit des flux paginés (www.podlove.org/paged-feeds) - -SUIVEZ, PARTAGEZ & PROFITEZ<br> -• Marquer les meilleurs épisodes en tant que favoris<br> -• Retrouvez un épisode à partir de l'historique de lecture ou en recherchant parmi les titres et commentaires des épisodes précédents<br> -• Partagez vos épisodes et flux sur les réseaux sociaux, par email, sur gPodder.net ou en les exportant au format OPML<br> -• Soutenez les créateurs de contenu avec l'intégration à Flattr et la possibilité de flatter automatiquement - -CONTRÔLER LE SYSTÈME<br> -• Prenez le contrôle en automatisant vos téléchargements : choix des flux, restriction de la connexion mobile, sélection du réseau WIFI à utiliser, uniquement durant la recharge et spécifiez la fréquence de mise à jour vous-même<br> -• Gérez l'espace de stockage en paramétrant le nombre d'épisodes à garder, leur suppression automatique (en fonction de vos favoris et de leur statut) et leur emplacement sur le disque<br> -• Utilisez AntennaPod dans votre langue (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Choix d'un thème clair ou sombre selon vos préférences<br> -• Sauvegardez vos abonnements avec l’intégration à gPodder.net et les exports OPML - -<b>Rejoignez la communauté d'AntennaPod !</b><br> -AntennaPod est développé activement par des volontaires. Vous pouvez aussi contribuer avec du code, des traductions ou des commentaires ! - -GitHub est l'endroit où aller pour demander de nouvelles options, faire part de bug ou pour contribuer au code :<br> -https://www.github.com/AntennaPod/AntennaPod - -Rejoignez notre Google Group pour partager vos idées, podcast préférés et vos remerciements à tous les bénévoles :<br> -https://groups.google.com/forum/#!forum/antennapod - -Vous avez une question ou des suggestions ? -https://twitter.com/@AntennaPod - -Retrouvez nous sur Transifex pour contribuer à la traduction de cette app :<br> -https://www.transifex.com/antennapod/antennapod - -Jetez un coup d’œil à notre programme de version Beta pour bénéficier des dernières options :<br> -https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/gl/listing/fulldescription b/app/src/main/play/gl-ES/listing/fulldescription index c26d4078c..c26d4078c 100644 --- a/app/src/main/play/gl/listing/fulldescription +++ b/app/src/main/play/gl-ES/listing/fulldescription diff --git a/app/src/main/play/gl-ES/listing/shortdescription b/app/src/main/play/gl-ES/listing/shortdescription new file mode 100644 index 000000000..9b18a10fc --- /dev/null +++ b/app/src/main/play/gl-ES/listing/shortdescription @@ -0,0 +1 @@ +Xestor/Reprodutor de podcast e radio doado de usar, flexible e de fontes abertas
\ No newline at end of file diff --git a/app/src/main/play/gl-ES/listing/title b/app/src/main/play/gl-ES/listing/title new file mode 100644 index 000000000..6c7c64cfc --- /dev/null +++ b/app/src/main/play/gl-ES/listing/title @@ -0,0 +1 @@ +AntennaPod diff --git a/app/src/main/play/he_IL/listing/fulldescription b/app/src/main/play/he_IL/listing/fulldescription deleted file mode 100644 index b4ac8ca6c..000000000 --- a/app/src/main/play/he_IL/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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. - -מיוצרת על ידי חובבי פודק×סטי×, ×× ×˜× ×”×¤×•×“ ×”×™× ×” ×ª×•×›× ×” ×—×™× ×ž×™×ª בכל מובן המילה: קוד פתוח, ×œ×œ× ×¢×œ×•×ª ×•×œ×œ× ×¤×¨×¡×•×ž×•×ª. - -<b>All features:</b><br> -IMPORT, ORGANIZE AND PLAY<br> -• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -CONTROL THE SYSTEM<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• 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/hi-IN/listing/fulldescription b/app/src/main/play/hi-IN/listing/fulldescription index f4687b885..c4d6594b9 100644 --- a/app/src/main/play/hi-IN/listing/fulldescription +++ b/app/src/main/play/hi-IN/listing/fulldescription @@ -1,20 +1,43 @@ -à¤à¤¨à¥à¤Ÿà¥‡à¤¨à¤¾à¤ªà¥‰à¤¡ à¤à¤‚डà¥à¤°à¥‰à¤¯à¤¡ 2.3.3 और ऊपर के लिठà¤à¤• खà¥à¤²à¤¾ सà¥à¤°à¥‹à¤¤ पॉडकासà¥à¤Ÿ पà¥à¤°à¤¬à¤‚धक है. यह आपको सà¥à¤µà¤šà¤¾à¤²à¤¿à¤¤ रूप से सà¤à¥€ फ़ीड ताज़ा या बाद में उनà¥à¤¹à¥‡à¤‚ सà¥à¤¨à¤¨à¥‡ के लिठà¤à¤• कतार में जोड़ने, à¤à¤ªà¤¿à¤¸à¥‹à¤¡ सà¥à¤Ÿà¥à¤°à¥€à¤®à¤¿à¤‚ग और डाउनलोड करने, à¤à¤• पॉडकैचर से उमà¥à¤®à¥€à¤¦ रखने वाली सà¤à¥€ बà¥à¤¨à¤¿à¤¯à¤¾à¤¦à¥€ सà¥à¤µà¤¿à¤§à¤¾à¤à¤ पà¥à¤°à¤¦à¤¾à¤¨ करता है. इसके अलावा, à¤à¤¨à¥à¤Ÿà¥‡à¤¨à¤¾à¤ªà¥‰à¤¡ आपको अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— के à¤à¥€à¤¤à¤° से फà¥à¤²à¥‡à¤Ÿà¤° पॉडकासà¥à¤Ÿ और पà¥à¤°à¤•à¤°à¤£à¥‹à¤‚ की सà¥à¤µà¤¿à¤§à¤¾ देता है. - -So far the following features are implemented: - -* डाउनलोड और à¤à¤ªà¤¿à¤¸à¥‹à¤¡ के सà¥à¤Ÿà¥à¤°à¥€à¤®à¤¿à¤‚ग -* चर गति पà¥à¤²à¥‡à¤¬à¥ˆà¤• (सफ़ाई धà¥à¤µà¤¨à¤¿ पà¥à¤¸à¥à¤¤à¤•à¤¾à¤²à¤¯ या पà¥à¤°à¥‡à¤¸à¥à¤Ÿà¤¿à¤¸à¥€à¤®à¥‹ कि आवशà¥à¤¯à¤•à¤¤à¤¾ है) - * à¤à¤Ÿà¤® और आरà¤à¤¸à¤à¤¸ फ़ीड के लिठसहायता -* Support for password-protected feeds and episodes -* Support for searching iTunes listings -* ओà¤à¤®à¤ªà¥€à¤à¤² आयात और निरà¥à¤¯à¤¾à¤¤ -* Flattr integration including automatic flattring -* पà¥à¤²à¥‡à¤¯à¤° होमसà¥à¤•à¥à¤°à¥€à¤¨ विजेट -* खोज -* सà¥à¤µà¤šà¤¾à¤²à¤¿à¤¤ फ़ीड अदà¥à¤¯à¤¤à¤¨ -* नठà¤à¤ªà¤¿à¤¸à¥‹à¤¡ की सà¥à¤µà¤šà¤¾à¤²à¤¿à¤¤ डाउनलोड -* सà¥à¤²à¥€à¤ª टाइमर -* Gpodder.net podcast निरà¥à¤¦à¥‡à¤¶à¤¿à¤•à¤¾ के लिठपà¥à¤°à¤µà¥‡à¤¶ -* gpodder.net सेवा के साथ सदसà¥à¤¯à¤¤à¤¾ सिंकà¥à¤°à¤¨à¤¾à¤‡à¤œà¤¼ -* Supports MP3 chapters, VorbisComment chapters and Podlove Simple Chapters -* Supports paged feeds (http://podlove.org/paged-feeds/)
\ No newline at end of file +à¤à¤¨à¥à¤Ÿà¥‡à¤¨à¤¾à¤ªà¥‰à¤¡ à¤à¤• पॉडकासà¥à¤Ÿ मेनेजर और पà¥à¤²à¥‡à¤¯à¤° है जो आपको सà¥à¤µà¤¤à¤‚तà¥à¤° पॉडकासà¥à¤Ÿà¤°à¥à¤¸ से लेकर बीबीसी, à¤à¤¨à¤ªà¥€à¤†à¤° और सीà¤à¤¨à¤à¤¨ जैसे बड़े पबà¥à¤²à¤¿à¤¶à¤¿à¤‚ग घरों के लाखों मà¥à¤«à¥à¤¤ और à¤à¥à¤—तान पॉडकासà¥à¤Ÿ की तà¥à¤°à¤‚त उपलबà¥à¤§à¤¿ करता है। आईटà¥à¤¯à¥‚नà¥à¤¸ पॉडकासà¥à¤Ÿ डेटाबेस, ओपीà¤à¤®à¤à¤² फाइलà¥à¤¸ या सरल आरà¤à¤¸à¤à¤¸ यूआरà¤à¤² का उपयोग करके उनके फीडà¥à¤¸ बिना कोई परेशानी के जोड़ें, आयात और निरà¥à¤¯à¤¾à¤¤ करें। à¤à¤ªà¤¿à¤¸à¥‹à¤¡ डाउनलोड करने (समय, अंतराल और वाईफाई नेटवरà¥à¤• निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ करके) और à¤à¤ªà¤¿à¤¸à¥‹à¤¡ को हटाने (आपके पसंदीदा और देरी की सेटिंगà¥à¤¸ के आधार पर) के लिठइसमे शकà¥à¤¤à¤¿à¤¶à¤¾à¤²à¥€ सà¥à¤µà¤šà¤¾à¤²à¤¨ नियंतà¥à¤°à¤¨à¥‹ है जो बैटरी पावर और मोबाइल डेटा की बचत करे।<br> +परंतॠसबसे महतà¥à¤µà¤ªà¥‚रà¥à¤£ बात: à¤à¤ªà¤¿à¤¸à¥‹à¤¡à¥à¤¸ डाउनलोड करें, सà¥à¤Ÿà¥à¤°à¥€à¤® करें या पंकà¥à¤¤à¤¿ बनाà¤à¤‚ और à¤à¤¡à¤œà¤¸à¥à¤Ÿà¥‡à¤¬à¤² पà¥à¤²à¥‡à¤¬à¥ˆà¤• गति, अधà¥à¤¯à¤¾à¤¯ समरà¥à¤¥à¤¨ और टाइमरॠके साथ उनà¥à¤¹à¥‡ अपने अंदाज़ में आनंद लें। आप हमारे फà¥à¤²à¤¾à¤Ÿà¤° à¤à¤•à¥€à¤•à¤°à¤£ के साथ निरà¥à¤®à¤¾à¤¤à¤¾à¤“ को अपना पà¥à¤¯à¤¾à¤° à¤à¥€ जता सकते हैं। + +पॉडकासà¥à¤Ÿ-उतà¥à¤¸à¤¾à¤¹à¥€ दà¥à¤µà¤¾à¤°à¤¾ निरà¥à¤®à¤¿à¤¤, à¤à¤¨à¥à¤Ÿà¥‡à¤¨à¤¾à¤ªà¥‰à¤¡ पूरà¥à¤£ रूप से ओपन सोरà¥à¤¸, मà¥à¤«à¥à¤¤ और विजà¥à¤žà¤¾à¤ªà¤¨ हीन है। + +<b>सारे विशेषताà¤à¤‚:</b><br> +आयात करे, वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¿à¤¤ करे और चलाà¤à¤‚<br> +• आईटà¥à¤¯à¥‚नà¥à¤¸ और gPodder.net डिरेकà¥à¤Ÿà¤°à¥€à¥›, ओपीà¤à¤®à¤à¤² फाइलà¥à¤¸ और आरà¤à¤¸à¤à¤¸ या à¤à¤Ÿà¤® लिंकà¥à¤¸ के माधà¥à¤¯à¤® से फीडà¥à¤¸ जोड़ें और आयात करें।<br> +• कहीं से à¤à¥€ पà¥à¤²à¥‡à¤¬à¥ˆà¤• मेनेज करें: होमसà¥à¤•à¥à¤°à¥€à¤¨ विजेट, सिसà¥à¤Ÿà¤® अधिसूचना और इयरपà¥à¤²à¤— और बà¥à¤²à¥‚टूथ नियंतà¥à¤°à¤£<br> +• à¤à¤¡à¤œà¤¸à¥à¤Ÿà¥‡à¤¬à¤² पà¥à¤²à¥‡à¤¬à¥ˆà¤• गति, अधà¥à¤¯à¤¾à¤¯ समरà¥à¤¥à¤¨ (MP3, वोरà¥à¤¬à¥€à¤¸ कमेंट और पॉडलव), याद रखी पà¥à¤²à¥‡à¤¬à¥ˆà¤• सà¥à¤¥à¤¾à¤¨ और आधà¥à¤¨à¤¿à¤• टाइमर (हिलाकर रीसेट करे, आवाज़ धीमी करे और पà¥à¤²à¥‡à¤¬à¥ˆà¤• गति कम करें) के साथ अपने अंदाज़ में सà¥à¤¨à¤¨à¥‡ का आनंद लें<br> +• पासवरà¥à¤¡-संरकà¥à¤·à¤¿à¤¤ फीडà¥à¤¸ और à¤à¤ªà¤¿à¤¸à¥‹à¤¡à¥à¤¸ की पहà¥à¤à¤š पà¥à¤°à¤¾à¤ªà¥à¤¤ करे<br> +• पेजà¥à¤¡à¥ फीडà¥à¤¸ का लाठउठाà¤à¤‚ (www.podlove.org/paged-feeds) + +जà¥à¥œà¥‡ रहे, शेयर करे और सराहिये<br> +• सबसे शà¥à¤°à¥‡à¤·à¥à¤ का टà¥à¤°à¥ˆà¤• रखने, उस à¤à¤ªà¤¿à¤¸à¥‹à¤¡ को पसंदीदा के रूप में चिहà¥à¤¨à¤¿à¤¤ करे<br> +• पà¥à¤²à¥‡à¤¬à¥ˆà¤• इतिहास दà¥à¤µà¤¾à¤°à¤¾ या (शीरà¥à¤·à¤• और शोनोटà¥à¤¸) को खोजकर, आपका वो à¤à¤• à¤à¤ªà¤¿à¤¸à¥‹à¤¡ पाय<br> +• उनà¥à¤¨à¤¤ सोशल मीडिया और ईमेल विकलà¥à¤ªà¥‹à¤‚, gPodder.net सेवाओं और ओपीà¤à¤®à¤à¤² निरà¥à¤¯à¤¾à¤¤ के माधà¥à¤¯à¤® से à¤à¤ªà¤¿à¤¸à¥‹à¤¡à¥à¤¸ और फ़ीड शेयर करें<br> +• सà¥à¤µà¤šà¤¾à¤²à¤¿à¤¤ फà¥à¤²à¤¾à¤Ÿà¤°à¤¿à¤‚ग सहित फà¥à¤²à¤¾à¤Ÿà¤° à¤à¤•à¥€à¤•à¤°à¤£ दà¥à¤µà¤¾à¤°à¤¾ निरà¥à¤®à¤¾à¤¤à¤¾à¤“ का समरà¥à¤¥à¤¨ करे + +सिसà¥à¤Ÿà¤® को काबू में करें<br> +• सà¥à¤µà¤šà¤¾à¤²à¤¿à¤¤ डौनà¥à¤²à¥‹à¤¡à¤¸ पर पूरा नियंतà¥à¤°à¤¿à¤¤ रखे: फीडà¥à¤¸ चà¥à¤¨à¥‡, मोबाइल और वैफै नेटवरà¥à¤• चà¥à¤¨à¥‡, फोन चारà¥à¤œà¤¿à¤‚ग की आवशà¥à¤¯à¤•à¤¤à¤¾, समय और अंतराल निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ करे<br> +• कैश किठगठà¤à¤ªà¤¿à¤¸à¥‹à¤¡ की मातà¥à¤°à¤¾ निरà¥à¤§à¤¾à¤°à¤¿à¤¤ करना, सà¥à¤®à¤¾à¤°à¥à¤Ÿ विलोपन करना (आपके पसंदीदा सूची और पà¥à¤²à¥‡ सà¥à¤¥à¤¿à¤¤à¤¿ के आधार पर) और अपनी पà¥à¤°à¤¾à¤¥à¤®à¤¿à¤• सà¥à¤¥à¤¾à¤¨ चà¥à¤¨à¤¨à¤¾<br> +• à¤à¤¨à¥à¤Ÿà¥‡à¤¨à¤¾à¤ªà¥‰à¤¡ को अपनी à¤à¤¾à¤·à¤¾ में इसà¥à¤¤à¥‡à¤®à¤¾à¤² करें (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> +• लाइट और डारà¥à¤• थीम का उपयोग करके, अपने परà¥à¤¯à¤¾à¤µà¤°à¤£ से अनà¥à¤•à¥‚लित बनाà¤<br> +• gPodder.net à¤à¤•à¥€à¤•à¤°à¤£ और ओपीà¤à¤®à¤à¤² निरà¥à¤¯à¤¾à¤¤ दà¥à¤µà¤¾à¤°à¤¾ अपने सबà¥à¤¸à¥à¤•à¥à¤°à¤¿à¤ªà¥à¤¶à¤¨à¥à¤¸ बैकअप करें। + +<b>à¤à¤¨à¥à¤Ÿà¥‡à¤‚नापॉड समà¥à¤¦à¤¾à¤¯ में शामिल होइà¤à¥¤</b><br> +à¤à¤¨à¥à¤Ÿà¥‡à¤‚नापॉड सà¥à¤µà¤¯à¤‚सेवकों दà¥à¤µà¤¾à¤°à¤¾ सकà¥à¤°à¤¿à¤¯ विकास में है। आप à¤à¥€ कोड या कमेंट के साथ योगदान कर सकते हैं। + +सà¥à¤µà¤¿à¤§à¤¾ अनà¥à¤°à¥‹à¤§, बग रिपोरà¥à¤Ÿ और कोड योगदान के लिठगिटहब पर जाà¤à¤‚:<br> +https://www.github.com/AntennaPod/AntennaPod + +हमारा गूगल गà¥à¤°à¥à¤ª आपके विचारों, पसंदीदा पॉडकासà¥à¤Ÿà¤¿à¤‚ग पल और सà¤à¥€ सà¥à¤µà¤¯à¤‚सेवकों के पà¥à¤°à¤¤à¤¿ आà¤à¤¾à¤° साà¤à¤¾ करने का सà¥à¤¥à¤¾à¤¨ है:<br> +https://groups.google.com/forum/#!forum/antennapod + +कà¥à¤¯à¤¾ आप का कोई सवाल पूछना चाहते है या कोई सà¥à¤à¤¾à¤µ देना चाहते है? +https://twitter.com/@AntennaPod + +अनà¥à¤µà¤¾à¤¦à¥‹ की सहायता करने टà¥à¤°à¤¾à¤‚सिफेकà¥à¤¸ पर जाà¤à¤‚:<br> +https://www.transifex.com/antennapod/antennapod + +नवीनतम विशेषताà¤à¤‚ को सबसे पहले पाने हमारे बीटा परीकà¥à¤·à¤£ कारà¥à¤¯à¤•à¥à¤°à¤® में शामिल होइà¤:<br> +https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/hi-IN/listing/title b/app/src/main/play/hi-IN/listing/title index 31552f353..6c7c64cfc 100644 --- a/app/src/main/play/hi-IN/listing/title +++ b/app/src/main/play/hi-IN/listing/title @@ -1 +1 @@ -AntennaPod
\ No newline at end of file +AntennaPod diff --git a/app/src/main/play/hi_IN/listing/fulldescription b/app/src/main/play/hi_IN/listing/fulldescription deleted file mode 100644 index 87b477fdc..000000000 --- a/app/src/main/play/hi_IN/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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> -• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -CONTROL THE SYSTEM<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• 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/hu/listing/fulldescription b/app/src/main/play/hu/listing/fulldescription deleted file mode 100644 index 87b477fdc..000000000 --- a/app/src/main/play/hu/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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> -• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -CONTROL THE SYSTEM<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• 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/id/listing/fulldescription b/app/src/main/play/id/listing/fulldescription deleted file mode 100644 index 87b477fdc..000000000 --- a/app/src/main/play/id/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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> -• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -CONTROL THE SYSTEM<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• Back-up your subscriptions with the gPodder.net integration and OPML export - -<b>Join the AntennaPod community!</b><br> -AntennaPod is under active development by volunteers. You can contribute too, with code or with comment! - -GitHub is the place to go for feature requests, bug reports and code contributions:<br> -https://www.github.com/AntennaPod/AntennaPod - -Our Google Group is the place to share your ideas, favourite podcasting moments and gratitude to all the volunteers:<br> -https://groups.google.com/forum/#!forum/antennapod - -Have a question or want to give us feedback? -https://twitter.com/@AntennaPod - -Transifex is the place to help with translations:<br> -https://www.transifex.com/antennapod/antennapod - -Check out our Beta Testing programme to get the latest features first:<br> -https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/is/listing/fulldescription b/app/src/main/play/is/listing/fulldescription deleted file mode 100644 index 87b477fdc..000000000 --- a/app/src/main/play/is/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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> -• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -CONTROL THE SYSTEM<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• Back-up your subscriptions with the gPodder.net integration and OPML export - -<b>Join the AntennaPod community!</b><br> -AntennaPod is under active development by volunteers. You can contribute too, with code or with comment! - -GitHub is the place to go for feature requests, bug reports and code contributions:<br> -https://www.github.com/AntennaPod/AntennaPod - -Our Google Group is the place to share your ideas, favourite podcasting moments and gratitude to all the volunteers:<br> -https://groups.google.com/forum/#!forum/antennapod - -Have a question or want to give us feedback? -https://twitter.com/@AntennaPod - -Transifex is the place to help with translations:<br> -https://www.transifex.com/antennapod/antennapod - -Check out our Beta Testing programme to get the latest features first:<br> -https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/it-IT/listing/fulldescription b/app/src/main/play/it-IT/listing/fulldescription index a88d693e0..3d0425660 100644 --- a/app/src/main/play/it-IT/listing/fulldescription +++ b/app/src/main/play/it-IT/listing/fulldescription @@ -1,40 +1,43 @@ -AntennaPod è un riproduttore e gestore di podcast che ti da accesso immediato a milioni di podcast gratuiti e a pagamento, dai podcaster indipendenti alle più grandi case editrici come BBC, NPR e CNN. Aggiungi, importa e esporta in modo semplici usando il database di podcast di iTunes, da file OPML o da semplici URL RSS. Risparmia fatica, batteria e dati con il potente controllo automatizzato per il download di episodi (orari specifici, intervalli e reti WiFi) e l'eliminazione degli episodi.<br> -But most importantly: Download, stream or queue episodes and enjoy them the way you like with adjustable playback speeds, chapter support and a sleep timer. You can even show your love to the content creators with our Flattr integration. +AntennaPod è un gestore e player di podcast che ti dà accesso istantaneo a milioni di podcast gratuiti e a pagamento, da podcaster indipendenti a grandi case editrici come BBC, NPR e CNN. Aggiungi, Importa ed esporta facilmente i Feed dal database di iTunes, file OPML oppure semplici collegamenti RSS. Risparmia fatica, batteria e dati con potenti controlli automatici per scaricare gli episodi (specifica orari, intervalli e reti WiFi) ed eliminare gli episodi.<br> +Ma soprattutto: Scarica, fai Stream o metti in coda gli episodi e goditeli come preferisci cambiando la velocità di riproduzione, saltando tra capitoli e impostando lo sleep timer. Puoi persino mostrare il tuo amore attraverso l'integrazione con Flattr. -Made by podcast-enthousiast, AntennaPod is free in all senses of the word: open source, no costs, no ads. +Creato da amatori del podcast, AntennaPod è <i>free</i> in tutti i sensi: open-source, nessun costo, nessuna pubblicità . -<b>Funzioni:</b><br> +<b>Tutte le funzioni:</b><br> IMPORTA, ORGANIZZA E RIPRODUCI<br> -• Aggiungi e importa feed via iTunes, gPodder.net, file OPML e link RSS o Atom<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Accedi a feed e episodi protetti da password<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -TIENI TRACCIA, CONDIVIDI & APPREZZA<br> -• Tieni traccia del meglio del meglio segnando i tuoi episodi preferiti<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring +• Aggiungi ed importa i feed tramite i database di iTunes e gPodder.net, file OPML e link RSS o Atom<br> +• Gestisci la riproduzione in ogni modo: attraverso il widget per la home, le notifiche di sistema oppure tramite i controlli sulle cuffie, sia cablate che bluetooth<br> +• Goditi l'ascolto a modo tuo attraverso la velocità di riproduzione regolabile, il supporto ai capitoli (MP3, VorbisComment e Podlove), la memoria della posizione di riproduzione e un timer di riproduzione avanzato (scuoti per reimpostare, abbassamento del volume e rallentamento di riproduzione)<br> +• Accedi a feed ed episodi protetti da password<br> +• Approfitta dei <i>paged feeds</i> (www.podlove.org/paged-feeds) + +TIENI TRACCIA, CONDIVIDI E APPREZZA<br> +• Tieni traccia degli episodi migliori aggiungendoli ai preferiti<br> +• Trova episodi specifici nella cronologia di riproduzione o cercando tra titoli e descrizioni<br> +• Condividi episodi e feed attraverso le opzioni avanzate di condivisione verso social e emali, i servizi online di gPodder.net e l'esportazione in file OPML<br> +• Supporta i creatori attraverso Flattr consentendo anche il <i>flattring</i> automatico CONTROLLA IL SISTEMA<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• Back-up your subscriptions with the gPodder.net integration and OPML export +• Prendi il controllo dei download automatici: scegli i Feed, escludi le reti cellulari, seleziona reti WiFi specifiche, attiva solo a telefono in carica e imposta orari e intervalli.<br> +• Gestisci la memoria impostando il numero massimo di episodi scaricati, l'eliminazione automatica (basata sui tuoi preferiti e lo stato di riproduzione) e selezionando la tua posizione preferita in memoria<br> +• Utilizza AntennaPod nella tua lingua (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> +• Adatta all'ambiente usando il tema chiaro e quello scuro<br> +• Fai il backup delle tue iscrizione con gPodder.net e l'esportazione OPML -<b>Entra nella community di AntennaPod!</b><br> -AntennaPod è sviluppato da volontari. Anche tu puoi contribuire, con il codice o con dei commenti! +<b>Unisciti alla comunità di AntennaPod!</b><br> +AntennaPod è in fase attiva di sviluppo da parte di volontari. Anche te puoi contribuire, con codice o commenti! -GitHub è il posto nel quale fare richieste, segnalare bug e contribuire allo sviluppo:<br> -www.github.com/AntennaPod/AntennaPod +Per chiedere nuove funzioni, contribuire con del codice o segnalare problemi, puoi trovarci su GitHub: +https://www.github.com/AntennaPod/AntennaPod -Il nostro Gruppo Google è il posto dove condividere le tue idee, podcast preferiti e gratitudine a tutti i nostri volontari:<br> +Il nostro Gruppo Google è il posto giusto per condividere le tue idee, i tuoi più bei momenti di podcasting e per mostrare gratitudine ai volontari<br> https://groups.google.com/forum/#!forum/antennapod -Transifex è il posto dove puoi aiutare a tradurre AntennaPod:<br> -www.transifex.com/antennapod/antennapod +Hai una domanda o vuoi fornirci un feedback? +https://twitter.com/@AntennaPod -Check out our Beta Testing programme to get the latest features first:<br> -www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file +Transifex è il posto in cui aiutare con le traduzioni:<br> +https://www.transifex.com/antennapod/antennapod + +Dai un'occhiata al nostro programma di beta testing per ricevere per primo le funzioni più recenti:<br> +https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/it-IT/listing/title b/app/src/main/play/it-IT/listing/title index 31552f353..6c7c64cfc 100644 --- a/app/src/main/play/it-IT/listing/title +++ b/app/src/main/play/it-IT/listing/title @@ -1 +1 @@ -AntennaPod
\ No newline at end of file +AntennaPod diff --git a/app/src/main/play/it/listing/fulldescription b/app/src/main/play/it/listing/fulldescription deleted file mode 100644 index 3d0425660..000000000 --- a/app/src/main/play/it/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -AntennaPod è un gestore e player di podcast che ti dà accesso istantaneo a milioni di podcast gratuiti e a pagamento, da podcaster indipendenti a grandi case editrici come BBC, NPR e CNN. Aggiungi, Importa ed esporta facilmente i Feed dal database di iTunes, file OPML oppure semplici collegamenti RSS. Risparmia fatica, batteria e dati con potenti controlli automatici per scaricare gli episodi (specifica orari, intervalli e reti WiFi) ed eliminare gli episodi.<br> -Ma soprattutto: Scarica, fai Stream o metti in coda gli episodi e goditeli come preferisci cambiando la velocità di riproduzione, saltando tra capitoli e impostando lo sleep timer. Puoi persino mostrare il tuo amore attraverso l'integrazione con Flattr. - -Creato da amatori del podcast, AntennaPod è <i>free</i> in tutti i sensi: open-source, nessun costo, nessuna pubblicità . - -<b>Tutte le funzioni:</b><br> -IMPORTA, ORGANIZZA E RIPRODUCI<br> -• Aggiungi ed importa i feed tramite i database di iTunes e gPodder.net, file OPML e link RSS o Atom<br> -• Gestisci la riproduzione in ogni modo: attraverso il widget per la home, le notifiche di sistema oppure tramite i controlli sulle cuffie, sia cablate che bluetooth<br> -• Goditi l'ascolto a modo tuo attraverso la velocità di riproduzione regolabile, il supporto ai capitoli (MP3, VorbisComment e Podlove), la memoria della posizione di riproduzione e un timer di riproduzione avanzato (scuoti per reimpostare, abbassamento del volume e rallentamento di riproduzione)<br> -• Accedi a feed ed episodi protetti da password<br> -• Approfitta dei <i>paged feeds</i> (www.podlove.org/paged-feeds) - -TIENI TRACCIA, CONDIVIDI E APPREZZA<br> -• Tieni traccia degli episodi migliori aggiungendoli ai preferiti<br> -• Trova episodi specifici nella cronologia di riproduzione o cercando tra titoli e descrizioni<br> -• Condividi episodi e feed attraverso le opzioni avanzate di condivisione verso social e emali, i servizi online di gPodder.net e l'esportazione in file OPML<br> -• Supporta i creatori attraverso Flattr consentendo anche il <i>flattring</i> automatico - -CONTROLLA IL SISTEMA<br> -• Prendi il controllo dei download automatici: scegli i Feed, escludi le reti cellulari, seleziona reti WiFi specifiche, attiva solo a telefono in carica e imposta orari e intervalli.<br> -• Gestisci la memoria impostando il numero massimo di episodi scaricati, l'eliminazione automatica (basata sui tuoi preferiti e lo stato di riproduzione) e selezionando la tua posizione preferita in memoria<br> -• Utilizza AntennaPod nella tua lingua (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adatta all'ambiente usando il tema chiaro e quello scuro<br> -• Fai il backup delle tue iscrizione con gPodder.net e l'esportazione OPML - -<b>Unisciti alla comunità di AntennaPod!</b><br> -AntennaPod è in fase attiva di sviluppo da parte di volontari. Anche te puoi contribuire, con codice o commenti! - -Per chiedere nuove funzioni, contribuire con del codice o segnalare problemi, puoi trovarci su GitHub: -https://www.github.com/AntennaPod/AntennaPod - -Il nostro Gruppo Google è il posto giusto per condividere le tue idee, i tuoi più bei momenti di podcasting e per mostrare gratitudine ai volontari<br> -https://groups.google.com/forum/#!forum/antennapod - -Hai una domanda o vuoi fornirci un feedback? -https://twitter.com/@AntennaPod - -Transifex è il posto in cui aiutare con le traduzioni:<br> -https://www.transifex.com/antennapod/antennapod - -Dai un'occhiata al nostro programma di beta testing per ricevere per primo le funzioni più recenti:<br> -https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/it_IT/listing/fulldescription b/app/src/main/play/it_IT/listing/fulldescription deleted file mode 100644 index eb2abb40d..000000000 --- a/app/src/main/play/it_IT/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -AntennaPod è un riproduttore e gestore di podcast che ti da accesso immediato a milioni di podcast gratuiti e a pagamento, dai podcaster indipendenti alle più grandi emittenti come BBC, NPR e CNN. Aggiungi, importa e esporta in modo semplici usando il database di podcast di iTunes, da file OPML o da semplici URL RSS. Risparmia fatica, batteria e dati con il potente controllo automatizzato per il download di episodi (orari specifici, intervalli e reti WiFi) e l'eliminazione degli episodi.<br> -But most importantly: Download, stream or queue episodes and enjoy them the way you like with adjustable playback speeds, chapter support and a sleep timer. You can even show your love to the content creators with our Flattr integration. - -Creato da amanti dei podcast, AntennaPod è libero in tutti i sensi: open source, gratis, senza pubblicità . - -<b>Funzioni:</b><br> -IMPORTA, ORGANIZZA E RIPRODUCI<br> -• Aggiungi e importa feed via iTunes, gPodder.net, file OPML e link RSS o Atom<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Accedi a feed e episodi protetti da password<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -TIENI TRACCIA, CONDIVIDI & APPREZZA<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Supporta i creatori di contenuti tramite l'integrazione con Flattr e il flattring automatico - -CONTROLLA IL SISTEMA<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Usa AntennaPod nella tua lingua (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• Back-up your subscriptions with the gPodder.net integration and OPML export - -<b>Entra nella community di AntennaPod!</b><br> -AntennaPod è sviluppato da volontari. Anche tu puoi contribuire, con il codice o con dei commenti! - -GitHub è il posto nel quale fare richieste, segnalare bug e contribuire allo sviluppo:<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 - -Hai una domanda o vuoi darci un feedback? -https://twitter.com/@AntennaPod - -Transifex è il posto dove puoi contribuire alla traduzione di AntennaPod:<br> -https://www.transifex.com/antennapod/antennapod - -Dai un'occhiata al nostro programma di Beta Testing per avere accesso in anticipo alle nuove features:<br> -https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/iw-IL/listing/shortdescription b/app/src/main/play/iw-IL/listing/shortdescription index ad3ccb1f8..7afb5a62d 100644 --- a/app/src/main/play/iw-IL/listing/shortdescription +++ b/app/src/main/play/iw-IL/listing/shortdescription @@ -1 +1 @@ -An open-source podcast manager for Android
\ No newline at end of file +Easy-to-use, flexible and open-source podcast & radio manager and player
\ No newline at end of file diff --git a/app/src/main/play/iw-IL/listing/title b/app/src/main/play/iw-IL/listing/title index 31552f353..6c7c64cfc 100644 --- a/app/src/main/play/iw-IL/listing/title +++ b/app/src/main/play/iw-IL/listing/title @@ -1 +1 @@ -AntennaPod
\ No newline at end of file +AntennaPod diff --git a/app/src/main/play/ja-JP/listing/fulldescription b/app/src/main/play/ja-JP/listing/fulldescription index 38f6deffb..b85f6787e 100644 --- a/app/src/main/play/ja-JP/listing/fulldescription +++ b/app/src/main/play/ja-JP/listing/fulldescription @@ -7,13 +7,12 @@ AntennaPodã¯ã€ç‹¬è‡ªã®ãƒãƒƒãƒ‰ã‚ャスターã‹ã‚‰ã€BBCã€NPRã€CNNãªã©ã インãƒãƒ¼ãƒˆã€æ•´ç†ã€å†ç”Ÿ<br> • iTunesã‚„ã€gPodder.netディレクトリã€OPMLファイルã€RSSã¾ãŸã¯Atom経由ã§ãƒ•ã‚£ãƒ¼ãƒ‰ã‚’è¿½åŠ ãŠã‚ˆã³ã‚¤ãƒ³ãƒãƒ¼ãƒˆã—ã¾ã™<br> • 様々ãªå ´æ‰€ã§å†ç”Ÿã‚’管ç†ã—ã¾ã™: ホーム画é¢ã‚¦ã‚£ã‚¸ã‚§ãƒƒãƒˆã€ã‚·ã‚¹ãƒ†ãƒ 通知ã€ã‚¤ãƒ¤ãƒ›ãƒ³ã€Bluetoothコントãƒãƒ¼ãƒ«<br> -• å†ç”Ÿé€Ÿåº¦ã®èª¿æ•´ã€ãƒãƒ£ãƒ—ターã®ã‚µãƒãƒ¼ãƒˆ (MP3ã€VorbisCommentã¨Podlove)ã€å†ç”Ÿä½ç½®ã®ä¿å˜ã€é«˜åº¦ãªã‚¹ãƒªãƒ¼ãƒ—タイマー (シェイクã—ã¦ãƒªã‚»ãƒƒãƒˆã€éŸ³é‡ã‚’å°ã•ãã€å†ç”Ÿé€Ÿåº¦ã‚’é…ã) ã§ã€ãŠå¥½ã¿ã® -èžãæ–¹ã§ãŠæ¥½ã—ã¿ãã ã•ã„<br> +• å†ç”Ÿé€Ÿåº¦ã®èª¿æ•´ã€ãƒãƒ£ãƒ—ターã®ã‚µãƒãƒ¼ãƒˆ (MP3ã€VorbisCommentã¨Podlove)ã€å†ç”Ÿä½ç½®ã®ä¿å˜ã€é«˜åº¦ãªã‚¹ãƒªãƒ¼ãƒ—タイマー (シェイクã—ã¦ãƒªã‚»ãƒƒãƒˆã€éŸ³é‡ã‚’å°ã•ãã€å†ç”Ÿé€Ÿåº¦ã‚’é…ã) ã§ã€ãŠå¥½ã¿ã®èžãæ–¹ã§ãŠæ¥½ã—ã¿ãã ã•ã„<br> • アクセスパスワードã§ä¿è·ã•ã‚ŒãŸãƒ•ã‚£ãƒ¼ãƒ‰ã¨ã‚¨ãƒ”ソード<br> • ページフィードをã”利用ãã ã•ã„ (www.podlove.org/paged-feeds) 記録ã€å…±æœ‰ & æ„Ÿè¬<br> -• エピソードをãŠæ°—ã«å…¥ã‚Šã¨ã—ã¦ãƒžãƒ¼ã‚¯ã—ã¦ã€ä¸€ç•ªã®ä¸ã®ä¸€ç•ªã‚’記録ã—ã¦ãã ã•ã„<br> +• エピソードをãŠæ°—ã«å…¥ã‚Šã¨ã—ã¦ãƒžãƒ¼ã‚¯ã—ã¦ã€ä¸€ç•ªã®ä¸ã®ä¸€ç•ªã‚’ä¿å˜ã—ã¦ãã ã•ã„<br> • å†ç”Ÿå±¥æ´ã‹ã‚‰ã€ã¾ãŸã¯æ¤œç´¢ (タイトルã¨ã‚·ãƒ§ãƒ¼ãƒŽãƒ¼ãƒˆ) ã—ã¦ç›®çš„ã®ã‚¨ãƒ”ソードを見ã¤ã‘ã¦ãã ã•ã„<br> • 高度ãªã‚½ãƒ¼ã‚·ãƒ£ãƒ«ãƒ¡ãƒ‡ã‚£ã‚¢ã¨ãƒ¡ãƒ¼ãƒ«ã‚ªãƒ—ションã€gPodder.netサービスã€OPMLエクスãƒãƒ¼ãƒˆã‹ã‚‰ã‚¨ãƒ”ソードやフィードを共有ã—ã¦ãã ã•ã„<br> • 自動Flattrã‚’å«ã‚€Flattrã®çµ±åˆã§ã‚³ãƒ³ãƒ†ãƒ³ãƒ„クリエイターをサãƒãƒ¼ãƒˆã—ã¾ã™ @@ -29,13 +28,16 @@ AntennaPodã¯ã€ç‹¬è‡ªã®ãƒãƒƒãƒ‰ã‚ャスターã‹ã‚‰ã€BBCã€NPRã€CNNãªã©ã AntennaPod ã¯ãƒœãƒ©ãƒ³ãƒ†ã‚£ã‚¢ã«ã‚ˆã£ã¦æ´»ç™ºã«é–‹ç™ºä¸ã§ã™ã€‚コードやコメントã§ã€ã‚ãªãŸã‚‚も貢献ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™! GitHubã¯ã€æ©Ÿèƒ½ã®ãƒªã‚¯ã‚¨ã‚¹ãƒˆã€ãƒã‚°ã®å ±å‘Šã€ã‚³ãƒ¼ãƒ‰ã®è²¢çŒ®ã®ãŸã‚ã®å ´æ‰€ã§ã™:<br> -www.github.com/AntennaPod/AntennaPod +https://www.github.com/AntennaPod/AntennaPod -ç§ãŸã¡ã®Googleグループã¯ã€ã‚ãªãŸã®ã‚¢ã‚¤ãƒ‡ã‚¢ã€ãŠæ°—ã«å…¥ã‚Šã®ãƒãƒƒãƒ‰ã‚ャスティングモーメントã€æ„Ÿè¬ã‚’ã€ã™ã¹ã¦ã®ãƒœãƒ©ãƒ³ãƒ†ã‚£ã‚¢ã¨å…±æœ‰ã™ã‚‹ãŸã‚ã®å ´æ‰€ã§:<br> +ç§ãŸã¡ã®Googleグループã¯ã€ã‚ãªãŸã®ã‚¢ã‚¤ãƒ‡ã‚¢ã€ãŠæ°—ã«å…¥ã‚Šã®ãƒãƒƒãƒ‰ã‚ャスティングモーメントã€æ„Ÿè¬ã‚’ã€ã™ã¹ã¦ã®ãƒœãƒ©ãƒ³ãƒ†ã‚£ã‚¢ã¨å…±æœ‰ã™ã‚‹ãŸã‚ã®å ´æ‰€ã§ã™:<br> https://groups.google.com/forum/#!forum/antennapod +質å•ã‚„ã€ç§ãŸã¡ã¸ã®ãƒ•ã‚£ãƒ¼ãƒ‰ãƒãƒƒã‚¯ãŒã‚ã‚Šã¾ã›ã‚“ã‹? +https://twitter.com/@AntennaPod + Transifexã¯ç¿»è¨³ã‚’支æ´ã™ã‚‹ãŸã‚ã®å ´æ‰€ã§ã™:<br> -www.transifex.com/antennapod/antennapod +https://www.transifex.com/antennapod/antennapod ç§ãŸã¡ã®ãƒ™ãƒ¼ã‚¿ãƒ†ã‚¹ãƒˆãƒ—ãƒã‚°ãƒ©ãƒ ã‚’ãƒã‚§ãƒƒã‚¯ã—ã¦ã€æœ€æ–°æ©Ÿèƒ½ã‚’最åˆã«å…¥æ‰‹ã—ã¦ãã ã•ã„:<br> -www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file +https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/ja-JP/listing/title b/app/src/main/play/ja-JP/listing/title index 31552f353..6c7c64cfc 100644 --- a/app/src/main/play/ja-JP/listing/title +++ b/app/src/main/play/ja-JP/listing/title @@ -1 +1 @@ -AntennaPod
\ No newline at end of file +AntennaPod diff --git a/app/src/main/play/ja/listing/fulldescription b/app/src/main/play/ja/listing/fulldescription deleted file mode 100644 index b85f6787e..000000000 --- a/app/src/main/play/ja/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -AntennaPodã¯ã€ç‹¬è‡ªã®ãƒãƒƒãƒ‰ã‚ャスターã‹ã‚‰ã€BBCã€NPRã€CNNãªã©ã®å¤§è¦æ¨¡ãªæ”¾é€ã¾ã§ã€æ•°ç™¾ä¸‡ã®ç„¡æ–™ã‚„有料ãƒãƒƒãƒ‰ã‚ャストã«çž¬æ™‚ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã“ã¨ãŒã§ãã‚‹ã€ãƒãƒƒãƒ‰ã‚ャストマãƒãƒ¼ã‚¸ãƒ£ãƒ¼ãŠã‚ˆã³ãƒ—レーヤーã§ã™ã€‚フィードã¯æ‰‹é–“ã®ã‹ã‹ã‚‰ãªã„iTunesã®Podcastã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã€OPMLファイルや簡å˜ãªRSSã®URLを使用ã—ã¦è¿½åŠ ã€ã‚¤ãƒ³ãƒãƒ¼ãƒˆã€ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã—ã¾ã™ã€‚エピソードã®ãƒ€ã‚¦ãƒ³ãƒãƒ¼ãƒ‰ (時間ã€é–“éš”ãŠã‚ˆã³WiFiãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚’指定) ã¨ã‚¨ãƒ”ソードã®å‰Šé™¤ (ãŠæ°—ã«å…¥ã‚Šã¨é…延è¨å®šã«åŸºã¥ã„ã¦) ã‚’ã™ã‚‹ãŸã‚ã«å¼·åŠ›ãªè‡ªå‹•ã‚³ãƒ³ãƒˆãƒãƒ¼ãƒ«ã§ã€æ‰‹é–“ã€ãƒãƒƒãƒ†ãƒªæ¶ˆè²»ã€ãƒ¢ãƒã‚¤ãƒ«ãƒ‡ãƒ¼ã‚¿ä½¿ç”¨é‡ã‚’節約ã—ã¾ã™ã€‚<br> -ã—ã‹ã—最もé‡è¦ãªã“ã¨: エピソードをダウンãƒãƒ¼ãƒ‰ã€ã‚¹ãƒˆãƒªãƒ¼ãƒ å†ç”Ÿã€ã¾ãŸã¯ã‚ューã«å…¥ã‚Œã¦ã€ãã—ã¦å†ç”Ÿé€Ÿåº¦ã®èª¿æ•´ã€ãƒãƒ£ãƒ—ターã®ã‚µãƒãƒ¼ãƒˆã€ã‚¹ãƒªãƒ¼ãƒ—タイマーã§å¥½ããªã‚ˆã†ã«æ¥½ã—ã‚“ã§ãã ã•ã„。Flattrçµ±åˆã§ã‚³ãƒ³ãƒ†ãƒ³ãƒ„作æˆè€…ã«ã‚ãªãŸã®æ„›ã‚’示ã™ã“ã¨ãŒã§ãã¾ã™ã€‚ - -ãƒãƒƒãƒ‰ã‚ャスト愛好家ãŒä½œæˆã—㟠AntennaPod ã¯ã™ã¹ã¦ã®æ„味ã§ãƒ•ãƒªãƒ¼è‡ªç”±ã§ã™: オープンソースã€ã‚³ã‚¹ãƒˆä¸è¦ã€åºƒå‘Šã¯ã‚ã‚Šã¾ã›ã‚“。 - -<b>ã™ã¹ã¦ã®æ©Ÿèƒ½:</b><br> -インãƒãƒ¼ãƒˆã€æ•´ç†ã€å†ç”Ÿ<br> -• iTunesã‚„ã€gPodder.netディレクトリã€OPMLファイルã€RSSã¾ãŸã¯Atom経由ã§ãƒ•ã‚£ãƒ¼ãƒ‰ã‚’è¿½åŠ ãŠã‚ˆã³ã‚¤ãƒ³ãƒãƒ¼ãƒˆã—ã¾ã™<br> -• 様々ãªå ´æ‰€ã§å†ç”Ÿã‚’管ç†ã—ã¾ã™: ホーム画é¢ã‚¦ã‚£ã‚¸ã‚§ãƒƒãƒˆã€ã‚·ã‚¹ãƒ†ãƒ 通知ã€ã‚¤ãƒ¤ãƒ›ãƒ³ã€Bluetoothコントãƒãƒ¼ãƒ«<br> -• å†ç”Ÿé€Ÿåº¦ã®èª¿æ•´ã€ãƒãƒ£ãƒ—ターã®ã‚µãƒãƒ¼ãƒˆ (MP3ã€VorbisCommentã¨Podlove)ã€å†ç”Ÿä½ç½®ã®ä¿å˜ã€é«˜åº¦ãªã‚¹ãƒªãƒ¼ãƒ—タイマー (シェイクã—ã¦ãƒªã‚»ãƒƒãƒˆã€éŸ³é‡ã‚’å°ã•ãã€å†ç”Ÿé€Ÿåº¦ã‚’é…ã) ã§ã€ãŠå¥½ã¿ã®èžãæ–¹ã§ãŠæ¥½ã—ã¿ãã ã•ã„<br> -• アクセスパスワードã§ä¿è·ã•ã‚ŒãŸãƒ•ã‚£ãƒ¼ãƒ‰ã¨ã‚¨ãƒ”ソード<br> -• ページフィードをã”利用ãã ã•ã„ (www.podlove.org/paged-feeds) - -記録ã€å…±æœ‰ & æ„Ÿè¬<br> -• エピソードをãŠæ°—ã«å…¥ã‚Šã¨ã—ã¦ãƒžãƒ¼ã‚¯ã—ã¦ã€ä¸€ç•ªã®ä¸ã®ä¸€ç•ªã‚’ä¿å˜ã—ã¦ãã ã•ã„<br> -• å†ç”Ÿå±¥æ´ã‹ã‚‰ã€ã¾ãŸã¯æ¤œç´¢ (タイトルã¨ã‚·ãƒ§ãƒ¼ãƒŽãƒ¼ãƒˆ) ã—ã¦ç›®çš„ã®ã‚¨ãƒ”ソードを見ã¤ã‘ã¦ãã ã•ã„<br> -• 高度ãªã‚½ãƒ¼ã‚·ãƒ£ãƒ«ãƒ¡ãƒ‡ã‚£ã‚¢ã¨ãƒ¡ãƒ¼ãƒ«ã‚ªãƒ—ションã€gPodder.netサービスã€OPMLエクスãƒãƒ¼ãƒˆã‹ã‚‰ã‚¨ãƒ”ソードやフィードを共有ã—ã¦ãã ã•ã„<br> -• 自動Flattrã‚’å«ã‚€Flattrã®çµ±åˆã§ã‚³ãƒ³ãƒ†ãƒ³ãƒ„クリエイターをサãƒãƒ¼ãƒˆã—ã¾ã™ - -システムã®ã‚³ãƒ³ãƒˆãƒãƒ¼ãƒ« -• 自動ダウンãƒãƒ¼ãƒ‰ã®åˆ¶å¾¡: フィードをé¸æŠžã€ãƒ¢ãƒã‚¤ãƒ«ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚’除外ã€ç‰¹å®šã®WiFiãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚’é¸æŠžã€é›»è©±ã‚’å……é›»ã™ã‚‹å¿…è¦ã€æ™‚間や間隔をè¨å®š<br> -• ã‚ャッシュã•ã‚Œã‚‹ã‚¨ãƒ”ソードã®é‡ã®è¨å®šã€ã‚¹ãƒžãƒ¼ãƒˆå‰Šé™¤ (ãŠæ°—ã«å…¥ã‚Šã‚„プレイ状æ³ã«åŸºã¥ã„ã¦) ã¨ã€ãŠå¥½ã¿ã®å ´æ‰€ã‚’é¸æŠžã—ã¦ã€ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚’管ç†ã—ã¾ã™<br> -• AntennaPod ã‚’ã‚ãªãŸã®è¨€èªžã§ã”利用ãã ã•ã„ (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• ライトã¨ãƒ€ãƒ¼ã‚¯ テーマを使用ã—ã¦ç’°å¢ƒã«é©å¿œã—ã¾ã™<br> -• gPodder.netçµ±åˆã¨OPMLã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã§ã€è³¼èªã‚’ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã—ã¾ã™ - -<b>AntennaPod ã®ã‚³ãƒŸãƒ¥ãƒ‹ãƒ†ã‚£ã«å‚åŠ ã—ã¦ãã ã•ã„!</b><br> -AntennaPod ã¯ãƒœãƒ©ãƒ³ãƒ†ã‚£ã‚¢ã«ã‚ˆã£ã¦æ´»ç™ºã«é–‹ç™ºä¸ã§ã™ã€‚コードやコメントã§ã€ã‚ãªãŸã‚‚も貢献ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™! - -GitHubã¯ã€æ©Ÿèƒ½ã®ãƒªã‚¯ã‚¨ã‚¹ãƒˆã€ãƒã‚°ã®å ±å‘Šã€ã‚³ãƒ¼ãƒ‰ã®è²¢çŒ®ã®ãŸã‚ã®å ´æ‰€ã§ã™:<br> -https://www.github.com/AntennaPod/AntennaPod - -ç§ãŸã¡ã®Googleグループã¯ã€ã‚ãªãŸã®ã‚¢ã‚¤ãƒ‡ã‚¢ã€ãŠæ°—ã«å…¥ã‚Šã®ãƒãƒƒãƒ‰ã‚ャスティングモーメントã€æ„Ÿè¬ã‚’ã€ã™ã¹ã¦ã®ãƒœãƒ©ãƒ³ãƒ†ã‚£ã‚¢ã¨å…±æœ‰ã™ã‚‹ãŸã‚ã®å ´æ‰€ã§ã™:<br> -https://groups.google.com/forum/#!forum/antennapod - -質å•ã‚„ã€ç§ãŸã¡ã¸ã®ãƒ•ã‚£ãƒ¼ãƒ‰ãƒãƒƒã‚¯ãŒã‚ã‚Šã¾ã›ã‚“ã‹? -https://twitter.com/@AntennaPod - -Transifexã¯ç¿»è¨³ã‚’支æ´ã™ã‚‹ãŸã‚ã®å ´æ‰€ã§ã™:<br> -https://www.transifex.com/antennapod/antennapod - -ç§ãŸã¡ã®ãƒ™ãƒ¼ã‚¿ãƒ†ã‚¹ãƒˆãƒ—ãƒã‚°ãƒ©ãƒ ã‚’ãƒã‚§ãƒƒã‚¯ã—ã¦ã€æœ€æ–°æ©Ÿèƒ½ã‚’最åˆã«å…¥æ‰‹ã—ã¦ãã ã•ã„:<br> -https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/kn_IN/listing/fulldescription b/app/src/main/play/kn_IN/listing/fulldescription deleted file mode 100644 index 87b477fdc..000000000 --- a/app/src/main/play/kn_IN/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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> -• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -CONTROL THE SYSTEM<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• 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/ko-KR/listing/fulldescription b/app/src/main/play/ko-KR/listing/fulldescription index 7f04d4e7b..65f20d943 100644 --- a/app/src/main/play/ko-KR/listing/fulldescription +++ b/app/src/main/play/ko-KR/listing/fulldescription @@ -1,20 +1,43 @@ -ì•ˆí…Œë‚˜íŒŸì€ ì˜¤í”ˆì†ŒìŠ¤ 팟ìºìŠ¤íŠ¸ 관리 프로그램입니다. 안드로ì´ë“œ 2.2.3 ì´ìƒì—ì„œ ë™ìž‘합니다. ì—í”¼ì†Œë“œì˜ ìŠ¤íŠ¸ë¦¬ë° ë° ë‹¤ìš´ë¡œë“œ, ìžë™ìœ¼ë¡œ 피드를 새로 확ì¸í•˜ê³ ë‚˜ì¤‘ì— ë“¤ì„ ìˆ˜ 있게 ëŒ€ê¸°ì—´ì— ì¶”ê°€í•˜ëŠ” 등 팟ìºìŠ¤íŠ¸ 프로그램ì—ì„œ ìƒê°í• 수 있는 ëª¨ë“ ê¸°ë³¸ ê¸°ëŠ¥ì„ ì§€ì›í•©ë‹ˆë‹¤. ë˜ ì•ˆí…Œë‚˜íŒŸ 앱 안ì—ì„œ 팟ìºìŠ¤íŠ¸ì— 대해 Flattr 기부 ê¸°ëŠ¥ì„ ì‚¬ìš©í• ìˆ˜ 있습니다. - -지금까지 ë‹¤ìŒ ê¸°ëŠ¥ì´ êµ¬í˜„ë˜ì—ˆìŠµë‹ˆë‹¤: - -* ì—피소드 다운로드 ë° ìŠ¤íŠ¸ë¦¬ë° -* 여러가지 ë°°ì† ìž¬ìƒ(Presto 사운드 ë¼ì´ë¸ŒëŸ¬ë¦¬ ë˜ëŠ” Prestissimo í•„ìš”) -* Atom ë° RSS 피드 ì§€ì› -* 암호로 ë³´í˜¸ëœ í”¼ë“œì™€ ì—피소드 ì§€ì› -* iTunes ëª©ë¡ ê²€ìƒ‰ 기능 -* OPML ê°€ì ¸ì˜¤ê¸° ë° ë‚´ë³´ë‚´ê¸° -* Flattr 통합, ìžë™ìœ¼ë¡œ Flattr하기 기능 í¬í•¨ -* 홈스í¬ë¦° ìž¬ìƒ ìœ„ì ¯ -* 검색 -* ìžë™ 피드 ì—…ë°ì´íŠ¸ -* 새 ì—피소드 ìžë™ 다운로드 -* 취침 타ì´ë¨¸ -* gpodder.net 팟ìºìŠ¤íŠ¸ ë””ë ‰í„°ë¦¬ 찾아보기 -* gpodder.net 서비스와 êµ¬ë… ì •ë³´ ë™ê¸°í™” -* MP3 챕터, VorbisComment 챕터, Podlove Simple Chapters 기능 -* 페ì´ì§€ 피드 (http://podlove.org/paged-feeds/) 지ì›
\ No newline at end of file +ì•ˆí…Œë‚˜íŒŸì„ ì‚¬ìš©í•´ 소규모 ë…립 ì œìž‘ìžë“¤ë¶€í„° BBC, NPR, CNN ë“±ì˜ ëŒ€í˜• ì–¸ë¡ ì‚¬ê¹Œì§€ ìˆ˜ë§Žì€ ë¬´ë£Œ ë° ìœ ë£Œ 팟ìºìŠ¤íŠ¸ì— ì ‘ê·¼í• ìˆ˜ 있습니다. iTunes 팟ìºìŠ¤íŠ¸ ë°ì´í„°ë² ì´ìŠ¤, OPML 파ì¼, RSS 주소를 사용해 팟ìºìŠ¤íŠ¸ 피드를 간편하게 ì¶”ê°€í•˜ê³ ë‚´ë³´ë‚´ê³ ê°€ì ¸ì˜¬ 수 있습니다. ê°•ë ¥í•œ ìžë™ 다운로드 ì œì–´(íŠ¹ì • 시간 간격 ë° Wi-Fi ë„¤íŠ¸ì›Œí¬ ì§€ì •)와 ì‚ì œ ì œì–´(ì¦ê²¨ì°¾ê¸° ë° ì§€ì—° ì„¤ì •ì— ê¸°ë°˜í•œ)를 통해 편리하게 배터리와 ëª¨ë°”ì¼ ë°ì´í„° ì‚¬ìš©ëŸ‰ì„ ì¤„ì´ì„¸ìš”.<br> +하지만 가장 중요한 기능ì€: ì—피소드를 다운로드하거나 스트리ë°í•˜ê±°ë‚˜ ëŒ€ê¸°ì—´ì„ ë§Œë“¤ê³ , ìž¬ìƒ ì†ë„ ì¡°ì ˆ, 챕터 지ì›, 취침 타ì´ë¨¸ë¥¼ 통해 ì›í•˜ëŠ”대로 ì¦ê¸¸ 수 있다는 ì 입니다. ë‚´ìž¥ëœ Flattr 지ì›ì„ 통해 팟ìºìŠ¤íŠ¸ ì œìž‘ìžë“¤ì—게 호ì‘ì„ ë³´ë‚¼ ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. + +팟ìºìŠ¤íŠ¸ ì• í˜¸ê°€ì— ì˜í•´ 만들어진, ì•ˆí…Œë‚˜íŒŸì€ ëª¨ë“ ë©´ì—ì„œ ìžìœ ë¡ìŠµë‹ˆë‹¤: 소스 코드가 공개ë˜ì–´ ìžˆê³ , 무료ì¸ë°ë‹¤ê°€ ê´‘ê³ ë„ ì—†ìŠµë‹ˆë‹¤. + +<b>ëª¨ë“ ê¸°ëŠ¥:</b><br> +ê°€ì ¸ì˜¤ê¸°, 관리하기, 재ìƒí•˜ê¸°<br> +• iTunes, gPodder.net, OPML 파ì¼, RSS ë° Atom ë§í¬ë¥¼ 통해 피드를 추가하거나 ê°€ì ¸ì˜¬ 수 있습니다.<br> +• 재ìƒì„ ì–´ë””ì—서나 ê´€ë¦¬í• ìˆ˜ 있습니다: 홈스í¬ë¦° ìœ„ì ¯, 시스템 알림, ì´ì–´í° ë° ë¸”ë£¨íˆ¬ìŠ¤ 컨트롤<br> +• ë°°ì† ìž¬ìƒ ì§€ì›, 챕터 지ì›(MP3, VorbisComment, Podlove), 마지막 ìž¬ìƒ ìœ„ì¹˜ 기억, ê³ ê¸‰ 취침 타ì´ë¨¸(í”들어서 초기화, 볼륨 낮추기, ìž¬ìƒ ëŠë¦¬ê²Œ 하기) ë“±ì˜ ê¸°ëŠ¥ìœ¼ë¡œ 팟ìºìŠ¤íŠ¸ë¥¼ ì¦ê¸°ì„¸ìš”<br> +• 암호로 ë³´í˜¸ëœ í”¼ë“œì™€ ì—í”¼ì†Œë“œì— ì ‘ê·¼<br> +• 페ì´ì§€ë¡œ êµ¬ë¶„ëœ í”¼ë“œ 활용 (www.podlove.org/paged-feeds) + +기ë¡í•˜ê³ , ê³µìœ í•˜ê³ , 호ì‘하기<br> +• 가장 좋아하는 팟ìºìŠ¤íŠ¸ ì—피소드를 ì¦ê²¨ì°¾ê¸°ë¡œ ì €ìž¥<br> +• ì—피소드를 ìž¬ìƒ ê¸°ë¡ ë˜ëŠ” 검색(ì œëª© ë° ë…¸íŠ¸)으로 찾기<br> +• ì—피소드와 피드를 SNS, ì´ë©”ì¼, gPodder.net, OPML 내보내기로 ê³µìœ <br> +• ìžë™ìœ¼ë¡œ Flattr하기 ë“±ì˜ Flattr 기능으로 팟ìºìŠ¤íŠ¸ ì œìž‘ìž ì§€ì› + +시스템 컨트롤 +• ìžë™ 다운로드를 ì œì–´í•˜ì„¸ìš”: 피드를 ê³ ë¥´ê³ , ëª¨ë°”ì¼ ë„¤íŠ¸ì›Œí¬ë¥¼ ì œì™¸ì‹œí‚¤ê³ , íŠ¹ì • Wi-Fi 네트워í¬ë¥¼ ì„ íƒí•˜ê³ , 기기가 ì¶©ì „ì¤‘ì¼ë•Œë§Œ 다운로드하게 í•˜ê³ , 시간과 ê°„ê²©ì„ ì •í•˜ì„¸ìš”<br> +• ì—피소드 ìºì‹œ 용량, 똑똑한 ì‚ì œ(ì¦ê²¨ì°¾ê¸°ì™€ ìž¬ìƒ ìƒíƒœì— 기반), ì„ í˜¸í•˜ëŠ” ì €ìž¥ 위치 등으로 ì €ìž¥ì†Œë¥¼ 관리하세요<br> +• 여러가지 언어로 ì•ˆí…Œë‚˜íŒŸì„ ì‚¬ìš©í•˜ì„¸ìš” (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> +• ë°ìŒ ë° ì–´ë‘움 테마로 í™˜ê²½ì— ë§žì¶° 사용하세요<br> +• gPodder.netê³¼ OPML 내보내기 기능으로 구ë…í•œ 팟ìºìŠ¤íŠ¸ë¥¼ 백업하세요 + +<b>안테나팟 ì»¤ë®¤ë‹ˆí‹°ì— ì°¸ì—¬í•˜ì„¸ìš”!</b><br> +ì•ˆí…Œë‚˜íŒŸì€ ì§€ì›ìžë“¤ì— ì˜í•´ 활발히 개발ë˜ê³ 있습니다. ë‹¹ì‹ ë„ ì œìž‘ì„ ë•ê±°ë‚˜ ì œì•ˆì„ í•´ì„œ ì°¸ì—¬í• ìˆ˜ 있습니다! + +GitHubì—ì„œ 새로운 기능 ì œì•ˆ, 버그 ë³´ê³ , ê·¸ë¦¬ê³ ì½”ë“œ 기여를 í• ìˆ˜ 있습니다.:<br> +https://www.github.com/AntennaPod/AntennaPod + +구글 그룹ì—ì„œ ì•„ì´ë””어와 ì¢‹ì€ íŒŸìºìŠ¤íŠ¸ë¥¼ ê³µìœ í•˜ê³ ëª¨ë“ ì§€ì›ìžë“¤ì—게 ê°ì‚¬í• 수 있습니다:<br> +https://groups.google.com/forum/#!forum/antennapod + +ì§ˆë¬¸ì´ ìžˆìœ¼ì‹ ê°€ìš”? 아니면 ì˜ê²¬ì´ ìžˆìœ¼ì‹ ê°€ìš”? +https://twitter.com/@AntennaPod + +Transifexì—ì„œ 번ì—ì„ ë„울 수 있습니다:<br> +https://www.transifex.com/antennapod/antennapod + +ë² íƒ€ 테스트 í”„ë¡œê·¸ëž¨ì„ í†µí•´ ìµœì‹ ê¸°ëŠ¥ì„ ê°€ìž¥ ë¨¼ì € 확ì¸í•´ë³´ì„¸ìš”:<br> +https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/ko-KR/listing/title b/app/src/main/play/ko-KR/listing/title index 31552f353..6c7c64cfc 100644 --- a/app/src/main/play/ko-KR/listing/title +++ b/app/src/main/play/ko-KR/listing/title @@ -1 +1 @@ -AntennaPod
\ No newline at end of file +AntennaPod diff --git a/app/src/main/play/ko/listing/fulldescription b/app/src/main/play/ko/listing/fulldescription deleted file mode 100644 index 65f20d943..000000000 --- a/app/src/main/play/ko/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -ì•ˆí…Œë‚˜íŒŸì„ ì‚¬ìš©í•´ 소규모 ë…립 ì œìž‘ìžë“¤ë¶€í„° BBC, NPR, CNN ë“±ì˜ ëŒ€í˜• ì–¸ë¡ ì‚¬ê¹Œì§€ ìˆ˜ë§Žì€ ë¬´ë£Œ ë° ìœ ë£Œ 팟ìºìŠ¤íŠ¸ì— ì ‘ê·¼í• ìˆ˜ 있습니다. iTunes 팟ìºìŠ¤íŠ¸ ë°ì´í„°ë² ì´ìŠ¤, OPML 파ì¼, RSS 주소를 사용해 팟ìºìŠ¤íŠ¸ 피드를 간편하게 ì¶”ê°€í•˜ê³ ë‚´ë³´ë‚´ê³ ê°€ì ¸ì˜¬ 수 있습니다. ê°•ë ¥í•œ ìžë™ 다운로드 ì œì–´(íŠ¹ì • 시간 간격 ë° Wi-Fi ë„¤íŠ¸ì›Œí¬ ì§€ì •)와 ì‚ì œ ì œì–´(ì¦ê²¨ì°¾ê¸° ë° ì§€ì—° ì„¤ì •ì— ê¸°ë°˜í•œ)를 통해 편리하게 배터리와 ëª¨ë°”ì¼ ë°ì´í„° ì‚¬ìš©ëŸ‰ì„ ì¤„ì´ì„¸ìš”.<br> -하지만 가장 중요한 기능ì€: ì—피소드를 다운로드하거나 스트리ë°í•˜ê±°ë‚˜ ëŒ€ê¸°ì—´ì„ ë§Œë“¤ê³ , ìž¬ìƒ ì†ë„ ì¡°ì ˆ, 챕터 지ì›, 취침 타ì´ë¨¸ë¥¼ 통해 ì›í•˜ëŠ”대로 ì¦ê¸¸ 수 있다는 ì 입니다. ë‚´ìž¥ëœ Flattr 지ì›ì„ 통해 팟ìºìŠ¤íŠ¸ ì œìž‘ìžë“¤ì—게 호ì‘ì„ ë³´ë‚¼ ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. - -팟ìºìŠ¤íŠ¸ ì• í˜¸ê°€ì— ì˜í•´ 만들어진, ì•ˆí…Œë‚˜íŒŸì€ ëª¨ë“ ë©´ì—ì„œ ìžìœ ë¡ìŠµë‹ˆë‹¤: 소스 코드가 공개ë˜ì–´ ìžˆê³ , 무료ì¸ë°ë‹¤ê°€ ê´‘ê³ ë„ ì—†ìŠµë‹ˆë‹¤. - -<b>ëª¨ë“ ê¸°ëŠ¥:</b><br> -ê°€ì ¸ì˜¤ê¸°, 관리하기, 재ìƒí•˜ê¸°<br> -• iTunes, gPodder.net, OPML 파ì¼, RSS ë° Atom ë§í¬ë¥¼ 통해 피드를 추가하거나 ê°€ì ¸ì˜¬ 수 있습니다.<br> -• 재ìƒì„ ì–´ë””ì—서나 ê´€ë¦¬í• ìˆ˜ 있습니다: 홈스í¬ë¦° ìœ„ì ¯, 시스템 알림, ì´ì–´í° ë° ë¸”ë£¨íˆ¬ìŠ¤ 컨트롤<br> -• ë°°ì† ìž¬ìƒ ì§€ì›, 챕터 지ì›(MP3, VorbisComment, Podlove), 마지막 ìž¬ìƒ ìœ„ì¹˜ 기억, ê³ ê¸‰ 취침 타ì´ë¨¸(í”들어서 초기화, 볼륨 낮추기, ìž¬ìƒ ëŠë¦¬ê²Œ 하기) ë“±ì˜ ê¸°ëŠ¥ìœ¼ë¡œ 팟ìºìŠ¤íŠ¸ë¥¼ ì¦ê¸°ì„¸ìš”<br> -• 암호로 ë³´í˜¸ëœ í”¼ë“œì™€ ì—í”¼ì†Œë“œì— ì ‘ê·¼<br> -• 페ì´ì§€ë¡œ êµ¬ë¶„ëœ í”¼ë“œ 활용 (www.podlove.org/paged-feeds) - -기ë¡í•˜ê³ , ê³µìœ í•˜ê³ , 호ì‘하기<br> -• 가장 좋아하는 팟ìºìŠ¤íŠ¸ ì—피소드를 ì¦ê²¨ì°¾ê¸°ë¡œ ì €ìž¥<br> -• ì—피소드를 ìž¬ìƒ ê¸°ë¡ ë˜ëŠ” 검색(ì œëª© ë° ë…¸íŠ¸)으로 찾기<br> -• ì—피소드와 피드를 SNS, ì´ë©”ì¼, gPodder.net, OPML 내보내기로 ê³µìœ <br> -• ìžë™ìœ¼ë¡œ Flattr하기 ë“±ì˜ Flattr 기능으로 팟ìºìŠ¤íŠ¸ ì œìž‘ìž ì§€ì› - -시스템 컨트롤 -• ìžë™ 다운로드를 ì œì–´í•˜ì„¸ìš”: 피드를 ê³ ë¥´ê³ , ëª¨ë°”ì¼ ë„¤íŠ¸ì›Œí¬ë¥¼ ì œì™¸ì‹œí‚¤ê³ , íŠ¹ì • Wi-Fi 네트워í¬ë¥¼ ì„ íƒí•˜ê³ , 기기가 ì¶©ì „ì¤‘ì¼ë•Œë§Œ 다운로드하게 í•˜ê³ , 시간과 ê°„ê²©ì„ ì •í•˜ì„¸ìš”<br> -• ì—피소드 ìºì‹œ 용량, 똑똑한 ì‚ì œ(ì¦ê²¨ì°¾ê¸°ì™€ ìž¬ìƒ ìƒíƒœì— 기반), ì„ í˜¸í•˜ëŠ” ì €ìž¥ 위치 등으로 ì €ìž¥ì†Œë¥¼ 관리하세요<br> -• 여러가지 언어로 ì•ˆí…Œë‚˜íŒŸì„ ì‚¬ìš©í•˜ì„¸ìš” (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• ë°ìŒ ë° ì–´ë‘움 테마로 í™˜ê²½ì— ë§žì¶° 사용하세요<br> -• gPodder.netê³¼ OPML 내보내기 기능으로 구ë…í•œ 팟ìºìŠ¤íŠ¸ë¥¼ 백업하세요 - -<b>안테나팟 ì»¤ë®¤ë‹ˆí‹°ì— ì°¸ì—¬í•˜ì„¸ìš”!</b><br> -ì•ˆí…Œë‚˜íŒŸì€ ì§€ì›ìžë“¤ì— ì˜í•´ 활발히 개발ë˜ê³ 있습니다. ë‹¹ì‹ ë„ ì œìž‘ì„ ë•ê±°ë‚˜ ì œì•ˆì„ í•´ì„œ ì°¸ì—¬í• ìˆ˜ 있습니다! - -GitHubì—ì„œ 새로운 기능 ì œì•ˆ, 버그 ë³´ê³ , ê·¸ë¦¬ê³ ì½”ë“œ 기여를 í• ìˆ˜ 있습니다.:<br> -https://www.github.com/AntennaPod/AntennaPod - -구글 그룹ì—ì„œ ì•„ì´ë””어와 ì¢‹ì€ íŒŸìºìŠ¤íŠ¸ë¥¼ ê³µìœ í•˜ê³ ëª¨ë“ ì§€ì›ìžë“¤ì—게 ê°ì‚¬í• 수 있습니다:<br> -https://groups.google.com/forum/#!forum/antennapod - -ì§ˆë¬¸ì´ ìžˆìœ¼ì‹ ê°€ìš”? 아니면 ì˜ê²¬ì´ ìžˆìœ¼ì‹ ê°€ìš”? -https://twitter.com/@AntennaPod - -Transifexì—ì„œ 번ì—ì„ ë„울 수 있습니다:<br> -https://www.transifex.com/antennapod/antennapod - -ë² íƒ€ 테스트 í”„ë¡œê·¸ëž¨ì„ í†µí•´ ìµœì‹ ê¸°ëŠ¥ì„ ê°€ìž¥ ë¨¼ì € 확ì¸í•´ë³´ì„¸ìš”:<br> -https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/ko_KR/listing/fulldescription b/app/src/main/play/ko_KR/listing/fulldescription deleted file mode 100644 index 87b477fdc..000000000 --- a/app/src/main/play/ko_KR/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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> -• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -CONTROL THE SYSTEM<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• 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 index 3f9f50a90..c25bce143 100644 --- a/app/src/main/play/lt/listing/fulldescription +++ b/app/src/main/play/lt/listing/fulldescription @@ -1,43 +1,43 @@ -„AntennaPod“ yra tinklalaidžių tvarkytuvÄ— ir leistuvÄ—, įgalinanti momentinÄ™ prieigÄ… prie milijonų nemokamų bei mokamų tinklalaidžių, nuo nepriklausomų tinklalaidžių kÅ«rÄ—jų iki didžiųjų leidyklų, tokių kaip „BBC“, „NPR“ ir „CNN“. Be vargo pridÄ—kite, importuokite ir eksportuokite jų sklaidos kanalus naudodamiesi „iTunes“ tinklalaidžių duomenų baze, OPML failais ar tiesiogiai iÅ¡ RSS kanalo adreso. Sutaupykite laiko, baterijos energijos ir suvartojamų mobiliųjų duomenų iÅ¡naudodami galingas automatinio epizodų atsiuntimo priemones (nurodykite atsiuntimo metÄ…, laiko intervalÄ… ir belaidžius tinklus) ir iÅ¡trindami epizodus (remiantis mÄ—giamųjų sÄ…raÅ¡u ir laikymo nustatymais).<br> -Bet svarbiausia: atsisiųskite, klausykitÄ—s iÅ¡ karto ar pridÄ—kite epizodus į eilÄ™ ir mÄ—gaukitÄ—s jais pasirinkdami atkÅ«rimo spartÄ…, naudodamiesi skyrių palaikymu bei miego laikmaÄiu. JÅ«s netgi galite iÅ¡reikÅ¡ti savo meilÄ™ turinio kÅ«rÄ—jams naudodamiesi mÅ«sų „Flattr“ integracija. +„AntennaPod“ yra tinklalaidžių tvarkytuvÄ— ir leistuvÄ—, įgalinanti prieigÄ… prie milijonų tinklalaidžių, nuo nepriklausomų kÅ«rÄ—jų iki didžiųjų leidyklų, tokių kaip „BBC“, „NPR“ ir „CNN“. Be vargo pridÄ—kite, importuokite ir eksportuokite sklaidos kanalus naudodamiesi „iTunes“ tinklalaidžių duomenų baze, OPML failais ar RSS kanalais. Taupykite laikÄ…, baterijos energijÄ… ir mobilius duomenis naudodami galingas automatinio atsiuntimo priemones (nurodykite atsiuntimo metÄ…, laiko intervalÄ… ir belaidžius tinklus) ir iÅ¡trindami epizodus (remiantis mÄ—giamųjų sÄ…raÅ¡u ir laikymo nustatymais).<br> +Bet svarbiausia: atsisiųskite, klausykitÄ—s iÅ¡ karto ar dÄ—kite epizodus į eilÄ™ ir mÄ—gaukitÄ—s jais pasirinkÄ™ atkÅ«rimo spartÄ…, naudodamiesi skyrių palaikymu bei miego laikmaÄiu. Be to, galite iÅ¡reikÅ¡ti savo meilÄ™ turinio kÅ«rÄ—jams naudodamiesi „Flattr“ integracija. -Sukurtas tinklalaidžių entuziasto, „AntennaPod“ yra laisvas visomis Å¡io žodžio prasmÄ—mis: atvirojo kodo, jokių mokesÄių, jokių reklamų. +Sukurtas tinklalaidžių entuziasto, „AntennaPod“ yra laisvas visomis prasmÄ—mis: atvirojo kodo, be mokesÄių, be reklamų. <b>Visos funkcijos:</b><br> IMPORTUOKITE, TVARKYKITE BEI KLAUSYKITÄ–S<br> -• PridÄ—kite bei importuokite sklaidos kanalus iÅ¡ „iTunes“ bei „gPodder.net“ paslaugų, OPML failų ir RSS ar Atom nuorodų<br> -• Valdykite atkÅ«rimÄ… bet kur: pradžios ekrano valdyklyje, programos praneÅ¡imuose, ausinių ar „Bluetooth“ valdikliu<br> -• MÄ—gaukitÄ—s klausydamiesi taip, kaip Jums patinka, naudodamiesi derinama atkÅ«rimo sparta, skyrių palaikymu (MP3, „VorbisComment“ ir „Podlove“), iÅ¡saugota paskutinio atkÅ«rimo pozicija ir miego laikmaÄiu (mažinamas garsis bei lÄ—tinama atkÅ«rimo sparta, pakraÄius nustatomas iÅ¡ naujo)<br> -• Pasiekite slaptažodžiu apsaugotus sklaidos kanalus bei epizodus<br> +• PridÄ—kite ar importuokite sklaidos kanalus iÅ¡ „iTunes“ ir „gPodder.net“, OPML failų, RSS ar Atom nuorodų<br> +• Valdykite atkÅ«rimÄ… bet kur: pradžios ekrane, programų praneÅ¡imuose, ausinių ar „Bluetooth“ valdikliu<br> +• MÄ—gaukitÄ—s klausydamiesi taip, kaip Jums patinka, naudodamiesi derinama atkÅ«rimo sparta, skyrių palaikymu (MP3, „VorbisComment“ ir „Podlove“), iÅ¡saugota atkÅ«rimo pozicija ir miego laikmaÄiu (mažinamas garsis bei lÄ—tinama atkÅ«rimo sparta, pakraÄius nustatomas iÅ¡ naujo)<br> +• Pasiekite slaptažodžiu apsaugotus sklaidos kanalus ir epizodus<br> • IÅ¡naudokite puslapiuotus sklaidos kanalus (www.podlove.org/paged-feeds) STEBÄ–KITE, DALINKITÄ–S IR MÄ–GAUKITÄ–S<br> -• Kaupkite geriausius iÅ¡ geriausiųjų pažymÄ—dami epizodus kaip mÄ—gstamiausius<br> -• Raskite tÄ… vienintelį epizodÄ… naudodamiesi atkÅ«rimo istorija arba paieÅ¡ka (pavadinimuose ir laidų užraÅ¡uose)<br> -• DalinkitÄ—s epizodais bei sklaidos kanalais per socialinius tinklus, el. paÅ¡tu, „gPodder.net“ paslaugÄ… bei eksportuotus OPML failus<br> -• Remkite turinio kÅ«rÄ—jus naudodamiesi „Flattr“ integracija bei automatiniu rÄ—mimu +• Kaupkite geriausius pažymÄ—jÄ™ epizodÄ… kaip mÄ—gstamÄ…<br> +• Raskite norimÄ… epizodÄ… pasinaudojÄ™ atkÅ«rimo istorija ir paieÅ¡ka (pavadinimuose ir laidų užraÅ¡uose)<br> +• DalinkitÄ—s epizodais ir sklaidos kanalais per socialinius tinklus, el. paÅ¡tu, „gPodder.net“ ir OPML failus<br> +• Remkite turinio kÅ«rÄ—jus pasinaudojÄ™ „Flattr“ integracija VALDYKITE SISTEMÄ„<br> -• Valdykite automatinį atsiuntimÄ…: pasirinkite sklaidos kanalus, neleiskite atsiuntimų mobiliuoju duomenų ryÅ¡iu, apibrėžkite leidžiamus belaidžio ryÅ¡io tinklus, reikalaukite, jog atsiuntimai bÅ«tų vykdomi telefono įkrovos metu ir nurodykite atsiuntimų dienos metÄ… ar intervalÄ…<br> -• Valdykite atmintinÄ—s naudojimÄ… nurodydami podÄ—lyje laikomų epizodų kiekį, iÅ¡manų iÅ¡trynimÄ… (remiantis atkÅ«rimo bÅ«sena bei mÄ—giamųjų sÄ…raÅ¡u) ir nurodykite saugojimo vietÄ…<br> +• Valdykite automatinį atsiuntimÄ…: pasirinkite sklaidos kanalus, neleiskite atsiuntimų mobiliuoju ryÅ¡iu, apibrėžkite leistinus belaidžius tinklus, reikalaukite, jog atsiuntimai bÅ«tų vykdomi įkrovos metu, nurodykite atsiuntimų dienos metÄ… ar intervalÄ…<br> +• Valdykite laikmenos naudojimÄ… nurodant podÄ—lyje laikomų epizodų kiekį, iÅ¡manų trynimÄ… (remiantis atkÅ«rimo bÅ«sena ir mÄ—giamųjų sÄ…raÅ¡u), saugojimo vietÄ…<br> • NaudokitÄ—s „AntennaPod“ savo kalba (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH, LT)<br> -• Pritaikykite savo aplinkai pasirinkdami Å¡viesiÄ… arba tamsiÄ… temÄ…<br> -• Sukurkite savo prenumeratų atsarginÄ™ kopijÄ… pasinaudodami „gPodder.net“ integracija arba OPML eksportu +• Pritaikykite savo aplinkai pasirinkÄ™ Å¡viesiÄ… ar tamsiÄ… temÄ…<br> +• Kurkite prenumeratų atsargines kopijas „gPodder.net“ ar OPML failais <b>Prisijunkite prie AntennaPod bendruomenÄ—s!</b><br> -„AntennaPod“ aplikacijÄ… aktyviai vysto savanoriai. JÅ«s taip pat galite prisidÄ—ti, nuo atsiliepimų iki programinio kodo! +„AntennaPod“ vysto savanoriai. Ir JÅ«s galite prisidÄ—ti, nuo atsiliepimų iki programinio kodo! -„GitHub“ yra ta vieta, kur galite pageidauti naujų funkcijų, praneÅ¡ti apie riktÄ… arba prisidÄ—ti programiniu kodu:<br> +Per „GitHub“ galite pageidauti naujų funkcijų, praneÅ¡ti apie riktÄ… ar prisidÄ—ti programiniu kodu:<br> https://www.github.com/AntennaPod/AntennaPod -MÅ«sų „Google“ grupÄ— yra puiki vieta pasidalinti idÄ—jomis, mÄ—gstamiausiais tinklalaidžių sklaidos momentais ar iÅ¡reikÅ¡ti padÄ—kÄ… visiems savanoriams:<br> +„Google“ grupÄ—je galite dalintis idÄ—jomis, mÄ—gstamais tinklalaidžių sklaidos momentais ar padÄ—koti savanoriams:<br> https://groups.google.com/forum/#!forum/antennapod -Turite klausimų ar norite palikti atsiliepimÄ…? +Turite klausimų ar atsiliepimų? https://twitter.com/@AntennaPod -„Transifex“ yra ta vieta, kur galite prisidÄ—ti prie aplikacijos vertimo:<br> +Prie vertimų galite prisidÄ—ti per „Transifex“:<br> https://www.transifex.com/antennapod/antennapod -IÅ¡bandykite mÅ«sų Beta Testavimo programÄ…, jei norite pirmieji gauti naujausias funkcijas:<br> +Jei norite pirmieji gauti naujas funkcijas, iÅ¡bandykite Beta Testavimo programÄ…:<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/shortdescription b/app/src/main/play/lt/listing/shortdescription new file mode 100644 index 000000000..0a0752647 --- /dev/null +++ b/app/src/main/play/lt/listing/shortdescription @@ -0,0 +1 @@ +Patogi naudoti, lanksti atvirojo kodo tinklalaidžių tvarkytuvė bei leistuvė
\ No newline at end of file diff --git a/app/src/main/play/ms_MY/listing/fulldescription b/app/src/main/play/ms_MY/listing/fulldescription deleted file mode 100644 index 87b477fdc..000000000 --- a/app/src/main/play/ms_MY/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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> -• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -CONTROL THE SYSTEM<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• 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/nb/listing/fulldescription b/app/src/main/play/nb/listing/fulldescription deleted file mode 100644 index 87b477fdc..000000000 --- a/app/src/main/play/nb/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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> -• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -CONTROL THE SYSTEM<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• 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/nb_NO/listing/fulldescription b/app/src/main/play/nb_NO/listing/fulldescription deleted file mode 100644 index 460a880fe..000000000 --- a/app/src/main/play/nb_NO/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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> -Men viktigst av alt: Last ned, strøm eller legg episoder i kø og nyt dem slik du ønsker med regulerbar avspillingshasitghet, kapittelstøtte og en tidtaker for automatisk avslÃ¥ing. Du kan til og med vise din takknemlighet til innholdets skapere med vÃ¥r Flattr-integrasjon. - -Laget av podkast-entusiaster er AntennaPod gratis i ordets rette forstand: Ã¥pen kildekode, ingen kostnader, ingen reklame. - -<br>Alle funksjoner:</b></b> -IMPORTER, ORGANISER OG SPILL AV<br> -• Legg til og importer strømmer fra mapper fra iTunes og gPodder.net, OPML-filer og linker fra RSS og Atom<br> -• Behandle avspillinger fra hvor som helst: widget pÃ¥ startskjerm, systemnotifikasjoner og ørepropp- og bluetoothkontroller<br> -• Nyt det Ã¥ høre pÃ¥ din mÃ¥te med regulerbar avspillingshastighet, kapittelstøtte (MP3, VorbisComment og Podlove), husket avspillingsposisjon og en avansert tidtaker for automatisk avslÃ¥ing (rist for Ã¥ tilbakestille, senke volumet og sakke ned avspillingen)<br> -• Støtte for passordbeskyttede strømmer og episoder<br> -• Støtte for «paged feeds» (www.podlove.org/paged-feeds) - -FØLG MED, DEL OG SETT PRIS PÃ…<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find den ene episoden gjennom avspillingshistorien eller ved Ã¥ søke (titler og shownotater)<br> -• Del episoder og strømmer gjennom avanserte sosiale medier- og e-postinstillinger, gPodder.net-tjenester og via OPML-eksportering<br> -• Støtt innholdsskapere med Flattr-integrasjon gjennom automatisk «flattring» - -KONTROLLER SYSTEMET<br> -• Ta kontroll over automatiske nedlastninger: velg feeds, ekskluder mobil tilkobling, spesifiser Wifi-nettverk, krev at telefonen er tilkoblet lader, sett tidspunk eller intervaller<br> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Bruk AntennaPod i ditt sprÃ¥k (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Tilpass appens stil ved Ã¥ bruke det mørke eller lyse temaet<br> -• Lag back-up av dine abonnement med gPodder.net-integrasjon og OPML-eksport - -<b>Join the AntennaPod community!</b><br> -AntennaPod er under aktiv utvikling av frivillige. Du kan ogsÃ¥ bidra, med kode eller kommentarer! - -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 - -Har du spørsmÃ¥l eller vil du gi oss tilbakemelding? -https://twitter.com/@AntennaPod - -Transifex er stedet for Ã¥ hjelpe til med oversettinger:<br> -https://www.transifex.com/antennapod/antennapod - -Sjekk ut vÃ¥rt program for betatesting for Ã¥ fÃ¥ de nyeste funksjonene først:<br> -https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/nl-NL/listing/fulldescription b/app/src/main/play/nl-NL/listing/fulldescription index 52a2d4337..736a3f3a5 100644 --- a/app/src/main/play/nl-NL/listing/fulldescription +++ b/app/src/main/play/nl-NL/listing/fulldescription @@ -1,20 +1,43 @@ -AntennaPod is een open-source podcast manager voor Android 2.3.3 en hoger. Het biedt alle basisfuncties die u verwacht van een podcatcher, zoals streaming en downloaden van episodes, alle feeds automatisch verversen of episodes aan een wachtrij toevoegen om ze later te luisteren. Bovendien laat AntennaPod je podcasts en afleveringen vanuit de app flattr'en. - -So far the following features are implemented: - -* Episodes downloaden en streamen -* Variabele afspeelsnelheid (vereist Presto Sound Library of Prestissimo) -* Support voor Atom en RSS feeds -* Ondersteuning voor wachtwoord-beveiligde feeds en afleveringen -* Support for searching iTunes listings -* OPML import en export -* Flattr integration including automatic flattring -* Homescreen widget voor de player -* Zoekfunctie -* Automatische feed updates -* Automatisch downloaden van nieuwe episodes -* Sleep timer -* Toegang tot de gpodder.net podcast gids -* Abonnementen synchroniseren met de gpodder.net dienst -* Supports MP3 chapters, VorbisComment chapters and Podlove Simple Chapters -* Supports paged feeds (http://podlove.org/paged-feeds/)
\ No newline at end of file +Met AntennaPod speel en beheer je al je podcasts en krijg je directe toegang tot duizenden gratis en betaalde podcasts - van onafhankelijke makers tot grote merken zoals BBC, CNN en NPO. Via de iTunes database, OPML-bestanden en simpele RSS-linkjes voeg je deze podcasts makkelijk toe. Dankzij simpele maar slimme automatische controle van het downloaden en verwijderen van afleveringen spaar je je batterij, hoef je je favoriete podcast niet meer handmatig te volgen en verbruik je geen onnodig mobiele data.<br> +Maar belangrijker: Met een handige wachtrij, aanpasbare afspeelsnelheden, ondersteuning van hoofdstukken en een slaap timer luister je naar podcasts op de manier die jij prettig vindt. Je kunt zelfs je liefde voor de makers uiten met onze Flattr-integratie. + +Gemaakt door podcast-enthousiastelingen, AntennaPod is vrij in de breedste zin van het woord: vrij van advertenties, open source en gratis. + +<b>Alle features:</b><br> +IMPORTEREN, ORGANISEREN, AFSPELEN<br> +• Voeg feeds toe via iTunes and gPodder.net database, OPML-bestanden and RSS of Atom linkjes<br> +• Beheer het afspelen overal: met een homescreen widget, in je Android meldingen en de knoppen op je koptelefoon en bluetooth-apparaat<br> +• Bepaal zelf hoe je luistert met aanpasbare afspeelsnelheden, ondersteuning van hoofdstukken (MP3, VorbisComment en Podlove), afspeelpositie voor elke aflevering en een handige 'slaap timer' (schudden om te resetten, volume langzaam zachter en herstel naar normale afspeelsnelheid)<br> +• Toegang tot wachtwoord-beveiligde podcasts en afleveringen<br> +• Doe je voordeel met 'paged feeds' (www.podlove.org/paged-feeds) + +DEEL & WAARDEER<br> +• Hou het beste van het beste bij door afleveringen als favoriet te markeren<br> +• Vindt die ene aflevering terug in de afspeelgeschiedenis of door te zoeken (in titels, shownotes en makers)<br> +• Deel podcasts en afleveringen via uitgebreide opties voor sociale media, WhatsApp, email en gPodder.net<br> +• Steun makers met Flattr-integratie, inclusief auto-Flattr + +HOUD DE CONTROLE +• Beheer automatische downloads: kies je podcasts, sluit mobiele netwerken uit, selecteer specifieke WiFi-verbindingen, eis dat de telefoon wordt opgeladen and bepaal tijden of intervals<br> +• Controleer geheugengebruik: stel een maximumaantal gedownloade afleveringen in, laat afleveringen automatisch verwijderen (maar sluit je favorieten en niet-afgespeelde afleveringen uit) en selecteer zelf je opslaglocatie<br> +• Gebruik AntennaPod in jouw taal: Nederlands! (Of in het Engels, Zweeds, Frans, Duits, Spaans, enz)<br> +• Voel je een kameleon: kies voor een licht of donker uiterlijk<br> +• Back-up je abonnementen via gPodder.net en geëxporteerde OPML-bestanden + +<b>Doe mee met de AntennaPod gemeenschap!</b><br> +AntennaPod wordt regelmatig geüpdatet door vrijwilligers. En jij kan ook helpen, met code of commentaar! + +GitHub is de beste plek voor foutmeldingen, verzoekjes voor nieuwe functies en bijdragen aan de code:<br> +https://www.github.com/AntennaPod/AntennaPod + +Onze Google Group is de beste plek om je ideeën, favoriete podcast-momenten en waardering naar alle vrijwilligers te delen:<br> +https://groups.google.com/forum/#!forum/antennapod + +Heb je een vraag of wil je feedback geven? +https://twitter.com/@AntennaPod + +Transifex is de beste plek om te helpen met vertalen:<br> +https://www.transifex.com/antennapod/antennapod + +Check het Beta Testprogramma om de laatste features als eerst te krijgen:<br> +https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/nl-NL/listing/shortdescription b/app/src/main/play/nl-NL/listing/shortdescription index 4eceefbb7..31c66d634 100644 --- a/app/src/main/play/nl-NL/listing/shortdescription +++ b/app/src/main/play/nl-NL/listing/shortdescription @@ -1 +1 @@ -Easy-to-use, flexible and open-source podcast manager and player
\ No newline at end of file +Gemakkelijk te gebruiken, flexibele en open-source podcastbeheerder en -speler
\ No newline at end of file diff --git a/app/src/main/play/nl-NL/listing/title b/app/src/main/play/nl-NL/listing/title index 31552f353..6c7c64cfc 100644 --- a/app/src/main/play/nl-NL/listing/title +++ b/app/src/main/play/nl-NL/listing/title @@ -1 +1 @@ -AntennaPod
\ No newline at end of file +AntennaPod diff --git a/app/src/main/play/nl/listing/fulldescription b/app/src/main/play/nl/listing/fulldescription deleted file mode 100644 index 736a3f3a5..000000000 --- a/app/src/main/play/nl/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -Met AntennaPod speel en beheer je al je podcasts en krijg je directe toegang tot duizenden gratis en betaalde podcasts - van onafhankelijke makers tot grote merken zoals BBC, CNN en NPO. Via de iTunes database, OPML-bestanden en simpele RSS-linkjes voeg je deze podcasts makkelijk toe. Dankzij simpele maar slimme automatische controle van het downloaden en verwijderen van afleveringen spaar je je batterij, hoef je je favoriete podcast niet meer handmatig te volgen en verbruik je geen onnodig mobiele data.<br> -Maar belangrijker: Met een handige wachtrij, aanpasbare afspeelsnelheden, ondersteuning van hoofdstukken en een slaap timer luister je naar podcasts op de manier die jij prettig vindt. Je kunt zelfs je liefde voor de makers uiten met onze Flattr-integratie. - -Gemaakt door podcast-enthousiastelingen, AntennaPod is vrij in de breedste zin van het woord: vrij van advertenties, open source en gratis. - -<b>Alle features:</b><br> -IMPORTEREN, ORGANISEREN, AFSPELEN<br> -• Voeg feeds toe via iTunes and gPodder.net database, OPML-bestanden and RSS of Atom linkjes<br> -• Beheer het afspelen overal: met een homescreen widget, in je Android meldingen en de knoppen op je koptelefoon en bluetooth-apparaat<br> -• Bepaal zelf hoe je luistert met aanpasbare afspeelsnelheden, ondersteuning van hoofdstukken (MP3, VorbisComment en Podlove), afspeelpositie voor elke aflevering en een handige 'slaap timer' (schudden om te resetten, volume langzaam zachter en herstel naar normale afspeelsnelheid)<br> -• Toegang tot wachtwoord-beveiligde podcasts en afleveringen<br> -• Doe je voordeel met 'paged feeds' (www.podlove.org/paged-feeds) - -DEEL & WAARDEER<br> -• Hou het beste van het beste bij door afleveringen als favoriet te markeren<br> -• Vindt die ene aflevering terug in de afspeelgeschiedenis of door te zoeken (in titels, shownotes en makers)<br> -• Deel podcasts en afleveringen via uitgebreide opties voor sociale media, WhatsApp, email en gPodder.net<br> -• Steun makers met Flattr-integratie, inclusief auto-Flattr - -HOUD DE CONTROLE -• Beheer automatische downloads: kies je podcasts, sluit mobiele netwerken uit, selecteer specifieke WiFi-verbindingen, eis dat de telefoon wordt opgeladen and bepaal tijden of intervals<br> -• Controleer geheugengebruik: stel een maximumaantal gedownloade afleveringen in, laat afleveringen automatisch verwijderen (maar sluit je favorieten en niet-afgespeelde afleveringen uit) en selecteer zelf je opslaglocatie<br> -• Gebruik AntennaPod in jouw taal: Nederlands! (Of in het Engels, Zweeds, Frans, Duits, Spaans, enz)<br> -• Voel je een kameleon: kies voor een licht of donker uiterlijk<br> -• Back-up je abonnementen via gPodder.net en geëxporteerde OPML-bestanden - -<b>Doe mee met de AntennaPod gemeenschap!</b><br> -AntennaPod wordt regelmatig geüpdatet door vrijwilligers. En jij kan ook helpen, met code of commentaar! - -GitHub is de beste plek voor foutmeldingen, verzoekjes voor nieuwe functies en bijdragen aan de code:<br> -https://www.github.com/AntennaPod/AntennaPod - -Onze Google Group is de beste plek om je ideeën, favoriete podcast-momenten en waardering naar alle vrijwilligers te delen:<br> -https://groups.google.com/forum/#!forum/antennapod - -Heb je een vraag of wil je feedback geven? -https://twitter.com/@AntennaPod - -Transifex is de beste plek om te helpen met vertalen:<br> -https://www.transifex.com/antennapod/antennapod - -Check het Beta Testprogramma om de laatste features als eerst te krijgen:<br> -https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/no/listing/fulldescription b/app/src/main/play/no/listing/fulldescription deleted file mode 100644 index 87b477fdc..000000000 --- a/app/src/main/play/no/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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> -• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -CONTROL THE SYSTEM<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• 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/pl-PL/listing/fulldescription b/app/src/main/play/pl-PL/listing/fulldescription index 795addbc5..28e75d3cc 100644 --- a/app/src/main/play/pl-PL/listing/fulldescription +++ b/app/src/main/play/pl-PL/listing/fulldescription @@ -1,20 +1,43 @@ -AntennaPod jest menadżerem podcastów dla Androida 2.3.3 i nowszych na otwartej licencji. Oferuje wszystkie podstawowe funkcje których oczekuje się od podcathera, takie jak strumieniowanie oraz pobieranie odcinków, odświeżanie wszystkich wątków automatycznie i dodawanie ich do kolejki do późniejszego odsłuchania. Oprócz tego AntennaPod pozwala na flattr-owanie podcastów i odcinków z poziomu aplikacji. - -Dotychczas zostały wdrożone następujące funkcjonalności: - -* Pobieranie i strumieniowanie odcinków -* Zmienna prędkość odtwarzania (wymaga Presto Sound Library lub Prestissimo) -* Wsparcie dla wątków Atom i RSS -* Wsparcie dla kanałów i odcinków zabezpieczonych hasłem -* Support for searching iTunes listings -* Import i eksport OPML -Integracja z serwisem Flattr umożliwiająca flattring -* Widget odtwarzacza na home screen -* Wyszukiwanie -* Automatyczne aktualizaje wątków -* Automatyczne pobieranie nowych odcinków -* Timer snu -* Dostęp do katalogu podcastów na gpodder.net -* Synchronizację subskrypcji z gpodder.net -* Obsługuje rodziały MP3, VorbisComment i Podlove Simple. -* Wspiera stronicowane kanały (http://podlove.org/paged-feeds/)
\ No newline at end of file +AntennaPod jest programem katalogujÄ…cym i odtwarzajÄ…cym który daje możliwość natychmiastowego dostÄ™pu do milionów darmowych i pÅ‚atnych podcastów. Od niezależych twórców po wielkich producentów takich jak BBC, NPR czy CNN. Dodawaj, importuj, eksportuj wÄ…tki bez przeszkód używajÄ…c bazy iTunes, plików OPML czy po prostu przez linki RSS. OszczÄ™dź wysiÅ‚ek, bateriÄ™ oraz pakiety danych mobilnych poprzez zaawansowanÄ… kontrolÄ™ automatycznego pobierania (okreÅ›lone godziny, interwaÅ‚y czy sieci WiFi) oraz inteligentne usuwanie odcinków ( na podstawie ulubionych i ustawieÅ„ opóźnieÅ„).<br> +Najważniejsze: pobieraj , streamuj lub kolejkuj odcinki oraz rozkoszuj siÄ™ nimi jak tylko chcesz z możliwoÅ›ciÄ… zmiany prÄ™dkoÅ›ci odtwarzania, wsparciem rozdziałów i wyÅ‚Ä…cznikiem czasowym. Możesz nawet pokazać jak bardzo doceniach twórców dziÄ™ki integracji z Flattr. + +Stworzone przez entuzjastów podcastów, AntennaPod jest darmowe w każdym sÅ‚owa znaczeniu: otwarty kod, brak opÅ‚at i reklam. + +<b>Wszystkie funkcje:</b><br> +ZAIMPORTUJ, ZORGANIZUJ I ODTWARZAJ<br> +• Dodawaj i importuj kanaÅ‚y poprzez iTunes, gPodder.net, z plików OPML, RSS i linków Atom<br> +• ZarzÄ…dzaj odtwarzaniem zewszÄ…d: widget na ekranie głównym, powiadomienia systemowe i kontrolery bluetooth<br> +• Delektuj siÄ™ sÅ‚uchaniem po swojemu z: zmiennÄ… prÄ™dkoÅ›ciÄ… odtwarzania, wsparciem rozdziałów (MP3, VorbisComment i Podlove), zapamiÄ™tywaniem miejsca zakoÅ„czenia sÅ‚uchania i zaawansowanym wyÅ‚Ä…cznikiem czasowym (potrzÄ…Å›nij aby zrestartować, zmiejszanie gÅ‚oÅ›noÅ›ci i zwalnianie odtwarzania) <br> +• DostÄ™p do odcinków i kanałów chroniony hasÅ‚em<br> +• Wykorzystaj zapisane kanaÅ‚y (www.podlove.org/paged-feeds) + +ÅšLEDŹ, DZIEL SIĘ I DOCENIAJ<br> +• ZapamiÄ™tywanie najlepszych z najlepszych poprzez dodawania odcinków do ulubionych<br> +• Wyszukiwanie odcinów w historii odtwarzania lub poprzez tytuÅ‚/przypisy<br> +• Dzial siÄ™ odcinkami i wÄ…tkami poprzez zaawansowane opcje medii spoÅ‚ecznych oraz emaila, serwisu gPodder.net lub poprzez eksport do OPML<br> +• Wsparcie twórców poprzez integracjÄ™ z Flattr, również poprzez automatyczne flattr-owanie + +Kontroluj system<br> +• Ustaw automatyczne pobieranie zgodnie z wÅ‚asnymi preferencjami: wybieranie wÄ…tków, pobieranie tylko przez WiFi, wybór okreÅ›lonych sieci WiFi, wymaganie Å‚adowania przy pobieraniu oraz ustawienie harmonogramu i interwałów<br> +• ZarzÄ…danie pamiÄ™ciÄ… poprzez ustawienia liczby pobranych odcinków z pomocÄ… inteligentnego kasowania( na podstawie ulubionych i statusu odtwarzania) oraz wyboru lokalizacji<br> +• Używaj AntennaPod w swoim jÄ™zyku (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> +• Dostosowanie wyglÄ…du jasnÄ… i ciemnÄ… skórkÄ…<br> +• Twórz kopie bezpieczeÅ„stwa swoich subskrypcji z pomocÄ… zintegrowanego gPoddder.net oraz plików OPML + +<b>DoÅ‚Ä…cz do spoÅ‚ecznoÅ›ci AntennaPod</b><br> +AntennaPod jest ciÄ…gle rozwijane przez ochotników. Ty też możesz pomóc, kodem lub komentarzem! + +Sugestie ulepszeÅ„, raporty bÅ‚Ä™dów oraz dodatki do kodu prosimy kierować poprzez GitHub<br> +https://www.github.com/AntennaPod/AntennaPod + +Nasza grupa Google jest miejsce do dzielenia siÄ™ pomysÅ‚ami, ulubionymi momentami podcastów oraz miejscem gdzie można podziÄ™kować ochotnikom za ich pracÄ™:<br> +https://groups.google.com/forum/#!forum/antennapod + +Masz pytanie lub chcesz przekazać nam swojÄ… opiniÄ™ ? +https://twitter.com/@AntennaPod + +Pomoc w tÅ‚umaczeniach na Transifex:<br> +https://www.transifex.com/antennapod/antennapod + +JeÅ›li chcesz otrzymywać najnowsze ulepszenia wczeÅ›niej niż inni rozważ doÅ‚Ä…czenie do programu beta testów:<br> +https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod diff --git a/app/src/main/play/pl-PL/listing/title b/app/src/main/play/pl-PL/listing/title index 31552f353..6c7c64cfc 100644 --- a/app/src/main/play/pl-PL/listing/title +++ b/app/src/main/play/pl-PL/listing/title @@ -1 +1 @@ -AntennaPod
\ No newline at end of file +AntennaPod diff --git a/app/src/main/play/pl/listing/fulldescription b/app/src/main/play/pl/listing/fulldescription deleted file mode 100644 index 87b477fdc..000000000 --- a/app/src/main/play/pl/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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> -• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -CONTROL THE SYSTEM<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• 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/pl_PL/listing/fulldescription b/app/src/main/play/pl_PL/listing/fulldescription deleted file mode 100644 index c2c8cc597..000000000 --- a/app/src/main/play/pl_PL/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -AntennaPod jest programem katalogujÄ…cym i odtwarzajÄ…cym który daje możliwość natychmiastowego dostÄ™pu do milionów darmowych i pÅ‚atnych podcastów. Od niezależych twórców po wielkich producentów takich jak BBC, NPR czy CNN. Dodawaj, importuj, eksportuj wÄ…tki bez przeszkód używajÄ…c bazy iTunes, plików OPML czy po prostu przez linki RSS. OszczÄ™dź wysiÅ‚ek, bateriÄ™ oraz pakiety danych mobilnych poprzez zaawansowanÄ… kontrolÄ™ automatycznego pobierania (okreÅ›lone godziny, interwaÅ‚y czy sieci WiFi) oraz inteligentne usuwanie odcinków ( na podstawie ulubionych i ustawieÅ„ opóźnieÅ„).<br> -Najważniejsze: pobieraj , streamuj lub kolejkuj odcinki oraz rozkoszuj siÄ™ nimi jak tylko chcesz z możliwoÅ›ciÄ… zmiany prÄ™dkoÅ›ci odtwarzania, wsparciem rozdziałów i wyÅ‚Ä…cznikiem czasowym. Możesz nawet pokazać jak bardzo doceniach twórców dziÄ™ki integracji z Flattr. - -Stworzone przez entuzjastów podcastów, AntennaPod jest darmowe w każdym sÅ‚owa znaczeniu: otwarty kod, brak opÅ‚at i reklam. - -<b>Wszystkie funkcje:</b><br> -ZAIMPORTUJ, ZORGANIZUJ I ODTWARZAJ<br> -• Dodawaj i importuj kanaÅ‚y poprzez iTunes, gPodder.net, z plików OPML, RSS i linków Atom<br> -• ZarzÄ…dzaj odtwarzaniem zewszÄ…d: widget na ekranie głównym, powiadomienia systemowe i kontrolery bluetooth<br> -• Delektuj siÄ™ sÅ‚uchaniem po swojemu z: zmiennÄ… prÄ™dkoÅ›ciÄ… odtwarzania, wsparciem rozdziałów (MP3, VorbisComment i Podlove), zapamiÄ™tywaniem miejsca zakoÅ„czenia sÅ‚uchania i zaawansowanym wyÅ‚Ä…cznikiem czasowym (potrzÄ…Å›nij aby zrestartować, zmiejszanie gÅ‚oÅ›noÅ›ci i zwalnianie odtwarzania) <br> -• DostÄ™p do odcinków i kanałów chroniony hasÅ‚em<br> -• Wykorzystaj zapisane kanaÅ‚y (www.podlove.org/paged-feeds) - -ÅšLEDŹ, DZIEL SIĘ I DOCENIAJ<br> -• ZapamiÄ™tywanie najlepszych z najlepszych poprzez dodawania odcinków do ulubionych<br> -• Wyszukiwanie odcinów w historii odtwarzania lub poprzez tytuÅ‚/przypisy<br> -• Dzial siÄ™ odcinkami i wÄ…tkami poprzez zaawansowane opcje medii spoÅ‚ecznych oraz emaila, serwisu gPodder.net lub poprzez eksport do OPML<br> -• Wsparcie twórców poprzez integracjÄ™ z Flattr, również poprzez automatyczne flattr-owanie - -Kontroluj system<br> -• Ustaw automatyczne pobieranie zgodnie z wÅ‚asnymi preferencjami: wybieranie wÄ…tków, pobieranie tylko przez WiFi, wybór okreÅ›lonych sieci WiFi, wymaganie Å‚adowania przy pobieraniu oraz ustawienie harmonogramu i interwałów<br> -• ZarzÄ…danie pamiÄ™ciÄ… poprzez ustawienia liczby pobranych odcinków z pomocÄ… inteligentnego kasowania( na podstawie ulubionych i statusu odtwarzania) oraz wyboru lokalizacji<br> -• Używaj AntennaPod w swoim jÄ™zyku (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Dostosowanie wyglÄ…du jasnÄ… i ciemnÄ… skórkÄ…<br> -• Twórz kopie bezpieczeÅ„stwa swoich subskrypcji z pomocÄ… zintegrowanego gPoddder.net oraz plików OPML - -<b>DoÅ‚Ä…cz do spoÅ‚ecznoÅ›ci AntennaPod</b><br> -AntennaPod jest ciÄ…gle rozwijane przez ochotników. Ty też możesz pomóc, kodem lub komentarzem! - -Sugestie ulepszeÅ„, raporty bÅ‚Ä™dów oraz dodatki do kodu prosimy kierować poprzez GitHub<br> -https://www.github.com/AntennaPod/AntennaPod - -Nasza grupa Google jest miejsce do dzielenia siÄ™ pomysÅ‚ami, ulubionymi momentami podcastów oraz miejscem gdzie można podziÄ™kować ochotnikom za ich pracÄ™:<br> -https://groups.google.com/forum/#!forum/antennapod - -Masz pytanie lub chcesz przekazać nam swojÄ… opiniÄ™ ? -https://twitter.com/@AntennaPod - -Pomoc w tÅ‚umaczeniach na Transifex:<br> -https://www.transifex.com/antennapod/antennapod - -JeÅ›li chcesz otrzymywać najnowsze ulepszenia wczeÅ›niej niż inni rozważ doÅ‚Ä…czenie do programu beta testów:<br> -https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/pt-BR/listing/fulldescription b/app/src/main/play/pt-BR/listing/fulldescription index 735334e0c..e40d3f450 100644 --- a/app/src/main/play/pt-BR/listing/fulldescription +++ b/app/src/main/play/pt-BR/listing/fulldescription @@ -1,40 +1,43 @@ -O AntennaPod é um gestor de podcasts que lhe permite aceder a milhões de podcasts (gratuitos ou pagos), a partir de diversas fontes tais como as estações BBC, NPR e CNN. A adição de fontes é muito fácil através das base de dados iTunes ou gPodder, ficheiros OPML ou fontes RSS. Poupe tempo, economize energia e dados móveis através dos mecanismos de controlo de transferência de episódios (possibilidade de especificar intervalos ou horas para as transferências e redes WiFi) e de eliminação de episódios (de acordo com as suas preferências).<br> -Mas ainda mais importante: pode transferir, emitir ou colocar episódios na lista de reprodução ao seu gosto, pode utilizar velocidades variáveis de reprodução, tem suporte a capÃtulos e um temporizador. Pode também mostrar o seu apreço aos disponibilizadores dos episódios através do serviço Flattr. - -Criado por entusiastas de podcasts, o AntennaPod é livre em todos os sentidos da palavra: open source, gratuito e sem publicidade. - -<b>Funcionalidades:</b><br> -Importação, organização e reprodução<br> -• Adicione e importe fontes existentes nos diretórios iTunes e gPodder.net, ficheiros OPML e ligações ATOM e RSS<br> -• Gestão de podcasts através do widget, barra de notificações e controlos de auriculares ou auscultadores<br> -• Velocidade variável de reprodução, suporte a capÃtulos (MP3, VorbisComment e Podlove), memorização da posição de reprodução e um temporizador avançado (agite para repor ou baixar e aumentar o volume)<br> -• Acesso a fontes e episódios protegidos por palavra-passe<br> -• Possibilidade de subscrever fontes paginadas (www.podlove.org/paged-feeds) - -Monitorização, partilha e suporte<br> -• Monitorize os seus podcasts preferidos marcando-os como favoritos<br> -• Localize um episódio através do histórico de reprodução ou através de uma pesquisa (tÃtulos e notas)<br> -• Partilhe episódios e fontes nas redes sociais, por e-mail, no diretório gPodder.net ou através de ficheiros OPML<br> -• Ajude os criadores de conteúdos através do serviço Flattr - -Controlar o sistema<br> -• Controle todas as transferÊncias automáticas: escolha as fontes, exclua redes móveis, especifique as redes WiFi, indique se o telefone deve estar a ser carregado e defina as horas ou intervalos das transferências<br> -• Faça a gestão do armazenamento através da cache de episódios, da eliminação inteligente (de acordo com os seus favoritos e estado de reprodução) e selecionado a localização de armazenamento<br> -• Utilize o AntennaPod no seu idioma (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapte-se ao seu ambiente através dos temas claro ou escuro<br> -• Salvaguarde as suas subscrições com a integração gPodder.net ou através da exportação OPML - -<b>Integre a comunidade do AntennaPod!</b><br> -O AntennaPod é desenvolvido por voluntários. Você também pode contribuir na programação ou reportando os erros encontrados! - -O GitHub é o local certo para os pedidos de funcionalidades, relatórios de erros e contribuições:<br> -www.github.com/AntennaPod/AntennaPod - -O nosso grupo Google é o local certo para partilhar ideias e agradecer aos nossos voluntários:<br> +AntennaPod é um gerenciador e reprodutor de <i>podcasts</i> que te dá acesso instantâneo a milhões de <i>podcasts</i> gratuitos e pagos, desde <i>podcasters</i> independentes até grandes editores como BBC, NPR e CNN. Adicione, importe e exporte seus <i>feeds</i> sem complicações utilizando a base de dados do iTunes, arquivos OPML ou simples URLs RSS. Economize esforços, bateria e uso de dados móveis com poderosos controles de automação para baixar episódios (especifique horários, intervalos e redes WiFi) e excluir episódios (baseado nos seus favoritos e configurações de adiamento).<br> +Mas o mais importante: Baixe, realize <i>streaming</i> ou enfilere episódios e desfrute deles da maneira que quiser com velocidades de reprodução ajustáveis, suporte para capÃtulos e cronômetro. Você pode até mostrar o seu apreço aos criadores de conteúdo com a integração com o Flattr. + +Desenvolvido por fãs de podcasts, AntennaPod é livre em todos os sentidos da palavra; <i>open source</i>, sem custos, sem propagandas. + +<b>Recursos disponÃveis:</b><br> +IMPORTE, ORGANIZE E TOQUE <br> +• Adicione and importe feeds pelo iTunes e diretorios gPodder.net, arquivos OPML e links RSS ou Atom<br> +• Gerencie suas reproduções de qualquer lugar: widget da tela inicial, notificações de sistema e fone de ouvido e controles bluetooth<br> +• Ouça do seu jeito com velocidade de reprodução ajustável, suporte a capÃtulos (MP3, VorbisComment e Podlove), marcador da posição de reprodução e um despertador avançado (chacoalhe para reiniciar, volume reduzido e reprodução desacelerada)<br> +• Acesse feeds e episódios protegidos por senha +• Faça uso de <i>feeds</i> paginados (www.podlove.org/paged-feeds) + +MANTENHA-SE ATUALIZADO, COMPARTILHE E APRECIE<br> +• Guarde o melhor do melhor marcando episódios como favoritos<br> +• Encontre aquele episódio especÃfico através do histórico de execução ou pelo sistema de busca (através de tÃtulos e anotações)<br> +• Compartilhe episódios e <i>feeds</i> através de opções em redes sociais, email, os serviços da gPodder.net e exportação OPML<br> +• Apoie os criadores de conteúdo com a integração com o Flattr + +CONTROLE O SISTEMA +• Tenha controle sobre a automação dos <i>downloads</i>: escolha <i>feeds</i>, exclua redes móveis, selecione redes especÃficas de WiFi, exija que o telefone esteja sendo carregado e defina horários ou intervalos<br> +• Gerencie o armazenamento configurando a quantidade de episódios em cache, exclusão inteligente dos episódios (baseada nos seus favoritos e status de reprodução)<br> +• Use o AntennaPod no seu idioma (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> +• Adapte-se ao ambiente utilizando os temas claro ou escuro<br> +• Faça <i>backup</i> das suas inscrições com a integração ao gPodder.net e exportação de OPML + +<b>Junte-se à comunidade AntennaPod!</b><br> +O AntennaPod está sob constante desenvolvimento através de voluntários. Você também pode contribuir, com código ou um comentário! + +Vá ao GitHub para solicitar funcionalidades, reportar bugs e contribuir com código:<br> +https://www.github.com/AntennaPod/AntennaPod + +Nosso grupo no Google é o lugar para compartilhar suas idéias, momentos de podcasts favoritos e agradecer aos voluntários:<br> https://groups.google.com/forum/#!forum/antennapod -O Transifex é o local no qual pode ajudar a traduzir a aplicação:<br> -www.transifex.com/antennapod/antennapod +Tem uma dúvida ou um comentário? +https://twitter.com/@AntennaPod -Junte-se ao nosso programa de testes para obter as funcionalidades mais recentes:<br> -www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file +Transifex é o lugar para ajudar com as traduções:<br> +https://www.transifex.com/antennapod/antennapod + +Cheque nosso programa de beta testing para receber as atualizações mais recentes primeiro:<br> +https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/pt-BR/listing/title b/app/src/main/play/pt-BR/listing/title index 31552f353..6c7c64cfc 100644 --- a/app/src/main/play/pt-BR/listing/title +++ b/app/src/main/play/pt-BR/listing/title @@ -1 +1 @@ -AntennaPod
\ No newline at end of file +AntennaPod diff --git a/app/src/main/play/pt-PT/listing/title b/app/src/main/play/pt-PT/listing/title index 31552f353..6c7c64cfc 100644 --- a/app/src/main/play/pt-PT/listing/title +++ b/app/src/main/play/pt-PT/listing/title @@ -1 +1 @@ -AntennaPod
\ No newline at end of file +AntennaPod diff --git a/app/src/main/play/pt/listing/fulldescription b/app/src/main/play/pt/listing/fulldescription deleted file mode 100644 index 58d88eb24..000000000 --- a/app/src/main/play/pt/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -O AntennaPod é um gestor de podcasts que lhe permite aceder a milhões de podcasts, gratuitos ou pagos, a partir de diversas fontes tais como as estações BBC, NPR e CNN. A adição de fontes é muito fácil através das base de dados iTunes ou gPodder, ficheiros OPML ou fontes RSS. Poupe tempo, economize bateria e dados móveis através dos mecanismos de controlo de descargas de episódios (possibilidade de especificar intervalos ou horas para as descargas e redes WiFi) e de eliminação de episódios (de acordo com as suas preferências).<br> -Mas ainda mais importante: pode descarregar, emitir ou colocar episódios na lista de reprodução ao seu gosto, pode utilizar velocidades variáveis de reprodução, tem suporte a capÃtulos e um temporizador. Pode também mostrar o seu apreço aos criadores dos episódios através do serviço Flattr. - -Criado por entusiastas de podcasts, o AntennaPod é livre em todos os sentidos da palavra: open source, gratuito e sem publicidade. - -<b>Funcionalidades:</b><br> -Importação, organização e reprodução<br> -• Adicione e importe fontes existentes nos diretórios iTunes e gPodder.net, ficheiros OPML e ligações ATOM e RSS<br> -• Gestão de podcasts através do widget, barra de notificações e controlos de auriculares ou auscultadores<br> -• Velocidade variável de reprodução, suporte a capÃtulos (MP3, VorbisComment e Podlove), memorização da posição de reprodução e um temporizador avançado (agite para repor, baixar e aumentar o volume)<br> -• Acesso a fontes e episódios protegidos por palavra-passe<br> -• Possibilidade de subscrever fontes paginadas (www.podlove.org/paged-feeds) - -Monitorização, partilha e suporte<br> -• Monitorize os seus podcasts preferidos marcando-os como favoritos<br> -• Localize um episódio através do histórico de reprodução ou através de uma pesquisa (tÃtulos e notas)<br> -• Partilhe episódios e fontes nas redes sociais, por e-mail, no diretório gPodder.net ou através de ficheiros OPML<br> -• Ajude os criadores de conteúdos através do serviço Flattr - -Controlo do sistema<br> -• Controle todas as descargas automáticas: escolha as fontes, exclua redes móveis, especifique as redes Wi-Fi, indique se o telefone deve estar a ser carregado e defina as horas ou intervalos das descargas<br> -• Faça a gestão do armazenamento através da cache de episódios, da eliminação inteligente (de acordo com os seus favoritos e estado de reprodução) e selecionado a localização de armazenamento<br> -• Utilize o AntennaPod no seu idioma (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapte-se ao seu ambiente através dos temas claro ou escuro<br> -• Salvaguarde as suas subscrições com a integração gPodder.net ou através da exportação OPML - -<b>Integre a comunidade do AntennaPod!</b><br> -O AntennaPod é desenvolvido por voluntários. Você também pode contribuir na programação ou reportando os erros encontrados! - -O GitHub é o local certo para os pedidos de funcionalidades, relatórios de erros e contributos:<br> -https://www.github.com/AntennaPod/AntennaPod - -O nosso grupo Google é o local certo para partilhar ideias e agradecer aos nossos voluntários:<br> -https://groups.google.com/forum/#!forum/antennapod - -Tem alguma questão ou comentário a fazer? -https://twitter.com/@AntennaPod - -O Transifex é o local no qual pode ajudar a traduzir a aplicação:<br> -https://www.transifex.com/antennapod/antennapod - -Junte-se ao nosso programa Beta para obter as funcionalidades mais recentes:<br> -https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/pt_BR/listing/fulldescription b/app/src/main/play/pt_BR/listing/fulldescription deleted file mode 100644 index e40d3f450..000000000 --- a/app/src/main/play/pt_BR/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -AntennaPod é um gerenciador e reprodutor de <i>podcasts</i> que te dá acesso instantâneo a milhões de <i>podcasts</i> gratuitos e pagos, desde <i>podcasters</i> independentes até grandes editores como BBC, NPR e CNN. Adicione, importe e exporte seus <i>feeds</i> sem complicações utilizando a base de dados do iTunes, arquivos OPML ou simples URLs RSS. Economize esforços, bateria e uso de dados móveis com poderosos controles de automação para baixar episódios (especifique horários, intervalos e redes WiFi) e excluir episódios (baseado nos seus favoritos e configurações de adiamento).<br> -Mas o mais importante: Baixe, realize <i>streaming</i> ou enfilere episódios e desfrute deles da maneira que quiser com velocidades de reprodução ajustáveis, suporte para capÃtulos e cronômetro. Você pode até mostrar o seu apreço aos criadores de conteúdo com a integração com o Flattr. - -Desenvolvido por fãs de podcasts, AntennaPod é livre em todos os sentidos da palavra; <i>open source</i>, sem custos, sem propagandas. - -<b>Recursos disponÃveis:</b><br> -IMPORTE, ORGANIZE E TOQUE <br> -• Adicione and importe feeds pelo iTunes e diretorios gPodder.net, arquivos OPML e links RSS ou Atom<br> -• Gerencie suas reproduções de qualquer lugar: widget da tela inicial, notificações de sistema e fone de ouvido e controles bluetooth<br> -• Ouça do seu jeito com velocidade de reprodução ajustável, suporte a capÃtulos (MP3, VorbisComment e Podlove), marcador da posição de reprodução e um despertador avançado (chacoalhe para reiniciar, volume reduzido e reprodução desacelerada)<br> -• Acesse feeds e episódios protegidos por senha -• Faça uso de <i>feeds</i> paginados (www.podlove.org/paged-feeds) - -MANTENHA-SE ATUALIZADO, COMPARTILHE E APRECIE<br> -• Guarde o melhor do melhor marcando episódios como favoritos<br> -• Encontre aquele episódio especÃfico através do histórico de execução ou pelo sistema de busca (através de tÃtulos e anotações)<br> -• Compartilhe episódios e <i>feeds</i> através de opções em redes sociais, email, os serviços da gPodder.net e exportação OPML<br> -• Apoie os criadores de conteúdo com a integração com o Flattr - -CONTROLE O SISTEMA -• Tenha controle sobre a automação dos <i>downloads</i>: escolha <i>feeds</i>, exclua redes móveis, selecione redes especÃficas de WiFi, exija que o telefone esteja sendo carregado e defina horários ou intervalos<br> -• Gerencie o armazenamento configurando a quantidade de episódios em cache, exclusão inteligente dos episódios (baseada nos seus favoritos e status de reprodução)<br> -• Use o AntennaPod no seu idioma (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapte-se ao ambiente utilizando os temas claro ou escuro<br> -• Faça <i>backup</i> das suas inscrições com a integração ao gPodder.net e exportação de OPML - -<b>Junte-se à comunidade AntennaPod!</b><br> -O AntennaPod está sob constante desenvolvimento através de voluntários. Você também pode contribuir, com código ou um comentário! - -Vá ao GitHub para solicitar funcionalidades, reportar bugs e contribuir com código:<br> -https://www.github.com/AntennaPod/AntennaPod - -Nosso grupo no Google é o lugar para compartilhar suas idéias, momentos de podcasts favoritos e agradecer aos voluntários:<br> -https://groups.google.com/forum/#!forum/antennapod - -Tem uma dúvida ou um comentário? -https://twitter.com/@AntennaPod - -Transifex é o lugar para ajudar com as traduções:<br> -https://www.transifex.com/antennapod/antennapod - -Cheque nosso programa de beta testing para receber as atualizações mais recentes primeiro:<br> -https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/ro/listing/shortdescription b/app/src/main/play/ro/listing/shortdescription index 4eceefbb7..7afb5a62d 100644 --- a/app/src/main/play/ro/listing/shortdescription +++ b/app/src/main/play/ro/listing/shortdescription @@ -1 +1 @@ -Easy-to-use, flexible and open-source podcast manager and player
\ No newline at end of file +Easy-to-use, flexible and open-source podcast & radio manager and player
\ No newline at end of file diff --git a/app/src/main/play/ro/listing/title b/app/src/main/play/ro/listing/title index 31552f353..6c7c64cfc 100644 --- a/app/src/main/play/ro/listing/title +++ b/app/src/main/play/ro/listing/title @@ -1 +1 @@ -AntennaPod
\ No newline at end of file +AntennaPod diff --git a/app/src/main/play/ro_RO/listing/fulldescription b/app/src/main/play/ro_RO/listing/fulldescription deleted file mode 100644 index 87b477fdc..000000000 --- a/app/src/main/play/ro_RO/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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> -• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -CONTROL THE SYSTEM<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• 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/ru-RU/listing/fulldescription b/app/src/main/play/ru-RU/listing/fulldescription index e3e1635ff..9b68a06c0 100644 --- a/app/src/main/play/ru-RU/listing/fulldescription +++ b/app/src/main/play/ru-RU/listing/fulldescription @@ -1,20 +1,43 @@ -AntennaPod — Ñто open-source менеджер подкаÑтов Ð´Ð»Ñ Android 2.3.3 и выше. Он предлагает вÑе оÑновные функции подкаÑÑ‚-менеджера, такие как воÑпроизведение из Ñети, загрузка выпуÑков, автоматичеÑкое обновление каналов и добавление выпуÑков в очередь. Кроме того, AntennaPod позволÑет Ñовершать Ð¿Ð¾Ð¶ÐµÑ€Ñ‚Ð²Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð´ÐºÐ°ÑÑ‚-каналам, поÑредÑтвом Flattr, прÑмо из приложениÑ. - -Были реализованы Ñледующие возможноÑти: - -* Загрузка и потоковое воÑпроизведение выпуÑков -* Изменение ÑкороÑти воÑÐ¿Ñ€Ð¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ (требует Presto Sound Library или Prestissimo) -* Поддержка каналов в форматах Atom и RSS -* Поддержка защищенных паролем каналов и выпуÑков -* Поддержка поиÑка по каталогу iTunes -* Импорт и ÑкÑпорт OPML -* Ð˜Ð½Ñ‚ÐµÐ³Ñ€Ð°Ñ†Ð¸Ñ Ñ Flattr, Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑкую поддержку через него -* Виджет Ð´Ð»Ñ Ð´Ð¾Ð¼Ð°ÑˆÐ½ÐµÐ³Ð¾ Ñкрана -* ПоиÑк -* ÐвтоматичеÑкое обновление каналов -* ÐвтоматичеÑÐºÐ°Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ° новых выпуÑков -* Таймер Ñна -* ДоÑтуп к каталогу подкаÑтов на gpodder.net -* Ð¡Ð¸Ð½Ñ…Ñ€Ð¾Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñок Ñ ÑервиÑом gpodder.net -* Поддержка Ð¾Ð³Ð»Ð°Ð²Ð»ÐµÐ½Ð¸Ñ MP3, VorbisComment и Podlove Simple Chapters -* Поддержка поÑтраничных лент (http://podlove.org/paged-feeds/)
\ No newline at end of file +AntennaPod — менеджер и проигрыватель подкаÑтов, который обеÑпечит Ð’Ð°Ñ Ð¼Ð³Ð½Ð¾Ð²ÐµÐ½Ð½Ñ‹Ð¼ доÑтупом к миллионам беÑплатных и платных подкаÑтов, как от незавиÑимых подкаÑтеров, так и крупных издательÑких домов, например, BBC, NPR и CNN. С лёгкоÑтью добавлÑйте, импортируйте и ÑкÑпортируйте их каналы иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³ подкаÑтов iTunes, файлы OPML или адреÑа каналов RSS. Сберегите уÑилиÑ, зарÑд батареи и мобильный трафик при помощи мощных ÑредÑтв автоматизации загрузки выпуÑков (фильтрациÑ, указание времени и интервалов, а также Ñетей WiFi) и их ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ (в ÑоответÑтвии Ñ Ð½Ð°Ñтройками избранного и ожиданиÑ).<br> +Ðо Ñамое главное: Загружайте, Ñлушайте Ñ Ñфира или Ñтавьте в очередь и получайте удовольÑтвие от их проÑÐ»ÑƒÑˆÐ¸Ð²Ð°Ð½Ð¸Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½ÑÑ Ñ€ÐµÐ³ÑƒÐ»Ð¸Ñ€ÑƒÐµÐ¼ÑƒÑŽ ÑкороÑÑ‚ÑŒ воÑпроизведениÑ, Ð¾Ð³Ð»Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸ таймер Ñна. Ð’Ñ‹ даже можете выразить Ñвою благодарноÑÑ‚ÑŒ ÑоздателÑм аудио поÑредÑтвом интеграции Ñ Flattr. + +Созданное поклонниками подкаÑтов, AntennaPod — беÑплатное и Ñвободное приложение без рекламы и платежей. + +<b>Ð’Ñе возможноÑти:</b><br> +Импортируйте, ÑиÑтематизируйте и проÑлушивайте<br> +• Добавление и импорт каналов через каталоги iTunes и gPodder.net, файлы OPML и ÑÑылки на каналы RSS или Atom<br> +• Ð’Ñевозможное управление воÑпроизведением: виджетом, ÑиÑтемным уведомлением и кнопками проводных и беÑпроводных гарнитур<br> +• ПриÑтное, по вашему вкуÑу, проÑлушивание применÑÑ Ñ€ÐµÐ³ÑƒÐ»Ð¸Ñ€Ð¾Ð²ÐºÑƒ ÑкороÑти воÑпроизведениÑ, Ð¾Ð³Ð»Ð°Ð²Ð»ÐµÐ½Ð¸Ñ (MP3, VorbisComment и Podlove), запоминание меÑта воÑÐ¿Ñ€Ð¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¸ продвинутый таймер Ñна (ÑÐ±Ñ€Ð¾Ñ Ð¿Ñ€Ð¸ вÑÑ‚Ñ€Ñхивание, Ñнижение громкоÑти и замедление воÑпроизведениÑ)<br> +• ДоÑтуп к каналам и выпуÑкам защищенным паролем<br> +• ИÑпользует преимущеÑтва поÑтраничных лент (www.podlove.org/paged-feeds) + +ОтÑлеживайте, делитеÑÑŒ и благодарите<br> +• ОтÑлеживайте лучших из лучших, Ð¿Ð¾Ð¼ÐµÑ‰Ð°Ñ Ð²Ñ‹Ð¿ÑƒÑки в избранное<br> +• ПоиÑк того Ñамого выпуÑка в иÑтории воÑÐ¿Ñ€Ð¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ по контекÑту (заголовки и заметки к выпуÑку)<br> +• Разнообразные возможноÑти поделитьÑÑ Ð²Ñ‹Ð¿ÑƒÑками и каналами через Ñоциальные Ñлужбы и e-mail, уÑлуги gPodder.net и ÑкÑпорт в OPML<br> +• Поддержка Ñоздателей аудио при помощи интеграции Ñ Flattr, в том чиÑле и автоматичеÑки + +УправлÑйте ÑиÑтемой<br> +• Управление автоматичеÑкой загрузкой: выбор отдельных каналов, отбор выпуÑков на оÑнове ключевых Ñлов, запрет на иÑпользование мобильных Ñетей, выбор отдельных точек доÑтупа WiFi, только во Ð²Ñ€ÐµÐ¼Ñ Ð·Ð°Ñ€Ñдки телефона и задание времени и интервалов<br> +• Управление хранением путём Ð·Ð°Ð´Ð°Ð½Ð¸Ñ ÐºÐ¾Ð»Ð¸Ñ‡ÐµÑтва выпуÑков в кÑше, автоудаление (на оÑновании наÑтроек избранного и ÑтатуÑа проÑлушиваниÑ) и выбор предпочитаемого раÑположениÑ<br> +• AntennaPod на родном Вам Ñзыке (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH, RU)<br> +• ПриÑпоÑабливаетÑÑ Ðº Вашему окружению поÑредÑтвом Ñветлой или тёмной темы<br> +• Резервирование Ваших подпиÑок путём интеграции Ñ gPodder.net и Ñкпорта в OPML + +<b>ПриÑоединÑйтеÑÑŒ к ÑообщеÑтву AntennaPod!</b><br> +AntennaPod поÑтоÑнно развиваетÑÑ Ñилами добровольцев. Ð’Ñ‹ тоже можете Ñделать Ñвой вклад при помощи кода или комментариÑ! + +ПоÑещайте GitHub Ð´Ð»Ñ Ð·Ð°Ð¿Ñ€Ð¾Ñа новых возможноÑтей, ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¾Ð± ошибках и внеÑÐµÐ½Ð¸Ñ ÐºÐ¾Ð´Ð°:<br> +https://www.github.com/AntennaPod/AntennaPod + +ПоделитеÑÑŒ идеÑми, любимыми мгновениÑми проÑÐ»ÑƒÑˆÐ¸Ð²Ð°Ð½Ð¸Ñ Ð¸ благодарноÑтью Ñо вÑеми добровольцами из нашей группы Google:<br> +https://groups.google.com/forum/#!forum/antennapod + +ПоÑвилиÑÑŒ вопроÑÑ‹ и Ð¾Ð±Ñ€Ð°Ñ‚Ð½Ð°Ñ ÑвÑзь? +https://twitter.com/@AntennaPod + +Помогайте Ñ Ð¿ÐµÑ€ÐµÐ²Ð¾Ð´Ð¾Ð¼ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð½Ð° Transifex:<br> +https://www.transifex.com/antennapod/antennapod + +Попробуйте ÑÐµÐ±Ñ Ð² программе Бета теÑÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸ получите доÑтуп к раÑпоÑледним возможноÑÑ‚Ñм в чиÑле первых:<br> +https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/ru-RU/listing/title b/app/src/main/play/ru-RU/listing/title index 31552f353..6c7c64cfc 100644 --- a/app/src/main/play/ru-RU/listing/title +++ b/app/src/main/play/ru-RU/listing/title @@ -1 +1 @@ -AntennaPod
\ No newline at end of file +AntennaPod diff --git a/app/src/main/play/ru_RU/listing/fulldescription b/app/src/main/play/ru_RU/listing/fulldescription deleted file mode 100644 index 9b68a06c0..000000000 --- a/app/src/main/play/ru_RU/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -AntennaPod — менеджер и проигрыватель подкаÑтов, который обеÑпечит Ð’Ð°Ñ Ð¼Ð³Ð½Ð¾Ð²ÐµÐ½Ð½Ñ‹Ð¼ доÑтупом к миллионам беÑплатных и платных подкаÑтов, как от незавиÑимых подкаÑтеров, так и крупных издательÑких домов, например, BBC, NPR и CNN. С лёгкоÑтью добавлÑйте, импортируйте и ÑкÑпортируйте их каналы иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³ подкаÑтов iTunes, файлы OPML или адреÑа каналов RSS. Сберегите уÑилиÑ, зарÑд батареи и мобильный трафик при помощи мощных ÑредÑтв автоматизации загрузки выпуÑков (фильтрациÑ, указание времени и интервалов, а также Ñетей WiFi) и их ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ (в ÑоответÑтвии Ñ Ð½Ð°Ñтройками избранного и ожиданиÑ).<br> -Ðо Ñамое главное: Загружайте, Ñлушайте Ñ Ñфира или Ñтавьте в очередь и получайте удовольÑтвие от их проÑÐ»ÑƒÑˆÐ¸Ð²Ð°Ð½Ð¸Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½ÑÑ Ñ€ÐµÐ³ÑƒÐ»Ð¸Ñ€ÑƒÐµÐ¼ÑƒÑŽ ÑкороÑÑ‚ÑŒ воÑпроизведениÑ, Ð¾Ð³Ð»Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸ таймер Ñна. Ð’Ñ‹ даже можете выразить Ñвою благодарноÑÑ‚ÑŒ ÑоздателÑм аудио поÑредÑтвом интеграции Ñ Flattr. - -Созданное поклонниками подкаÑтов, AntennaPod — беÑплатное и Ñвободное приложение без рекламы и платежей. - -<b>Ð’Ñе возможноÑти:</b><br> -Импортируйте, ÑиÑтематизируйте и проÑлушивайте<br> -• Добавление и импорт каналов через каталоги iTunes и gPodder.net, файлы OPML и ÑÑылки на каналы RSS или Atom<br> -• Ð’Ñевозможное управление воÑпроизведением: виджетом, ÑиÑтемным уведомлением и кнопками проводных и беÑпроводных гарнитур<br> -• ПриÑтное, по вашему вкуÑу, проÑлушивание применÑÑ Ñ€ÐµÐ³ÑƒÐ»Ð¸Ñ€Ð¾Ð²ÐºÑƒ ÑкороÑти воÑпроизведениÑ, Ð¾Ð³Ð»Ð°Ð²Ð»ÐµÐ½Ð¸Ñ (MP3, VorbisComment и Podlove), запоминание меÑта воÑÐ¿Ñ€Ð¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¸ продвинутый таймер Ñна (ÑÐ±Ñ€Ð¾Ñ Ð¿Ñ€Ð¸ вÑÑ‚Ñ€Ñхивание, Ñнижение громкоÑти и замедление воÑпроизведениÑ)<br> -• ДоÑтуп к каналам и выпуÑкам защищенным паролем<br> -• ИÑпользует преимущеÑтва поÑтраничных лент (www.podlove.org/paged-feeds) - -ОтÑлеживайте, делитеÑÑŒ и благодарите<br> -• ОтÑлеживайте лучших из лучших, Ð¿Ð¾Ð¼ÐµÑ‰Ð°Ñ Ð²Ñ‹Ð¿ÑƒÑки в избранное<br> -• ПоиÑк того Ñамого выпуÑка в иÑтории воÑÐ¿Ñ€Ð¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ по контекÑту (заголовки и заметки к выпуÑку)<br> -• Разнообразные возможноÑти поделитьÑÑ Ð²Ñ‹Ð¿ÑƒÑками и каналами через Ñоциальные Ñлужбы и e-mail, уÑлуги gPodder.net и ÑкÑпорт в OPML<br> -• Поддержка Ñоздателей аудио при помощи интеграции Ñ Flattr, в том чиÑле и автоматичеÑки - -УправлÑйте ÑиÑтемой<br> -• Управление автоматичеÑкой загрузкой: выбор отдельных каналов, отбор выпуÑков на оÑнове ключевых Ñлов, запрет на иÑпользование мобильных Ñетей, выбор отдельных точек доÑтупа WiFi, только во Ð²Ñ€ÐµÐ¼Ñ Ð·Ð°Ñ€Ñдки телефона и задание времени и интервалов<br> -• Управление хранением путём Ð·Ð°Ð´Ð°Ð½Ð¸Ñ ÐºÐ¾Ð»Ð¸Ñ‡ÐµÑтва выпуÑков в кÑше, автоудаление (на оÑновании наÑтроек избранного и ÑтатуÑа проÑлушиваниÑ) и выбор предпочитаемого раÑположениÑ<br> -• AntennaPod на родном Вам Ñзыке (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH, RU)<br> -• ПриÑпоÑабливаетÑÑ Ðº Вашему окружению поÑредÑтвом Ñветлой или тёмной темы<br> -• Резервирование Ваших подпиÑок путём интеграции Ñ gPodder.net и Ñкпорта в OPML - -<b>ПриÑоединÑйтеÑÑŒ к ÑообщеÑтву AntennaPod!</b><br> -AntennaPod поÑтоÑнно развиваетÑÑ Ñилами добровольцев. Ð’Ñ‹ тоже можете Ñделать Ñвой вклад при помощи кода или комментариÑ! - -ПоÑещайте GitHub Ð´Ð»Ñ Ð·Ð°Ð¿Ñ€Ð¾Ñа новых возможноÑтей, ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¾Ð± ошибках и внеÑÐµÐ½Ð¸Ñ ÐºÐ¾Ð´Ð°:<br> -https://www.github.com/AntennaPod/AntennaPod - -ПоделитеÑÑŒ идеÑми, любимыми мгновениÑми проÑÐ»ÑƒÑˆÐ¸Ð²Ð°Ð½Ð¸Ñ Ð¸ благодарноÑтью Ñо вÑеми добровольцами из нашей группы Google:<br> -https://groups.google.com/forum/#!forum/antennapod - -ПоÑвилиÑÑŒ вопроÑÑ‹ и Ð¾Ð±Ñ€Ð°Ñ‚Ð½Ð°Ñ ÑвÑзь? -https://twitter.com/@AntennaPod - -Помогайте Ñ Ð¿ÐµÑ€ÐµÐ²Ð¾Ð´Ð¾Ð¼ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð½Ð° Transifex:<br> -https://www.transifex.com/antennapod/antennapod - -Попробуйте ÑÐµÐ±Ñ Ð² программе Бета теÑÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸ получите доÑтуп к раÑпоÑледним возможноÑÑ‚Ñм в чиÑле первых:<br> -https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/sl_SI/listing/fulldescription b/app/src/main/play/sl_SI/listing/fulldescription deleted file mode 100644 index 87b477fdc..000000000 --- a/app/src/main/play/sl_SI/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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> -• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -CONTROL THE SYSTEM<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• 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/sv-SE/listing/fulldescription b/app/src/main/play/sv-SE/listing/fulldescription index bdf641cf2..84b7d9681 100644 --- a/app/src/main/play/sv-SE/listing/fulldescription +++ b/app/src/main/play/sv-SE/listing/fulldescription @@ -12,14 +12,14 @@ IMPORTERA, ORGANISERA OCH SPELA<br> • Dra nytta av siduppdelade flöden (www.podlove.ord/paged-feeds) SPÃ…RA, DELA & UPPSKATTA<br> -• SpÃ¥ra det bästa av det bästa med favoritmarkering av episoder<br> +• HÃ¥ll ordning pÃ¥ de bästa av de bästa med favoritmarkering av episoder<br> • Hitta just den där episoden i uppspelningshistoriken eller genom sökning (titel och shownotes)<br> • Dela episoder och flöden med avancerade vald för social media och och email, tjänsten gPodder.net och via OPML export<br> • Stöd innehÃ¥llsskaparna via integrering av Flattr och automatisk flattring KONTROLLERA SYSTEMET<br> -• Ta kontroll över automatisk nedladdning: välj flöden, exkludera mobilnätverk, välj specifika WiFi nätver, kräv att telefonen är inkopplad för laddning och sätt tider eller intervall<br> -• Hantera lagringsutrymme genom att välja antalet cachade episoder, smart borttagning (baserat pÃ¥ dina favoriter och uppspelningsstatus) och välj den plats du föredrar<br> +• Ta kontroll över automatisk nedladdning: välj flöden, exkludera mobilnätverk, välj specifika WiFi nätverk, kräv att telefonen är inkopplad för laddning och sätt tider eller intervall för körning<br> +• Hantera lagringsutrymme genom att välja antalet cachade episoder, smart borttagning (baserat pÃ¥ dina favoriter och uppspelningsstatus) och välj den lagringsplats du föredrar<br> • Använd AntennaPod pÃ¥ ditt sprÃ¥k (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> • Anpassa till din omgivning med det ljusa och mörka temat<br> • Ta backup av dina prenumerationer med integreringen av gPodder.net och OPML exportering @@ -28,13 +28,16 @@ KONTROLLERA SYSTEMET<br> AntennaPod är under aktiv utveckling av volontärer. Du kan ocksÃ¥ bidra, med kod eller kommentarer! GitHub är platsen att gÃ¥ till för att be om funktioner, skapa buggrapporter eller bidra med kod:<br> -www.github.com/AntennaPod/AntennaPod +https://www.github.com/AntennaPod/AntennaPod VÃ¥r Google Group är platsen för att dela idéer, dina favoritögonblick med podcasting och din uppskattning till volontärerna:<br> https://groups.google.com/forum/#!forum/antennapod +Har du frÃ¥gor eller vill ge feedback? +https://twitter.com/@AntennaPod + Transifex är platsen att gÃ¥ till för att hjälpa till med översättningen:<br> -www.transifex.com/antennapod/antennapod +https://www.transifex.com/antennapod/antennapod Kolla in vÃ¥rat Beta Testing program för att fÃ¥ de senaste funktionerna först:<br> -www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file +https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/sv-SE/listing/title b/app/src/main/play/sv-SE/listing/title index 31552f353..6c7c64cfc 100644 --- a/app/src/main/play/sv-SE/listing/title +++ b/app/src/main/play/sv-SE/listing/title @@ -1 +1 @@ -AntennaPod
\ No newline at end of file +AntennaPod diff --git a/app/src/main/play/sv_SE/listing/fulldescription b/app/src/main/play/sv_SE/listing/fulldescription deleted file mode 100644 index 84b7d9681..000000000 --- a/app/src/main/play/sv_SE/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -AntennaPod är en podcasthanterare och spelare som ger dig omedelbar tillgÃ¥ng till millioner av gratis och betalda podcasts, allt ifrÃ¥n oberoende podcasters till publiceringsjättar som BBC, NPR och CNN. Lägg till, importera och exportera enkelt deras flöden med hjälp av iTunes podcastdatabas, OPML filer eller enkla RSS URL:er. Spara tid, batterikraft och mobildata med kraftfull automatisering för nedladdning (specifiera tider, intervall och WiFi-nätverk) och borttagning av episoder (baserat pÃ¥ dina favoriter och fördröjningsinställningar).<br> -Men viktigast: Ladda ner, strömma eller köa episoder och avnjut dem pÃ¥ ditt sätt med justerbar uppspelningshastighet, kapitelstöd och en sovtimer. Du kan till och med visa din uppskattning av innehÃ¥llsskaparna med vÃ¥r integrering av Flattr. - -Gjord av podcastenthusiaster, AntennaPod är fri i alla ordets bemärkelser: öppen källkod, inga kostnader, ingen reklam. - -<b>Alla funktioner:</b><br> -IMPORTERA, ORGANISERA OCH SPELA<br> -• Lägg till och importera flöden via iTunes och gPodder.net, OPML filer och RSS eller Atom länkar<br> -• Hantera uppspelningen frÃ¥n vartsomhelst: hemskärmswidget, aviseringsfältet och hörlurs/bluetoth-kontroller<br> -• Njut av att lyssna pÃ¥ ditt sätt med justerbar uppspelningshastighet, kapitelstöd (MP4, VorbisComment och Podlove), ihÃ¥gkommen uppspelningsposition och en avancerad sömntimer (skaka för Ã¥terställaning, sänk volymen och sänk hastigheten)<br> -• Kom Ã¥t lösenordsskyddade flöden och episoder<br> -• Dra nytta av siduppdelade flöden (www.podlove.ord/paged-feeds) - -SPÃ…RA, DELA & UPPSKATTA<br> -• HÃ¥ll ordning pÃ¥ de bästa av de bästa med favoritmarkering av episoder<br> -• Hitta just den där episoden i uppspelningshistoriken eller genom sökning (titel och shownotes)<br> -• Dela episoder och flöden med avancerade vald för social media och och email, tjänsten gPodder.net och via OPML export<br> -• Stöd innehÃ¥llsskaparna via integrering av Flattr och automatisk flattring - -KONTROLLERA SYSTEMET<br> -• Ta kontroll över automatisk nedladdning: välj flöden, exkludera mobilnätverk, välj specifika WiFi nätverk, kräv att telefonen är inkopplad för laddning och sätt tider eller intervall för körning<br> -• Hantera lagringsutrymme genom att välja antalet cachade episoder, smart borttagning (baserat pÃ¥ dina favoriter och uppspelningsstatus) och välj den lagringsplats du föredrar<br> -• Använd AntennaPod pÃ¥ ditt sprÃ¥k (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Anpassa till din omgivning med det ljusa och mörka temat<br> -• Ta backup av dina prenumerationer med integreringen av gPodder.net och OPML exportering - -<b>GÃ¥ med i AntennaPods gemenskap!</b><br> -AntennaPod är under aktiv utveckling av volontärer. Du kan ocksÃ¥ bidra, med kod eller kommentarer! - -GitHub är platsen att gÃ¥ till för att be om funktioner, skapa buggrapporter eller bidra med kod:<br> -https://www.github.com/AntennaPod/AntennaPod - -VÃ¥r Google Group är platsen för att dela idéer, dina favoritögonblick med podcasting och din uppskattning till volontärerna:<br> -https://groups.google.com/forum/#!forum/antennapod - -Har du frÃ¥gor eller vill ge feedback? -https://twitter.com/@AntennaPod - -Transifex är platsen att gÃ¥ till för att hjälpa till med översättningen:<br> -https://www.transifex.com/antennapod/antennapod - -Kolla in vÃ¥rat Beta Testing program för att fÃ¥ de senaste funktionerna först:<br> -https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/sw_KE/listing/fulldescription b/app/src/main/play/sw_KE/listing/fulldescription deleted file mode 100644 index 87b477fdc..000000000 --- a/app/src/main/play/sw_KE/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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> -• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -CONTROL THE SYSTEM<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• 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 deleted file mode 100644 index 87b477fdc..000000000 --- a/app/src/main/play/te/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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> -• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -CONTROL THE SYSTEM<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• 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/tr-TR/listing/fulldescription b/app/src/main/play/tr-TR/listing/fulldescription index 7ea4d906d..90bda48af 100644 --- a/app/src/main/play/tr-TR/listing/fulldescription +++ b/app/src/main/play/tr-TR/listing/fulldescription @@ -1,20 +1,43 @@ -AntennaPod, Android 2.3.3 ve üzeri için açık kaynak kodlu cepyayını yöneticisidir. Bölümleri yayınlama ve indirme, beslemelerin otomatik olarak yenilenmesi veya daha sonra dinlemek için sıraya konması gibi bir cepyayını yakalayıcısından beklediğiniz tüm temel özellikleri içerir. Hatta cepyayınlarını ve bölümleri uygulama içinden flattr aracılığıyla desteklemenize olanak verir. - -Şimdiye kadar aşağıdaki özellikler eklenmiştir: - -* Bölümlerin indirilmesi ve yayınlanması -* Değişken çalma hızı (Presto Sound Library veya Prestissimo gerekir) -* Atom ve RSS besleme desteği -* Şifre korumalı besleme ve bölüm desteği -* iTunes listelerinde arama yapma desteği -* OPML içe aktarma ve dışa aktarma -* Otomatik flatter içeren Flattr entegrasyonu -* Ev ekranı oynatıcı widget'ı -* Arama -* Otomatik besleme güncellemeleri -* Yeni bölümlerin otomatik indirilmesi -*Uyku zamanlayıcı -* gpodder.net cepyayını dizinine erişim -* gpodder.net servisi ile üyelik senkronizasyonu -* MP3 kısımları, VorbisComment kısımlar ve Podlove Simple Chapter desteği -* Sayfalanmış beslemeler desteği (http://podlove.org/paged-feeds/)
\ No newline at end of file +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>Tüm özellikler:</b><br> +IMPORT, ORGANIZE AND PLAY<br> +• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> +• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> +• 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> +• Access password-protected feeds and episodes<br> +• Take advantage of paged feeds (www.podlove.org/paged-feeds) + +KEEP TRACK, SHARE & APPRECIATE<br> +• Keep track of the best of the best by marking episodes as favourites<br> +• Find that one episode through the playback history or by searching (titles and shownotes)<br> +• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> +• Support content creators with Flattr integration including automatic flattring + +SÄ°STEMÄ° KONTROL ET<br> +• 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> +• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> +• AntennaPod'u kendi dilinizde kullanın (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> +• Adapt to your environment using the light and dark theme<br> +• Back-up your subscriptions with the gPodder.net integration and OPML export + +<b>AntennaPod topluluÄŸuna katılın!</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 + +Bir sorunuz mu var veya bize geri bildirim bırakmak mı istiyorsunuz? +https://twitter.com/@AntennaPod + +Tercümelere yardım etmenin yeri Transifex:<br> +https://www.transifex.com/antennapod/antennapod + +En son özellikleri ilk önce almak isterseniz Beta Testing programımıza katılın:<br> +https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/tr-TR/listing/title b/app/src/main/play/tr-TR/listing/title index 31552f353..6c7c64cfc 100644 --- a/app/src/main/play/tr-TR/listing/title +++ b/app/src/main/play/tr-TR/listing/title @@ -1 +1 @@ -AntennaPod
\ No newline at end of file +AntennaPod diff --git a/app/src/main/play/tr/listing/fulldescription b/app/src/main/play/tr/listing/fulldescription deleted file mode 100644 index 90bda48af..000000000 --- a/app/src/main/play/tr/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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>Tüm özellikler:</b><br> -IMPORT, ORGANIZE AND PLAY<br> -• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -SÄ°STEMÄ° KONTROL ET<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• AntennaPod'u kendi dilinizde kullanın (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• Back-up your subscriptions with the gPodder.net integration and OPML export - -<b>AntennaPod topluluÄŸuna katılın!</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 - -Bir sorunuz mu var veya bize geri bildirim bırakmak mı istiyorsunuz? -https://twitter.com/@AntennaPod - -Tercümelere yardım etmenin yeri Transifex:<br> -https://www.transifex.com/antennapod/antennapod - -En son özellikleri ilk önce almak isterseniz Beta Testing programımıza katılın:<br> -https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/uk/listing/shortdescription b/app/src/main/play/uk/listing/shortdescription index ac638de72..a5636500d 100644 --- a/app/src/main/play/uk/listing/shortdescription +++ b/app/src/main/play/uk/listing/shortdescription @@ -1 +1 @@ -Менеджер подкаÑтів Ð´Ð»Ñ Android з відкритими вихідними текÑтами.
\ No newline at end of file +Легкий у викориÑтанні, гнучкий плеєр Ñ– менеджер подкаÑтів з відкритим кодом.
\ No newline at end of file diff --git a/app/src/main/play/uk/listing/title b/app/src/main/play/uk/listing/title index 31552f353..6c7c64cfc 100644 --- a/app/src/main/play/uk/listing/title +++ b/app/src/main/play/uk/listing/title @@ -1 +1 @@ -AntennaPod
\ No newline at end of file +AntennaPod diff --git a/app/src/main/play/uk_UA/listing/fulldescription b/app/src/main/play/uk_UA/listing/fulldescription deleted file mode 100644 index ae8ac2c20..000000000 --- a/app/src/main/play/uk_UA/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -AntennaPod це менеджер подкаÑтів та плейер що дає доÑтуп до мільйонів безкоштовних та комерційних подкаÑтів від незалежних подкаÑтерів та великих корпорацій таких Ñк BBC, NPR та CNN. Є можливіÑÑ‚ÑŒ додавати, імпортувати та екÑпортувати канали за допомогою бази даних подкаÑтів iTunes, файлів OPML або проÑтих поÑилань на RSS. Зберігайте зуÑиллÑ, Ð¶Ð¸Ð²Ð»ÐµÐ½Ð½Ñ Ñ‚Ð° мобільний трафік за допомогою автоматичного Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ ÐµÐ¿Ñ–Ð·Ð¾Ð´Ñ–Ð² (зазначивши чаÑ, інтервали та мережі WiFi) та Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ ÐµÐ¿Ñ–Ð·Ð¾Ð´Ñ–Ð² (з урахуваннÑм ваших побажань та налаштувань).<br> -Ðле найважливіше: завантажуйте, Ñлухайте або додавайте до черги епізоди так, Ñк вам подобаєтьÑÑ Ð· налаштуваннÑм швидкоÑÑ‚Ñ– програваннÑ, підтримкою розділів та таймера Ñну. Можливо навіть фінанÑово заохочувати авторів за допомогою інтергації з ÑервіÑом Flattr. - -Зроблений ентузіаÑтом подкаÑтів, AntennaPod Ñ” вільним в уÑÑ–Ñ… ÑенÑах цього Ñлова: відкриті вихідні текÑти, безкоштовний, без реклами. - -<b>Ð’ÑÑ– можливоÑÑ‚Ñ–:</b><br> -ІМПОРТУЙТЕ, ВПОРЯДКОВУЙТЕ ТРСЛУХÐЙТЕ<br> -• Додавайте та імпортуйте канали з каталогів iTunes та gPodder.net, файлів OPML та з поÑилань на RSS або Atom<br> -• Керуйте програваннÑм будь-де: з віджета, нотифікації, кнопками навушників або через блютуÑ<br> -• Слухайте так Ñк вам подобаєтьÑÑ Ð· налаштуваннÑм швидкоÑÑ‚Ñ– програваннÑ, підтримкой розділів (в форматах MP3, VorbisComment та Podlove), зберіганнÑм момента Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð²Ð°Ð½Ð½Ñ Ñ‚Ð° таймером Ñну (перезапуÑк ÑтруÑом, Ð·Ð½Ð¸Ð¶ÐµÐ½Ð½Ñ Ð³ÑƒÑ‡Ð½Ð¾ÑÑ‚Ñ– та ÑƒÐ¿Ð¾Ð²Ñ–Ð»ÑŒÐ½ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð²Ð°Ð½Ð½Ñ)<br> -• ДоÑтуп до каналів та епізодів що захищені паролем<br> -• ВикориÑтовуйте поÑторінкові канали (www.podlove.org/paged-feeds) - -ВІДСТЕЖУЙТЕ, ДІЛІТЬСЯ ТРОЦІÐЮЙТЕ<br> -• Зберігайте найкраще в улюблених епізодах<br> -• Відшукайте той Ñамий епізод в Ñ–Ñторії Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð²Ð°Ð½Ð½Ñ Ð°Ð±Ð¾ пошуком (в назвах Ñ– нотатках)<br> -• ДілітьÑÑ ÐµÐ¿Ñ–Ð·Ð¾Ð´Ð°Ð¼Ð¸ та каналами за допомогою Ñоцмереж та пошти, ÑервіÑів gPodder.net та через екÑпорт OPML файлів<br> -• Підтримуйте авторів за допомогою інтегрованого ÑервіÑа Flattr з можливіÑÑ‚ÑŽ автоматичной підтримки - -КЕРУЙТЕ СИСТЕМОЙ<br> -• Керуйте автоматичним завантаженнÑм: вибирайте канали, мобільні мережі, мережі WiFi, завантажуйте тільки під Ñ‡Ð°Ñ Ð·Ð°Ñ€Ñдки або у вÑтановлений Ñ‡Ð°Ñ Ñ– інтервали<br> -• Керуйте збереженнÑм, вÑтановлюйте ліміт на кеш епізодів, налагоджуйте розумне Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ (з урахуваннÑм улюблених епізодів Ñ– ÑтатуÑа програваннÑ) та вибирайте міÑце зберіганнÑ<br> -• КориÑтуйтеÑÑŒ AntennaPod вашою мовою (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• ПриÑтоÑовуйтеÑÑŒ до ваших умов, кориÑтуйтеÑÑŒ Ñвітлой або темной темами<br> -• Зберігайте ваші підпиÑки на gPodder.net або екÑпортуйте в файл OPML - -<b>ДолучайтеÑÑŒ до Ñпільноти AntennaPod!</b><br> -AntennaPod швидко розвиваєтьÑÑ Ð²Ð¾Ð»Ð¾Ð½Ñ‚ÐµÑ€Ð°Ð¼Ð¸. Ви також маєте змогу допомогти, кодом або зауваженнÑми! - -ДолучитиÑÑŒ до проекта, повідомити про ваші Ð¿Ð¾Ð±Ð°Ð¶Ð°Ð½Ð½Ñ Ñ‚Ð° про помилки можна на GitHub:<br> -https://www.github.com/AntennaPod/AntennaPod - -Ð’ нашій групі на Google можна поділитиÑÑŒ ідеÑми, улюбленими моментами з подкаÑтінга та добрими побажаннÑми волонтерам:<br> -https://groups.google.com/forum/#!forum/antennapod - -Маєте Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð°Ð±Ð¾ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ð½Ð°Ñ? -https://twitter.com/@AntennaPod - -Допомагайте з перекладом на Transifex:<br> -https://www.transifex.com/antennapod/antennapod - -Зверніть увагу на нашу програму Ð´Ð»Ñ Ð±ÐµÑ‚Ð° теÑÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñкщо бажаєте получати найновіші верÑÑ–Ñ— в першу чергу:<br> -https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
\ No newline at end of file diff --git a/app/src/main/play/vi/listing/fulldescription b/app/src/main/play/vi/listing/fulldescription index 87b477fdc..9519b5da1 100644 --- a/app/src/main/play/vi/listing/fulldescription +++ b/app/src/main/play/vi/listing/fulldescription @@ -3,7 +3,7 @@ But most importantly: Download, stream or queue episodes and enjoy them the way Made by podcast-enthousiast, AntennaPod is free in all senses of the word: open source, no costs, no ads. -<b>All features:</b><br> +Má»i tÃnh năng: IMPORT, ORGANIZE AND PLAY<br> • Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> • Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> @@ -17,14 +17,14 @@ KEEP TRACK, SHARE & APPRECIATE<br> • Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> • Support content creators with Flattr integration including automatic flattring -CONTROL THE SYSTEM<br> +ÄIỀU KHIỂN HỆ THá»NG • 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> • Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> • Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> • Adapt to your environment using the light and dark theme<br> • Back-up your subscriptions with the gPodder.net integration and OPML export -<b>Join the AntennaPod community!</b><br> +Tham gia cá»™ng đồng AntennaPod! 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> @@ -33,7 +33,7 @@ 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? +Có má»™t thắc mắc hay muốn phản hồi cho chúng tôi? https://twitter.com/@AntennaPod Transifex is the place to help with translations:<br> diff --git a/app/src/main/play/vi/listing/shortdescription b/app/src/main/play/vi/listing/shortdescription new file mode 100644 index 000000000..7afb5a62d --- /dev/null +++ b/app/src/main/play/vi/listing/shortdescription @@ -0,0 +1 @@ +Easy-to-use, flexible and open-source podcast & radio manager and player
\ No newline at end of file diff --git a/app/src/main/play/vi/listing/title b/app/src/main/play/vi/listing/title new file mode 100644 index 000000000..6c7c64cfc --- /dev/null +++ b/app/src/main/play/vi/listing/title @@ -0,0 +1 @@ +AntennaPod diff --git a/app/src/main/play/vi_VN/listing/fulldescription b/app/src/main/play/vi_VN/listing/fulldescription deleted file mode 100644 index 87b477fdc..000000000 --- a/app/src/main/play/vi_VN/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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> -• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -CONTROL THE SYSTEM<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• 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-CN/listing/fulldescription b/app/src/main/play/zh-CN/listing/fulldescription index 932b5ba3a..6f2a6209e 100644 --- a/app/src/main/play/zh-CN/listing/fulldescription +++ b/app/src/main/play/zh-CN/listing/fulldescription @@ -1,20 +1,43 @@ -AntennaPod 是一款开æºæ’客管ç†è½¯ä»¶, æä¾› Android 2.3.3 åŠä»¥ä¸Šå¹³å°è¿è¡Œ. 它æä¾›äº†æ‰€æœ‰ä½ æ‰€æœŸæœ›çš„æ’客基本功能, 例如在线æµåª’体和下载收å¬æ›²ç›®, 以åŠè‡ªåŠ¨åˆ·æ–°æ‰€æœ‰è®¢é˜…å’Œæ·»åŠ åˆ°æ’放列表. æ¤å¤–, AntennaPod 支æŒåº”用内 Flattr æ’客和节目表. - -So far the following features are implemented: - -* 在线æµåª’体和下载收å¬æ›²ç›® -* å˜é€Ÿæ’放 (éœ€è¦ Presto 声音库或者 Prestissimo) -* æ”¯æŒ Atom å’Œ RSS 订阅 -* 支æŒåŠ 密的订阅 -* Support for searching iTunes listings -* OPML 文件导入导出 -* Flattr integration including automatic flattring -* æ’放器主å±å¹•çª—å£å°éƒ¨ä»¶ (Widget) -* æœç´¢ -* 自动订阅更新 -* 自动下载新曲目 -* ç¡çœ 计时器 -* 访问 gpodder.net æ’客目录 -* åŒæ¥ gpodder.net 订阅æœåŠ¡ -* Supports MP3 chapters, VorbisComment chapters and Podlove Simple Chapters -* Supports paged feeds (http://podlove.org/paged-feeds/)
\ No newline at end of file +AntennaPod 是æ’客管ç†å’Œæ’æ”¾å·¥å…·ï¼Œä½¿å¾—ä½ å³åˆ»æ”¶å¬åˆ°æ•°ç™¾ä¸‡æ¥è‡ªä»Žä¸ªäººæ’客制作者到类似BBCã€NPRå’ŒCNNç‰å¤§åž‹å‡ºç‰ˆæœºæž„çš„å…费或付费æ’客。通过 iTunes æ•°æ®åº“ã€OPML 文件或简å•çš„ RSS 地å€ï¼Œä½ å¯ä»¥è‡ªç”±åœ°æ·»åŠ ã€å¯¼å…¥å’Œå¯¼å‡ºæ’客订阅æµã€‚通过指定次数ã€é—´éš”时间和 WIFI 网络的下载以åŠåŸºäºŽä¸ªäººå–œå¥½å’Œå»¶è¿Ÿåˆ 除的设置,功能强大的智能控制åšåˆ°äº†çœåŠ›ã€çœç”µå’Œçœæµé‡ã€‚<br> +但最é‡è¦çš„åœ¨äºŽï¼Œä½ å¯ä»¥é€‰æ‹©ä¸‹è½½ã€ä¸²æµæˆ–åŠ å…¥é˜Ÿåˆ—ç‰æ–¹å¼æ”¶å¬èŠ‚目,并使用调节回放速度ã€ç« 节跳转和定时ç¡çœ çš„è¾…åŠ©åŠŸèƒ½ã€‚ä½ ç”šè‡³å¯ä»¥é€šè¿‡ Flattr 集æˆåŠŸèƒ½å‘å†…å®¹åˆ›ä½œè€…è¡¨è¾¾ä½ è¡·å¿ƒçš„æ„Ÿè°¢ã€‚ + +AntennaPod 是一个由æ’客爱好者开å‘,在多ç§æ„义下“自由â€çš„软件——开æºã€å…费并且没有广告。 + +<b>特性包括:</b><br> +导入,组织和æ’放<br> +• 通过 iTunes,gPodder.net,OPML文件,RSS或Atomé“¾æŽ¥æ·»åŠ å’Œå¯¼å…¥è®¢é˜… +• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> +• 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> +• Access password-protected feeds and episodes<br> +• Take advantage of paged feeds (www.podlove.org/paged-feeds) + +KEEP TRACK, SHARE & APPRECIATE<br> +• Keep track of the best of the best by marking episodes as favourites<br> +• Find that one episode through the playback history or by searching (titles and shownotes)<br> +• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> +• Support content creators with Flattr integration including automatic flattring + +CONTROL THE SYSTEM<br> +• 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> +• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> +• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> +• Adapt to your environment using the light and dark theme<br> +• 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-CN/listing/title b/app/src/main/play/zh-CN/listing/title index 31552f353..6c7c64cfc 100644 --- a/app/src/main/play/zh-CN/listing/title +++ b/app/src/main/play/zh-CN/listing/title @@ -1 +1 @@ -AntennaPod
\ No newline at end of file +AntennaPod diff --git a/app/src/main/play/zh/listing/fulldescription b/app/src/main/play/zh/listing/fulldescription deleted file mode 100644 index 87b477fdc..000000000 --- a/app/src/main/play/zh/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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> -• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -CONTROL THE SYSTEM<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• 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_CN/listing/fulldescription b/app/src/main/play/zh_CN/listing/fulldescription deleted file mode 100644 index 6f2a6209e..000000000 --- a/app/src/main/play/zh_CN/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -AntennaPod 是æ’客管ç†å’Œæ’æ”¾å·¥å…·ï¼Œä½¿å¾—ä½ å³åˆ»æ”¶å¬åˆ°æ•°ç™¾ä¸‡æ¥è‡ªä»Žä¸ªäººæ’客制作者到类似BBCã€NPRå’ŒCNNç‰å¤§åž‹å‡ºç‰ˆæœºæž„çš„å…费或付费æ’客。通过 iTunes æ•°æ®åº“ã€OPML 文件或简å•çš„ RSS 地å€ï¼Œä½ å¯ä»¥è‡ªç”±åœ°æ·»åŠ ã€å¯¼å…¥å’Œå¯¼å‡ºæ’客订阅æµã€‚通过指定次数ã€é—´éš”时间和 WIFI 网络的下载以åŠåŸºäºŽä¸ªäººå–œå¥½å’Œå»¶è¿Ÿåˆ 除的设置,功能强大的智能控制åšåˆ°äº†çœåŠ›ã€çœç”µå’Œçœæµé‡ã€‚<br> -但最é‡è¦çš„åœ¨äºŽï¼Œä½ å¯ä»¥é€‰æ‹©ä¸‹è½½ã€ä¸²æµæˆ–åŠ å…¥é˜Ÿåˆ—ç‰æ–¹å¼æ”¶å¬èŠ‚目,并使用调节回放速度ã€ç« 节跳转和定时ç¡çœ çš„è¾…åŠ©åŠŸèƒ½ã€‚ä½ ç”šè‡³å¯ä»¥é€šè¿‡ Flattr 集æˆåŠŸèƒ½å‘å†…å®¹åˆ›ä½œè€…è¡¨è¾¾ä½ è¡·å¿ƒçš„æ„Ÿè°¢ã€‚ - -AntennaPod 是一个由æ’客爱好者开å‘,在多ç§æ„义下“自由â€çš„软件——开æºã€å…费并且没有广告。 - -<b>特性包括:</b><br> -导入,组织和æ’放<br> -• 通过 iTunes,gPodder.net,OPML文件,RSS或Atomé“¾æŽ¥æ·»åŠ å’Œå¯¼å…¥è®¢é˜… -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -CONTROL THE SYSTEM<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• 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_HK/listing/fulldescription b/app/src/main/play/zh_HK/listing/fulldescription deleted file mode 100644 index 87b477fdc..000000000 --- a/app/src/main/play/zh_HK/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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> -• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -CONTROL THE SYSTEM<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• 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 deleted file mode 100644 index 87b477fdc..000000000 --- a/app/src/main/play/zh_TW/listing/fulldescription +++ /dev/null @@ -1,43 +0,0 @@ -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> -• Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br> -• Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br> -• 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> -• Access password-protected feeds and episodes<br> -• Take advantage of paged feeds (www.podlove.org/paged-feeds) - -KEEP TRACK, SHARE & APPRECIATE<br> -• Keep track of the best of the best by marking episodes as favourites<br> -• Find that one episode through the playback history or by searching (titles and shownotes)<br> -• Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br> -• Support content creators with Flattr integration including automatic flattring - -CONTROL THE SYSTEM<br> -• 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> -• Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br> -• Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br> -• Adapt to your environment using the light and dark theme<br> -• 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/all_episodes_fragment.xml b/app/src/main/res/layout/all_episodes_fragment.xml index 5336fb8ce..099216007 100644 --- a/app/src/main/res/layout/all_episodes_fragment.xml +++ b/app/src/main/res/layout/all_episodes_fragment.xml @@ -10,10 +10,16 @@ android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="match_parent" - android:scrollbarStyle="outsideOverlay" + android:clipToPadding="false" android:paddingTop="@dimen/list_vertical_padding" android:paddingBottom="@dimen/list_vertical_padding" - android:clipToPadding="false"/> + android:scrollbarStyle="outsideOverlay" + tools:itemCount="13" + tools:listitem="@layout/new_episodes_listitem" /> + + <include + android:id="@+id/emptyView" + layout="@layout/empty_view_layout"/> <ProgressBar android:id="@+id/progLoading" @@ -22,7 +28,7 @@ android:layout_gravity="center" android:indeterminateOnly="true" android:visibility="gone" - tools:visibility="visible" + tools:visibility="gone" tools:layout_width="match_parent" tools:layout_height="64dp" tools:background="@android:color/holo_red_light"/> diff --git a/app/src/main/res/layout/audio_controls.xml b/app/src/main/res/layout/audio_controls.xml index 852b6e922..090aec47f 100644 --- a/app/src/main/res/layout/audio_controls.xml +++ b/app/src/main/res/layout/audio_controls.xml @@ -21,6 +21,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="16dp" + android:layout_marginStart="16dp" android:text="1.00x"/> </LinearLayout> @@ -35,6 +36,7 @@ android:layout_width="32dp" android:layout_height="32dp" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:gravity="center" android:text="-" android:textStyle="bold" @@ -48,6 +50,7 @@ android:layout_height="32dp" android:minWidth="0dp" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:gravity="center" android:text="+" android:textStyle="bold" @@ -60,12 +63,21 @@ android:layout_width="match_parent" android:layout_height="32dp" android:layout_toRightOf="@id/butDecSpeed" + android:layout_toEndOf="@id/butDecSpeed" android:layout_toLeftOf="@id/butIncSpeed" + android:layout_toStartOf="@id/butIncSpeed" android:layout_centerVertical="true" android:max="40"/> </RelativeLayout> + <CheckBox + android:id="@+id/skipSilence" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="4dp" + android:text="@string/pref_skip_silence_title" /> + <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" @@ -79,6 +91,7 @@ android:layout_height="wrap_content" android:layout_marginTop="-12dp" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" android:orientation="horizontal" android:gravity="center"> @@ -101,6 +114,7 @@ android:layout_height="wrap_content" android:layout_marginTop="8dp" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" android:orientation="horizontal" android:gravity="center"> diff --git a/app/src/main/res/layout/authentication_dialog.xml b/app/src/main/res/layout/authentication_dialog.xml index 00e74c9e1..187045c63 100644 --- a/app/src/main/res/layout/authentication_dialog.xml +++ b/app/src/main/res/layout/authentication_dialog.xml @@ -67,8 +67,10 @@ android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_toLeftOf="@id/horizontal_divider" + android:layout_toStartOf="@id/horizontal_divider" android:background="?android:attr/selectableItemBackground" android:text="@string/cancel_label" /> @@ -78,8 +80,10 @@ android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_alignParentTop="true" android:layout_toRightOf="@id/horizontal_divider" + android:layout_toEndOf="@id/horizontal_divider" android:background="?android:attr/selectableItemBackground" android:text="@string/confirm_label" /> </RelativeLayout> diff --git a/app/src/main/res/layout/directory_chooser.xml b/app/src/main/res/layout/directory_chooser.xml index 14e2f6a38..5b9269607 100644 --- a/app/src/main/res/layout/directory_chooser.xml +++ b/app/src/main/res/layout/directory_chooser.xml @@ -33,8 +33,10 @@ android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_toLeftOf="@id/horizontal_divider" + android:layout_toStartOf="@id/horizontal_divider" android:background="?android:attr/selectableItemBackground" android:text="@string/cancel_label" /> @@ -44,8 +46,10 @@ android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_alignParentTop="true" android:layout_toRightOf="@id/horizontal_divider" + android:layout_toEndOf="@id/horizontal_divider" android:background="?android:attr/selectableItemBackground" android:text="@string/confirm_label" /> </RelativeLayout> @@ -62,6 +66,7 @@ android:layout_width="60dp" android:layout_height="60dp" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:background="?attr/selectableItemBackground" android:src="?attr/navigation_up" @@ -77,6 +82,7 @@ android:layout_marginRight="8dp" android:layout_marginTop="8dp" android:layout_toRightOf="@id/butNavUp" + android:layout_toEndOf="@id/butNavUp" android:text="@string/selected_folder_label" android:textStyle="bold" tools:background="@android:color/holo_green_dark"> @@ -87,9 +93,11 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_below="@id/txtvSelectedFolderLabel" android:layout_margin="8dp" android:layout_toRightOf="@id/butNavUp" + android:layout_toEndOf="@id/butNavUp" android:ellipsize="start" android:scrollHorizontally="true" android:singleLine="true" diff --git a/app/src/main/res/layout/download_authentication_activity.xml b/app/src/main/res/layout/download_authentication_activity.xml index f6925dc3a..3414a5e00 100644 --- a/app/src/main/res/layout/download_authentication_activity.xml +++ b/app/src/main/res/layout/download_authentication_activity.xml @@ -77,8 +77,10 @@ android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_toLeftOf="@id/horizontal_divider" + android:layout_toStartOf="@id/horizontal_divider" android:background="?android:attr/selectableItemBackground" android:text="@string/cancel_label"/> @@ -88,8 +90,10 @@ android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_alignParentTop="true" android:layout_toRightOf="@id/horizontal_divider" + android:layout_toEndOf="@id/horizontal_divider" android:background="?android:attr/selectableItemBackground" android:text="@string/confirm_label"/> </RelativeLayout> diff --git a/app/src/main/res/layout/downloaded_episodeslist_item.xml b/app/src/main/res/layout/downloaded_episodeslist_item.xml index 770b88c7e..65a08251f 100644 --- a/app/src/main/res/layout/downloaded_episodeslist_item.xml +++ b/app/src/main/res/layout/downloaded_episodeslist_item.xml @@ -13,6 +13,7 @@ android:layout_gravity="center_vertical" android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding" android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding" + android:layout_marginStart="@dimen/listitem_threeline_horizontalpadding" android:layout_marginTop="@dimen/listitem_threeline_verticalpadding" android:contentDescription="@string/cover_label" android:scaleType="centerCrop" @@ -24,7 +25,9 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/listitem_threeline_textleftpadding" + android:layout_marginStart="@dimen/listitem_threeline_textleftpadding" android:layout_marginRight="@dimen/listitem_threeline_textrightpadding" + android:layout_marginEnd="@dimen/listitem_threeline_textrightpadding" android:layout_marginTop="@dimen/listitem_threeline_verticalpadding" android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding" android:layout_weight="1" @@ -74,6 +77,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" tools:text="Jan 23" tools:background="@android:color/holo_green_dark"/> @@ -88,7 +92,7 @@ android:layout_height="match_parent" android:background="?attr/selectableItemBackground" android:clickable="false" - android:contentDescription="@string/remove_episode_lable" + android:contentDescription="@string/delete_episode_label" android:focusable="false" android:focusableInTouchMode="false" android:src="?attr/content_discard" diff --git a/app/src/main/res/layout/downloadlist_item.xml b/app/src/main/res/layout/downloadlist_item.xml index 97f3ac1a1..668ec817a 100644 --- a/app/src/main/res/layout/downloadlist_item.xml +++ b/app/src/main/res/layout/downloadlist_item.xml @@ -17,6 +17,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding" + android:layout_marginStart="@dimen/listitem_threeline_horizontalpadding" android:layout_marginTop="@dimen/listitem_threeline_verticalpadding" android:ellipsize="end" android:lines="1" @@ -48,6 +49,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:ellipsize="end" android:lines="1" android:textColor="?android:attr/textColorPrimary" @@ -60,6 +62,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:ellipsize="end" android:lines="1" android:textColor="?android:attr/textColorPrimary" diff --git a/app/src/main/res/layout/downloadlog_item.xml b/app/src/main/res/layout/downloadlog_item.xml index 712dda63e..505102ea4 100644 --- a/app/src/main/res/layout/downloadlog_item.xml +++ b/app/src/main/res/layout/downloadlog_item.xml @@ -17,6 +17,7 @@ android:layout_height="48sp" android:layout_alignParentTop="true" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:textSize="48sp" android:gravity="center" /> @@ -26,7 +27,9 @@ android:layout_height="wrap_content" android:layout_below="@id/txtvIcon" android:layout_alignLeft="@id/txtvIcon" + android:layout_alignStart="@id/txtvIcon" android:layout_alignRight="@id/txtvIcon" + android:layout_alignEnd="@id/txtvIcon" android:layout_marginTop="8dp" android:text="{fa-repeat}" tools:text="↻" /> @@ -38,7 +41,9 @@ android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" android:layout_marginBottom="8dp" tools:text="Media file" tools:background="@android:color/holo_green_dark" /> @@ -50,8 +55,11 @@ android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_toRightOf="@id/txtvIcon" + android:layout_toEndOf="@id/txtvIcon" android:layout_toLeftOf="@id/txtvType" + android:layout_toStartOf="@id/txtvType" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" android:layout_marginBottom="8dp" android:minLines="1" android:maxLines="2" @@ -64,8 +72,10 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/txtvIcon" + android:layout_toEndOf="@id/txtvIcon" android:layout_below="@id/txtvTitle" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" android:layout_marginBottom="8dp" tools:text="January 23" tools:background="@android:color/holo_green_dark" /> @@ -76,7 +86,9 @@ android:layout_height="wrap_content" android:layout_below="@id/txtvDate" android:layout_toRightOf="@id/txtvIcon" + android:layout_toEndOf="@id/txtvIcon" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" android:textColor="?android:attr/textColorTertiary" android:textSize="@dimen/text_size_micro" tools:text="@string/design_time_downloaded_log_failure_reason" diff --git a/app/src/main/res/layout/ellipsize_start_listitem.xml b/app/src/main/res/layout/ellipsize_start_listitem.xml index 4a70ff982..1b6c48152 100644 --- a/app/src/main/res/layout/ellipsize_start_listitem.xml +++ b/app/src/main/res/layout/ellipsize_start_listitem.xml @@ -1,22 +1,22 @@ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - android:orientation="vertical" - android:layout_width="match_parent" - android:layout_height="match_parent" - tools:background="@android:color/darker_gray"> + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + tools:background="@android:color/darker_gray"> <TextView android:id="@+id/txtvTitle" - android:textColor="?android:attr/textColorPrimary" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textSize="@dimen/text_size_small" - android:singleLine="true" android:layout_margin="16dp" android:ellipsize="start" - tools:text="List item title" - tools:background="@android:color/holo_green_dark"/> + android:singleLine="true" + android:textColor="?android:attr/textColorPrimary" + android:textSize="@dimen/text_size_small" + tools:background="@android:color/holo_green_dark" + tools:text="List item title" /> </LinearLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/empty_view_layout.xml b/app/src/main/res/layout/empty_view_layout.xml new file mode 100644 index 000000000..051773e51 --- /dev/null +++ b/app/src/main/res/layout/empty_view_layout.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:gravity="center"
+ xmlns:tools="http://schemas.android.com/tools">
+
+ <TextView
+ android:id="@+id/emptyViewTitle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingLeft="10dp"
+ android:paddingRight="10dp"
+ tools:text="empty"
+ android:textSize="20sp"
+ android:textStyle="bold"
+ android:paddingBottom="10dp"/>
+
+ <TextView
+ android:id="@+id/emptyViewMessage"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="15sp"
+ tools:text="empty"
+ android:paddingLeft="15dp"
+ android:paddingRight="15dp"
+ android:textAlignment="center"/>
+
+</LinearLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/episodes_apply_action_fragment.xml b/app/src/main/res/layout/episodes_apply_action_fragment.xml index e9a2e2e23..984e960d8 100644 --- a/app/src/main/res/layout/episodes_apply_action_fragment.xml +++ b/app/src/main/res/layout/episodes_apply_action_fragment.xml @@ -1,115 +1,50 @@ <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + 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"> - - <LinearLayout - android:id="@+id/bottomBar" - android:layout_width="match_parent" - android:layout_height="68dp" - android:layout_alignParentBottom="true" - android:gravity="center_vertical" - android:orientation="horizontal" - android:padding="4dp"> - - <Button - android:id="@+id/btnAddToQueue" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_weight="1" - android:background="@android:color/transparent" - android:drawableTop="?attr/content_new" - android:text="@string/add_to_queue_label" - android:textSize="10sp" /> - - <View - android:id="@+id/divider1" - android:layout_width="1dp" - android:layout_height="match_parent" - android:layout_margin="4dp" - android:background="?android:attr/listDivider" - tools:background="@android:color/holo_red_dark" /> - - <Button - android:id="@+id/btnMarkAsPlayed" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_weight="1" - android:background="@android:color/transparent" - android:drawableTop="?attr/navigation_accept" - android:text="@string/mark_read_label" - android:textSize="10sp" /> - - <View - android:id="@+id/divider2" - android:layout_width="1dp" - android:layout_height="match_parent" - android:layout_margin="4dp" - android:background="?android:attr/listDivider" - tools:background="@android:color/holo_red_dark" /> - - <Button - android:id="@+id/btnMarkAsUnplayed" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_weight="1" - android:background="@android:color/transparent" - android:drawableTop="?attr/navigation_cancel" - android:text="@string/mark_unread_label" - android:textSize="10sp" /> - - <View - android:id="@+id/divider3" - android:layout_width="1dp" - android:layout_height="match_parent" - android:layout_margin="4dp" - android:background="?android:attr/listDivider" - tools:background="@android:color/holo_red_dark" /> - - <Button - android:id="@+id/btnDownload" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_weight="1" - android:background="@android:color/transparent" - android:drawableTop="?attr/av_download" - android:text="@string/download_label" - android:textSize="10sp" /> - - <View - android:id="@+id/divider4" - android:layout_width="1dp" - android:layout_height="match_parent" - android:layout_margin="4dp" - android:background="?android:attr/listDivider" - tools:background="@android:color/holo_red_dark" /> - - <Button - android:id="@+id/btnDelete" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_weight="1" - android:background="@android:color/transparent" - android:drawableTop="?attr/content_discard" - android:text="@string/remove_episode_lable" - android:textSize="10sp" /> - - </LinearLayout> - - <View - android:id="@+id/divider" - android:layout_width="match_parent" - android:layout_height="1dp" - android:layout_above="@id/bottomBar" - android:background="?android:attr/listDivider" - android:paddingBottom="4dp" - tools:background="@android:color/holo_red_dark" /> - <ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_above="@id/divider"/> + android:layout_alignParentTop="true" + android:layout_marginTop="0dp" /> + + <com.leinardi.android.speeddial.SpeedDialOverlayLayout + android:id="@+id/fabSDOverlay" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + <!-- The FAB SpeedDial + 1. MUST be placed at the bottom of the layout xml to ensure it is at the front, + clickable on Pre-Lollipop devices (that do not support elevation). + See: https://stackoverflow.com/a/2614402 + 2. ScrollView is needed to ensure the vertical list of speed dials are + accessible when screen height is small, eg., landscape mode on most phones. + --> + <ScrollView + android:id="@+id/fabSDScrollCtr" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentBottom="true" + android:layout_alignParentEnd="true" + android:layout_alignParentRight="true" + android:elevation="@dimen/sd_close_elevation" + tools:ignore="UnusedAttribute"> + <!-- android:elevation: + 1. Needs to match the speed dial's minimal elevation, + or the speed dial can't be clicked at all + --> + <com.leinardi.android.speeddial.SpeedDialView + android:id="@+id/fabSD" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:sdMainFabClosedSrc="@drawable/ic_fab_edit" + app:sdOverlayLayout="@id/fabSDOverlay" + android:layout_marginEnd="16dp" + android:layout_marginRight="16dp" + android:layout_marginBottom="16dp" + /> + </ScrollView> </RelativeLayout> diff --git a/app/src/main/res/layout/feedinfo.xml b/app/src/main/res/layout/feedinfo.xml index bb544d289..50061c4d8 100644 --- a/app/src/main/res/layout/feedinfo.xml +++ b/app/src/main/res/layout/feedinfo.xml @@ -36,7 +36,9 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:layout_marginBottom="8dp" app:layout_row="0" app:layout_column="0" @@ -60,6 +62,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:layout_marginBottom="8dp" app:layout_row="1" app:layout_column="0" @@ -83,6 +86,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" app:layout_row="2" app:layout_column="0" android:lines="1" diff --git a/app/src/main/res/layout/feeditem_fragment.xml b/app/src/main/res/layout/feeditem_fragment.xml index a6ce221db..78c0b3b16 100644 --- a/app/src/main/res/layout/feeditem_fragment.xml +++ b/app/src/main/res/layout/feeditem_fragment.xml @@ -32,6 +32,7 @@ android:layout_width="50dp" android:layout_height="50dp" android:layout_marginRight="16dp" + android:layout_marginEnd="16dp" android:layout_marginBottom="16dp" android:contentDescription="@string/cover_label" android:gravity="center_vertical" @@ -45,6 +46,7 @@ android:layout_height="wrap_content" android:layout_alignTop="@id/imgvCover" android:layout_toRightOf="@id/imgvCover" + android:layout_toEndOf="@id/imgvCover" tools:text="Podcast title" tools:background="@android:color/holo_green_dark" /> @@ -54,6 +56,7 @@ android:layout_height="wrap_content" android:layout_below="@id/txtvPodcast" android:layout_toRightOf="@id/imgvCover" + android:layout_toEndOf="@id/imgvCover" android:textSize="16sp" android:textColor="?android:attr/textColorPrimary" android:ellipsize="end" @@ -67,6 +70,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/imgvCover" + android:layout_toEndOf="@id/imgvCover" android:layout_below="@id/txtvTitle" tools:text="00:42:23" tools:background="@android:color/holo_green_dark"/> @@ -77,8 +81,10 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_below="@id/txtvTitle" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" tools:text="Jan 23" tools:background="@android:color/holo_green_dark" /> @@ -98,7 +104,9 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="16dp" + android:layout_marginStart="16dp" android:layout_marginRight="16dp" + android:layout_marginEnd="16dp" android:orientation="horizontal" tools:background="@android:color/holo_blue_bright"> @@ -108,6 +116,7 @@ android:layout_height="48dp" android:layout_gravity="center_vertical" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:layout_weight="1" android:background="?attr/selectableItemBackground" android:ellipsize="end" @@ -123,6 +132,7 @@ android:layout_height="48dp" android:layout_gravity="center_vertical" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" android:layout_weight="1" android:background="?attr/selectableItemBackground" android:ellipsize="end" diff --git a/app/src/main/res/layout/feeditemlist_header.xml b/app/src/main/res/layout/feeditemlist_header.xml index 1478e35d7..e1f451e9e 100644 --- a/app/src/main/res/layout/feeditemlist_header.xml +++ b/app/src/main/res/layout/feeditemlist_header.xml @@ -19,10 +19,12 @@ android:layout_width="@dimen/thumbnail_length_onlinefeedview" android:layout_height="@dimen/thumbnail_length_onlinefeedview" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_centerVertical="true" android:layout_marginBottom="16dp" android:layout_marginLeft="16dp" + android:layout_marginStart="16dp" android:layout_marginTop="16dp" android:contentDescription="@string/cover_label" tools:src="@drawable/ic_stat_antenna_default" @@ -33,8 +35,10 @@ android:layout_width="40dp" android:layout_height="40dp" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_alignParentTop="true" android:layout_marginLeft="16dp" + android:layout_marginStart="16dp" android:layout_marginTop="8dp" android:background="?attr/selectableItemBackground" android:contentDescription="@string/show_info_label" @@ -62,9 +66,12 @@ android:layout_alignParentTop="true" android:layout_marginBottom="16dp" android:layout_marginLeft="16dp" + android:layout_marginStart="16dp" android:layout_marginTop="16dp" android:layout_toLeftOf="@id/butShowInfo" + android:layout_toStartOf="@id/butShowInfo" android:layout_toRightOf="@id/imgvCover" + android:layout_toEndOf="@id/imgvCover" android:ellipsize="end" android:maxLines="2" android:shadowColor="@color/black" @@ -80,8 +87,13 @@ android:layout_below="@id/txtvTitle" android:layout_marginBottom="16dp" android:layout_marginLeft="16dp" + android:layout_marginStart="16dp" + android:layout_marginRight="16dp" + android:layout_marginEnd="16dp" android:layout_toLeftOf="@id/butShowSettings" + android:layout_toStartOf="@id/butShowSettings" android:layout_toRightOf="@id/imgvCover" + android:layout_toEndOf="@id/imgvCover" android:ellipsize="end" android:lines="1" android:shadowColor="@color/black" diff --git a/app/src/main/res/layout/feeditemlist_item.xml b/app/src/main/res/layout/feeditemlist_item.xml index 5a2f091ec..adf0748eb 100644 --- a/app/src/main/res/layout/feeditemlist_item.xml +++ b/app/src/main/res/layout/feeditemlist_item.xml @@ -13,6 +13,7 @@ android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding" + android:layout_marginStart="@dimen/listitem_threeline_horizontalpadding" android:layout_weight="1" android:layout_marginTop="@dimen/listitem_threeline_verticalpadding" android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding" @@ -24,6 +25,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_alignParentTop="true" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" @@ -36,9 +38,11 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_marginBottom="4dp" android:layout_toLeftOf="@id/statusUnread" + android:layout_toStartOf="@id/statusUnread" tools:text="Episode title" tools:background="@android:color/holo_green_dark" /> @@ -48,6 +52,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_below="@id/txtvItemname" tools:text="00:42:23" tools:background="@android:color/holo_green_dark" /> @@ -57,8 +62,10 @@ android:layout_width="@dimen/enc_icons_size" android:layout_height="@dimen/enc_icons_size" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_below="@id/txtvItemname" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:contentDescription="@string/in_queue_label" android:src="?attr/stat_playlist" android:visibility="visible" @@ -71,7 +78,9 @@ android:layout_height="@dimen/enc_icons_size" android:layout_below="@id/txtvItemname" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:layout_toLeftOf="@id/imgvInPlaylist" + android:layout_toStartOf="@id/imgvInPlaylist" tools:ignore="ContentDescription" tools:src="@drawable/ic_hearing_white_18dp" tools:background="@android:color/holo_red_light" /> @@ -83,7 +92,9 @@ android:layout_height="wrap_content" android:layout_below="@id/txtvItemname" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:layout_toLeftOf="@id/imgvType" + android:layout_toStartOf="@id/imgvType" tools:text="Jan 23" tools:background="@android:color/holo_green_dark" /> @@ -92,16 +103,18 @@ style="?android:attr/progressBarStyleHorizontal" android:layout_width="0dp" android:layout_height="wrap_content" + android:layout_alignBottom="@id/txtvPublished" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" + android:layout_toStartOf="@id/txtvPublished" android:layout_toLeftOf="@id/txtvPublished" + android:layout_toEndOf="@id/txtvLenSize" android:layout_toRightOf="@id/txtvLenSize" - android:layout_alignTop="@id/txtvPublished" - android:layout_alignBottom="@id/txtvPublished" - tools:background="@android:color/holo_blue_light" + android:layoutDirection="ltr" + android:indeterminate="false" android:max="100" android:progress="42" - android:indeterminate="false" /> + tools:background="@android:color/holo_blue_light" /> </RelativeLayout> diff --git a/app/src/main/res/layout/feedsettings.xml b/app/src/main/res/layout/feedsettings.xml index 23d116d4c..9e5f2245b 100644 --- a/app/src/main/res/layout/feedsettings.xml +++ b/app/src/main/res/layout/feedsettings.xml @@ -39,7 +39,8 @@ app:layout_row="0" app:layout_column="0" app:layout_gravity="center_vertical" - android:layout_marginRight="10dp" /> + android:layout_marginRight="10dp" + android:layout_marginEnd="10dp" /> <Spinner android:layout_width="wrap_content" @@ -97,6 +98,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:layout_marginBottom="8dp" app:layout_row="0" app:layout_column="0" @@ -119,6 +121,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:layout_marginBottom="8dp" app:layout_row="1" app:layout_column="0" diff --git a/app/src/main/res/layout/gpodnet_podcast_listitem.xml b/app/src/main/res/layout/gpodnet_podcast_listitem.xml index bbe8e65d6..27a8bbdca 100644 --- a/app/src/main/res/layout/gpodnet_podcast_listitem.xml +++ b/app/src/main/res/layout/gpodnet_podcast_listitem.xml @@ -15,8 +15,10 @@ android:layout_width="@dimen/thumbnail_length_itemlist" android:layout_height="@dimen/thumbnail_length_itemlist" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:adjustViewBounds="true" android:contentDescription="@string/cover_label" android:cropToPadding="true" @@ -30,6 +32,7 @@ android:layout_height="wrap_content" android:layout_alignTop="@id/txtvTitle" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:orientation="horizontal"> <ImageView @@ -37,6 +40,7 @@ android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_marginRight="-4dp" + android:layout_marginEnd="-4dp" android:src="?attr/feed" /> <TextView @@ -56,7 +60,9 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/imgvCover" + android:layout_toEndOf="@id/imgvCover" android:layout_toLeftOf="@id/subscribers_container" + android:layout_toStartOf="@id/subscribers_container" android:layout_alignTop="@id/imgvCover" android:maxLines="2" android:includeFontPadding="false" @@ -69,6 +75,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_toRightOf="@id/imgvCover" + android:layout_toEndOf="@id/imgvCover" android:layout_below="@id/txtvTitle" android:textSize="14sp" android:textColor="?android:attr/textColorSecondary" diff --git a/app/src/main/res/layout/gpodnet_tag_listitem.xml b/app/src/main/res/layout/gpodnet_tag_listitem.xml index 9e545e59d..a377f9ba1 100644 --- a/app/src/main/res/layout/gpodnet_tag_listitem.xml +++ b/app/src/main/res/layout/gpodnet_tag_listitem.xml @@ -13,6 +13,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding" + android:layout_marginStart="@dimen/listitem_threeline_horizontalpadding" android:layout_marginTop="@dimen/listitem_threeline_verticalpadding" android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding" android:lines="1" @@ -25,7 +26,9 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_marginRight="@dimen/listitem_threeline_horizontalpadding" + android:layout_marginEnd="@dimen/listitem_threeline_horizontalpadding" android:layout_marginTop="@dimen/listitem_threeline_verticalpadding" android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding" tools:text="301" diff --git a/app/src/main/res/layout/gpodnetauth_credentials.xml b/app/src/main/res/layout/gpodnetauth_credentials.xml index a290b682b..f995ae4cc 100644 --- a/app/src/main/res/layout/gpodnetauth_credentials.xml +++ b/app/src/main/res/layout/gpodnetauth_credentials.xml @@ -59,6 +59,7 @@ android:layout_height="wrap_content" android:layout_below="@id/etxtPassword" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:text="@string/gpodnetauth_login_butLabel" android:layout_margin="8dp"/> @@ -68,7 +69,9 @@ android:layout_height="wrap_content" android:layout_below="@id/etxtPassword" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_toLeftOf="@id/butLogin" + android:layout_toStartOf="@id/butLogin" android:textColor="@color/download_failed_red" android:textSize="@dimen/text_size_small" android:maxLines="2" @@ -84,7 +87,8 @@ android:layout_height="wrap_content" android:visibility="gone" android:layout_alignTop="@+id/butLogin" - android:layout_toLeftOf="@+id/butLogin"/> + android:layout_toLeftOf="@+id/butLogin" + android:layout_toStartOf="@+id/butLogin"/> <TextView android:layout_width="match_parent" diff --git a/app/src/main/res/layout/gpodnetauth_device.xml b/app/src/main/res/layout/gpodnetauth_device.xml index 38455f02c..5840fe955 100644 --- a/app/src/main/res/layout/gpodnetauth_device.xml +++ b/app/src/main/res/layout/gpodnetauth_device.xml @@ -41,7 +41,8 @@ android:textColor="?android:attr/textColorSecondary" android:layout_margin="8dp" android:layout_alignTop="@+id/etxtDeviceID" - android:layout_alignLeft="@+id/etxtCaption"/> + android:layout_alignLeft="@+id/etxtCaption" + android:layout_alignStart="@+id/etxtCaption"/> <EditText android:id="@+id/etxtDeviceID" @@ -49,7 +50,9 @@ android:layout_height="wrap_content" android:layout_below="@id/etxtCaption" android:layout_toRightOf="@id/txtvDeviceID" + android:layout_toEndOf="@id/txtvDeviceID" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_margin="8dp"/> <Button @@ -58,6 +61,7 @@ android:layout_height="wrap_content" android:layout_margin="8dp" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_below="@id/etxtDeviceID" android:text="@string/gpodnetauth_device_butCreateNewDevice"/> @@ -66,8 +70,10 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_below="@id/etxtDeviceID" android:layout_toLeftOf="@id/butCreateNewDevice" + android:layout_toStartOf="@id/butCreateNewDevice" android:textColor="@color/download_failed_red" android:layout_margin="16dp" android:textSize="@dimen/text_size_small" @@ -80,6 +86,7 @@ android:layout_height="wrap_content" android:layout_alignTop="@id/butCreateNewDevice" android:layout_toLeftOf="@id/butCreateNewDevice" + android:layout_toStartOf="@id/butCreateNewDevice" android:textColor="@color/download_failed_red" android:textSize="@dimen/text_size_medium" android:visibility="gone" @@ -102,7 +109,9 @@ android:text="@string/gpodnetauth_device_butChoose" android:layout_below="@+id/spinnerChooseDevice" android:layout_alignLeft="@+id/butCreateNewDevice" - android:layout_alignRight="@+id/butCreateNewDevice"/> + android:layout_alignStart="@+id/butCreateNewDevice" + android:layout_alignRight="@+id/butCreateNewDevice" + android:layout_alignEnd="@+id/butCreateNewDevice"/> <Spinner android:id="@+id/spinnerChooseDevice" @@ -110,7 +119,9 @@ android:layout_height="wrap_content" android:layout_below="@id/txtvChooseExistingDevice" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_margin="8dp" - android:layout_alignParentRight="true"/> + android:layout_alignParentRight="true" + android:layout_alignParentEnd="true"/> </RelativeLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/itemdescription_listitem.xml b/app/src/main/res/layout/itemdescription_listitem.xml index 51bc9a5eb..9d03e30a3 100644 --- a/app/src/main/res/layout/itemdescription_listitem.xml +++ b/app/src/main/res/layout/itemdescription_listitem.xml @@ -17,8 +17,10 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_alignParentTop="true" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" android:textSize="14sp" android:textColor="?android:textColorSecondary" android:ellipsize="end" @@ -31,8 +33,10 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_toLeftOf="@id/txtvPubDate" + android:layout_toStartOf="@id/txtvPubDate" android:textSize="16sp" android:textColor="?android:attr/textColorPrimary" android:ellipsize="end" diff --git a/app/src/main/res/layout/itunes_podcast_listitem.xml b/app/src/main/res/layout/itunes_podcast_listitem.xml index 1e6e5a836..4848563b1 100644 --- a/app/src/main/res/layout/itunes_podcast_listitem.xml +++ b/app/src/main/res/layout/itunes_podcast_listitem.xml @@ -16,8 +16,10 @@ android:layout_width="@dimen/thumbnail_length_itemlist" android:layout_height="@dimen/thumbnail_length_itemlist" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:adjustViewBounds="true" android:contentDescription="@string/cover_label" android:cropToPadding="true" @@ -29,6 +31,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_toRightOf="@id/imgvCover" + android:layout_toEndOf="@id/imgvCover" android:layout_centerVertical="true" android:orientation="vertical"> diff --git a/app/src/main/res/layout/mediaplayerinfo_activity.xml b/app/src/main/res/layout/mediaplayerinfo_activity.xml index 21c4940b5..c9e93e149 100644 --- a/app/src/main/res/layout/mediaplayerinfo_activity.xml +++ b/app/src/main/res/layout/mediaplayerinfo_activity.xml @@ -47,6 +47,7 @@ android:paddingTop="8dp" android:layout_alignParentBottom="true" android:background="?attr/overlay_drawable" + android:layoutDirection="ltr" android:orientation="vertical"> @@ -59,8 +60,10 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_centerVertical="true" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" android:text="@string/position_default_label" android:textColor="?android:attr/textColorSecondary" android:textSize="@dimen/text_size_micro" @@ -71,8 +74,10 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_centerVertical="true" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:text="@string/position_default_label" android:textColor="?android:attr/textColorSecondary" android:textSize="@dimen/text_size_micro" @@ -84,9 +89,13 @@ android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:layout_toLeftOf="@id/txtvLength" + android:layout_toStartOf="@id/txtvLength" android:layout_toRightOf="@id/txtvPosition" + android:layout_toEndOf="@id/txtvPosition" android:max="500" tools:background="@android:color/holo_green_dark" /> @@ -106,7 +115,9 @@ android:layout_width="@dimen/audioplayer_playercontrols_length" android:layout_height="@dimen/audioplayer_playercontrols_length" android:layout_marginLeft="16dp" + android:layout_marginStart="16dp" android:layout_marginRight="16dp" + android:layout_marginEnd="16dp" android:layout_centerHorizontal="true" android:background="?attr/selectableItemBackground" android:contentDescription="@string/pause_label" @@ -120,7 +131,9 @@ android:layout_width="@dimen/audioplayer_playercontrols_length" android:layout_height="@dimen/audioplayer_playercontrols_length" android:layout_toLeftOf="@id/butPlay" + android:layout_toStartOf="@id/butPlay" android:layout_marginLeft="16dp" + android:layout_marginStart="16dp" android:background="?attr/selectableItemBackground" android:contentDescription="@string/rewind_label" android:src="?attr/av_rew_big" @@ -134,7 +147,9 @@ android:layout_height="wrap_content" android:layout_below="@id/butRev" android:layout_alignLeft="@id/butRev" + android:layout_alignStart="@id/butRev" android:layout_alignRight="@id/butRev" + android:layout_alignEnd="@id/butRev" android:layout_marginTop="-8dp" android:gravity="center" android:text="30" @@ -147,6 +162,7 @@ android:layout_width="@dimen/audioplayer_playercontrols_length" android:layout_height="@dimen/audioplayer_playercontrols_length" android:layout_toLeftOf="@id/butRev" + android:layout_toStartOf="@id/butRev" android:background="?attr/selectableItemBackground" android:contentDescription="@string/set_playback_speed_label" android:src="?attr/av_fast_forward" @@ -161,6 +177,7 @@ android:layout_width="@dimen/audioplayer_playercontrols_length" android:layout_height="@dimen/audioplayer_playercontrols_length" android:layout_toLeftOf="@id/butRev" + android:layout_toStartOf="@id/butRev" android:background="?attr/selectableItemBackground" android:contentDescription="@string/cast_disconnect_label" android:src="?attr/ic_cast_disconnect" @@ -175,7 +192,9 @@ android:layout_width="@dimen/audioplayer_playercontrols_length" android:layout_height="@dimen/audioplayer_playercontrols_length" android:layout_toRightOf="@id/butPlay" + android:layout_toEndOf="@id/butPlay" android:layout_marginRight="16dp" + android:layout_marginEnd="16dp" android:background="?attr/selectableItemBackground" android:contentDescription="@string/fast_forward_label" android:src="?attr/av_ff_big" @@ -189,7 +208,9 @@ android:layout_height="wrap_content" android:layout_below="@id/butFF" android:layout_alignLeft="@id/butFF" + android:layout_alignStart="@id/butFF" android:layout_alignRight="@id/butFF" + android:layout_alignEnd="@id/butFF" android:layout_marginTop="-8dp" android:gravity="center" android:text="30" @@ -202,6 +223,7 @@ android:layout_width="@dimen/audioplayer_playercontrols_length" android:layout_height="@dimen/audioplayer_playercontrols_length" android:layout_toRightOf="@id/butFF" + android:layout_toEndOf="@id/butFF" android:background="?attr/selectableItemBackground" android:scaleType="fitCenter" android:src="?attr/av_skip_big" diff --git a/app/src/main/res/layout/nav_feedlistitem.xml b/app/src/main/res/layout/nav_feedlistitem.xml index 18b5255aa..73d07bc57 100644 --- a/app/src/main/res/layout/nav_feedlistitem.xml +++ b/app/src/main/res/layout/nav_feedlistitem.xml @@ -5,8 +5,8 @@ android:orientation="vertical" android:layout_width="match_parent" android:layout_height="@dimen/listitem_iconwithtext_height" - android:paddingRight="@dimen/listitem_threeline_verticalpadding" - tools:background="@android:color/darker_gray"> + tools:background="@android:color/darker_gray" + android:foreground="?attr/selectableItemBackground"> <ImageView android:id="@+id/imgvCover" @@ -14,6 +14,7 @@ android:layout_width="@dimen/thumbnail_length_navlist" android:layout_height="@dimen/thumbnail_length_navlist" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_centerVertical="true" android:adjustViewBounds="true" android:cropToPadding="true" @@ -21,6 +22,7 @@ android:layout_marginTop="4dp" android:layout_marginBottom="4dp" android:layout_marginLeft="@dimen/listitem_icon_leftpadding" + android:layout_marginStart="@dimen/listitem_icon_leftpadding" tools:src="@drawable/ic_stat_antenna_default" tools:background="@android:color/holo_green_dark"/> @@ -29,10 +31,14 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/list_vertical_padding" + android:layout_marginStart="@dimen/list_vertical_padding" + android:layout_marginRight="@dimen/listitem_icon_rightpadding" + android:layout_marginEnd="@dimen/listitem_icon_rightpadding" android:lines="1" android:textColor="?android:attr/textColorTertiary" android:textSize="@dimen/text_size_navdrawer" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_centerVertical="true" tools:text="23" tools:background="@android:color/holo_green_dark"/> @@ -42,7 +48,9 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toLeftOf="@id/txtvCount" + android:layout_toStartOf="@id/txtvCount" android:layout_marginLeft="@dimen/list_vertical_padding" + android:layout_marginStart="@dimen/list_vertical_padding" android:layout_alignWithParentIfMissing="true" android:lines="1" android:text="{fa-exclamation-circle}" @@ -63,8 +71,11 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/listitem_iconwithtext_textleftpadding" + android:layout_marginStart="@dimen/listitem_iconwithtext_textleftpadding" android:layout_toRightOf="@id/imgvCover" + android:layout_toEndOf="@id/imgvCover" android:layout_toLeftOf="@id/itxtvFailure" + android:layout_toStartOf="@id/itxtvFailure" android:layout_alignWithParentIfMissing="true" tools:text="Navigation feed item title" tools:background="@android:color/holo_green_dark"/> diff --git a/app/src/main/res/layout/nav_list.xml b/app/src/main/res/layout/nav_list.xml index e2fe61e28..2d044f548 100644 --- a/app/src/main/res/layout/nav_list.xml +++ b/app/src/main/res/layout/nav_list.xml @@ -24,6 +24,7 @@ android:layout_height="@dimen/thumbnail_length_navlist" android:layout_marginBottom="4dp" android:layout_marginLeft="@dimen/listitem_icon_leftpadding" + android:layout_marginStart="@dimen/listitem_icon_leftpadding" android:layout_marginTop="4dp" android:adjustViewBounds="true" android:contentDescription="@string/cover_label" @@ -39,6 +40,7 @@ android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginLeft="16dp" + android:layout_marginStart="16dp" android:layout_weight="1" android:gravity="center_vertical" android:text="@string/settings_label" diff --git a/app/src/main/res/layout/nav_listitem.xml b/app/src/main/res/layout/nav_listitem.xml index d62672c34..1332b5263 100644 --- a/app/src/main/res/layout/nav_listitem.xml +++ b/app/src/main/res/layout/nav_listitem.xml @@ -5,6 +5,7 @@ android:orientation="vertical" android:layout_width="match_parent" android:layout_height="@dimen/listitem_iconwithtext_height" + android:foreground="?attr/selectableItemBackground" tools:background="@android:color/darker_gray"> <ImageView @@ -13,12 +14,14 @@ android:layout_width="@dimen/thumbnail_length_navlist" android:layout_height="@dimen/thumbnail_length_navlist" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_centerVertical="true" android:adjustViewBounds="true" android:cropToPadding="true" android:scaleType="centerInside" android:padding="4dp" android:layout_marginLeft="@dimen/listitem_icon_leftpadding" + android:layout_marginStart="@dimen/listitem_icon_leftpadding" android:layout_marginTop="4dp" android:layout_marginBottom="4dp" tools:src="@drawable/ic_new_releases_white_24dp" @@ -36,8 +39,11 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/listitem_iconwithtext_textleftpadding" + android:layout_marginStart="@dimen/listitem_iconwithtext_textleftpadding" android:layout_marginRight="48dp" + android:layout_marginEnd="48dp" android:layout_toRightOf="@id/imgvCover" + android:layout_toEndOf="@id/imgvCover" tools:text="Navigation item title" tools:background="@android:color/holo_green_dark" /> @@ -50,8 +56,11 @@ android:textColor="?android:attr/textColorTertiary" android:textSize="@dimen/text_size_navdrawer" android:layout_marginLeft="12dp" + android:layout_marginStart="12dp" android:layout_marginRight="@dimen/listitem_icon_rightpadding" + android:layout_marginEnd="@dimen/listitem_icon_rightpadding" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_centerVertical="true" tools:text="23" tools:background="@android:color/holo_green_dark"/> diff --git a/app/src/main/res/layout/new_episodes_listitem.xml b/app/src/main/res/layout/new_episodes_listitem.xml index d533ee642..150d692e7 100644 --- a/app/src/main/res/layout/new_episodes_listitem.xml +++ b/app/src/main/res/layout/new_episodes_listitem.xml @@ -13,7 +13,6 @@ android:layout_height="wrap_content" android:background="?attr/selectableItemBackground" android:orientation="horizontal" - tools:background="@android:color/darker_gray" android:gravity="center_vertical"> <RelativeLayout @@ -27,6 +26,7 @@ android:layout_gravity="center_vertical" android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding" android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding" + android:layout_marginStart="@dimen/listitem_threeline_horizontalpadding" android:layout_marginTop="@dimen/listitem_threeline_verticalpadding" android:background="@color/light_gray" android:ellipsize="end" @@ -38,12 +38,13 @@ android:layout_height="64dp" android:layout_width="64dp" android:layout_alignLeft="@id/txtvPlaceholder" + android:layout_alignStart="@id/txtvPlaceholder" android:layout_alignTop="@id/txtvPlaceholder" android:layout_alignRight="@id/txtvPlaceholder" + android:layout_alignEnd="@id/txtvPlaceholder" android:layout_alignBottom="@id/txtvPlaceholder" android:contentDescription="@string/cover_label" - tools:src="@drawable/ic_stat_antenna_default" - tools:background="@android:color/holo_green_dark" /> + tools:src="@tools:sample/avatars" /> </RelativeLayout> @@ -52,10 +53,11 @@ android:layout_height="wrap_content" android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding" android:layout_marginLeft="@dimen/listitem_threeline_textleftpadding" + android:layout_marginStart="@dimen/listitem_threeline_textleftpadding" android:layout_marginRight="@dimen/listitem_threeline_textrightpadding" + android:layout_marginEnd="@dimen/listitem_threeline_textrightpadding" android:layout_marginTop="@dimen/listitem_threeline_verticalpadding" - android:layout_weight="1" - tools:background="@android:color/white" > + android:layout_weight="1"> <TextView @@ -64,8 +66,11 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_alignParentTop="true" - android:layout_marginLeft="8dp"/> + android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" + tools:text="@sample/episodes.json/data/status_label"/> <TextView android:id="@+id/txtvTitle" @@ -73,10 +78,11 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_toLeftOf="@id/statusUnread" - tools:text="Episode title" - tools:background="@android:color/holo_green_dark" /> + android:layout_toStartOf="@id/statusUnread" + tools:text="@sample/episodes.json/data/title" /> <RelativeLayout android:id="@+id/bottom_bar" @@ -85,8 +91,9 @@ android:layout_below="@id/txtvTitle" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentRight="true" - tools:background="@android:color/holo_red_light" > + android:layout_alignParentEnd="true"> <TextView android:id="@+id/txtvDuration" @@ -94,19 +101,20 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" - tools:text="00:42:23" - tools:background="@android:color/holo_blue_dark" /> + android:layout_alignParentStart="true" + tools:text="@sample/episodes.json/data/duration" /> <ImageView android:id="@+id/imgvInPlaylist" android:layout_width="@dimen/enc_icons_size" android:layout_height="@dimen/enc_icons_size" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" android:contentDescription="@string/in_queue_label" android:src="?attr/stat_playlist" - tools:src="@drawable/ic_list_grey600_24dp" - tools:background="@android:color/black" /> + tools:src="@sample/inplaylist" /> <TextView android:id="@+id/txtvPublished" @@ -115,9 +123,9 @@ android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_toLeftOf="@id/imgvInPlaylist" + android:layout_toStartOf="@id/imgvInPlaylist" android:ellipsize="end" - tools:text="Jan 23" - tools:background="@android:color/holo_green_dark" /> + tools:text="@sample/episodes.json/data/published_at" /> <ProgressBar android:id="@+id/pbar_progress" diff --git a/app/src/main/res/layout/numberpicker.xml b/app/src/main/res/layout/numberpicker.xml new file mode 100644 index 000000000..813326bd6 --- /dev/null +++ b/app/src/main/res/layout/numberpicker.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:padding="32dp"> + + <EditText + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:inputType="numberDecimal" + android:ems="10" + android:selectAllOnFocus="true" + android:id="@+id/number" /> + +</LinearLayout> diff --git a/app/src/main/res/layout/onlinefeedview_header.xml b/app/src/main/res/layout/onlinefeedview_header.xml index 491d955fb..4217322e4 100644 --- a/app/src/main/res/layout/onlinefeedview_header.xml +++ b/app/src/main/res/layout/onlinefeedview_header.xml @@ -10,6 +10,7 @@ android:layout_width="@dimen/thumbnail_length_onlinefeedview" android:layout_height="@dimen/thumbnail_length_onlinefeedview" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_marginLeft="16dp" android:layout_marginRight="16dp" @@ -24,10 +25,13 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_marginBottom="8dp" android:layout_marginRight="16dp" + android:layout_marginEnd="16dp" android:layout_marginTop="16dp" android:layout_toRightOf="@id/imgvCover" + android:layout_toEndOf="@id/imgvCover" android:ellipsize="end" android:gravity="center_vertical" android:maxLines="2" @@ -41,7 +45,9 @@ android:layout_below="@id/txtvTitle" android:layout_marginBottom="8dp" android:layout_marginRight="16dp" + android:layout_marginEnd="16dp" android:layout_toRightOf="@id/imgvCover" + android:layout_toEndOf="@id/imgvCover" android:ellipsize="end" android:lines="1" android:textColor="?android:attr/textColorSecondary" @@ -61,7 +67,9 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="16dp" + android:layout_marginStart="16dp" android:layout_marginRight="16dp" + android:layout_marginEnd="16dp" android:layout_marginTop="8dp" android:textColor="?android:attr/textColorPrimary" android:textSize="@dimen/text_size_micro" /> @@ -80,7 +88,9 @@ android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:layout_marginLeft="16dp" + android:layout_marginStart="16dp" android:layout_marginRight="16dp" + android:layout_marginEnd="16dp" android:textColor="?android:attr/textColorSecondary" android:textSize="@dimen/text_size_small" tools:text="@string/design_time_lorem_ipsum" diff --git a/app/src/main/res/layout/opml_selection.xml b/app/src/main/res/layout/opml_selection.xml index 3133debd1..f8f37b5ac 100644 --- a/app/src/main/res/layout/opml_selection.xml +++ b/app/src/main/res/layout/opml_selection.xml @@ -32,8 +32,10 @@ android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_toLeftOf="@id/horizontal_divider" + android:layout_toStartOf="@id/horizontal_divider" android:background="?android:attr/selectableItemBackground" android:text="@string/cancel_label" /> @@ -43,8 +45,10 @@ android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_alignParentTop="true" android:layout_toRightOf="@id/horizontal_divider" + android:layout_toEndOf="@id/horizontal_divider" android:background="?android:attr/selectableItemBackground" android:text="@string/confirm_label" /> </RelativeLayout> diff --git a/app/src/main/res/layout/queue_fragment.xml b/app/src/main/res/layout/queue_fragment.xml index 71bf16d30..cf00f2b1b 100644 --- a/app/src/main/res/layout/queue_fragment.xml +++ b/app/src/main/res/layout/queue_fragment.xml @@ -27,13 +27,9 @@ android:layout_below="@id/divider" android:scrollbars="vertical"/> - <TextView - android:id="@id/android:empty" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_centerInParent="true" - android:gravity="center" - android:text="@string/no_items_label" /> + <include + android:id="@+id/emptyView" + layout="@layout/empty_view_layout"/> <ProgressBar android:id="@+id/progLoading" diff --git a/app/src/main/res/layout/queue_listitem.xml b/app/src/main/res/layout/queue_listitem.xml index 7d18b386d..6b41b68d5 100644 --- a/app/src/main/res/layout/queue_listitem.xml +++ b/app/src/main/res/layout/queue_listitem.xml @@ -60,7 +60,9 @@ android:layout_height="wrap_content" android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding" android:layout_marginLeft="@dimen/listitem_threeline_textleftpadding" + android:layout_marginStart="@dimen/listitem_threeline_textleftpadding" android:layout_marginRight="@dimen/listitem_threeline_textrightpadding" + android:layout_marginEnd="@dimen/listitem_threeline_textrightpadding" android:layout_marginTop="@dimen/listitem_threeline_verticalpadding" android:layout_weight="1" tools:background="@android:color/holo_red_dark"> @@ -73,9 +75,11 @@ android:layout_height="wrap_content" android:lines="2" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_alignParentTop="true" android:layout_marginLeft="8dp" - android:gravity="right|top" + android:layout_marginStart="8dp" + android:gravity="end|top" android:text="Feb\n12" tools:background="@android:color/holo_blue_light" /> @@ -85,7 +89,9 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toLeftOf="@id/txtvPubDate" + android:layout_toStartOf="@id/txtvPubDate" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:text="Queue item title" android:ellipsize="end" @@ -98,7 +104,9 @@ android:layout_below="@id/txtvTitle" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" - android:layout_alignParentRight="true"> + android:layout_alignParentStart="true" + android:layout_alignParentRight="true" + android:layout_alignParentEnd="true"> <TextView android:id="@+id/txtvProgressLeft" @@ -106,6 +114,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_marginBottom="0dp" android:text="00:42:23" tools:background="@android:color/holo_blue_light"/> @@ -116,6 +125,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_marginBottom="0dp" tools:text="Jan 23" tools:background="@android:color/holo_green_dark" /> @@ -126,6 +136,7 @@ android:layout_width="match_parent" android:layout_height="4dp" android:layout_below="@id/txtvProgressLeft" + android:layoutDirection="ltr" android:max="100" tools:background="@android:color/holo_blue_light" /> diff --git a/app/src/main/res/layout/searchlist_item.xml b/app/src/main/res/layout/searchlist_item.xml index 83ba39cd5..50374c737 100644 --- a/app/src/main/res/layout/searchlist_item.xml +++ b/app/src/main/res/layout/searchlist_item.xml @@ -12,8 +12,10 @@ android:layout_width="@dimen/thumbnail_length_itemlist" android:layout_height="@dimen/thumbnail_length_itemlist" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_centerVertical="true" android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding" + android:layout_marginStart="@dimen/listitem_threeline_horizontalpadding" android:contentDescription="@string/cover_label" android:scaleType="centerCrop" tools:src="@drawable/ic_stat_antenna_default" @@ -23,8 +25,11 @@ android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_marginLeft="@dimen/listitem_iconwithtext_textleftpadding" + android:layout_marginStart="@dimen/listitem_iconwithtext_textleftpadding" android:layout_marginRight="@dimen/listitem_threeline_verticalpadding" + android:layout_marginEnd="@dimen/listitem_threeline_verticalpadding" android:layout_toRightOf="@id/imgvFeedimage" + android:layout_toEndOf="@id/imgvFeedimage" android:orientation="vertical" tools:background="@android:color/holo_red_dark"> diff --git a/app/src/main/res/layout/secondary_action.xml b/app/src/main/res/layout/secondary_action.xml index b2aea03f8..1f4d9e4e6 100644 --- a/app/src/main/res/layout/secondary_action.xml +++ b/app/src/main/res/layout/secondary_action.xml @@ -9,5 +9,4 @@ android:focusable="false" android:focusableInTouchMode="false" tools:ignore="ContentDescription" - tools:src="@drawable/ic_play_arrow_grey600_36dp" - tools:background="@android:color/holo_green_dark" /> + tools:src="@sample/secondaryaction" /> diff --git a/app/src/main/res/layout/simple_list_item_multiple_choice_on_start.xml b/app/src/main/res/layout/simple_list_item_multiple_choice_on_start.xml new file mode 100644 index 000000000..3c03f71ea --- /dev/null +++ b/app/src/main/res/layout/simple_list_item_multiple_choice_on_start.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Based on simple_list_item_multiple_choice.xml + from The Android Open Source Project + This one puts the check box at the start of the view (rather than at the end). + --> +<!-- Copyright (C) 2008 The Android Open Source Project + + 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. +--> + +<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@android:id/text1" + android:layout_width="match_parent" + android:layout_height="?android:attr/listPreferredItemHeightSmall" + android:textAppearance="?android:attr/textAppearanceListItemSmall" + android:gravity="center_vertical" + android:drawableStart="?android:attr/listChoiceIndicatorMultiple" + android:drawableLeft="?android:attr/listChoiceIndicatorMultiple" + android:paddingStart="?android:attr/listPreferredItemPaddingStart" + android:paddingLeft="?android:attr/listPreferredItemPaddingLeft" + android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" + android:paddingRight="?android:attr/listPreferredItemPaddingRight" + /> diff --git a/app/src/main/res/layout/simplechapter_item.xml b/app/src/main/res/layout/simplechapter_item.xml index 28cdb08c3..0d02eac1a 100644 --- a/app/src/main/res/layout/simplechapter_item.xml +++ b/app/src/main/res/layout/simplechapter_item.xml @@ -13,6 +13,7 @@ android:layout_height="match_parent" android:layout_gravity="center_vertical" android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding" + android:layout_marginStart="@dimen/listitem_threeline_horizontalpadding" android:gravity="center_vertical" tools:text="Start" tools:background="@android:color/holo_green_dark" /> @@ -22,7 +23,9 @@ android:layout_height="match_parent" android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding" android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding" + android:layout_marginStart="@dimen/listitem_threeline_horizontalpadding" android:layout_marginRight="@dimen/listitem_threeline_horizontalpadding" + android:layout_marginEnd="@dimen/listitem_threeline_horizontalpadding" android:layout_marginTop="@dimen/listitem_threeline_verticalpadding" android:layout_weight="1" android:gravity="center_vertical" diff --git a/app/src/main/res/layout/splash.xml b/app/src/main/res/layout/splash.xml new file mode 100644 index 000000000..71b6cd15a --- /dev/null +++ b/app/src/main/res/layout/splash.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <ProgressBar + style="?android:attr/progressBarStyle" + android:layout_width="24dp" + android:layout_height="24dp" + android:layout_alignParentBottom="true" + android:layout_centerHorizontal="true" + android:layout_margin="36dp" + android:id="@+id/progressBar"/> +</RelativeLayout> diff --git a/app/src/main/res/layout/statistics_listitem.xml b/app/src/main/res/layout/statistics_listitem.xml index 20e01bf32..b186add9e 100644 --- a/app/src/main/res/layout/statistics_listitem.xml +++ b/app/src/main/res/layout/statistics_listitem.xml @@ -4,7 +4,10 @@ android:orientation="vertical" android:layout_width="match_parent" android:layout_height="@dimen/listitem_iconwithtext_height" + android:paddingLeft="@dimen/listitem_threeline_verticalpadding" + android:paddingStart="@dimen/listitem_threeline_verticalpadding" android:paddingRight="@dimen/listitem_threeline_verticalpadding" + android:paddingEnd="@dimen/listitem_threeline_verticalpadding" tools:background="@android:color/darker_gray"> <ImageView @@ -13,13 +16,13 @@ android:layout_width="@dimen/thumbnail_length_navlist" android:layout_height="@dimen/thumbnail_length_navlist" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_centerVertical="true" android:adjustViewBounds="true" android:cropToPadding="true" android:scaleType="centerCrop" android:layout_marginTop="4dp" android:layout_marginBottom="4dp" - android:layout_marginLeft="@dimen/listitem_icon_leftpadding" tools:src="@drawable/ic_stat_antenna_default" tools:background="@android:color/holo_green_dark"/> @@ -28,10 +31,12 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/list_vertical_padding" + android:layout_marginStart="@dimen/list_vertical_padding" android:lines="1" android:textColor="?android:attr/textColorTertiary" android:textSize="@dimen/text_size_navdrawer" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_centerVertical="true" tools:text="23" tools:background="@android:color/holo_green_dark"/> @@ -47,8 +52,11 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/listitem_iconwithtext_textleftpadding" + android:layout_marginStart="@dimen/listitem_iconwithtext_textleftpadding" android:layout_toRightOf="@id/imgvCover" + android:layout_toEndOf="@id/imgvCover" android:layout_toLeftOf="@id/txtvTime" + android:layout_toStartOf="@id/txtvTime" android:layout_alignWithParentIfMissing="true" tools:text="Navigation feed item title" tools:background="@android:color/holo_green_dark"/> diff --git a/app/src/main/res/layout/videoplayer_activity.xml b/app/src/main/res/layout/videoplayer_activity.xml index 10fbf8f49..4de46810e 100644 --- a/app/src/main/res/layout/videoplayer_activity.xml +++ b/app/src/main/res/layout/videoplayer_activity.xml @@ -25,6 +25,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" + android:layoutDirection="ltr" android:orientation="horizontal"> <ImageButton @@ -32,27 +33,27 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="8dp" - android:background="@drawable/overlay_button_circle_background" + android:background="@drawable/md_transparent" android:contentDescription="@string/rewind_label" - android:src="@drawable/ic_av_rewind_80dp" /> + android:src="@drawable/ic_av_fast_rewind_white_80dp" /> <ImageButton android:id="@+id/butPlay" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="8dp" - android:background="@drawable/overlay_button_circle_background" + android:background="@drawable/md_transparent" android:contentDescription="@string/pause_label" - android:src="@drawable/ic_av_pause_circle_outline_80dp" /> + android:src="@drawable/ic_av_pause_white_80dp" /> <ImageButton android:id="@+id/butFF" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="8dp" - android:background="@drawable/overlay_button_circle_background" + android:background="@drawable/md_transparent" android:contentDescription="@string/fast_forward_label" - android:src="@drawable/ic_av_fast_forward_80dp" /> + android:src="@drawable/ic_av_fast_forward_white_80dp" /> </LinearLayout> @@ -68,6 +69,7 @@ android:layout_width="match_parent" android:layout_height="50dp" android:background="#80000000" + android:layoutDirection="ltr" android:paddingTop="8dp"> <TextView @@ -75,10 +77,13 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_marginBottom="8dp" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:layout_marginTop="4dp" android:text="@string/position_default_label" android:textColor="@color/white" @@ -89,10 +94,13 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_alignParentTop="true" android:layout_marginBottom="8dp" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:layout_marginTop="4dp" android:text="@string/position_default_label" android:textColor="@color/white" @@ -103,7 +111,9 @@ android:layout_width="0px" android:layout_height="wrap_content" android:layout_toLeftOf="@+id/txtvLength" + android:layout_toStartOf="@+id/txtvLength" android:layout_toRightOf="@+id/txtvPosition" + android:layout_toEndOf="@+id/txtvPosition" android:layout_centerInParent="true" android:max="500" /> diff --git a/app/src/main/res/menu/allepisodes_context.xml b/app/src/main/res/menu/allepisodes_context.xml index 7398b9118..28493c5b6 100644 --- a/app/src/main/res/menu/allepisodes_context.xml +++ b/app/src/main/res/menu/allepisodes_context.xml @@ -7,6 +7,12 @@ android:menuCategory="container" android:title="@string/skip_episode_label" /> + + <item + android:id="@+id/mark_as_seen_item" + android:menuCategory="container" + android:title="@string/mark_as_seen_label" /> + <item android:id="@+id/mark_read_item" android:menuCategory="container" diff --git a/app/src/main/res/menu/episodes_apply_action_speeddial.xml b/app/src/main/res/menu/episodes_apply_action_speeddial.xml new file mode 100644 index 000000000..39083e41b --- /dev/null +++ b/app/src/main/res/menu/episodes_apply_action_speeddial.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android"> + <!-- the order is opposite of the typical menu: + catered to FAB speed dial, which somehow shows the item in reverse. + E.g., item @id/delete_batch is the first in the xml, + visually it will be shown at the bottom of the list of actions. + --> + <item android:id="@+id/delete_batch" + android:icon="?attr/content_discard" + android:title="@string/delete_episode_label" + /> + <item android:id="@+id/download_batch" + android:icon="?attr/av_download" + android:title="@string/download_label" + /> + <item android:id="@+id/mark_unread_batch" + android:icon="?attr/navigation_cancel" + android:title="@string/mark_unread_label" + /> + <item + android:id="@+id/mark_read_batch" + android:icon="?attr/navigation_accept" + android:title="@string/mark_read_label" + /> + <item android:id="@+id/remove_from_queue_batch" + android:icon="?attr/content_remove_from_queue" + android:title="@string/remove_from_queue_label" + /> + <item + android:id="@+id/add_to_queue_batch" + android:icon="?attr/content_new" + android:title="@string/add_to_queue_label" + /> +</menu> diff --git a/app/src/main/res/menu/feeditemlist_context.xml b/app/src/main/res/menu/feeditemlist_context.xml index d3ec88bc7..1f4f09faa 100644 --- a/app/src/main/res/menu/feeditemlist_context.xml +++ b/app/src/main/res/menu/feeditemlist_context.xml @@ -24,6 +24,10 @@ android:id="@+id/remove_from_queue_item" android:menuCategory="container" android:title="@string/remove_from_queue_label" /> + <item + android:id="@+id/remove_item" + android:menuCategory="container" + android:title="@string/delete_label" /> <item android:id="@+id/add_to_favorites_item" diff --git a/app/src/main/res/menu/opml_selection_options.xml b/app/src/main/res/menu/opml_selection_options.xml index 26d2a0519..8b3310dc2 100644 --- a/app/src/main/res/menu/opml_selection_options.xml +++ b/app/src/main/res/menu/opml_selection_options.xml @@ -4,14 +4,14 @@ <item android:id="@id/select_all_item" - android:icon="?attr/ic_check_box_outline" + android:icon="?attr/ic_select_all" android:title="@string/select_all_label" custom:showAsAction="ifRoom"> </item> <item android:id="@id/deselect_all_item" - android:icon="?attr/ic_check_box" + android:icon="?attr/ic_select_none" android:title="@string/deselect_all_label" custom:showAsAction="ifRoom"> </item> diff --git a/app/src/main/res/menu/queue_context.xml b/app/src/main/res/menu/queue_context.xml index e93d808c1..c88620665 100644 --- a/app/src/main/res/menu/queue_context.xml +++ b/app/src/main/res/menu/queue_context.xml @@ -26,6 +26,10 @@ android:id="@+id/remove_from_queue_item" android:menuCategory="container" android:title="@string/remove_from_queue_label" /> + <item + android:id="@+id/remove_item" + android:menuCategory="container" + android:title="@string/delete_label" /> <item android:id="@+id/add_to_favorites_item" diff --git a/app/src/main/res/values-w300dp/dimens-fabspeeddial.xml b/app/src/main/res/values-w300dp/dimens-fabspeeddial.xml new file mode 100644 index 000000000..e531395c0 --- /dev/null +++ b/app/src/main/res/values-w300dp/dimens-fabspeeddial.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <!-- increase FAB speed dial label's max width if the screen is wide enough + (300dp ~ 1.875 inch, devices with 3.5-inch screens have a width of ~ 1.9in + so the setup is applicable for most phones) + --> + <dimen name="sd_label_max_width">240dp</dimen> +</resources> diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index d3b72e17c..f45847e54 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -8,7 +8,7 @@ <Preference android:key="prefScreenInterface" android:title="@string/user_interface_label" - android:icon="?attr/type_video" /> + android:icon="?attr/ic_cellphone_text" /> <Preference android:key="prefScreenPlayback" @@ -38,16 +38,21 @@ <PreferenceCategory android:title="@string/project_pref"> <Preference android:key="prefFaq" - android:title="@string/pref_faq"/> + android:title="@string/pref_faq" + android:icon="?attr/ic_question_answer" /> + <Preference android:key="prefKnownIssues" - android:title="@string/pref_known_issues"/> + android:title="@string/pref_known_issues" + android:icon="?attr/ic_known_issues" /> <Preference android:key="prefSendCrashReport" android:title="@string/crash_report_title" - android:summary="@string/crash_report_sum"/> + android:summary="@string/crash_report_sum" + android:icon="?attr/ic_bug" /> <Preference android:key="prefAbout" - android:title="@string/about_pref"/> + android:title="@string/about_pref" + android:icon="?attr/action_about" /> </PreferenceCategory> </PreferenceScreen> diff --git a/app/src/main/res/xml/preferences_network.xml b/app/src/main/res/xml/preferences_network.xml index 0ab8e5866..59dd0c51b 100644 --- a/app/src/main/res/xml/preferences_network.xml +++ b/app/src/main/res/xml/preferences_network.xml @@ -1,19 +1,13 @@ <?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:numberpicker="http://schemas.android.com/apk/de.danoeh.antennapod" xmlns:search="http://schemas.android.com/apk/com.bytehamster.lib.preferencesearch"> <PreferenceCategory android:title="@string/automation"> <Preference android:key="prefAutoUpdateIntervall" android:summary="@string/pref_autoUpdateIntervallOrTime_sum" android:title="@string/pref_autoUpdateIntervallOrTime_title"/> - <SwitchPreference - android:defaultValue="false" - android:enabled="true" - android:key="prefMobileUpdate" - android:summary="@string/pref_mobileUpdate_sum" - android:title="@string/pref_mobileUpdate_title"/> <Preference android:summary="@string/pref_automatic_download_sum" android:key="prefAutoDownloadSettings" @@ -22,12 +16,19 @@ </PreferenceCategory> <PreferenceCategory android:title="@string/download_pref_details"> - <EditTextPreference + <ListPreference + android:defaultValue="images" + android:entries="@array/mobile_update_entries" + android:entryValues="@array/mobile_update_values" + android:key="prefMobileUpdateAllowed" + android:summary="@string/pref_mobileUpdate_sum" + android:title="@string/pref_mobileUpdate_title"/> + <de.danoeh.antennapod.preferences.NumberPickerPreference android:defaultValue="4" - android:inputType="number" + numberpicker:minValue="1" + numberpicker:maxValue="50" android:key="prefParallelDownloads" - android:title="@string/pref_parallel_downloads_title" - app:useStockLayout="true"/> + android:title="@string/pref_parallel_downloads_title"/> <SwitchPreference android:defaultValue="true" android:enabled="true" diff --git a/app/src/main/res/xml/preferences_playback.xml b/app/src/main/res/xml/preferences_playback.xml index c43f6da71..9182df600 100644 --- a/app/src/main/res/xml/preferences_playback.xml +++ b/app/src/main/res/xml/preferences_playback.xml @@ -109,12 +109,14 @@ </PreferenceCategory> <PreferenceCategory android:title="@string/media_player"> - <SwitchPreference - android:defaultValue="true" - android:enabled="false" - android:key="prefSonic" - android:summary="@string/pref_sonic_message" - android:title="@string/pref_sonic_title"/> + <ListPreference + android:defaultValue="sonic" + android:entries="@array/media_player_options" + android:key="prefMediaPlayer" + android:title="@string/media_player" + android:summary="@string/pref_media_player_message" + android:entryValues="@array/media_player_values" + app:useStockLayout="true"/> </PreferenceCategory> <PreferenceCategory android:title="@string/experimental_pref"> diff --git a/app/src/main/res/xml/preferences_storage.xml b/app/src/main/res/xml/preferences_storage.xml index fe48cc99c..9f394ad12 100644 --- a/app/src/main/res/xml/preferences_storage.xml +++ b/app/src/main/res/xml/preferences_storage.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto"> + xmlns:search="http://schemas.android.com/apk/com.bytehamster.lib.preferencesearch"> <Preference android:title="@string/choose_data_directory" @@ -25,6 +25,12 @@ android:key="prefFavoriteKeepsEpisode" android:summary="@string/pref_favorite_keeps_episodes_sum" android:title="@string/pref_favorite_keeps_episodes_title"/> + <SwitchPreference + android:defaultValue="false" + android:enabled="true" + android:key="prefDeleteRemovesFromQueue" + android:summary="@string/pref_delete_removes_from_queue_sum" + android:title="@string/pref_delete_removes_from_queue_title"/> <PreferenceCategory android:title="@string/import_export_pref"> <Preference @@ -38,6 +44,7 @@ android:title="@string/html_export_label"/> <Preference android:key="importExport" + search:keywords="@string/import_export_search_keywords" android:title="@string/import_export"/> </PreferenceCategory> </PreferenceScreen> diff --git a/app/src/main/res/xml/preferences_user_interface.xml b/app/src/main/res/xml/preferences_user_interface.xml index da694b844..1d970a5f7 100644 --- a/app/src/main/res/xml/preferences_user_interface.xml +++ b/app/src/main/res/xml/preferences_user_interface.xml @@ -57,4 +57,14 @@ android:summary="@string/pref_lockscreen_background_sum" android:title="@string/pref_lockscreen_background_title"/> </PreferenceCategory> + <PreferenceCategory android:title="@string/behavior"> + <ListPreference + android:entryValues="@array/back_button_behavior_values" + android:entries="@array/back_button_behavior_options" + android:key="prefBackButtonBehavior" + android:title="@string/pref_back_button_behavior_title" + android:summary="@string/pref_back_button_behavior_sum" + android:defaultValue="default" + app:useStockLayout="true"/> + </PreferenceCategory> </PreferenceScreen> diff --git a/app/src/main/templates/about.html b/app/src/main/templates/about.html index 400727c46..cc3a24e62 100644 --- a/app/src/main/templates/about.html +++ b/app/src/main/templates/about.html @@ -8,30 +8,52 @@ font-family: 'Roboto-Light'; src: url('file:///android_asset/Roboto-Light.ttf'); } + + html, body { + background: @background@; + margin: 0; + padding: 0; + } * { - color: %s; + color: @fontcolor@; font-family: roboto-Light; font-size: 12pt; } - header { + img#logo { display: block; margin-left: auto; margin-right: auto; - padding-bottom: 500px; + max-height: 200px; + max-height: 50vh; + max-width: 100%; + height: auto; + width: auto; } - - versiontag { - color: gray; + + div#logobackground{ + width: 100%; + background: #42a5f5; + } + + .card { + background: @card_background@; + margin: 10px; + padding: 10px; + border: 1px solid @card_border@; + border-top-width: 0; + border-bottom-width: 2px; } h1 { font-size: 15pt; + margin-left: 20px; } h2 { font-size: 13pt; + margin-top: 0px; } a { @@ -44,67 +66,117 @@ <title>About AntennaPod</title> </head> <body> -<div id="header" align="center"> - <img src="file:///android_asset/logo.png" alt="Logo" width="100px" height="100px"/> - - <p>AntennaPod, Version @versionname@</p> - <p>Commit: @commit@</p> +<div id="logobackground"> +<img id="logo" src="file:///android_asset/logo.png" alt="Logo"/> +</div> - <p>Created by Daniel Oeh</p> +<h1>AntennaPod</h1> - <p>Copyright © 2012-@year@ AntennaPod Contributors <a href="CONTRIBUTORS.txt">(View)</a></p> +<div class="card"> +<table> +<tr><td>Version:</td><td><b>@versionname@</b></td></tr> +<tr><td>Commit:</td><td><b>@commit@</b></td></tr> +</table> +</div> - <p>Licensed under the MIT License <a href="LICENSE.txt">(View)</a></p> +<div class="card"> +Created by Daniel Oeh<br /> +Copyright © 2012-@year@<br /> +AntennaPod Contributors <a href="CONTRIBUTORS.txt">(View)</a><br /> +Licensed under the MIT License <a href="LICENSE.txt">(View)</a> </div> + <h1>Used libraries</h1> +<div class="card"> <h2>Apache Commons <a href="http://commons.apache.org/">(Link)</a></h2> by The Apache Software Foundation, licensed under the Apache 2.0 license <a href="LICENSE_APACHE-2.0.txt">(View)</a> +</div> +<div class="card"> <h2>EventBus <a href="https://github.com/greenrobot/EventBus">(Link)</a></h2> by greenrobot, licensed under the Apache 2.0 license <a href="LICENSE_APACHE-2.0.txt">(View)</a> +</div> + +<div class="card"> +<h2>ExoPlayer <a href="https://github.com/google/ExoPlayer">(Link)</a></h2> +by Google, licensed under the Apache 2.0 license <a href="LICENSE_APACHE-2.0.txt">(View)</a> +</div> +<div class="card"> <h2>flattr4j <a href="http://www.shredzone.org/projects/flattr4j/wiki">(Link)</a></h2> licensed under the Apache 2.0 license <a href="LICENSE_APACHE-2.0.txt">(View)</a> +</div> +<div class="card"> <h2>Glide <a href="https://github.com/bumptech/glide/">(Link)</a></h2> licensed under the Simplified BSD license <a href="LICENSE_GLIDE.txt">(View)</a> +</div> +<div class="card"> <h2>Iconify <a href="https://github.com/JoanZapata/android-iconify">(Link)</a></h2> by Joan Zapata, licensed under the Apache 2.0 license <a href="LICENSE_ANDROID_ICONIFY.txt">(View)</a> +</div> +<div class="card"> <h2>jsoup <a href="http://jsoup.org/">(Link)</a></h2> licensed under the MIT license <a href="LICENSE_JSOUP.txt">(View)</a> +</div> +<div class="card"> <h2>Material Design Icons <a href="https://github.com/google/material-design-icons">(Link)</a></h2> by Google, licensed under an Attribution-ShareAlike 4.0 International license <a href="LICENSE_MATERIAL_DESIGN_ICONS.txt">(View)</a> +</div> + +<div class="card"> +<h2>Material Design Icons <a href="https://github.com/Templarian/MaterialDesign">(Link)</a></h2> +by Templarian, licensed under the SIL Open Font License, Version 1.1 <a href="LICENSE_SIL.txt">(View)</a> +</div> +<div class="card"> <h2>Material Dialogs <a href="https://github.com/afollestad/material-dialogs">(Link)</a></h2> by Aidan Michael Follestad, licensed under the MIT License <a href="LICENSE_MATERIAL_DIALOGS.txt">(View)</a> +</div> +<div class="card"> <h2>OkHttp <a href="https://github.com/square/okhttp">(Link)</a></h2> by Square, licensed under the Apache 2.0 license <a href="LICENSE_OKHTTP.txt">(View)</a> +</div> +<div class="card"> <h2>Okio <a href="https://github.com/square/okio">(Link)</a></h2> by Square, licensed under the Apache 2.0 license <a href="LICENSE_APACHE-2.0.txt">(View)</a> +</div> +<div class="card"> <h2>Presto Client <a href="http://www.aocate.com/presto/">(Link)</a></h2> licensed under the Apache 2.0 license <a href="LICENSE_PRESTO.txt">(View)</a> +</div> +<div class="card"> <h2>RecyclerView-FlexibleDivider <a href="https://github.com/yqritc/RecyclerView-FlexibleDivider">(Link)</a></h2> licensed under the Apache 2.0 license <a href="LICENSE_APACHE-2.0.txt">(View)</a> +</div> +<div class="card"> <h2>RxAndroid <a href="https://github.com/ReactiveX/RxAndroid">(Link)</a></h2> licensed under the Apache 2.0 license <a href="LICENSE_APACHE-2.0.txt">(View)</a> +</div> +<div class="card"> <h2>StackBlur <a href="https://github.com/kikoso/android-stackblur">(Link)</a></h2> by Enrique López Mañas, licensed under the Apache 2.0 license <a href="LICENSE_APACHE-2.0.txt">(View)</a> +</div> +<div class="card"> <h2>Triangle Label View <a href="https://github.com/shts/TriangleLabelView">(Link)</a></h2> by Shota Saito, licensed under the Apache 2.0 license <a href="LICENSE_TRIANGLE_LABEL_VIEW.txt">(View)</a> +</div> +<div class="card"> <h2>AntennaPod-AudioPlayer <a href="https://github.com/AntennaPod/AntennaPod-AudioPlayer/">(Link)</a></h2> by the AntennaPod team, licensed under the Apache 2.0 license <a href="LICENSE_APACHE-2.0.txt">(View)</a> +</div> </body> </html> diff --git a/app/src/play/java/de/danoeh/antennapod/dialog/CustomMRControllerDialog.java b/app/src/play/java/de/danoeh/antennapod/dialog/CustomMRControllerDialog.java index 4cde95d6f..ae8e20575 100644 --- a/app/src/play/java/de/danoeh/antennapod/dialog/CustomMRControllerDialog.java +++ b/app/src/play/java/de/danoeh/antennapod/dialog/CustomMRControllerDialog.java @@ -35,16 +35,17 @@ import android.widget.LinearLayout; import android.widget.TextView; import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.target.Target; import java.util.concurrent.ExecutionException; import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.glide.ApGlideSettings; -import rx.Observable; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; +import io.reactivex.Observable; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; public class CustomMRControllerDialog extends MediaRouteControllerDialog { public static final String TAG = "CustomMRContrDialog"; @@ -60,7 +61,7 @@ public class CustomMRControllerDialog extends MediaRouteControllerDialog { private boolean viewsCreated = false; - private Subscription fetchArtSubscription; + private Disposable fetchArtSubscription; private MediaControllerCompat mediaController; private MediaControllerCompat.Callback mediaControllerCallback; @@ -327,7 +328,7 @@ public class CustomMRControllerDialog extends MediaRouteControllerDialog { @Override public void onDetachedFromWindow() { if (fetchArtSubscription != null) { - fetchArtSubscription.unsubscribe(); + fetchArtSubscription.dispose(); fetchArtSubscription = null; } super.onDetachedFromWindow(); @@ -396,11 +397,11 @@ public class CustomMRControllerDialog extends MediaRouteControllerDialog { } if (fetchArtSubscription != null) { - fetchArtSubscription.unsubscribe(); + fetchArtSubscription.dispose(); } fetchArtSubscription = Observable.fromCallable(() -> fetchArt(description)) - .subscribeOn(Schedulers.newThread()) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { fetchArtSubscription = null; @@ -454,6 +455,7 @@ public class CustomMRControllerDialog extends MediaRouteControllerDialog { return context.getTheme().resolveAttribute(attr, value, true) ? value.resourceId : 0; } + @NonNull private Pair<Bitmap, Integer> fetchArt(@NonNull MediaDescriptionCompat description) { Bitmap iconBitmap = description.getIconBitmap(); Uri iconUri = description.getIconUri(); @@ -463,10 +465,10 @@ public class CustomMRControllerDialog extends MediaRouteControllerDialog { } else if (iconUri != null) { try { art = Glide.with(getContext().getApplicationContext()) - .load(iconUri.toString()) .asBitmap() - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .into(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) + .load(iconUri.toString()) + .apply(RequestOptions.diskCacheStrategyOf(ApGlideSettings.AP_DISK_CACHE_STRATEGY)) + .submit(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) .get(); } catch (InterruptedException | ExecutionException e) { Log.e(TAG, "Image art load failed", e); diff --git a/app/src/play/play b/app/src/play/play new file mode 120000 index 000000000..e9d641154 --- /dev/null +++ b/app/src/play/play @@ -0,0 +1 @@ +../main/play
\ No newline at end of file diff --git a/build.gradle b/build.gradle index bc1bb870d..664cecbd9 100644 --- a/build.gradle +++ b/build.gradle @@ -1,23 +1,26 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. - buildscript { repositories { + google() jcenter() mavenCentral() - google() } dependencies { - classpath 'com.android.tools.build:gradle:3.1.0' - classpath "com.github.triplet.gradle:play-publisher:1.2.0" - // Exclude the version that the android plugin depends on. - configurations.classpath.exclude group: "com.android.tools.external.lombok" + classpath 'com.android.tools.build:gradle:3.3.0' + classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.8.5' } } allprojects { repositories { - jcenter() google() + jcenter() + maven { url "https://jitpack.io" } + } + + gradle.projectsEvaluated { + tasks.withType(JavaCompile) { + options.compilerArgs << "-Xlint" << "-Xlint:-deprecation" << "-Xlint:-serial" + } } } @@ -38,18 +41,18 @@ subprojects { project.ext { compileSdkVersion = 26 - buildToolsVersion = "27.0.3" minSdkVersion = 14 targetSdkVersion = 26 - supportVersion = "26.1.0" + supportVersion = "27.1.1" + awaitilityVersion = "3.1.2" commonsioVersion = "2.5" commonslangVersion = "3.6" commonstextVersion = "1.3" eventbusVersion = "2.4.0" flattr4jVersion = "2.14" - glideVersion = "3.8.0" - glideOkhttpIntegrationVersion = "1.5.0" + glideVersion = "4.8.0" + glideOkhttpIntegrationVersion = "4.8.0" iconifyVersion = "2.2.2" jsoupVersion = "1.11.2" materialDialogsVersion = "0.9.0.2" @@ -57,11 +60,12 @@ project.ext { okioVersion = "1.14.0" recyclerviewFlexibledividerVersion = "1.4.0" robotiumSoloVersion = "5.6.3" - rxAndroidVersion = "1.2.1" - rxJavaVersion = "1.3.8" + rxAndroidVersion = "2.1.0" + rxJavaVersion = "2.2.2" rxJavaRulesVersion = "1.3.3.0" triangleLabelViewVersion = "1.1.2" + exoPlayerVersion = "2.9.3" audioPlayerVersion = "v1.0.17" castCompanionLibVer = "2.9.1" @@ -69,8 +73,8 @@ project.ext { wearableSupportVersion = "2.2.0" } -task wrapper(type: Wrapper) { - gradleVersion = "4.4.1" +wrapper { + gradleVersion = "4.10.2" } // free build hack: common functions diff --git a/ci/wait_for_emulator.sh b/ci/wait_for_emulator.sh deleted file mode 100644 index 317883878..000000000 --- a/ci/wait_for_emulator.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -bootanim="" -failcounter=0 -until [[ "$bootanim" =~ "stopped" ]]; do - bootanim=`adb -e shell getprop init.svc.bootanim 2>&1` - echo "$bootanim" - if [[ "$bootanim" =~ "not found" ]]; then - let "failcounter += 1" - if [[ $failcounter -gt 3 ]]; then - echo "Failed to start emulator" - exit 1 - fi - fi - sleep 1 -done -echo "Done" diff --git a/contributers.template.py b/contributers.template.py index 3127baa0c..0f4d78698 100755 --- a/contributers.template.py +++ b/contributers.template.py @@ -6,7 +6,15 @@ TRANSIFEX_USER = "" TRANSIFEX_PW = "" print('DEVELOPERS\n==========\n') -p = subprocess.Popen("git log --format='%aN' | sort -fu", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) +p = subprocess.Popen("git log --format='%aN' --no-merges " + +"| grep -v '@' " # No email adresses + +"| grep -v 'no.reply' " # no.reply + +"| sed -e 's/^\(Daniel\|daniel oeh\|danieloeh\)$/Daniel Oeh/I'" # Duplicate name + +"| sed -e 's/^keunes$/Koen Glotzbach/'" # Duplicate name + +"| sed -e 's/^H. Lehmann$/ByteHamster/'" # Duplicate name + +"| sed -e 's/^domingos86$/Domingos Lopes/'" # Duplicate name + +"| sed -e 's/^orionlee$/Sam Lee/'" # Duplicate name + +"| sort -fu", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) for line in p.stdout.readlines(): output = line.decode() print(output, end='') @@ -17,6 +25,7 @@ language_codes = { "af": "Afrikaans", "ak_GH": "Akan (Ghana)", "ak": "Akan", + "ast_ES": "Asturian (Spain)", "sq_AL": "Albanian (Albania)", "sq": "Albanian", "am_ET": "Amharic (Ethiopia)", diff --git a/core/build.gradle b/core/build.gradle index eb857269a..65dfa1a7b 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -2,7 +2,6 @@ apply plugin: "com.android.library" android { compileSdkVersion rootProject.ext.compileSdkVersion - buildToolsVersion rootProject.ext.buildToolsVersion defaultConfig { minSdkVersion rootProject.ext.minSdkVersion @@ -10,7 +9,7 @@ android { versionCode 1 versionName "1.0" testApplicationId "de.danoeh.antennapod.core.tests" - testInstrumentationRunner "de.danoeh.antennapod.core.AntennaPodTestRunner" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { @@ -41,11 +40,6 @@ android { } -repositories { - maven { url "https://jitpack.io" } - mavenCentral() -} - dependencies { implementation "com.android.support:support-v4:$supportVersion" implementation "com.android.support:appcompat-v7:$supportVersion" @@ -60,13 +54,17 @@ dependencies { implementation "com.jayway.android.robotium:robotium-solo:$robotiumSoloVersion" implementation "org.jsoup:jsoup:$jsoupVersion" implementation "com.github.bumptech.glide:glide:$glideVersion" + annotationProcessor "com.github.bumptech.glide:compiler:$glideVersion" implementation "com.github.bumptech.glide:okhttp3-integration:$glideOkhttpIntegrationVersion@aar" implementation "com.squareup.okhttp3:okhttp:$okhttpVersion" implementation "com.squareup.okhttp3:okhttp-urlconnection:$okhttpVersion" implementation "com.squareup.okio:okio:$okioVersion" implementation "de.greenrobot:eventbus:$eventbusVersion" - implementation "io.reactivex:rxandroid:$rxAndroidVersion" + implementation "io.reactivex.rxjava2:rxandroid:$rxAndroidVersion" + implementation "io.reactivex.rxjava2:rxjava:$rxJavaVersion" + implementation "org.awaitility:awaitility:$awaitilityVersion" + implementation "com.google.android.exoplayer:exoplayer:$exoPlayerVersion" implementation "com.github.AntennaPod:AntennaPod-AudioPlayer:$audioPlayerVersion" // Add casting features @@ -81,6 +79,10 @@ dependencies { } testImplementation 'junit:junit:4.12' + testImplementation 'org.mockito:mockito-core:1.10.19' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test:rules:1.0.2' } @@ -92,11 +94,3 @@ tasks.withType(Test) { displayGranularity 2 } } - -allprojects { - gradle.projectsEvaluated { - tasks.withType(JavaCompile) { - options.compilerArgs << "-Xlint" << "-Xlint:-deprecation" << "-Xlint:-serial" - } - } -} diff --git a/core/src/androidTest/java/de/danoeh/antennapod/core/AntennaPodTestRunner.java b/core/src/androidTest/java/de/danoeh/antennapod/core/AntennaPodTestRunner.java deleted file mode 100644 index 5d086c054..000000000 --- a/core/src/androidTest/java/de/danoeh/antennapod/core/AntennaPodTestRunner.java +++ /dev/null @@ -1,16 +0,0 @@ -package de.danoeh.antennapod.core; - -import android.test.InstrumentationTestRunner; -import android.test.suitebuilder.TestSuiteBuilder; - -import junit.framework.TestSuite; - -public class AntennaPodTestRunner extends InstrumentationTestRunner { - - @Override - public TestSuite getAllTests() { - return new TestSuiteBuilder(AntennaPodTestRunner.class) - .includeAllPackagesUnderHere() - .build(); - } -}
\ No newline at end of file diff --git a/core/src/androidTest/java/de/danoeh/antennapod/core/util/DateUtilsTest.java b/core/src/androidTest/java/de/danoeh/antennapod/core/util/DateUtilsTest.java index d5efdbc24..bef83b060 100644 --- a/core/src/androidTest/java/de/danoeh/antennapod/core/util/DateUtilsTest.java +++ b/core/src/androidTest/java/de/danoeh/antennapod/core/util/DateUtilsTest.java @@ -3,6 +3,7 @@ package de.danoeh.antennapod.core.util; import android.test.AndroidTestCase; +import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.TimeZone; @@ -156,4 +157,12 @@ public class DateUtilsTest extends AndroidTestCase { Date actual = DateUtils.parse("Mon, 8 Sept 2014 00:00:00 GMT"); // should be Sep assertEquals(expected, actual); } + + public void testParseDateWithTwoTimezones() { + final GregorianCalendar exp1 = new GregorianCalendar(2015, Calendar.MARCH, 1, 1, 0, 0); + exp1.setTimeZone(TimeZone.getTimeZone("GMT-4")); + final Date expected = new Date(exp1.getTimeInMillis()); + final Date actual = DateUtils.parse("Sun 01 Mar 2015 01:00:00 GMT-0400 (EDT)"); + assertEquals(expected, actual); + } } diff --git a/core/src/main/java/android/support/v4/app/SafeJobIntentService.java b/core/src/main/java/android/support/v4/app/SafeJobIntentService.java new file mode 100644 index 000000000..c07c409ee --- /dev/null +++ b/core/src/main/java/android/support/v4/app/SafeJobIntentService.java @@ -0,0 +1,118 @@ +package android.support.v4.app; + +import android.app.job.JobParameters; +import android.app.job.JobServiceEngine; +import android.app.job.JobWorkItem; +import android.content.Intent; +import android.os.Build; +import android.os.IBinder; +import android.support.annotation.RequiresApi; +import android.util.Log; + + +public abstract class SafeJobIntentService extends JobIntentService { + + @Override + public void onCreate() { + super.onCreate(); + if (Build.VERSION.SDK_INT >= 26) { + mJobImpl = new SafeJobServiceEngineImpl(this); + } + } + + /** + * Implementation of a safe JobServiceEngine for interaction with JobIntentService. + */ + @RequiresApi(26) + static final class SafeJobServiceEngineImpl extends JobServiceEngine + implements JobIntentService.CompatJobEngine { + static final String TAG = "JobServiceEngineImpl"; + + static final boolean DEBUG = false; + + final JobIntentService mService; + final Object mLock = new Object(); + JobParameters mParams; + + final class WrapperWorkItem implements JobIntentService.GenericWorkItem { + final JobWorkItem mJobWork; + + WrapperWorkItem(JobWorkItem jobWork) { + mJobWork = jobWork; + } + + @Override + public Intent getIntent() { + return mJobWork.getIntent(); + } + + @Override + public void complete() { + synchronized (mLock) { + if (mParams != null) { + try { + mParams.completeWork(mJobWork); + } catch (SecurityException e) { + Log.e(TAG, Log.getStackTraceString(e)); + } + } + } + } + } + + SafeJobServiceEngineImpl(JobIntentService service) { + super(service); + mService = service; + } + + @Override + public IBinder compatGetBinder() { + return getBinder(); + } + + @Override + public boolean onStartJob(JobParameters params) { + if (DEBUG) Log.d(TAG, "onStartJob: " + params); + mParams = params; + // We can now start dequeuing work! + mService.ensureProcessorRunningLocked(false); + return true; + } + + @Override + public boolean onStopJob(JobParameters params) { + if (DEBUG) Log.d(TAG, "onStartJob: " + params); + boolean result = mService.doStopCurrentWork(); + synchronized (mLock) { + // Once we return, the job is stopped, so its JobParameters are no + // longer valid and we should not be doing anything with them. + mParams = null; + } + return result; + } + + /** + * Dequeue some work. + */ + @Override + public JobIntentService.GenericWorkItem dequeueWork() { + JobWorkItem work = null; + synchronized (mLock) { + if (mParams == null) { + return null; + } + try { + work = mParams.dequeueWork(); + } catch (SecurityException e) { + Log.e(TAG, Log.getStackTraceString(e)); + } + } + if (work != null) { + work.getIntent().setExtrasClassLoader(mService.getClassLoader()); + return new WrapperWorkItem(work); + } else { + return null; + } + } + } +} diff --git a/core/src/main/java/de/danoeh/antennapod/core/UpdateManager.java b/core/src/main/java/de/danoeh/antennapod/core/UpdateManager.java index 96e3a77be..1b4cbc0ea 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/UpdateManager.java +++ b/core/src/main/java/de/danoeh/antennapod/core/UpdateManager.java @@ -10,21 +10,15 @@ import android.util.Log; import org.antennapod.audio.MediaPlayer; -import java.io.File; -import java.util.List; - -import de.danoeh.antennapod.core.feed.Feed; -import de.danoeh.antennapod.core.feed.FeedImage; -import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.preferences.UserPreferences; -import de.danoeh.antennapod.core.storage.DBReader; -import de.danoeh.antennapod.core.storage.DBWriter; /* * This class's job is do perform maintenance tasks whenever the app has been updated */ class UpdateManager { + private UpdateManager(){} + private static final String TAG = UpdateManager.class.getSimpleName(); private static final String PREF_NAME = "app_version"; @@ -64,32 +58,22 @@ class UpdateManager { } private static void onUpgrade(final int oldVersionCode, final int newVersionCode) { - if(oldVersionCode < 1030099) { - // delete the now obsolete image cache - // from now on, Glide will handle caching images - new Thread() { - public void run() { - List<Feed> feeds = DBReader.getFeedList(); - for (Feed podcast : feeds) { - List<FeedItem> episodes = DBReader.getFeedItemList(podcast); - for (FeedItem episode : episodes) { - FeedImage image = episode.getImage(); - if (image != null && image.isDownloaded() && image.getFile_url() != null) { - File imageFile = new File(image.getFile_url()); - if (imageFile.exists()) { - imageFile.delete(); - } - image.setFile_url(null); // calls setDownloaded(false) - DBWriter.setFeedImage(image); - } - } - } - } - }.start(); - } - if(oldVersionCode < 1050004) { + if (oldVersionCode < 1050004) { if(MediaPlayer.isPrestoLibraryInstalled(context) && Build.VERSION.SDK_INT >= 16) { - UserPreferences.enableSonic(true); + UserPreferences.enableSonic(); + } + } + + if (oldVersionCode < 1070196) { + // migrate episode cleanup value (unit changed from days to hours) + int oldValueInDays = UserPreferences.getEpisodeCleanupValue(); + if (oldValueInDays > 0) { + UserPreferences.setEpisodeCleanupValue(oldValueInDays * 24); + } // else 0 or special negative values, no change needed + } + if (oldVersionCode < 1070197) { + if (prefs.getBoolean("prefMobileUpdate", false)) { + prefs.edit().putString(UserPreferences.PREF_MOBILE_UPDATE, "everything").apply(); } } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/asynctask/DBTaskLoader.java b/core/src/main/java/de/danoeh/antennapod/core/asynctask/DBTaskLoader.java deleted file mode 100644 index 1b4aafeaa..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/asynctask/DBTaskLoader.java +++ /dev/null @@ -1,29 +0,0 @@ -package de.danoeh.antennapod.core.asynctask; - -import android.content.Context; -import android.support.v4.content.AsyncTaskLoader; - -/** - * Subclass of AsyncTaskLoader that is made for loading data with one of the DB*-classes. - * This class will provide a useful default implementation that would otherwise always be necessary when interacting - * with the DB*-classes with an AsyncTaskLoader. - */ -abstract class DBTaskLoader<D> extends AsyncTaskLoader<D> { - - public DBTaskLoader(Context context) { - super(context); - } - - @Override - protected void onStopLoading() { - super.onStopLoading(); - cancelLoad(); - } - - @Override - protected void onStartLoading() { - super.onStartLoading(); - // according to https://code.google.com/p/android/issues/detail?id=14944, this has to be called manually - forceLoad(); - } -} 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 1e0c07b01..4504b2e7f 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 @@ -2,7 +2,6 @@ package de.danoeh.antennapod.core.asynctask; import android.app.ProgressDialog; import android.content.Context; -import android.content.Intent; import android.os.AsyncTask; import java.util.concurrent.ExecutionException; @@ -11,6 +10,7 @@ import de.danoeh.antennapod.core.R; import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.service.playback.PlaybackService; import de.danoeh.antennapod.core.storage.DBWriter; +import de.danoeh.antennapod.core.util.IntentUtils; /** Removes a feed in the background. */ public class FeedRemover extends AsyncTask<Void, Void, Void> { @@ -41,7 +41,7 @@ public class FeedRemover extends AsyncTask<Void, Void, Void> { dialog.dismiss(); } if(skipOnCompletion) { - context.sendBroadcast(new Intent(PlaybackService.ACTION_SKIP_CURRENT_EPISODE)); + IntentUtils.sendLocalBroadcast(context, PlaybackService.ACTION_SKIP_CURRENT_EPISODE); } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/asynctask/FlattrClickWorker.java b/core/src/main/java/de/danoeh/antennapod/core/asynctask/FlattrClickWorker.java index f4c99011a..318e404c8 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/asynctask/FlattrClickWorker.java +++ b/core/src/main/java/de/danoeh/antennapod/core/asynctask/FlattrClickWorker.java @@ -10,7 +10,6 @@ import android.support.v4.app.NotificationCompat; import android.util.Log; import android.widget.Toast; -import de.danoeh.antennapod.core.util.gui.NotificationUtils; import org.shredzone.flattr4j.exception.FlattrException; import java.util.LinkedList; @@ -27,6 +26,7 @@ import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.util.NetworkUtils; import de.danoeh.antennapod.core.util.flattr.FlattrThing; import de.danoeh.antennapod.core.util.flattr.FlattrUtils; +import de.danoeh.antennapod.core.util.gui.NotificationUtils; /** * Performs a click action in a background thread. diff --git a/core/src/main/java/de/danoeh/antennapod/core/asynctask/FlattrStatusFetcher.java b/core/src/main/java/de/danoeh/antennapod/core/asynctask/FlattrStatusFetcher.java index 420a60469..6d9ab2bd3 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/asynctask/FlattrStatusFetcher.java +++ b/core/src/main/java/de/danoeh/antennapod/core/asynctask/FlattrStatusFetcher.java @@ -19,11 +19,9 @@ import de.danoeh.antennapod.core.util.flattr.FlattrUtils; public class FlattrStatusFetcher extends Thread { private static final String TAG = "FlattrStatusFetcher"; - private final Context context; public FlattrStatusFetcher(Context context) { super(); - this.context = context; } @Override 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 78df74ee7..3395653f3 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 @@ -44,7 +44,7 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource { * Name of the author */ private String author; - private FeedImage image; + private String imageUrl; private List<FeedItem> items; /** @@ -96,7 +96,7 @@ 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 customTitle, String link, String description, String paymentLink, - String author, String language, String type, String feedIdentifier, FeedImage image, String fileUrl, + String author, String language, String type, String feedIdentifier, String imageUrl, String fileUrl, String downloadUrl, boolean downloaded, FlattrStatus status, boolean paged, String nextPageLink, String filter, boolean lastUpdateFailed) { super(fileUrl, downloadUrl, downloaded); @@ -111,7 +111,7 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource { this.language = language; this.type = type; this.feedIdentifier = feedIdentifier; - this.image = image; + this.imageUrl = imageUrl; this.flattrStatus = status; this.paged = paged; this.nextPageLink = nextPageLink; @@ -128,9 +128,9 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource { * This constructor is used for test purposes and uses a default flattr status object. */ 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 author, String language, String type, String feedIdentifier, String imageUrl, String fileUrl, String downloadUrl, boolean downloaded) { - this(id, lastUpdate, title, null, link, description, paymentLink, author, language, type, feedIdentifier, image, + this(id, lastUpdate, title, null, link, description, paymentLink, author, language, type, feedIdentifier, imageUrl, fileUrl, downloadUrl, downloaded, new FlattrStatus(), false, null, null, false); } @@ -191,6 +191,7 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource { int indexNextPageLink = cursor.getColumnIndex(PodDBAdapter.KEY_NEXT_PAGE_LINK); int indexHide = cursor.getColumnIndex(PodDBAdapter.KEY_HIDE); int indexLastUpdateFailed = cursor.getColumnIndex(PodDBAdapter.KEY_LAST_UPDATE_FAILED); + int indexImageUrl = cursor.getColumnIndex(PodDBAdapter.KEY_IMAGE_URL); Feed feed = new Feed( cursor.getLong(indexId), @@ -204,7 +205,7 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource { cursor.getString(indexLanguage), cursor.getString(indexType), cursor.getString(indexFeedIdentifier), - null, + cursor.getString(indexImageUrl), cursor.getString(indexFileUrl), cursor.getString(indexDownloadUrl), cursor.getInt(indexDownloaded) > 0, @@ -266,8 +267,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.image != null) { - this.image = other.image; + if (other.imageUrl != null) { + this.imageUrl = other.imageUrl; } if (other.feedTitle != null) { feedTitle = other.feedTitle; @@ -305,8 +306,8 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource { if (super.compareWithOther(other)) { return true; } - if (other.image != null) { - if (image == null || !TextUtils.equals(image.download_url, other.image.download_url)) { + if (other.imageUrl != null) { + if (imageUrl == null || !TextUtils.equals(imageUrl, other.imageUrl)) { return true; } } @@ -411,12 +412,12 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource { this.description = description; } - public FeedImage getImage() { - return image; + public String getImageUrl() { + return imageUrl; } - public void setImage(FeedImage image) { - this.image = image; + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; } public List<FeedItem> getItems() { @@ -505,11 +506,7 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource { @Override public String getImageLocation() { - if (image != null) { - return image.getImageLocation(); - } else { - return null; - } + return imageUrl; } public int getPageNr() { diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedComponent.java b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedComponent.java index a3f91b1c9..2610d253f 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedComponent.java +++ b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedComponent.java @@ -50,7 +50,7 @@ public abstract class FeedComponent { @Override public boolean equals(Object o) { if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (o == null || !(o instanceof FeedComponent)) return false; FeedComponent that = (FeedComponent) o; @@ -62,4 +62,4 @@ public abstract class FeedComponent { public int hashCode() { return (int) (id ^ (id >>> 32)); } -}
\ No newline at end of file +} diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedImage.java b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedImage.java deleted file mode 100644 index 45bd2ad31..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedImage.java +++ /dev/null @@ -1,92 +0,0 @@ -package de.danoeh.antennapod.core.feed; - -import android.database.Cursor; - -import java.io.File; - -import de.danoeh.antennapod.core.asynctask.ImageResource; -import de.danoeh.antennapod.core.storage.PodDBAdapter; - - -public class FeedImage extends FeedFile implements ImageResource { - public static final int FEEDFILETYPE_FEEDIMAGE = 1; - - private String title; - private FeedComponent owner; - - public FeedImage(FeedComponent owner, String download_url, String title) { - super(null, download_url, false); - this.download_url = download_url; - this.title = title; - this.owner = owner; - } - - public FeedImage(long id, String title, String file_url, - String download_url, boolean downloaded) { - super(file_url, download_url, downloaded); - this.id = id; - this.title = title; - } - - public FeedImage() { - super(); - } - - public static FeedImage fromCursor(Cursor cursor) { - int indexId = cursor.getColumnIndex(PodDBAdapter.KEY_ID); - int indexTitle = cursor.getColumnIndex(PodDBAdapter.KEY_TITLE); - int indexFileUrl = cursor.getColumnIndex(PodDBAdapter.KEY_FILE_URL); - int indexDownloadUrl = cursor.getColumnIndex(PodDBAdapter.KEY_DOWNLOAD_URL); - int indexDownloaded = cursor.getColumnIndex(PodDBAdapter.KEY_DOWNLOADED); - - return new FeedImage( - cursor.getLong(indexId), - cursor.getString(indexTitle), - cursor.getString(indexFileUrl), - cursor.getString(indexDownloadUrl), - cursor.getInt(indexDownloaded) > 0 - ); - } - - - @Override - public String getHumanReadableIdentifier() { - if (owner != null && owner.getHumanReadableIdentifier() != null) { - return owner.getHumanReadableIdentifier(); - } else { - return download_url; - } - } - - @Override - public int getTypeAsInt() { - return FEEDFILETYPE_FEEDIMAGE; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public FeedComponent getOwner() { - return owner; - } - - public void setOwner(FeedComponent owner) { - this.owner = owner; - } - - @Override - public String getImageLocation() { - if (file_url != null && downloaded) { - return new File(file_url).getAbsolutePath(); - } else if(download_url != null) { - return download_url; - } else { - return null; - } - } -} 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 87298d4c3..0f0343f25 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 @@ -2,8 +2,8 @@ package de.danoeh.antennapod.core.feed; import android.database.Cursor; import android.support.annotation.Nullable; - import android.text.TextUtils; + import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; @@ -75,7 +75,7 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr * in the database. The 'hasChapters' attribute should be used to check if this item has any chapters. * */ private List<Chapter> chapters; - private FeedImage image; + private String imageUrl; /* * 0: auto download disabled @@ -100,7 +100,7 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr * This constructor is used by DBReader. * */ public FeedItem(long id, String title, String link, Date pubDate, String paymentLink, long feedId, - FlattrStatus flattrStatus, boolean hasChapters, FeedImage image, int state, + FlattrStatus flattrStatus, boolean hasChapters, String imageUrl, int state, String itemIdentifier, long autoDownload) { this.id = id; this.title = title; @@ -110,7 +110,7 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr this.feedId = feedId; this.flattrStatus = flattrStatus; this.hasChapters = hasChapters; - this.image = image; + this.imageUrl = imageUrl; this.state = state; this.itemIdentifier = itemIdentifier; this.autoDownload = autoDownload; @@ -158,6 +158,7 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr int indexRead = cursor.getColumnIndex(PodDBAdapter.KEY_READ); int indexItemIdentifier = cursor.getColumnIndex(PodDBAdapter.KEY_ITEM_IDENTIFIER); int indexAutoDownload = cursor.getColumnIndex(PodDBAdapter.KEY_AUTO_DOWNLOAD); + int indexImageUrl = cursor.getColumnIndex(PodDBAdapter.KEY_IMAGE_URL); long id = cursor.getInt(indexId); String title = cursor.getString(indexTitle); @@ -170,15 +171,16 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr int state = cursor.getInt(indexRead); String itemIdentifier = cursor.getString(indexItemIdentifier); long autoDownload = cursor.getLong(indexAutoDownload); + String imageUrl = cursor.getString(indexImageUrl); return new FeedItem(id, title, link, pubDate, paymentLink, feedId, flattrStatus, - hasChapters, null, state, itemIdentifier, autoDownload); + hasChapters, imageUrl, state, itemIdentifier, autoDownload); } public void updateFromOther(FeedItem other) { super.updateFromOther(other); - if (other.image != null) { - this.image = other.image; + if (other.imageUrl != null) { + this.imageUrl = other.imageUrl; } if (other.title != null) { title = other.title; @@ -192,7 +194,7 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr if (other.link != null) { link = other.link; } - if (other.pubDate != null && other.pubDate != pubDate) { + if (other.pubDate != null && other.pubDate.equals(pubDate)) { pubDate = other.pubDate; } if (other.media != null) { @@ -212,9 +214,6 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr chapters = other.chapters; } } - if (image == null) { - image = other.image; - } } /** @@ -389,8 +388,8 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr public String getImageLocation() { if(media != null && media.hasEmbeddedPicture()) { return media.getImageLocation(); - } else if (image != null) { - return image.getImageLocation(); + } else if (imageUrl != null) { + return imageUrl; } else if (feed != null) { return feed.getImageLocation(); } else { @@ -426,29 +425,12 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr * Returns the image of this item or the image of the feed if this item does * not have its own image. */ - public FeedImage getImage() { - return (hasItemImage()) ? image : feed.getImage(); - } - - public void setImage(FeedImage image) { - this.image = image; - if (image != null) { - image.setOwner(this); - } - } - - /** - * Returns true if this FeedItem has its own image, false otherwise. - */ - public boolean hasItemImage() { - return image != null; + public String getImageUrl() { + return (imageUrl != null) ? imageUrl : feed.getImageUrl(); } - /** - * Returns true if this FeedItem has its own image and the image has been downloaded. - */ - public boolean hasItemImageDownloaded() { - return image != null && image.isDownloaded(); + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; } @Override 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 200153876..719383d23 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 @@ -8,6 +8,8 @@ import java.util.List; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.util.LongList; +import static de.danoeh.antennapod.core.feed.FeedItem.TAG_FAVORITE; + public class FeedItemFilter { private final String[] mProperties; @@ -19,6 +21,7 @@ public class FeedItemFilter { private boolean showDownloaded = false; private boolean showNotDownloaded = false; private boolean showHasMedia = false; + private boolean showIsFavorite = false; public FeedItemFilter(String properties) { this(TextUtils.split(properties, ",")); @@ -53,6 +56,9 @@ public class FeedItemFilter { case "has_media": showHasMedia = true; break; + case "is_favorite": + showIsFavorite = true; + break; } } } @@ -88,6 +94,8 @@ public class FeedItemFilter { if (showHasMedia && !item.hasMedia()) continue; + if (showIsFavorite && !item.isTagged(TAG_FAVORITE)) continue; + // If the item reaches here, it meets all criteria result.add(item); } diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java index a22422596..f3a43e2d0 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java +++ b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java @@ -19,6 +19,7 @@ import de.danoeh.antennapod.core.gpoddernet.model.GpodnetEpisodeAction; import de.danoeh.antennapod.core.preferences.GpodnetPreferences; 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; @@ -218,7 +219,7 @@ public class FeedMedia extends FeedFile implements Playable { * currently being played and the current player status is playing. */ public boolean isCurrentlyPlaying() { - return isPlaying() && + return isPlaying() && PlaybackService.isRunning && ((PlaybackPreferences.getCurrentPlayerStatus() == PlaybackPreferences.PLAYER_STATUS_PLAYING)); } @@ -531,8 +532,8 @@ public class FeedMedia extends FeedFile implements Playable { UserPreferences.isAutoFlattr() && item.getPaymentLink() != null && item.getFlattrStatus().getUnflattred() && - (completed && autoFlattrThreshold <= 1.0f || - played_duration >= autoFlattrThreshold * duration)) { + ((completed && autoFlattrThreshold <= 1.0f) || + (played_duration >= autoFlattrThreshold * duration))) { DBTasks.flattrItemIfLoggedIn(context, item); } } @@ -593,7 +594,7 @@ public class FeedMedia extends FeedFile implements Playable { @Override public void setDownloaded(boolean downloaded) { super.setDownloaded(downloaded); - if(item != null && downloaded) { + if(item != null && downloaded && item.isNew()) { item.setPlayed(false); } } @@ -625,6 +626,9 @@ public class FeedMedia extends FeedFile implements Playable { @Override public boolean equals(Object o) { + if (o == null) { + return false; + } if (FeedMediaFlavorHelper.instanceOfRemoteMedia(o)) { return o.equals(this); } diff --git a/core/src/main/java/de/danoeh/antennapod/core/glide/ApGlideModule.java b/core/src/main/java/de/danoeh/antennapod/core/glide/ApGlideModule.java index 835dee735..552c1b691 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/glide/ApGlideModule.java +++ b/core/src/main/java/de/danoeh/antennapod/core/glide/ApGlideModule.java @@ -2,31 +2,35 @@ package de.danoeh.antennapod.core.glide; import android.content.Context; +import android.support.annotation.NonNull; import com.bumptech.glide.Glide; import com.bumptech.glide.GlideBuilder; +import com.bumptech.glide.Registry; +import com.bumptech.glide.annotation.GlideModule; import com.bumptech.glide.load.DecodeFormat; import com.bumptech.glide.load.engine.cache.InternalCacheDiskCacheFactory; -import com.bumptech.glide.module.GlideModule; +import com.bumptech.glide.module.AppGlideModule; import java.io.InputStream; +import com.bumptech.glide.request.RequestOptions; import de.danoeh.antennapod.core.preferences.UserPreferences; /** * {@see com.bumptech.glide.integration.okhttp.OkHttpGlideModule} */ -public class ApGlideModule implements GlideModule { +@GlideModule +public class ApGlideModule extends AppGlideModule { @Override - public void applyOptions(Context context, GlideBuilder builder) { - builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888); + public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) { + builder.setDefaultRequestOptions(new RequestOptions().format(DecodeFormat.PREFER_ARGB_8888)); builder.setDiskCache(new InternalCacheDiskCacheFactory(context, UserPreferences.getImageCacheSize())); } @Override - public void registerComponents(Context context, Glide glide) { - glide.register(String.class, InputStream.class, new ApOkHttpUrlLoader.Factory()); + public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) { + registry.replace(String.class, InputStream.class, new ApOkHttpUrlLoader.Factory()); } - } diff --git a/core/src/main/java/de/danoeh/antennapod/core/glide/ApGlideSettings.java b/core/src/main/java/de/danoeh/antennapod/core/glide/ApGlideSettings.java index fc1acd0e1..d0061af99 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/glide/ApGlideSettings.java +++ b/core/src/main/java/de/danoeh/antennapod/core/glide/ApGlideSettings.java @@ -6,6 +6,7 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy; * The settings that AntennaPod will use for various Glide options */ public class ApGlideSettings { + private ApGlideSettings(){} public static final DiskCacheStrategy AP_DISK_CACHE_STRATEGY = DiskCacheStrategy.ALL; } 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 3e4f06a12..2e742e979 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 @@ -1,12 +1,12 @@ package de.danoeh.antennapod.core.glide; -import android.content.Context; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.text.TextUtils; import android.util.Log; 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.Options; import com.bumptech.glide.load.model.GlideUrl; import com.bumptech.glide.load.model.ModelLoader; import com.bumptech.glide.load.model.ModelLoaderFactory; @@ -15,14 +15,14 @@ import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; +import com.bumptech.glide.load.model.MultiModelLoaderFactory; +import com.bumptech.glide.signature.ObjectKey; 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; +import okhttp3.*; +import okhttp3.internal.http.RealResponseBody; /** * @see com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader @@ -56,19 +56,20 @@ class ApOkHttpUrlLoader implements ModelLoader<String, InputStream> { /** * Constructor for a new Factory that runs requests using a static singleton client. */ - public Factory() { + Factory() { this(getInternalClient()); } /** * Constructor for a new Factory that runs requests using given client. */ - public Factory(OkHttpClient client) { + Factory(OkHttpClient client) { this.client = client; } + @NonNull @Override - public ModelLoader<String, InputStream> build(Context context, GenericLoaderFactory factories) { + public ModelLoader<String, InputStream> build(@NonNull MultiModelLoaderFactory multiFactory) { return new ApOkHttpUrlLoader(client); } @@ -84,28 +85,40 @@ class ApOkHttpUrlLoader implements ModelLoader<String, InputStream> { this.client = client; } + @Nullable @Override - public DataFetcher<InputStream> getResourceFetcher(String model, int width, int height) { - Log.d(TAG, "getResourceFetcher() called with: " + "model = [" + model + "], width = [" + public LoadData<InputStream> buildLoadData(@NonNull String model, int width, int height, @NonNull Options options) { + Log.d(TAG, "buildLoadData() called with: " + "model = [" + model + "], width = [" + width + "], height = [" + height + "]"); if(TextUtils.isEmpty(model)) { return null; } else if(model.startsWith("/")) { - return new AudioCoverFetcher(model); + return new LoadData<>(new ObjectKey(model), new AudioCoverFetcher(model)); } else { GlideUrl url = new GlideUrl(model); - return new OkHttpStreamFetcher(client, url); + return new LoadData<>(new ObjectKey(model), new OkHttpStreamFetcher(client, url)); } } + @Override + public boolean handles(@NonNull String s) { + return true; + } + private static class NetworkAllowanceInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { - if (NetworkUtils.isDownloadAllowed()) { + if (NetworkUtils.isImageAllowed()) { return chain.proceed(chain.request()); } else { - return null; + return new Response.Builder() + .protocol(Protocol.HTTP_2) + .code(420) + .message("Policy Not Fulfilled") + .body(ResponseBody.create(null, new byte[0])) + .request(chain.request()) + .build(); } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/glide/AudioCoverFetcher.java b/core/src/main/java/de/danoeh/antennapod/core/glide/AudioCoverFetcher.java index 8159a1b3e..479846655 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/glide/AudioCoverFetcher.java +++ b/core/src/main/java/de/danoeh/antennapod/core/glide/AudioCoverFetcher.java @@ -2,7 +2,9 @@ package de.danoeh.antennapod.core.glide; import android.media.MediaMetadataRetriever; +import android.support.annotation.NonNull; import com.bumptech.glide.Priority; +import com.bumptech.glide.load.DataSource; import com.bumptech.glide.load.data.DataFetcher; import java.io.ByteArrayInputStream; @@ -20,22 +22,20 @@ class AudioCoverFetcher implements DataFetcher<InputStream> { this.path = path; } - @Override public String getId() { - return path; - } - - @Override public InputStream loadData(Priority priority) throws Exception { + @Override + public void loadData(@NonNull Priority priority, @NonNull DataCallback<? super InputStream> callback) { MediaMetadataRetriever retriever = new MediaMetadataRetriever(); try { retriever.setDataSource(path); byte[] picture = retriever.getEmbeddedPicture(); if (picture != null) { - return new ByteArrayInputStream(picture); + callback.onDataReady(new ByteArrayInputStream(picture)); + return; } } finally { retriever.release(); } - throw new IOException("Loading embedded cover did not work"); + callback.onLoadFailed(new IOException("Loading embedded cover did not work")); } @Override public void cleanup() { @@ -44,4 +44,16 @@ class AudioCoverFetcher implements DataFetcher<InputStream> { @Override public void cancel() { // cannot cancel } + + @NonNull + @Override + public Class<InputStream> getDataClass() { + return InputStream.class; + } + + @NonNull + @Override + public DataSource getDataSource() { + return DataSource.LOCAL; + } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/glide/FastBlurTransformation.java b/core/src/main/java/de/danoeh/antennapod/core/glide/FastBlurTransformation.java index ee58c2f39..a740782d6 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/glide/FastBlurTransformation.java +++ b/core/src/main/java/de/danoeh/antennapod/core/glide/FastBlurTransformation.java @@ -1,13 +1,15 @@ package de.danoeh.antennapod.core.glide; -import android.content.Context; import android.graphics.Bitmap; import android.media.ThumbnailUtils; +import android.support.annotation.NonNull; import android.util.Log; import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; import com.bumptech.glide.load.resource.bitmap.BitmapTransformation; +import java.security.MessageDigest; + public class FastBlurTransformation extends BitmapTransformation { private static final String TAG = FastBlurTransformation.class.getSimpleName(); @@ -15,8 +17,8 @@ public class FastBlurTransformation extends BitmapTransformation { private static final int STACK_BLUR_RADIUS = 1; private static final int BLUR_IMAGE_WIDTH = 150; - public FastBlurTransformation(Context context) { - super(context); + public FastBlurTransformation() { + super(); } @Override @@ -33,11 +35,6 @@ public class FastBlurTransformation extends BitmapTransformation { return result; } - @Override - public String getId() { - return "FastBlurTransformation[width=" + BLUR_IMAGE_WIDTH + "px,radius=" + STACK_BLUR_RADIUS +"]"; - } - private static Bitmap fastBlur(Bitmap bitmap, int radius) { // Stack Blur v1.0 from @@ -264,4 +261,8 @@ public class FastBlurTransformation extends BitmapTransformation { return bitmap; } + @Override + public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) { + messageDigest.update(TAG.getBytes()); + } }
\ No newline at end of file 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 3af5e9080..2588cfdee 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 @@ -14,6 +14,7 @@ import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; @@ -587,7 +588,7 @@ public class GpodnetService { String result = null; ResponseBody body = null; try { - String credential = Credentials.basic(username, password); + String credential = Credentials.basic(username, password, Charset.forName("UTF-8")); Request authRequest = request.newBuilder().header("Authorization", credential).build(); Response response = httpClient.newCall(authRequest).execute(); checkStatusCode(response); diff --git a/core/src/main/java/de/danoeh/antennapod/core/gpoddernet/model/GpodnetEpisodeAction.java b/core/src/main/java/de/danoeh/antennapod/core/gpoddernet/model/GpodnetEpisodeAction.java index b76988fd8..330cde525 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/gpoddernet/model/GpodnetEpisodeAction.java +++ b/core/src/main/java/de/danoeh/antennapod/core/gpoddernet/model/GpodnetEpisodeAction.java @@ -169,7 +169,7 @@ public class GpodnetEpisodeAction { @Override public boolean equals(Object o) { if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (o == null || !(o instanceof GpodnetEpisodeAction)) return false; GpodnetEpisodeAction that = (GpodnetEpisodeAction) o; diff --git a/core/src/main/java/de/danoeh/antennapod/core/preferences/GpodnetPreferences.java b/core/src/main/java/de/danoeh/antennapod/core/preferences/GpodnetPreferences.java index b51b8d996..5b17dd338 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/preferences/GpodnetPreferences.java +++ b/core/src/main/java/de/danoeh/antennapod/core/preferences/GpodnetPreferences.java @@ -24,6 +24,8 @@ import de.danoeh.antennapod.core.service.GpodnetSyncService; */ public class GpodnetPreferences { + private GpodnetPreferences(){} + private static final String TAG = "GpodnetPreferences"; private static final String PREF_NAME = "gpodder.net"; 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 index b7ed890f5..0f3a9fcb3 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/preferences/SleepTimerPreferences.java +++ b/core/src/main/java/de/danoeh/antennapod/core/preferences/SleepTimerPreferences.java @@ -23,7 +23,6 @@ public class SleepTimerPreferences { private static final String DEFAULT_VALUE = "15"; private static final int DEFAULT_TIME_UNIT = 1; - private static Context context; private static SharedPreferences prefs; /** 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 44b2fa2b2..805f0c1b6 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 @@ -8,14 +8,7 @@ import android.support.annotation.NonNull; import android.support.v4.app.NotificationCompat; import android.text.TextUtils; import android.util.Log; -import de.danoeh.antennapod.core.R; -import de.danoeh.antennapod.core.service.download.ProxyConfig; -import de.danoeh.antennapod.core.storage.APCleanupAlgorithm; -import de.danoeh.antennapod.core.storage.APNullCleanupAlgorithm; -import de.danoeh.antennapod.core.storage.APQueueCleanupAlgorithm; -import de.danoeh.antennapod.core.storage.EpisodeCleanupAlgorithm; -import de.danoeh.antennapod.core.util.Converter; -import de.danoeh.antennapod.core.util.download.AutoUpdateManager; + import org.json.JSONArray; import org.json.JSONException; @@ -27,6 +20,15 @@ import java.util.Arrays; import java.util.List; import java.util.concurrent.TimeUnit; +import de.danoeh.antennapod.core.R; +import de.danoeh.antennapod.core.service.download.ProxyConfig; +import de.danoeh.antennapod.core.storage.APCleanupAlgorithm; +import de.danoeh.antennapod.core.storage.APNullCleanupAlgorithm; +import de.danoeh.antennapod.core.storage.APQueueCleanupAlgorithm; +import de.danoeh.antennapod.core.storage.EpisodeCleanupAlgorithm; +import de.danoeh.antennapod.core.util.Converter; +import de.danoeh.antennapod.core.util.download.AutoUpdateManager; + /** * Provides access to preferences set by the user in the settings screen. A * private instance of this class must first be instantiated via @@ -34,6 +36,7 @@ import java.util.concurrent.TimeUnit; * when called. */ public class UserPreferences { + private UserPreferences(){} private static final String IMPORT_DIR = "import/"; @@ -44,11 +47,13 @@ public class UserPreferences { public static final String PREF_HIDDEN_DRAWER_ITEMS = "prefHiddenDrawerItems"; private static final String PREF_DRAWER_FEED_ORDER = "prefDrawerFeedOrder"; private static final String PREF_DRAWER_FEED_COUNTER = "prefDrawerFeedIndicator"; - private static final String PREF_EXPANDED_NOTIFICATION = "prefExpandNotify"; + public static final String PREF_EXPANDED_NOTIFICATION = "prefExpandNotify"; private static final String PREF_PERSISTENT_NOTIFICATION = "prefPersistNotify"; public static final String PREF_COMPACT_NOTIFICATION_BUTTONS = "prefCompactNotificationButtons"; public static final String PREF_LOCKSCREEN_BACKGROUND = "prefLockscreenBackground"; private static final String PREF_SHOW_DOWNLOAD_REPORT = "prefShowDownloadReport"; + public static final String PREF_BACK_BUTTON_BEHAVIOR = "prefBackButtonBehavior"; + private static final String PREF_BACK_BUTTON_GO_TO_PAGE = "prefBackButtonGoToPage"; // Queue private static final String PREF_QUEUE_ADD_TO_FRONT = "prefQueueAddToFront"; @@ -72,7 +77,7 @@ public class UserPreferences { // Network private static final String PREF_ENQUEUE_DOWNLOADED = "prefEnqueueDownloaded"; public static final String PREF_UPDATE_INTERVAL = "prefAutoUpdateIntervall"; - private static final String PREF_MOBILE_UPDATE = "prefMobileUpdate"; + public static final String PREF_MOBILE_UPDATE = "prefMobileUpdateAllowed"; public static final String PREF_EPISODE_CLEANUP = "prefEpisodeCleanup"; public static final String PREF_PARALLEL_DOWNLOADS = "prefParallelDownloads"; public static final String PREF_EPISODE_CACHE_SIZE = "prefEpisodeCacheSize"; @@ -95,9 +100,13 @@ public class UserPreferences { // Other private static final String PREF_DATA_FOLDER = "prefDataFolder"; public static final String PREF_IMAGE_CACHE_SIZE = "prefImageCacheSize"; + public static final String PREF_DELETE_REMOVES_FROM_QUEUE = "prefDeleteRemovesFromQueue"; // Mediaplayer + public static final String PREF_MEDIA_PLAYER = "prefMediaPlayer"; + public static final String PREF_MEDIA_PLAYER_EXOPLAYER = "exoplayer"; private static final String PREF_PLAYBACK_SPEED = "prefPlaybackSpeed"; + public static final String PREF_PLAYBACK_SKIP_SILENCE = "prefSkipSilence"; private static final String PREF_FAST_FORWARD_SECS = "prefFastForwardSecs"; private static final String PREF_REWIND_SECS = "prefRewindSecs"; private static final String PREF_QUEUE_LOCKED = "prefQueueLocked"; @@ -107,9 +116,7 @@ public class UserPreferences { private static final String PREF_RIGHT_VOLUME = "prefRightVolume"; // Experimental - public static final String PREF_SONIC = "prefSonic"; private static final String PREF_STEREO_TO_MONO = "PrefStereoToMono"; - public static final String PREF_NORMALIZER = "prefNormalizer"; public static final String PREF_CAST_ENABLED = "prefCast"; //Used for enabling Chromecast support public static final int EPISODE_CLEANUP_QUEUE = -1; public static final int EPISODE_CLEANUP_NULL = -2; @@ -122,7 +129,6 @@ public class UserPreferences { private static final int EPISODE_CACHE_SIZE_UNLIMITED = -1; public static final int FEED_ORDER_COUNTER = 0; public static final int FEED_ORDER_ALPHABETICAL = 1; - public static final int FEED_ORDER_LAST_UPDATE = 2; public static final int FEED_ORDER_MOST_PLAYED = 3; public static final int FEED_COUNTER_SHOW_NEW_UNPLAYED_SUM = 0; public static final int FEED_COUNTER_SHOW_NEW = 1; @@ -161,6 +167,8 @@ public class UserPreferences { int theme = getTheme(); if (theme == R.style.Theme_AntennaPod_Dark) { return R.style.Theme_AntennaPod_Dark_NoTitle; + } else if (theme == R.style.Theme_AntennaPod_TrueBlack) { + return R.style.Theme_AntennaPod_TrueBlack_NoTitle; } else { return R.style.Theme_AntennaPod_Light_NoTitle; } @@ -304,6 +312,10 @@ public class UserPreferences { return Integer.parseInt(prefs.getString(PREF_SMART_MARK_AS_PLAYED_SECS, "30")); } + public static boolean shouldDeleteRemoveFromQueue() { + return prefs.getBoolean(PREF_DELETE_REMOVES_FROM_QUEUE, false); + } + public static boolean isAutoFlattr() { return prefs.getBoolean(PREF_AUTO_FLATTR, false); } @@ -312,6 +324,10 @@ public class UserPreferences { return prefs.getString(PREF_PLAYBACK_SPEED, "1.00"); } + public static boolean isSkipSilence() { + return prefs.getBoolean(PREF_PLAYBACK_SKIP_SILENCE, false); + } + public static String[] getPlaybackSpeedArray() { return readPlaybackSpeedArray(prefs.getString(PREF_PLAYBACK_SPEED_ARRAY, null)); } @@ -364,8 +380,16 @@ public class UserPreferences { } } + public static String getMobileUpdatesEnabled() { + return prefs.getString(PREF_MOBILE_UPDATE, "images"); + } + public static boolean isAllowMobileUpdate() { - return prefs.getBoolean(PREF_MOBILE_UPDATE, false); + return getMobileUpdatesEnabled().equals("everything"); + } + + public static boolean isAllowMobileImages() { + return isAllowMobileUpdate() || getMobileUpdatesEnabled().equals("images"); } public static int getParallelDownloads() { @@ -498,6 +522,12 @@ public class UserPreferences { .apply(); } + public static void setSkipSilence(boolean skipSilence) { + prefs.edit() + .putBoolean(PREF_PLAYBACK_SKIP_SILENCE, skipSilence) + .apply(); + } + public static void setPlaybackSpeedArray(String[] speeds) { JSONArray jsonArray = new JSONArray(); for (String speed : speeds) { @@ -597,6 +627,8 @@ public class UserPreferences { return R.style.Theme_AntennaPod_Light; case 1: return R.style.Theme_AntennaPod_Dark; + case 2: + return R.style.Theme_AntennaPod_TrueBlack; default: return R.style.Theme_AntennaPod_Light; } @@ -636,13 +668,15 @@ public class UserPreferences { } public static boolean useSonic() { - return prefs.getBoolean(PREF_SONIC, false); + return prefs.getString(PREF_MEDIA_PLAYER, "sonic").equals("sonic"); } - public static void enableSonic(boolean enable) { - prefs.edit() - .putBoolean(PREF_SONIC, enable) - .apply(); + public static boolean useExoplayer() { + return prefs.getString(PREF_MEDIA_PLAYER, "sonic").equals(PREF_MEDIA_PLAYER_EXOPLAYER); + } + + public static void enableSonic() { + prefs.edit().putString(PREF_MEDIA_PLAYER, "sonic").apply(); } public static boolean stereoToMono() { @@ -665,7 +699,7 @@ public class UserPreferences { } public static EpisodeCleanupAlgorithm getEpisodeCleanupAlgorithm() { - int cleanupValue = Integer.parseInt(prefs.getString(PREF_EPISODE_CLEANUP, "-1")); + int cleanupValue = getEpisodeCleanupValue(); if (cleanupValue == EPISODE_CLEANUP_QUEUE) { return new APQueueCleanupAlgorithm(); } else if (cleanupValue == EPISODE_CLEANUP_NULL) { @@ -675,6 +709,16 @@ public class UserPreferences { } } + public static int getEpisodeCleanupValue() { + return Integer.parseInt(prefs.getString(PREF_EPISODE_CLEANUP, "-1")); + } + + public static void setEpisodeCleanupValue(int episodeCleanupValue) { + prefs.edit() + .putString(PREF_EPISODE_CLEANUP, Integer.toString(episodeCleanupValue)) + .apply(); + } + /** * Return the folder where the app stores all of its data. This method will * return the standard data folder if none has been set by the user. @@ -802,4 +846,29 @@ public class UserPreferences { public enum VideoBackgroundBehavior { STOP, PICTURE_IN_PICTURE, CONTINUE_PLAYING } + + public enum BackButtonBehavior { + DEFAULT, OPEN_DRAWER, DOUBLE_TAP, SHOW_PROMPT, GO_TO_PAGE + } + + public static BackButtonBehavior getBackButtonBehavior() { + switch (prefs.getString(PREF_BACK_BUTTON_BEHAVIOR, "default")) { + case "default": return BackButtonBehavior.DEFAULT; + case "drawer": return BackButtonBehavior.OPEN_DRAWER; + case "doubletap": return BackButtonBehavior.DOUBLE_TAP; + case "prompt": return BackButtonBehavior.SHOW_PROMPT; + case "page": return BackButtonBehavior.GO_TO_PAGE; + default: return BackButtonBehavior.DEFAULT; + } + } + + public static String getBackButtonGoToPage() { + return prefs.getString(PREF_BACK_BUTTON_GO_TO_PAGE, "QueueFragment"); + } + + public static void setBackButtonGoToPage(String tag) { + prefs.edit() + .putString(PREF_BACK_BUTTON_GO_TO_PAGE, tag) + .apply(); + } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/receiver/PlayerWidget.java b/core/src/main/java/de/danoeh/antennapod/core/receiver/PlayerWidget.java index edc2ea3e0..7663cdbe4 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/receiver/PlayerWidget.java +++ b/core/src/main/java/de/danoeh/antennapod/core/receiver/PlayerWidget.java @@ -6,10 +6,11 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.util.Log; -import de.danoeh.antennapod.core.service.PlayerWidgetJobService; import java.util.Arrays; +import de.danoeh.antennapod.core.service.PlayerWidgetJobService; + public class PlayerWidget extends AppWidgetProvider { private static final String TAG = "PlayerWidget"; diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateJobService.java b/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateJobService.java index 55a8d6b86..7d80d4e7c 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateJobService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateJobService.java @@ -5,6 +5,7 @@ import android.app.job.JobService; import android.os.Build; import android.support.annotation.RequiresApi; import android.util.Log; + import de.danoeh.antennapod.core.ClientConfig; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.util.FeedUpdateUtils; diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java b/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java index de040603d..5584991ca 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java @@ -6,8 +6,8 @@ import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.support.annotation.NonNull; -import android.support.v4.app.JobIntentService; import android.support.v4.app.NotificationCompat; +import android.support.v4.app.SafeJobIntentService; import android.support.v4.util.ArrayMap; import android.util.Log; import android.util.Pair; @@ -44,7 +44,8 @@ import de.danoeh.antennapod.core.util.gui.NotificationUtils; * Synchronizes local subscriptions with gpodder.net service. The service should be started with ACTION_SYNC as an action argument. * This class also provides static methods for starting the GpodnetSyncService. */ -public class GpodnetSyncService extends JobIntentService { +public class GpodnetSyncService extends SafeJobIntentService { + private static final String TAG = "GpodnetSyncService"; private static final long WAIT_INTERVAL = 5000L; @@ -61,8 +62,10 @@ public class GpodnetSyncService extends JobIntentService { private static boolean syncSubscriptions = false; private static boolean syncActions = false; + private static final int JOB_ID = -17000; + private static void enqueueWork(Context context, Intent intent) { - enqueueWork(context, GpodnetSyncService.class, 0, intent); + enqueueWork(context, GpodnetSyncService.class, JOB_ID, intent); } @Override diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java b/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java index 4948912ca..dbf80cf37 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java @@ -10,7 +10,7 @@ import android.graphics.Bitmap; import android.os.Build; import android.os.IBinder; import android.support.annotation.NonNull; -import android.support.v4.app.JobIntentService; +import android.support.v4.app.SafeJobIntentService; import android.util.Log; import android.view.KeyEvent; import android.view.View; @@ -21,23 +21,26 @@ import com.bumptech.glide.Glide; import de.danoeh.antennapod.core.R; import de.danoeh.antennapod.core.glide.ApGlideSettings; import de.danoeh.antennapod.core.receiver.MediaButtonReceiver; +import de.danoeh.antennapod.core.receiver.PlayerWidget; import de.danoeh.antennapod.core.service.playback.PlaybackService; import de.danoeh.antennapod.core.service.playback.PlayerStatus; import de.danoeh.antennapod.core.util.Converter; import de.danoeh.antennapod.core.util.playback.Playable; -import de.danoeh.antennapod.core.receiver.PlayerWidget; /** * Updates the state of the player widget */ -public class PlayerWidgetJobService extends JobIntentService { +public class PlayerWidgetJobService extends SafeJobIntentService { + private static final String TAG = "PlayerWidgetJobService"; private PlaybackService playbackService; private final Object waitForService = new Object(); + private static final int JOB_ID = -17001; + public static void updateWidget(Context context) { - enqueueWork(context, PlayerWidgetJobService.class, 0, new Intent(context, PlayerWidgetJobService.class)); + enqueueWork(context, PlayerWidgetJobService.class, JOB_ID, new Intent(context, PlayerWidgetJobService.class)); } @Override @@ -46,8 +49,8 @@ public class PlayerWidgetJobService extends JobIntentService { return; } - if (PlaybackService.isRunning && playbackService == null) { - synchronized (waitForService) { + synchronized (waitForService) { + if (PlaybackService.isRunning && playbackService == null) { bindService(new Intent(this, PlaybackService.class), mConnection, 0); while (playbackService == null) { try { 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 57d099dfc..97007a214 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 @@ -40,6 +40,9 @@ import okhttp3.internal.http.StatusLine; * Provides access to a HttpClient singleton. */ public class AntennapodHttpClient { + + private AntennapodHttpClient(){} + private static final String TAG = "AntennapodHttpClient"; private static final int CONNECTION_TIMEOUT = 30000; diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadRequest.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadRequest.java index 9a64bebf7..48234c387 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadRequest.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadRequest.java @@ -124,7 +124,7 @@ public class DownloadRequest implements Parcelable { @Override public boolean equals(Object o) { if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (o == null || !(o instanceof DownloadRequest)) return false; DownloadRequest that = (DownloadRequest) o; @@ -211,10 +211,6 @@ public class DownloadRequest implements Parcelable { this.size = size; } - public int getStatusMsg() { - return statusMsg; - } - public void setStatusMsg(int statusMsg) { this.statusMsg = statusMsg; } 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 9c2266622..ae1e9de86 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 @@ -13,14 +13,12 @@ import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.support.annotation.NonNull; -import android.support.annotation.VisibleForTesting; import android.support.v4.app.NotificationCompat; import android.text.TextUtils; import android.util.Log; import android.util.Pair; import android.webkit.URLUtil; -import de.danoeh.antennapod.core.util.gui.NotificationUtils; import org.apache.commons.io.FileUtils; import org.xml.sax.SAXException; @@ -30,10 +28,8 @@ import java.net.HttpURLConnection; import java.util.ArrayList; import java.util.Collections; import java.util.Date; -import java.util.HashSet; import java.util.LinkedList; import java.util.List; -import java.util.Set; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.CompletionService; @@ -55,7 +51,6 @@ import de.danoeh.antennapod.core.R; import de.danoeh.antennapod.core.event.DownloadEvent; import de.danoeh.antennapod.core.event.FeedItemEvent; import de.danoeh.antennapod.core.feed.Feed; -import de.danoeh.antennapod.core.feed.FeedImage; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.feed.FeedPreferences; @@ -75,6 +70,7 @@ import de.danoeh.antennapod.core.syndication.handler.UnsupportedFeedtypeExceptio import de.danoeh.antennapod.core.util.ChapterUtils; import de.danoeh.antennapod.core.util.DownloadError; import de.danoeh.antennapod.core.util.InvalidFeedException; +import de.danoeh.antennapod.core.util.gui.NotificationUtils; import de.greenrobot.event.EventBus; /** @@ -117,11 +113,6 @@ public class DownloadService extends Service { private CompletionService<Downloader> downloadExecutor; private FeedSyncThread feedSyncThread; - /** - * Number of threads of downloadExecutor. - */ - private static final int NUM_PARALLEL_DOWNLOADS = 6; - private DownloadRequester requester; @@ -489,9 +480,7 @@ public class DownloadService extends Service { if (status.isSuccessful()) { successfulDownloads++; } else if (!status.isCancelled()) { - if (status.getFeedfileType() != FeedImage.FEEDFILETYPE_FEEDIMAGE) { - createReport = true; - } + createReport = true; failedDownloads++; } } @@ -688,10 +677,6 @@ public class DownloadService extends Service { Log.d(TAG, "Bundling " + results.size() + " feeds"); - for (Pair<DownloadRequest, FeedHandlerResult> result : results) { - removeDuplicateImages(result.second.feed); // duplicate images have to removed because the DownloadRequester does not accept two downloads with the same download URL yet. - } - // Save information of feed in DB if (dbUpdateFuture != null) { try { @@ -866,22 +851,6 @@ public class DownloadService extends Service { return true; } - /** - * Delete files that aren't needed anymore - */ - private void cleanup(Feed feed) { - if (feed.getFile_url() != null) { - if (new File(feed.getFile_url()).delete()) { - Log.d(TAG, "Successfully deleted cache file."); - } else { - Log.e(TAG, "Failed to delete cache file."); - } - feed.setFile_url(null); - } else { - Log.d(TAG, "Didn't delete cache file: File url is not set."); - } - } - public void shutdown() { isActive = false; if (isCollectingRequests) { @@ -1101,26 +1070,6 @@ public class DownloadService extends Service { } } - /** - * Checks if the FeedItems of this feed have images that point to the same URL. If two FeedItems - * have an image that points to the same URL, the reference of the second item is removed, so - * that every image reference is unique. - */ - @VisibleForTesting - static void removeDuplicateImages(Feed feed) { - Set<String> known = new HashSet<>(); - for (FeedItem item : feed.getItems()) { - String url = item.hasItemImage() ? item.getImage().getDownload_url() : null; - if (url != null) { - if (known.contains(url)) { - item.setImage(null); - } else { - known.add(url); - } - } - } - } - private static String compileNotificationString(List<Downloader> downloads) { List<String> lines = new ArrayList<>(downloads.size()); for (Downloader downloader : downloads) { diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/Downloader.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/Downloader.java index 445210d3a..38b93eab8 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/Downloader.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/Downloader.java @@ -2,6 +2,7 @@ package de.danoeh.antennapod.core.service.download; import android.content.Context; import android.net.wifi.WifiManager; +import android.support.annotation.NonNull; import java.util.concurrent.Callable; @@ -18,10 +19,12 @@ public abstract class Downloader implements Callable<Downloader> { volatile boolean cancelled; + @NonNull final DownloadRequest request; + @NonNull final DownloadStatus result; - Downloader(DownloadRequest request) { + Downloader(@NonNull DownloadRequest request) { super(); this.request = request; this.request.setStatusMsg(R.string.download_pending); @@ -54,10 +57,12 @@ public abstract class Downloader implements Callable<Downloader> { return this; } + @NonNull public DownloadRequest getDownloadRequest() { return request; } + @NonNull public DownloadStatus getResult() { return result; } diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloaderCallback.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloaderCallback.java deleted file mode 100644 index b0829f084..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloaderCallback.java +++ /dev/null @@ -1,10 +0,0 @@ -package de.danoeh.antennapod.core.service.download; - -/** - * Callback used by the Downloader-classes to notify the requester that the - * download has completed. - */ -public interface DownloaderCallback { - - void onDownloadCompleted(Downloader downloader); -} 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 7ab0931d6..c27cefc10 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 @@ -1,5 +1,6 @@ package de.danoeh.antennapod.core.service.download; +import android.support.annotation.NonNull; import android.text.TextUtils; import android.util.Log; @@ -20,7 +21,6 @@ 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; @@ -39,7 +39,7 @@ public class HttpDownloader extends Downloader { private static final int BUFFER_SIZE = 8 * 1024; - public HttpDownloader(DownloadRequest request) { + public HttpDownloader(@NonNull DownloadRequest request) { super(request); } @@ -50,13 +50,8 @@ public class HttpDownloader extends Downloader { if (request.isDeleteOnFailure() && fileExists) { Log.w(TAG, "File already exists"); - if (request.getFeedfileType() != FeedImage.FEEDFILETYPE_FEEDIMAGE) { - onFail(DownloadError.ERROR_FILE_EXISTS, null); - return; - } else { - onSuccess(); - return; - } + onSuccess(); + return; } OkHttpClient.Builder httpClientBuilder = AntennapodHttpClient.newBuilder(); @@ -310,7 +305,7 @@ public class HttpDownloader extends Downloader { String encoded = ByteString.of(bytes).base64(); return "Basic " + encoded; } catch (UnsupportedEncodingException e) { - throw new AssertionError(); + throw new AssertionError(e); } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java new file mode 100644 index 000000000..281bd064b --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java @@ -0,0 +1,249 @@ +package de.danoeh.antennapod.core.service.playback; + +import android.content.Context; +import android.net.Uri; +import android.view.SurfaceHolder; + +import com.google.android.exoplayer2.C; +import com.google.android.exoplayer2.DefaultLoadControl; +import com.google.android.exoplayer2.DefaultRenderersFactory; +import com.google.android.exoplayer2.ExoPlaybackException; +import com.google.android.exoplayer2.ExoPlayerFactory; +import com.google.android.exoplayer2.PlaybackParameters; +import com.google.android.exoplayer2.Player; +import com.google.android.exoplayer2.SeekParameters; +import com.google.android.exoplayer2.SimpleExoPlayer; +import com.google.android.exoplayer2.Timeline; +import com.google.android.exoplayer2.audio.AudioAttributes; +import com.google.android.exoplayer2.source.ExtractorMediaSource; +import com.google.android.exoplayer2.source.MediaSource; +import com.google.android.exoplayer2.source.TrackGroupArray; +import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; +import com.google.android.exoplayer2.trackselection.TrackSelectionArray; +import com.google.android.exoplayer2.upstream.DataSource; +import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; +import com.google.android.exoplayer2.util.Util; + +import org.antennapod.audio.MediaPlayer; +import de.danoeh.antennapod.core.util.playback.IPlayer; + + +public class ExoPlayerWrapper implements IPlayer { + private final Context mContext; + private SimpleExoPlayer mExoPlayer; + private MediaSource mediaSource; + private MediaPlayer.OnSeekCompleteListener audioSeekCompleteListener; + private MediaPlayer.OnCompletionListener audioCompletionListener; + private MediaPlayer.OnErrorListener audioErrorListener; + + ExoPlayerWrapper(Context context) { + mContext = context; + mExoPlayer = createPlayer(); + } + + private SimpleExoPlayer createPlayer() { + SimpleExoPlayer p = ExoPlayerFactory.newSimpleInstance(mContext, new DefaultRenderersFactory(mContext), + new DefaultTrackSelector(), new DefaultLoadControl()); + p.setSeekParameters(SeekParameters.PREVIOUS_SYNC); + p.addListener(new Player.EventListener() { + @Override + public void onTimelineChanged(Timeline timeline, Object manifest, int reason) { + + } + + @Override + public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) { + + } + + @Override + public void onLoadingChanged(boolean isLoading) { + + } + + @Override + public void onPlayerStateChanged(boolean playWhenReady, int playbackState) { + if (playbackState == Player.STATE_ENDED) { + audioCompletionListener.onCompletion(null); + } + } + + @Override + public void onRepeatModeChanged(int repeatMode) { + + } + + @Override + public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) { + + } + + @Override + public void onPlayerError(ExoPlaybackException error) { + if (audioErrorListener != null) { + audioErrorListener.onError(null, 0, 0); + } + } + + @Override + public void onPositionDiscontinuity(int reason) { + + } + + @Override + public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) { + + } + + @Override + public void onSeekProcessed() { + audioSeekCompleteListener.onSeekComplete(null); + } + }); + return p; + } + + @Override + public boolean canSetSpeed() { + return true; + } + + @Override + public boolean canDownmix() { + return false; + } + + @Override + public int getCurrentPosition() { + return (int) mExoPlayer.getCurrentPosition(); + } + + @Override + public float getCurrentSpeedMultiplier() { + return mExoPlayer.getPlaybackParameters().speed; + } + + @Override + public int getDuration() { + if (mExoPlayer.getDuration() == C.TIME_UNSET) { + return PlaybackServiceMediaPlayer.INVALID_TIME; + } + return (int) mExoPlayer.getDuration(); + } + + @Override + public boolean isPlaying() { + return mExoPlayer.getPlayWhenReady(); + } + + @Override + public void pause() { + mExoPlayer.setPlayWhenReady(false); + } + + @Override + public void prepare() throws IllegalStateException { + mExoPlayer.prepare(mediaSource); + } + + @Override + public void release() { + if (mExoPlayer != null) { + mExoPlayer.release(); + } + audioSeekCompleteListener = null; + audioCompletionListener = null; + audioErrorListener = null; + } + + @Override + public void reset() { + mExoPlayer.release(); + mExoPlayer = createPlayer(); + } + + @Override + public void seekTo(int i) throws IllegalStateException { + mExoPlayer.seekTo(i); + } + + @Override + public void setAudioStreamType(int i) { + AudioAttributes a = mExoPlayer.getAudioAttributes(); + AudioAttributes.Builder b = new AudioAttributes.Builder(); + b.setContentType(i); + b.setFlags(a.flags); + b.setUsage(a.usage); + mExoPlayer.setAudioAttributes(b.build()); + } + + @Override + public void setDataSource(String s) throws IllegalArgumentException, IllegalStateException { + DataSource.Factory dataSourceFactory = + new DefaultDataSourceFactory(mContext, Util.getUserAgent(mContext, mContext.getPackageName()), null); + ExtractorMediaSource.Factory f = new ExtractorMediaSource.Factory(dataSourceFactory); + mediaSource = f.createMediaSource(Uri.parse(s)); + } + + @Override + public void setDisplay(SurfaceHolder sh) { + mExoPlayer.setVideoSurfaceHolder(sh); + } + + @Override + public void setPlaybackParams(float speed, boolean skipSilence) { + PlaybackParameters params = mExoPlayer.getPlaybackParameters(); + mExoPlayer.setPlaybackParameters(new PlaybackParameters(speed, params.pitch, skipSilence)); + } + + @Override + public void setDownmix(boolean b) { + + } + + @Override + public void setVolume(float v, float v1) { + mExoPlayer.setVolume(v); + } + + @Override + public void setWakeMode(Context context, int i) { + + } + + @Override + public void start() { + mExoPlayer.setPlayWhenReady(true); + } + + @Override + public void stop() { + mExoPlayer.stop(); + } + + void setOnCompletionListener(MediaPlayer.OnCompletionListener audioCompletionListener) { + this.audioCompletionListener = audioCompletionListener; + } + + void setOnSeekCompleteListener(MediaPlayer.OnSeekCompleteListener audioSeekCompleteListener) { + this.audioSeekCompleteListener = audioSeekCompleteListener; + } + + void setOnErrorListener(MediaPlayer.OnErrorListener audioErrorListener) { + this.audioErrorListener = audioErrorListener; + } + + int getVideoWidth() { + if (mExoPlayer.getVideoFormat() == null) { + return 0; + } + return mExoPlayer.getVideoFormat().width; + } + + int getVideoHeight() { + if (mExoPlayer.getVideoFormat() == null) { + return 0; + } + return mExoPlayer.getVideoFormat().height; + } +} 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 0e64f484f..9274b9a49 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 @@ -1,7 +1,10 @@ package de.danoeh.antennapod.core.service.playback; import android.content.Context; +import android.media.AudioAttributes; +import android.media.AudioFocusRequest; import android.media.AudioManager; +import android.os.Build; import android.os.PowerManager; import android.support.annotation.NonNull; import android.telephony.TelephonyManager; @@ -202,9 +205,26 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { private void resumeSync() { if (playerStatus == PlayerStatus.PAUSED || playerStatus == PlayerStatus.PREPARED) { - int focusGained = audioManager.requestAudioFocus( - audioFocusChangeListener, AudioManager.STREAM_MUSIC, - AudioManager.AUDIOFOCUS_GAIN); + int focusGained; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + AudioAttributes audioAttributes = new AudioAttributes.Builder() + .setUsage(AudioAttributes.USAGE_MEDIA) + .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH) + .build(); + AudioFocusRequest audioFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN) + .setAudioAttributes(audioAttributes) + .setOnAudioFocusChangeListener(audioFocusChangeListener) + .setAcceptsDelayedFocusGain(true) + .setWillPauseWhenDucked(true) + .build(); + focusGained = audioManager.requestAudioFocus(audioFocusRequest); + } else { + focusGained = audioManager.requestAudioFocus( + audioFocusChangeListener, AudioManager.STREAM_MUSIC, + AudioManager.AUDIOFOCUS_GAIN); + } + if (focusGained == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { Log.d(TAG, "Audiofocus successfully requested"); Log.d(TAG, "Resuming/Starting playback"); @@ -216,7 +236,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { Log.e(TAG, Log.getStackTraceString(e)); UserPreferences.setPlaybackSpeed(String.valueOf(speed)); } - setSpeed(speed); + setPlaybackParams(speed, UserPreferences.isSkipSilence()); setVolume(UserPreferences.getLeftVolume(), UserPreferences.getRightVolume()); if (playerStatus == PlayerStatus.PREPARED && media.getPosition() > 0) { @@ -259,7 +279,13 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { setPlayerStatus(PlayerStatus.PAUSED, media, getPosition()); if (abandonFocus) { - audioManager.abandonAudioFocus(audioFocusChangeListener); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + AudioFocusRequest.Builder builder = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN) + .setOnAudioFocusChangeListener(audioFocusChangeListener); + audioManager.abandonAudioFocusRequest(builder.build()); + } else { + audioManager.abandonAudioFocus(audioFocusChangeListener); + } pausedBecauseOfTransientAudiofocusLoss = false; } if (stream && reinit) { @@ -313,7 +339,10 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { Log.d(TAG, "Resource prepared"); - if (mediaType == MediaType.VIDEO) { + if (mediaType == MediaType.VIDEO && mediaPlayer instanceof ExoPlayerWrapper) { + ExoPlayerWrapper vp = (ExoPlayerWrapper) mediaPlayer; + videoSize = new Pair<>(vp.getVideoWidth(), vp.getVideoHeight()); + } else if(mediaType == MediaType.VIDEO && mediaPlayer instanceof VideoPlayer) { VideoPlayer vp = (VideoPlayer) mediaPlayer; videoSize = new Pair<>(vp.getVideoWidth(), vp.getVideoHeight()); } @@ -447,7 +476,8 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { || playerStatus == PlayerStatus.PAUSED || playerStatus == PlayerStatus.PREPARED) { retVal = mediaPlayer.getDuration(); - } else if (media != null && media.getDuration() > 0) { + } + if (retVal <= 0 && media != null && media.getDuration() > 0) { retVal = media.getDuration(); } @@ -507,14 +537,14 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { * Sets the playback speed. * This method is executed on the caller's thread. */ - private void setSpeedSync(float speed) { + private void setSpeedSyncAndSkipSilence(float speed, boolean skipSilence) { playerLock.lock(); if (media != null && media.getMediaType() == MediaType.AUDIO) { if (mediaPlayer.canSetSpeed()) { - mediaPlayer.setPlaybackSpeed(speed); Log.d(TAG, "Playback speed was set to " + speed); callback.playbackSpeedChanged(speed); } + mediaPlayer.setPlaybackParams(speed, skipSilence); } playerLock.unlock(); } @@ -524,8 +554,8 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { * This method is executed on an internal executor service. */ @Override - public void setSpeed(final float speed) { - executor.submit(() -> setSpeedSync(speed)); + public void setPlaybackParams(final float speed, final boolean skipSilence) { + executor.submit(() -> setSpeedSyncAndSkipSilence(speed, skipSilence)); } /** @@ -610,13 +640,29 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { executor.shutdown(); if (mediaPlayer != null) { try { - mediaPlayer.stop(); + removeMediaPlayerErrorListener(); + if (mediaPlayer.isPlaying()) { + mediaPlayer.stop(); + } } catch (Exception ignore) { } mediaPlayer.release(); } releaseWifiLockIfNecessary(); } + private void removeMediaPlayerErrorListener() { + if (mediaPlayer instanceof VideoPlayer) { + VideoPlayer vp = (VideoPlayer) mediaPlayer; + vp.setOnErrorListener((mp, what, extra) -> true); + } else if (mediaPlayer instanceof AudioPlayer) { + AudioPlayer ap = (AudioPlayer) mediaPlayer; + ap.setOnErrorListener((mediaPlayer, i, i1) -> true); + } else if (mediaPlayer instanceof ExoPlayerWrapper) { + ExoPlayerWrapper ap = (ExoPlayerWrapper) mediaPlayer; + ap.setOnErrorListener((mediaPlayer, i, i1) -> true); + } + } + /** * Releases internally used resources. This method should only be called when the object is not used anymore. * This method is executed on an internal executor service. @@ -669,6 +715,10 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { Pair<Integer, Integer> res; if (mediaPlayer == null || playerStatus == PlayerStatus.ERROR || mediaType != MediaType.VIDEO) { res = null; + } else if (mediaPlayer instanceof ExoPlayerWrapper) { + ExoPlayerWrapper vp = (ExoPlayerWrapper) mediaPlayer; + videoSize = new Pair<>(vp.getVideoWidth(), vp.getVideoHeight()); + res = videoSize; } else { VideoPlayer vp = (VideoPlayer) mediaPlayer; videoSize = new Pair<>(vp.getVideoWidth(), vp.getVideoHeight()); @@ -698,15 +748,19 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { if (mediaPlayer != null) { mediaPlayer.release(); } - if(media == null) { + if (media == null) { mediaPlayer = null; return; } - if (media.getMediaType() == MediaType.VIDEO) { + + if (UserPreferences.useExoplayer()) { + mediaPlayer = new ExoPlayerWrapper(context); + } else if (media.getMediaType() == MediaType.VIDEO) { mediaPlayer = new VideoPlayer(); } else { mediaPlayer = new AudioPlayer(context); } + mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.setWakeMode(context, PowerManager.PARTIAL_WAKE_LOCK); setMediaPlayerListeners(mediaPlayer); @@ -787,7 +841,14 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { if (mediaPlayer != null) { mediaPlayer.reset(); } - audioManager.abandonAudioFocus(audioFocusChangeListener); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + AudioFocusRequest.Builder builder = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN) + .setOnAudioFocusChangeListener(audioFocusChangeListener); + audioManager.abandonAudioFocusRequest(builder.build()); + } else { + audioManager.abandonAudioFocus(audioFocusChangeListener); + } final Playable currentMedia = media; Playable nextMedia = null; @@ -883,6 +944,11 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { ap.setOnBufferingUpdateListener(audioBufferingUpdateListener); ap.setOnInfoListener(audioInfoListener); ap.setOnSpeedAdjustmentAvailableChangedListener(audioSetSpeedAbilityListener); + } else if (mp instanceof ExoPlayerWrapper) { + ExoPlayerWrapper ap = (ExoPlayerWrapper) mp; + ap.setOnCompletionListener(audioCompletionListener); + ap.setOnSeekCompleteListener(audioSeekCompleteListener); + ap.setOnErrorListener(audioErrorListener); } else { Log.w(TAG, "Unknown media player: " + mp); } @@ -925,7 +991,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { private final MediaPlayer.OnErrorListener audioErrorListener = (mp, what, extra) -> { - if(mp.canFallback()) { + if(mp != null && mp.canFallback()) { mp.fallback(); return true; } else { 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 be6cb346d..7fe93a162 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 @@ -24,13 +24,14 @@ import android.os.Vibrator; import android.preference.PreferenceManager; import android.support.annotation.NonNull; import android.support.annotation.StringRes; +import android.support.v4.app.NotificationCompat; +import android.support.v4.content.ContextCompat; import android.support.v4.media.MediaBrowserCompat; import android.support.v4.media.MediaBrowserServiceCompat; import android.support.v4.media.MediaDescriptionCompat; import android.support.v4.media.MediaMetadataCompat; import android.support.v4.media.session.MediaSessionCompat; import android.support.v4.media.session.PlaybackStateCompat; -import android.support.v4.app.NotificationCompat; import android.text.TextUtils; import android.util.Log; import android.util.Pair; @@ -39,6 +40,7 @@ import android.view.SurfaceHolder; import android.widget.Toast; import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.target.Target; import java.util.ArrayList; @@ -65,14 +67,20 @@ import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.storage.FeedSearcher; import de.danoeh.antennapod.core.util.IntList; -import de.danoeh.antennapod.core.util.gui.NotificationUtils; +import de.danoeh.antennapod.core.util.IntentUtils; import de.danoeh.antennapod.core.util.QueueAccess; +import de.danoeh.antennapod.core.util.gui.NotificationUtils; 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 + * + * Callers should connect to the service with either: + * - .bindService() + * - ContextCompat.startForegroundService(), optionally with arguments, such as media to be played, in intent extras + * */ public class PlaybackService extends MediaBrowserServiceCompat { /** @@ -191,10 +199,6 @@ public class PlaybackService extends MediaBrowserServiceCompat { */ public static boolean isRunning = false; /** - * Is true if service has received a valid start command. - */ - public static boolean started = false; - /** * Is true if the service was running, but paused due to headphone disconnect */ private static boolean transientPause = false; @@ -310,15 +314,9 @@ public class PlaybackService extends MediaBrowserServiceCompat { } flavorHelper.initializeMediaPlayer(PlaybackService.this); - mediaSession.setActive(true); - NotificationCompat.Builder notificationBuilder = createBasicNotification(); - startForeground(NOTIFICATION_ID, notificationBuilder.build()); EventBus.getDefault().post(new ServiceEvent(ServiceEvent.Action.SERVICE_STARTED)); - - - setupNotification(Playable.PlayableUtils.createInstanceFromPreferences(getApplicationContext())); } private NotificationCompat.Builder createBasicNotification() { @@ -343,8 +341,8 @@ public class PlaybackService extends MediaBrowserServiceCompat { public void onDestroy() { super.onDestroy(); Log.d(TAG, "Service is about to be destroyed"); + stopForeground(true); isRunning = false; - started = false; currentMediaType = MediaType.UNKNOWN; PreferenceManager.getDefaultSharedPreferences(this) @@ -365,7 +363,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { mediaPlayer.shutdown(); taskManager.shutdown(); } - + @Override public BrowserRoot onGetRoot(@NonNull String clientPackageName, int clientUid, Bundle rootHints) { Log.d(TAG, "OnGetRoot: clientPackageName=" + clientPackageName + @@ -459,33 +457,32 @@ public class PlaybackService extends MediaBrowserServiceCompat { final boolean castDisconnect = intent.getBooleanExtra(EXTRA_CAST_DISCONNECT, false); Playable playable = intent.getParcelableExtra(EXTRA_PLAYABLE); if (keycode == -1 && playable == null && !castDisconnect) { - Log.e(TAG, "PlaybackService was started with no arguments"); - stopSelf(); + // Typical cases when the service was started with no argument + // - when it is first bound, and then moved to startedState, as in <code>serviceManager.moveServiceToStartedState()</code> + // - callers (e.g., Controller) explicitly + Log.d(TAG, "PlaybackService was started with no arguments."); return Service.START_NOT_STICKY; } - if ((flags & Service.START_FLAG_REDELIVERY) != 0) { - Log.d(TAG, "onStartCommand is a redelivered intent, calling stopForeground now."); - stopForeground(true); - } else { - - if (keycode != -1) { - Log.d(TAG, "Received media button event"); - handleKeycode(keycode, true); - } else if (!flavorHelper.castDisconnect(castDisconnect) && playable != null) { - started = true; - boolean stream = intent.getBooleanExtra(EXTRA_SHOULD_STREAM, - true); - boolean startWhenPrepared = intent.getBooleanExtra(EXTRA_START_WHEN_PREPARED, false); - boolean prepareImmediately = intent.getBooleanExtra(EXTRA_PREPARE_IMMEDIATELY, false); - sendNotificationBroadcast(NOTIFICATION_TYPE_RELOAD, 0); - //If the user asks to play External Media, the casting session, if on, should end. - flavorHelper.castDisconnect(playable instanceof ExternalMedia); - if (playable instanceof FeedMedia) { - playable = DBReader.getFeedMedia(((FeedMedia) playable).getId()); - } - mediaPlayer.playMediaObject(playable, stream, startWhenPrepared, prepareImmediately); + if (keycode != -1) { + Log.d(TAG, "Received media button event"); + boolean handled = handleKeycode(keycode, true); + if (!handled) { + // Just silently ignores unsupported keycode. Whether the service will + // continue to run is solely dependent on whether it is playing some media. + return Service.START_NOT_STICKY; + } + } else if (!flavorHelper.castDisconnect(castDisconnect) && playable != null) { + boolean stream = intent.getBooleanExtra(EXTRA_SHOULD_STREAM, true); + boolean startWhenPrepared = intent.getBooleanExtra(EXTRA_START_WHEN_PREPARED, false); + boolean prepareImmediately = intent.getBooleanExtra(EXTRA_PREPARE_IMMEDIATELY, false); + sendNotificationBroadcast(NOTIFICATION_TYPE_RELOAD, 0); + //If the user asks to play External Media, the casting session, if on, should end. + flavorHelper.castDisconnect(playable instanceof ExternalMedia); + if (playable instanceof FeedMedia) { + playable = DBReader.getFeedMedia(((FeedMedia) playable).getId()); } + mediaPlayer.playMediaObject(playable, stream, startWhenPrepared, prepareImmediately); } return Service.START_NOT_STICKY; @@ -559,12 +556,23 @@ public class PlaybackService extends MediaBrowserServiceCompat { mediaPlayer.seekDelta(-UserPreferences.getRewindSecs() * 1000); return true; case KeyEvent.KEYCODE_MEDIA_STOP: + // The logic gives UI illusion of stop by removing notification + // In the UI within AntennaPod, including widgets, it is seen as PAUSE, e.g., + // users can still user on-screen widget to resume playing. if (status == PlayerStatus.PLAYING) { + // Implementation note: Use of a state in serviceManager to tell it to + // show stop state UI (i.e., stopForeground(true)) is a bit awkward. + // + // More intuitive API would be for mediaPlayer.pause() returns a Future that + // returns after pause, including the related async notification work completes. + // However, it has its own complication, that mediaPlayer.pause() does not + // really know when all the related work completes, as they are buried into + // (asynchronous) callbacks. + serviceManager.treatNextPauseAsStopOnUI(); mediaPlayer.pause(true, true); - started = false; + } else { + serviceManager.showUIForStopState(); } - - stopForeground(true); // gets rid of persistent notification return true; default: Log.d(TAG, "Unhandled key code: " + keycode); @@ -580,7 +588,6 @@ public class PlaybackService extends MediaBrowserServiceCompat { Playable playable = Playable.PlayableUtils.createInstanceFromPreferences(getApplicationContext()); if (playable != null) { mediaPlayer.playMediaObject(playable, false, true, true); - started = true; PlaybackService.this.updateMediaSessionMetadata(playable); } } @@ -594,19 +601,10 @@ public class PlaybackService extends MediaBrowserServiceCompat { mediaPlayer.setVideoSurface(sh); } - /** - * Called when the surface holder of the mediaplayer has to be changed. - */ - private void resetVideoSurface() { - taskManager.cancelPositionSaver(); - mediaPlayer.resetVideoSurface(); - } - public void notifyVideoSurfaceAbandoned() { + Log.v(TAG, "notifyVideoSurfaceAbandoned()"); mediaPlayer.pause(true, false); mediaPlayer.resetVideoSurface(); - setupNotification(getPlayable()); - stopForeground(!UserPreferences.isPersistNotify()); } private final PlaybackServiceTaskManager.PSTMCallback taskManagerCallback = new PlaybackServiceTaskManager.PSTMCallback() { @@ -652,7 +650,12 @@ public class PlaybackService extends MediaBrowserServiceCompat { private final PlaybackServiceMediaPlayer.PSMPCallback mediaPlayerCallback = new PlaybackServiceMediaPlayer.PSMPCallback() { @Override public void statusChanged(PlaybackServiceMediaPlayer.PSMPInfo newInfo) { - currentMediaType = mediaPlayer.getCurrentMediaType(); + if (mediaPlayer != null) { + currentMediaType = mediaPlayer.getCurrentMediaType(); + } else { + currentMediaType = MediaType.UNKNOWN; + } + updateMediaSession(newInfo.playerStatus); switch (newInfo.playerStatus) { case INITIALIZED: @@ -664,27 +667,15 @@ public class PlaybackService extends MediaBrowserServiceCompat { break; case PAUSED: - if ((UserPreferences.isPersistNotify() || isCasting) && - android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - // do not remove notification on pause based on user pref and whether android version supports expanded notifications - // Change [Play] button to [Pause] - setupNotification(newInfo); - } else if (!UserPreferences.isPersistNotify() && !isCasting) { - // remove notification on pause - stopForeground(true); - } writePlayerStatusPlaybackPreferences(); break; case STOPPED: - //setCurrentlyPlayingMedia(PlaybackPreferences.NO_MEDIA_PLAYING); - //stopSelf(); + //writePlaybackPreferencesNoMediaPlaying(); break; case PLAYING: writePlayerStatusPlaybackPreferences(); - setupNotification(newInfo); - started = true; // set sleep timer if auto-enabled if (newInfo.oldPlayerStatus != null && newInfo.oldPlayerStatus != PlayerStatus.SEEKING && SleepTimerPreferences.autoEnable() && !sleepTimerActive()) { @@ -699,9 +690,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { } - Intent statusUpdate = new Intent(ACTION_PLAYER_STATUS_CHANGED); - // statusUpdate.putExtra(EXTRA_NEW_PLAYER_STATUS, newInfo.playerStatus.ordinal()); - sendBroadcast(statusUpdate); + IntentUtils.sendLocalBroadcast(getApplicationContext(), ACTION_PLAYER_STATUS_CHANGED); PlayerWidgetJobService.updateWidget(getBaseContext()); bluetoothNotifyChange(newInfo, AVRCP_ACTION_PLAYER_STATUS_CHANGED); bluetoothNotifyChange(newInfo, AVRCP_ACTION_META_CHANGED); @@ -709,7 +698,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { @Override public void shouldStop() { - stopSelf(); + serviceManager.stopService(); } @Override @@ -758,7 +747,6 @@ public class PlaybackService extends MediaBrowserServiceCompat { } sendNotificationBroadcast(NOTIFICATION_TYPE_ERROR, what); writePlaybackPreferencesNoMediaPlaying(); - stopSelf(); return true; } @@ -842,9 +830,6 @@ public class PlaybackService extends MediaBrowserServiceCompat { if (stopPlaying) { taskManager.cancelPositionSaver(); writePlaybackPreferencesNoMediaPlaying(); - if (!isCasting) { - stopForeground(true); - } } if (mediaType == null) { sendNotificationBroadcast(NOTIFICATION_TYPE_PLAYBACK_END, 0); @@ -913,7 +898,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { final List<FeedItem> queue = taskManager.getQueue(); if (QueueAccess.ItemListAccess(queue).contains(item.getId())) { // don't know if it actually matters to not autodownload when smart mark as played is triggered - DBWriter.removeQueueItem(PlaybackService.this, item, ended); + DBWriter.removeQueueItem(PlaybackService.this, ended, item); } } catch (InterruptedException e) { e.printStackTrace(); @@ -1042,17 +1027,11 @@ public class PlaybackService extends MediaBrowserServiceCompat { editor.commit(); } - /** - * Send ACTION_PLAYER_STATUS_CHANGED without changing the status attribute. - */ - private void postStatusUpdateIntent() { - sendBroadcast(new Intent(ACTION_PLAYER_STATUS_CHANGED)); - } - private void sendNotificationBroadcast(int type, int code) { Intent intent = new Intent(ACTION_PLAYER_NOTIFICATION); intent.putExtra(EXTRA_NOTIFICATION_TYPE, type); intent.putExtra(EXTRA_NOTIFICATION_CODE, code); + intent.setPackage(getPackageName()); sendBroadcast(intent); } @@ -1064,6 +1043,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { private void updateMediaSession(final PlayerStatus playerStatus) { PlaybackStateCompat.Builder sessionState = new PlaybackStateCompat.Builder(); + @PlaybackStateCompat.State int state; if (playerStatus != null) { switch (playerStatus) { @@ -1098,7 +1078,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { } else { state = PlaybackStateCompat.STATE_NONE; } - sessionState.setState(state, mediaPlayer.getPosition(), mediaPlayer.getPlaybackSpeed()); + sessionState.setState(state, getCurrentPosition(), getCurrentPlaybackSpeed()); long capabilities = PlaybackStateCompat.ACTION_PLAY_PAUSE | PlaybackStateCompat.ACTION_REWIND | PlaybackStateCompat.ACTION_FAST_FORWARD @@ -1127,7 +1107,9 @@ public class PlaybackService extends MediaBrowserServiceCompat { flavorHelper.mediaSessionSetExtraForWear(mediaSession); - mediaSession.setPlaybackState(sessionState.build()); + final PlaybackStateCompat sessionStateBuilt = sessionState.build(); + mediaSession.setPlaybackState(sessionStateBuilt); + serviceManager.onPlaybackStateChange(sessionStateBuilt); } private static boolean useSkipToPreviousForRewindInLockscreen() { @@ -1167,10 +1149,10 @@ public class PlaybackService extends MediaBrowserServiceCompat { builder.putString(MediaMetadataCompat.METADATA_KEY_ART_URI, imageLocation); try { Bitmap art = Glide.with(this) - .load(imageLocation) .asBitmap() - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .into(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) + .load(imageLocation) + .apply(RequestOptions.diskCacheStrategyOf(ApGlideSettings.AP_DISK_CACHE_STRATEGY)) + .submit(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) .get(); builder.putBitmap(MediaMetadataCompat.METADATA_KEY_ART, art); } catch (Throwable tr) { @@ -1181,7 +1163,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { builder.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON_URI, imageLocation); } } - if (!Thread.currentThread().isInterrupted() && started) { + if (!Thread.currentThread().isInterrupted() && isStarted()) { mediaSession.setSessionActivity(PendingIntent.getActivity(this, 0, PlaybackService.getPlayerActivityIntent(this), PendingIntent.FLAG_UPDATE_CURRENT)); @@ -1204,49 +1186,55 @@ public class PlaybackService extends MediaBrowserServiceCompat { */ private Thread notificationSetupThread; - /** - * Prepares notification and starts the service in the foreground. - */ - private void setupNotification(final PlaybackServiceMediaPlayer.PSMPInfo info) { - setupNotification(info.playable); - } - - private synchronized void setupNotification(final Playable playable) { + private synchronized void setupNotification(final Playable playable, boolean treatPauseAsStop) { if (notificationSetupThread != null) { notificationSetupThread.interrupt(); } + if (playable == null) { + Log.d(TAG, "setupNotification: playable is null"); + if (!isStarted()) { + serviceManager.stopService(); + } + return; + } Runnable notificationSetupTask = new Runnable() { Bitmap icon = null; @Override public void run() { - Log.d(TAG, "Starting background work"); - if (playable != null) { - int iconSize = getResources().getDimensionPixelSize( - android.R.dimen.notification_large_icon_width); - try { - icon = Glide.with(PlaybackService.this) - .load(playable.getImageLocation()) - .asBitmap() - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .centerCrop() - .into(iconSize, iconSize) - .get(); - } catch (Throwable tr) { - Log.e(TAG, "Error loading the media icon for the notification", tr); + Log.d(TAG, "notificationSetupTask: Starting background work"); + + if (mediaPlayer == null) { + Log.d(TAG, "notificationSetupTask: mediaPlayer is null"); + if (!isStarted()) { + serviceManager.stopService(); } + return; + } + + int iconSize = getResources().getDimensionPixelSize( + android.R.dimen.notification_large_icon_width); + try { + icon = Glide.with(PlaybackService.this) + .asBitmap() + .load(playable.getImageLocation()) + .apply(RequestOptions.diskCacheStrategyOf(ApGlideSettings.AP_DISK_CACHE_STRATEGY)) + .apply(new RequestOptions().centerCrop()) + .submit(iconSize, iconSize) + .get(); + } catch (Throwable tr) { + Log.e(TAG, "Error loading the media icon for the notification", tr); } + if (icon == null) { icon = BitmapFactory.decodeResource(getApplicationContext().getResources(), ClientConfig.playbackServiceCallbacks.getNotificationIconResource(getApplicationContext())); } - if (mediaPlayer == null) { - return; - } PlayerStatus playerStatus = mediaPlayer.getPlayerStatus(); + Log.v(TAG, "notificationSetupTask: playerStatus=" + playerStatus); - if (!Thread.currentThread().isInterrupted() && started && playable != null) { + if (!Thread.currentThread().isInterrupted() && isStarted()) { String contentText = playable.getEpisodeTitle(); String contentTitle = playable.getFeedTitle(); Notification notification; @@ -1338,15 +1326,33 @@ public class PlaybackService extends MediaBrowserServiceCompat { playerStatus == PlayerStatus.PREPARING || playerStatus == PlayerStatus.SEEKING || isCasting) { + Log.v(TAG, "notificationSetupTask: make service foreground"); startForeground(NOTIFICATION_ID, notification); + } else if (playerStatus == PlayerStatus.PAUSED) { + if (treatPauseAsStop) { + stopForeground(true); + } else if ((UserPreferences.isPersistNotify() || isCasting) && + android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + // do not remove notification on pause based on user pref and whether android version supports expanded notifications + // Change [Play] button to [Pause] + leaveNotificationAsBackground(notification); + } else if (!UserPreferences.isPersistNotify() && !isCasting) { + // remove notification on pause + stopForeground(true); + } } else { - stopForeground(false); - NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); - mNotificationManager.notify(NOTIFICATION_ID, notification); + leaveNotificationAsBackground(notification); } Log.d(TAG, "Notification set up"); } } + + private void leaveNotificationAsBackground(@NonNull Notification notification) { + stopForeground(false); + NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); + mNotificationManager.notify(NOTIFICATION_ID, notification); + } + }; notificationSetupThread = new Thread(notificationSetupTask); notificationSetupThread.start(); @@ -1541,7 +1547,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { @Override public void onReceive(Context context, Intent intent) { if (TextUtils.equals(intent.getAction(), ACTION_SHUTDOWN_PLAYBACK_SERVICE)) { - stopSelf(); + serviceManager.stopService(); } } @@ -1618,7 +1624,11 @@ public class PlaybackService extends MediaBrowserServiceCompat { } public void setSpeed(float speed) { - mediaPlayer.setSpeed(speed); + mediaPlayer.setPlaybackParams(speed, UserPreferences.isSkipSilence()); + } + + public void skipSilence(boolean skipSilence) { + mediaPlayer.setPlaybackParams(getCurrentPlaybackSpeed(), skipSilence); } public void setVolume(float leftVolume, float rightVolume) { @@ -1626,6 +1636,9 @@ public class PlaybackService extends MediaBrowserServiceCompat { } public float getCurrentPlaybackSpeed() { + if(mediaPlayer == null) { + return 1.0f; + } return mediaPlayer.getPlaybackSpeed(); } @@ -1667,6 +1680,9 @@ public class PlaybackService extends MediaBrowserServiceCompat { * an invalid state. */ public int getDuration() { + if (mediaPlayer == null) { + return INVALID_TIME; + } return mediaPlayer.getDuration(); } @@ -1675,6 +1691,9 @@ public class PlaybackService extends MediaBrowserServiceCompat { * is in an invalid state. */ public int getCurrentPosition() { + if (mediaPlayer == null) { + return INVALID_TIME; + } return mediaPlayer.getPosition(); } @@ -1783,7 +1802,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { public boolean onMediaButtonEvent(final Intent mediaButton) { Log.d(TAG, "onMediaButtonEvent(" + mediaButton + ")"); if (mediaButton != null) { - KeyEvent keyEvent = (KeyEvent) mediaButton.getParcelableExtra(Intent.EXTRA_KEY_EVENT); + KeyEvent keyEvent = mediaButton.getParcelableExtra(Intent.EXTRA_KEY_EVENT); if (keyEvent != null && keyEvent.getAction() == KeyEvent.ACTION_DOWN && keyEvent.getRepeatCount() == 0) { @@ -1826,8 +1845,6 @@ public class PlaybackService extends MediaBrowserServiceCompat { void saveCurrentPosition(boolean fromMediaPlayer, Playable playable, int position); - void setupNotification(boolean connected, PlaybackServiceMediaPlayer.PSMPInfo info); - MediaSessionCompat getMediaSession(); Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter); @@ -1867,24 +1884,6 @@ public class PlaybackService extends MediaBrowserServiceCompat { } @Override - public void setupNotification(boolean connected, PlaybackServiceMediaPlayer.PSMPInfo info) { - if (connected) { - PlaybackService.this.setupNotification(info); - } else { - PlayerStatus status = info.playerStatus; - if ((status == PlayerStatus.PLAYING || - status == PlayerStatus.SEEKING || - status == PlayerStatus.PREPARING || - UserPreferences.isPersistNotify()) && - android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - PlaybackService.this.setupNotification(info); - } else if (!UserPreferences.isPersistNotify()) { - PlaybackService.this.stopForeground(true); - } - } - } - - @Override public MediaSessionCompat getMediaSession() { return PlaybackService.this.mediaSession; } @@ -1899,4 +1898,116 @@ public class PlaybackService extends MediaBrowserServiceCompat { PlaybackService.this.unregisterReceiver(receiver); } }; + + private boolean isStarted() { + return serviceManager.serviceInStartedState; + } + + /** + * The helper that manages PlaybackService's foreground service life cycle and the associated + * notification control. + * + * The logic is adapted from a sample app from The Android Open Source Project. + * See https://github.com/googlesamples/android-MediaBrowserService/blob/6cf01be9ef82ca2dd653f03e2a4af0b075cc0021/Application/src/main/java/com/example/android/mediasession/service/MusicService.java#L211 + * + */ + private class ServiceManager { + private boolean serviceInStartedState; + private boolean toTreatNextPauseAsStopOnUI = false; + + /** + * + * Entry point method for callers. Upon PlaybackState changes, + * the manager start/stop the PlaybackService as well as relevant notification + */ + void onPlaybackStateChange(PlaybackStateCompat state) { + // Report the state to the MediaSession. + + Log.v(TAG, "onPlaybackStateChange(" + (state != null ? state.getState() : "null") + ")"); + try { + // Manage the started state of this service. + switch (state.getState()) { + case PlaybackStateCompat.STATE_CONNECTING: + // move the service to started, aka, making it foreground + // upon STATE_CONNECTING, i.e., in preparing to play a media. + // This is done so that in case the preparation takes a long time, e.g., + // streaming over a slow network, + // the service won't be killed by the system prematurely. + moveServiceToStartedState(state); + break; + case PlaybackStateCompat.STATE_PLAYING: + moveServiceToStartedState(state); + break; + case PlaybackStateCompat.STATE_PAUSED: + updateNotificationForPause(state); + break; + case PlaybackStateCompat.STATE_STOPPED: + moveServiceOutOfStartedState(state); + break; + case PlaybackStateCompat.STATE_ERROR: + moveServiceOutOfStartedState(state); + break; + } + } finally { + if (toTreatNextPauseAsStopOnUI) { + Log.v(TAG, "onPlaybackStateChange() - toTreatNextPauseAsStopOnUI enabled. The actual state (should be PAUSED, aka 2): " + state.getState()); + toTreatNextPauseAsStopOnUI = false; + } + } + } + + /** + * Tell service manager that on the next state change, if the state is STATE_PAUSED, + * give UI treatment as if it is stopped. + * + * @see #handleKeycode(int, boolean) the use case + */ + public void treatNextPauseAsStopOnUI() { + this.toTreatNextPauseAsStopOnUI = true; + } + + public void showUIForStopState() { + Log.v(TAG, "serviceManager.showUIForStopState()"); + stopForeground(true); // gets rid of persistent notification, to give the UI illusion of STOP + } + + public void stopService() { + stopForeground(true); + stopSelf(); + serviceInStartedState = false; + } + + private void moveServiceToStartedState(PlaybackStateCompat state) { + if (!serviceInStartedState) { + ContextCompat.startForegroundService( + PlaybackService.this, + new Intent(PlaybackService.this, PlaybackService.class)); + serviceInStartedState = true; + } + + doSetupNotification(); + } + + private void updateNotificationForPause(PlaybackStateCompat state) { + doSetupNotification(); + } + + private void moveServiceOutOfStartedState(PlaybackStateCompat state) { + stopService(); + } + + private void doSetupNotification() { + if (mediaPlayer != null && mediaPlayer.getPlayable() != null) { + // it updates notification and set foreground status + // based on player status (similar to PlaybackState) + setupNotification(mediaPlayer.getPlayable(), toTreatNextPauseAsStopOnUI); + } else { + // should not happen unless there are bugs. + Log.e(TAG, "doSetupNotification() - unexpectedly there is no playable. No notification setup done. mediaPlayer." + mediaPlayer); + } + } + } + + private final ServiceManager serviceManager = new ServiceManager(); + } 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 a2481b801..b8198fa63 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 @@ -148,10 +148,12 @@ public abstract class PlaybackServiceMediaPlayer { public abstract boolean canSetSpeed(); /** - * Sets the playback speed. + * Sets the playback parameters. + * - Speed + * - SkipSilence (ExoPlayer only) * This method is executed on an internal executor service. */ - public abstract void setSpeed(float speed); + public abstract void setPlaybackParams(final float speed, final boolean skipSilence); /** * Returns the current playback speed. If the playback speed could not be retrieved, 1 is returned. diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlayerStatus.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlayerStatus.java index 8a222d7ec..4f2ae34f8 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlayerStatus.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlayerStatus.java @@ -12,7 +12,7 @@ public enum PlayerStatus { INITIALIZING(9), // playback service is loading the Playable's metadata INITIALIZED(10); // playback service was started, data source of media player was set. - private int statusValue; + private final int statusValue; private static final PlayerStatus[] fromOrdinalLookup; static { diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/APCleanupAlgorithm.java b/core/src/main/java/de/danoeh/antennapod/core/storage/APCleanupAlgorithm.java index e94874453..c63ac4416 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/APCleanupAlgorithm.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/APCleanupAlgorithm.java @@ -2,6 +2,7 @@ package de.danoeh.antennapod.core.storage; import android.content.Context; import android.support.annotation.NonNull; +import android.support.annotation.VisibleForTesting; import android.util.Log; import java.util.ArrayList; @@ -20,11 +21,12 @@ import de.danoeh.antennapod.core.feed.FeedMedia; public class APCleanupAlgorithm extends EpisodeCleanupAlgorithm { private static final String TAG = "APCleanupAlgorithm"; - /** the number of days after playback to wait before an item is eligible to be cleaned up */ - private final int numberOfDaysAfterPlayback; + /** the number of days after playback to wait before an item is eligible to be cleaned up. + Fractional for number of hours, e.g., 0.5 = 12 hours, 0.0416 = 1 hour. */ + private final int numberOfHoursAfterPlayback; - public APCleanupAlgorithm(int numberOfDaysAfterPlayback) { - this.numberOfDaysAfterPlayback = numberOfDaysAfterPlayback; + public APCleanupAlgorithm(int numberOfHoursAfterPlayback) { + this.numberOfHoursAfterPlayback = numberOfHoursAfterPlayback; } /** @@ -77,13 +79,17 @@ public class APCleanupAlgorithm extends EpisodeCleanupAlgorithm { return counter; } + @VisibleForTesting + Date calcMostRecentDateForDeletion(@NonNull Date currentDate) { + return minusHours(currentDate, numberOfHoursAfterPlayback); + } + @NonNull private List<FeedItem> getCandidates() { List<FeedItem> candidates = new ArrayList<>(); List<FeedItem> downloadedItems = DBReader.getDownloadedItems(); - Calendar cal = Calendar.getInstance(); - cal.add(Calendar.DAY_OF_MONTH, -1 * numberOfDaysAfterPlayback); - Date mostRecentDateForDeletion = cal.getTime(); + + Date mostRecentDateForDeletion = calcMostRecentDateForDeletion(new Date()); for (FeedItem item : downloadedItems) { if (item.hasMedia() && item.getMedia().isDownloaded() @@ -108,5 +114,16 @@ public class APCleanupAlgorithm extends EpisodeCleanupAlgorithm { return getNumEpisodesToCleanup(0); } - public int getNumberOfDaysAfterPlayback() { return numberOfDaysAfterPlayback; } + @VisibleForTesting + public int getNumberOfHoursAfterPlayback() { return numberOfHoursAfterPlayback; } + + private static Date minusHours(Date baseDate, int numberOfHours) { + Calendar cal = Calendar.getInstance(); + cal.setTime(baseDate); + + cal.add(Calendar.HOUR_OF_DAY, -1 * numberOfHours); + + return cal.getTime(); + } + } 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 fa87cc216..1b579f99a 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 @@ -1,7 +1,10 @@ package de.danoeh.antennapod.core.storage; import android.database.Cursor; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.v4.util.ArrayMap; +import android.text.TextUtils; import android.util.Log; import java.util.ArrayList; @@ -13,7 +16,6 @@ import java.util.Map; import de.danoeh.antennapod.core.feed.Chapter; import de.danoeh.antennapod.core.feed.Feed; -import de.danoeh.antennapod.core.feed.FeedImage; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.feed.FeedPreferences; @@ -57,6 +59,7 @@ public final class DBReader { * of the returned list does NOT have its list of FeedItems yet. The FeedItem-list * can be loaded separately with {@link #getFeedItemList(Feed)}. */ + @NonNull public static List<Feed> getFeedList() { Log.d(TAG, "Extracting Feedlist"); @@ -69,13 +72,14 @@ public final class DBReader { } } + @NonNull private static List<Feed> getFeedList(PodDBAdapter adapter) { Cursor cursor = null; try { cursor = adapter.getAllFeedsCursor(); List<Feed> feeds = new ArrayList<>(cursor.getCount()); while (cursor.moveToNext()) { - Feed feed = extractFeedFromCursorRow(adapter, cursor); + Feed feed = extractFeedFromCursorRow(cursor); feeds.add(feed); } return feeds; @@ -198,28 +202,19 @@ public final class DBReader { } } + @NonNull private static List<FeedItem> extractItemlistFromCursor(PodDBAdapter adapter, Cursor cursor) { List<FeedItem> result = new ArrayList<>(cursor.getCount()); - LongList imageIds = new LongList(cursor.getCount()); LongList itemIds = new LongList(cursor.getCount()); if (cursor.moveToFirst()) { do { - int indexImage = cursor.getColumnIndex(PodDBAdapter.KEY_IMAGE); - long imageId = cursor.getLong(indexImage); - imageIds.add(imageId); - FeedItem item = FeedItem.fromCursor(cursor); result.add(item); itemIds.add(item.getId()); } while (cursor.moveToNext()); - Map<Long, FeedImage> images = getFeedImages(adapter, imageIds.toArray()); Map<Long, FeedMedia> medias = getFeedMedia(adapter, itemIds); - for (int i = 0; i < result.size(); i++) { - FeedItem item = result.get(i); - long imageId = imageIds.get(i); - FeedImage image = images.get(imageId); - item.setImage(image); + for (FeedItem item : result) { FeedMedia media = medias.get(item.getId()); item.setMedia(media); if (media != null) { @@ -253,28 +248,14 @@ public final class DBReader { return result; } - private static Feed extractFeedFromCursorRow(PodDBAdapter adapter, Cursor cursor) { - final FeedImage image; - int indexImage = cursor.getColumnIndex(PodDBAdapter.KEY_IMAGE); - long imageId = cursor.getLong(indexImage); - if (imageId != 0) { - image = getFeedImage(adapter, imageId); - } else { - image = null; - } - + private static Feed extractFeedFromCursorRow(Cursor cursor) { Feed feed = Feed.fromCursor(cursor); - if (image != null) { - feed.setImage(image); - image.setOwner(feed); - } - FeedPreferences preferences = FeedPreferences.fromCursor(cursor); feed.setPreferences(preferences); - return feed; } + @NonNull static List<FeedItem> getQueue(PodDBAdapter adapter) { Log.d(TAG, "getQueue()"); Cursor cursor = null; @@ -331,6 +312,7 @@ public final class DBReader { * @return A list of FeedItems sorted by the same order as the queue. The caller can wrap the returned * list in a {@link de.danoeh.antennapod.core.util.QueueAccess} object for easier access to the queue's properties. */ + @NonNull public static List<FeedItem> getQueue() { Log.d(TAG, "getQueue() called"); @@ -348,6 +330,7 @@ public final class DBReader { * * @return A list of FeedItems whose episdoe has been downloaded. */ + @NonNull public static List<FeedItem> getDownloadedItems() { Log.d(TAG, "getDownloadedItems() called"); @@ -438,6 +421,7 @@ public final class DBReader { * * @param limit The maximum number of episodes that should be loaded. */ + @NonNull public static List<FeedItem> getRecentlyPublishedEpisodes(int limit) { Log.d(TAG, "getRecentlyPublishedEpisodes() called with: " + "limit = [" + limit + "]"); @@ -464,6 +448,7 @@ public final class DBReader { * @return The playback history. The FeedItems are sorted by their media's playbackCompletionDate in descending order. * The size of the returned list is limited by {@link #PLAYBACK_HISTORY_SIZE}. */ + @NonNull public static List<FeedItem> getPlaybackHistory() { Log.d(TAG, "getPlaybackHistory() called"); @@ -599,13 +584,14 @@ public final class DBReader { } } + @Nullable static Feed getFeed(final long feedId, PodDBAdapter adapter) { Feed feed = null; Cursor cursor = null; try { cursor = adapter.getFeedCursor(feedId); if (cursor.moveToNext()) { - feed = extractFeedFromCursorRow(adapter, cursor); + feed = extractFeedFromCursorRow(cursor); feed.setItems(getFeedItemList(feed)); } else { Log.e(TAG, "getFeed could not find feed with id " + feedId); @@ -618,6 +604,7 @@ public final class DBReader { } } + @Nullable private static FeedItem getFeedItem(final long itemId, PodDBAdapter adapter) { Log.d(TAG, "Loading feeditem with id " + itemId); @@ -651,6 +638,7 @@ public final class DBReader { * @return The FeedItem or null if the FeedItem could not be found. All FeedComponent-attributes * as well as chapter marks of the FeedItem will also be loaded from the database. */ + @Nullable public static FeedItem getFeedItem(final long itemId) { Log.d(TAG, "getFeedItem() called with: " + "itemId = [" + itemId + "]"); @@ -663,6 +651,7 @@ public final class DBReader { } } + @Nullable private static FeedItem getFeedItem(final String podcastUrl, final String episodeUrl, PodDBAdapter adapter) { Log.d(TAG, "Loading feeditem with podcast url " + podcastUrl + " and episode url " + episodeUrl); Cursor cursor = null; @@ -714,7 +703,7 @@ public final class DBReader { if (cursor.moveToFirst()) { String username = cursor.getString(0); String password = cursor.getString(1); - if (username != null && password != null) { + if (!TextUtils.isEmpty(username) && password != null) { credentials = username + ":" + password; } else { credentials = ""; @@ -839,62 +828,6 @@ public final class DBReader { } /** - * Searches the DB for a FeedImage of the given id. - * - * @param imageId The id of the object - * @return The found object - */ - public static FeedImage getFeedImage(final long imageId) { - Log.d(TAG, "getFeedImage() called with: " + "imageId = [" + imageId + "]"); - PodDBAdapter adapter = PodDBAdapter.getInstance(); - adapter.open(); - try { - return getFeedImage(adapter, imageId); - } finally { - adapter.close(); - } - } - - /** - * Searches the DB for a FeedImage of the given id. - * - * @param imageId The id of the object - * @return The found object - */ - private static FeedImage getFeedImage(PodDBAdapter adapter, final long imageId) { - return getFeedImages(adapter, imageId).get(imageId); - } - - /** - * Searches the DB for a FeedImage of the given id. - * - * @param imageIds The ids of the images - * @return Map that associates the id of an image with the image itself - */ - private static Map<Long, FeedImage> getFeedImages(PodDBAdapter adapter, final long... imageIds) { - String[] ids = new String[imageIds.length]; - for (int i = 0, len = imageIds.length; i < len; i++) { - ids[i] = String.valueOf(imageIds[i]); - } - Cursor cursor = adapter.getImageCursor(ids); - int imageCount = cursor.getCount(); - if (imageCount == 0) { - cursor.close(); - return Collections.emptyMap(); - } - Map<Long, FeedImage> result = new ArrayMap<>(imageCount); - try { - while (cursor.moveToNext()) { - FeedImage image = FeedImage.fromCursor(cursor); - result.put(image.getId(), image); - } - } finally { - cursor.close(); - } - return result; - } - - /** * Searches the DB for a FeedMedia of the given id. * * @param mediaId The id of the object @@ -938,6 +871,7 @@ public final class DBReader { * countAll calculation time * @return The StatisticsInfo object */ + @NonNull public static StatisticsData getStatistics(boolean sortByCountAll) { PodDBAdapter adapter = PodDBAdapter.getInstance(); adapter.open(); @@ -961,10 +895,6 @@ public final class DBReader { continue; } - // played duration used to be reset when the item is added to the playback history - if (media.getPlaybackCompletionDate() != null) { - feedPlayedTime += media.getDuration() / 1000; - } feedPlayedTime += media.getPlayedDuration() / 1000; if (item.isPlayed()) { @@ -1088,7 +1018,7 @@ public final class DBReader { Cursor feedCursor = adapter.getFeedsInFlattrQueueCursor(); if (feedCursor.moveToFirst()) { do { - result.add(extractFeedFromCursorRow(adapter, feedCursor)); + result.add(extractFeedFromCursorRow(feedCursor)); } while (feedCursor.moveToNext()); } feedCursor.close(); @@ -1108,6 +1038,7 @@ public final class DBReader { * the list of subscriptions, the number of items in the queue and the number of unread * items. */ + @NonNull public static NavDrawerData getNavDrawerData() { Log.d(TAG, "getNavDrawerData() called with: " + ""); PodDBAdapter adapter = PodDBAdapter.getInstance(); 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 da500fd3e..dab8e19b5 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 @@ -1,11 +1,9 @@ package de.danoeh.antennapod.core.storage; import android.content.Context; -import android.content.Intent; import android.content.SharedPreferences; import android.database.Cursor; import android.support.annotation.Nullable; -import android.support.v4.content.ContextCompat; import android.util.Log; import java.util.ArrayList; @@ -19,7 +17,6 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.FutureTask; -import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import de.danoeh.antennapod.core.ClientConfig; @@ -30,12 +27,11 @@ 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.IntentUtils; import de.danoeh.antennapod.core.util.LongList; import de.danoeh.antennapod.core.util.comparator.FeedItemPubdateComparator; import de.danoeh.antennapod.core.util.exception.MediaFileNotFoundException; @@ -142,8 +138,7 @@ public final class DBTasks { } catch (MediaFileNotFoundException e) { e.printStackTrace(); if (media.isPlaying()) { - context.sendBroadcast(new Intent( - PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE)); + IntentUtils.sendLocalBroadcast(context, PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE); } notifyMissingFeedMediaFile(context, media); } @@ -198,8 +193,10 @@ public final class DBTasks { if (ClientConfig.gpodnetCallbacks.gpodnetEnabled()) { GpodnetSyncService.sendSyncIntent(context); } - Log.d(TAG, "refreshAllFeeds autodownload"); - autodownloadUndownloadedItems(context); + // Note: automatic download of episodes will be done but not here. + // Instead it is done after all feeds have been refreshed (asynchronously), + // in DownloadService.onDestroy() + // See Issue #2577 for the details of the rationale if (callback != null) { callback.run(); @@ -207,6 +204,11 @@ public final class DBTasks { }).start(); } + public static long getLastRefreshAllFeedsTimeMillis(final Context context) { + SharedPreferences prefs = context.getSharedPreferences(DBTasks.PREF_NAME, MODE_PRIVATE); + return prefs.getLong(DBTasks.PREF_LAST_REFRESH, 0); + } + /** * @param context * @param feedList the list of feeds to refresh @@ -237,27 +239,6 @@ public final class DBTasks { } /** - * Downloads all pages of the given feed. - * - * @param context Used for requesting the download. - * @param feed The Feed object. - */ - public static void refreshCompleteFeed(final Context context, final Feed feed) { - try { - refreshFeed(context, feed, true, false); - } catch (DownloadRequestException e) { - e.printStackTrace(); - DBWriter.addDownloadStatus( - new DownloadStatus(feed, feed - .getHumanReadableIdentifier(), - DownloadError.ERROR_REQUEST_ERROR, false, e - .getMessage() - ) - ); - } - } - - /** * Downloads all pages of the given feed even if feed has not been modified since last refresh * * @param context Used for requesting the download. @@ -338,31 +319,6 @@ 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. @@ -378,27 +334,6 @@ public final class DBTasks { } /** - * Request the download of all objects in the queue. from a separate Thread. - * - * @param context Used for requesting the download an accessing the database. - */ - public static void downloadAllItemsInQueue(final Context context) { - new Thread() { - public void run() { - List<FeedItem> queue = DBReader.getQueue(); - if (!queue.isEmpty()) { - try { - downloadFeedItems(context, - queue.toArray(new FeedItem[queue.size()])); - } catch (DownloadRequestException e) { - e.printStackTrace(); - } - } - } - }.start(); - } - - /** * Requests the download of a list of FeedItem objects. * * @param context Used for requesting the download and accessing the DB. @@ -817,10 +752,8 @@ public final class DBTasks { */ abstract static class QueryTask<T> implements Callable<T> { private T result; - private final Context context; public QueryTask(Context context) { - this.context = context; } @Override diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBUpgrader.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBUpgrader.java new file mode 100644 index 000000000..0beb765e7 --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBUpgrader.java @@ -0,0 +1,293 @@ +package de.danoeh.antennapod.core.storage; + +import android.content.ContentValues; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.media.MediaMetadataRetriever; +import android.util.Log; + +import de.danoeh.antennapod.core.feed.FeedItem; + +class DBUpgrader { + /** + * Upgrades the given database to a new schema version + */ + static void upgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) { + if (oldVersion <= 1) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + " ADD COLUMN " + + PodDBAdapter.KEY_TYPE + " TEXT"); + } + if (oldVersion <= 2) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS + + " ADD COLUMN " + PodDBAdapter.KEY_LINK + " TEXT"); + } + if (oldVersion <= 3) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + + " ADD COLUMN " + PodDBAdapter.KEY_ITEM_IDENTIFIER + " TEXT"); + } + if (oldVersion <= 4) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + " ADD COLUMN " + + PodDBAdapter.KEY_FEED_IDENTIFIER + " TEXT"); + } + if (oldVersion <= 5) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_DOWNLOAD_LOG + + " ADD COLUMN " + PodDBAdapter.KEY_REASON_DETAILED + " TEXT"); + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_DOWNLOAD_LOG + + " ADD COLUMN " + PodDBAdapter.KEY_DOWNLOADSTATUS_TITLE + " TEXT"); + } + if (oldVersion <= 6) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS + + " ADD COLUMN " + PodDBAdapter.KEY_CHAPTER_TYPE + " INTEGER"); + } + if (oldVersion <= 7) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA + + " ADD COLUMN " + PodDBAdapter.KEY_PLAYBACK_COMPLETION_DATE + + " INTEGER"); + } + if (oldVersion <= 8) { + final int KEY_ID_POSITION = 0; + final int KEY_MEDIA_POSITION = 1; + + // Add feeditem column to feedmedia table + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA + + " ADD COLUMN " + PodDBAdapter.KEY_FEEDITEM + + " INTEGER"); + Cursor feeditemCursor = db.query(PodDBAdapter.TABLE_NAME_FEED_ITEMS, + new String[]{PodDBAdapter.KEY_ID, PodDBAdapter.KEY_MEDIA}, "? > 0", + new String[]{PodDBAdapter.KEY_MEDIA}, null, null, null); + if (feeditemCursor.moveToFirst()) { + db.beginTransaction(); + ContentValues contentValues = new ContentValues(); + do { + long mediaId = feeditemCursor.getLong(KEY_MEDIA_POSITION); + contentValues.put(PodDBAdapter.KEY_FEEDITEM, feeditemCursor.getLong(KEY_ID_POSITION)); + db.update(PodDBAdapter.TABLE_NAME_FEED_MEDIA, contentValues, PodDBAdapter.KEY_ID + "=?", new String[]{String.valueOf(mediaId)}); + contentValues.clear(); + } while (feeditemCursor.moveToNext()); + db.setTransactionSuccessful(); + db.endTransaction(); + } + feeditemCursor.close(); + } + if (oldVersion <= 9) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + + " ADD COLUMN " + PodDBAdapter.KEY_AUTO_DOWNLOAD + + " INTEGER DEFAULT 1"); + } + if (oldVersion <= 10) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + + " ADD COLUMN " + PodDBAdapter.KEY_FLATTR_STATUS + + " INTEGER"); + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + + " ADD COLUMN " + PodDBAdapter.KEY_FLATTR_STATUS + + " INTEGER"); + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA + + " ADD COLUMN " + PodDBAdapter.KEY_PLAYED_DURATION + + " INTEGER"); + } + if (oldVersion <= 11) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + + " ADD COLUMN " + PodDBAdapter.KEY_USERNAME + + " TEXT"); + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + + " ADD COLUMN " + PodDBAdapter.KEY_PASSWORD + + " TEXT"); + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + + " ADD COLUMN " + PodDBAdapter.KEY_IMAGE + + " INTEGER"); + } + if (oldVersion <= 12) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + + " ADD COLUMN " + PodDBAdapter.KEY_IS_PAGED + " INTEGER DEFAULT 0"); + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + + " ADD COLUMN " + PodDBAdapter.KEY_NEXT_PAGE_LINK + " TEXT"); + } + if (oldVersion <= 13) { + // remove duplicate rows in "Chapters" table that were created because of a bug. + db.execSQL(String.format("DELETE FROM %s WHERE %s NOT IN " + + "(SELECT MIN(%s) as %s FROM %s GROUP BY %s,%s,%s,%s,%s)", + PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS, + PodDBAdapter.KEY_ID, + PodDBAdapter.KEY_ID, + PodDBAdapter.KEY_ID, + PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS, + PodDBAdapter.KEY_TITLE, + PodDBAdapter.KEY_START, + PodDBAdapter.KEY_FEEDITEM, + PodDBAdapter.KEY_LINK, + PodDBAdapter.KEY_CHAPTER_TYPE)); + } + if (oldVersion <= 14) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + + " ADD COLUMN " + PodDBAdapter.KEY_AUTO_DOWNLOAD + " INTEGER"); + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + + " SET " + PodDBAdapter.KEY_AUTO_DOWNLOAD + " = " + + "(SELECT " + PodDBAdapter.KEY_AUTO_DOWNLOAD + + " FROM " + PodDBAdapter.TABLE_NAME_FEEDS + + " WHERE " + PodDBAdapter.TABLE_NAME_FEEDS + "." + PodDBAdapter.KEY_ID + + " = " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_FEED + ")"); + + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + + " ADD COLUMN " + PodDBAdapter.KEY_HIDE + " TEXT"); + + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + + " ADD COLUMN " + PodDBAdapter.KEY_LAST_UPDATE_FAILED + " INTEGER DEFAULT 0"); + + // create indexes + db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_FEED); + db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDMEDIA_FEEDITEM); + db.execSQL(PodDBAdapter.CREATE_INDEX_QUEUE_FEEDITEM); + db.execSQL(PodDBAdapter.CREATE_INDEX_SIMPLECHAPTERS_FEEDITEM); + } + if (oldVersion <= 15) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA + + " ADD COLUMN " + PodDBAdapter.KEY_HAS_EMBEDDED_PICTURE + " INTEGER DEFAULT -1"); + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA + + " SET " + PodDBAdapter.KEY_HAS_EMBEDDED_PICTURE + "=0" + + " WHERE " + PodDBAdapter.KEY_DOWNLOADED + "=0"); + Cursor c = db.rawQuery("SELECT " + PodDBAdapter.KEY_FILE_URL + + " FROM " + PodDBAdapter.TABLE_NAME_FEED_MEDIA + + " WHERE " + PodDBAdapter.KEY_DOWNLOADED + "=1 " + + " AND " + PodDBAdapter.KEY_HAS_EMBEDDED_PICTURE + "=-1", null); + if (c.moveToFirst()) { + MediaMetadataRetriever mmr = new MediaMetadataRetriever(); + do { + String fileUrl = c.getString(0); + try { + mmr.setDataSource(fileUrl); + byte[] image = mmr.getEmbeddedPicture(); + if (image != null) { + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA + + " SET " + PodDBAdapter.KEY_HAS_EMBEDDED_PICTURE + "=1" + + " WHERE " + PodDBAdapter.KEY_FILE_URL + "='" + fileUrl + "'"); + } else { + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA + + " SET " + PodDBAdapter.KEY_HAS_EMBEDDED_PICTURE + "=0" + + " WHERE " + PodDBAdapter.KEY_FILE_URL + "='" + fileUrl + "'"); + } + } catch (Exception e) { + e.printStackTrace(); + } + } while (c.moveToNext()); + } + c.close(); + } + if (oldVersion <= 16) { + String selectNew = "SELECT " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_ID + + " FROM " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + + " INNER JOIN " + PodDBAdapter.TABLE_NAME_FEED_MEDIA + " ON " + + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_ID + "=" + + PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + PodDBAdapter.KEY_FEEDITEM + + " LEFT OUTER JOIN " + PodDBAdapter.TABLE_NAME_QUEUE + " ON " + + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_ID + "=" + + PodDBAdapter.TABLE_NAME_QUEUE + "." + PodDBAdapter.KEY_FEEDITEM + + " WHERE " + + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_READ + " = 0 AND " // unplayed + + PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + PodDBAdapter.KEY_DOWNLOADED + " = 0 AND " // undownloaded + + PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + PodDBAdapter.KEY_POSITION + " = 0 AND " // not partially played + + PodDBAdapter.TABLE_NAME_QUEUE + "." + PodDBAdapter.KEY_ID + " IS NULL"; // not in queue + String sql = "UPDATE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + + " SET " + PodDBAdapter.KEY_READ + "=" + FeedItem.NEW + + " WHERE " + PodDBAdapter.KEY_ID + " IN (" + selectNew + ")"; + Log.d("Migration", "SQL: " + sql); + db.execSQL(sql); + } + if (oldVersion <= 17) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + + " ADD COLUMN " + PodDBAdapter.KEY_AUTO_DELETE_ACTION + " INTEGER DEFAULT 0"); + } + if (oldVersion < 1030005) { + db.execSQL("UPDATE FeedItems SET auto_download=0 WHERE " + + "(read=1 OR id IN (SELECT feeditem FROM FeedMedia WHERE position>0 OR downloaded=1)) " + + "AND id NOT IN (SELECT feeditem FROM Queue)"); + } + if (oldVersion < 1040001) { + db.execSQL(PodDBAdapter.CREATE_TABLE_FAVORITES); + } + if (oldVersion < 1040002) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA + + " ADD COLUMN " + PodDBAdapter.KEY_LAST_PLAYED_TIME + " INTEGER DEFAULT 0"); + } + if (oldVersion < 1040013) { + db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_PUBDATE); + db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_READ); + } + if (oldVersion < 1050003) { + // Migrates feed list filter data + + db.beginTransaction(); + + // Change to intermediate values to avoid overwriting in the following find/replace + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" + + "SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'unplayed', 'noplay')"); + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" + + "SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'not_queued', 'noqueue')"); + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" + + "SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'not_downloaded', 'nodl')"); + + // Replace played, queued, and downloaded with their opposites + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" + + "SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'played', 'unplayed')"); + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" + + "SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'queued', 'not_queued')"); + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" + + "SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'downloaded', 'not_downloaded')"); + + // Now replace intermediates for unplayed, not queued, etc. with their opposites + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" + + "SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'noplay', 'played')"); + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" + + "SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'noqueue', 'queued')"); + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" + + "SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'nodl', 'downloaded')"); + + // Paused doesn't have an opposite, so unplayed is the next best option + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" + + "SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'paused', 'unplayed')"); + + db.setTransactionSuccessful(); + db.endTransaction(); + + // and now get ready for autodownload filters + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + + " ADD COLUMN " + PodDBAdapter.KEY_INCLUDE_FILTER + " TEXT DEFAULT ''"); + + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + + " ADD COLUMN " + PodDBAdapter.KEY_EXCLUDE_FILTER + " TEXT DEFAULT ''"); + + // and now auto refresh + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + + " ADD COLUMN " + PodDBAdapter.KEY_KEEP_UPDATED + " INTEGER DEFAULT 1"); + } + if (oldVersion < 1050004) { + // prevent old timestamps to be misinterpreted as ETags + 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"); + } + if (oldVersion < 1060596) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + + " ADD COLUMN " + PodDBAdapter.KEY_IMAGE_URL + " TEXT"); + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + + " ADD COLUMN " + PodDBAdapter.KEY_IMAGE_URL + " TEXT"); + + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + " SET " + PodDBAdapter.KEY_IMAGE_URL + " = (" + + " SELECT " + PodDBAdapter.KEY_DOWNLOAD_URL + + " FROM " + PodDBAdapter.TABLE_NAME_FEED_IMAGES + + " WHERE " + PodDBAdapter.TABLE_NAME_FEED_IMAGES + "." + PodDBAdapter.KEY_ID + + " = " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_IMAGE + ")"); + + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + " SET " + PodDBAdapter.KEY_IMAGE_URL + " = (" + + " SELECT " + PodDBAdapter.KEY_DOWNLOAD_URL + + " FROM " + PodDBAdapter.TABLE_NAME_FEED_IMAGES + + " WHERE " + PodDBAdapter.TABLE_NAME_FEED_IMAGES + "." + PodDBAdapter.KEY_ID + + " = " + PodDBAdapter.TABLE_NAME_FEEDS + "." + PodDBAdapter.KEY_IMAGE + ")"); + + db.execSQL("DROP TABLE " + PodDBAdapter.TABLE_NAME_FEED_IMAGES); + } + } + +} 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 8cdf82e15..f7226729a 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 @@ -5,6 +5,7 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.preference.PreferenceManager; +import android.support.annotation.NonNull; import android.util.Log; import org.shredzone.flattr4j.model.Flattr; @@ -32,7 +33,6 @@ import de.danoeh.antennapod.core.event.QueueEvent; import de.danoeh.antennapod.core.feed.EventDistributor; import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.FeedEvent; -import de.danoeh.antennapod.core.feed.FeedImage; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.feed.FeedPreferences; @@ -42,6 +42,7 @@ import de.danoeh.antennapod.core.preferences.PlaybackPreferences; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.service.download.DownloadStatus; import de.danoeh.antennapod.core.service.playback.PlaybackService; +import de.danoeh.antennapod.core.util.IntentUtils; import de.danoeh.antennapod.core.util.LongList; import de.danoeh.antennapod.core.util.Permutor; import de.danoeh.antennapod.core.util.flattr.FlattrStatus; @@ -80,65 +81,72 @@ public class DBWriter { * @param context A context that is used for opening a database connection. * @param mediaId ID of the FeedMedia object whose downloaded file should be deleted. */ - public static Future<?> deleteFeedMediaOfItem(final Context context, + public static Future<?> deleteFeedMediaOfItem(@NonNull final Context context, final long mediaId) { return dbExec.submit(() -> { final FeedMedia media = DBReader.getFeedMedia(mediaId); if (media != null) { - Log.i(TAG, String.format("Requested to delete FeedMedia [id=%d, title=%s, downloaded=%s", - media.getId(), media.getEpisodeTitle(), String.valueOf(media.isDownloaded()))); - if (media.isDownloaded()) { - // delete downloaded media file - File mediaFile = new File(media.getFile_url()); - if (mediaFile.exists() && !mediaFile.delete()) { - MessageEvent evt = new MessageEvent(context.getString(R.string.delete_failed)); - EventBus.getDefault().post(evt); - return; - } - media.setDownloaded(false); - media.setFile_url(null); - media.setHasEmbeddedPicture(false); - PodDBAdapter adapter = PodDBAdapter.getInstance(); - adapter.open(); - adapter.setMedia(media); - adapter.close(); - - // If media is currently being played, change playback - // type to 'stream' and shutdown playback service - SharedPreferences prefs = PreferenceManager - .getDefaultSharedPreferences(context); - if (PlaybackPreferences.getCurrentlyPlayingMedia() == FeedMedia.PLAYABLE_TYPE_FEEDMEDIA) { - if (media.getId() == PlaybackPreferences - .getCurrentlyPlayingFeedMediaId()) { - SharedPreferences.Editor editor = prefs.edit(); - editor.putBoolean( - PlaybackPreferences.PREF_CURRENT_EPISODE_IS_STREAM, - true); - editor.commit(); - } - if (PlaybackPreferences - .getCurrentlyPlayingFeedMediaId() == media - .getId()) { - context.sendBroadcast(new Intent( - PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE)); - } - } - // Gpodder: queue delete action for synchronization - if(GpodnetPreferences.loggedIn()) { - FeedItem item = media.getItem(); - GpodnetEpisodeAction action = new GpodnetEpisodeAction.Builder(item, GpodnetEpisodeAction.Action.DELETE) - .currentDeviceId() - .currentTimestamp() - .build(); - GpodnetPreferences.enqueueEpisodeAction(action); - } + boolean result = deleteFeedMediaSynchronous(context, media); + + if (result && UserPreferences.shouldDeleteRemoveFromQueue()) { + DBWriter.removeQueueItemSynchronous(context, false, media.getItem().getId()); } - EventBus.getDefault().post(FeedItemEvent.deletedMedia(Collections.singletonList(media.getItem()))); - EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast(); } }); } + private static boolean deleteFeedMediaSynchronous(@NonNull Context context, @NonNull FeedMedia media) { + Log.i(TAG, String.format("Requested to delete FeedMedia [id=%d, title=%s, downloaded=%s", + media.getId(), media.getEpisodeTitle(), String.valueOf(media.isDownloaded()))); + if (media.isDownloaded()) { + // delete downloaded media file + File mediaFile = new File(media.getFile_url()); + if (mediaFile.exists() && !mediaFile.delete()) { + MessageEvent evt = new MessageEvent(context.getString(R.string.delete_failed)); + EventBus.getDefault().post(evt); + return false; + } + media.setDownloaded(false); + media.setFile_url(null); + media.setHasEmbeddedPicture(false); + PodDBAdapter adapter = PodDBAdapter.getInstance(); + adapter.open(); + adapter.setMedia(media); + adapter.close(); + + // If media is currently being played, change playback + // type to 'stream' and shutdown playback service + SharedPreferences prefs = PreferenceManager + .getDefaultSharedPreferences(context); + if (PlaybackPreferences.getCurrentlyPlayingMedia() == FeedMedia.PLAYABLE_TYPE_FEEDMEDIA) { + if (media.getId() == PlaybackPreferences + .getCurrentlyPlayingFeedMediaId()) { + SharedPreferences.Editor editor = prefs.edit(); + editor.putBoolean( + PlaybackPreferences.PREF_CURRENT_EPISODE_IS_STREAM, + true); + editor.commit(); + } + if (PlaybackPreferences.getCurrentlyPlayingFeedMediaId() == media.getId()) { + IntentUtils.sendLocalBroadcast(context, PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE); + } + } + // Gpodder: queue delete action for synchronization + if(GpodnetPreferences.loggedIn()) { + FeedItem item = media.getItem(); + GpodnetEpisodeAction action = new GpodnetEpisodeAction.Builder(item, GpodnetEpisodeAction.Action.DELETE) + .currentDeviceId() + .currentTimestamp() + .build(); + GpodnetPreferences.enqueueEpisodeAction(action); + } + } + EventBus.getDefault().post(FeedItemEvent.deletedMedia(Collections.singletonList(media.getItem()))); + EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast(); + + return true; + } + /** * Deletes a Feed and all downloaded files of its components like images and downloaded episodes. * @@ -157,8 +165,7 @@ public class DBWriter { if (PlaybackPreferences.getCurrentlyPlayingMedia() == FeedMedia.PLAYABLE_TYPE_FEEDMEDIA && PlaybackPreferences.getLastPlayedFeedId() == feed .getId()) { - context.sendBroadcast(new Intent( - PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE)); + IntentUtils.sendLocalBroadcast(context, PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE); SharedPreferences.Editor editor = prefs.edit(); editor.putLong( PlaybackPreferences.PREF_CURRENTLY_PLAYING_FEED_ID, @@ -166,17 +173,6 @@ public class DBWriter { editor.commit(); } - // delete image file - if (feed.getImage() != null) { - if (feed.getImage().isDownloaded() - && feed.getImage().getFile_url() != null) { - File imageFile = new File(feed.getImage() - .getFile_url()); - imageFile.delete(); - } else if (requester.isDownloadingFile(feed.getImage())) { - requester.cancelDownload(context, feed.getImage()); - } - } // delete stored media files and mark them as read List<FeedItem> queue = DBReader.getQueue(); List<FeedItem> removed = new ArrayList<>(); @@ -200,16 +196,6 @@ public class DBWriter { && requester.isDownloadingFile(item.getMedia())) { requester.cancelDownload(context, item.getMedia()); } - - if (item.hasItemImage()) { - FeedImage image = item.getImage(); - if (image.isDownloaded() && image.getFile_url() != null) { - File imgFile = new File(image.getFile_url()); - imgFile.delete(); - } else if (requester.isDownloadingFile(image)) { - requester.cancelDownload(context, item.getImage()); - } - } } PodDBAdapter adapter = PodDBAdapter.getInstance(); adapter.open(); @@ -437,38 +423,68 @@ public class DBWriter { /** * Removes a FeedItem object from the queue. - * - * @param context A context that is used for opening a database connection. - * @param item FeedItem that should be removed. + * @param context A context that is used for opening a database connection. * @param performAutoDownload true if an auto-download process should be started after the operation. + * @param item FeedItem that should be removed. */ public static Future<?> removeQueueItem(final Context context, - final FeedItem item, final boolean performAutoDownload) { - return dbExec.submit(() -> { - final PodDBAdapter adapter = PodDBAdapter.getInstance(); - adapter.open(); - final List<FeedItem> queue = DBReader.getQueue(adapter); + final boolean performAutoDownload, final FeedItem item) { + return dbExec.submit(() -> removeQueueItemSynchronous(context, performAutoDownload, item.getId())); + } - if (queue != null) { - int position = queue.indexOf(item); + public static Future<?> removeQueueItem(final Context context, final boolean performAutoDownload, + final long... itemIds) { + return dbExec.submit(() -> removeQueueItemSynchronous(context, performAutoDownload, itemIds)); + } + + private static void removeQueueItemSynchronous(final Context context, + final boolean performAutoDownload, + final long... itemIds) { + if (itemIds.length < 1) { + return; + } + final PodDBAdapter adapter = PodDBAdapter.getInstance(); + adapter.open(); + final List<FeedItem> queue = DBReader.getQueue(adapter); + + if (queue != null) { + boolean queueModified = false; + List<QueueEvent> events = new ArrayList<>(); + List<FeedItem> updatedItems = new ArrayList<>(); + for (long itemId : itemIds) { + int position = indexInItemList(queue, itemId); if (position >= 0) { + final FeedItem item = DBReader.getFeedItem(itemId); + if (item == null) { + Log.e(TAG, "removeQueueItem - item in queue but somehow cannot be loaded." + + " Item ignored. It should never happen. id:" + itemId); + continue; + } queue.remove(position); - adapter.setQueue(queue); item.removeTag(FeedItem.TAG_QUEUE); - EventBus.getDefault().post(QueueEvent.removed(item)); - EventBus.getDefault().post(FeedItemEvent.updated(item)); + events.add(QueueEvent.removed(item)); + updatedItems.add(item); + queueModified = true; } else { - Log.w(TAG, "Queue was not modified by call to removeQueueItem"); + Log.v(TAG, "removeQueueItem - item not in queue:" + itemId); } - } else { - Log.e(TAG, "removeQueueItem: Could not load queue"); } - adapter.close(); - if (performAutoDownload) { - DBTasks.autodownloadUndownloadedItems(context); + if (queueModified) { + adapter.setQueue(queue); + for (QueueEvent event : events) { + EventBus.getDefault().post(event); + } + EventBus.getDefault().post(FeedItemEvent.updated(updatedItems)); + } else { + Log.w(TAG, "Queue was not modified by call to removeQueueItem"); } - }); - + } else { + Log.e(TAG, "removeQueueItem: Could not load queue"); + } + adapter.close(); + if (performAutoDownload) { + DBTasks.autodownloadUndownloadedItems(context); + } } public static Future<?> addFavoriteItem(final FeedItem item) { @@ -482,22 +498,6 @@ public class DBWriter { }); } - public static Future<?> addFavoriteItemById(final long itemId) { - return dbExec.submit(() -> { - final FeedItem item = DBReader.getFeedItem(itemId); - if (item == null) { - Log.d(TAG, "Can't find item for itemId " + itemId); - return; - } - final PodDBAdapter adapter = PodDBAdapter.getInstance().open(); - adapter.addFavoriteItem(item); - adapter.close(); - item.addTag(FeedItem.TAG_FAVORITE); - EventBus.getDefault().post(FavoritesEvent.added(item)); - EventBus.getDefault().post(FeedItemEvent.updated(item)); - }); - } - public static Future<?> removeFavoriteItem(final FeedItem item) { return dbExec.submit(() -> { final PodDBAdapter adapter = PodDBAdapter.getInstance().open(); @@ -633,11 +633,13 @@ public class DBWriter { * FeedItem.NEW, FeedItem.UNPLAYED * @param resetMediaPosition true if this method should also reset the position of the FeedItem's FeedMedia object. */ + @NonNull public static Future<?> markItemPlayed(FeedItem item, int played, boolean resetMediaPosition) { long mediaId = (item.hasMedia()) ? item.getMedia().getId() : 0; return markItemPlayed(item.getId(), played, mediaId, resetMediaPosition); } + @NonNull private static Future<?> markItemPlayed(final long itemId, final int played, final long mediaId, @@ -786,21 +788,6 @@ public class DBWriter { } /** - * Saves a FeedImage object in the database. This method will save all attributes of the FeedImage object. The - * contents of FeedComponent-attributes (e.g. the FeedImages's 'feed'-attribute) will not be saved. - * - * @param image The FeedImage object. - */ - public static Future<?> setFeedImage(final FeedImage image) { - return dbExec.submit(() -> { - PodDBAdapter adapter = PodDBAdapter.getInstance(); - adapter.open(); - adapter.setImage(image); - adapter.close(); - }); - } - - /** * Updates download URL of a feed */ public static Future<?> updateFeedDownloadURL(final String original, final String updated) { @@ -829,12 +816,17 @@ public class DBWriter { } private static boolean itemListContains(List<FeedItem> items, long itemId) { - for (FeedItem item : items) { + return indexInItemList(items, itemId) >= 0; + } + + private static int indexInItemList(List<FeedItem> items, long itemId) { + for (int i = 0; i < items.size(); i ++) { + FeedItem item = items.get(i); if (item.getId() == itemId) { - return true; + return i; } } - return false; + return -1; } /** diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java index 7d4b737db..892a4675a 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java @@ -23,6 +23,7 @@ import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.service.download.DownloadRequest; import de.danoeh.antennapod.core.service.download.DownloadService; import de.danoeh.antennapod.core.util.FileNameGenerator; +import de.danoeh.antennapod.core.util.IntentUtils; import de.danoeh.antennapod.core.util.URLChecker; @@ -242,6 +243,7 @@ public class DownloadRequester { Log.d(TAG, "Cancelling download with url " + downloadUrl); Intent cancelIntent = new Intent(DownloadService.ACTION_CANCEL_DOWNLOAD); cancelIntent.putExtra(DownloadService.EXTRA_DOWNLOAD_URL, downloadUrl); + cancelIntent.setPackage(context.getPackageName()); context.sendBroadcast(cancelIntent); } @@ -250,8 +252,7 @@ public class DownloadRequester { */ public synchronized void cancelAllDownloads(Context context) { Log.d(TAG, "Cancelling all running downloads"); - context.sendBroadcast(new Intent( - DownloadService.ACTION_CANCEL_ALL_DOWNLOADS)); + IntentUtils.sendLocalBroadcast(context, DownloadService.ACTION_CANCEL_ALL_DOWNLOADS); } /** 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 aa5706ad0..4093c41a5 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 @@ -1,6 +1,7 @@ package de.danoeh.antennapod.core.storage; import android.content.Context; +import android.support.annotation.NonNull; import java.util.ArrayList; import java.util.Collections; @@ -19,6 +20,8 @@ import de.danoeh.antennapod.core.util.comparator.SearchResultValueComparator; * Performs search on Feeds and FeedItems */ public class FeedSearcher { + private FeedSearcher(){} + private static final String TAG = "FeedSearcher"; @@ -33,6 +36,7 @@ public class FeedSearcher { * @param selectedFeed feed to search, 0 to search through all feeds * @return list of episodes containing the query */ + @NonNull public static List<SearchResult> performSearch(final Context context, final String query, final long selectedFeed) { final int values[] = {2, 1, 0, 0, 0, 0}; @@ -43,7 +47,7 @@ public class FeedSearcher { context.getString(R.string.found_in_authors_label), context.getString(R.string.found_in_feeds_label)}; - List<SearchResult> result = new ArrayList<>(); + final List<SearchResult> result = new ArrayList<>(); List<FutureTask<List<FeedItem>>> tasks = new ArrayList<>(); tasks.add(DBTasks.searchFeedItemTitle(context, selectedFeed, query)); 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 e82252310..1daa43025 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 @@ -1,5 +1,6 @@ package de.danoeh.antennapod.core.storage; +import android.annotation.SuppressLint; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; @@ -12,9 +13,14 @@ import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; import android.media.MediaMetadataRetriever; +import android.os.Build; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.text.TextUtils; import android.util.Log; +import org.apache.commons.io.FileUtils; + import java.io.File; import java.io.IOException; import java.util.Arrays; @@ -26,8 +32,6 @@ import de.danoeh.antennapod.core.R; import de.danoeh.antennapod.core.event.ProgressEvent; import de.danoeh.antennapod.core.feed.Chapter; import de.danoeh.antennapod.core.feed.Feed; -import de.danoeh.antennapod.core.feed.FeedComponent; -import de.danoeh.antennapod.core.feed.FeedImage; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.feed.FeedPreferences; @@ -36,7 +40,6 @@ import de.danoeh.antennapod.core.service.download.DownloadStatus; import de.danoeh.antennapod.core.util.LongIntMap; import de.danoeh.antennapod.core.util.flattr.FlattrStatus; import de.greenrobot.event.EventBus; -import org.apache.commons.io.FileUtils; // TODO Remove media column from feeditem table @@ -74,8 +77,9 @@ public class PodDBAdapter { public static final String KEY_SIZE = "filesize"; public static final String KEY_MIME_TYPE = "mime_type"; public static final String KEY_IMAGE = "image"; + public static final String KEY_IMAGE_URL = "image_url"; public static final String KEY_FEED = "feed"; - private static final String KEY_MEDIA = "media"; + public static final String KEY_MEDIA = "media"; public static final String KEY_DOWNLOADED = "downloaded"; public static final String KEY_LASTUPDATE = "last_update"; public static final String KEY_FEEDFILE = "feedfile"; @@ -114,14 +118,14 @@ public class PodDBAdapter { public static final String KEY_EXCLUDE_FILTER = "exclude_filter"; // Table names - 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"; + static final String TABLE_NAME_FEEDS = "Feeds"; + static final String TABLE_NAME_FEED_ITEMS = "FeedItems"; + static final String TABLE_NAME_FEED_IMAGES = "FeedImages"; + static final String TABLE_NAME_FEED_MEDIA = "FeedMedia"; + static final String TABLE_NAME_DOWNLOAD_LOG = "DownloadLog"; + static final String TABLE_NAME_QUEUE = "Queue"; + static final String TABLE_NAME_SIMPLECHAPTERS = "SimpleChapters"; + static final String TABLE_NAME_FAVORITES = "Favorites"; // SQL Statements for creating new tables private static final String TABLE_PRIMARY_KEY = KEY_ID @@ -133,7 +137,7 @@ public class PodDBAdapter { + KEY_DOWNLOADED + " INTEGER," + KEY_LINK + " TEXT," + KEY_DESCRIPTION + " TEXT," + KEY_PAYMENT_LINK + " TEXT," + KEY_LASTUPDATE + " TEXT," + KEY_LANGUAGE + " TEXT," + KEY_AUTHOR - + " TEXT," + KEY_IMAGE + " INTEGER," + KEY_TYPE + " TEXT," + + " TEXT," + KEY_IMAGE_URL + " TEXT," + KEY_TYPE + " TEXT," + KEY_FEED_IDENTIFIER + " TEXT," + KEY_AUTO_DOWNLOAD + " INTEGER DEFAULT 1," + KEY_FLATTR_STATUS + " INTEGER," + KEY_USERNAME + " TEXT," @@ -155,14 +159,9 @@ public class PodDBAdapter { + KEY_MEDIA + " INTEGER," + KEY_FEED + " INTEGER," + KEY_HAS_CHAPTERS + " INTEGER," + KEY_ITEM_IDENTIFIER + " TEXT," + KEY_FLATTR_STATUS + " INTEGER," - + KEY_IMAGE + " INTEGER," + + KEY_IMAGE_URL + " TEXT," + KEY_AUTO_DOWNLOAD + " INTEGER)"; - private static final String CREATE_TABLE_FEED_IMAGES = "CREATE TABLE " - + TABLE_NAME_FEED_IMAGES + " (" + TABLE_PRIMARY_KEY + KEY_TITLE - + " TEXT," + KEY_FILE_URL + " TEXT," + KEY_DOWNLOAD_URL + " TEXT," - + KEY_DOWNLOADED + " INTEGER)"; - private static final String CREATE_TABLE_FEED_MEDIA = "CREATE TABLE " + TABLE_NAME_FEED_MEDIA + " (" + TABLE_PRIMARY_KEY + KEY_DURATION + " INTEGER," + KEY_FILE_URL + " TEXT," + KEY_DOWNLOAD_URL @@ -191,36 +190,31 @@ public class PodDBAdapter { + KEY_LINK + " TEXT," + KEY_CHAPTER_TYPE + " INTEGER)"; // SQL Statements for creating indexes - private static final String CREATE_INDEX_FEEDITEMS_FEED = "CREATE INDEX " + static final String CREATE_INDEX_FEEDITEMS_FEED = "CREATE INDEX " + TABLE_NAME_FEED_ITEMS + "_" + KEY_FEED + " ON " + TABLE_NAME_FEED_ITEMS + " (" + KEY_FEED + ")"; - private static final String CREATE_INDEX_FEEDITEMS_IMAGE = "CREATE INDEX " - + TABLE_NAME_FEED_ITEMS + "_" + KEY_IMAGE + " ON " + TABLE_NAME_FEED_ITEMS + " (" - + KEY_IMAGE + ")"; - - private static final String CREATE_INDEX_FEEDITEMS_PUBDATE = "CREATE INDEX IF NOT EXISTS " + static final String CREATE_INDEX_FEEDITEMS_PUBDATE = "CREATE INDEX IF NOT EXISTS " + TABLE_NAME_FEED_ITEMS + "_" + KEY_PUBDATE + " ON " + TABLE_NAME_FEED_ITEMS + " (" + KEY_PUBDATE + ")"; - private static final String CREATE_INDEX_FEEDITEMS_READ = "CREATE INDEX IF NOT EXISTS " + static final String CREATE_INDEX_FEEDITEMS_READ = "CREATE INDEX IF NOT EXISTS " + TABLE_NAME_FEED_ITEMS + "_" + KEY_READ + " ON " + TABLE_NAME_FEED_ITEMS + " (" + KEY_READ + ")"; - - private static final String CREATE_INDEX_QUEUE_FEEDITEM = "CREATE INDEX " + static final String CREATE_INDEX_QUEUE_FEEDITEM = "CREATE INDEX " + TABLE_NAME_QUEUE + "_" + KEY_FEEDITEM + " ON " + TABLE_NAME_QUEUE + " (" + KEY_FEEDITEM + ")"; - private static final String CREATE_INDEX_FEEDMEDIA_FEEDITEM = "CREATE INDEX " + static final String CREATE_INDEX_FEEDMEDIA_FEEDITEM = "CREATE INDEX " + TABLE_NAME_FEED_MEDIA + "_" + KEY_FEEDITEM + " ON " + TABLE_NAME_FEED_MEDIA + " (" + KEY_FEEDITEM + ")"; - private static final String CREATE_INDEX_SIMPLECHAPTERS_FEEDITEM = "CREATE INDEX " + static final String CREATE_INDEX_SIMPLECHAPTERS_FEEDITEM = "CREATE INDEX " + TABLE_NAME_SIMPLECHAPTERS + "_" + KEY_FEEDITEM + " ON " + TABLE_NAME_SIMPLECHAPTERS + " (" + KEY_FEEDITEM + ")"; - private static final String CREATE_TABLE_FAVORITES = "CREATE TABLE " + static final String CREATE_TABLE_FAVORITES = "CREATE TABLE " + TABLE_NAME_FAVORITES + "(" + KEY_ID + " INTEGER PRIMARY KEY," + KEY_FEEDITEM + " INTEGER," + KEY_FEED + " INTEGER)"; @@ -240,7 +234,7 @@ public class PodDBAdapter { TABLE_NAME_FEEDS + "." + KEY_LASTUPDATE, TABLE_NAME_FEEDS + "." + KEY_LANGUAGE, TABLE_NAME_FEEDS + "." + KEY_AUTHOR, - TABLE_NAME_FEEDS + "." + KEY_IMAGE, + TABLE_NAME_FEEDS + "." + KEY_IMAGE_URL, TABLE_NAME_FEEDS + "." + KEY_TYPE, TABLE_NAME_FEEDS + "." + KEY_FEED_IDENTIFIER, TABLE_NAME_FEEDS + "." + KEY_AUTO_DOWNLOAD, @@ -273,7 +267,7 @@ public class PodDBAdapter { TABLE_NAME_FEED_ITEMS + "." + KEY_HAS_CHAPTERS, TABLE_NAME_FEED_ITEMS + "." + KEY_ITEM_IDENTIFIER, TABLE_NAME_FEED_ITEMS + "." + KEY_FLATTR_STATUS, - TABLE_NAME_FEED_ITEMS + "." + KEY_IMAGE, + TABLE_NAME_FEED_ITEMS + "." + KEY_IMAGE_URL, TABLE_NAME_FEED_ITEMS + "." + KEY_AUTO_DOWNLOAD }; @@ -283,7 +277,6 @@ public class PodDBAdapter { private static final String[] ALL_TABLES = { TABLE_NAME_FEEDS, TABLE_NAME_FEED_ITEMS, - TABLE_NAME_FEED_IMAGES, TABLE_NAME_FEED_MEDIA, TABLE_NAME_DOWNLOAD_LOG, TABLE_NAME_QUEUE, @@ -310,7 +303,6 @@ public class PodDBAdapter { private static Context context; private static volatile SQLiteDatabase db; - private static int counter = 0; public static void init(Context context) { PodDBAdapter.context = context.getApplicationContext(); @@ -330,20 +322,20 @@ public class PodDBAdapter { } public synchronized PodDBAdapter open() { - counter++; - Log.v(TAG, "Opening DB #" + counter); - if (db == null || !db.isOpen() || db.isReadOnly()) { db = openDb(); } return this; } + @SuppressLint("NewApi") private SQLiteDatabase openDb() { SQLiteDatabase newDb; try { newDb = SingletonHolder.dbHelper.getWritableDatabase(); - newDb.enableWriteAheadLogging(); + if (Build.VERSION.SDK_INT >= 16) { + newDb.disableWriteAheadLogging(); + } } catch (SQLException ex) { Log.e(TAG, Log.getStackTraceString(ex)); newDb = SingletonHolder.dbHelper.getReadableDatabase(); @@ -352,14 +344,7 @@ public class PodDBAdapter { } public synchronized void close() { - counter--; - Log.v(TAG, "Closing DB #" + counter); - - if (counter == 0) { - Log.v(TAG, "Closing DB, really"); - db.close(); - db = null; - } + // do nothing } public static boolean deleteDatabase() { @@ -388,12 +373,7 @@ public class PodDBAdapter { values.put(KEY_PAYMENT_LINK, feed.getPaymentLink()); values.put(KEY_AUTHOR, feed.getAuthor()); values.put(KEY_LANGUAGE, feed.getLanguage()); - if (feed.getImage() != null) { - if (feed.getImage().getId() == 0) { - setImage(feed.getImage()); - } - values.put(KEY_IMAGE, feed.getImage().getId()); - } + values.put(KEY_IMAGE_URL, feed.getImageUrl()); values.put(KEY_FILE_URL, feed.getFile_url()); values.put(KEY_DOWNLOAD_URL, feed.getDownload_url()); @@ -450,54 +430,7 @@ public class PodDBAdapter { } /** - * Inserts or updates an image entry - * - * @return the id of the entry - */ - public long setImage(FeedImage image) { - boolean startedTransaction = false; - - try { - if (!db.inTransaction()) { - db.beginTransactionNonExclusive(); - startedTransaction = true; - } - - ContentValues values = new ContentValues(); - values.put(KEY_TITLE, image.getTitle()); - values.put(KEY_DOWNLOAD_URL, image.getDownload_url()); - values.put(KEY_DOWNLOADED, image.isDownloaded()); - values.put(KEY_FILE_URL, image.getFile_url()); - if (image.getId() == 0) { - image.setId(db.insert(TABLE_NAME_FEED_IMAGES, null, values)); - } else { - db.update(TABLE_NAME_FEED_IMAGES, values, KEY_ID + "=?", - new String[]{String.valueOf(image.getId())}); - } - - final FeedComponent owner = image.getOwner(); - if (owner != null && owner.getId() != 0) { - values.clear(); - values.put(KEY_IMAGE, image.getId()); - if (owner instanceof Feed) { - db.update(TABLE_NAME_FEEDS, values, KEY_ID + "=?", new String[]{String.valueOf(image.getOwner().getId())}); - } - } - if (startedTransaction) { - db.setTransactionSuccessful(); - } - } catch (SQLException e) { - Log.e(TAG, Log.getStackTraceString(e)); - } finally { - if (startedTransaction) { - db.endTransaction(); - } - } - return image.getId(); - } - - /** - * Inserts or updates an image entry + * Inserts or updates a media entry * * @return the id of the entry */ @@ -608,31 +541,6 @@ public class PodDBAdapter { } /** - * Counts feeds and feed items in the flattr queue - */ - public int getFlattrQueueSize() { - int res = 0; - Cursor c = db.rawQuery(String.format("SELECT count(*) FROM %s WHERE %s=%s", - TABLE_NAME_FEEDS, KEY_FLATTR_STATUS, String.valueOf(FlattrStatus.STATUS_QUEUE)), null); - if (c.moveToFirst()) { - res = c.getInt(0); - c.close(); - } else { - Log.e(TAG, "Unable to determine size of flattr queue: Could not count number of feeds"); - } - c = db.rawQuery(String.format("SELECT count(*) FROM %s WHERE %s=%s", - TABLE_NAME_FEED_ITEMS, KEY_FLATTR_STATUS, String.valueOf(FlattrStatus.STATUS_QUEUE)), null); - if (c.moveToFirst()) { - res += c.getInt(0); - c.close(); - } else { - Log.e(TAG, "Unable to determine size of flattr queue: Could not count number of feed items"); - } - - return res; - } - - /** * Updates the download URL of a Feed. */ public void setFeedDownloadUrl(String original, String updated) { @@ -759,12 +667,7 @@ public class PodDBAdapter { values.put(KEY_ITEM_IDENTIFIER, item.getItemIdentifier()); values.put(KEY_FLATTR_STATUS, item.getFlattrStatus().toLong()); values.put(KEY_AUTO_DOWNLOAD, item.getAutoDownload()); - if (item.hasItemImage()) { - if (item.getImage().getId() == 0) { - setImage(item.getImage()); - } - values.put(KEY_IMAGE, item.getImage().getId()); - } + values.put(KEY_IMAGE_URL, item.getImageUrl()); if (item.getId() == 0) { item.setId(db.insert(TABLE_NAME_FEED_ITEMS, null, values)); @@ -944,17 +847,6 @@ public class PodDBAdapter { return count > 0; } - public long getDownloadLogSize() { - final String query = String.format("SELECT COUNT(%s) FROM %s", KEY_ID, TABLE_NAME_DOWNLOAD_LOG); - Cursor result = db.rawQuery(query, null); - long count = 0; - if (result.moveToFirst()) { - count = result.getLong(0); - } - result.close(); - return count; - } - public void setQueue(List<FeedItem> queue) { ContentValues values = new ContentValues(); try { @@ -993,11 +885,6 @@ public class PodDBAdapter { new String[]{String.valueOf(item.getId())}); } - private void removeFeedImage(FeedImage image) { - db.delete(TABLE_NAME_FEED_IMAGES, KEY_ID + "=?", - new String[]{String.valueOf(image.getId())}); - } - /** * Remove a FeedItem and its FeedMedia entry. */ @@ -1008,9 +895,6 @@ public class PodDBAdapter { if (item.hasChapters() || item.getChapters() != null) { removeChaptersOfItem(item); } - if (item.hasItemImage()) { - removeFeedImage(item.getImage()); - } db.delete(TABLE_NAME_FEED_ITEMS, KEY_ID + "=?", new String[]{String.valueOf(item.getId())}); } @@ -1021,9 +905,6 @@ public class PodDBAdapter { public void removeFeed(Feed feed) { try { db.beginTransactionNonExclusive(); - if (feed.getImage() != null) { - removeFeedImage(feed.getImage()); - } if (feed.getItems() != null) { for (FeedItem item : feed.getItems()) { removeFeedItem(item); @@ -1094,18 +975,6 @@ public class PodDBAdapter { } /** - * Returns a cursor for a DB query in the FeedMedia table for a given ID. - * - * @param item The item you want to get the FeedMedia from - * @return The cursor of the query - */ - public final Cursor getFeedMediaOfItemCursor(final FeedItem item) { - return db.query(TABLE_NAME_FEED_MEDIA, null, KEY_ID + "=?", - new String[]{String.valueOf(item.getMedia().getId())}, null, - null, null); - } - - /** * Returns a cursor for a DB query in the FeedImages table for given IDs. * * @param imageIds IDs of the images @@ -1363,17 +1232,12 @@ public class PodDBAdapter { public Cursor getImageAuthenticationCursor(final String imageUrl) { String downloadUrl = DatabaseUtils.sqlEscapeString(imageUrl); final String query = "" - + "SELECT " + KEY_USERNAME + "," + KEY_PASSWORD + " FROM " + TABLE_NAME_FEED_IMAGES + + "SELECT " + KEY_USERNAME + "," + KEY_PASSWORD + " FROM " + TABLE_NAME_FEED_ITEMS + " INNER JOIN " + TABLE_NAME_FEEDS - + " ON " + TABLE_NAME_FEED_IMAGES + "." + KEY_ID + "=" + TABLE_NAME_FEEDS + "." + KEY_IMAGE - + " WHERE " + TABLE_NAME_FEED_IMAGES + "." + KEY_DOWNLOAD_URL + "=" + downloadUrl - + " UNION SELECT " + KEY_USERNAME + "," + KEY_PASSWORD - + " FROM " + TABLE_NAME_FEED_IMAGES - + " INNER JOIN " + TABLE_NAME_FEED_ITEMS - + " ON " + TABLE_NAME_FEED_IMAGES + "." + KEY_ID + "=" + TABLE_NAME_FEED_ITEMS + "." + KEY_IMAGE - + " INNER JOIN " + TABLE_NAME_FEEDS - + " ON " + TABLE_NAME_FEED_ITEMS + "." + KEY_FEED + "=" + TABLE_NAME_FEEDS + "." + KEY_ID - + " WHERE " + TABLE_NAME_FEED_IMAGES + "." + KEY_DOWNLOAD_URL + "=" + downloadUrl; + + " ON " + TABLE_NAME_FEED_ITEMS + "." + KEY_FEED + " = " + TABLE_NAME_FEEDS + "." + KEY_ID + + " WHERE " + TABLE_NAME_FEED_ITEMS + "." + KEY_IMAGE_URL + "=" + downloadUrl + + " UNION SELECT " + KEY_USERNAME + "," + KEY_PASSWORD + " FROM " + TABLE_NAME_FEEDS + + " WHERE " + TABLE_NAME_FEEDS + "." + KEY_IMAGE_URL + "=" + downloadUrl; return db.rawQuery(query, null); } @@ -1389,9 +1253,15 @@ public class PodDBAdapter { } public final int getNumberOfNewItems() { - final String query = "SELECT COUNT(" + KEY_ID + ")" - + " FROM " + TABLE_NAME_FEED_ITEMS - + " WHERE " + KEY_READ + "=" + FeedItem.NEW; + Object[] args = new String[]{ + TABLE_NAME_FEED_ITEMS + "." + KEY_ID, + TABLE_NAME_FEED_ITEMS, + TABLE_NAME_FEEDS, + TABLE_NAME_FEED_ITEMS + "." + KEY_FEED + "=" + TABLE_NAME_FEEDS + "." + KEY_ID, + TABLE_NAME_FEED_ITEMS + "." + KEY_READ + "=" + FeedItem.NEW + + " AND " + TABLE_NAME_FEEDS + "." + KEY_KEEP_UPDATED + " > 0" + }; + final String query = String.format("SELECT COUNT(%s) FROM %s INNER JOIN %s ON %s WHERE %s", args); Cursor c = db.rawQuery(query, null); int result = 0; if (c.moveToFirst()) { @@ -1672,7 +1542,7 @@ public class PodDBAdapter { */ private static class PodDBHelper extends SQLiteOpenHelper { - private static final int VERSION = 1060200; + private static final int VERSION = 1060596; private final Context context; @@ -1693,7 +1563,6 @@ public class PodDBAdapter { public void onCreate(final SQLiteDatabase db) { db.execSQL(CREATE_TABLE_FEEDS); db.execSQL(CREATE_TABLE_FEED_ITEMS); - db.execSQL(CREATE_TABLE_FEED_IMAGES); db.execSQL(CREATE_TABLE_FEED_MEDIA); db.execSQL(CREATE_TABLE_DOWNLOAD_LOG); db.execSQL(CREATE_TABLE_QUEUE); @@ -1701,7 +1570,6 @@ public class PodDBAdapter { db.execSQL(CREATE_TABLE_FAVORITES); db.execSQL(CREATE_INDEX_FEEDITEMS_FEED); - db.execSQL(CREATE_INDEX_FEEDITEMS_IMAGE); db.execSQL(CREATE_INDEX_FEEDITEMS_PUBDATE); db.execSQL(CREATE_INDEX_FEEDITEMS_READ); db.execSQL(CREATE_INDEX_FEEDMEDIA_FEEDITEM); @@ -1716,263 +1584,7 @@ public class PodDBAdapter { EventBus.getDefault().post(ProgressEvent.start(context.getString(R.string.progress_upgrading_database))); Log.w("DBAdapter", "Upgrading from version " + oldVersion + " to " + newVersion + "."); - if (oldVersion <= 1) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + " ADD COLUMN " - + KEY_TYPE + " TEXT"); - } - if (oldVersion <= 2) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS - + " ADD COLUMN " + KEY_LINK + " TEXT"); - } - if (oldVersion <= 3) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS - + " ADD COLUMN " + KEY_ITEM_IDENTIFIER + " TEXT"); - } - if (oldVersion <= 4) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + " ADD COLUMN " - + KEY_FEED_IDENTIFIER + " TEXT"); - } - if (oldVersion <= 5) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_DOWNLOAD_LOG - + " ADD COLUMN " + KEY_REASON_DETAILED + " TEXT"); - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_DOWNLOAD_LOG - + " ADD COLUMN " + KEY_DOWNLOADSTATUS_TITLE + " TEXT"); - } - if (oldVersion <= 6) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS - + " ADD COLUMN " + KEY_CHAPTER_TYPE + " INTEGER"); - } - if (oldVersion <= 7) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA - + " ADD COLUMN " + KEY_PLAYBACK_COMPLETION_DATE - + " INTEGER"); - } - if (oldVersion <= 8) { - final int KEY_ID_POSITION = 0; - final int KEY_MEDIA_POSITION = 1; - - // Add feeditem column to feedmedia table - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA - + " ADD COLUMN " + KEY_FEEDITEM - + " INTEGER"); - Cursor feeditemCursor = db.query(PodDBAdapter.TABLE_NAME_FEED_ITEMS, - new String[]{KEY_ID, KEY_MEDIA}, "? > 0", - new String[]{KEY_MEDIA}, null, null, null); - if (feeditemCursor.moveToFirst()) { - db.beginTransaction(); - ContentValues contentValues = new ContentValues(); - do { - long mediaId = feeditemCursor.getLong(KEY_MEDIA_POSITION); - contentValues.put(KEY_FEEDITEM, feeditemCursor.getLong(KEY_ID_POSITION)); - db.update(PodDBAdapter.TABLE_NAME_FEED_MEDIA, contentValues, KEY_ID + "=?", new String[]{String.valueOf(mediaId)}); - contentValues.clear(); - } while (feeditemCursor.moveToNext()); - db.setTransactionSuccessful(); - db.endTransaction(); - } - feeditemCursor.close(); - } - if (oldVersion <= 9) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS - + " ADD COLUMN " + KEY_AUTO_DOWNLOAD - + " INTEGER DEFAULT 1"); - } - if (oldVersion <= 10) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS - + " ADD COLUMN " + KEY_FLATTR_STATUS - + " INTEGER"); - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS - + " ADD COLUMN " + KEY_FLATTR_STATUS - + " INTEGER"); - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA - + " ADD COLUMN " + KEY_PLAYED_DURATION - + " INTEGER"); - } - if (oldVersion <= 11) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS - + " ADD COLUMN " + KEY_USERNAME - + " TEXT"); - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS - + " ADD COLUMN " + KEY_PASSWORD - + " TEXT"); - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS - + " ADD COLUMN " + KEY_IMAGE - + " INTEGER"); - } - if (oldVersion <= 12) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS - + " ADD COLUMN " + KEY_IS_PAGED + " INTEGER DEFAULT 0"); - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS - + " ADD COLUMN " + KEY_NEXT_PAGE_LINK + " TEXT"); - } - if (oldVersion <= 13) { - // remove duplicate rows in "Chapters" table that were created because of a bug. - db.execSQL(String.format("DELETE FROM %s WHERE %s NOT IN " + - "(SELECT MIN(%s) as %s FROM %s GROUP BY %s,%s,%s,%s,%s)", - PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS, - KEY_ID, - KEY_ID, - KEY_ID, - PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS, - KEY_TITLE, - KEY_START, - KEY_FEEDITEM, - KEY_LINK, - KEY_CHAPTER_TYPE)); - } - if (oldVersion <= 14) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS - + " ADD COLUMN " + KEY_AUTO_DOWNLOAD + " INTEGER"); - db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS - + " SET " + KEY_AUTO_DOWNLOAD + " = " - + "(SELECT " + KEY_AUTO_DOWNLOAD - + " FROM " + PodDBAdapter.TABLE_NAME_FEEDS - + " WHERE " + PodDBAdapter.TABLE_NAME_FEEDS + "." + KEY_ID - + " = " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + KEY_FEED + ")"); - - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS - + " ADD COLUMN " + KEY_HIDE + " TEXT"); - - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS - + " ADD COLUMN " + KEY_LAST_UPDATE_FAILED + " INTEGER DEFAULT 0"); - - // create indexes - db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_FEED); - db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_IMAGE); - db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDMEDIA_FEEDITEM); - db.execSQL(PodDBAdapter.CREATE_INDEX_QUEUE_FEEDITEM); - db.execSQL(PodDBAdapter.CREATE_INDEX_SIMPLECHAPTERS_FEEDITEM); - } - if (oldVersion <= 15) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA - + " ADD COLUMN " + KEY_HAS_EMBEDDED_PICTURE + " INTEGER DEFAULT -1"); - db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA - + " SET " + KEY_HAS_EMBEDDED_PICTURE + "=0" - + " WHERE " + KEY_DOWNLOADED + "=0"); - Cursor c = db.rawQuery("SELECT " + KEY_FILE_URL - + " FROM " + PodDBAdapter.TABLE_NAME_FEED_MEDIA - + " WHERE " + KEY_DOWNLOADED + "=1 " - + " AND " + KEY_HAS_EMBEDDED_PICTURE + "=-1", null); - if (c.moveToFirst()) { - MediaMetadataRetriever mmr = new MediaMetadataRetriever(); - do { - String fileUrl = c.getString(0); - try { - mmr.setDataSource(fileUrl); - byte[] image = mmr.getEmbeddedPicture(); - if (image != null) { - db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA - + " SET " + KEY_HAS_EMBEDDED_PICTURE + "=1" - + " WHERE " + KEY_FILE_URL + "='" + fileUrl + "'"); - } else { - db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA - + " SET " + KEY_HAS_EMBEDDED_PICTURE + "=0" - + " WHERE " + KEY_FILE_URL + "='" + fileUrl + "'"); - } - } catch (Exception e) { - e.printStackTrace(); - } - } while (c.moveToNext()); - } - c.close(); - } - if (oldVersion <= 16) { - String selectNew = "SELECT " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + KEY_ID - + " FROM " + PodDBAdapter.TABLE_NAME_FEED_ITEMS - + " INNER JOIN " + PodDBAdapter.TABLE_NAME_FEED_MEDIA + " ON " - + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + KEY_ID + "=" - + PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + KEY_FEEDITEM - + " LEFT OUTER JOIN " + PodDBAdapter.TABLE_NAME_QUEUE + " ON " - + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + KEY_ID + "=" - + PodDBAdapter.TABLE_NAME_QUEUE + "." + KEY_FEEDITEM - + " WHERE " - + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + KEY_READ + " = 0 AND " // unplayed - + PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + KEY_DOWNLOADED + " = 0 AND " // undownloaded - + PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + KEY_POSITION + " = 0 AND " // not partially played - + PodDBAdapter.TABLE_NAME_QUEUE + "." + KEY_ID + " IS NULL"; // not in queue - String sql = "UPDATE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS - + " SET " + KEY_READ + "=" + FeedItem.NEW - + " WHERE " + KEY_ID + " IN (" + selectNew + ")"; - Log.d("Migration", "SQL: " + sql); - db.execSQL(sql); - } - if (oldVersion <= 17) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS - + " ADD COLUMN " + PodDBAdapter.KEY_AUTO_DELETE_ACTION + " INTEGER DEFAULT 0"); - } - if (oldVersion < 1030005) { - db.execSQL("UPDATE FeedItems SET auto_download=0 WHERE " + - "(read=1 OR id IN (SELECT feeditem FROM FeedMedia WHERE position>0 OR downloaded=1)) " + - "AND id NOT IN (SELECT feeditem FROM Queue)"); - } - if (oldVersion < 1040001) { - db.execSQL(CREATE_TABLE_FAVORITES); - } - if (oldVersion < 1040002) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA - + " ADD COLUMN " + PodDBAdapter.KEY_LAST_PLAYED_TIME + " INTEGER DEFAULT 0"); - } - if (oldVersion < 1040013) { - db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_PUBDATE); - db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_READ); - } - if (oldVersion < 1050003) { - // Migrates feed list filter data - - db.beginTransaction(); - - // Change to intermediate values to avoid overwriting in the following find/replace - db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" + - "SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'unplayed', 'noplay')"); - db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" + - "SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'not_queued', 'noqueue')"); - db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" + - "SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'not_downloaded', 'nodl')"); - - // Replace played, queued, and downloaded with their opposites - db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" + - "SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'played', 'unplayed')"); - db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" + - "SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'queued', 'not_queued')"); - db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" + - "SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'downloaded', 'not_downloaded')"); - - // Now replace intermediates for unplayed, not queued, etc. with their opposites - db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" + - "SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'noplay', 'played')"); - db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" + - "SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'noqueue', 'queued')"); - db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" + - "SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'nodl', 'downloaded')"); - - // Paused doesn't have an opposite, so unplayed is the next best option - db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" + - "SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'paused', 'unplayed')"); - - db.setTransactionSuccessful(); - db.endTransaction(); - - // and now get ready for autodownload filters - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS - + " ADD COLUMN " + PodDBAdapter.KEY_INCLUDE_FILTER + " TEXT DEFAULT ''"); - - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS - + " ADD COLUMN " + PodDBAdapter.KEY_EXCLUDE_FILTER + " TEXT DEFAULT ''"); - - // and now auto refresh - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS - + " ADD COLUMN " + PodDBAdapter.KEY_KEEP_UPDATED + " INTEGER DEFAULT 1"); - } - if (oldVersion < 1050004) { - // prevent old timestamps to be misinterpreted as ETags - 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"); - } - + DBUpgrader.upgrade(db, oldVersion, newVersion); EventBus.getDefault().post(ProgressEvent.end()); } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/TypeGetter.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/TypeGetter.java index ee0a71f30..b4c77e58d 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/TypeGetter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/TypeGetter.java @@ -54,18 +54,19 @@ public class TypeGetter { return Type.ATOM; case RSS_ROOT: String strVersion = xpp.getAttributeValue(null, "version"); - if (strVersion != null) { - if (strVersion.equals("2.0")) { - feed.setType(Feed.TYPE_RSS2); - Log.d(TAG, "Recognized type RSS 2.0"); - return Type.RSS20; - } else if (strVersion.equals("0.91") - || strVersion.equals("0.92")) { - Log.d(TAG, "Recognized type RSS 0.91/0.92"); - return Type.RSS091; - } + if (strVersion == null) { + feed.setType(Feed.TYPE_RSS2); + Log.d(TAG, "Assuming type RSS 2.0"); + return Type.RSS20; + } else if (strVersion.equals("2.0")) { + feed.setType(Feed.TYPE_RSS2); + Log.d(TAG, "Recognized type RSS 2.0"); + return Type.RSS20; + } else if (strVersion.equals("0.91") || strVersion.equals("0.92")) { + Log.d(TAG, "Recognized type RSS 0.91/0.92"); + return Type.RSS091; } - throw new UnsupportedFeedtypeException(Type.INVALID); + throw new UnsupportedFeedtypeException("Unsupported rss version"); default: Log.d(TAG, "Type is invalid"); throw new UnsupportedFeedtypeException(Type.INVALID, tag); diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/UnsupportedFeedtypeException.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/UnsupportedFeedtypeException.java index 606f93faf..fd7d0a4e1 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/UnsupportedFeedtypeException.java +++ b/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/UnsupportedFeedtypeException.java @@ -5,7 +5,8 @@ import de.danoeh.antennapod.core.syndication.handler.TypeGetter.Type; public class UnsupportedFeedtypeException extends Exception { private static final long serialVersionUID = 9105878964928170669L; private final TypeGetter.Type type; - private String rootElement; + private String rootElement; + private String message = null; public UnsupportedFeedtypeException(Type type) { super(); @@ -17,6 +18,11 @@ public class UnsupportedFeedtypeException extends Exception { this.rootElement = rootElement; } + public UnsupportedFeedtypeException(String message) { + this.message = message; + type = Type.INVALID; + } + public TypeGetter.Type getType() { return type; } @@ -27,7 +33,9 @@ public class UnsupportedFeedtypeException extends Exception { @Override public String getMessage() { - if (type == TypeGetter.Type.INVALID) { + if (message != null) { + return message; + } else if (type == TypeGetter.Type.INVALID) { return "Invalid type"; } else { return "Type " + type + " not supported"; diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSITunes.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSITunes.java index 670e99fce..b3b8a40ce 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSITunes.java +++ b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSITunes.java @@ -7,7 +7,6 @@ import org.xml.sax.Attributes; import java.util.concurrent.TimeUnit; -import de.danoeh.antennapod.core.feed.FeedImage; import de.danoeh.antennapod.core.syndication.handler.HandlerState; public class NSITunes extends Namespace { @@ -16,7 +15,6 @@ public class NSITunes extends Namespace { public static final String NSURI = "http://www.itunes.com/dtds/podcast-1.0.dtd"; private static final String IMAGE = "image"; - private static final String IMAGE_TITLE = "image"; private static final String IMAGE_HREF = "href"; private static final String AUTHOR = "author"; @@ -29,21 +27,15 @@ public class NSITunes extends Namespace { public SyndElement handleElementStart(String localName, HandlerState state, Attributes attributes) { if (IMAGE.equals(localName)) { - FeedImage image = new FeedImage(); - image.setTitle(IMAGE_TITLE); - image.setDownload_url(attributes.getValue(IMAGE_HREF)); + String url = attributes.getValue(IMAGE_HREF); if (state.getCurrentItem() != null) { - // this is an items image - image.setTitle(state.getCurrentItem().getTitle() + IMAGE_TITLE); - image.setOwner(state.getCurrentItem()); - state.getCurrentItem().setImage(image); + state.getCurrentItem().setImageUrl(url); } else { // this is the feed image // prefer to all other images - if (!TextUtils.isEmpty(image.getDownload_url())) { - image.setOwner(state.getFeed()); - state.getFeed().setImage(image); + if (!TextUtils.isEmpty(url)) { + state.getFeed().setImageUrl(url); } } } @@ -55,6 +47,9 @@ public class NSITunes extends Namespace { if(state.getContentBuf() == null) { return; } + SyndElement secondElement = state.getSecondTag(); + String second = secondElement.getName(); + if (AUTHOR.equals(localName)) { if (state.getFeed() != null) { String author = state.getContentBuf().toString(); @@ -103,10 +98,9 @@ public class NSITunes extends Namespace { } if (state.getCurrentItem() != null && (TextUtils.isEmpty(state.getCurrentItem().getDescription()) || - state.getCurrentItem().getDescription().length() * 1.25 < summary.length()) - ) { + state.getCurrentItem().getDescription().length() * 1.25 < summary.length())) { state.getCurrentItem().setDescription(summary); - } else if (state.getFeed() != null) { + } else if (NSRSS20.CHANNEL.equals(second) && state.getFeed() != null) { state.getFeed().setDescription(summary); } } 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 f2cfc2e57..638383223 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 @@ -7,7 +7,6 @@ import org.xml.sax.Attributes; import java.util.concurrent.TimeUnit; -import de.danoeh.antennapod.core.feed.FeedImage; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.syndication.handler.HandlerState; import de.danoeh.antennapod.core.syndication.namespace.atom.AtomText; @@ -94,25 +93,16 @@ public class NSMedia extends Namespace { } 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); + state.getCurrentItem().setImageUrl(url); } } else if (IMAGE.equals(localName)) { String url = attributes.getValue(IMAGE_URL); if (url != null) { - FeedImage image = new FeedImage(); - image.setDownload_url(url); - if (state.getCurrentItem() != null) { - image.setOwner(state.getCurrentItem()); - state.getCurrentItem().setImage(image); + state.getCurrentItem().setImageUrl(url); } else { - if (state.getFeed().getImage() == null) { - image.setOwner(state.getFeed()); - state.getFeed().setImage(image); + if (state.getFeed().getImageUrl() == null) { + state.getFeed().setImageUrl(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 3d752df76..e391af1b2 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 @@ -5,8 +5,6 @@ import android.util.Log; import org.xml.sax.Attributes; -import de.danoeh.antennapod.core.feed.Feed; -import de.danoeh.antennapod.core.feed.FeedImage; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.syndication.handler.HandlerState; @@ -23,9 +21,6 @@ public class NSRSS20 extends Namespace { 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"; private static final String GUID = "guid"; @@ -77,17 +72,6 @@ public class NSRSS20 extends Namespace { state.getCurrentItem().setMedia(media); } - } else if (IMAGE.equals(localName)) { - if (state.getTagstack().size() >= 1) { - String parent = state.getTagstack().peek().getName(); - if (CHANNEL.equals(parent)) { - Feed feed = state.getFeed(); - if(feed != null && feed.getImage() == null) { - feed.setImage(new FeedImage()); - feed.getImage().setOwner(state.getFeed()); - } - } - } } return new SyndElement(localName, this); } @@ -134,11 +118,6 @@ public class NSRSS20 extends Namespace { state.getCurrentItem().setTitle(title); } else if (CHANNEL.equals(second) && state.getFeed() != null) { state.getFeed().setTitle(title); - } else if (IMAGE.equals(second) && CHANNEL.equals(third)) { - if(state.getFeed() != null && state.getFeed().getImage() != null && - state.getFeed().getImage().getTitle() == null) { - state.getFeed().getImage().setTitle(title); - } } } else if (LINK.equals(top)) { if (CHANNEL.equals(second) && state.getFeed() != null) { @@ -150,9 +129,8 @@ public class NSRSS20 extends Namespace { state.getCurrentItem().setPubDate(DateUtils.parse(content)); } else if (URL.equals(top) && IMAGE.equals(second) && CHANNEL.equals(third)) { // prefer itunes:image - if(state.getFeed() != null && state.getFeed().getImage() != null && - state.getFeed().getImage().getDownload_url() == null) { - state.getFeed().getImage().setDownload_url(content); + if (state.getFeed() != null) { + state.getFeed().setImageUrl(content); } } else if (DESCR.equals(localName)) { if (CHANNEL.equals(second) && state.getFeed() != null) { diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/Namespace.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/Namespace.java index 1836bbec1..e5fbdb9bb 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/Namespace.java +++ b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/Namespace.java @@ -15,7 +15,6 @@ public abstract class Namespace { public abstract SyndElement handleElementStart(String localName, HandlerState state, Attributes attributes); /** Called by a Feedhandler when in endElement and it detects a namespace element - * @return true if namespace handled the element, false if it ignored it * */ public abstract void handleElementEnd(String localName, HandlerState state); 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 1fe388d9d..83957456a 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 @@ -5,7 +5,6 @@ import android.util.Log; import org.xml.sax.Attributes; -import de.danoeh.antennapod.core.feed.FeedImage; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.syndication.handler.HandlerState; @@ -48,8 +47,6 @@ public class NSAtom extends Namespace { 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"; - private static final String LINK_REL_SELF = "self"; private static final String LINK_REL_NEXT = "next"; // type-values private static final String LINK_TYPE_ATOM = "application/atom+xml"; @@ -210,10 +207,10 @@ public class NSAtom extends Namespace { state.getCurrentItem().setPubDate(DateUtils.parse(content)); } else if (PUBLISHED.equals(top) && ENTRY.equals(second) && state.getCurrentItem() != null) { state.getCurrentItem().setPubDate(DateUtils.parse(content)); - } else if (IMAGE_LOGO.equals(top) && state.getFeed() != null && state.getFeed().getImage() == null) { - state.getFeed().setImage(new FeedImage(state.getFeed(), content, null)); + } else if (IMAGE_LOGO.equals(top) && state.getFeed() != null && state.getFeed().getImageUrl() == null) { + state.getFeed().setImageUrl(content); } else if (IMAGE_ICON.equals(top) && state.getFeed() != null) { - state.getFeed().setImage(new FeedImage(state.getFeed(), content, null)); + state.getFeed().setImageUrl(content); } else if (AUTHOR_NAME.equals(top) && AUTHOR.equals(second) && state.getFeed() != null && state.getCurrentItem() == null) { String currentName = state.getFeed().getAuthor(); diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/Consumer.java b/core/src/main/java/de/danoeh/antennapod/core/util/Consumer.java new file mode 100644 index 000000000..13a87af0d --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/util/Consumer.java @@ -0,0 +1,5 @@ +package de.danoeh.antennapod.core.util; + +public interface Consumer<T> { + void accept(T t); +} diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/Converter.java b/core/src/main/java/de/danoeh/antennapod/core/util/Converter.java index b513fbe99..6ecca941a 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/Converter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/Converter.java @@ -28,7 +28,6 @@ public final class Converter { /** Determines the length of the number for best readability.*/ private static final int NUM_LENGTH = 1024; - private static final int DAYS_MIL = 86400000; private static final int HOURS_MIL = 3600000; private static final int MINUTES_MIL = 60000; private static final int SECONDS_MIL = 1000; @@ -75,13 +74,14 @@ public final class Converter { return String.format(Locale.getDefault(), "%02d:%02d:%02d", h, m, s); } - /** Converts milliseconds to a string containing hours and minutes */ - public static String getDurationStringShort(int duration) { - int h = duration / HOURS_MIL; - int rest = duration - h * HOURS_MIL; - int m = rest / MINUTES_MIL; - - return String.format(Locale.getDefault(), "%02d:%02d", h, m); + /** Converts milliseconds to a string containing hours and minutes or minutes and seconds*/ + public static String getDurationStringShort(int duration, boolean durationIsInHours) { + int firstPartBase = durationIsInHours ? HOURS_MIL : MINUTES_MIL; + int firstPart = duration / firstPartBase; + int leftoverFromFirstPart = duration - firstPart * firstPartBase; + int secondPart = leftoverFromFirstPart / (durationIsInHours ? MINUTES_MIL : SECONDS_MIL); + + return String.format(Locale.getDefault(), "%02d:%02d", firstPart, secondPart); } /** Converts long duration string (HH:MM:SS) to milliseconds. */ @@ -95,14 +95,20 @@ public final class Converter { Integer.parseInt(parts[2]) * 1000; } - /** Converts short duration string (HH:MM) to milliseconds. */ - public static int durationStringShortToMs(String input) { + /** + * Converts short duration string (XX:YY) to milliseconds. If durationIsInHours is true then the + * format is HH:MM, otherwise it's MM:SS. + * */ + public static int durationStringShortToMs(String input, boolean durationIsInHours) { String[] parts = input.split(":"); if (parts.length != 2) { return 0; } - return Integer.parseInt(parts[0]) * 3600 * 1000 + - Integer.parseInt(parts[1]) * 1000 * 60; + + int modifier = durationIsInHours ? 60 : 1; + + return Integer.parseInt(parts[0]) * 60 * 1000 * modifier+ + Integer.parseInt(parts[1]) * 1000 * modifier; } /** Converts milliseconds to a localized string containing hours and minutes */ @@ -131,6 +137,7 @@ public final class Converter { return String.format(Locale.getDefault(), "%.1f ", hours) + context.getString(R.string.time_hours); } + /** * Converts the volume as read as the progress from a SeekBar scaled to 100 and as saved in * UserPreferences to the format taken by setVolume methods. diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/DateUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/DateUtils.java index 5056ea274..5141e3a78 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/DateUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/DateUtils.java @@ -17,7 +17,9 @@ import java.util.TimeZone; */ public class DateUtils { - private static final String TAG = "DateUtils"; + private DateUtils(){} + + private static final String TAG = "DateUtils"; private static final TimeZone defaultTimezone = TimeZone.getTimeZone("GMT"); @@ -85,7 +87,8 @@ public class DateUtils { "yyyy-MM-dd'T'HH:mm:ss'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-ddZ", - "yyyy-MM-dd" + "yyyy-MM-dd", + "EEE d MMM yyyy HH:mm:ss 'GMT'Z (z)" }; SimpleDateFormat parser = new SimpleDateFormat("", Locale.US); @@ -134,7 +137,7 @@ public class DateUtils { if (parts.length >= 2) { result += Integer.parseInt(parts[idx]) * 60000L; idx++; - result += (Float.parseFloat(parts[idx])) * 1000L; + result += (long) (Float.parseFloat(parts[idx]) * 1000L); } return result; } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/EpisodeFilter.java b/core/src/main/java/de/danoeh/antennapod/core/util/EpisodeFilter.java deleted file mode 100644 index fb1b0dc8f..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/util/EpisodeFilter.java +++ /dev/null @@ -1,50 +0,0 @@ -package de.danoeh.antennapod.core.util; - -import java.util.ArrayList; -import java.util.List; - -import de.danoeh.antennapod.core.feed.FeedItem; - -class EpisodeFilter { - - private EpisodeFilter() { - - } - - /** Return a copy of the itemlist without items which have no media. */ - public static ArrayList<FeedItem> getEpisodeList(List<FeedItem> items) { - ArrayList<FeedItem> episodes = new ArrayList<>(items); - for (FeedItem item : items) { - if (item.getMedia() == null) { - episodes.remove(item); - } - } - return episodes; - } - - public static int countItemsWithEpisodes(List<FeedItem> items) { - int count = 0; - for (FeedItem item : items) { - if (item.getMedia() != null) { - count++; - } - } - return count; - } - - public static FeedItem accessEpisodeByIndex(List<FeedItem> items, - int position) { - int count = 0; - for (FeedItem item : items) { - - if (item.getMedia() != null) { - if (count == position) { - return item; - } else { - count++; - } - } - } - return null; - } -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/FeedItemUtil.java b/core/src/main/java/de/danoeh/antennapod/core/util/FeedItemUtil.java index 76a6549ae..826c06822 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/FeedItemUtil.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/FeedItemUtil.java @@ -5,6 +5,7 @@ import java.util.List; import de.danoeh.antennapod.core.feed.FeedItem; public class FeedItemUtil { + private FeedItemUtil(){} public static int indexOfItemWithDownloadUrl(List<FeedItem> items, String downloadUrl) { if(items == null) { diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/FeedUpdateUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/FeedUpdateUtils.java index 24e0da9ed..afaf13390 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/FeedUpdateUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/FeedUpdateUtils.java @@ -2,20 +2,30 @@ package de.danoeh.antennapod.core.util; import android.content.Context; import android.util.Log; + +import org.awaitility.core.ConditionTimeoutException; + +import java.util.concurrent.TimeUnit; + import de.danoeh.antennapod.core.storage.DBTasks; +import static org.awaitility.Awaitility.with; + public class FeedUpdateUtils { private static final String TAG = "FeedUpdateUtils"; - private FeedUpdateUtils() { - - } + private FeedUpdateUtils() {} public static void startAutoUpdate(Context context, Runnable callback) { - if (NetworkUtils.networkAvailable() && NetworkUtils.isDownloadAllowed()) { + try { + with().pollInterval(1, TimeUnit.SECONDS) + .await() + .atMost(10, TimeUnit.SECONDS) + .until(() -> NetworkUtils.networkAvailable() && NetworkUtils.isDownloadAllowed()); DBTasks.refreshAllFeeds(context, null, callback); - } else { + } catch (ConditionTimeoutException ignore) { Log.d(TAG, "Blocking automatic update: no wifi available / no mobile updates allowed"); } } + } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/Function.java b/core/src/main/java/de/danoeh/antennapod/core/util/Function.java new file mode 100644 index 000000000..c4f4ad68a --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/util/Function.java @@ -0,0 +1,7 @@ +package de.danoeh.antennapod.core.util; + +import io.reactivex.annotations.NonNull; + +public interface Function<T, R> { + R apply(@NonNull T t); +} diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/IntentUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/IntentUtils.java index 1571b71c2..e81ab47ed 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/IntentUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/IntentUtils.java @@ -8,6 +8,7 @@ import android.content.pm.ResolveInfo; import java.util.List; public class IntentUtils { + private IntentUtils(){} /* * Checks if there is at least one exported activity that can be performed for the intent @@ -23,4 +24,8 @@ public class IntentUtils { return false; } + public static void sendLocalBroadcast(Context context, String action) { + context.sendBroadcast(new Intent(action).setPackage(context.getPackageName())); + } + } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/LangUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/LangUtils.java index 7ec7f84c4..90e0b0981 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/LangUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/LangUtils.java @@ -5,6 +5,9 @@ import android.support.v4.util.ArrayMap; import java.nio.charset.Charset; public class LangUtils { + + private LangUtils(){} + public static final Charset UTF_8 = Charset.forName("UTF-8"); private static final ArrayMap<String, String> languages; 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 cbda583fa..9bdd375ce 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 @@ -18,15 +18,16 @@ 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 io.reactivex.Single; +import io.reactivex.SingleOnSubscribe; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.schedulers.Schedulers; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; -import rx.Observable; -import rx.Subscriber; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; public class NetworkUtils { + private NetworkUtils(){} private static final String TAG = NetworkUtils.class.getSimpleName(); @@ -89,9 +90,13 @@ public class NetworkUtils { return info != null && info.isConnected(); } - public static boolean isDownloadAllowed() { - return UserPreferences.isAllowMobileUpdate() || !NetworkUtils.isNetworkMetered(); - } + public static boolean isDownloadAllowed() { + return UserPreferences.isAllowMobileUpdate() || !NetworkUtils.isNetworkMetered(); + } + + public static boolean isImageAllowed() { + return UserPreferences.isAllowMobileImages() || !NetworkUtils.isNetworkMetered(); + } private static boolean isNetworkMetered() { ConnectivityManager connManager = (ConnectivityManager) context @@ -111,11 +116,10 @@ public class NetworkUtils { return null; } - public static Observable<Long> getFeedMediaSizeObservable(FeedMedia media) { - return Observable.create((Observable.OnSubscribe<Long>) subscriber -> { + public static Single<Long> getFeedMediaSizeObservable(FeedMedia media) { + return Single.create((SingleOnSubscribe<Long>) emitter -> { if (!NetworkUtils.isDownloadAllowed()) { - subscriber.onNext(0L); - subscriber.onCompleted(); + emitter.onSuccess(0L); return; } long size = Integer.MIN_VALUE; @@ -129,8 +133,7 @@ public class NetworkUtils { String url = media.getDownload_url(); if(TextUtils.isEmpty(url)) { - subscriber.onNext(0L); - subscriber.onCompleted(); + emitter.onSuccess(0L); return; } @@ -150,8 +153,7 @@ public class NetworkUtils { } } } catch (IOException e) { - subscriber.onNext(0L); - subscriber.onCompleted(); + emitter.onSuccess(0L); Log.e(TAG, Log.getStackTraceString(e)); return; // better luck next time } @@ -163,11 +165,10 @@ public class NetworkUtils { } else { media.setSize(size); } - subscriber.onNext(size); - subscriber.onCompleted(); + emitter.onSuccess(size); DBWriter.setFeedMedia(media); }) - .subscribeOn(Schedulers.newThread()) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/Optional.java b/core/src/main/java/de/danoeh/antennapod/core/util/Optional.java new file mode 100644 index 000000000..0fe11ec53 --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/util/Optional.java @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package de.danoeh.antennapod.core.util; + +import java.util.NoSuchElementException; +import java.util.Objects; + +// AntennaPod's stripped-down version of Java/Android platform's java.util.Optional +// so that it can be used on lower API level (API level 14) + +// Android-changed: removed ValueBased paragraph. +/** + * A container object which may or may not contain a non-null value. + * If a value is present, {@code isPresent()} will return {@code true} and + * {@code get()} will return the value. + * + * <p>Additional methods that depend on the presence or absence of a contained + * value are provided, such as {@link #orElse(java.lang.Object) orElse()} + * (return a default value if value not present) and + * {@link #ifPresent(java.util.function.Consumer) ifPresent()} (execute a block + * of code if the value is present). + * + * @since 1.8 + */ +public final class Optional<T> { + /** + * Common instance for {@code empty()}. + */ + private static final Optional<?> EMPTY = new Optional<>(); + + /** + * If non-null, the value; if null, indicates no value is present + */ + private final T value; + + /** + * Constructs an empty instance. + * + * @implNote Generally only one empty instance, {@link Optional#EMPTY}, + * should exist per VM. + */ + private Optional() { + this.value = null; + } + + /** + * Returns an empty {@code Optional} instance. No value is present for this + * Optional. + * + * @apiNote Though it may be tempting to do so, avoid testing if an object + * is empty by comparing with {@code ==} against instances returned by + * {@code Option.empty()}. There is no guarantee that it is a singleton. + * Instead, use {@link #isPresent()}. + * + * @param <T> Type of the non-existent value + * @return an empty {@code Optional} + */ + public static<T> Optional<T> empty() { + @SuppressWarnings("unchecked") + Optional<T> t = (Optional<T>) EMPTY; + return t; + } + + /** + * Constructs an instance with the value present. + * + * @param value the non-null value to be present + * @throws NullPointerException if value is null + */ + private Optional(T value) { + this.value = Objects.requireNonNull(value); + } + + /** + * Returns an {@code Optional} with the specified present non-null value. + * + * @param <T> the class of the value + * @param value the value to be present, which must be non-null + * @return an {@code Optional} with the value present + * @throws NullPointerException if value is null + */ + public static <T> Optional<T> of(T value) { + return new Optional<>(value); + } + + /** + * Returns an {@code Optional} describing the specified value, if non-null, + * otherwise returns an empty {@code Optional}. + * + * @param <T> the class of the value + * @param value the possibly-null value to describe + * @return an {@code Optional} with a present value if the specified value + * is non-null, otherwise an empty {@code Optional} + */ + public static <T> Optional<T> ofNullable(T value) { + return value == null ? empty() : of(value); + } + + /** + * If a value is present in this {@code Optional}, returns the value, + * otherwise throws {@code NoSuchElementException}. + * + * @return the non-null value held by this {@code Optional} + * @throws NoSuchElementException if there is no value present + * + * @see Optional#isPresent() + */ + public T get() { + if (value == null) { + throw new NoSuchElementException("No value present"); + } + return value; + } + + /** + * Return {@code true} if there is a value present, otherwise {@code false}. + * + * @return {@code true} if there is a value present, otherwise {@code false} + */ + public boolean isPresent() { + return value != null; + } + + + /** + * Return the value if present, otherwise return {@code other}. + * + * @param other the value to be returned if there is no value present, may + * be null + * @return the value, if present, otherwise {@code other} + */ + public T orElse(T other) { + return value != null ? value : other; + } + + /** + * Indicates whether some other object is "equal to" this Optional. The + * other object is considered equal if: + * <ul> + * <li>it is also an {@code Optional} and; + * <li>both instances have no value present or; + * <li>the present values are "equal to" each other via {@code equals()}. + * </ul> + * + * @param obj an object to be tested for equality + * @return {code true} if the other object is "equal to" this object + * otherwise {@code false} + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (!(obj instanceof Optional)) { + return false; + } + + Optional<?> other = (Optional<?>) obj; + return (value == other.value) || (value != null && value.equals(other.value)); + } + + /** + * Returns the hash code value of the present value, if any, or 0 (zero) if + * no value is present. + * + * @return hash code value of the present value or 0 if no value is present + */ + @Override + public int hashCode() { + return value != null ? value.hashCode() : 0; + } + + /** + * Returns a non-empty string representation of this Optional suitable for + * debugging. The exact presentation format is unspecified and may vary + * between implementations and versions. + * + * @implSpec If a value is present the result must include its string + * representation in the result. Empty and present Optionals must be + * unambiguously differentiable. + * + * @return the string representation of this instance + */ + @Override + public String toString() { + return value != null + ? String.format("Optional[%s]", value) + : "Optional.empty"; + } +} diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/QueueAccess.java b/core/src/main/java/de/danoeh/antennapod/core/util/QueueAccess.java index 7377b202d..9408be348 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/QueueAccess.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/QueueAccess.java @@ -58,19 +58,4 @@ public abstract class QueueAccess { }; } - public static QueueAccess NotInQueueAccess() { - return new QueueAccess() { - @Override - public boolean contains(long id) { - return false; - } - - @Override - public boolean remove(long id) { - return false; - } - }; - - } - } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/RewindAfterPauseUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/RewindAfterPauseUtils.java index ee306a401..d1818aeef 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/RewindAfterPauseUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/RewindAfterPauseUtils.java @@ -9,6 +9,7 @@ import java.util.concurrent.TimeUnit; * Media file should be "rewinded" x seconds after user resumes the playback. */ public class RewindAfterPauseUtils { + private RewindAfterPauseUtils(){} public static final long ELAPSED_TIME_FOR_SHORT_REWIND = TimeUnit.MINUTES.toMillis(1); public static final long ELAPSED_TIME_FOR_MEDIUM_REWIND = TimeUnit.HOURS.toMillis(1); diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/StorageUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/StorageUtils.java index 1ef81bf64..3a6bf5755 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/StorageUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/StorageUtils.java @@ -14,6 +14,8 @@ import de.danoeh.antennapod.core.preferences.UserPreferences; * Utility functions for handling storage errors */ public class StorageUtils { + private StorageUtils(){} + private static final String TAG = "StorageUtils"; public static boolean storageAvailable() { diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/ThemeUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/ThemeUtils.java index f67367643..14f091249 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/ThemeUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/ThemeUtils.java @@ -1,17 +1,25 @@ package de.danoeh.antennapod.core.util; +import android.content.Context; +import android.support.annotation.AttrRes; +import android.support.annotation.ColorInt; import android.util.Log; +import android.util.TypedValue; import de.danoeh.antennapod.core.R; import de.danoeh.antennapod.core.preferences.UserPreferences; public class ThemeUtils { + private ThemeUtils(){} + private static final String TAG = "ThemeUtils"; public static int getSelectionBackgroundColor() { int theme = UserPreferences.getTheme(); if (theme == R.style.Theme_AntennaPod_Dark) { return R.color.selection_background_color_dark; + } else if (theme == R.style.Theme_AntennaPod_TrueBlack){ + return R.color.selection_background_color_trueblack; } else if (theme == R.style.Theme_AntennaPod_Light) { return R.color.selection_background_color_light; } else { @@ -20,4 +28,10 @@ public class ThemeUtils { return R.color.selection_background_color_light; } } + + public static @ColorInt int getColorFromAttr(Context context, @AttrRes int attr) { + TypedValue typedValue = new TypedValue(); + context.getTheme().resolveAttribute(attr, typedValue, true); + return typedValue.data; + } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/URLChecker.java b/core/src/main/java/de/danoeh/antennapod/core/util/URLChecker.java index 40faa1dd2..ffc6a6e28 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/URLChecker.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/URLChecker.java @@ -1,6 +1,7 @@ package de.danoeh.antennapod.core.util; import android.net.Uri; +import android.support.annotation.NonNull; import android.util.Log; import de.danoeh.antennapod.core.BuildConfig; @@ -29,7 +30,7 @@ public final class URLChecker { * @param url The url which is going to be prepared * @return The prepared url */ - public static String prepareURL(String url) { + public static String prepareURL(@NonNull String url) { url = url.trim(); if (url.startsWith("feed://")) { if (BuildConfig.DEBUG) Log.d(TAG, "Replacing feed:// with http://"); diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/download/AutoUpdateManager.java b/core/src/main/java/de/danoeh/antennapod/core/util/download/AutoUpdateManager.java index ad723c685..1629f4aaf 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/download/AutoUpdateManager.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/download/AutoUpdateManager.java @@ -11,12 +11,17 @@ import android.os.Build; import android.os.SystemClock; import android.support.annotation.RequiresApi; import android.util.Log; -import de.danoeh.antennapod.core.receiver.FeedUpdateReceiver; -import de.danoeh.antennapod.core.service.FeedUpdateJobService; import java.util.Calendar; import java.util.concurrent.TimeUnit; +import de.danoeh.antennapod.core.preferences.UserPreferences; +import de.danoeh.antennapod.core.receiver.FeedUpdateReceiver; +import de.danoeh.antennapod.core.service.FeedUpdateJobService; +import de.danoeh.antennapod.core.storage.DBTasks; +import de.danoeh.antennapod.core.util.Converter; +import de.danoeh.antennapod.core.util.FeedUpdateUtils; + public class AutoUpdateManager { private static final int JOB_ID_FEED_UPDATE = 42; private static final String TAG = "AutoUpdateManager"; @@ -152,4 +157,29 @@ public class AutoUpdateManager { updateIntent); Log.d(TAG, "Changed alarm to new time of day " + alarm.get(Calendar.HOUR_OF_DAY) + ":" + alarm.get(Calendar.MINUTE)); } + + /* + * 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; + } + long lastRefresh = DBTasks.getLastRefreshAllFeedsTimeMillis(context); + Log.d(TAG, "last refresh: " + Converter.getDurationStringLocalized(context, + System.currentTimeMillis() - lastRefresh) + " ago"); + if(lastRefresh <= System.currentTimeMillis() - interval) { + FeedUpdateUtils.startAutoUpdate(context, null); + } + } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/exception/MediaFileNotFoundException.java b/core/src/main/java/de/danoeh/antennapod/core/util/exception/MediaFileNotFoundException.java index ecb641dad..3000e2fa4 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/exception/MediaFileNotFoundException.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/exception/MediaFileNotFoundException.java @@ -12,11 +12,6 @@ public class MediaFileNotFoundException extends Exception { this.media = media; } - public MediaFileNotFoundException(FeedMedia media) { - super(); - this.media = media; - } - public FeedMedia getMedia() { return media; } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/flattr/FlattrServiceCreator.java b/core/src/main/java/de/danoeh/antennapod/core/util/flattr/FlattrServiceCreator.java index 45cb56988..d4d5843d2 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/flattr/FlattrServiceCreator.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/flattr/FlattrServiceCreator.java @@ -11,7 +11,9 @@ import de.danoeh.antennapod.core.BuildConfig; /** Ensures that only one instance of the FlattrService class exists at a time */ class FlattrServiceCreator { - private static final String TAG = "FlattrServiceCreator"; + private FlattrServiceCreator(){} + + public static final String TAG = "FlattrServiceCreator"; private static volatile FlattrService flattrService; diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/flattr/FlattrUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/flattr/FlattrUtils.java index 313d1c2f2..919fc82f2 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/flattr/FlattrUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/flattr/FlattrUtils.java @@ -1,8 +1,6 @@ package de.danoeh.antennapod.core.util.flattr; import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.content.SharedPreferences; import android.net.Uri; @@ -36,6 +34,8 @@ import de.danoeh.antennapod.core.storage.DBWriter; */ public class FlattrUtils { + private FlattrUtils(){} + private static final String TAG = "FlattrUtils"; private static final String HOST_NAME = "de.danoeh.antennapod"; diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/gui/MoreContentListFooterUtil.java b/core/src/main/java/de/danoeh/antennapod/core/util/gui/MoreContentListFooterUtil.java index 386f46724..6e5c3e84b 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/gui/MoreContentListFooterUtil.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/gui/MoreContentListFooterUtil.java @@ -27,8 +27,8 @@ public class MoreContentListFooterUtil { } public void setLoadingState(boolean newState) { - final ImageView imageView = (ImageView) root.findViewById(R.id.imgExpand); - final ProgressBar progressBar = (ProgressBar) root.findViewById(R.id.progBar); + final ImageView imageView = root.findViewById(R.id.imgExpand); + final ProgressBar progressBar = root.findViewById(R.id.progBar); if (newState) { imageView.setVisibility(View.GONE); progressBar.setVisibility(View.VISIBLE); diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/gui/NotificationUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/gui/NotificationUtils.java index 1c42364ea..52a43aab2 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/gui/NotificationUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/gui/NotificationUtils.java @@ -6,6 +6,7 @@ import android.app.NotificationManager; import android.content.Context; import android.os.Build; import android.support.annotation.RequiresApi; + import de.danoeh.antennapod.core.R; public class NotificationUtils { @@ -41,6 +42,7 @@ public class NotificationUtils { NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID_DOWNLOADING, c.getString(R.string.notification_channel_downloading), NotificationManager.IMPORTANCE_LOW); mChannel.setDescription(c.getString(R.string.notification_channel_downloading_description)); + mChannel.setShowBadge(false); return mChannel; } @@ -49,6 +51,7 @@ public class NotificationUtils { NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID_PLAYING, c.getString(R.string.notification_channel_playing), NotificationManager.IMPORTANCE_LOW); mChannel.setDescription(c.getString(R.string.notification_channel_playing_description)); + mChannel.setShowBadge(false); return mChannel; } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/AudioPlayer.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/AudioPlayer.java index 846733882..2b3f38841 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/AudioPlayer.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/AudioPlayer.java @@ -21,18 +21,12 @@ public class AudioPlayer extends MediaPlayer implements IPlayer { private final SharedPreferences.OnSharedPreferenceChangeListener sonicListener = (sharedPreferences, key) -> { - if (key.equals(UserPreferences.PREF_SONIC)) { + if (key.equals(UserPreferences.PREF_MEDIA_PLAYER)) { checkMpi(); } }; @Override - public void setScreenOnWhilePlaying(boolean screenOn) { - Log.e(TAG, "Setting screen on while playing not supported in Audio Player"); - throw new UnsupportedOperationException("Setting screen on while playing not supported in Audio Player"); - } - - @Override public void setDisplay(SurfaceHolder sh) { if (sh != null) { Log.e(TAG, "Setting display not supported in Audio Player"); @@ -40,10 +34,13 @@ public class AudioPlayer extends MediaPlayer implements IPlayer { } } - @Override - public void setVideoScalingMode(int mode) { - throw new UnsupportedOperationException("Setting scaling mode is not supported in Audio Player"); - } + @Override + public void setPlaybackParams(float speed, boolean skipSilence) { + if(canSetSpeed()) { + setPlaybackSpeed(speed); + } + //Default player does not support silence skipping + } @Override protected boolean useSonic() { diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/IPlayer.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/IPlayer.java index aba395ec1..c2b768ea8 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/IPlayer.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/IPlayer.java @@ -6,13 +6,11 @@ import android.view.SurfaceHolder; import java.io.IOException; public interface IPlayer { - boolean canSetPitch(); boolean canSetSpeed(); boolean canDownmix(); - float getCurrentPitchStepsAdjustment(); int getCurrentPosition(); @@ -20,20 +18,12 @@ public interface IPlayer { int getDuration(); - float getMaxSpeedMultiplier(); - - float getMinSpeedMultiplier(); - - boolean isLooping(); - boolean isPlaying(); void pause(); void prepare() throws IllegalStateException, IOException; - void prepareAsync(); - void release(); void reset(); @@ -42,22 +32,12 @@ public interface IPlayer { void setAudioStreamType(int streamtype); - void setScreenOnWhilePlaying(boolean screenOn); - void setDataSource(String path) throws IllegalStateException, IOException, IllegalArgumentException, SecurityException; void setDisplay(SurfaceHolder sh); - void setEnableSpeedAdjustment(boolean enableSpeedAdjustment); - - void setLooping(boolean looping); - - void setPitchStepsAdjustment(float pitchSteps); - - void setPlaybackPitch(float f); - - void setPlaybackSpeed(float f); + void setPlaybackParams(float speed, boolean skipSilence); void setDownmix(boolean enable); @@ -67,7 +47,5 @@ public interface IPlayer { void stop(); - void setVideoScalingMode(int mode); - void setWakeMode(Context context, int mode); } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/MediaPlayerError.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/MediaPlayerError.java index a576dd497..b04c02075 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/MediaPlayerError.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/MediaPlayerError.java @@ -7,6 +7,7 @@ import de.danoeh.antennapod.core.R; /** Utility class for MediaPlayer errors. */ public class MediaPlayerError { + private MediaPlayerError(){} /** Get a human-readable string for a specific error code. */ public static String getErrorString(Context context, int code) { diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/Playable.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/Playable.java index ff7f5b79d..da9b96430 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/Playable.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/Playable.java @@ -176,6 +176,8 @@ public interface Playable extends Parcelable, * Provides utility methods for Playable objects. */ class PlayableUtils { + private PlayableUtils(){} + private static final String TAG = "PlayableUtils"; /** 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 a3f02d5cc..6498b9ff1 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 @@ -7,15 +7,11 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; -import android.content.SharedPreferences; import android.content.res.TypedArray; import android.media.MediaPlayer; import android.os.Build; import android.os.IBinder; -import android.preference.PreferenceManager; import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.v4.content.ContextCompat; import android.text.TextUtils; import android.util.Log; import android.util.Pair; @@ -24,10 +20,8 @@ import android.widget.ImageButton; import android.widget.SeekBar; import android.widget.TextView; -import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import de.danoeh.antennapod.core.R; @@ -41,11 +35,14 @@ import de.danoeh.antennapod.core.service.playback.PlaybackServiceMediaPlayer; import de.danoeh.antennapod.core.service.playback.PlayerStatus; import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.util.Converter; +import de.danoeh.antennapod.core.util.Optional; import de.danoeh.antennapod.core.util.playback.Playable.PlayableUtils; -import rx.Observable; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; +import io.reactivex.Maybe; +import io.reactivex.MaybeOnSubscribe; +import io.reactivex.Observable; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; /** * Communicates with the playback service. GUI classes should use this class to @@ -73,7 +70,8 @@ public abstract class PlaybackController { private boolean released = false; private boolean initialized = false; - private Subscription serviceBinder; + private Disposable serviceBinder; + private Disposable mediaLoader; /** * True if controller should reinit playback service if 'pause' button is @@ -106,6 +104,7 @@ public abstract class PlaybackController { } private synchronized void initServiceRunning() { + Log.v(TAG, "initServiceRunning()"); if (initialized) { return; } @@ -148,7 +147,7 @@ public abstract class PlaybackController { } if(serviceBinder != null) { - serviceBinder.unsubscribe(); + serviceBinder.dispose(); } try { activity.unbindService(mConnection); @@ -183,27 +182,20 @@ public abstract class PlaybackController { private void bindToService() { Log.d(TAG, "Trying to connect to service"); if (serviceBinder != null) { - serviceBinder.unsubscribe(); + serviceBinder.dispose(); } serviceBinder = Observable.fromCallable(this::getPlayLastPlayedMediaIntent) - .subscribeOn(Schedulers.newThread()) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) - .subscribe(intent -> { + .subscribe(optionalIntent -> { boolean bound = false; - if (!PlaybackService.started) { - if (intent != null) { - Log.d(TAG, "Calling start service"); - ContextCompat.startForegroundService(activity, intent); - bound = activity.bindService(intent, mConnection, 0); - } else { - status = PlayerStatus.STOPPED; - setupGUI(); - handleStatus(); - } + if (optionalIntent.isPresent()) { + Log.d(TAG, "Calling bind service"); + bound = activity.bindService(optionalIntent.get(), mConnection, 0); } else { - Log.d(TAG, "PlaybackService is running, trying to connect without start command."); - bound = activity.bindService(new Intent(activity, PlaybackService.class), - mConnection, 0); + status = PlayerStatus.STOPPED; + setupGUI(); + handleStatus(); } Log.d(TAG, "Result for service binding: " + bound); }, error -> Log.e(TAG, Log.getStackTraceString(error))); @@ -213,24 +205,26 @@ public abstract class PlaybackController { * Returns an intent that starts the PlaybackService and plays the last * played media or null if no last played media could be found. */ - @Nullable private Intent getPlayLastPlayedMediaIntent() { + @NonNull + private Optional<Intent> getPlayLastPlayedMediaIntent() { Log.d(TAG, "Trying to restore last played media"); Playable media = PlayableUtils.createInstanceFromPreferences(activity); if (media == null) { Log.d(TAG, "No last played media found"); - return null; + return Optional.empty(); } + boolean fileExists = media.localFileAvailable(); boolean lastIsStream = PlaybackPreferences.getCurrentEpisodeIsStream(); if (!fileExists && !lastIsStream && media instanceof FeedMedia) { DBTasks.notifyMissingFeedMediaFile(activity, (FeedMedia) media); } - return new PlaybackServiceStarter(activity, media) + return Optional.of(new PlaybackServiceStarter(activity, media) .startWhenPrepared(false) .shouldStream(lastIsStream || !fileExists) - .getIntent(); + .getIntent()); } @@ -413,8 +407,8 @@ public abstract class PlaybackController { pauseResource = res.getResourceId(1, R.drawable.ic_pause_grey600_36dp); res.recycle(); } else { - playResource = R.drawable.ic_av_play_circle_outline_80dp; - pauseResource = R.drawable.ic_av_pause_circle_outline_80dp; + playResource = R.drawable.ic_av_play_white_80dp; + pauseResource = R.drawable.ic_av_pause_white_80dp; } Log.d(TAG, "status: " + status.toString()); @@ -588,7 +582,8 @@ public abstract class PlaybackController { .startWhenPrepared(true) .streamIfLastWasStream() .start(); - Log.w(TAG, "Play/Pause button was pressed, but playbackservice was null!"); + Log.d(TAG, "Play/Pause button was pressed, but playbackservice was null - " + + "it is likely to have been released by Android system. Restarting it."); return; } switch (status) { @@ -699,7 +694,7 @@ public abstract class PlaybackController { return org.antennapod.audio.MediaPlayer.isPrestoLibraryInstalled(activity.getApplicationContext()) || UserPreferences.useSonic() || Build.VERSION.SDK_INT >= 23 - || playbackService != null && playbackService.canSetSpeed(); + || (playbackService != null && playbackService.canSetSpeed()); } public void setPlaybackSpeed(float speed) { @@ -707,6 +702,11 @@ public abstract class PlaybackController { playbackService.setSpeed(speed); } } + public void setSkipSilence(boolean skipSilence) { + if (playbackService != null) { + playbackService.skipSilence(skipSilence); + } + } public void setVolume(float leftVolume, float rightVolume) { if (playbackService != null) { @@ -760,6 +760,7 @@ public abstract class PlaybackController { } public void notifyVideoSurfaceAbandoned() { + Log.v(TAG, "notifyVideoSurfaceAbandoned() - hasPlaybackService=" + (playbackService != null)); if (playbackService != null) { playbackService.notifyVideoSurfaceAbandoned(); } @@ -780,18 +781,28 @@ public abstract class PlaybackController { } private void initServiceNotRunning() { - if (getMedia() == null) { - return; - } - if (getMedia().getMediaType() == MediaType.AUDIO) { - TypedArray res = activity.obtainStyledAttributes(new int[]{ - de.danoeh.antennapod.core.R.attr.av_play_big}); - getPlayButton().setImageResource( - res.getResourceId(0, de.danoeh.antennapod.core.R.drawable.ic_play_arrow_grey600_36dp)); - res.recycle(); - } else { - getPlayButton().setImageResource(R.drawable.ic_av_play_circle_outline_80dp); - } + Log.v(TAG, "initServiceNotRunning()"); + mediaLoader = Maybe.create((MaybeOnSubscribe<Playable>) emitter -> { + Playable media = getMedia(); + if (media != null) { + emitter.onSuccess(media); + } else { + emitter.onComplete(); + } + }) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(media -> { + if (media.getMediaType() == MediaType.AUDIO) { + TypedArray res = activity.obtainStyledAttributes(new int[]{ + de.danoeh.antennapod.core.R.attr.av_play_big}); + getPlayButton().setImageResource( + res.getResourceId(0, de.danoeh.antennapod.core.R.drawable.ic_play_arrow_grey600_36dp)); + res.recycle(); + } else { + getPlayButton().setImageResource(R.drawable.ic_av_play_white_80dp); + } + }, error -> Log.e(TAG, Log.getStackTraceString(error))); } /** @@ -799,7 +810,7 @@ public abstract class PlaybackController { */ public class MediaPositionObserver implements Runnable { - public static final int WAITING_INTERVALL = 1000; + static final int WAITING_INTERVALL = 1000; @Override public void run() { diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackServiceStarter.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackServiceStarter.java index 3ba553d12..64cf61457 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackServiceStarter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackServiceStarter.java @@ -2,12 +2,15 @@ package de.danoeh.antennapod.core.util.playback; import android.content.Context; import android.content.Intent; -import android.media.MediaPlayer; import android.support.v4.content.ContextCompat; +import android.util.Log; + import de.danoeh.antennapod.core.preferences.PlaybackPreferences; import de.danoeh.antennapod.core.service.playback.PlaybackService; public class PlaybackServiceStarter { + private static final String TAG = "PlaybackServiceStarter"; + private final Context context; private final Playable media; private boolean startWhenPrepared = false; @@ -64,6 +67,10 @@ public class PlaybackServiceStarter { launchIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM, shouldStream); launchIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY, prepareImmediately); + if (media == null) { + Log.e(TAG, "getIntent() - media is unexpectedly null. intent:" + launchIntent); + } + return launchIntent; } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/Timeline.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/Timeline.java index 34cfe6d05..75229b9cf 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/Timeline.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/Timeline.java @@ -7,6 +7,7 @@ import android.support.annotation.ColorInt; import android.support.annotation.NonNull; import android.text.TextUtils; import android.util.Log; +import android.util.Pair; import android.util.TypedValue; import org.jsoup.Jsoup; @@ -14,6 +15,7 @@ import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; +import java.util.ArrayList; import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -68,7 +70,7 @@ public class Timeline { private static final Pattern TIMECODE_LINK_REGEX = Pattern.compile("antennapod://timecode/((\\d+))"); private static final String TIMECODE_LINK = "<a class=\"timecode\" href=\"antennapod://timecode/%d\">%s</a>"; - private static final Pattern TIMECODE_REGEX = Pattern.compile("\\b(?:(?:(([0-9][0-9])):))?(([0-9][0-9])):(([0-9][0-9]))\\b"); + private static final Pattern TIMECODE_REGEX = Pattern.compile("\\b((\\d+):)?(\\d+):(\\d{2})\\b"); private static final Pattern LINE_BREAK_REGEX = Pattern.compile("<br */?>"); @@ -81,6 +83,7 @@ public class Timeline { * @param addTimecodes True if this method should add timecode links * @return The processed HTML string. */ + @NonNull public String processShownotes(final boolean addTimecodes) { final Playable playable = (shownotesProvider instanceof Playable) ? (Playable) shownotesProvider : null; @@ -90,8 +93,8 @@ public class Timeline { try { shownotes = shownotesProvider.loadShownotes().call(); } catch (Exception e) { - e.printStackTrace(); - return null; + Log.e(TAG, "processShownotes() - encounters exceptions unexpectedly in load, treat as if no shownotes.", e); + shownotes = ""; } if (TextUtils.isEmpty(shownotes)) { @@ -127,35 +130,12 @@ public class Timeline { // apply timecode links if (addTimecodes) { - Elements elementsWithTimeCodes = document.body().getElementsMatchingOwnText(TIMECODE_REGEX); - Log.d(TAG, "Recognized " + elementsWithTimeCodes.size() + " timecodes"); - for (Element element : elementsWithTimeCodes) { - Matcher matcherLong = TIMECODE_REGEX.matcher(element.html()); - StringBuffer buffer = new StringBuffer(); - while (matcherLong.find()) { - String h = matcherLong.group(1); - String group = matcherLong.group(0); - int time = (h != null) ? Converter.durationStringLongToMs(group) : - Converter.durationStringShortToMs(group); - - String rep; - if (playable == null || playable.getDuration() > time) { - rep = String.format(Locale.getDefault(), TIMECODE_LINK, time, group); - } else { - rep = group; - } - matcherLong.appendReplacement(buffer, rep); - } - matcherLong.appendTail(buffer); - - element.html(buffer.toString()); - } + addTimecodes(document, playable); } return document.toString(); } - /** * Returns true if the given link is a timecode link. */ @@ -186,4 +166,69 @@ public class Timeline { public void setShownotesProvider(@NonNull ShownotesProvider shownotesProvider) { this.shownotesProvider = shownotesProvider; } + + private void addTimecodes(Document document, final Playable playable) { + Elements elementsWithTimeCodes = document.body().getElementsMatchingOwnText(TIMECODE_REGEX); + Log.d(TAG, "Recognized " + elementsWithTimeCodes.size() + " timecodes"); + + if (elementsWithTimeCodes.size() == 0) { + // No elements with timecodes + return; + } + + int playableDuration = playable == null ? Integer.MAX_VALUE : playable.getDuration(); + boolean useHourFormat = true; + + if (playableDuration != Integer.MAX_VALUE) { + + // We need to decide if we are going to treat short timecodes as HH:MM or MM:SS. To do + // so we will parse all the short timecodes and see if they fit in the duration. If one + // does not we will use MM:SS, otherwise all will be parsed as HH:MM. + for (Element element : elementsWithTimeCodes) { + Matcher matcherForElement = TIMECODE_REGEX.matcher(element.html()); + while (matcherForElement.find()) { + + // We only want short timecodes right now. + if (matcherForElement.group(1) == null) { + int time = Converter.durationStringShortToMs(matcherForElement.group(0), true); + + // If the parsed timecode is greater then the duration then we know we need to + // use the minute format so we are done. + if (time > playableDuration) { + useHourFormat = false; + break; + } + } + } + + if (!useHourFormat) { + break; + } + } + } + + for (Element element : elementsWithTimeCodes) { + + Matcher matcherForElement = TIMECODE_REGEX.matcher(element.html()); + StringBuffer buffer = new StringBuffer(); + + while (matcherForElement.find()) { + String group = matcherForElement.group(0); + + int time = matcherForElement.group(1) != null + ? Converter.durationStringLongToMs(group) + : Converter.durationStringShortToMs(group, useHourFormat); + + String replacementText = group; + if (time < playableDuration) { + replacementText = String.format(Locale.getDefault(), TIMECODE_LINK, time, group); + } + + matcherForElement.appendReplacement(buffer, replacementText); + } + + matcherForElement.appendTail(buffer); + element.html(buffer.toString()); + } + } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/VideoPlayer.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/VideoPlayer.java index 368379509..f3c1c4f59 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/VideoPlayer.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/VideoPlayer.java @@ -7,11 +7,6 @@ public class VideoPlayer extends MediaPlayer implements IPlayer { private static final String TAG = "VideoPlayer"; @Override - public boolean canSetPitch() { - return false; - } - - @Override public boolean canSetSpeed() { return false; } @@ -22,47 +17,13 @@ public class VideoPlayer extends MediaPlayer implements IPlayer { } @Override - public float getCurrentPitchStepsAdjustment() { - return 1; - } - - @Override public float getCurrentSpeedMultiplier() { return 1; } @Override - public float getMaxSpeedMultiplier() { - return 1; - } - - @Override - public float getMinSpeedMultiplier() { - return 1; - } - - @Override - public void setEnableSpeedAdjustment(boolean enableSpeedAdjustment) throws UnsupportedOperationException { - Log.e(TAG, "Setting enable speed adjustment unsupported in video player"); - throw new UnsupportedOperationException("Setting enable speed adjustment unsupported in video player"); - } - - @Override - public void setPitchStepsAdjustment(float pitchSteps) { - Log.e(TAG, "Setting pitch steps adjustment unsupported in video player"); - throw new UnsupportedOperationException("Setting pitch steps adjustment unsupported in video player"); - } - - @Override - public void setPlaybackPitch(float f) { - Log.e(TAG, "Setting playback pitch unsupported in video player"); - throw new UnsupportedOperationException("Setting playback pitch unsupported in video player"); - } - - @Override - public void setPlaybackSpeed(float f) { - Log.e(TAG, "Setting playback speed unsupported in video player"); - throw new UnsupportedOperationException("Setting playback speed unsupported in video player"); + public void setPlaybackParams(float speed, boolean skipSilence) { + //Ignore this for non ExoPlayer implementations } @Override diff --git a/core/src/main/res/drawable-hdpi/ic_av_fast_forward_80dp.png b/core/src/main/res/drawable-hdpi/ic_av_fast_forward_80dp.png Binary files differdeleted file mode 100755 index 43783fbce..000000000 --- a/core/src/main/res/drawable-hdpi/ic_av_fast_forward_80dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-hdpi/ic_av_pause_circle_outline_80dp.png b/core/src/main/res/drawable-hdpi/ic_av_pause_circle_outline_80dp.png Binary files differdeleted file mode 100644 index 115f7ebef..000000000 --- a/core/src/main/res/drawable-hdpi/ic_av_pause_circle_outline_80dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-hdpi/ic_av_play_circle_outline_80dp.png b/core/src/main/res/drawable-hdpi/ic_av_play_circle_outline_80dp.png Binary files differdeleted file mode 100644 index 392c87bd2..000000000 --- a/core/src/main/res/drawable-hdpi/ic_av_play_circle_outline_80dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-hdpi/ic_av_rewind_80dp.png b/core/src/main/res/drawable-hdpi/ic_av_rewind_80dp.png Binary files differdeleted file mode 100755 index 41052af65..000000000 --- a/core/src/main/res/drawable-hdpi/ic_av_rewind_80dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-hdpi/ic_baseline_question_answer_white_24dp.png b/core/src/main/res/drawable-hdpi/ic_baseline_question_answer_white_24dp.png Binary files differnew file mode 100755 index 000000000..67924a5a2 --- /dev/null +++ b/core/src/main/res/drawable-hdpi/ic_baseline_question_answer_white_24dp.png diff --git a/core/src/main/res/drawable-hdpi/ic_bug_grey600_24dp.png b/core/src/main/res/drawable-hdpi/ic_bug_grey600_24dp.png Binary files differnew file mode 100644 index 000000000..daadfb35f --- /dev/null +++ b/core/src/main/res/drawable-hdpi/ic_bug_grey600_24dp.png diff --git a/core/src/main/res/drawable-hdpi/ic_bug_white_24dp.png b/core/src/main/res/drawable-hdpi/ic_bug_white_24dp.png Binary files differnew file mode 100644 index 000000000..549f67bf4 --- /dev/null +++ b/core/src/main/res/drawable-hdpi/ic_bug_white_24dp.png diff --git a/core/src/main/res/drawable-hdpi/ic_cellphone_text_grey600_24dp.png b/core/src/main/res/drawable-hdpi/ic_cellphone_text_grey600_24dp.png Binary files differnew file mode 100644 index 000000000..71ccc26ea --- /dev/null +++ b/core/src/main/res/drawable-hdpi/ic_cellphone_text_grey600_24dp.png diff --git a/core/src/main/res/drawable-hdpi/ic_cellphone_text_white_24dp.png b/core/src/main/res/drawable-hdpi/ic_cellphone_text_white_24dp.png Binary files differnew file mode 100644 index 000000000..70e52c60b --- /dev/null +++ b/core/src/main/res/drawable-hdpi/ic_cellphone_text_white_24dp.png diff --git a/core/src/main/res/drawable-hdpi/ic_check_box_grey600_24dp.png b/core/src/main/res/drawable-hdpi/ic_check_box_grey600_24dp.png Binary files differdeleted file mode 100644 index 187a426a8..000000000 --- a/core/src/main/res/drawable-hdpi/ic_check_box_grey600_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-hdpi/ic_check_box_outline_blank_grey600_24dp.png b/core/src/main/res/drawable-hdpi/ic_check_box_outline_blank_grey600_24dp.png Binary files differdeleted file mode 100644 index 076773bca..000000000 --- a/core/src/main/res/drawable-hdpi/ic_check_box_outline_blank_grey600_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-hdpi/ic_check_box_outline_blank_white_24dp.png b/core/src/main/res/drawable-hdpi/ic_check_box_outline_blank_white_24dp.png Binary files differdeleted file mode 100644 index ecaf0d5be..000000000 --- a/core/src/main/res/drawable-hdpi/ic_check_box_outline_blank_white_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-hdpi/ic_check_box_white_24dp.png b/core/src/main/res/drawable-hdpi/ic_check_box_white_24dp.png Binary files differdeleted file mode 100644 index 5ce64cc5f..000000000 --- a/core/src/main/res/drawable-hdpi/ic_check_box_white_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-hdpi/ic_format_list_bulleted_grey600_24dp.png b/core/src/main/res/drawable-hdpi/ic_format_list_bulleted_grey600_24dp.png Binary files differnew file mode 100644 index 000000000..3668c9a00 --- /dev/null +++ b/core/src/main/res/drawable-hdpi/ic_format_list_bulleted_grey600_24dp.png diff --git a/core/src/main/res/drawable-hdpi/ic_format_list_bulleted_white_24dp.png b/core/src/main/res/drawable-hdpi/ic_format_list_bulleted_white_24dp.png Binary files differnew file mode 100644 index 000000000..a1a2c5b68 --- /dev/null +++ b/core/src/main/res/drawable-hdpi/ic_format_list_bulleted_white_24dp.png diff --git a/core/src/main/res/drawable-hdpi/ic_forum_grey600_24dp.png b/core/src/main/res/drawable-hdpi/ic_forum_grey600_24dp.png Binary files differnew file mode 100644 index 000000000..da5398d15 --- /dev/null +++ b/core/src/main/res/drawable-hdpi/ic_forum_grey600_24dp.png diff --git a/core/src/main/res/drawable-hdpi/ic_indeterminate_check_box_grey600_24dp.png b/core/src/main/res/drawable-hdpi/ic_indeterminate_check_box_grey600_24dp.png Binary files differdeleted file mode 100644 index e56fbf224..000000000 --- a/core/src/main/res/drawable-hdpi/ic_indeterminate_check_box_grey600_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-hdpi/ic_indeterminate_check_box_white_24dp.png b/core/src/main/res/drawable-hdpi/ic_indeterminate_check_box_white_24dp.png Binary files differdeleted file mode 100644 index dccf44930..000000000 --- a/core/src/main/res/drawable-hdpi/ic_indeterminate_check_box_white_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-mdpi/ic_av_fast_forward_80dp.png b/core/src/main/res/drawable-mdpi/ic_av_fast_forward_80dp.png Binary files differdeleted file mode 100755 index 0bf060d89..000000000 --- a/core/src/main/res/drawable-mdpi/ic_av_fast_forward_80dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-mdpi/ic_av_pause_circle_outline_80dp.png b/core/src/main/res/drawable-mdpi/ic_av_pause_circle_outline_80dp.png Binary files differdeleted file mode 100644 index 1e71c271f..000000000 --- a/core/src/main/res/drawable-mdpi/ic_av_pause_circle_outline_80dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-mdpi/ic_av_play_circle_outline_80dp.png b/core/src/main/res/drawable-mdpi/ic_av_play_circle_outline_80dp.png Binary files differdeleted file mode 100644 index d305f0c69..000000000 --- a/core/src/main/res/drawable-mdpi/ic_av_play_circle_outline_80dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-mdpi/ic_av_rewind_80dp.png b/core/src/main/res/drawable-mdpi/ic_av_rewind_80dp.png Binary files differdeleted file mode 100755 index 99ac9f3c9..000000000 --- a/core/src/main/res/drawable-mdpi/ic_av_rewind_80dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-mdpi/ic_baseline_question_answer_white_24dp.png b/core/src/main/res/drawable-mdpi/ic_baseline_question_answer_white_24dp.png Binary files differnew file mode 100755 index 000000000..e87df752e --- /dev/null +++ b/core/src/main/res/drawable-mdpi/ic_baseline_question_answer_white_24dp.png diff --git a/core/src/main/res/drawable-mdpi/ic_bug_grey600_24dp.png b/core/src/main/res/drawable-mdpi/ic_bug_grey600_24dp.png Binary files differnew file mode 100644 index 000000000..4b372a4e3 --- /dev/null +++ b/core/src/main/res/drawable-mdpi/ic_bug_grey600_24dp.png diff --git a/core/src/main/res/drawable-mdpi/ic_bug_white_24dp.png b/core/src/main/res/drawable-mdpi/ic_bug_white_24dp.png Binary files differnew file mode 100644 index 000000000..9d7603552 --- /dev/null +++ b/core/src/main/res/drawable-mdpi/ic_bug_white_24dp.png diff --git a/core/src/main/res/drawable-mdpi/ic_cellphone_text_grey600_24dp.png b/core/src/main/res/drawable-mdpi/ic_cellphone_text_grey600_24dp.png Binary files differnew file mode 100644 index 000000000..c26da2ce2 --- /dev/null +++ b/core/src/main/res/drawable-mdpi/ic_cellphone_text_grey600_24dp.png diff --git a/core/src/main/res/drawable-mdpi/ic_cellphone_text_white_24dp.png b/core/src/main/res/drawable-mdpi/ic_cellphone_text_white_24dp.png Binary files differnew file mode 100644 index 000000000..8569a642d --- /dev/null +++ b/core/src/main/res/drawable-mdpi/ic_cellphone_text_white_24dp.png diff --git a/core/src/main/res/drawable-mdpi/ic_check_box_grey600_24dp.png b/core/src/main/res/drawable-mdpi/ic_check_box_grey600_24dp.png Binary files differdeleted file mode 100644 index d5bdfa433..000000000 --- a/core/src/main/res/drawable-mdpi/ic_check_box_grey600_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-mdpi/ic_check_box_outline_blank_grey600_24dp.png b/core/src/main/res/drawable-mdpi/ic_check_box_outline_blank_grey600_24dp.png Binary files differdeleted file mode 100644 index aefe5b6c1..000000000 --- a/core/src/main/res/drawable-mdpi/ic_check_box_outline_blank_grey600_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-mdpi/ic_check_box_outline_blank_white_24dp.png b/core/src/main/res/drawable-mdpi/ic_check_box_outline_blank_white_24dp.png Binary files differdeleted file mode 100644 index a3a588c64..000000000 --- a/core/src/main/res/drawable-mdpi/ic_check_box_outline_blank_white_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-mdpi/ic_check_box_white_24dp.png b/core/src/main/res/drawable-mdpi/ic_check_box_white_24dp.png Binary files differdeleted file mode 100644 index dc94cdbf4..000000000 --- a/core/src/main/res/drawable-mdpi/ic_check_box_white_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-mdpi/ic_format_list_bulleted_grey600_24dp.png b/core/src/main/res/drawable-mdpi/ic_format_list_bulleted_grey600_24dp.png Binary files differnew file mode 100644 index 000000000..726eae499 --- /dev/null +++ b/core/src/main/res/drawable-mdpi/ic_format_list_bulleted_grey600_24dp.png diff --git a/core/src/main/res/drawable-mdpi/ic_format_list_bulleted_white_24dp.png b/core/src/main/res/drawable-mdpi/ic_format_list_bulleted_white_24dp.png Binary files differnew file mode 100644 index 000000000..0cc401dff --- /dev/null +++ b/core/src/main/res/drawable-mdpi/ic_format_list_bulleted_white_24dp.png diff --git a/core/src/main/res/drawable-mdpi/ic_forum_grey600_24dp.png b/core/src/main/res/drawable-mdpi/ic_forum_grey600_24dp.png Binary files differnew file mode 100644 index 000000000..d3bcfe7b6 --- /dev/null +++ b/core/src/main/res/drawable-mdpi/ic_forum_grey600_24dp.png diff --git a/core/src/main/res/drawable-mdpi/ic_indeterminate_check_box_grey600_24dp.png b/core/src/main/res/drawable-mdpi/ic_indeterminate_check_box_grey600_24dp.png Binary files differdeleted file mode 100644 index 0e6ce58e3..000000000 --- a/core/src/main/res/drawable-mdpi/ic_indeterminate_check_box_grey600_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-mdpi/ic_indeterminate_check_box_white_24dp.png b/core/src/main/res/drawable-mdpi/ic_indeterminate_check_box_white_24dp.png Binary files differdeleted file mode 100644 index c496b4648..000000000 --- a/core/src/main/res/drawable-mdpi/ic_indeterminate_check_box_white_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-v21/overlay_button_circle_background.xml b/core/src/main/res/drawable-v21/overlay_button_circle_background.xml deleted file mode 100644 index c121690df..000000000 --- a/core/src/main/res/drawable-v21/overlay_button_circle_background.xml +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<shape xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="rectangle"> - <gradient - android:type="radial" - android:gradientRadius="37.5%p" - android:startColor="#000000" - android:endColor="@android:color/transparent"/> -</shape>
\ No newline at end of file diff --git a/core/src/main/res/drawable-xhdpi/ic_av_fast_forward_80dp.png b/core/src/main/res/drawable-xhdpi/ic_av_fast_forward_80dp.png Binary files differdeleted file mode 100755 index 270dc9bf8..000000000 --- a/core/src/main/res/drawable-xhdpi/ic_av_fast_forward_80dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xhdpi/ic_av_pause_circle_outline_80dp.png b/core/src/main/res/drawable-xhdpi/ic_av_pause_circle_outline_80dp.png Binary files differdeleted file mode 100644 index 2e0b8ff6f..000000000 --- a/core/src/main/res/drawable-xhdpi/ic_av_pause_circle_outline_80dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xhdpi/ic_av_play_circle_outline_80dp.png b/core/src/main/res/drawable-xhdpi/ic_av_play_circle_outline_80dp.png Binary files differdeleted file mode 100644 index 990ae524a..000000000 --- a/core/src/main/res/drawable-xhdpi/ic_av_play_circle_outline_80dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xhdpi/ic_av_rewind_80dp.png b/core/src/main/res/drawable-xhdpi/ic_av_rewind_80dp.png Binary files differdeleted file mode 100755 index d94a40811..000000000 --- a/core/src/main/res/drawable-xhdpi/ic_av_rewind_80dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xhdpi/ic_baseline_question_answer_white_24dp.png b/core/src/main/res/drawable-xhdpi/ic_baseline_question_answer_white_24dp.png Binary files differnew file mode 100755 index 000000000..731f89c83 --- /dev/null +++ b/core/src/main/res/drawable-xhdpi/ic_baseline_question_answer_white_24dp.png diff --git a/core/src/main/res/drawable-xhdpi/ic_bug_grey600_24dp.png b/core/src/main/res/drawable-xhdpi/ic_bug_grey600_24dp.png Binary files differnew file mode 100644 index 000000000..49e5deaa9 --- /dev/null +++ b/core/src/main/res/drawable-xhdpi/ic_bug_grey600_24dp.png diff --git a/core/src/main/res/drawable-xhdpi/ic_bug_white_24dp.png b/core/src/main/res/drawable-xhdpi/ic_bug_white_24dp.png Binary files differnew file mode 100644 index 000000000..7416bde03 --- /dev/null +++ b/core/src/main/res/drawable-xhdpi/ic_bug_white_24dp.png diff --git a/core/src/main/res/drawable-xhdpi/ic_cellphone_text_grey600_24dp.png b/core/src/main/res/drawable-xhdpi/ic_cellphone_text_grey600_24dp.png Binary files differnew file mode 100644 index 000000000..fc8219fa9 --- /dev/null +++ b/core/src/main/res/drawable-xhdpi/ic_cellphone_text_grey600_24dp.png diff --git a/core/src/main/res/drawable-xhdpi/ic_cellphone_text_white_24dp.png b/core/src/main/res/drawable-xhdpi/ic_cellphone_text_white_24dp.png Binary files differnew file mode 100644 index 000000000..9468fa9a9 --- /dev/null +++ b/core/src/main/res/drawable-xhdpi/ic_cellphone_text_white_24dp.png diff --git a/core/src/main/res/drawable-xhdpi/ic_check_box_grey600_24dp.png b/core/src/main/res/drawable-xhdpi/ic_check_box_grey600_24dp.png Binary files differdeleted file mode 100644 index e46ab71b4..000000000 --- a/core/src/main/res/drawable-xhdpi/ic_check_box_grey600_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xhdpi/ic_check_box_outline_blank_grey600_24dp.png b/core/src/main/res/drawable-xhdpi/ic_check_box_outline_blank_grey600_24dp.png Binary files differdeleted file mode 100644 index bb15a903a..000000000 --- a/core/src/main/res/drawable-xhdpi/ic_check_box_outline_blank_grey600_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xhdpi/ic_check_box_outline_blank_white_24dp.png b/core/src/main/res/drawable-xhdpi/ic_check_box_outline_blank_white_24dp.png Binary files differdeleted file mode 100644 index 336682497..000000000 --- a/core/src/main/res/drawable-xhdpi/ic_check_box_outline_blank_white_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xhdpi/ic_check_box_white_24dp.png b/core/src/main/res/drawable-xhdpi/ic_check_box_white_24dp.png Binary files differdeleted file mode 100644 index cdb4a3181..000000000 --- a/core/src/main/res/drawable-xhdpi/ic_check_box_white_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xhdpi/ic_format_list_bulleted_grey600_24dp.png b/core/src/main/res/drawable-xhdpi/ic_format_list_bulleted_grey600_24dp.png Binary files differnew file mode 100644 index 000000000..322adb6e0 --- /dev/null +++ b/core/src/main/res/drawable-xhdpi/ic_format_list_bulleted_grey600_24dp.png diff --git a/core/src/main/res/drawable-xhdpi/ic_format_list_bulleted_white_24dp.png b/core/src/main/res/drawable-xhdpi/ic_format_list_bulleted_white_24dp.png Binary files differnew file mode 100644 index 000000000..c25860017 --- /dev/null +++ b/core/src/main/res/drawable-xhdpi/ic_format_list_bulleted_white_24dp.png diff --git a/core/src/main/res/drawable-xhdpi/ic_forum_grey600_24dp.png b/core/src/main/res/drawable-xhdpi/ic_forum_grey600_24dp.png Binary files differnew file mode 100644 index 000000000..ac6876140 --- /dev/null +++ b/core/src/main/res/drawable-xhdpi/ic_forum_grey600_24dp.png diff --git a/core/src/main/res/drawable-xhdpi/ic_indeterminate_check_box_grey600_24dp.png b/core/src/main/res/drawable-xhdpi/ic_indeterminate_check_box_grey600_24dp.png Binary files differdeleted file mode 100644 index 3b0d3aa1a..000000000 --- a/core/src/main/res/drawable-xhdpi/ic_indeterminate_check_box_grey600_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xhdpi/ic_indeterminate_check_box_white_24dp.png b/core/src/main/res/drawable-xhdpi/ic_indeterminate_check_box_white_24dp.png Binary files differdeleted file mode 100644 index 57e478e9f..000000000 --- a/core/src/main/res/drawable-xhdpi/ic_indeterminate_check_box_white_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxhdpi/ic_av_fast_forward_80dp.png b/core/src/main/res/drawable-xxhdpi/ic_av_fast_forward_80dp.png Binary files differdeleted file mode 100755 index 3b55c5d55..000000000 --- a/core/src/main/res/drawable-xxhdpi/ic_av_fast_forward_80dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxhdpi/ic_av_pause_circle_outline_80dp.png b/core/src/main/res/drawable-xxhdpi/ic_av_pause_circle_outline_80dp.png Binary files differdeleted file mode 100644 index 76cc4db32..000000000 --- a/core/src/main/res/drawable-xxhdpi/ic_av_pause_circle_outline_80dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxhdpi/ic_av_play_circle_outline_80dp.png b/core/src/main/res/drawable-xxhdpi/ic_av_play_circle_outline_80dp.png Binary files differdeleted file mode 100644 index eebf0110c..000000000 --- a/core/src/main/res/drawable-xxhdpi/ic_av_play_circle_outline_80dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxhdpi/ic_av_rewind_80dp.png b/core/src/main/res/drawable-xxhdpi/ic_av_rewind_80dp.png Binary files differdeleted file mode 100755 index 38a5fc264..000000000 --- a/core/src/main/res/drawable-xxhdpi/ic_av_rewind_80dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxhdpi/ic_baseline_question_answer_white_24dp.png b/core/src/main/res/drawable-xxhdpi/ic_baseline_question_answer_white_24dp.png Binary files differnew file mode 100755 index 000000000..255b82707 --- /dev/null +++ b/core/src/main/res/drawable-xxhdpi/ic_baseline_question_answer_white_24dp.png diff --git a/core/src/main/res/drawable-xxhdpi/ic_bug_grey600_24dp.png b/core/src/main/res/drawable-xxhdpi/ic_bug_grey600_24dp.png Binary files differnew file mode 100644 index 000000000..7bbf31c6b --- /dev/null +++ b/core/src/main/res/drawable-xxhdpi/ic_bug_grey600_24dp.png diff --git a/core/src/main/res/drawable-xxhdpi/ic_bug_white_24dp.png b/core/src/main/res/drawable-xxhdpi/ic_bug_white_24dp.png Binary files differnew file mode 100644 index 000000000..fe2c2bee3 --- /dev/null +++ b/core/src/main/res/drawable-xxhdpi/ic_bug_white_24dp.png diff --git a/core/src/main/res/drawable-xxhdpi/ic_cellphone_text_grey600_24dp.png b/core/src/main/res/drawable-xxhdpi/ic_cellphone_text_grey600_24dp.png Binary files differnew file mode 100644 index 000000000..82a453f05 --- /dev/null +++ b/core/src/main/res/drawable-xxhdpi/ic_cellphone_text_grey600_24dp.png diff --git a/core/src/main/res/drawable-xxhdpi/ic_cellphone_text_white_24dp.png b/core/src/main/res/drawable-xxhdpi/ic_cellphone_text_white_24dp.png Binary files differnew file mode 100644 index 000000000..d1f990a65 --- /dev/null +++ b/core/src/main/res/drawable-xxhdpi/ic_cellphone_text_white_24dp.png diff --git a/core/src/main/res/drawable-xxhdpi/ic_check_box_grey600_24dp.png b/core/src/main/res/drawable-xxhdpi/ic_check_box_grey600_24dp.png Binary files differdeleted file mode 100644 index 7093f28d5..000000000 --- a/core/src/main/res/drawable-xxhdpi/ic_check_box_grey600_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxhdpi/ic_check_box_outline_blank_grey600_24dp.png b/core/src/main/res/drawable-xxhdpi/ic_check_box_outline_blank_grey600_24dp.png Binary files differdeleted file mode 100644 index 050e6cd6c..000000000 --- a/core/src/main/res/drawable-xxhdpi/ic_check_box_outline_blank_grey600_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxhdpi/ic_check_box_outline_blank_white_24dp.png b/core/src/main/res/drawable-xxhdpi/ic_check_box_outline_blank_white_24dp.png Binary files differdeleted file mode 100644 index 56d380575..000000000 --- a/core/src/main/res/drawable-xxhdpi/ic_check_box_outline_blank_white_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxhdpi/ic_check_box_white_24dp.png b/core/src/main/res/drawable-xxhdpi/ic_check_box_white_24dp.png Binary files differdeleted file mode 100644 index ba9af5265..000000000 --- a/core/src/main/res/drawable-xxhdpi/ic_check_box_white_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxhdpi/ic_format_list_bulleted_grey600_24dp.png b/core/src/main/res/drawable-xxhdpi/ic_format_list_bulleted_grey600_24dp.png Binary files differnew file mode 100644 index 000000000..87f8073ea --- /dev/null +++ b/core/src/main/res/drawable-xxhdpi/ic_format_list_bulleted_grey600_24dp.png diff --git a/core/src/main/res/drawable-xxhdpi/ic_format_list_bulleted_white_24dp.png b/core/src/main/res/drawable-xxhdpi/ic_format_list_bulleted_white_24dp.png Binary files differnew file mode 100644 index 000000000..da3433c61 --- /dev/null +++ b/core/src/main/res/drawable-xxhdpi/ic_format_list_bulleted_white_24dp.png diff --git a/core/src/main/res/drawable-xxhdpi/ic_forum_grey600_24dp.png b/core/src/main/res/drawable-xxhdpi/ic_forum_grey600_24dp.png Binary files differnew file mode 100644 index 000000000..7a3204693 --- /dev/null +++ b/core/src/main/res/drawable-xxhdpi/ic_forum_grey600_24dp.png diff --git a/core/src/main/res/drawable-xxhdpi/ic_indeterminate_check_box_grey600_24dp.png b/core/src/main/res/drawable-xxhdpi/ic_indeterminate_check_box_grey600_24dp.png Binary files differdeleted file mode 100644 index 2e7d39a5a..000000000 --- a/core/src/main/res/drawable-xxhdpi/ic_indeterminate_check_box_grey600_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxhdpi/ic_indeterminate_check_box_white_24dp.png b/core/src/main/res/drawable-xxhdpi/ic_indeterminate_check_box_white_24dp.png Binary files differdeleted file mode 100644 index ec4981f5c..000000000 --- a/core/src/main/res/drawable-xxhdpi/ic_indeterminate_check_box_white_24dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxxhdpi/ic_av_fast_forward_80dp.png b/core/src/main/res/drawable-xxxhdpi/ic_av_fast_forward_80dp.png Binary files differdeleted file mode 100755 index 1c915d9dd..000000000 --- a/core/src/main/res/drawable-xxxhdpi/ic_av_fast_forward_80dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxxhdpi/ic_av_rewind_80dp.png b/core/src/main/res/drawable-xxxhdpi/ic_av_rewind_80dp.png Binary files differdeleted file mode 100755 index 190bb0f4c..000000000 --- a/core/src/main/res/drawable-xxxhdpi/ic_av_rewind_80dp.png +++ /dev/null diff --git a/core/src/main/res/drawable-xxxhdpi/ic_baseline_question_answer_white_24db.png b/core/src/main/res/drawable-xxxhdpi/ic_baseline_question_answer_white_24db.png Binary files differnew file mode 100755 index 000000000..0d697e0f9 --- /dev/null +++ b/core/src/main/res/drawable-xxxhdpi/ic_baseline_question_answer_white_24db.png diff --git a/core/src/main/res/drawable-xxxhdpi/ic_bug_grey600_24dp.png b/core/src/main/res/drawable-xxxhdpi/ic_bug_grey600_24dp.png Binary files differnew file mode 100644 index 000000000..b612b2aa9 --- /dev/null +++ b/core/src/main/res/drawable-xxxhdpi/ic_bug_grey600_24dp.png diff --git a/core/src/main/res/drawable-xxxhdpi/ic_bug_white_24dp.png b/core/src/main/res/drawable-xxxhdpi/ic_bug_white_24dp.png Binary files differnew file mode 100644 index 000000000..32a3f5511 --- /dev/null +++ b/core/src/main/res/drawable-xxxhdpi/ic_bug_white_24dp.png diff --git a/core/src/main/res/drawable-xxxhdpi/ic_cellphone_text_grey600_24dp.png b/core/src/main/res/drawable-xxxhdpi/ic_cellphone_text_grey600_24dp.png Binary files differnew file mode 100644 index 000000000..829b15396 --- /dev/null +++ b/core/src/main/res/drawable-xxxhdpi/ic_cellphone_text_grey600_24dp.png diff --git a/core/src/main/res/drawable-xxxhdpi/ic_cellphone_text_white_24dp.png b/core/src/main/res/drawable-xxxhdpi/ic_cellphone_text_white_24dp.png Binary files differnew file mode 100644 index 000000000..baa783a92 --- /dev/null +++ b/core/src/main/res/drawable-xxxhdpi/ic_cellphone_text_white_24dp.png diff --git a/core/src/main/res/drawable-xxxhdpi/ic_format_list_bulleted_grey600_24dp.png b/core/src/main/res/drawable-xxxhdpi/ic_format_list_bulleted_grey600_24dp.png Binary files differnew file mode 100644 index 000000000..c56590fe0 --- /dev/null +++ b/core/src/main/res/drawable-xxxhdpi/ic_format_list_bulleted_grey600_24dp.png diff --git a/core/src/main/res/drawable-xxxhdpi/ic_format_list_bulleted_white_24dp.png b/core/src/main/res/drawable-xxxhdpi/ic_format_list_bulleted_white_24dp.png Binary files differnew file mode 100644 index 000000000..5deea3286 --- /dev/null +++ b/core/src/main/res/drawable-xxxhdpi/ic_format_list_bulleted_white_24dp.png diff --git a/core/src/main/res/drawable-xxxhdpi/ic_forum_grey600_24dp.png b/core/src/main/res/drawable-xxxhdpi/ic_forum_grey600_24dp.png Binary files differnew file mode 100644 index 000000000..0ae33696b --- /dev/null +++ b/core/src/main/res/drawable-xxxhdpi/ic_forum_grey600_24dp.png diff --git a/core/src/main/res/drawable/ic_av_fast_forward_white_80dp.xml b/core/src/main/res/drawable/ic_av_fast_forward_white_80dp.xml new file mode 100644 index 000000000..a60145f1d --- /dev/null +++ b/core/src/main/res/drawable/ic_av_fast_forward_white_80dp.xml @@ -0,0 +1,10 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="80dp" + android:width="80dp" + android:viewportHeight="24.0" + android:viewportWidth="24.0"> + <path android:pathData="M4,18l8.5,-6L4,6v12zM13,6v12l8.5,-6L13,6z" + android:fillColor="#FFFFFFFF" + android:strokeColor="#505050" + android:strokeWidth="0.75"/> +</vector> diff --git a/core/src/main/res/drawable/ic_av_fast_rewind_white_80dp.xml b/core/src/main/res/drawable/ic_av_fast_rewind_white_80dp.xml new file mode 100644 index 000000000..4609e0c3e --- /dev/null +++ b/core/src/main/res/drawable/ic_av_fast_rewind_white_80dp.xml @@ -0,0 +1,10 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:viewportHeight="24.0" + android:viewportWidth="24.0" + android:width="80dp" + android:height="80dp"> + <path android:pathData="M11,18L11,6l-8.5,6 8.5,6zM11.5,12l8.5,6L20,6l-8.5,6z" + android:fillColor="#FFFFFFFF" + android:strokeColor="#505050" + android:strokeWidth="0.75"/> +</vector> diff --git a/core/src/main/res/drawable/ic_av_pause_white_80dp.xml b/core/src/main/res/drawable/ic_av_pause_white_80dp.xml new file mode 100644 index 000000000..ad8847cb7 --- /dev/null +++ b/core/src/main/res/drawable/ic_av_pause_white_80dp.xml @@ -0,0 +1,10 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="80dp" + android:width="80dp" + android:viewportHeight="24.0" + android:viewportWidth="24.0"> + <path android:pathData="M6,19h4L10,5L6,5v14zM14,5v14h4L18,5h-4z" + android:fillColor="#FFFFFFFF" + android:strokeColor="#505050" + android:strokeWidth="0.75"/> +</vector> diff --git a/core/src/main/res/drawable/ic_av_play_white_80dp.xml b/core/src/main/res/drawable/ic_av_play_white_80dp.xml new file mode 100644 index 000000000..9f9dbb1b1 --- /dev/null +++ b/core/src/main/res/drawable/ic_av_play_white_80dp.xml @@ -0,0 +1,10 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="80dp" + android:width="80dp" + android:viewportHeight="24.0" + android:viewportWidth="24.0"> + <path android:pathData="M8,5v14l11,-7z" + android:fillColor="#FFFFFFFF" + android:strokeColor="#505050" + android:strokeWidth="0.75"/> +</vector> diff --git a/core/src/main/res/drawable/ic_fab_edit.xml b/core/src/main/res/drawable/ic_fab_edit.xml new file mode 100644 index 000000000..cb2e394b0 --- /dev/null +++ b/core/src/main/res/drawable/ic_fab_edit.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" + android:viewportHeight="24.0" android:viewportWidth="24.0" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="#FFFFFFFF" android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/> +</vector> diff --git a/core/src/main/res/drawable/ic_remove_grey600.xml b/core/src/main/res/drawable/ic_remove_grey600.xml new file mode 100644 index 000000000..5a6b2af6b --- /dev/null +++ b/core/src/main/res/drawable/ic_remove_grey600.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" + android:viewportHeight="24.0" android:viewportWidth="24.0" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="#FF757575" android:pathData="M19,13H5v-2h14v2z"/> +</vector> diff --git a/core/src/main/res/drawable/ic_remove_white.xml b/core/src/main/res/drawable/ic_remove_white.xml new file mode 100644 index 000000000..d812091fb --- /dev/null +++ b/core/src/main/res/drawable/ic_remove_white.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" + android:viewportHeight="24.0" android:viewportWidth="24.0" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="#FFFFFFFF" android:pathData="M19,13H5v-2h14v2z"/> +</vector> diff --git a/core/src/main/res/drawable/ic_select_all_grey600.xml b/core/src/main/res/drawable/ic_select_all_grey600.xml new file mode 100644 index 000000000..96e9a2de5 --- /dev/null +++ b/core/src/main/res/drawable/ic_select_all_grey600.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FF757575" + android:pathData="M3,5h2L5,3c-1.1,0 -2,0.9 -2,2zM3,13h2v-2L3,11v2zM7,21h2v-2L7,19v2zM3,9h2L5,7L3,7v2zM13,3h-2v2h2L13,3zM19,3v2h2c0,-1.1 -0.9,-2 -2,-2zM5,21v-2L3,19c0,1.1 0.9,2 2,2zM3,17h2v-2L3,15v2zM9,3L7,3v2h2L9,3zM11,21h2v-2h-2v2zM19,13h2v-2h-2v2zM19,21c1.1,0 2,-0.9 2,-2h-2v2zM19,9h2L21,7h-2v2zM19,17h2v-2h-2v2zM15,21h2v-2h-2v2zM15,5h2L17,3h-2v2zM7,17h10L17,7L7,7v10zM9,9h6v6L9,15L9,9z"/> +</vector> diff --git a/core/src/main/res/drawable/ic_select_all_white.xml b/core/src/main/res/drawable/ic_select_all_white.xml new file mode 100644 index 000000000..0fc49c923 --- /dev/null +++ b/core/src/main/res/drawable/ic_select_all_white.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M3,5h2L5,3c-1.1,0 -2,0.9 -2,2zM3,13h2v-2L3,11v2zM7,21h2v-2L7,19v2zM3,9h2L5,7L3,7v2zM13,3h-2v2h2L13,3zM19,3v2h2c0,-1.1 -0.9,-2 -2,-2zM5,21v-2L3,19c0,1.1 0.9,2 2,2zM3,17h2v-2L3,15v2zM9,3L7,3v2h2L9,3zM11,21h2v-2h-2v2zM19,13h2v-2h-2v2zM19,21c1.1,0 2,-0.9 2,-2h-2v2zM19,9h2L21,7h-2v2zM19,17h2v-2h-2v2zM15,21h2v-2h-2v2zM15,5h2L17,3h-2v2zM7,17h10L17,7L7,7v10zM9,9h6v6L9,15L9,9z"/> +</vector> diff --git a/core/src/main/res/drawable/ic_select_none_grey600.xml b/core/src/main/res/drawable/ic_select_none_grey600.xml new file mode 100644 index 000000000..8057f73ca --- /dev/null +++ b/core/src/main/res/drawable/ic_select_none_grey600.xml @@ -0,0 +1,11 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FF757575" + android:pathData="m3,5l2,0l0,-2c-1.1,0 -2,0.9 -2,2zm0,8l2,0l0,-2l-2,0l0,2zm4,8l2,0l0,-2l-2,0l0,2zm-4,-12l2,0l0,-2l-2,0l0,2zm10,-6l-2,0l0,2l2,0l0,-2zm6,0l0,2l2,0c0,-1.1 -0.9,-2 -2,-2zm-14,18l0,-2l-2,0c0,1.1 0.9,2 2,2zm-2,-4l2,0l0,-2l-2,0l0,2zm6,-14l-2,0l0,2l2,0l0,-2zm2,18l2,0l0,-2l-2,0l0,2zm8,-8l2,0l0,-2l-2,0l0,2zm0,8c1.1,0 2,-0.9 2,-2l-2,0l0,2zm0,-12l2,0l0,-2l-2,0l0,2zm0,8l2,0l0,-2l-2,0l0,2zm-4,4l2,0l0,-2l-2,0l0,2zm0,-16l2,0l0,-2l-2,0l0,2z"/> + <path android:fillColor="#FF757575" + android:pathData="M17,8.41L15.59,7 12,10.59 8.41,7 7,8.41 10.59,12 7,15.59 8.41,17 12,13.41 15.59,17 17,15.59 13.41,12z"/> +</vector> diff --git a/core/src/main/res/drawable/ic_select_none_white.xml b/core/src/main/res/drawable/ic_select_none_white.xml new file mode 100644 index 000000000..3e1f6b884 --- /dev/null +++ b/core/src/main/res/drawable/ic_select_none_white.xml @@ -0,0 +1,11 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FFFFFFFF" + android:pathData="m3,5l2,0l0,-2c-1.1,0 -2,0.9 -2,2zm0,8l2,0l0,-2l-2,0l0,2zm4,8l2,0l0,-2l-2,0l0,2zm-4,-12l2,0l0,-2l-2,0l0,2zm10,-6l-2,0l0,2l2,0l0,-2zm6,0l0,2l2,0c0,-1.1 -0.9,-2 -2,-2zm-14,18l0,-2l-2,0c0,1.1 0.9,2 2,2zm-2,-4l2,0l0,-2l-2,0l0,2zm6,-14l-2,0l0,2l2,0l0,-2zm2,18l2,0l0,-2l-2,0l0,2zm8,-8l2,0l0,-2l-2,0l0,2zm0,8c1.1,0 2,-0.9 2,-2l-2,0l0,2zm0,-12l2,0l0,-2l-2,0l0,2zm0,8l2,0l0,-2l-2,0l0,2zm-4,4l2,0l0,-2l-2,0l0,2zm0,-16l2,0l0,-2l-2,0l0,2z"/> + <path android:fillColor="#FFFFFFFF" + android:pathData="M17,8.41L15.59,7 12,10.59 8.41,7 7,8.41 10.59,12 7,15.59 8.41,17 12,13.41 15.59,17 17,15.59 13.41,12z"/> +</vector> diff --git a/core/src/main/res/drawable/overlay_button_circle_background.xml b/core/src/main/res/drawable/overlay_button_circle_background.xml deleted file mode 100644 index 90c51472c..000000000 --- a/core/src/main/res/drawable/overlay_button_circle_background.xml +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<shape xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="rectangle"> - <gradient - android:type="radial" - android:gradientRadius="60" - android:startColor="#000000" - android:endColor="@android:color/transparent"/> -</shape>
\ No newline at end of file diff --git a/core/src/main/res/drawable/overlay_drawable_dark_trueblack.xml b/core/src/main/res/drawable/overlay_drawable_dark_trueblack.xml new file mode 100644 index 000000000..5f58e8421 --- /dev/null +++ b/core/src/main/res/drawable/overlay_drawable_dark_trueblack.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<layer-list xmlns:android="http://schemas.android.com/apk/res/android" > + + <item> + <shape android:shape="rectangle" > + <solid android:color="#45B3E1" /> + </shape> + </item> + <item android:top="1dp"> + <shape android:shape="rectangle" > + <solid android:color="@color/black" /> + </shape> + </item> + +</layer-list>
\ No newline at end of file diff --git a/core/src/main/res/drawable/progress_bar_horizontal_trueblack.xml b/core/src/main/res/drawable/progress_bar_horizontal_trueblack.xml new file mode 100644 index 000000000..604bb2655 --- /dev/null +++ b/core/src/main/res/drawable/progress_bar_horizontal_trueblack.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:id="@android:id/background"> + <shape> + <solid android:color="#000000"/> + </shape> + </item> + <item android:id="@android:id/progress"> + <clip> + <shape> + <solid android:color="@color/holo_blue_dark"/> + </shape> + </clip> + </item> +</layer-list> diff --git a/core/src/main/res/values-ar/strings.xml b/core/src/main/res/values-ar/strings.xml index fe932e959..5c29b5119 100644 --- a/core/src/main/res/values-ar/strings.xml +++ b/core/src/main/res/values-ar/strings.xml @@ -1,16 +1,34 @@ <?xml version='1.0' encoding='UTF-8'?> <resources xmlns:tools="http://schemas.android.com/tools"> <!--Activitiy and fragment titles--> + <string name="feed_update_receiver_name">تØديث التسجيل</string> + <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="new_episodes_label">جديد</string> <string name="favorite_episodes_label">المÙضلات</string> <string name="new_label">جديد</string> - <string name="settings_label">اعدادات</string> + <string name="settings_label">إعدادات</string> <string name="downloads_label">تنزيل</string> <string name="downloads_running_label">جارى التشغيل</string> <string name="downloads_completed_label">اكتمل</string> <string name="downloads_log_label">سجل</string> + <string name="subscriptions_label">تسجيلات</string> + <string name="subscriptions_list_label">لائØØ© التسجيلات</string> <string name="cancel_download_label">الغاء التنزيل</string> + <string name="playback_history_label">أرشي٠التشغيل</string> + <string name="gpodnet_main_label">gpodder.net</string> + <string name="gpodnet_summary">تزامن مع أجهزة أخرى</string> + <string name="gpodnet_auth_label">تسجيل الدخول لموقع gpodder</string> + <string name="free_space_label"> %1$s مجانا</string> + <string name="episode_cache_full_title">ذاكرة تخزين الØلقات ممتلئة</string> + <string name="episode_cache_full_message">لقد تم تجاوز الØد الأقصى لتخزين الØلقات. المرجو الرÙع من قيمة التخزين ÙÙŠ قائمة الإعدادات.</string> + <string name="synchronizing">المزامنة...</string> <!--Statistics fragment--> + <string name="total_time_listened_to_podcasts">مجموع وقت تشغيل البودكاستات:</string> + <string name="statistics_mode">نمط الإØصائيات</string> <!--Main activity--> <string name="drawer_open">قائمة الÙتØ</string> <string name="drawer_close">قائمة الاغلاÙ</string> @@ -26,11 +44,13 @@ <string name="copied_url_msg">تم نسخ الرابط للØاÙظة</string> <string name="go_to_position_label">اذهب لهذا الموقع</string> <!--Playback history--> + <string name="clear_history_label">Ù…Ø³Ø Ø§Ù„Ø£Ø±Ø´ÙŠÙ</string> <!--Other--> <string name="confirm_label">تأكيد</string> <string name="cancel_label">الغاء</string> <string name="yes">نعم</string> <string name="no">لا</string> + <string name="reset">إعادة التعيين</string> <string name="author_label">المؤلÙ</string> <string name="language_label">لغة</string> <string name="url_label">عنوان الموقع</string> @@ -60,7 +80,6 @@ <string name="show_info_label">اظهار المعلومات</string> <string name="share_label">مشاركة</string> <string name="share_link_label">مشاركة الرابط</string> - <string name="episode_actions">تطبيق الاجراء</string> <string name="hide_unplayed_episodes_label">لم يتم تشغيله</string> <string name="hide_paused_episodes_label">ايقا٠مؤقت</string> <string name="hide_downloaded_episodes_label">تم التنزيل</string> @@ -105,24 +124,73 @@ <!--Auto-Flattr dialog--> <!--Search--> <!--OPML import and export--> + <string name="opml_import_error_no_file">لم يتم اختيار أي ملÙ</string> + <string name="select_all_label">اختر الكل</string> + <string name="deselect_all_label">ألغ اختيار الكل</string> + <string name="select_options_label">اختر...</string> + <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="export_success_title">تم التصدير بنجاØ</string> <!--Sleep timer--> + <string name="enter_time_here_label">أدخل التوقيت</string> + <string name="timer_vibration_label">تشغيل الهزاز</string> + <string name="time_seconds">ثواني</string> + <string name="time_minutes">دقائق</string> + <string name="time_hours">ساعات</string> <!--gpodder.net--> + <string name="gpodnet_taglist_header">الÙئات</string> + <string name="gpodnet_toplist_header">أقوى البودكاستات</string> + <string name="gpodnet_suggestions_header">إقتراØات</string> + <string name="gpodnetauth_login_title">تسجيل الدخول</string> + <string name="gpodnetauth_login_butLabel">تسجيل الدخول</string> + <string name="username_label">إسم المستخدم</string> + <string name="password_label">كلمة المرور</string> + <string name="gpodnetauth_device_title">اختيار الأجهزة:</string> + <string name="gpodnetauth_device_butCreateNewDevice">أدخل جهازا جديدا</string> + <string name="gpodnetauth_device_chooseExistingDevice">اختر جهازا من القائمة: </string> + <string name="gpodnetauth_device_butChoose">إختر</string> + <string name="gpodnetauth_finish_title">لقد تم تسجيل الدخول بنجاØ!</string> + <string name="gpodnetauth_finish_butgomainscreen">إذهب إلى الصÙØØ© الرئيسية</string> + <string name="gpodnetsync_auth_error_descr">خطأ ÙÙŠ إسم المستخدم أو كلمة المرور</string> + <string name="gpodnetsync_pref_report_successful">تم بنجاØ</string> <!--Directory chooser--> + <string name="selected_folder_label">إختيار المستند:</string> + <string name="create_folder_label">أنشأ مستندا جديدا</string> + <string name="choose_data_directory">إختيار مستند البيانات</string> <!--Online feed view--> + <string name="downloading_label">تØميل ...</string> <!--Content descriptions for image buttons--> + <string name="media_type_audio_label">صوت</string> + <string name="media_type_video_label">Ùيديو</string> + <string name="load_next_page_label">تØميل الصÙØØ© التالية</string> <!--Feed information screen--> + <string name="authentication_label">تسجيل الدخول</string> <!--Progress information--> <!--AntennaPodSP--> <!--Episodes apply actions--> <string name="all_label">الكل</string> + <string name="selected_all_label">إختيار كل الØلقات</string> <string name="unplayed_label">لم يتم تشغيله</string> <string name="downloaded_label">تم التنزيل</string> <string name="not_downloaded_label">لم يتم التنزيل</string> <!--Sort--> <!--Rating dialog--> <!--Audio controls--> + <string name="volume">مستوى الصوت</string> <!--proxy settings--> + <string name="proxy_type_label">النوع</string> <!--Database import/export--> + <string name="label_import">استيراد</string> + <string name="label_export">تصدير</string> + <string name="export_ok">تم التصدير بنجاØ</string> <!--Casting--> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> + <string name="notification_channel_downloading">تØميل</string> + <string name="notification_channel_playing">يشغل Øاليا</string> + <string name="notification_channel_error">الأخطاء</string> </resources> diff --git a/core/src/main/res/values-az/strings.xml b/core/src/main/res/values-az/strings.xml index c27aa54d2..92bfb7f44 100644 --- a/core/src/main/res/values-az/strings.xml +++ b/core/src/main/res/values-az/strings.xml @@ -165,7 +165,6 @@ <string name="deselect_all_label">Seçimi ləğv et</string> <string name="opml_export_label">OPML ixraçı</string> <string name="export_error_label">Ä°xracın xÉ™tası</string> - <string name="opml_export_success_sum">OPML fayl:\u0020 yazılıb</string> <!--Sleep timer--> <string name="set_sleeptimer_label">Yuxu taymerini qoy</string> <string name="disable_sleeptimer_label">Yuxu taymerini keçir</string> @@ -200,4 +199,5 @@ <!--Database import/export--> <!--Casting--> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-b+ast/strings.xml b/core/src/main/res/values-b+ast/strings.xml index 5113a895e..421896086 100644 --- a/core/src/main/res/values-b+ast/strings.xml +++ b/core/src/main/res/values-b+ast/strings.xml @@ -109,7 +109,6 @@ <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> @@ -243,7 +242,6 @@ <!--Preferences--> <string name="storage_pref">Almacenamientu</string> <string name="project_pref">Proyeutu</string> - <string name="services_label">Servicios</string> <string name="flattr_label">Flattr</string> <string name="pref_episode_cleanup_title">Llimpieza d\'episodios</string> <string name="pref_pauseOnDisconnect_sum">Posa la reproducción al desconeutase los auriculares o Bluetooth</string> @@ -378,4 +376,5 @@ <!--Database import/export--> <!--Casting--> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-bg/strings.xml b/core/src/main/res/values-bg/strings.xml index 286c9a3eb..19dc2a971 100644 --- a/core/src/main/res/values-bg/strings.xml +++ b/core/src/main/res/values-bg/strings.xml @@ -30,6 +30,7 @@ <string name="drawer_feed_counter_downloaded">Брой изтеглени епизоди</string> <string name="drawer_feed_counter_none">Ðикакви</string> <!--Webview actions--> + <string name="open_in_browser_label">Отвори в браузъра</string> <string name="copy_url_label">Копирай URL адреÑ</string> <string name="share_url_label">Сподели URL адреÑ</string> <string name="copied_url_msg">ÐдреÑÑŠÑ‚ е копиран</string> @@ -40,6 +41,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> @@ -47,7 +49,9 @@ <string name="cover_label">Снимка</string> <string name="error_label">Грешка</string> <string name="error_msg_prefix">Възникна грешка:</string> + <string name="refresh_label">Обнови</string> <string name="external_storage_error_msg">ÐÑма налична външна памет. Уверете Ñе, че външната памет е монтирана, за да може приложението да работи правилно.</string> + <string name="chapter_duration">Времетраене: %1$s</string> <string name="description_label">ОпиÑание</string> <string name="most_recent_prefix">Ðай-нов епизод:\u0020</string> <string name="size_prefix">Размер:\u0020</string> @@ -60,6 +64,7 @@ <string name="etxtFeedurlHint">www.primer.com/emisiq</string> <string name="txtvfeedurl_label">ДобавÑне на подкаÑÑ‚ по URL адреÑ</string> <string name="podcastdirectories_label">Ðамиране на подкаÑÑ‚ в директориÑ</string> + <string name="podcastdirectories_descr">Можете да Ñ‚ÑŠÑ€Ñите нови подкаÑти в iTunes или fyyd, или да прегледате gpodder.net Ñпоред име, ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ Ð¸ популÑрноÑÑ‚.</string> <!--Actions on feeds--> <string name="mark_all_read_label">Маркирай вÑички като Ñлушани</string> <string name="mark_all_read_msg">Ð’Ñички епизоди Ñа маркирани като Ñлушани</string> @@ -79,6 +84,8 @@ <string name="share_item_url_label">Сподели URL Ð°Ð´Ñ€ÐµÑ Ð½Ð° епизода</string> <string name="share_item_url_with_position_label">Сподели URL Ð°Ð´Ñ€ÐµÑ Ð½Ð° епизода Ñ Ð¿Ð¾Ð·Ð¸Ñ†Ð¸Ñ</string> <string name="feed_remover_msg">Премахване на емиÑиÑта</string> + <string name="hide_downloaded_episodes_label">Изтеглени</string> + <string name="hide_not_downloaded_episodes_label">Ðеизтеглени</string> <!--actions on feeditems--> <string name="stream_label">Стрийм</string> <string name="marked_as_seen_label">Маркиран като прегледан</string> @@ -111,7 +118,6 @@ <string name="other_pref">Други</string> <string name="about_pref">ОтноÑно</string> <string name="queue_label">Опашка</string> - <string name="services_label">УÑлуги</string> <string name="flattr_label">Flattr</string> <string name="pref_episode_cleanup_title">ПочиÑтване на епизодите</string> <string name="pref_episode_cleanup_summary">Епизодите, които не Ñа в опашката и не Ñа в любими, отговарÑÑ‚ на уÑловиÑта за премахване, ако автоматичното изтеглÑне Ñе нуждае от мÑÑто за нови епизоди</string> @@ -175,6 +181,7 @@ <string name="crash_report_sum">Изпратете най-Ð½Ð¾Ð²Ð¸Ñ Ð´Ð¾ÐºÐ»Ð°Ð´ за Ñрив чрез имейл</string> <string name="send_email">Изпращане на имейл</string> <string name="experimental_pref">ЕкÑпериментални</string> + <string name="pref_current_value">Текуща ÑтойноÑÑ‚: %1$s</string> <string name="pref_proxy_title">ПрокÑи</string> <string name="pref_faq">ЧеÑто задавани въпроÑи</string> <string name="pref_known_issues">ИзвеÑтни проблеми</string> @@ -193,10 +200,9 @@ <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> - <string name="opml_export_success_sum">.opml файлът беше запиÑан в:\u0020</string> <string name="opml_import_ask_read_permission">Ðеобходим е доÑтъп до външната памет за прочитане на OPML файла</string> <!--Sleep timer--> + <string name="timer_vibration_label">ВибрациÑ</string> <string name="time_seconds">Ñекунди</string> <string name="time_minutes">минути</string> <string name="time_hours">чаÑа</string> @@ -216,6 +222,7 @@ <string name="gpodnet_taglist_header">КÐТЕГОРИИ</string> <string name="gpodnet_toplist_header">ТОП ПОДКÐСТИ</string> <string name="gpodnet_suggestions_header">ПРЕДЛОЖЕÐИЯ</string> + <string name="gpodnet_search_hint">ТърÑене в gpodder.net</string> <string name="gpodnetauth_login_title">Вход</string> <string name="gpodnetauth_login_butLabel">Вход</string> <string name="username_label">ПотребителÑко име</string> @@ -229,11 +236,21 @@ <!--Progress information--> <!--AntennaPodSP--> <string name="filter">Филтър</string> + <string name="search_fyyd_label">ТърÑене във fyyd</string> <!--Episodes apply actions--> <!--Sort--> <!--Rating dialog--> <!--Audio controls--> <!--proxy settings--> + <string name="proxy_type_label">Тип</string> + <string name="host_label">ХоÑÑ‚</string> + <string name="port_label">Порт</string> + <string name="proxy_test_label">ТеÑÑ‚</string> + <string name="proxy_test_successful">ТеÑÑ‚ÑŠÑ‚ е уÑпешен</string> + <string name="proxy_test_failed">ТеÑÑ‚ÑŠÑ‚ е неуÑпешен</string> + <string name="proxy_port_invalid_error">Портът не е валиден</string> + <!--Database import/export--> <!--Casting--> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-ca-rES/strings.xml b/core/src/main/res/values-ca-rES/strings.xml index fe20ff5da..d9f216268 100644 --- a/core/src/main/res/values-ca-rES/strings.xml +++ b/core/src/main/res/values-ca-rES/strings.xml @@ -58,4 +58,5 @@ <!--Database import/export--> <!--Casting--> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-ca/strings.xml b/core/src/main/res/values-ca/strings.xml index 86fac02a5..ecf51f704 100644 --- a/core/src/main/res/values-ca/strings.xml +++ b/core/src/main/res/values-ca/strings.xml @@ -1,12 +1,14 @@ <?xml version='1.0' encoding='UTF-8'?> <resources xmlns:tools="http://schemas.android.com/tools"> <!--Activitiy and fragment titles--> + <string name="feed_update_receiver_name">Actualitzar subscripcions</string> <string name="feeds_label">Canals</string> <string name="statistics_label">EstadÃstiques</string> <string name="add_feed_label">Afegeix podcast</string> <string name="episodes_label">Episodis</string> <string name="all_episodes_short_label">Tot</string> - <string name="favorite_episodes_label">Favorits</string> + <string name="new_episodes_label">Nou</string> + <string name="favorite_episodes_label">Preferits</string> <string name="new_label">Nous</string> <string name="settings_label">Configuració</string> <string name="downloads_label">Baixades</string> @@ -15,13 +17,15 @@ <string name="downloads_log_label">Registre</string> <string name="subscriptions_label">Subscripcions</string> <string name="subscriptions_list_label">Llista de subscripcions</string> - <string name="cancel_download_label">Cancel·la la baixada</string> + <string name="cancel_download_label">Cancel·la\nBaixada</string> <string name="playback_history_label">Historial de reproducció</string> <string name="gpodnet_main_label">gpodder.net</string> + <string name="gpodnet_summary">Sincronitzar amb altres dispositius</string> <string name="gpodnet_auth_label">Inici de sessió a gpodder.net</string> <string name="free_space_label">%1$s lliure</string> - <string name="episode_cache_full_title">Caché d\'episodi completa</string> - <string name="episode_cache_full_message">S\'ha arribat al lÃmit de la caché. Pots incrementar la capacitat de la caché a les Opcions</string> + <string name="episode_cache_full_title">La memòria cau d\'episodis és plena</string> + <string name="episode_cache_full_message">S\'ha arribat al lÃmit de la memòria cau d\'episodis. Pots incrementar-ne la capacitat a la configuració.</string> + <string name="synchronizing">Sincronitzant...</string> <!--Statistics fragment--> <string name="total_time_listened_to_podcasts">Temps total de podcasts reproduïts</string> <string name="statistics_details_dialog">%1$d de %2$depisodis començats.\n\nReproduïts %3$s de %4$s.</string> @@ -33,7 +37,7 @@ <string name="drawer_open">Obre menú</string> <string name="drawer_close">Tanca menú</string> <string name="drawer_preferences">Calaix de preferències</string> - <string name="drawer_feed_order_unplayed_episodes">Ordre per durada</string> + <string name="drawer_feed_order_unplayed_episodes">Ordre per comptador</string> <string name="drawer_feed_order_alphabetical">Ordre alfabètic</string> <string name="drawer_feed_order_last_update">Ordre per data de publicació</string> <string name="drawer_feed_order_most_played">Ordre per número d\'episodis reproduïts</string> @@ -56,13 +60,14 @@ <string name="yes">SÃ</string> <string name="no">No</string> <string name="reset">Reiniciar</string> - <string name="author_label">Autor</string> + <string name="author_label">Autor/s</string> <string name="language_label">Llengua</string> <string name="url_label">Adreça web</string> <string name="podcast_settings_label">Configuració</string> <string name="cover_label">Imatge</string> <string name="error_label">Error</string> <string name="error_msg_prefix">S\'ha produït un error:</string> + <string name="needs_storage_permission">Calen permisos d\'emmagatzematge per a aquesta operació</string> <string name="refresh_label">Actualitza</string> <string name="external_storage_error_msg">L\'emmagatzemament extern no està disponible. Assegureu-vos que està muntat per què l\'aplicació funcioni correctament.</string> <string name="chapters_label">CapÃtols</string> @@ -82,7 +87,7 @@ <string name="auto_download_apply_to_items_title">Aplica als episodis previs</string> <string name="auto_download_apply_to_items_message">El nou ajustament de <i>baixada automà tica</i> s\'aplicarà als nous episodis.\nVols que també sigui aplicat als episodis publicats prèviament?</string> <string name="auto_delete_label">Esborra episodi automà ticament</string> - <string name="parallel_downloads_suffix">\u0020baixades paral·leles</string> + <string name="parallel_downloads_suffix">\u0020baixades en paral·lel</string> <string name="feed_auto_download_global">Valor predeterminat global</string> <string name="feed_auto_download_always">Sempre</string> <string name="feed_auto_download_never">Mai</string> @@ -105,25 +110,28 @@ <string name="mark_all_read_label">Marca-ho tot com a llegit</string> <string name="mark_all_read_msg">S\'han marcat tots els episodis com a llegits</string> <string name="mark_all_read_confirmation_msg">Si us plau confirma que vols marcar tots els episodis com reproduits.</string> - <string name="mark_all_read_feed_confirmation_msg">Si us plau confirma que vols marcar tots els episodis d\'aquest canal com reproduits.</string> + <string name="mark_all_read_feed_confirmation_msg">Si us plau, confirmeu que voleu marcar tots els episodis d\'aquest podcast com a reproduïts.</string> <string name="mark_all_seen_label">Marca tot com a llegit</string> - <string name="mark_all_seen_msg">S\'han marcat tots els episodis com a vistos</string> + <string name="mark_all_seen_msg">Marcar tots episodis com a visualitzats</string> <string name="mark_all_seen_confirmation_msg">Si us plau confirma que vols marcar tots els episodis com vistos.</string> <string name="show_info_label">Mostra informació</string> - <string name="rename_feed_label">Renombra podcast</string> - <string name="remove_feed_label">Esborra podcast</string> - <string name="share_label">Compartir...</string> - <string name="share_link_label">Comparteix l\'enllaç</string> - <string name="share_file_label">Comparteix un fitxer</string> - <string name="share_link_with_position_label">Comparteix enllaç amb posició</string> - <string name="share_feed_url_label">Comparteix adreça del canal</string> - <string name="share_item_url_label">Comparteix adreça del fitxer del canal</string> - <string name="share_item_url_with_position_label">Comparteix adreça del fitxer del canal amb posició</string> - <string name="feed_delete_confirmation_msg">Confirmeu que voleu suprimir el canal \"%1$s\" i TOTS els episodis que n\'heu descarregat.</string> - <string name="feed_remover_msg">S\'està esborrant el canal</string> - <string name="load_complete_feed">S\'ha actualitzat el canal</string> + <string name="show_feed_settings_label">Mostrar configuració del podcast</string> + <string name="feed_info_label">Informació del podcast</string> + <string name="feed_settings_label">Configuració del podcast</string> + <string name="rename_feed_label">Canvia el nom al podcast</string> + <string name="remove_feed_label">Suprimeix podcast</string> + <string name="share_label">Comparteix...</string> + <string name="share_link_label">Comparteix l\'adreça de l\'episodi</string> + <string name="share_link_with_position_label">Comparteix l\'adreça de l\'episodi i la posició</string> + <string name="share_file_label">Comparteix el fitxer</string> + <string name="share_feed_url_label">Comparteix l\'adreça del canal</string> + <string name="share_item_url_label">Comparteix l\'adreça del fitxer multimèdia</string> + <string name="share_item_url_with_position_label">Comparteix l\'adreça del fitxer multimèdia i la posició</string> + <string name="feed_delete_confirmation_msg">Si us plau, confirmeu que voleu eliminar el podcast \"%1$s\" i tots els seus episodis (fins i tot els ja baixats).</string> + <string name="feed_remover_msg">Eliminant podcast</string> + <string name="load_complete_feed">Refrescar tot el podcast</string> <string name="hide_episodes_title">Amaga Episodis</string> - <string name="episode_actions">Aplica accions</string> + <string name="batch_edit">Editar lot</string> <string name="hide_unplayed_episodes_label">Per reproduir</string> <string name="hide_paused_episodes_label">Pausat</string> <string name="hide_played_episodes_label">Reproduit</string> @@ -132,6 +140,7 @@ <string name="hide_downloaded_episodes_label">Baixat</string> <string name="hide_not_downloaded_episodes_label">No baixat</string> <string name="hide_has_media_label">Conté medis</string> + <string name="hide_is_favorite_label">És preferint</string> <string name="filtered_label">Filtrat</string> <string name="refresh_failed_msg">{fa-exclamation-circle} Darrera actualització fallida</string> <string name="open_podcast">Obrir podcast</string> @@ -144,7 +153,8 @@ <string name="remove_label">Suprimeix</string> <string name="delete_label">Esborrar</string> <string name="delete_failed">No s\'ha pogut esborrar el fitxer. Reiniciar el dispositiu pot ajudar.</string> - <string name="remove_episode_lable">Esborra episodi</string> + <string name="remove_episode_lable">Suprimeix episodi</string> + <string name="mark_as_seen_label">Marcar com a visualitzat</string> <string name="marked_as_seen_label">Marcat com a vist</string> <string name="mark_read_label">Marca com a llegit</string> <string name="marked_as_read_label">Marcats com llegits</string> @@ -152,22 +162,24 @@ <string name="add_to_queue_label">Afegeix a la cua</string> <string name="added_to_queue_label">Afegit a la cua</string> <string name="remove_from_queue_label">Suprimeix de la cua</string> - <string name="add_to_favorite_label">Afegit a Favorits</string> - <string name="added_to_favorites">Afegit a favorits</string> - <string name="remove_from_favorite_label">Suprimeix de Favorits</string> - <string name="removed_from_favorites">Tret de favorits</string> + <string name="add_to_favorite_label">Afegit a preferits</string> + <string name="added_to_favorites">Afegit a preferits</string> + <string name="remove_from_favorite_label">Suprimeix de preferits</string> + <string name="removed_from_favorites">S\'ha suprimit de preferits</string> <string name="visit_website_label">Visita el lloc web</string> <string name="support_label">Comparteix amb Flattr</string> <string name="skip_episode_label">Omet l\'episodi</string> <string name="activate_auto_download">Activa baixades automà tiques</string> <string name="deactivate_auto_download">Desactiva les baixades automà tiques</string> <string name="reset_position">Restablir posició de reproducció</string> - <string name="removed_item">Element eliminat</string> + <string name="removed_item">S\'ha suprimit l\'element</string> <!--Download messages and labels--> <string name="download_successful">ha funcionat</string> <string name="download_failed">ha fallat</string> <string name="download_pending">Baixada pendent</string> <string name="download_running">Baixada en procés</string> + <string name="download_error_details">Detalls</string> + <string name="download_error_details_message">%1$s \n\nURL del fitxer:\n%2$s</string> <string name="download_error_device_not_found">No s\'ha trobat cap dispositiu d\'emmagatzemament</string> <string name="download_error_insufficient_space">No hi ha prou espai</string> <string name="download_error_file_error">Error de fitxer</string> @@ -218,6 +230,7 @@ <string name="playback_error_unknown">Error desconegut</string> <string name="no_media_playing_label">No s\'està reproduint res</string> <string name="player_buffering_msg">S\'està carregant</string> + <string name="player_go_to_picture_in_picture">Mode Picture-in-picture</string> <string name="playbackservice_notification_title">Podcast en reproducció</string> <string name="unknown_media_key">AntennaPod - Control desconegut: %1$d</string> <!--Queue operations--> @@ -234,7 +247,9 @@ <string name="date">Data</string> <string name="duration">Durada</string> <string name="episode_title">TÃtol de l\'episodi</string> - <string name="feed_title">TÃtol del feed</string> + <string name="feed_title">TÃtol del podcast</string> + <string name="random">Aleatori</string> + <string name="smart_shuffle">Mescla intel·ligent</string> <string name="ascending">Ascendent</string> <string name="descending">Descendent</string> <string name="clear_queue_confirmation_msg">Si us plau, confirma que vols suprimir tots els episodis de la cua</string> @@ -272,7 +287,7 @@ <string name="enable_sonic">Activa Sonic</string> <!--Empty list labels--> <string name="no_items_label">No hi ha elements a la llista.</string> - <string name="no_feeds_label">No us heu subscrit a cap canal.</string> + <string name="no_feeds_label">Encara no us heu subscrit a cap podcast.</string> <string name="no_chapters_label">Aquest episodi no té capÃtols</string> <string name="no_shownotes_label">Aquest episodi no té notes.</string> <!--Preferences--> @@ -281,15 +296,23 @@ <string name="other_pref">Altres</string> <string name="about_pref">Quant a</string> <string name="queue_label">Cua</string> - <string name="services_label">Serveis</string> + <string name="integrations_label">Integracions</string> <string name="flattr_label">Flattr</string> + <string name="flattr_summary">Servei de micropagaments</string> + <string name="automation">Automatització</string> + <string name="download_pref_details">Detalls</string> + <string name="import_export_pref">Importa/Exporta</string> + <string name="appearance">Aparença</string> + <string name="external_elements">Elements externs</string> + <string name="interruptions">Interrupcions</string> + <string name="buttons">Botons de control de reproducció</string> + <string name="media_player">Reproductor multimèdia</string> <string name="pref_episode_cleanup_title">Neteja l\'episodi</string> - <string name="pref_episode_cleanup_summary">Els episodis que no es troben a la cua i no són favorits haurien de ser candidats a ser esborrats si l\'Auto Descà rrega necessita espai per a nous episodis</string> + <string name="pref_episode_cleanup_summary">Els episodis que no es troben a la cua i no són preferits seran candidats a ser suprimits si l\'Auto Descà rrega necessita espai per a nous episodis</string> <string name="pref_pauseOnDisconnect_sum">Pausa la reproducció en desconnectar els auriculars o el bluetooth</string> <string name="pref_unpauseOnHeadsetReconnect_sum">Continua la reproducció en connectar novament els auriculars</string> <string name="pref_unpauseOnBluetoothReconnect_sum">Continua la reproducció en connectar novament el bluetooth</string> <string name="pref_hardwareForwardButtonSkips_title">Endavant per saltar</string> - <string name="pref_hardwareForwardButtonSkips_sum">En prémer el botó fÃsic d\'Endavant, passar al següent episodi en comptes d\'avançar a la reproducció</string> <string name="pref_hardwarePreviousButtonRestarts_title">Endarrere per reiniciar</string> <string name="pref_hardwarePreviousButtonRestarts_sum">En prémer un botó fÃsic, reinicieu l\'episodi actual en lloc de rebobinar-lo</string> <string name="pref_followQueue_sum">Salta al següent element de la cua en acabar la reproducció</string> @@ -299,8 +322,8 @@ <string name="pref_smart_mark_as_played_title">Marca intel·ligent com a reproduït</string> <string name="pref_skip_keeps_episodes_sum">Mantenir episodis quan són passats de llarg</string> <string name="pref_skip_keeps_episodes_title">Mantenir els episodis passats de llarg</string> - <string name="pref_favorite_keeps_episodes_sum">Conserva els episodis marcats com a favorits.</string> - <string name="pref_favorite_keeps_episodes_title">Conserva els episodis favorits.</string> + <string name="pref_favorite_keeps_episodes_sum">Conserva els episodis marcats com a preferits.</string> + <string name="pref_favorite_keeps_episodes_title">Conserva els episodis preferits.</string> <string name="playback_pref">Reproducció</string> <string name="network_pref">Xarxa</string> <string name="pref_autoUpdateIntervallOrTime_title">Actualitza interval o horari del dia</string> @@ -338,7 +361,7 @@ <string name="pref_nav_drawer_feed_order_title">Estableix l\'ordre de les subscripcions</string> <string name="pref_nav_drawer_feed_order_sum">Canvia l\'ordre de les subscripcions</string> <string name="pref_nav_drawer_feed_counter_title">Estableix el comptador de les subscripcions</string> - <string name="pref_nav_drawer_feed_counter_sum">Canvia la informació mostrada pel comptador de les subscripcions</string> + <string name="pref_nav_drawer_feed_counter_sum">Canvia la informació mostrada pel comptador de les subscripcions. També afecta l\'ordre de les subscripcions si a l\'opció \'Ordre de les subscripcions\' s\'ha indicat \'Comptador\'.</string> <string name="pref_set_theme_sum">Canvieu l\'aparença d\'AntennaPod.</string> <string name="pref_automatic_download_title">Baixada automà tica</string> <string name="pref_automatic_download_sum">Configureu la baixada automà tica d\'episodis.</string> @@ -349,9 +372,10 @@ <string name="pref_automatic_download_on_battery_title">Baixa mentre no es carrega</string> <string name="pref_automatic_download_on_battery_sum">Permet les baixades automà tiques mentre la bateria no es carrega</string> <string name="pref_parallel_downloads_title">Baixades paral·leles</string> - <string name="pref_episode_cache_title">Memòria d\'episodis</string> + <string name="pref_episode_cache_title">Memòria cau d\'episodis</string> <string name="pref_theme_title_light">Clar</string> <string name="pref_theme_title_dark">Fosc</string> + <string name="pref_theme_title_trueblack">Negra (per AMOLED)</string> <string name="pref_episode_cache_unlimited">Sense lÃmits</string> <string name="pref_update_interval_hours_plural">hores</string> <string name="pref_update_interval_hours_singular">hora</string> @@ -380,8 +404,6 @@ <string name="pref_rewind_sum">Personalitza el nombre de segons del salt endarrere quan es prem el botó de Rebobinat</string> <string name="pref_gpodnet_sethostname_title">Definex nom del servidor</string> <string name="pref_gpodnet_sethostname_use_default_host">Utilitza el servidor per defecte</string> - <string name="pref_expandNotify_title">Amplia la notificació</string> - <string name="pref_expandNotify_sum">Amplia sempre les notificacions per mostrar els botons de reproducció.</string> <string name="pref_persistNotify_title">Botons de reproducció persistents</string> <string name="pref_persistNotify_sum">Manté els controls a l\'à rea de notificacions i pantalla de bloqueig quan la reproducció estigui aturada</string> <string name="pref_compact_notification_buttons_title">Estableix els botons del bloqueig de pantalla</string> @@ -402,8 +424,7 @@ <string name="crash_report_sum">Envia l\'últim informe de tancament abrupte per e-mail</string> <string name="send_email">Envia e-mail</string> <string name="experimental_pref">Experimental</string> - <string name="pref_sonic_title">Reproductor Sonic Media Player</string> - <string name="pref_sonic_message">Fes servir el reproductor Sonic Media Player integrat en comptes del reproductor natiu d\'Android i Prestissimo</string> + <string name="pref_media_player_message">Seleccioneu el reproductor multimèdia per a reproduir fitxers</string> <string name="pref_current_value">Valor actual: %1$s</string> <string name="pref_proxy_title">Servidor intermediari</string> <string name="pref_proxy_sum">Estableix un servidor intermediari</string> @@ -415,6 +436,11 @@ <string name="pref_cast_message_free_flavor">Chromecast requereix de llibreries propietà ries de terceres parts que estan inhabilitades en aquesta versió d\'AntennaPod</string> <string name="pref_enqueue_downloaded_title">Afegeix les baixades a la cua</string> <string name="pref_enqueue_downloaded_summary">Afegeix els episodis descarregats a la cua</string> + <string name="media_player_builtin">Reproductor Android està ndard</string> + <string name="pref_videoBehavior_title">En sortir d\'un vÃdeo</string> + <string name="pref_videoBehavior_sum">Comportament a l\'abandonar la reproducció d\'un vÃdeo</string> + <string name="stop_playback">Atura reproducció</string> + <string name="continue_playback">Continuar reproducció d\'audio</string> <!--Auto-Flattr dialog--> <string name="auto_flattr_enable">Activa la compartició automà tica per Flattr</string> <string name="auto_flattr_after_percent">Comparteix per Flattr l\'episodi en haver-ne reproduït el %d per cent</string> @@ -424,8 +450,8 @@ <string name="search_hint">Cerca episodis</string> <string name="found_in_shownotes_label">Troba a les notes dels canals</string> <string name="found_in_chapters_label">Trobat als capÃtols</string> - <string name="found_in_authors_label">Troba als autors</string> - <string name="found_in_feeds_label">Troba als canals</string> + <string name="found_in_authors_label">Trobat a autor/s</string> + <string name="found_in_feeds_label">Trobat a un podcast</string> <string name="search_status_no_results">No s\'ha trobat cap resultat</string> <string name="search_label">Cerca</string> <string name="found_in_title_label">Trobat al tÃtol</string> @@ -451,8 +477,8 @@ <string name="html_export_label">Exporta HTML</string> <string name="exporting_label">Exportant...</string> <string name="export_error_label">Error d\'exportació</string> - <string name="opml_export_success_title">S\'ha exportat l\'OPML correctament.</string> - <string name="opml_export_success_sum">El fitxer OPML s\'ha escrit a:\u0020</string> + <string name="export_success_title">Exportació correcta</string> + <string name="export_success_sum">S\'ha exportat el fitxer a:\n\n%1$s</string> <string name="opml_import_ask_read_permission">Per llegir arxius OPML és necessari accés a la memòria externa</string> <!--Sleep timer--> <string name="set_sleeptimer_label">Defineix un temporitzador</string> @@ -625,7 +651,7 @@ <string name="label_import">Importa</string> <string name="label_export">Exporta</string> <string name="import_select_file">Tria un fitxer per a importar</string> - <string name="export_ok">S\'ha exportat amb èxit. S\'ha escrit la base de dades a la targeta SD.</string> + <string name="export_ok">Exportació correcta.</string> <string name="import_ok">S\'ha importat amb èxit.\n\nPremeu D\'acord per a reiniciar l\'AntennaPod.</string> <!--Casting--> <string name="cast_media_route_menu_title">Reproduir a...</string> @@ -643,4 +669,13 @@ <string name="cast_failed_seek">No s\'ha pogut cercar la nova posició al dispositiu de difusió</string> <string name="cast_failed_receiver_player_error">El reproductor receptor ha trobat un error greu</string> <string name="cast_failed_media_error_skipping">Error en la reproducció. Saltant...</string> + <!--Notification channels--> + <string name="notification_channel_user_action">Acció necessà ria</string> + <string name="notification_channel_user_action_description">Mostrar si es requereix la vostra acció, per exemple si heu d\'entrar una contrasenya.</string> + <string name="notification_channel_downloading">Baixant</string> + <string name="notification_channel_downloading_description">Mostrar durant baixades.</string> + <string name="notification_channel_playing">Reproducció actual</string> + <string name="notification_channel_playing_description">Permet controlar la reproducció. Aquesta és la notificació principal que veureu durant la reproducció d\'un podcast.</string> + <string name="notification_channel_error">Errors</string> + <string name="notification_channel_error_description">Mostrar si quelcom va malament, per exemple si una baixada o sincronització fallen.</string> </resources> diff --git a/core/src/main/res/values-cs-rCZ/strings.xml b/core/src/main/res/values-cs-rCZ/strings.xml index f7b1156de..1d9868b2c 100644 --- a/core/src/main/res/values-cs-rCZ/strings.xml +++ b/core/src/main/res/values-cs-rCZ/strings.xml @@ -1,11 +1,13 @@ <?xml version='1.0' encoding='UTF-8'?> <resources xmlns:tools="http://schemas.android.com/tools"> <!--Activitiy and fragment titles--> + <string name="feed_update_receiver_name">Aktualizovat sbÃrky</string> <string name="feeds_label">Kanály</string> <string name="statistics_label">Statistiky</string> <string name="add_feed_label">PÅ™idat podcast</string> <string name="episodes_label">Epizody</string> <string name="all_episodes_short_label">VÅ¡e</string> + <string name="new_episodes_label">Nový</string> <string name="favorite_episodes_label">OblÃbené</string> <string name="new_label">Nový</string> <string name="settings_label">NastavenÃ</string> @@ -18,10 +20,12 @@ <string name="cancel_download_label">ZruÅ¡it stahovánÃ</string> <string name="playback_history_label">Historie pÅ™ehrávánÃ</string> <string name="gpodnet_main_label">gpodder.net</string> + <string name="gpodnet_summary">Synchronizovat s ostatnÃmi pÅ™Ãstroji</string> <string name="gpodnet_auth_label">Login pro gpodder.net</string> <string name="free_space_label">%1$s volné</string> <string name="episode_cache_full_title">Odkládacà prostor pro epizody je plný</string> <string name="episode_cache_full_message">DoÅ¡lo k zaplnÄ›nà limitu odkládacÃho prostoru pro epizody. Můžete navýšit vyhrazený prostor v NastavenÃ.</string> + <string name="synchronizing">Synchronizace...</string> <!--Statistics fragment--> <string name="total_time_listened_to_podcasts">Celkový Äas poslechnutých podcastů:</string> <string name="statistics_details_dialog">%1$d z %2$d zapoÄatých epizod.\n\nPÅ™ehraných %3$s z %4$s.</string> @@ -52,7 +56,7 @@ <string name="no">Ne </string> <string name="reset">Reset</string> - <string name="author_label">Autor</string> + <string name="author_label">PÅ™ispÄ›vatel(é)</string> <string name="language_label">Jazyk</string> <string name="url_label">URL</string> <string name="podcast_settings_label">NastavenÃ</string> @@ -88,6 +92,7 @@ <plurals name="episode_cleanup_days_after_listening"> <item quantity="one">1 den po dokonÄenÃ</item> <item quantity="few">%d dny po dokonÄenÃ</item> + <item quantity="many">%d dnů po dokonÄenÃ</item> <item quantity="other">%d dnů po dokonÄenÃ</item> </plurals> <!--'Add Feed' Activity labels--> @@ -101,23 +106,12 @@ <string name="mark_all_read_label">OznaÄit vÅ¡e jako poslechnuté</string> <string name="mark_all_read_msg">VÅ¡echny epizody oznaÄeny jako poslechnuté</string> <string name="mark_all_read_confirmation_msg">PotvrÄte prosÃm, že chcete oznaÄit vÅ¡echny vybrané epizody jako poslechnuté.</string> - <string name="mark_all_read_feed_confirmation_msg">PotvrÄte prosÃm, že chcete oznaÄit vÅ¡echny epizody z tohoto zdroje jako poslechnuté.</string> <string name="mark_all_seen_label">OznaÄit vÅ¡e jako zobrazené</string> - <string name="mark_all_seen_msg">OznaÄit vÅ¡echny epizody jako shlédnuté</string> <string name="mark_all_seen_confirmation_msg">PotvrÄte prosÃm, že chcete oznaÄit vÅ¡echny epizody jako shlédnuté.</string> <string name="show_info_label">Informace o zdroji</string> - <string name="rename_feed_label">PÅ™ejmenovat podcast</string> - <string name="remove_feed_label">Odstranit podcast</string> <string name="share_label">SdÃlet</string> - <string name="share_link_label">SdÃlet odkaz</string> - <string name="share_link_with_position_label">SdÃlet odkaz s pozicÃ</string> <string name="share_feed_url_label">SdÃlet URL kanálu</string> - <string name="share_item_url_label">SdÃlet URL souboru epizody</string> - <string name="share_item_url_with_position_label">SdÃlet URL souboru epizody s pozicÃ</string> - <string name="feed_remover_msg">Odstranit kanál</string> - <string name="load_complete_feed">Obnovit kompletnà kanál</string> <string name="hide_episodes_title">Skrýt epizody</string> - <string name="episode_actions">Provést akce</string> <string name="hide_unplayed_episodes_label">Neposlechnuté</string> <string name="hide_paused_episodes_label">Pozastavené</string> <string name="hide_played_episodes_label">Poslechnuté</string> @@ -185,6 +179,7 @@ <plurals name="downloads_left"> <item quantity="one">%d ÄekajÃcà na staženÃ</item> <item quantity="few">%d ÄekajÃcà na staženÃ</item> + <item quantity="many">%d ÄekajÃcÃch na staženÃ</item> <item quantity="other">%d ÄekajÃcÃch na staženÃ</item> </plurals> <string name="downloads_processing">ProbÃhá stahovánÃ</string> @@ -228,7 +223,6 @@ <string name="date">Datum</string> <string name="duration">Délka</string> <string name="episode_title">Název epizody</string> - <string name="feed_title">Název kanálu</string> <string name="ascending">VzestupnÄ›</string> <string name="descending">SestupnÄ›</string> <string name="clear_queue_confirmation_msg">PotvrÄte prosÃm, že chcete vyÄistit tuto frontu a VÅ ECHNY v nà obsažené epizody</string> @@ -266,7 +260,6 @@ <string name="enable_sonic">Povolit Sonic</string> <!--Empty list labels--> <string name="no_items_label">Žádné položky v seznamu.</string> - <string name="no_feeds_label">ZatÃm nebyly pÅ™idány žádné kanály.</string> <string name="no_chapters_label">Tato epizoda nemá žádné kapitoly.</string> <string name="no_shownotes_label">Tato epizoda neobsahuje žádné poznámky.</string> <!--Preferences--> @@ -275,14 +268,12 @@ <string name="other_pref">OstatnÃ</string> <string name="about_pref">O aplikaci</string> <string name="queue_label">Fronta</string> - <string name="services_label">Služby</string> <string name="flattr_label">Flattr</string> <string name="pref_episode_cleanup_title">VyÄistit epizody</string> <string name="pref_episode_cleanup_summary">Epizody, které nejsou ve frontÄ› a nejsou oznaÄeny za oblÃbené by mÄ›lo být možné smazat, pokud bude funkce automatického stahovánà potÅ™ebovat mÃsto pro nové epizody</string> <string name="pref_pauseOnDisconnect_sum">PÅ™i odpojenà sluchátek nebo bluetooth pÅ™ipojenà pozastavit pÅ™ehrávánÃ.</string> <string name="pref_unpauseOnHeadsetReconnect_sum">PokraÄovat v pÅ™ehrávánà po pÅ™ipojenà sluchátek</string> <string name="pref_unpauseOnBluetoothReconnect_sum">PokraÄovat v pÅ™ehrávánà po pÅ™ipojenà bluetooth</string> - <string name="pref_hardwareForwardButtonSkips_sum">Po stlaÄenà hardwarového tlaÄÃtka pro posun vpÅ™ed mÃsto pÅ™etoÄenà vpÅ™ed pÅ™eskoÄit na dalÅ¡Ã epizodu</string> <string name="pref_hardwarePreviousButtonRestarts_title">TlaÄÃtko zpÄ›t restartuje</string> <string name="pref_hardwarePreviousButtonRestarts_sum">Po stlaÄenà hardwarového tlaÄÃtka pro posun zpÄ›t mÃsto pÅ™etoÄenà vpÅ™ed restartovat pÅ™ehrávánà aktuálnà epizody</string> <string name="pref_followQueue_sum">Po pÅ™ehránà položky z fronty pÅ™ejÃt automaticky na dalÅ¡Ã</string> @@ -328,7 +319,6 @@ <string name="pref_nav_drawer_feed_order_title">Nastavit poÅ™adà sbÃrek</string> <string name="pref_nav_drawer_feed_order_sum">Upravit poÅ™adà vaÅ¡ich sbÃrek</string> <string name="pref_nav_drawer_feed_counter_title">Nastavit poÄÃtadlo sbÃrek</string> - <string name="pref_nav_drawer_feed_counter_sum">Upravit informaci zobrazovanou poÄÃtadlem sbÃrek</string> <string name="pref_set_theme_sum">ZmÄ›nit vzhled AntennaPod.</string> <string name="pref_automatic_download_title">Automatické stahovánÃ</string> <string name="pref_automatic_download_sum">Nastavenà automatického stahovánà epizod.</string> @@ -364,8 +354,6 @@ <string name="pref_playback_speed_sum">PÅ™izpůsobenà rychlosti je dostupné pro pÅ™ehrávánà zvuku různými rychlostmi</string> <string name="pref_gpodnet_sethostname_title">Nastavit hostname</string> <string name="pref_gpodnet_sethostname_use_default_host">PoužÃt pÅ™ednastaveného hosta</string> - <string name="pref_expandNotify_title">RozÅ¡ÃÅ™ené upozornÄ›nÃ</string> - <string name="pref_expandNotify_sum">Vždy zobrazovat tlaÄÃtka pro pÅ™ehrávánà v upozornÄ›nÃ.</string> <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> @@ -386,7 +374,6 @@ <string name="crash_report_sum">OdesÃlat hlášenà o poslednÃm pádu aplikace emailem</string> <string name="send_email">Poslat email</string> <string name="experimental_pref">ExperimentálnÃ</string> - <string name="pref_sonic_message">PoužÃt pÅ™ipojený sonic media player jako náhradu za výchozà pÅ™ehrávaÄ médià pro Android a Prestissimo</string> <string name="pref_current_value">Aktuálnà hodnota: %1$s</string> <string name="pref_proxy_title">Proxy</string> <string name="pref_proxy_sum">Nastavit sÃÅ¥ovou proxy</string> @@ -430,8 +417,6 @@ <string name="html_export_label">HTML export</string> <string name="exporting_label">Export</string> <string name="export_error_label">Chyba exportu</string> - <string name="opml_export_success_title">OPML export byl úspěšný.</string> - <string name="opml_export_success_sum">OPML soubor byl zapsán do:\u0020</string> <string name="opml_import_ask_read_permission">Pro pÅ™eÄtenà OPML souboru je vyžadován pÅ™Ãstup k externÃmu úložiÅ¡ti</string> <!--Sleep timer--> <string name="set_sleeptimer_label">Nastavit ÄasovaÄ vypnutÃ</string> @@ -449,16 +434,19 @@ <plurals name="time_seconds_quantified"> <item quantity="one">1 sekunda</item> <item quantity="few">%d sekundy</item> + <item quantity="many">%d sekund</item> <item quantity="other">%d sekund</item> </plurals> <plurals name="time_minutes_quantified"> <item quantity="one">1 minuta</item> <item quantity="few">%d minuty</item> + <item quantity="many">%d minut</item> <item quantity="other">%d minut</item> </plurals> <plurals name="time_hours_quantified"> <item quantity="one">1 hodina</item> <item quantity="few">%d hodiny</item> + <item quantity="many">%d hodin</item> <item quantity="other">%d hodin</item> </plurals> <string name="auto_enable_label">Automaticky zapnout</string> @@ -618,4 +606,5 @@ <string name="cast_failed_seek">Selhal posun na novou pozici na vysÃlaÄi</string> <string name="cast_failed_receiver_player_error">PÅ™ijÃmaÄ zaznamenal závažnou chybu</string> <string name="cast_failed_media_error_skipping">Chyba pÅ™ehrávánà médiÃ. PÅ™eskakuji...</string> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-da/strings.xml b/core/src/main/res/values-da/strings.xml index 6364ef099..a094cdacf 100644 --- a/core/src/main/res/values-da/strings.xml +++ b/core/src/main/res/values-da/strings.xml @@ -56,7 +56,6 @@ <string name="yes">Ja</string> <string name="no">Nej</string> <string name="reset">Nulstil</string> - <string name="author_label">Forfatter</string> <string name="language_label">Sprog</string> <string name="url_label">Webadresse</string> <string name="podcast_settings_label">Indstillinger </string> @@ -105,25 +104,13 @@ <string name="mark_all_read_label">Marker alle som afspillet</string> <string name="mark_all_read_msg">Marker alle udsendelser som afspillet</string> <string name="mark_all_read_confirmation_msg">Bekræft venligst at du ønsker at markere alle udsendelser som værende afspillet.</string> - <string name="mark_all_read_feed_confirmation_msg">Bekræft venligst at du ønsker at markere alle udsendelser i denne feed som værende afspillet.</string> <string name="mark_all_seen_label">Marker alle som set</string> - <string name="mark_all_seen_msg">Markerede alle udsendelser som set</string> <string name="mark_all_seen_confirmation_msg">Bekræft venligst at du ønsker at markere alle udsendelser som set.</string> <string name="show_info_label">Vis information</string> - <string name="rename_feed_label">Omdøb podcast</string> - <string name="remove_feed_label">Fjern podcast</string> <string name="share_label">Del…</string> - <string name="share_link_label">Del link</string> <string name="share_file_label">Del fil</string> - <string name="share_link_with_position_label">Del link med position</string> <string name="share_feed_url_label">Del webadresse for feedet</string> - <string name="share_item_url_label">Del webadresse for udsendelsen</string> - <string name="share_item_url_with_position_label">Del webadresse for udsendelsen med position</string> - <string name="feed_delete_confirmation_msg">Bekræft venligst at du ønsker at slette feedet \"%1$s\" og ALLE overførte udsendelser i dette feed.</string> - <string name="feed_remover_msg">Fjerner feed</string> - <string name="load_complete_feed">Opdater hele feedet</string> <string name="hide_episodes_title">Skjul udsendelser</string> - <string name="episode_actions">Anvend handlinger</string> <string name="hide_unplayed_episodes_label">Uafspillede</string> <string name="hide_paused_episodes_label">Sat pÃ¥ pause</string> <string name="hide_played_episodes_label">Afspillede</string> @@ -234,7 +221,6 @@ <string name="date">Dato</string> <string name="duration">Varighed</string> <string name="episode_title">Titel pÃ¥ udsendelse</string> - <string name="feed_title">Titel pÃ¥ feed</string> <string name="ascending">Stigende</string> <string name="descending">Faldende</string> <string name="clear_queue_confirmation_msg">Bekræft venligst at du vil rydde ALLE udsendelser fra køen</string> @@ -272,7 +258,6 @@ <string name="enable_sonic">SlÃ¥ Sonic til</string> <!--Empty list labels--> <string name="no_items_label">Der er ingen elementer i denne liste.</string> - <string name="no_feeds_label">Du har endnu ikke abonneret pÃ¥ nogen feeds.</string> <string name="no_chapters_label">Denne udsendelse har ingen kapitler.</string> <string name="no_shownotes_label">Denne udsendelse har ingen beskrivelse.</string> <!--Preferences--> @@ -281,7 +266,6 @@ <string name="other_pref">Andre</string> <string name="about_pref">Om</string> <string name="queue_label">Kø</string> - <string name="services_label">Tjenester</string> <string name="flattr_label">Flattr</string> <string name="pref_episode_cleanup_title">Oprydning i udsendelser</string> <string name="pref_episode_cleanup_summary">Tillad at udsendelser, som ikke er i køen og som ikke er markeret som foretrukne, kan fjernes, hvis Automatisk overførsel har brug for plads til nye udsendelser</string> @@ -289,7 +273,6 @@ <string name="pref_unpauseOnHeadsetReconnect_sum">Genoptag afspilning nÃ¥r hovedtelefonerne tilsluttes igen</string> <string name="pref_unpauseOnBluetoothReconnect_sum">Genoptag afspilning nÃ¥r bluetooth forbinder igen</string> <string name="pref_hardwareForwardButtonSkips_title">Fremadknap springer over</string> - <string name="pref_hardwareForwardButtonSkips_sum">NÃ¥r der trykkes pÃ¥ en fysisk fremadknap, skal der springes til den næste udsendelse i stedet for at spoles fremad.</string> <string name="pref_hardwarePreviousButtonRestarts_title">Tilbageknap genstarter</string> <string name="pref_hardwarePreviousButtonRestarts_sum">NÃ¥r der trykkes pÃ¥ en fysisk tilbageknap, skal den aktuelle udsendelse afspilles forfra i stedet for at der spoles tilbage.</string> <string name="pref_followQueue_sum">Spring til næste element i køen nÃ¥r afspilningen er færdig</string> @@ -338,7 +321,6 @@ <string name="pref_nav_drawer_feed_order_title">Vælg abonnementsorden</string> <string name="pref_nav_drawer_feed_order_sum">Ændr rækkefølgen af dine abonnementer</string> <string name="pref_nav_drawer_feed_counter_title">Indstil abonnementstæller</string> - <string name="pref_nav_drawer_feed_counter_sum">Vælg den information, som abonnementstælleren viser</string> <string name="pref_set_theme_sum">Ændr AntennaPods udseende.</string> <string name="pref_automatic_download_title">Automatisk overførsel</string> <string name="pref_automatic_download_sum">Konfigurer automatisk overførsel af udsendelser</string> @@ -380,8 +362,6 @@ <string name="pref_rewind_sum">Indstil antallet af sekunder, der skal springes tilbage, nÃ¥r der trykkes pÃ¥ tilbagespolingsknappen</string> <string name="pref_gpodnet_sethostname_title">Indstil værtsnavn</string> <string name="pref_gpodnet_sethostname_use_default_host">Brug standard vært</string> - <string name="pref_expandNotify_title">Udvidelse af notifikation</string> - <string name="pref_expandNotify_sum">Udvid altid notifikationen for at vise afspilningsknapper.</string> <string name="pref_persistNotify_title">Vedholdende afspilningsknapper</string> <string name="pref_persistNotify_sum">Behold notifikation og knapper pÃ¥ lÃ¥seskærmen, nÃ¥r afspilningen sættes pÃ¥ pause.</string> <string name="pref_compact_notification_buttons_title">Indstil knapper pÃ¥ lÃ¥seskærm</string> @@ -402,8 +382,6 @@ <string name="crash_report_sum">Send den seneste nedbrudsrapport via e-mail</string> <string name="send_email">Send e-mail</string> <string name="experimental_pref">Eksperimentelt</string> - <string name="pref_sonic_title">Sonic-medieafspiller</string> - <string name="pref_sonic_message">Brug indbygget Sonic-medieafspiller i stedet for Androids indbyggede medieafspiller og Prestissimo</string> <string name="pref_current_value">Nuværende værdi: %1$s</string> <string name="pref_proxy_title">Proxy</string> <string name="pref_proxy_sum">Indstil en netværksproxy</string> @@ -424,8 +402,6 @@ <string name="search_hint">Søg efter udsendelser</string> <string name="found_in_shownotes_label">Fundet i beskrivelse</string> <string name="found_in_chapters_label">Fundet i kapitler</string> - <string name="found_in_authors_label">Fundet i forfattere</string> - <string name="found_in_feeds_label">Fundet i feeds</string> <string name="search_status_no_results">Fandt ingen resultater</string> <string name="search_label">Søg</string> <string name="found_in_title_label">Fundet i titel</string> @@ -451,8 +427,6 @@ <string name="html_export_label">HTML-eksport</string> <string name="exporting_label">Eksporterer…</string> <string name="export_error_label">Eksportfejl</string> - <string name="opml_export_success_title">OPML-eksport lykkedes.</string> - <string name="opml_export_success_sum">.opml-filen blev skrevet til:\u0020</string> <string name="opml_import_ask_read_permission">Adgang til eksternt lager er pÃ¥krævet for at læse OPML-filen</string> <!--Sleep timer--> <string name="set_sleeptimer_label">Indstil søvntimer</string> @@ -637,4 +611,5 @@ <string name="cast_failed_seek">Det lykkedes ikke at søge til den nye position pÃ¥ cast-enheden</string> <string name="cast_failed_receiver_player_error">Modtagerafspilleren er stødt pÃ¥ en alvorlig fejl</string> <string name="cast_failed_media_error_skipping">Fejl ved afspilning af medie. Springer over…</string> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-de/strings.xml b/core/src/main/res/values-de/strings.xml index c1faf9b5b..3c736f1b0 100644 --- a/core/src/main/res/values-de/strings.xml +++ b/core/src/main/res/values-de/strings.xml @@ -1,11 +1,13 @@ <?xml version='1.0' encoding='UTF-8'?> <resources xmlns:tools="http://schemas.android.com/tools"> <!--Activitiy and fragment titles--> + <string name="feed_update_receiver_name">Abonnements aktualisieren</string> <string name="feeds_label">Feeds</string> <string name="statistics_label">Statistiken</string> <string name="add_feed_label">Podcast hinzufügen</string> <string name="episodes_label">Episoden</string> <string name="all_episodes_short_label">Alle</string> + <string name="new_episodes_label">Neu</string> <string name="favorite_episodes_label">Favoriten</string> <string name="new_label">Neu</string> <string name="settings_label">Einstellungen</string> @@ -18,10 +20,12 @@ <string name="cancel_download_label">Download abbrechen</string> <string name="playback_history_label">Zuletzt gespielt</string> <string name="gpodnet_main_label">gpodder.net</string> + <string name="gpodnet_summary">Mit anderen Geräten synchronisieren</string> <string name="gpodnet_auth_label">gpodder.net Anmeldung</string> <string name="free_space_label">%1$s frei</string> <string name="episode_cache_full_title">Episodenspeicher voll</string> <string name="episode_cache_full_message">Der Episodenspeicher ist voll. Du kannst die Größe des Episodenspeichers in den Einstellungen erhöhen.</string> + <string name="synchronizing">Synchronisiere...</string> <!--Statistics fragment--> <string name="total_time_listened_to_podcasts">Gesamtzeit gespielter Podcasts:</string> <string name="statistics_details_dialog">%1$d von %2$d Episoden gestartet.\n\n%3$s von %4$s Episoden gespielt.</string> @@ -56,15 +60,16 @@ <string name="yes">Ja</string> <string name="no">Nein</string> <string name="reset">Reset</string> - <string name="author_label">Autor</string> + <string name="author_label">Autor(en)</string> <string name="language_label">Sprache</string> <string name="url_label">URL</string> <string name="podcast_settings_label">Einstellungen</string> <string name="cover_label">Bild</string> <string name="error_label">Fehler</string> <string name="error_msg_prefix">Ein Fehler ist aufgetreten:</string> + <string name="needs_storage_permission">Für diese Funktion wird die Speicher-Berechtigung benötigt</string> <string name="refresh_label">Aktualisieren</string> - <string name="external_storage_error_msg">Der externe Speicher ist nicht verfügbar. Bitte stelle sicher, dass das externe Speichermedium eingelegt ist, damit die Anwendung funktioniert.</string> + <string name="external_storage_error_msg">Der externe Speicher ist nicht verfügbar. Bitte stelle sicher, dass das externe Speichermedium eingelegt ist, damit die App funktioniert.</string> <string name="chapters_label">Kapitel</string> <string name="chapter_duration">Dauer: %1$s</string> <string name="shownotes_label">Shownotizen</string> @@ -110,20 +115,23 @@ <string name="mark_all_seen_msg">Alle Episoden als gesehen markiert</string> <string name="mark_all_seen_confirmation_msg">Bitte bestätige, dass alle Episoden als gesehen markiert werden sollen.</string> <string name="show_info_label">Informationen anzeigen</string> - <string name="rename_feed_label">Podcast umbenennen</string> + <string name="show_feed_settings_label">Zeige Feed-Einstellungen</string> + <string name="feed_info_label">Feed-Informationen</string> + <string name="feed_settings_label">Feed-Einstellungen</string> + <string name="rename_feed_label">Feed umbenennen</string> <string name="remove_feed_label">Podcast entfernen</string> <string name="share_label">Teilen…</string> - <string name="share_link_label">Teile Link</string> - <string name="share_file_label">Teile Datei</string> + <string name="share_link_label">Episoden URL Teilen</string> <string name="share_link_with_position_label">Teile Link mit Zeitmarke</string> + <string name="share_file_label">Teile Datei</string> <string name="share_feed_url_label">Teile URL des Podcasts</string> - <string name="share_item_url_label">Teile URL der Episode</string> - <string name="share_item_url_with_position_label">Teile URL der Episode mit Zeitmarke</string> - <string name="feed_delete_confirmation_msg">Bitte bestätige, dass du den Feed \"%1$s\" und ALLE heruntergeladenen Episoden löschen möchtest.</string> - <string name="feed_remover_msg">Entferne Feed</string> + <string name="share_item_url_label">Teile URL der Episodendatei</string> + <string name="share_item_url_with_position_label">Teile URL der Episodendatei mit Zeitmarke</string> + <string name="feed_delete_confirmation_msg">Bitte bestätige, dass du den Podcast \"%1$s\" und ALLE heruntergeladenen Episoden dieses Feeds entfernen möchtest.</string> + <string name="feed_remover_msg">Entferne Podcast</string> <string name="load_complete_feed">Kompletten Feed aktualisieren</string> <string name="hide_episodes_title">Episoden verbergen</string> - <string name="episode_actions">Aktionen anwenden</string> + <string name="batch_edit">Stapelbearbeitung</string> <string name="hide_unplayed_episodes_label">Ungespielt</string> <string name="hide_paused_episodes_label">Pausiert</string> <string name="hide_played_episodes_label">Gespielt</string> @@ -132,6 +140,7 @@ <string name="hide_downloaded_episodes_label">Heruntergeladen</string> <string name="hide_not_downloaded_episodes_label">Nicht heruntergeladen</string> <string name="hide_has_media_label">Hat Medien</string> + <string name="hide_is_favorite_label">Favorit</string> <string name="filtered_label">Gefiltert</string> <string name="refresh_failed_msg">{fa-exclamation-circle} Aktualisierung fehlgeschlagen</string> <string name="open_podcast">Podcast öffnen</string> @@ -145,6 +154,7 @@ <string name="delete_label">Löschen</string> <string name="delete_failed">Die Datei kann nicht gelöscht werden. Eventuell hilft es, das Gerät neu zu starten.</string> <string name="remove_episode_lable">Episode entfernen</string> + <string name="mark_as_seen_label">Als gelesen markieren</string> <string name="marked_as_seen_label">Als gesehen markiert</string> <string name="mark_read_label">Als gespielt markieren</string> <string name="marked_as_read_label">Als gespielt markiert</string> @@ -168,6 +178,8 @@ <string name="download_failed">fehlgeschlagen</string> <string name="download_pending">Download anstehend</string> <string name="download_running">Download läuft</string> + <string name="download_error_details">Details</string> + <string name="download_error_details_message">%1$s \n\nDatei-URL:\n%2$s</string> <string name="download_error_device_not_found">Speichermedium nicht gefunden</string> <string name="download_error_insufficient_space">Zu wenig Speicherplatz</string> <string name="download_error_file_error">Dateifehler</string> @@ -218,6 +230,7 @@ <string name="playback_error_unknown">Unbekannter Fehler</string> <string name="no_media_playing_label">Keine Medienwiedergabe</string> <string name="player_buffering_msg">Puffert</string> + <string name="player_go_to_picture_in_picture">Bild-in-Bild-Modus</string> <string name="playbackservice_notification_title">Spiele Podcast ab</string> <string name="unknown_media_key">AntennaPod - Unbekannte Medientaste: %1$d</string> <!--Queue operations--> @@ -234,7 +247,9 @@ <string name="date">Datum</string> <string name="duration">Dauer</string> <string name="episode_title">Episodentitel</string> - <string name="feed_title">Podcastname</string> + <string name="feed_title">Feedname</string> + <string name="random">Zufällig</string> + <string name="smart_shuffle">Schlaues Mischen</string> <string name="ascending">Aufsteigend</string> <string name="descending">Absteigend</string> <string name="clear_queue_confirmation_msg">Bitte bestätige, dass ALLE Episoden aus der Abspielliste entfernt werden sollen</string> @@ -281,15 +296,23 @@ <string name="other_pref">Anderes</string> <string name="about_pref">Ãœber</string> <string name="queue_label">Abspielliste</string> - <string name="services_label">Dienste</string> + <string name="integrations_label">Einbindungen</string> <string name="flattr_label">Flattr</string> + <string name="flattr_summary">Micropayment-Dienst</string> + <string name="automation">Automatisierung</string> + <string name="download_pref_details">Details</string> + <string name="import_export_pref">Import/Export</string> + <string name="appearance">Erscheinungsbild</string> + <string name="external_elements">Externe Elemente</string> + <string name="interruptions">Unterbrechungen</string> + <string name="buttons">Buttons zur Steuerung der Wiedergabe</string> + <string name="media_player">Medienabspieler</string> <string name="pref_episode_cleanup_title">Automatisches Löschen</string> <string name="pref_episode_cleanup_summary">Episoden, die weder in der Abspielliste noch Favoriten sind, können gelöscht werden, wenn beim automatischen Herunterladen Speicherplatz für neue Episoden gebraucht wird</string> <string name="pref_pauseOnDisconnect_sum">Wiedergabe pausieren, wenn Kopfhörer ausgesteckt oder Bluetooth getrennt wird</string> <string name="pref_unpauseOnHeadsetReconnect_sum">Wiedergabe fortsetzen, wenn Kopfhörer wieder eingesteckt werden</string> <string name="pref_unpauseOnBluetoothReconnect_sum">Wiedergabe fortsetzen, wenn Bluetooth wieder verbunden ist</string> <string name="pref_hardwareForwardButtonSkips_title">\"Nächster\"-Taste springt zur nächsten Episode</string> - <string name="pref_hardwareForwardButtonSkips_sum">Zur nächsten Episode springen, wenn die \"Nächster\"-Taste gedrückt wird (statt vorzuspulen)</string> <string name="pref_hardwarePreviousButtonRestarts_title">Vorheriger-Taste startet neu</string> <string name="pref_hardwarePreviousButtonRestarts_sum">Die Wiedergabe der aktuellen Episode neu starten, wenn die \"Vorheriger\"-Taste gedrückt wird (statt zurückzuspulen)</string> <string name="pref_followQueue_sum">Springe zur nächsten Episode in der Abspielliste, wenn die Wiedergabe endet</string> @@ -338,7 +361,7 @@ <string name="pref_nav_drawer_feed_order_title">Reihenfolge der Abonnements einstellen</string> <string name="pref_nav_drawer_feed_order_sum">Ändere die Reihenfolge deiner Abonnements</string> <string name="pref_nav_drawer_feed_counter_title">Abonnement-Zähler einstellen</string> - <string name="pref_nav_drawer_feed_counter_sum">Ändere, welche Information der Abonnement-Zähler anzeigt</string> + <string name="pref_nav_drawer_feed_counter_sum">Ändere die durch den Abonnementszähler angezeigten Informationen. Betrifft auch die Sortierung der Abonnements wenn \"Reihenfolge der Abonnements\" auf \"Zähler\" gesetzt ist.</string> <string name="pref_set_theme_sum">Ändere das Aussehen von AntennaPod.</string> <string name="pref_automatic_download_title">Automatisches Herunterladen</string> <string name="pref_automatic_download_sum">Konfiguriere das automatische Herunterladen von Episoden.</string> @@ -352,6 +375,7 @@ <string name="pref_episode_cache_title">Episodenspeicher</string> <string name="pref_theme_title_light">Hell</string> <string name="pref_theme_title_dark">Dunkel</string> + <string name="pref_theme_title_trueblack">Schwarz (für AMOLED)</string> <string name="pref_episode_cache_unlimited">Unbegrenzt</string> <string name="pref_update_interval_hours_plural">Stunden</string> <string name="pref_update_interval_hours_singular">Stunde</string> @@ -380,8 +404,6 @@ <string name="pref_rewind_sum">Passe an, wie viele Sekunden zurückgespult wird, wenn die entsprechende Hardware-Taste gedrückt wird</string> <string name="pref_gpodnet_sethostname_title">Hostname ändern</string> <string name="pref_gpodnet_sethostname_use_default_host">Standard-Host verwenden</string> - <string name="pref_expandNotify_title">Benachrichtigung erweitern</string> - <string name="pref_expandNotify_sum">Erweiterte Wiedergabebenachrichtigung mit Abspiel-, Pause- und Stop-Knöpfen anzeigen.</string> <string name="pref_persistNotify_title">Persistente Wiedergabesteuerung</string> <string name="pref_persistNotify_sum">Zeige Wiedergabebedienelemente in der Benachrichtigung und im Lockscreen an, während die Wiedergabe pausiert ist.</string> <string name="pref_compact_notification_buttons_title">Lockscreen-Wiedergabetasten festlegen</string> @@ -402,8 +424,7 @@ <string name="crash_report_sum">Sende den aktuellen Absturzbericht per E-Mail</string> <string name="send_email">E-Mail senden</string> <string name="experimental_pref">Experimentell</string> - <string name="pref_sonic_title">Sonic Media Player</string> - <string name="pref_sonic_message">Benutze den integrierten Sonic Mediaplayer als Ersatz für Androids eigenen Mediaplayer und Prestissimo</string> + <string name="pref_media_player_message">Wähle, welcher Medienabspieler benutzt werden soll, um Dateien abzuspielen</string> <string name="pref_current_value">Aktueller Wert: %1$s</string> <string name="pref_proxy_title">Proxy</string> <string name="pref_proxy_sum">Richte einen Netzwerk-Proxy ein</string> @@ -415,6 +436,11 @@ <string name="pref_cast_message_free_flavor">Chromecast benötigt proprietäre Bibliotheken von Drittanbietern, die in dieser Version von AntennaPod deaktiviert sind</string> <string name="pref_enqueue_downloaded_title">Downloads einreihen</string> <string name="pref_enqueue_downloaded_summary">Füge heruntergeladene Episoden zur Abspielliste hinzu</string> + <string name="media_player_builtin">Androids eingebauter Abspieler</string> + <string name="pref_videoBehavior_title">Beim Beenden des Videos</string> + <string name="pref_videoBehavior_sum">Verhalten beim Verlassen der Video-Wiedergabe</string> + <string name="stop_playback">Wiedergabe anhalten</string> + <string name="continue_playback">Audiowiedergabe fortsetzen</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> @@ -424,8 +450,8 @@ <string name="search_hint">Suche nach Episoden</string> <string name="found_in_shownotes_label">In Shownotizen gefunden</string> <string name="found_in_chapters_label">In Kapiteln gefunden</string> - <string name="found_in_authors_label">In Autoren gefunden</string> - <string name="found_in_feeds_label">In Feeds gefunden</string> + <string name="found_in_authors_label">Gefunden in Autor(en)</string> + <string name="found_in_feeds_label">Gefunden in Podcast</string> <string name="search_status_no_results">Keine Ergebnisse gefunden</string> <string name="search_label">Suchen</string> <string name="found_in_title_label">In Titel gefunden</string> @@ -451,8 +477,8 @@ <string name="html_export_label">HTML Export</string> <string name="exporting_label">Exportiere…</string> <string name="export_error_label">Exportfehler</string> - <string name="opml_export_success_title">OPML Export erfolgreich</string> - <string name="opml_export_success_sum">Die OPML Datei wurde unter dem folgenden Pfad gespeichert:\u0020</string> + <string name="export_success_title">Export erfolgreich</string> + <string name="export_success_sum">Die exportierte Datei wurde geschrieben nach:\n\n%1$s</string> <string name="opml_import_ask_read_permission">Zugriff auf externen Speicher wird benötigt, um die OPML Datei zu lesen</string> <!--Sleep timer--> <string name="set_sleeptimer_label">Timer einstellen</string> @@ -625,7 +651,7 @@ <string name="label_import">Import</string> <string name="label_export">Export</string> <string name="import_select_file">Zu importierende Datei auswählen</string> - <string name="export_ok">Export erfolgreich. Die Datenbank wurde auf die SD-Karte geschrieben.</string> + <string name="export_ok">Export erfolgreich.</string> <string name="import_ok">Import erfolgreich.\n\nBitte OK drücken, um AntennaPod neuzustarten</string> <!--Casting--> <string name="cast_media_route_menu_title">Abspielen auf...</string> @@ -643,4 +669,13 @@ <string name="cast_failed_seek">Spulen zur neuen Position fehlgeschlagen</string> <string name="cast_failed_receiver_player_error">Es wurde ein schwerer Fehler beim Empfangsgerät festgestellt</string> <string name="cast_failed_media_error_skipping">Fehler bei Wiedergabe. Ãœberspringe...</string> + <!--Notification channels--> + <string name="notification_channel_user_action">Handlung notwendig</string> + <string name="notification_channel_user_action_description">Wird gezeigt, wenn deine Handlung notwendig ist, zum Beispiel wenn du ein Passwort eingeben musst.</string> + <string name="notification_channel_downloading">Lädt herunter</string> + <string name="notification_channel_downloading_description">Wird gezeigt beim Herunterladen.</string> + <string name="notification_channel_playing">Jetzt spielt</string> + <string name="notification_channel_playing_description">Erlaubt es, die Wiedergabe zu steuern. Dies ist die Hauptbenachrichtigung, die du siehst, während ein Podcast abgespielt wird.</string> + <string name="notification_channel_error">Fehler</string> + <string name="notification_channel_error_description">Wird gezeigt, wenn etwas schief gegangen ist, etwa wenn das Herunterladen oder die gpodder-Synchronisierung fehlschlägt.</string> </resources> diff --git a/core/src/main/res/values-el/strings.xml b/core/src/main/res/values-el/strings.xml index 152e73426..f72115bb2 100644 --- a/core/src/main/res/values-el/strings.xml +++ b/core/src/main/res/values-el/strings.xml @@ -1,16 +1,18 @@ <?xml version='1.0' encoding='UTF-8'?> <resources xmlns:tools="http://schemas.android.com/tools"> <!--Activitiy and fragment titles--> + <string name="feed_update_receiver_name">ΑνανÎωση ΣυνδÏομών</string> <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="new_episodes_label">ÎÎα</string> <string name="favorite_episodes_label">ΑγαπημÎνα</string> <string name="new_label">ÎÎα</string> <string name="settings_label">Ρυθμίσεις</string> <string name="downloads_label">Λήψεις</string> - <string name="downloads_running_label">ΕκτÎλεση</string> + <string name="downloads_running_label">ΕκτÎλείται</string> <string name="downloads_completed_label">ΟλοκληÏώθηκε</string> <string name="downloads_log_label">Είσοδος</string> <string name="subscriptions_label">ΣυνδÏομÎÏ‚</string> @@ -18,55 +20,71 @@ <string name="cancel_download_label">ΑκÏÏωση\nΛήψης</string> <string name="playback_history_label">ΙστοÏικό ΑναπαÏαγωγής</string> <string name="gpodnet_main_label">gpodder.net</string> + <string name="gpodnet_summary">ΣυγχÏονισμός με άλλες συσκευÎÏ‚</string> <string name="gpodnet_auth_label">gpodder.net ΣÏνδεση</string> + <string name="synchronizing">Εκτελείται συγχÏονισμός</string> <!--Statistics fragment--> + <string name="total_time_listened_to_podcasts">Συνολικός χÏόνος εκτελεσμÎνων podcasts:</string> <!--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> + <string name="drawer_feed_order_most_played">Ταξινόμηση κατά αÏιθμό εκτελεσμÎνων επεισοδίων</string> + <string name="drawer_feed_counter_new_unplayed">ΑÏιθμός νÎων επεισοδίων και αÏιθμός μη εκτελεσμÎνων επεισοδίων</string> <string name="drawer_feed_counter_new">ΑÏιθμός νÎων επεισοδίων</string> + <string name="drawer_feed_counter_unplayed">ΑÏιθμός μη εκτελεσμÎνων επεισοδίων</string> + <string name="drawer_feed_counter_downloaded">ΑÏιθμός ληφθÎντων επεισοδίων</string> + <string name="drawer_feed_counter_none">Κενό</string> <!--Webview actions--> <string name="open_in_browser_label">Άνοιγμα στον ΠεÏιηγητή</string> <string name="copy_url_label">ΑντιγÏαφή διεÏθυνσης URL</string> - <string name="share_url_label">ΜοιÏασμα URL</string> + <string name="share_url_label">ΜοίÏασμα URL</string> <string name="copied_url_msg">ΑντιγÏαφή URL στο Î ÏόχειÏο</string> + <string name="go_to_position_label">Μετάβαση σε αυτή τη θÎση</string> <!--Playback history--> <string name="clear_history_label">ΕκκαθάÏιση ΙστοÏικοÏ</string> <!--Other--> <string name="confirm_label">Επιβεβαίωση</string> <string name="cancel_label">ΑκÏÏωση</string> - <string name="author_label">ΔημιουÏγος</string> - <string name="language_label">Γλωσσα</string> - <string name="podcast_settings_label">Ρυθμισεις</string> - <string name="cover_label">Εικονα</string> - <string name="error_label">Σφαλμα</string> + <string name="yes">Îαι</string> + <string name="no">Όχι</string> + <string name="language_label">Γλώσσα</string> + <string name="url_label">URL</string> + <string name="podcast_settings_label">Ρυθμίσεις</string> + <string name="cover_label">Εικόνα</string> + <string name="error_label">Σφάλμα</string> <string name="error_msg_prefix">ΠαÏουσιάστηκε Îνα σφάλμα:</string> <string name="refresh_label">ΑνανÎωση</string> <string name="external_storage_error_msg">Καμία εξωτεÏική αποθήκευση είναι διαθÎσιμη. ΠαÏακαλώ βεβαιωθείτε ότι η εξωτεÏική αποθήκευση Îχει τοποθετηθεί Îτσι ώστε η εφαÏμογή να μποÏεί να λειτουÏγήσει σωστά.</string> <string name="chapters_label">Κεφάλαια</string> + <string name="chapter_duration">ΔιάÏκεια: %1$s</string> <string name="shownotes_label">Εμφάνιση Σημειώσεων</string> <string name="description_label">ΠεÏιγÏαφή</string> - <string name="episodes_suffix">\u0020επεισοδια</string> + <string name="most_recent_prefix">Πιο Ï€Ïόσφατο επεισόδιο:\u0020</string> + <string name="episodes_suffix">\u0020επεισόδια</string> <string name="length_prefix">Μήκος:\u0020</string> <string name="size_prefix">ÎœÎγεθος:\u0020</string> <string name="processing_label">ΕπεξεÏγασία</string> - <string name="save_username_password_label">Αποθήκευση του όνοματος χÏήστη και του κωδικόυ Ï€Ïόσβασης</string> + <string name="save_username_password_label">Αποθήκευση του ονόματος χÏήστη και του ÎºÏ‰Î´Î¹ÎºÎ¿Ï Ï€Ïόσβασης</string> <string name="close_label">Κλείσιμο</string> - <string name="retry_label">Επανάληψη</string> + <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_always">Πάντα</string> <string name="feed_auto_download_never">ΠοτÎ</string> + <string name="send_label">Αποστολή...</string> <string name="episode_cleanup_never">ΠοτÎ</string> <!--'Add Feed' Activity labels--> <string name="feedurl_label">URL της Ροής</string> <string name="etxtFeedurlHint">www.example.com/feed</string> <string name="txtvfeedurl_label">Î Ïοσθήκη Podcast με τη διεÏθυνση URL</string> + <string name="podcastdirectories_label">ΕÏÏεση Podcast στο Φάκελο</string> <string name="browse_gpoddernet_label">ΠεÏιήγηση στο gpodder.net</string> <!--Actions on feeds--> <string name="show_info_label">Εμφάνιση πληÏοφοÏιών</string> - <string name="remove_feed_label">ΚατάÏγηση Podcast</string> <string name="hide_episodes_title">ΑπόκÏυψη Επεισοδίων</string> <string name="hide_downloaded_episodes_label">ΕιλημμÎνα</string> <string name="refresh_failed_msg">{fa-exclamation-circle} Η Τελευταία ΑνανÎωση ΑπÎτυχε</string> @@ -175,12 +193,10 @@ <string name="set_playback_speed_label">ΤαχÏτητες αναπαÏαγωγής</string> <!--Empty list labels--> <string name="no_items_label">Δεν υπάÏχουν στοιχεία σε αυτή τη λίστα.</string> - <string name="no_feeds_label">Δεν Îχετε εγγÏαφεί σε οποιεσδήποτε Ï„Ïοφοδοσίες ακόμα</string> <!--Preferences--> <string name="other_pref">Άλλα</string> <string name="about_pref">Σχετικά με</string> <string name="queue_label">ΣειÏά αναμονής</string> - <string name="services_label">ΥπηÏεσίες</string> <string name="flattr_label">Flattr</string> <string name="pref_unpauseOnHeadsetReconnect_sum">ΣυνÎχιση της αναπαÏαγωγής, όταν τα ακουστικά επανασυνδÎονται</string> <string name="pref_followQueue_sum">Μετάβαση στο επόμενο στοιχείο σειÏάς αναμονής όταν η αναπαÏαγωγή ολοκληÏωθεί</string> @@ -223,8 +239,6 @@ <string name="pref_playback_speed_sum">Î ÏοσαÏμόστε τις διαθÎσιμες ταχÏτητες για αναπαÏαγωγή ήχου μεταβλητής ταχÏτητας</string> <string name="pref_gpodnet_sethostname_title">ΟÏισμός κεντÏÎ¹ÎºÎ¿Ï Ï…Ï€Î¿Î»Î¿Î³Î¹ÏƒÏ„Î®</string> <string name="pref_gpodnet_sethostname_use_default_host">ΧÏήση Ï€ÏοεπιλεγμÎνης υποδοχής</string> - <string name="pref_expandNotify_title">Ανάπτυξη κοινοποίησης</string> - <string name="pref_expandNotify_sum">Πάντα επÎκταση της ειδοποίησης για εμφανιση κουμπιων αναπαÏαγωγής.</string> <string name="pref_persistNotify_sum">ΔιατηÏηση των ελÎγχων κοινοποίησης και lockscreen όταν γίνεται παÏση της αναπαÏαγωγής.</string> <string name="pref_expand_notify_unsupport_toast">Εκδόσεις του Android Ï€Ïιν από το 4.1 δεν υποστηÏίζουν εκτεταμÎνες κοινοποιήσεις.</string> <string name="pref_queueAddToFront_sum">Î Ïοσθήκη νÎων επεισοδίων στο μπÏοστινό μÎÏος της ουÏάς.</string> @@ -255,8 +269,6 @@ <string name="choose_file_from_external_application">ΧÏησιμοποιήστε εξωτεÏική εφαÏμογή</string> <string name="opml_export_label">OPML εξαγωγή</string> <string name="export_error_label">Σφάλμα κατά την εξαγωγή</string> - <string name="opml_export_success_title">Η Εξαγωγή OPML είναι επιτυχής</string> - <string name="opml_export_success_sum">Το αÏχείο .opml συντάχθηκε για:\u0020</string> <!--Sleep timer--> <string name="set_sleeptimer_label">ΡÏθμιση του χÏονοδιακόπτη Ïπνου</string> <string name="disable_sleeptimer_label">ΑπενεÏγοποίηση χÏονοδιακόπτη Ïπνου</string> @@ -341,4 +353,7 @@ <!--Database import/export--> <!--Casting--> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> + <string name="notification_channel_downloading">Λήψη</string> + <string name="notification_channel_error">Σφάλματα</string> </resources> diff --git a/core/src/main/res/values-es-rES/strings.xml b/core/src/main/res/values-es-rES/strings.xml index 8aa30231b..024989498 100644 --- a/core/src/main/res/values-es-rES/strings.xml +++ b/core/src/main/res/values-es-rES/strings.xml @@ -193,7 +193,6 @@ <string name="deselect_all_label">Deseleccionar todo</string> <string name="opml_export_label">Exportar a OPML</string> <string name="export_error_label">Error en la exportación</string> - <string name="opml_export_success_sum">El archivo OPML se ha escrito en:\u0020</string> <!--Sleep timer--> <string name="set_sleeptimer_label">Establecer un temporizador</string> <string name="disable_sleeptimer_label">Desactivar el temporizador</string> @@ -229,4 +228,5 @@ <!--Database import/export--> <!--Casting--> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-es/strings.xml b/core/src/main/res/values-es/strings.xml index 7c6341a06..73eabec89 100644 --- a/core/src/main/res/values-es/strings.xml +++ b/core/src/main/res/values-es/strings.xml @@ -1,11 +1,13 @@ <?xml version='1.0' encoding='UTF-8'?> <resources xmlns:tools="http://schemas.android.com/tools"> <!--Activitiy and fragment titles--> + <string name="feed_update_receiver_name">Actualizar suscripciones</string> <string name="feeds_label">Canales</string> <string name="statistics_label">EstadÃsticas</string> - <string name="add_feed_label">Añadir podcast</string> + <string name="add_feed_label">Añadir pódcast</string> <string name="episodes_label">Episodios</string> <string name="all_episodes_short_label">Todos</string> + <string name="new_episodes_label">Nuevos</string> <string name="favorite_episodes_label">Favoritos</string> <string name="new_label">Nuevos</string> <string name="settings_label">Ajustes</string> @@ -13,41 +15,43 @@ <string name="downloads_running_label">En curso</string> <string name="downloads_completed_label">Completadas</string> <string name="downloads_log_label">Registro</string> - <string name="subscriptions_label">Subscripciones</string> - <string name="subscriptions_list_label">Lista de subscripciones</string> + <string name="subscriptions_label">Suscripciones</string> + <string name="subscriptions_list_label">Lista de suscripciones</string> <string name="cancel_download_label">Cancelar\ndescarga</string> <string name="playback_history_label">Historial de reproducciones</string> <string name="gpodnet_main_label">gpodder.net</string> + <string name="gpodnet_summary">Sincronizar con otros dispositivos</string> <string name="gpodnet_auth_label">Iniciar sesión en gpodder.net</string> <string name="free_space_label">%1$s libre</string> - <string name="episode_cache_full_title">Caché de episodios completa</string> - <string name="episode_cache_full_message">Se ha alcanzado el lÃmite de caché de episodios. Puedes aumentar el tamaño de la caché en las Opciones.</string> + <string name="episode_cache_full_title">Almacenamiento de episodios completo</string> + <string name="episode_cache_full_message">Se ha alcanzado el lÃmite de almacenamiento de episodios. Puedes aumentar el tamaño en opciones.</string> + <string name="synchronizing">Sincronizando…</string> <!--Statistics fragment--> - <string name="total_time_listened_to_podcasts">Tiempo total reproducido:</string> - <string name="statistics_details_dialog">Empezados %1$d episodios de %2$d.\n\nReproducidos %3$s de %4$s.</string> + <string name="total_time_listened_to_podcasts">Tiempo total de reproducción de pódcast:</string> + <string name="statistics_details_dialog">%1$d episodios iniciados de %2$d.\n\nReproducidos %3$s de %4$s.</string> <string name="statistics_mode">Modo de estadÃsticas</string> <string name="statistics_mode_normal">Calcula la duración real reproducida. Reproducir dos veces cuenta doble, y marcar como leÃdo no cuenta como reproducido</string> - <string name="statistics_mode_count_all">Resumir todos los podcasts marcados como reproducidos</string> + <string name="statistics_mode_count_all">Suma de todos los pódcast marcados como reproducidos</string> <string name="statistics_speed_not_counted">Aviso: La velocidad de reproducción nunca se tiene en cuenta.</string> <!--Main activity--> <string name="drawer_open">Abrir menú</string> <string name="drawer_close">Cerrar menú</string> <string name="drawer_preferences">Preferencias del cajón</string> - <string name="drawer_feed_order_unplayed_episodes">Ordenar por cuenta</string> + <string name="drawer_feed_order_unplayed_episodes">Ordenar por contador</string> <string name="drawer_feed_order_alphabetical">Ordenar alfabéticamente</string> <string name="drawer_feed_order_last_update">Ordenar por fecha de publicación</string> <string name="drawer_feed_order_most_played">Ordenar por número de episodios reproducidos</string> - <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_new_unplayed">Número de episodios nuevos y no reproducidos</string> + <string name="drawer_feed_counter_new">Número de episodios nuevos</string> + <string name="drawer_feed_counter_unplayed">Número de episodios no reproducidos</string> + <string name="drawer_feed_counter_downloaded">Número 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> <string name="copy_url_label">Copiar URL</string> <string name="share_url_label">Compartir URL</string> - <string name="copied_url_msg">URL copiado en el portapapeles</string> - <string name="go_to_position_label">Ir a esta posición</string> + <string name="copied_url_msg">URL copiada al portapapeles</string> + <string name="go_to_position_label">Ir a esa posición</string> <!--Playback history--> <string name="clear_history_label">Vaciar el historial</string> <!--Other--> @@ -55,14 +59,15 @@ <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="reset">Restablecer</string> + <string name="author_label">Autor(es)</string> <string name="language_label">Idioma</string> <string name="url_label">URL</string> <string name="podcast_settings_label">Ajustes</string> <string name="cover_label">Imagen</string> <string name="error_label">Error</string> <string name="error_msg_prefix">Se produjo un error:</string> + <string name="needs_storage_permission">Se necesitan permisos de almacenamiento para esta operación</string> <string name="refresh_label">Actualizar</string> <string name="external_storage_error_msg">No se encuentra un almacenamiento externo. Asegúrese de que su almacenamiento externo esté montado para que la aplicación funcione correctamente.</string> <string name="chapters_label">CapÃtulos</string> @@ -80,15 +85,15 @@ <string name="retry_label">Reintentar</string> <string name="auto_download_label">Incluir en descargas automáticas</string> <string name="auto_download_apply_to_items_title">Aplicar a episodios anteriores</string> - <string name="auto_download_apply_to_items_message">La nueva opción <i>Auto Descarga</i> se aplicará automáticamente a episodios nuevos.\n¿También desea aplicarlo a episodios anteriores?</string> - <string name="auto_delete_label">Borrar Episodio Automáticamente</string> + <string name="auto_download_apply_to_items_message">La nueva opción <i>descarga automática</i> se aplicará automáticamente a episodios nuevos.\n¿También desea aplicarlo a episodios anteriores?</string> + <string name="auto_delete_label">Borrar episodio automáticamente</string> <string name="parallel_downloads_suffix">\u0020descargas paralelas</string> <string name="feed_auto_download_global">Global por defecto</string> <string name="feed_auto_download_always">Siempre</string> <string name="feed_auto_download_never">Nunca</string> <string name="send_label">Enviar…</string> <string name="episode_cleanup_never">Nunca</string> - <string name="episode_cleanup_queue_removal">Cuando no esté en cola</string> + <string name="episode_cleanup_queue_removal">Cuando no esté en la cola</string> <string name="episode_cleanup_after_listening">Después de acabar</string> <plurals name="episode_cleanup_days_after_listening"> <item quantity="one">1 dÃa después de acabar</item> @@ -97,77 +102,84 @@ <!--'Add Feed' Activity labels--> <string name="feedurl_label">URL del canal</string> <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">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> + <string name="txtvfeedurl_label">Añadir pódcast por URL</string> + <string name="podcastdirectories_label">Buscar pódcast en el directorio</string> + <string name="podcastdirectories_descr">Para nuevos pódcast, puedes buscar en iTunes o fyyd, o explorar en gpodder.net por nombre, categorÃa o popularidad.</string> + <string name="browse_gpoddernet_label">Explorar en gpodder.net</string> <!--Actions on feeds--> - <string name="mark_all_read_label">Marcar todos como escuchado</string> - <string name="mark_all_read_msg">Se marcaron todos los episodios como escuchados</string> - <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_read_label">Marcar todos como reproducidos</string> + <string name="mark_all_read_msg">Marcados todos los episodios como reproducidos</string> + <string name="mark_all_read_confirmation_msg">Confirme que quiere marcar todos los episodios como reproducidos.</string> + <string name="mark_all_read_feed_confirmation_msg">Confirme que quiere marcar todos los episodios de este pódcast como reproducidos.</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="mark_all_seen_msg">Marcados todos los episodios como vistos</string> + <string name="mark_all_seen_confirmation_msg">Confirme que quiere 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="show_feed_settings_label">Mostrar ajustes del pódcast</string> + <string name="feed_info_label">Información del pódcast</string> + <string name="feed_settings_label">Ajustes del pódcast</string> + <string name="rename_feed_label">Renombrar el pódcast</string> + <string name="remove_feed_label">Eliminar el pódcast</string> <string name="share_label">Compartir…</string> - <string name="share_link_label">Compartir el enlace de la web</string> - <string name="share_file_label">Compartir archivo</string> - <string name="share_link_with_position_label">Compartir enlace con posición</string> + <string name="share_link_label">Compartir URL del episodio</string> + <string name="share_link_with_position_label">Compartir URL del episodio con posición</string> + <string name="share_file_label">Compartir el archivo</string> <string name="share_feed_url_label">Compartir URL del canal</string> - <string name="share_item_url_label">Compartir URL del archivo del episodio</string> - <string name="share_item_url_with_position_label">Compartir URL del episodio con posición</string> - <string name="feed_delete_confirmation_msg">Por favor, confirma que quieres borrar el feed \"%1$s\" y TODOS los episodios descargados de dicho feed.</string> - <string name="feed_remover_msg">Quitando el canal</string> - <string name="load_complete_feed">Actualizar el canal completo</string> + <string name="share_item_url_label">Compartir URL del archivo</string> + <string name="share_item_url_with_position_label">Compartir URL del archivo con posición</string> + <string name="feed_delete_confirmation_msg">Confirme que quiere borrar el pódcast \"%1$s\" y TODOS los episodios (incluidos los descargados).</string> + <string name="feed_remover_msg">Eliminando el pódcast</string> + <string name="load_complete_feed">Actualizar el pódcast completo</string> <string name="hide_episodes_title">Ocultar episodios</string> - <string name="episode_actions">Aplicar acciones</string> - <string name="hide_unplayed_episodes_label">No escuchados</string> + <string name="batch_edit">Edición por lotes</string> + <string name="hide_unplayed_episodes_label">No reproducidos</string> <string name="hide_paused_episodes_label">Pausados</string> - <string name="hide_played_episodes_label">Escuchados</string> + <string name="hide_played_episodes_label">Reproducidos</string> <string name="hide_queued_episodes_label">En cola</string> <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="hide_is_favorite_label">Es favorito</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> + <string name="open_podcast">Abrir pódcast</string> <!--actions on feeditems--> <string name="download_label">Descargar</string> <string name="play_label">Reproducir</string> <string name="pause_label">Pausar</string> <string name="stop_label">Detener</string> - <string name="stream_label">Transmitir</string> - <string name="remove_label">Quitar</string> + <string name="stream_label">Escuchar en directo</string> + <string name="remove_label">Eliminar</string> <string name="delete_label">Borrar</string> <string name="delete_failed">No se puede borrar el fichero. Reiniciar el dispositivo podrÃa ayudar.</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> - <string name="marked_as_read_label">Marcado como escuchado</string> - <string name="mark_unread_label">Marcar como no escuchado</string> + <string name="remove_episode_lable">Eliminar episodio</string> + <string name="mark_as_seen_label">Marcar como visto</string> + <string name="marked_as_seen_label">Marcado como visto</string> + <string name="mark_read_label">Marcar como reproducido</string> + <string name="marked_as_read_label">Marcado como reproducido</string> + <string name="mark_unread_label">Marcar como no reproducido</string> <string name="add_to_queue_label">Añadir a la cola</string> <string name="added_to_queue_label">Añadido a la cola</string> - <string name="remove_from_queue_label">Quitar de la cola</string> - <string name="add_to_favorite_label">Añadir a Favoritos</string> - <string name="added_to_favorites">Añadido a Favoritos</string> - <string name="remove_from_favorite_label">Eliminar de Favoritos</string> - <string name="removed_from_favorites">Quitado de Favoritos</string> + <string name="remove_from_queue_label">Eliminar de la cola</string> + <string name="add_to_favorite_label">Añadir a favoritos</string> + <string name="added_to_favorites">Añadido a favoritos</string> + <string name="remove_from_favorite_label">Eliminar de favoritos</string> + <string name="removed_from_favorites">Eliminado de favoritos</string> <string name="visit_website_label">Visitar el sitio web</string> <string name="support_label">Añadir a Flattr</string> <string name="skip_episode_label">Omitir episodio</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">Resetear posición de reproducción</string> + <string name="reset_position">Restablecer la posición de reproducción</string> <string name="removed_item">Elemento elminado</string> <!--Download messages and labels--> - <string name="download_successful">exitoso</string> - <string name="download_failed">fallido</string> + <string name="download_successful">exitosa</string> + <string name="download_failed">fallida</string> <string name="download_pending">Descarga pendiente</string> <string name="download_running">Descarga en curso</string> + <string name="download_error_details">Detalles</string> + <string name="download_error_details_message">%1$s \n\nURL de archivo:\n%2$s</string> <string name="download_error_device_not_found">No se ha encontrado un dispositivo de almacenamiento</string> <string name="download_error_insufficient_space">Espacio insuficiente</string> <string name="download_error_file_error">Error de archivo</string> @@ -182,9 +194,9 @@ <string name="download_error_forbidden">Prohibido</string> <string name="cancel_all_downloads_label">Cancelar todas las descargas</string> <string name="download_canceled_msg">Descarga cancelada</string> - <string name="download_canceled_autodownload_enabled_msg">Descarga cancelada\nSe desactivó <i>Descarga automática</i> en este elemento</string> + <string name="download_canceled_autodownload_enabled_msg">Descarga cancelada\nSe desactivó la <i>descarga automática</i> en este elemento</string> <string name="download_report_title">Descargas completadas con error(es)</string> - <string name="download_report_content_title">Informe de descarga</string> + <string name="download_report_content_title">Informe de descargas</string> <string name="download_error_malformed_url">URL con formato incorrecto</string> <string name="download_error_io_error">Error de E/S</string> <string name="download_error_request_error">Error de solicitud</string> @@ -194,22 +206,22 @@ <item quantity="other">Quedan %d descargas</item> </plurals> <string name="downloads_processing">Procesando descargas</string> - <string name="download_notification_title">Descargando datos del podcast</string> + <string name="download_notification_title">Descargando datos del pódcast</string> <string name="download_report_content">%1$d descargas exitosas, %2$d fallidas</string> <string name="download_log_title_unknown">TÃtulo desconocido</string> <string name="download_type_feed">Canal</string> - <string name="download_type_media">Archivo de medios</string> + <string name="download_type_media">Archivo multimedia</string> <string name="download_type_image">Imagen</string> <string name="download_request_error_dialog_message_prefix">Ha ocurrido un error al intentar descargar el archivo:\u0020</string> - <string name="authentication_notification_title">Se necesita autenticación</string> - <string name="authentication_notification_msg">Para acceder al recurso solicitado debe proporcionar un usuario y contraseña</string> + <string name="authentication_notification_title">Autenticación requerida</string> + <string name="authentication_notification_msg">El recurso solicitado requiere un usuario y contraseña</string> <string name="confirm_mobile_download_dialog_title">Confirmar descarga por red móvil</string> - <string name="confirm_mobile_download_dialog_message_not_in_queue">Se desactivaron las descargas por red de datos móviles en la configuración.\n\nPuede elegir entre añadir el episodio a la cola o permitir las descargas temporalmente.\n\n<small>Se recordará la elección por 10 minutos.</small></string> - <string name="confirm_mobile_download_dialog_message">Se desactivaron las descargas por red de datos móviles en la configuración.\n\n¿Quiere permitir las descargas temporalmente?\n\n<small>Se recordará la elección por 10 minutos.</small></string> + <string name="confirm_mobile_download_dialog_message_not_in_queue">Se desactivaron las descargas por red de datos móviles en la configuración.\n\nPuede elegir entre añadir el episodio a la cola o permitir las descargas temporalmente.\n\n<small>Se recordará su elección durante 10 minutos.</small></string> + <string name="confirm_mobile_download_dialog_message">Se desactivaron las descargas por red de datos móviles en la configuración.\n\n¿Quiere permitir las descargas temporalmente?\n\n<small>Se recordará su elección durante 10 minutos.</small></string> <string name="confirm_mobile_download_dialog_only_add_to_queue">Añadir a la cola</string> <string name="confirm_mobile_download_dialog_enable_temporarily">Permitir temporalmente</string> <!--Mediaplayer messages--> - <string name="player_error_msg">Error</string> + <string name="player_error_msg">¡Error!</string> <string name="player_stopped_msg">No hay medios en reproducción</string> <string name="player_preparing_msg">Preparando</string> <string name="player_ready_msg">Listo</string> @@ -218,7 +230,8 @@ <string name="playback_error_unknown">Error desconocido</string> <string name="no_media_playing_label">No hay medios en reproducción</string> <string name="player_buffering_msg">Almacenando</string> - <string name="playbackservice_notification_title">Reproduciendo el podcast</string> + <string name="player_go_to_picture_in_picture">Modo picture-in-picture</string> + <string name="playbackservice_notification_title">Reproduciendo el pódcast</string> <string name="unknown_media_key">AntennaPod - Tecla multimedia desconocida: %1$d</string> <!--Queue operations--> <string name="lock_queue">Bloquear cola</string> @@ -227,108 +240,118 @@ <string name="queue_unlocked">Cola desbloqueada</string> <string name="clear_queue_label">Vaciar la cola</string> <string name="undo">Deshacer</string> - <string name="removed_from_queue">Se quitó el elemento</string> + <string name="removed_from_queue">Elemento eliminado</string> <string name="move_to_top_label">Mover al principio</string> <string name="move_to_bottom_label">Mover al final</string> <string name="sort">Ordenar</string> <string name="date">Fecha</string> <string name="duration">Duración</string> <string name="episode_title">TÃtulo del episodio</string> - <string name="feed_title">TÃtulo del feed</string> + <string name="feed_title">TÃtulo del pódcast</string> + <string name="random">Aleatorio</string> + <string name="smart_shuffle">Reproducción inteligente</string> <string name="ascending">Ascendente</string> <string name="descending">Descendente</string> <string name="clear_queue_confirmation_msg">Confirme que quiere borrar TODOS los episodios de la cola</string> <!--Flattr--> <string name="flattr_auth_label">Identificarse en Flattr</string> - <string name="flattr_auth_explanation">Pulse el botón inferior para comenzar la autenticación. Su navegador abrirá la pantalla de identificación de Flattr y le preguntará si quiere conceder permiso a AntennaPod para valorar cosas. Tras concederlo, volverá a esta pantalla automáticamente.</string> + <string name="flattr_auth_explanation">Pulse el botón inferior para iniciar el proceso de autenticación. Su navegador abrirá la pantalla de inicio de sesión en Flattr y le preguntará si quiere conceder permiso a AntennaPod para valorar. Tras concederlo, volverá a esta pantalla automáticamente.</string> <string name="authenticate_label">Autenticarse</string> - <string name="return_home_label">Volver a la pantalla principal</string> - <string name="flattr_auth_success">Autentificación exitosa. Ya puede valorar cosas en Flattr desde la aplicación.</string> - <string name="no_flattr_token_title">No se ha encontrado un token de Flattr</string> + <string name="return_home_label">Volver al inicio</string> + <string name="flattr_auth_success">Autenticación exitosa. Ya puede valorar en Flattr desde la aplicación.</string> + <string name="no_flattr_token_title">No se ha encontrado el token de Flattr</string> <string name="no_flattr_token_notification_msg">Parece que su cuenta de Flattr no está conectada con AntennaPod. Toque aquà para autenticarse.</string> - <string name="no_flattr_token_msg">Su cuenta de Flattr no está conectada con AntennaPod. Puede conectarla o puede visitar la página web de cada cosa para valorarla desde allÃ.</string> + <string name="no_flattr_token_msg">Su cuenta de Flattr no está conectada con AntennaPod. Puede conectarla con AntennaPod para valorar dentro de la aplicación o puede visitar la página web de Flattr para valorar desde allÃ.</string> <string name="authenticate_now_label">Autenticarse</string> <string name="action_forbidden_title">Acción prohibida</string> - <string name="action_forbidden_msg">AntennaPod no tiene permiso para realizar esta acción. La razón puede ser que se haya revocado el token de acceso de AntennaPod para su cuenta. Puede re-autenticarse o visitar la página web de la cosa.</string> + <string name="action_forbidden_msg">AntennaPod no tiene permiso para realizar esta acción. La razón puede ser que se haya revocado el token de acceso de AntennaPod en su cuenta. Puede reautenticarse o visitar la página web.</string> <string name="access_revoked_title">Acceso revocado</string> - <string name="access_revoked_info">Ha revocado el token de acceso de AntennaPod a su cuenta. Para completar el proceso debe eliminar esta aplicación de la lista de aplicaciones aprobadas, en los ajustes de Flattr.</string> + <string name="access_revoked_info">Ha revocado el token de acceso de AntennaPod a su cuenta. Para completar el proceso debe eliminar esta aplicación de la lista de aplicaciones aprobadas en los ajustes de la web de Flattr.</string> <!--Flattr--> - <string name="flattr_click_success">Ha hecho Flattr en un elemento.</string> - <string name="flattr_click_success_count">Ha hecho Flattr en %d elementos.</string> - <string name="flattr_click_success_queue">Flattr: %s.</string> - <string name="flattr_click_failure_count">No se pudo hacer Flattr en %d elementos.</string> - <string name="flattr_click_failure">No se hizo Flattr: %s.</string> - <string name="flattr_click_enqueued">Se hará Flattr de esta cosa más tarde</string> - <string name="flattring_thing">Haciendo Flattr de %s</string> - <string name="flattring_label">AntennaPod haciendo Flattr</string> - <string name="flattrd_label">AntennaPod hizo Flattr</string> - <string name="flattrd_failed_label">AntennaPod Flattr falló</string> - <string name="flattr_retrieving_status">Obteniendo lista de Flattr</string> + <string name="flattr_click_success">Ha valorado con Flattr un elemento.</string> + <string name="flattr_click_success_count">Ha valorado con Flattr %d elementos.</string> + <string name="flattr_click_success_queue">valorado con Flattr: %s.</string> + <string name="flattr_click_failure_count">No se pudieron valorar con Flattr %d elementos.</string> + <string name="flattr_click_failure">No se ha valorado con Flattr: %s.</string> + <string name="flattr_click_enqueued">Se valorará con Flattr más tarde</string> + <string name="flattring_thing">Valorando con Flattr a %s</string> + <string name="flattring_label">AntennaPod está valorando con Flattr</string> + <string name="flattrd_label">AntennaPod ha valorado con Flattr</string> + <string name="flattrd_failed_label">AntennaPod falló al valorar con Flattr</string> + <string name="flattr_retrieving_status">Obteniendo lista de valoraciones con Flattr</string> <!--Variable Speed--> <string name="download_plugin_label">Descargar complemento</string> <string name="no_playback_plugin_title">Complemento no instalado</string> - <string name="no_playback_plugin_or_sonic_msg">Para que funciona la velocidad de reproducción variable, recomendamos habilitar el reproductor Sonic Media [Android 4.1+].\n\nPor otro lado, puedes descargar el plugin de terceros <i>Prestissimo</i> de la Play Store.\nCualquier problema con Prestissimo no es reponsabilidad de AntennaPod y no deberÃa ser reportado al propietario del plugin.</string> + <string name="no_playback_plugin_or_sonic_msg">Para que funcione la velocidad de reproducción variable, recomendamos habilitar el reproductor Sonic [Android 4.1+].\n\nTambién puede descargar el plugin <i>Prestissimo</i> de la Play Store.\nNingún problema con Prestissimo es reponsabilidad de AntennaPod y deberÃa ser reportado al propietario del plugin.</string> <string name="set_playback_speed_label">Velocidades de reproducción</string> <string name="enable_sonic">Activar Sonic</string> <!--Empty list labels--> <string name="no_items_label">Esta lista no tiene elementos.</string> - <string name="no_feeds_label">No se ha suscrito a ningún canal.</string> + <string name="no_feeds_label">No se ha suscrito a ningún pódcast.</string> <string name="no_chapters_label">Este episodio no tiene capÃtulos.</string> - <string name="no_shownotes_label">Este episodio no tiene anotaciones.</string> + <string name="no_shownotes_label">Este episodio no tiene notas del programa.</string> <!--Preferences--> <string name="storage_pref">Almacenamiento</string> <string name="project_pref">Proyecto</string> <string name="other_pref">Otros</string> <string name="about_pref">Acerca de</string> <string name="queue_label">Cola</string> - <string name="services_label">Servicios</string> + <string name="integrations_label">Integraciones</string> <string name="flattr_label">Flattr</string> + <string name="flattr_summary">Servicio de micropagos</string> + <string name="automation">Automatización</string> + <string name="download_pref_details">Detalles</string> + <string name="import_export_pref">Importar/Exportar</string> + <string name="appearance">Apariencia</string> + <string name="external_elements">Elementos externos</string> + <string name="interruptions">Interrupciones</string> + <string name="buttons">Botones de control</string> + <string name="media_player">Reproductor multimedia</string> <string name="pref_episode_cleanup_title">Limpieza de episodios</string> - <string name="pref_episode_cleanup_summary">Los episodios que no estén en la cola ni en Favoritos pueden eliminarse si Descarga automática necesita espacio para episodios nuevos</string> + <string name="pref_episode_cleanup_summary">Los episodios que no estén en la cola ni en favoritos pueden eliminarse si la descarga automática necesita espacio para nuevos episodios</string> <string name="pref_pauseOnDisconnect_sum">Pausar la reproducción al desconectar los auriculares o el bluetooth</string> - <string name="pref_unpauseOnHeadsetReconnect_sum">Reanudar reproducción cuando se reconecten los auriculares</string> - <string name="pref_unpauseOnBluetoothReconnect_sum">Reanudar reproducción cuando se reconecte el bluetooth</string> - <string name="pref_hardwareForwardButtonSkips_title">Saltar episodio con botón avance</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_unpauseOnHeadsetReconnect_sum">Reanudar la reproducción cuando se reconecten los auriculares</string> + <string name="pref_unpauseOnBluetoothReconnect_sum">Reanudar la reproducción cuando se reconecte el bluetooth</string> + <string name="pref_hardwareForwardButtonSkips_title">Botón avance: Saltar</string> + <string name="pref_hardwarePreviousButtonRestarts_title">Botón retroceso: Reiniciar</string> + <string name="pref_hardwarePreviousButtonRestarts_sum">Al pulsar el botón fÃsico de retroceso se comenzará el episodio de nuevo en lugar de retroceder</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_sum">Borrar el episodio cuando finalice la reproducción</string> <string name="pref_auto_delete_title">Eliminar automáticamente</string> - <string name="pref_smart_mark_as_played_sum">Marcar episodios como escuchados incluso si todavÃa quedan unos segundos por escuchar</string> - <string name="pref_smart_mark_as_played_title">Marcar como terminado inteligente</string> - <string name="pref_skip_keeps_episodes_sum">Conservar episodios al saltarlos</string> + <string name="pref_smart_mark_as_played_sum">Marca los episodios como reproducidos incluso si todavÃa quedan unos segundos por escuchar</string> + <string name="pref_smart_mark_as_played_title">Marcado inteligente como reproducido</string> + <string name="pref_skip_keeps_episodes_sum">Conservar los episodios cuando son saltados</string> <string name="pref_skip_keeps_episodes_title">Conservar episodios saltados</string> <string name="pref_favorite_keeps_episodes_sum">Conservar los episodios cuando se marcan como favoritos</string> - <string name="pref_favorite_keeps_episodes_title">Conservar los episodios favoritos</string> + <string name="pref_favorite_keeps_episodes_title">Conservar episodios favoritos</string> <string name="playback_pref">Reproducción</string> <string name="network_pref">Red</string> <string name="pref_autoUpdateIntervallOrTime_title">Intervalo de actualización u hora del dÃa</string> - <string name="pref_autoUpdateIntervallOrTime_sum">Especificar el intervalo o la hora del dÃa en que se actualizarán automáticamente los canales</string> - <string name="pref_autoUpdateIntervallOrTime_message">Se puede ajustar un <i>intervalo</i> como \"cada 2 horas\", especificar una <i>hora del dÃa</i> como \"7:00 AM\" o <i>deshabilitar</i> las actualizaciones automáticas.\n\n<small>Nota: Las horas de actualización no son exactas. Puede haber un ligero retraso.</small></string> + <string name="pref_autoUpdateIntervallOrTime_sum">Especifique un intervalo o una hora especÃfica del dÃa para actualizar automáticamente los canales</string> + <string name="pref_autoUpdateIntervallOrTime_message">Se puede ajustar un <i>intervalo</i> como \"cada 2 horas\", especificar una <i>hora del dÃa</i> como las \"7:00 AM\" o <i>deshabilitar</i> las actualizaciones automáticas.\n\n<small>Nota: Las horas de actualización no son exactas. Puede haber un ligero retraso.</small></string> <string name="pref_autoUpdateIntervallOrTime_Disable">Deshabilitar</string> <string name="pref_autoUpdateIntervallOrTime_Interval">Ajustar intervalo</string> <string name="pref_autoUpdateIntervallOrTime_TimeOfDay">Ajustar hora del dÃa</string> <string name="pref_autoUpdateIntervallOrTime_every">todos los %1$s</string> <string name="pref_autoUpdateIntervallOrTime_at">a las %1$s</string> - <string name="pref_downloadMediaOnWifiOnly_sum">Solo descargar los contenidos por WiFi</string> + <string name="pref_downloadMediaOnWifiOnly_sum">Descargar los contenidos solo por wifi</string> <string name="pref_followQueue_title">Reproducción continua</string> - <string name="pref_downloadMediaOnWifiOnly_title">Descarga de contenidos por WiFi</string> - <string name="pref_pauseOnHeadsetDisconnect_title">Desconexión de los cascos</string> - <string name="pref_unpauseOnHeadsetReconnect_title">Reconectar auriculares</string> - <string name="pref_unpauseOnBluetoothReconnect_title">Reconectar Bluetooth</string> + <string name="pref_downloadMediaOnWifiOnly_title">Descarga de contenidos por wifi</string> + <string name="pref_pauseOnHeadsetDisconnect_title">Desconectar sin los auriculares</string> + <string name="pref_unpauseOnHeadsetReconnect_title">Reconectar con los auriculares</string> + <string name="pref_unpauseOnBluetoothReconnect_title">Reconectar con Bluetooth</string> <string name="pref_mobileUpdate_title">Actualizaciones por red móvil</string> - <string name="pref_mobileUpdate_sum">Permitir actualizaciones por red de datos móvil</string> + <string name="pref_mobileUpdate_sum">Permitir actualizaciones por la red de datos móvil</string> <string name="refreshing_label">Actualizando</string> <string name="flattr_settings_label">Ajustes de Flattr</string> - <string name="pref_flattr_auth_title">Identificación en Flattr</string> + <string name="pref_flattr_auth_title">Identificarse en Flattr</string> <string name="pref_flattr_auth_sum">IdentifÃquese en Flattr para valorar cosas directamente desde la aplicación</string> - <string name="pref_flattr_this_app_title">Valorar esta aplicación en Flattr</string> + <string name="pref_flattr_this_app_title">Valorar en Flattr esta aplicación</string> <string name="pref_flattr_this_app_sum">Apoye el desarrollo de AntennaPod valorándola en Flattr. ¡Gracias!</string> - <string name="pref_revokeAccess_title">Revocar el acceso</string> - <string name="pref_revokeAccess_sum">Rescindir el permiso de acceso de esta aplicación a su cuenta de Flattr.</string> - <string name="pref_auto_flattr_title">Uso de Flattr automático</string> - <string name="pref_auto_flattr_sum">Configurar flattr automático</string> + <string name="pref_revokeAccess_title">Revocar acceso</string> + <string name="pref_revokeAccess_sum">Revocar el acceso de esta aplicación en su cuenta de Flattr.</string> + <string name="pref_auto_flattr_title">Flattr automático</string> + <string name="pref_auto_flattr_sum">Configurar Flattr automático</string> <string name="user_interface_label">Interfaz de usuario</string> <string name="pref_set_theme_title">Elegir un tema</string> <string name="pref_nav_drawer_title">Personalizar el cajón de navegación</string> @@ -338,131 +361,134 @@ <string name="pref_nav_drawer_feed_order_title">Ajustar orden de suscripción</string> <string name="pref_nav_drawer_feed_order_sum">Cambiar el orden de las suscripciones</string> <string name="pref_nav_drawer_feed_counter_title">Ajustar contador de suscripción</string> - <string name="pref_nav_drawer_feed_counter_sum">Cambiar la información mostrada en el contador de suscripción</string> + <string name="pref_nav_drawer_feed_counter_sum">Cambiar la información mostrada en el contador de las suscripciones. También afecta al orden de las suscripciones si el \'orden de la suscripción\' está en modo \'Contador\'.</string> <string name="pref_set_theme_sum">Cambiar la apariencia de AntennaPod.</string> <string name="pref_automatic_download_title">Descarga automática</string> <string name="pref_automatic_download_sum">Configurar la descarga automática de episodios.</string> - <string name="pref_autodl_wifi_filter_title">Activar el filtro WiFi</string> - <string name="pref_autodl_wifi_filter_sum">Permitir la descarga automática sólo para las redes WiFi marcadas.</string> + <string name="pref_autodl_wifi_filter_title">Activar el filtro wifi</string> + <string name="pref_autodl_wifi_filter_sum">Permitir la descarga automática sólo desde las redes wifi seleccionadas.</string> <string name="pref_autodl_allow_on_mobile_title">Descargar bajo conexión móvil</string> - <string name="pref_autodl_allow_on_mobile_sum">Permite descarga automática sobre la red de Internet del móvil.</string> + <string name="pref_autodl_allow_on_mobile_sum">Permitir la descarga automática a través de la conexión de datos móviles.</string> <string name="pref_automatic_download_on_battery_title">Descargar cuando no se está cargando</string> - <string name="pref_automatic_download_on_battery_sum">Permitir la descarga automática cuando la baterÃa no está cargando</string> + <string name="pref_automatic_download_on_battery_sum">Permitir la descarga automática cuando la baterÃa no se esté cargando</string> <string name="pref_parallel_downloads_title">Descargas paralelas</string> - <string name="pref_episode_cache_title">Caché de episodios</string> + <string name="pref_episode_cache_title">Almacenamiento de episodios</string> <string name="pref_theme_title_light">Claro</string> <string name="pref_theme_title_dark">Oscuro</string> + <string name="pref_theme_title_trueblack">Negro (para AMOLED)</string> <string name="pref_episode_cache_unlimited">Ilimitado</string> <string name="pref_update_interval_hours_plural">horas</string> <string name="pref_update_interval_hours_singular">hora</string> <string name="pref_update_interval_hours_manual">Manual</string> <string name="pref_gpodnet_authenticate_title">Iniciar sesión</string> - <string name="pref_gpodnet_authenticate_sum">Inicie sesión con su cuenta de gpodder.net para sincronizar sus suscripciones.</string> + <string name="pref_gpodnet_authenticate_sum">Iniciar sesión en su cuenta de gpodder.net para sincronizar sus suscripciones.</string> <string name="pref_gpodnet_logout_title">Cerrar sesión</string> - <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_logout_toast">Ha cerrado la sesión correctamente</string> + <string name="pref_gpodnet_setlogin_information_title">Cambiar información de inicio de sesión</string> <string name="pref_gpodnet_setlogin_information_sum">Modificar datos de inicio de sesión en 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_changes_sum">Sincronizar cambios de suscripción y episodios con gpodder.net.</string> + <string name="pref_gpodnet_full_sync_title">Sincronización completa</string> + <string name="pref_gpodnet_full_sync_sum">Sincronizar todas las suscripciones y episodios 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_gpodnet_sync_started">Sincronización iniciada</string> + <string name="pref_gpodnet_full_sync_started">Sincronización completa iniciada</string> + <string name="pref_gpodnet_login_status"><![CDATA[Identificado como <i>%1$s</i> con dispositivo <i>%2$s</i>]]></string> + <string name="pref_gpodnet_notifications_title">Mostrar errores de sincronización</string> + <string name="pref_gpodnet_notifications_sum">Este ajuste no afecta a los 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_playback_speed_sum">Personalice las velocidades disponibles en la reproducción de audio a velocidad variable</string> <string name="pref_fast_forward">Intervalo de avance</string> - <string name="pref_fast_forward_sum">Personaliza el número de segundos a avanzar cuando se pulsa el botón de avance rápido</string> + <string name="pref_fast_forward_sum">Personalice el número de segundos que avanzará cuando se pulsa el botón de avance</string> <string name="pref_rewind">Intervalo de retroceso</string> - <string name="pref_rewind_sum">Personaliza el número de segundos a retroceder cuando se pulsa el botón de retroceder</string> - <string name="pref_gpodnet_sethostname_title">Definir nombre de equipo</string> - <string name="pref_gpodnet_sethostname_use_default_host">Usar nombre de equipo por defecto</string> - <string name="pref_expandNotify_title">Expandir Notificación</string> - <string name="pref_expandNotify_sum">Expandir siempre la notificación para mostrar los botones de reproducción</string> + <string name="pref_rewind_sum">Personalice el número de segundos que retrocederá cuando se pulsa el botón de retrocedeso</string> + <string name="pref_gpodnet_sethostname_title">Establecer nombre del dispositivo</string> + <string name="pref_gpodnet_sethostname_use_default_host">Usar el nombre por defecto</string> <string name="pref_persistNotify_title">Controles de reproducción persistentes</string> - <string name="pref_persistNotify_sum">Mantener la notificación y controles en pantalla de bloqueo cuando se pausa.</string> - <string name="pref_compact_notification_buttons_title">Configurar botones de la pantalla de bloqueo</string> - <string name="pref_compact_notification_buttons_sum">Cambiar los botones de la pantalla de bloqueo. El botón play/pausa siempre está incluido.</string> - <string name="pref_compact_notification_buttons_dialog_title">Seleccionar un máximo de %1$d elementos</string> + <string name="pref_persistNotify_sum">Mantener las notificaciones y los controles en pantalla de bloqueo cuando se pausa la reproducción.</string> + <string name="pref_compact_notification_buttons_title">Configurar botones en la pantalla de bloqueo</string> + <string name="pref_compact_notification_buttons_sum">Cambiar los botones en la pantalla de bloqueo. El botón reproducir/pausar siempre está incluido.</string> + <string name="pref_compact_notification_buttons_dialog_title">Seleccionar máximo %1$d elementos</string> <string name="pref_compact_notification_buttons_dialog_error">Sólo puedes seleccionar un máximo de %1$d elementos.</string> <string name="pref_lockscreen_background_title">Establecer fondo de pantalla de bloqueo</string> - <string name="pref_lockscreen_background_sum">Establecer el fondo de pantalla de bloqueo desde la imagen del episodio. Como efecto lateral, esto también mostrará la imagen en aplicaciones de terceros.</string> + <string name="pref_lockscreen_background_sum">Establecer el fondo de pantalla de bloqueo desde la imagen del episodio. Como efecto secundario, esto también mostrarán las imagen de aplicaciones de terceros.</string> <string name="pref_showDownloadReport_title">Mostrar informe de descarga</string> <string name="pref_showDownloadReport_sum">Si la descarga falla, generar un informe con los detalles del fallo</string> <string name="pref_expand_notify_unsupport_toast">Las versiones de Android anteriores a la 4.1 no soportan notificaciones expandidas</string> <string name="pref_queueAddToFront_sum">Agregar nuevos episodios al principio de la cola.</string> <string name="pref_queueAddToFront_title">Poner al principio de la cola.</string> <string name="pref_smart_mark_as_played_disabled">Deshabilitado</string> - <string name="pref_image_cache_size_title">Tamaño de la caché de imágenes</string> - <string name="pref_image_cache_size_sum">Tamaño de la caché en disco para imágenes.</string> - <string name="crash_report_title">Informe de fallo</string> - <string name="crash_report_sum">Enviar el último informe de fallo por e-mail</string> - <string name="send_email">Enviar e-mail</string> + <string name="pref_image_cache_size_title">Tamaño del almacenamiento de imágenes</string> + <string name="pref_image_cache_size_sum">Tamaño del almacenamiento de imágenes en disco.</string> + <string name="crash_report_title">Informe de fallos</string> + <string name="crash_report_sum">Enviar el último informe de fallo por correo electrónico</string> + <string name="send_email">Enviar correo electrónico</string> <string name="experimental_pref">Experimental</string> - <string name="pref_sonic_title">Sonic media player</string> - <string name="pref_sonic_message">Usar el reproductor Sonic Media incorporado en lugar del reproductor multimedia de Android y Prestissimo</string> + <string name="pref_media_player_message">Seleccione qué reproductor multimedia usar para reproducir archivos</string> <string name="pref_current_value">Valor actual: %1$s</string> <string name="pref_proxy_title">Proxy</string> <string name="pref_proxy_sum">Configurar proxy de red</string> <string name="pref_faq">Preguntas frecuentes</string> <string name="pref_known_issues">Problemas conocidos</string> - <string name="pref_no_browser_found">No se ha encontrado navegador web.</string> + <string name="pref_no_browser_found">No se ha encontrado un navegador web.</string> <string name="pref_cast_title">Soporte para Chromecast</string> <string name="pref_cast_message_play_flavor">Habilitar soporte para reproducción remota en dispositivos Cast (como Chromecast, altavoces o Android TV)</string> <string name="pref_cast_message_free_flavor">Chromecast requiere librerÃas propietarias de terceros que están deshabilitadas en esta versión de AntennaPod</string> - <string name="pref_enqueue_downloaded_title">Poner descargados en cola</string> + <string name="pref_enqueue_downloaded_title">Agregar descargados a la cola</string> <string name="pref_enqueue_downloaded_summary">Agregar episodios descargados a la cola</string> + <string name="media_player_builtin">Reproductor Android integrado</string> + <string name="pref_videoBehavior_title">Al salir del vÃdeo</string> + <string name="pref_videoBehavior_sum">Comportamiento al salir de la reproducción de video</string> + <string name="stop_playback">Parar reproducción</string> + <string name="continue_playback">Continuar la reproducción de audio</string> <!--Auto-Flattr dialog--> <string name="auto_flattr_enable">Habilitar Flattr automático</string> - <string name="auto_flattr_after_percent">Hacer Flattr del episodio en cuanto se haya reproducido el %d por ciento</string> - <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> + <string name="auto_flattr_after_percent">Valorar con Flattr el episodio cuando se haya reproducido el %d por ciento</string> + <string name="auto_flattr_ater_beginning">Valorar con Flattr el episodio al comenzar la reproducción</string> + <string name="auto_flattr_ater_end">Valorar con Flattr el episodio al terminar la reproducción</string> <!--Search--> <string name="search_hint">Buscar episodios</string> - <string name="found_in_shownotes_label">Encontrado en las notas del show</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="found_in_authors_label">Encontrado en los autores</string> - <string name="found_in_feeds_label">Encontrado en los feeds</string> + <string name="found_in_authors_label">Encontrado en autor(es)</string> + <string name="found_in_feeds_label">Encontrado en pódcast</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> + <string name="no_results_for_query">No se han encontrado resultados de \"%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_txtv_button_lable">Los archivos OPML le permiten migrar sus pódcast de una aplicación a otra.</string> <string name="opml_import_option">Opción %1$d</string> <string name="opml_import_explanation_1">Elegir un una ruta del sistema de ficheros local.</string> - <string name="opml_import_explanation_2">Usar una aplicación externa tipo Dropbox, Google Drive or su gestor de ficheros favorito para abrir un archivo OPML.</string> - <string name="opml_import_explanation_3">Muchas aplicaciones como Google Mail, Dropbox, Google Drive y la mayorÃa de gestores de ficheros pueden <i>abrir</i> archivos OPML <i>con</i> AntennaPod.</string> + <string name="opml_import_explanation_2">Usar una aplicación externa tipo Dropbox, Google Drive o su gestor de ficheros favorito para abrir un archivo OPML.</string> + <string name="opml_import_explanation_3">Muchas aplicaciones como Google Mail, Dropbox, Google Drive y la mayorÃa de gestores de ficheros pueden <i>abrir</i> archivos OPML <i>de</i> AntennaPod.</string> <string name="start_import_label">Comenzar la importación</string> - <string name="opml_import_label">Importación de OPML</string> + <string name="opml_import_label">Importar de OPML</string> <string name="opml_directory_error">¡ERROR!</string> <string name="reading_opml_label">Leyendo el archivo OPML</string> - <string name="opml_reader_error">Error al leer el documento OPML</string> + <string name="opml_reader_error">Error al leer el documento OPML:</string> <string name="opml_import_error_no_file">¡Debes seleccionar un archivo!</string> <string name="select_all_label">Seleccionar todo</string> <string name="deselect_all_label">Deseleccionar todo</string> <string name="select_options_label">Seleccionar…</string> <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="choose_file_from_external_application">Usar una 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> - <string name="opml_export_success_sum">El archivo OPML se ha escrito en:\u0020</string> - <string name="opml_import_ask_read_permission">Es necesario el acceso al almacenamiento externo para leer archivos OPML</string> + <string name="export_success_title">Exportación exitosa</string> + <string name="export_success_sum">El archivo exportado fue guardado en:\n\n%1$s</string> + <string name="opml_import_ask_read_permission">Necesita acceso al almacenamiento externo para leer archivos OPML</string> <!--Sleep timer--> <string name="set_sleeptimer_label">Establecer un temporizador</string> <string name="disable_sleeptimer_label">Desactivar el temporizador</string> <string name="enter_time_here_label">Introducir hora</string> <string name="sleep_timer_label">Temporizador</string> <string name="time_left_label">Tiempo restante:\u0020</string> - <string name="time_dialog_invalid_input">Entrada no válida, el tiempo debe ser un entero</string> - <string name="timer_about_to_expire_label"><b>Cuando el temporizador vaya a expirara:</b></string> - <string name="shake_to_reset_label">Agitar para reiniciar temporizador</string> + <string name="time_dialog_invalid_input">Entrada no válida, el tiempo debe ser un número entero</string> + <string name="timer_about_to_expire_label"><b>Cuando el temporizador vaya a expirar:</b></string> + <string name="shake_to_reset_label">Agitar para reiniciar el temporizador</string> <string name="timer_vibration_label">Vibrar</string> <string name="time_seconds">segundos</string> <string name="time_minutes">minutos</string> @@ -479,22 +505,22 @@ <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> + <string name="auto_enable_label">Autohabilitar</string> + <string name="sleep_timer_enabled_label">Temporizador habilitado</string> + <string name="sleep_timer_disabled_label">Temporizador deshabilitado</string> <!--gpodder.net--> <string name="gpodnet_taglist_header">CATEGORÃAS</string> - <string name="gpodnet_toplist_header">MEJORES PODCASTS</string> + <string name="gpodnet_toplist_header">MEJORES PÓDCAST</string> <string name="gpodnet_suggestions_header">SUGERENCIAS</string> <string name="gpodnet_search_hint">Buscar en gpodder.net</string> <string name="gpodnetauth_login_title">Iniciar sesión</string> - <string name="gpodnetauth_login_descr">Bienvenido al proceso de autenticación de gpodder.net. Primero, escriba sus datos de inicio de sesión:</string> + <string name="gpodnetauth_login_descr">Bienvenidoinicio de sesión de gpodder.net. Primero, escriba sus datos de inicio de sesión:</string> <string name="gpodnetauth_login_butLabel">Iniciar sesión</string> - <string name="gpodnetauth_login_register">Si no tienes una cuenta aún, puedes crearla en:\nhttps://gpodder.net/register/</string> - <string name="username_label">Nombre de usuario</string> + <string name="gpodnetauth_login_register">Si aún no tienes una cuenta, puedes crearla en:\nhttps://gpodder.net/register/</string> + <string name="username_label">Usuario</string> <string name="password_label">Contraseña</string> <string name="gpodnetauth_device_title">Selección del dispositivo</string> - <string name="gpodnetauth_device_descr">Cree un nuevo dispositivo para usar con su cuenta de gpodder.net o elija uno existente:</string> + <string name="gpodnetauth_device_descr">Cree un nuevo dispositivo para usar en su cuenta de gpodder.net o elija uno existente:</string> <string name="gpodnetauth_device_deviceID">Id. de dispositivo:\u0020</string> <string name="gpodnetauth_device_caption">Descripción</string> <string name="gpodnetauth_device_butCreateNewDevice">Crear dispositivo nuevo</string> @@ -507,7 +533,7 @@ <string name="gpodnetauth_finish_descr">¡Enhorabuena! Su cuenta de gpodder.net está ahora asociada con su dispositivo. A partir de ahora AntennaPod sincronizará automáticamente las suscripciones de su dispositivo con su cuenta de gpodder.net.</string> <string name="gpodnetauth_finish_butsyncnow">Comenzar sincronización ahora</string> <string name="gpodnetauth_finish_butgomainscreen">Ir a la pantalla principal</string> - <string name="gpodnetsync_auth_error_title">Error de autenticación de gpodder.net</string> + <string name="gpodnetsync_auth_error_title">Error de autenticación en gpodder.net</string> <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> @@ -518,10 +544,10 @@ <string name="create_folder_label">Crear carpeta</string> <string name="choose_data_directory">Elegir carpeta de datos</string> <string name="choose_data_directory_message">Por favor elige la raÃz de la carpeta de datos. AntennaPod creará los subdirectorios apropiados.</string> - <string name="choose_data_directory_permission_rationale">Se necesita acceso a almacenamiento externo para cambiar la carpeta de datos</string> - <string name="create_folder_msg">¿Crear carpeta con nombre «%1$s»?</string> + <string name="choose_data_directory_permission_rationale">Necesita acceso al almacenamiento externo para cambiar la carpeta de datos</string> + <string name="create_folder_msg">¿Crear carpeta con nombre \"%1$s\"?</string> <string name="create_folder_success">Carpeta creada</string> - <string name="create_folder_error_no_write_access">No se puede escribir a esta carpeta</string> + <string name="create_folder_error_no_write_access">No se puede escribir en esta carpeta</string> <string name="create_folder_error_already_exists">Ya existe la carpeta</string> <string name="create_folder_error">No se ha podido crear la carpeta</string> <string name="folder_does_not_exist_error">\"%1$s\" no existe</string> @@ -532,7 +558,7 @@ <string name="set_to_default_folder">Elegir carpeta predeterminada</string> <string name="pref_pausePlaybackForFocusLoss_sum">Pausar la reproducción en lugar de bajar el volumen cuando otra aplicación reproduzca sonidos</string> <string name="pref_pausePlaybackForFocusLoss_title">Pausar durante las interrupciones</string> - <string name="pref_resumeAfterCall_sum">Reanudar reproducción tras una llamada</string> + <string name="pref_resumeAfterCall_sum">Reanudar la reproducción tras una llamada</string> <string name="pref_resumeAfterCall_title">Reanudar tras una llamada</string> <string name="pref_restart_required">Es necesario reiniciar AntennaPod para aplicar los cambios.</string> <!--Online feed view--> @@ -540,8 +566,8 @@ <string name="subscribed_label">Suscrito</string> <string name="downloading_label">Descargando…</string> <!--Content descriptions for image buttons--> - <string name="rewind_label">Rebobinar</string> - <string name="fast_forward_label">Avance rápido</string> + <string name="rewind_label">Retroceso</string> + <string name="fast_forward_label">Avance</string> <string name="media_type_audio_label">Audio</string> <string name="media_type_video_label">VÃdeo</string> <string name="navigate_upwards_label">Navegar hacia arriba</string> @@ -551,40 +577,40 @@ <string name="load_next_page_label">Cargar la página siguiente</string> <!--Feed information screen--> <string name="authentication_label">Autenticación</string> - <string name="authentication_descr">Cambiar nombre y contraseña de este podcast y sus episodios</string> - <string name="auto_download_settings_label">Opciones de Auto Descarga</string> - <string name="episode_filters_label">Filtro de Episodios</string> - <string name="episode_filters_description">Listado de términos para decidir si un episodio debe ser incluÃdo o excluÃdo al auto descargar</string> + <string name="authentication_descr">Cambiar nombre y contraseña de este pódcast y sus episodios</string> + <string name="auto_download_settings_label">Opciones de descarga automática</string> + <string name="episode_filters_label">Filtro de episodios</string> + <string name="episode_filters_description">Lista de términos usados para decidir si un episodio debe ser incluÃdo o excluÃdo de la descarga automática</string> <string name="episode_filters_include">Incluir</string> <string name="episode_filters_exclude">Excluir</string> - <string name="episode_filters_hint">Palabras sueltas \n\"Múltiples palabras\"</string> + <string name="episode_filters_hint">Palabras sueltas \n\"múltiples palabras\"</string> <string name="keep_updated">Mantener actualizado</string> <!--Progress information--> <string name="progress_upgrading_database">Actualizando la base de datos</string> <!--AntennaPodSP--> - <string name="sp_apps_importing_feeds_msg">Importando subscripciones de aplicaciones de uso especÃfico...</string> + <string name="sp_apps_importing_feeds_msg">Importando suscripciones 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> + <string name="search_fyyd_label">Buscar en fyyd</string> <!--Episodes apply actions--> - <string name="all_label">Todo</string> - <string name="selected_all_label">Seleccionados todos los episodios</string> + <string name="all_label">Todos</string> + <string name="selected_all_label">Todos los episodios seleccionados</string> <string name="none_label">Ninguno</string> - <string name="deselected_all_label">Deseleccionados todos los episodios</string> - <string name="played_label">Reproducido</string> - <string name="selected_played_label">Seleccionados episodios reproducidos</string> + <string name="deselected_all_label">Ningún episodio seleccionado</string> + <string name="played_label">Reproducidos</string> + <string name="selected_played_label">Episodios reproducidos seleccionados</string> <string name="unplayed_label">No reproducidos</string> - <string name="selected_unplayed_label">Seleccionados episodios no reproducidos</string> - <string name="downloaded_label">Descargado</string> - <string name="selected_downloaded_label">Seleccionados episodios descargados</string> + <string name="selected_unplayed_label">Episodios no reproducidos seleccionados</string> + <string name="downloaded_label">Descargados</string> + <string name="selected_downloaded_label">Episodios descargados seleccionados</string> <string name="not_downloaded_label">No descargado</string> - <string name="selected_not_downloaded_label">Seleccionados episodios no descargados</string> + <string name="selected_not_downloaded_label">Episodios no descargados seleccionados</string> <string name="queued_label">En cola</string> - <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="selected_queued_label">Episodios en cola seleccionados</string> + <string name="not_queued_label">No están en cola</string> + <string name="selected_not_queued_label">Episodios que no están en cola seleccionados</string> <string name="has_media">Tiene multimedia</string> - <string name="selected_has_media_label">Seleccionar episodios con multimedia</string> + <string name="selected_has_media_label">Episodios con multimedia seleccionados</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> @@ -594,9 +620,9 @@ <string name="sort_duration_long_short">Duración (Largo \u2192 Corto)</string> <!--Rating dialog--> <string name="rating_title">¿Te gusta AntennaPod?</string> - <string name="rating_message">EstarÃamos muy agradecidos si nos dedicas un tiempo para puntuar AntennaPod</string> + <string name="rating_message">EstarÃamos muy agradecidos si nos dedicas un poco de tiempo para valorar AntennaPod.</string> <string name="rating_never_label">Déjame en paz</string> - <string name="rating_later_label">Recuérdamelo después</string> + <string name="rating_later_label">Recuérdamelo más tarde</string> <string name="rating_now_label">¡Venga, hagámoslo!</string> <!--Audio controls--> <string name="audio_controls">Controles de audio</string> @@ -605,42 +631,51 @@ <string name="left_short">I</string> <string name="right_short">D</string> <string name="audio_effects">Efectos de audio</string> - <string name="stereo_to_mono">Downmix: De estereo a mono</string> - <string name="sonic_only">Sólo Sonic</string> + <string name="stereo_to_mono">Mezclar: de estéreo a mono</string> + <string name="sonic_only">Solo Sonic</string> <!--proxy settings--> <string name="proxy_type_label">Tipo</string> <string name="host_label">Host</string> <string name="port_label">Puerto</string> <string name="optional_hint">(Opcional)</string> - <string name="proxy_test_label">Probar</string> - <string name="proxy_checking">Comprobando...</string> + <string name="proxy_test_label">Test</string> + <string name="proxy_checking">Comprobando…</string> <string name="proxy_test_successful">Test correcto</string> <string name="proxy_test_failed">Test fallido</string> <string name="proxy_host_empty_error">El host no puede estar en blanco</string> - <string name="proxy_host_invalid_error">El host no es una IP ni un host válido</string> - <string name="proxy_port_invalid_error">Puerto inválido</string> + <string name="proxy_host_invalid_error">El host no es una dirección IP o dominio válido</string> + <string name="proxy_port_invalid_error">Puerto no válido</string> <!--Database import/export--> <string name="import_export">Importar/Exportar base de datos</string> - <string name="import_export_warning">Esta función experimental se puede usar para transferir tus suscripciones y episodios reproducidos a otro dispositivo.\n\nLas base de datos exportadas solo se pueden importar cuando se usa la misma versión de AntennaPod. En otro caso, esta función podrÃa provocar comportamiento inesperado.\n\nDespués de importar, los episodios podrÃan mostrarse como descargados cuando no lo están. Reproduce estos episodios para que AntennaPod lo detecte.</string> + <string name="import_export_warning">Esta función experimental se puede usar para transferir sus suscripciones y episodios reproducidos a otro dispositivo.\n\nLas bases de datos exportadas solo se pueden importar cuando se usa la misma versión de AntennaPod. En otro caso, esta función podrÃa provocar un comportamiento inesperado.\n\nDespués de la importación, los episodios podrÃan mostrarse como descargados cuando no lo están. Presione el botón de reproducción de los episodios para que AntennaPod lo detecte.</string> <string name="label_import">Importar</string> <string name="label_export">Exportar</string> - <string name="import_select_file">Seleccionar firchero a importar</string> - <string name="export_ok">Exportación exitosa. La base de datos se guardó en la tarjeta SD.</string> - <string name="import_ok">Importación exitosa.\n\nPor favor, pulse OK para reiniciar AntennaPod</string> + <string name="import_select_file">Seleccionar archivo a importar</string> + <string name="export_ok">Exportación exitosa.</string> + <string name="import_ok">Importación exitosa.\n\nPulse OK para reiniciar AntennaPod</string> <!--Casting--> - <string name="cast_media_route_menu_title">Reproducir en...</string> - <string name="cast_disconnect_label">Desconectar la sesión Cast</string> - <string name="cast_not_castable">El medio seleccionado no es compatible con el dispositivo Cast</string> - <string name="cast_failed_to_play">Fallo al iniciar la reproducción del medio</string> - <string name="cast_failed_to_stop">Fallo al detener la reproducción del medio</string> - <string name="cast_failed_to_pause">Fallo al pausar la reproducción del medio</string> + <string name="cast_media_route_menu_title">Reproducir en…</string> + <string name="cast_disconnect_label">Desconectar la sesión de cast</string> + <string name="cast_not_castable">El medio seleccionado no es compatible con el dispositivo de cast</string> + <string name="cast_failed_to_play">Error al iniciar la reproducción del medio</string> + <string name="cast_failed_to_stop">Error al detener la reproducción del medio</string> + <string name="cast_failed_to_pause">Error al pausar la reproducción del medio</string> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> - <string name="cast_failed_setting_volume">Fallo al ajustar el volumen</string> - <string name="cast_failed_no_connection">No hay conexión con el dispositivo Cast</string> - <string name="cast_failed_no_connection_trans">Se ha perdido la conexión con el dispositivo Cast. La aplicación está intentando reconectar. Por favor, espera unos segundos e intenta de nuevo.</string> - <string name="cast_failed_perform_action">Fallo en la acción</string> - <string name="cast_failed_status_request">Fallo al sincronizar con el dispositivo Cast</string> - <string name="cast_failed_seek">Fallo al cambiar de posición en el dispositivo Cast</string> + <string name="cast_failed_setting_volume">Error al ajustar el volumen</string> + <string name="cast_failed_no_connection">No hay ninguna conexión con el dispositivo de cast</string> + <string name="cast_failed_no_connection_trans">Se ha perdido la conexión con dispositivo de cast. La aplicación está intentando restablecer la conexión. Espere unos segundos y vuelva a intentarlo.</string> + <string name="cast_failed_perform_action">Error al realizar la acción</string> + <string name="cast_failed_status_request">Error al sincronizar con el dispositivo de cast</string> + <string name="cast_failed_seek">Error al buscar la nueva posición en el dispositivo de cast</string> <string name="cast_failed_receiver_player_error">El reproductor ha encontrado un error grave</string> - <string name="cast_failed_media_error_skipping">Error reproduciendo medio. Saltando...</string> + <string name="cast_failed_media_error_skipping">Error reproduciendo medio. Saltando…</string> + <!--Notification channels--> + <string name="notification_channel_user_action">Acción necesaria</string> + <string name="notification_channel_user_action_description">Se muestra si su acción es necesaria, por ejemplo, si necesita introducir una contraseña.</string> + <string name="notification_channel_downloading">Descargando</string> + <string name="notification_channel_downloading_description">Se muestra mientras se está descargando.</string> + <string name="notification_channel_playing">Reproduciendo</string> + <string name="notification_channel_playing_description">Permite controlar la reproducción. Es la notificación principal que se ve mientras se reproduce un pódcast.</string> + <string name="notification_channel_error">Errores</string> + <string name="notification_channel_error_description">Muestra si algo salió mal, por ejemplo, si falla la descarga o la sincronización de gpodder</string> </resources> diff --git a/core/src/main/res/values-et/strings.xml b/core/src/main/res/values-et/strings.xml index d7afdf834..9d5673751 100644 --- a/core/src/main/res/values-et/strings.xml +++ b/core/src/main/res/values-et/strings.xml @@ -48,7 +48,6 @@ <string name="yes">Jah</string> <string name="no">Ei</string> <string name="reset">Nulli</string> - <string name="author_label">Autor</string> <string name="language_label">Keel</string> <string name="url_label">URL</string> <string name="podcast_settings_label">Seaded</string> @@ -93,18 +92,11 @@ <string name="mark_all_read_label">Märgi kuulatuks</string> <string name="mark_all_read_msg">Märgi kõik saated esitatuks</string> <string name="mark_all_seen_label">Märgi kõik nähtuks</string> - <string name="mark_all_seen_msg">Märgi kõik saated nähtuks</string> <string name="show_info_label">Näita infot</string> - <string name="rename_feed_label">Nimeta taskuhääling ümber</string> - <string name="remove_feed_label">Eemalda taskuhääling</string> <string name="share_label">Jaga...</string> - <string name="share_link_label">Jaga linki</string> - <string name="share_link_with_position_label">Jaga linki koos asukohaga</string> + <string name="share_file_label">Jaga faili</string> <string name="share_feed_url_label">Jaga uudisvoo URL-i</string> - <string name="feed_remover_msg">Uudisvoo eemaldamine</string> - <string name="load_complete_feed">Värskenda kogu uudisvoogu</string> <string name="hide_episodes_title">Peida saated</string> - <string name="episode_actions">Rakenda tegevused</string> <string name="hide_unplayed_episodes_label">Esitamata</string> <string name="hide_paused_episodes_label">Peatatud</string> <string name="hide_played_episodes_label">Esitatud</string> @@ -147,6 +139,7 @@ <string name="download_failed">ebaõnnestus</string> <string name="download_pending">Ootel allalaadimine</string> <string name="download_running">Allalaadimine on käimas</string> + <string name="download_error_details">Ãœksikasjad</string> <string name="download_error_device_not_found">Salvestuskohta ei leitud</string> <string name="download_error_insufficient_space">Pole piisavalt ruumi</string> <string name="download_error_file_error">Faili viga</string> @@ -207,7 +200,6 @@ <string name="date">Kuupäeva järgi</string> <string name="duration">Kestuse järgi</string> <string name="episode_title">Saate pealkiri</string> - <string name="feed_title">Uudisvoo pealkiri</string> <string name="ascending">Kasvavalt</string> <string name="descending">Kahanevalt</string> <!--Flattr--> @@ -224,7 +216,6 @@ <string name="enable_sonic">Luba Sonicu kasutamine</string> <!--Empty list labels--> <string name="no_items_label">Selles nimekirjas pole midagi.</string> - <string name="no_feeds_label">Sa pole veel ühtegi uusidvoogi tellinud.</string> <string name="no_chapters_label">Saatel pole peatükke.</string> <string name="no_shownotes_label">Sellel saatel pole mingeid märkusi.</string> <!--Preferences--> @@ -233,7 +224,6 @@ <string name="other_pref">Muud</string> <string name="about_pref">Info</string> <string name="queue_label">Järjekord</string> - <string name="services_label">Teenused</string> <string name="flattr_label">Flattr</string> <string name="pref_episode_cleanup_title">Saadete kustutamien</string> <string name="pref_followQueue_sum">Kui saade lõpeb, siis esita kohe järgmine järjekorras olev saade.</string> @@ -241,6 +231,7 @@ <string name="pref_auto_delete_title">Automaatne kustutamine</string> <string name="pref_skip_keeps_episodes_sum">Hoia saated alles, kui need jäetakse vahele</string> <string name="pref_skip_keeps_episodes_title">Hoia vahelejäetud osad alles</string> + <string name="pref_favorite_keeps_episodes_title">Säilita lemmikosad</string> <string name="playback_pref">Esitamine</string> <string name="network_pref">Võrk</string> <string name="pref_autoUpdateIntervallOrTime_title">Uuendamise intervall või kellaaeg</string> @@ -293,8 +284,6 @@ <string name="pref_playback_speed_title">Esitamise kiirused</string> <string name="pref_gpodnet_sethostname_title">Määra hostinimi</string> <string name="pref_gpodnet_sethostname_use_default_host">Kasuta vaikimisi hosti</string> - <string name="pref_expandNotify_title">Teavituste laiendamine</string> - <string name="pref_expandNotify_sum">Näita alati teavitustes pleieri nuppe.</string> <string name="pref_persistNotify_title">Püsivad taasesitamise nupud</string> <string name="pref_compact_notification_buttons_title">Määra lukustutekraani nupud</string> <string name="pref_lockscreen_background_title">Määra lukustusekraani taustapilt</string> @@ -342,8 +331,6 @@ <string name="html_export_label">HTML eksport</string> <string name="exporting_label">Eksportimine...</string> <string name="export_error_label">Viga eksportimisel</string> - <string name="opml_export_success_title">OPML eksport oli edukas.</string> - <string name="opml_export_success_sum">.opml fail kirjutati kausta:\u0020</string> <!--Sleep timer--> <string name="set_sleeptimer_label">Määra unetaimer</string> <string name="disable_sleeptimer_label">Keela unetaimer</string> @@ -368,6 +355,9 @@ <item quantity="one">1 tund</item> <item quantity="other">%d tundi</item> </plurals> + <string name="auto_enable_label">Automaatne kustutamine</string> + <string name="sleep_timer_enabled_label">Unetaimer on sisse lülitatud</string> + <string name="sleep_timer_disabled_label">Unetaimer on välja lülitatud</string> <!--gpodder.net--> <string name="gpodnet_taglist_header">KATEGOORIAD</string> <string name="gpodnet_toplist_header">POPIMAD TASKUHÄÄLINGUD</string> @@ -385,6 +375,7 @@ <string name="gpodnetauth_device_chooseExistingDevice">Vali olemasolev seade:</string> <string name="gpodnetauth_device_errorEmpty">Seadme ID ei tohi olla tühi</string> <string name="gpodnetauth_device_errorAlreadyUsed">Seadme ID on juba kasutuses</string> + <string name="gpodnetauth_device_caption_errorEmpty">Pealkiri ei tohi olla tühi</string> <string name="gpodnetauth_device_butChoose">Vali</string> <string name="gpodnetauth_finish_title">Sisse logitud!</string> <string name="gpodnetauth_finish_butsyncnow">Alusta kohe sünkroonimist</string> @@ -490,9 +481,17 @@ <string name="proxy_test_successful">Kontroll oli edukas</string> <string name="proxy_test_failed">Kontroll ebaõnnestus</string> <string name="proxy_host_empty_error">Hostinimi ei saa olla tühi</string> + <string name="proxy_host_invalid_error">Se pole korrektne IP aadress või domeen</string> <string name="proxy_port_invalid_error">Port pole korrektne</string> <!--Database import/export--> + <string name="import_export">Andmebaasi importimine/eksportimine</string> + <string name="label_import">Impordi</string> + <string name="label_export">Ekspordi</string> + <string name="import_select_file">Vali fail, mida importida</string> + <string name="export_ok">Eksportimine on sooritatud.</string> <!--Casting--> <string name="cast_media_route_menu_title">Esita...</string> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <string name="cast_failed_media_error_skipping">Tõrge meedia esitamisel. Jätame vahele...</string> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-fa/strings.xml b/core/src/main/res/values-fa/strings.xml index fb8bb5e7c..dc6e7cb2e 100644 --- a/core/src/main/res/values-fa/strings.xml +++ b/core/src/main/res/values-fa/strings.xml @@ -1,15 +1,17 @@ <?xml version='1.0' encoding='UTF-8'?> <resources xmlns:tools="http://schemas.android.com/tools"> <!--Activitiy and fragment titles--> + <string name="feed_update_receiver_name">به‌روز رسانی اشتراک‌ها</string> <string name="feeds_label">خوراک</string> <string name="statistics_label">آمار</string> <string name="add_feed_label">اضاÙÙ‡ کردن پادکست</string> - <string name="episodes_label">قسمت ها</string> + <string name="episodes_label">قسمت‌ها</string> <string name="all_episodes_short_label">همه</string> + <string name="new_episodes_label">جدید</string> <string name="favorite_episodes_label">علاقه مندی ها</string> <string name="new_label">جدید</string> <string name="settings_label">تنظیمات</string> - <string name="downloads_label">دانلودها</string> + <string name="downloads_label">بارگیری‌ها</string> <string name="downloads_running_label">در Øال اجرا</string> <string name="downloads_completed_label">تکمیل شده</string> <string name="downloads_log_label">log</string> @@ -18,10 +20,12 @@ <string name="cancel_download_label">بارگیری n\ لغو</string> <string name="playback_history_label">تاریخچه پخش</string> <string name="gpodnet_main_label">gpodder.net</string> + <string name="gpodnet_summary">هم‌گام‌سازی با دیگر دستگاه‌ها</string> <string name="gpodnet_auth_label">gpodder.net Login</string> <string name="free_space_label">%1$s free </string> <string name="episode_cache_full_title">ظرÙیت ØاÙظه پنهان تکمیل شده است</string> <string name="episode_cache_full_message">Øد مجاز تکمیل شده است . شما Ù…ÛŒ توانید اندازه ØاÙظه پنهان را در تنظیمات اÙزایش دهید.</string> + <string name="synchronizing">در Øال هم‌گام‌سازی</string> <!--Statistics fragment--> <string name="total_time_listened_to_podcasts">مجموع زمان پخش پادکست ها:</string> <string name="statistics_mode">Øالت آمار</string> @@ -35,11 +39,11 @@ <string name="drawer_feed_order_unplayed_episodes">مرتب سازی بر اساس شمارنده</string> <string name="drawer_feed_order_alphabetical">مرتب سازی بر اساس Øرو٠الÙبا</string> <string name="drawer_feed_order_last_update">مرتب سازی بر اساس تاریخ انتشار</string> - <string name="drawer_feed_order_most_played">مرتب سازی بر اساس تعداد قسمت پخش شده</string> - <string name="drawer_feed_counter_new_unplayed">تعداد قسمت های جدید Ùˆ پخش نشده</string> - <string name="drawer_feed_counter_new">تعداد قسمت های جدید</string> - <string name="drawer_feed_counter_unplayed">تعداد قسمت های پخش نشده</string> - <string name="drawer_feed_counter_downloaded">تعداد قسمت های دانلود شده</string> + <string name="drawer_feed_order_most_played">مرتب‌سازی بر اساس تعداد قسمت پخش شده</string> + <string name="drawer_feed_counter_new_unplayed">تعداد قسمت‌های جدید Ùˆ پخش نشده</string> + <string name="drawer_feed_counter_new">تعداد قسمت‌های جدید</string> + <string name="drawer_feed_counter_unplayed">تعداد قسمت‌های پخش نشده</string> + <string name="drawer_feed_counter_downloaded">تعداد قسمت‌های بارگیری شده</string> <string name="drawer_feed_counter_none">هیچ یک</string> <!--Webview actions--> <string name="open_in_browser_label">باز کردن در مرور گر</string> @@ -55,7 +59,7 @@ <string name="yes">بله</string> <string name="no">خیر</string> <string name="reset">بازنشانی</string> - <string name="author_label">نویسنده</string> + <string name="author_label">مؤلÙ(ها)</string> <string name="language_label">زبان</string> <string name="url_label">URL</string> <string name="podcast_settings_label">تنظیمات</string> @@ -69,7 +73,7 @@ <string name="shownotes_label">Shownotes</string> <string name="description_label">شرØ</string> <string name="most_recent_prefix">آخرین قسمت: \u0020</string> - <string name="episodes_suffix">\u0020قسمت ها</string> + <string name="episodes_suffix">\u0020قسمت</string> <string name="length_prefix">طول:\u0020</string> <string name="size_prefix">Øجم:\u0020</string> <string name="processing_label">در Øال پردازش</string> @@ -78,10 +82,10 @@ <string name="close_label">بستن</string> <string name="retry_label">تلاش مجدد</string> <string name="auto_download_label">شامل در دریاÙت خودکار است</string> - <string name="auto_download_apply_to_items_title">اعمال به قسمت های قبلی</string> - <string name="auto_download_apply_to_items_message">تنظیمات جدید<i>دانلود خودکار</i> به طور اتوماتیک به قسمت های جدید اعمال خواهد شد. \ n آیا شما همچنین Ù…ÛŒ خواهید آن را به قسمت هایی Ú©Ù‡ قبلا منتشر شده اعمال کنید؟</string> - <string name="auto_delete_label">Øذ٠خودکار قسمت ها </string> - <string name="parallel_downloads_suffix">\u0020دانلود همزمان</string> + <string name="auto_download_apply_to_items_title">اعمال بر قسمت‌های قبلی</string> + <string name="auto_download_apply_to_items_message">تنظیمات جدید<i>بارگیری خودکار</i> به طور خودکار بر قسمت‌های جدید اعمال خواهد شد.\n آیا می‌خواهید آن را بر قسمت‌هایی Ú©Ù‡ قبلا منتشر شده نیز اعمال کنید؟</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">Never</string> @@ -90,6 +94,7 @@ <string name="episode_cleanup_queue_removal">وقتی Ú©Ù‡ در ص٠نیست</string> <string name="episode_cleanup_after_listening">بعد از تمام شدن</string> <plurals name="episode_cleanup_days_after_listening"> + <item quantity="one">%dروز بعد از اتمام</item> <item quantity="other">%dروز بعد از اتمام</item> </plurals> <!--'Add Feed' Activity labels--> @@ -101,46 +106,45 @@ <string name="browse_gpoddernet_label">Browse gpodder.net</string> <!--Actions on feeds--> <string name="mark_all_read_label">علامت گذاری همه به عنوان پخش شده</string> - <string name="mark_all_read_msg">همه قسمت ها به عنوان پخش شده علامت گذاری شد.</string> - <string name="mark_all_read_confirmation_msg">لطÙا تأیید کنید Ú©Ù‡ میخواهید تمام قسمتها را بعنوان پخش شده علامت بزنید.</string> - <string name="mark_all_read_feed_confirmation_msg">لطÙا تأیید کنید Ú©Ù‡ میخواهید تمام قسمتهای این خوراک را بعنوان پخش شده علامت بزنید.</string> + <string name="mark_all_read_msg">همه قسمت‌ها به عنوان پخش شده علامت‌گذاری شد</string> + <string name="mark_all_read_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="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="show_feed_settings_label">نمایش تنظیمات پادکست</string> + <string name="feed_info_label">اطلاعات پادکست</string> + <string name="feed_settings_label">تنظیمات پادکست</string> + <string name="rename_feed_label">تغییر نام پادکست</string> + <string name="remove_feed_label">پاک‌کردن پادکست</string> <string name="share_label">اشتراک گذاری...</string> - <string name="share_link_label">اشتراک گذاری لینک</string> + <string name="share_link_label">هم‌رسانی نشانی پادکست</string> <string name="share_file_label">اشتراک گذاری Ùایل</string> - <string name="share_link_with_position_label">اشتراک گذاری لینک با موقعیت پخش</string> <string name="share_feed_url_label">اشتراک گذاری URL خوراک </string> - <string name="share_item_url_label">اشتراک گذاری Ùایل URL قسمت</string> - <string name="share_item_url_with_position_label">اشتراک گذاری Ùایل URL قسمت با موقعیت پخش</string> - <string name="feed_delete_confirmation_msg">لطÙا تأیید کنید Ú©Ù‡ میخواهید خوراک \"%1$s\" Ùˆ تمام قسمتهای آن Ú©Ù‡ دانلود کرده اید را Øذ٠کنید.</string> - <string name="feed_remover_msg">Øذ٠خوراک</string> - <string name="load_complete_feed">تازه کردن کامل خوراک</string> - <string name="hide_episodes_title">پنهان کردن قسمت ها</string> - <string name="episode_actions">درخواست اعمال</string> + <string name="share_item_url_label">هم‌رسانی نشانی پرونده رسانه</string> + <string name="feed_remover_msg">در Øال پاک‌کردن پادکست</string> + <string name="load_complete_feed">تازه‌سازی تمام پادکست</string> + <string name="hide_episodes_title">پنهان کردن قسمت‌ها</string> + <string name="batch_edit">ویرایش گروهی</string> <string name="hide_unplayed_episodes_label">پخش نشده</string> <string name="hide_paused_episodes_label">متوق٠شد</string> <string name="hide_played_episodes_label">پخش شد</string> <string name="hide_queued_episodes_label">در صÙ</string> <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_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="open_podcast">باز کردن پادکست</string> <!--actions on feeditems--> - <string name="download_label">دانلود</string> + <string name="download_label">بارگیری</string> <string name="play_label">پخش</string> <string name="pause_label">Ù…Ú©Ø«</string> <string name="stop_label">توقÙ</string> + <string name="stream_label">جریان</string> <string name="remove_label">ØØ°Ù</string> <string name="delete_label">ØØ°Ù</string> <string name="delete_failed">Ùایل Øذ٠نشد.! راه اندازی مجدد دستگاه Ù…ÛŒ تواند Ú©Ù…Ú© کند.</string> - <string name="remove_episode_lable">Øذ٠قسمت</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> @@ -152,16 +156,19 @@ <string name="added_to_favorites">به موارد دلخواه اضاÙÙ‡ شد.</string> <string name="remove_from_favorite_label">از علاقه مندی ها Øذ٠شود</string> <string name="removed_from_favorites">از موارد دلخواه Øذ٠شد.</string> + <string name="visit_website_label">مشاهده وب‌سایت</string> <string name="skip_episode_label">رد شدن از قسمت</string> - <string name="activate_auto_download">Ùعال کردن دانلود خودکار</string> - <string name="deactivate_auto_download">غیر Ùعال کردن دانلود خودکار</string> + <string name="activate_auto_download">Ùعال کردن بارگیری خودکار</string> + <string name="deactivate_auto_download">غیر Ùعال کردن بارگیری خودکار</string> <string name="reset_position">تنظیم مجدد موقعیت پخش</string> <string name="removed_item">مورد Øذ٠شده است</string> <!--Download messages and labels--> <string name="download_successful">موÙقیت آمیز</string> <string name="download_failed">ناموÙÙ‚</string> - <string name="download_pending">دانلود در Øال انتظار</string> - <string name="download_running">دانلود در Øال اجرا</string> + <string name="download_pending">بارگیری معوق</string> + <string name="download_running">بارگیری در Øال اجرا</string> + <string name="download_error_details">جزئیات</string> + <string name="download_error_details_message">%1$s\n\nنشانی پرونده:\n%2$s</string> <string name="download_error_device_not_found">ØاÙظه خارجی یاÙت نشد.</string> <string name="download_error_insufficient_space">Ùضای ناکاÙÛŒ</string> <string name="download_error_file_error">خطای Ùایل</string> @@ -171,24 +178,121 @@ <string name="download_error_connection_error">خطای اتصال</string> <string name="download_error_unknown_host">میزبان ناشناس</string> <string name="download_error_unauthorized">خطای اØراز هویت</string> - <string name="cancel_all_downloads_label">لغو همه دانلودها</string> - <string name="download_canceled_msg">دانلود لغو شد.</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> + <string name="download_report_title">بارگیری‌ها با خطا(ها) کامل شد</string> + <string name="download_report_content_title">گزارش بارگیری</string> + <string name="download_error_io_error">خطای ورودی/خروجی</string> + <string name="download_error_request_error">خطای درخواست</string> + <string name="download_error_db_access">خطای دسترسی به پایگاه‌داده</string> + <string name="downloads_processing">پردازش بارگیری‌ها</string> + <string name="download_notification_title">بارگیری داده پادکست</string> + <string name="download_log_title_unknown">عنوان ناشناخته</string> <string name="download_type_feed">خوراک</string> + <string name="download_type_media">پرونده رسانه</string> + <string name="download_type_image">تصویر</string> + <string name="confirm_mobile_download_dialog_enable_temporarily">اجازه موقت</string> <!--Mediaplayer messages--> + <string name="player_error_msg">خطا!</string> + <string name="player_stopped_msg">رسانه‌ای در Øال پخش نیست</string> + <string name="player_preparing_msg">آماده‌سازی</string> + <string name="player_ready_msg">آماده</string> + <string name="playback_error_unknown">خطای ناشناخته</string> + <string name="no_media_playing_label">رسانه‌ای در Øال پخش نیست</string> + <string name="player_go_to_picture_in_picture">Øالت تصویر در تصویر</string> + <string name="playbackservice_notification_title">در Øال پخش پادکست</string> <!--Queue operations--> + <string name="clear_queue_label">پاک‌کردن صÙ</string> + <string name="sort">مرتب‌سازی</string> + <string name="date">تاریخ</string> + <string name="duration">مدت</string> + <string name="episode_title">عنوان قسمت</string> + <string name="feed_title">عنوان پادکست</string> + <string name="random">تصادÙÛŒ</string> <!--Flattr--> + <string name="return_home_label">بازگشت به خانه</string> <!--Flattr--> <!--Variable Speed--> <!--Empty list labels--> <!--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> + <string name="download_pref_details">جزئیات</string> + <string name="import_export_pref">وارد/صادر کرد</string> + <string name="appearance">نمایش</string> + <string name="external_elements">عناصر خارجی</string> + <string name="buttons">دکمه‌های کنترل پخش</string> + <string name="media_player">پخش‌کننده رسانه</string> + <string name="pref_auto_delete_title">Øذ٠خودکار</string> + <string name="playback_pref">پخش</string> + <string name="network_pref">شبکه</string> + <string name="user_interface_label">رابط کاربری</string> + <string name="pref_set_theme_title">انتخاب پوسته</string> + <string name="pref_theme_title_light">روشن</string> + <string name="pref_theme_title_dark">تاریک</string> + <string name="pref_theme_title_trueblack">سیاه (مناسب AMOLED)</string> + <string name="pref_episode_cache_unlimited">نامØدود</string> + <string name="pref_update_interval_hours_plural">ساعت</string> + <string name="pref_update_interval_hours_singular">ساعت</string> + <string name="pref_update_interval_hours_manual">دستی</string> + <string name="pref_gpodnet_authenticate_title">ورود</string> + <string name="pref_gpodnet_logout_title">خروج</string> + <string name="pref_gpodnet_logout_toast">خروج موÙقیت‌آمیز بود</string> + <string name="pref_gpodnet_setlogin_information_title">تغییر اطلاعات ورود</string> + <string name="pref_playback_speed_title">سرعت‌های پخش</string> + <string name="pref_lockscreen_background_title">تنظیم پس‌زمینه صÙØÙ‡ Ù‚ÙÙ„</string> + <string name="pref_queueAddToFront_title">Ùرستادن به جلوی صÙ</string> + <string name="pref_smart_mark_as_played_disabled">غیرÙعال</string> + <string name="crash_report_title">گزارش مشکل</string> + <string name="crash_report_sum">Ùرستادن گزارش آخرین مشکل با رایانامه</string> + <string name="send_email">Ùرستادن رایانامه</string> + <string name="experimental_pref">آزمایشی</string> + <string name="pref_proxy_title">پروکسی</string> + <string name="pref_proxy_sum">تنظیم پروکسی شبکه</string> + <string name="pref_faq">سوالات پرتکرار</string> + <string name="pref_known_issues">مشکلات شناخته شده</string> + <string name="pref_no_browser_found">مرورگر وب پیدا نشد.</string> + <string name="pref_cast_title">پشتیبانی از کروم‌کست</string> + <string name="pref_enqueue_downloaded_title">در ص٠نهادن بارگیری‌شده‌ها</string> + <string name="media_player_builtin">پخش‌کننده پیش‌Ùرض اندروید</string> + <string name="stop_playback">توق٠پخش</string> + <string name="continue_playback">ادامه پخش صدا</string> <!--Auto-Flattr dialog--> <!--Search--> + <string name="search_hint">جستجو برای قسمت‌ها</string> + <string name="search_status_no_results">نتیجه‌ای یاÙت نشد</string> + <string name="search_label">جستجو</string> <!--OPML import and export--> + <string name="opml_directory_error">خطا!</string> + <string name="select_all_label">انتخاب همه</string> + <string name="deselect_all_label">انتخاب هیچ</string> + <string name="select_options_label">انتخاب...</string> <!--Sleep timer--> + <string name="time_seconds">ثانیه</string> + <string name="time_minutes">دقیقه</string> + <string name="time_hours">ساعت</string> <!--gpodder.net--> + <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> + <string name="choose_data_directory">انتخاب پوشه داده</string> + <string name="create_folder_success">ساخت پوشه جدید</string> + <string name="create_folder_error_already_exists">این پوشه از قبل موجود است</string> + <string name="create_folder_error">ناتوانی در ساخت پوشه</string> + <string name="folder_not_empty_dialog_title">این پوشه، خالی نیست</string> + <string name="set_to_default_folder">انتخاب پوشه پیش‌Ùرض</string> <!--Online feed view--> + <string name="subscribe_label">اشتراک</string> + <string name="subscribed_label">مشترک‌شده</string> + <string name="downloading_label">درØال بارگیری...</string> <!--Content descriptions for image buttons--> <!--Feed information screen--> <!--Progress information--> @@ -201,4 +305,5 @@ <!--Database import/export--> <!--Casting--> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-fi/strings.xml b/core/src/main/res/values-fi/strings.xml index acf3abe75..2d9481b84 100644 --- a/core/src/main/res/values-fi/strings.xml +++ b/core/src/main/res/values-fi/strings.xml @@ -36,4 +36,5 @@ <!--Database import/export--> <!--Casting--> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-fr/strings.xml b/core/src/main/res/values-fr/strings.xml index dc4e356bf..11c41d415 100644 --- a/core/src/main/res/values-fr/strings.xml +++ b/core/src/main/res/values-fr/strings.xml @@ -1,11 +1,13 @@ <?xml version='1.0' encoding='UTF-8'?> <resources xmlns:tools="http://schemas.android.com/tools"> <!--Activitiy and fragment titles--> + <string name="feed_update_receiver_name">Mettre à jour les abonnements</string> <string name="feeds_label">Flux</string> <string name="statistics_label">Statistiques</string> <string name="add_feed_label">Ajouter un podcast</string> - <string name="episodes_label">Épisodes</string> + <string name="episodes_label">Episodes</string> <string name="all_episodes_short_label">Tout</string> + <string name="new_episodes_label">Nouveaux</string> <string name="favorite_episodes_label">Favoris</string> <string name="new_label">Nouveau</string> <string name="settings_label">Préférences</string> @@ -18,10 +20,12 @@ <string name="cancel_download_label">Annuler les téléchargements</string> <string name="playback_history_label">Journal de lecture</string> <string name="gpodnet_main_label">gpodder.net</string> + <string name="gpodnet_summary">Synchroniser avec d\'autres appareils</string> <string name="gpodnet_auth_label">Identifiants gpodder.net</string> <string name="free_space_label">%1$s d\'espace libre</string> <string name="episode_cache_full_title">L\'emplacement pour stocker les épisodes est plein</string> <string name="episode_cache_full_message">Le nombre maximal d\'épisodes téléchargés a été atteint. Vous pouvez changer ce nombre dans les paramètres.</string> + <string name="synchronizing">Synchronisation...</string> <!--Statistics fragment--> <string name="total_time_listened_to_podcasts">Temps d\'écoute total</string> <string name="statistics_details_dialog">%1$d épisodes sur %2$d commencés.\n\nLu %3$s sur %4$s.</string> @@ -44,9 +48,9 @@ <string name="drawer_feed_counter_none">Aucun</string> <!--Webview actions--> <string name="open_in_browser_label">Ouvrir dans le navigateur</string> - <string name="copy_url_label">Copier l\'URL</string> - <string name="share_url_label">Partager l\'URL</string> - <string name="copied_url_msg">URL copiée dans le presse-papier</string> + <string name="copy_url_label">Copier le lien</string> + <string name="share_url_label">Partager le lien</string> + <string name="copied_url_msg">Lien copié dans le presse-papier</string> <string name="go_to_position_label">Aller à cette position</string> <!--Playback history--> <string name="clear_history_label">Effacer le journal</string> @@ -56,13 +60,14 @@ <string name="yes">Oui</string> <string name="no">Non</string> <string name="reset">Réinitialiser</string> - <string name="author_label">Auteur</string> + <string name="author_label">Auteur(s)</string> <string name="language_label">Langue</string> - <string name="url_label">URL</string> + <string name="url_label">Lien</string> <string name="podcast_settings_label">Préférences</string> <string name="cover_label">Image</string> <string name="error_label">Erreur</string> <string name="error_msg_prefix">Une erreur a eu lieu :</string> + <string name="needs_storage_permission">L\'autorisation d\'utiliser le stockage est requis pour cette opération</string> <string name="refresh_label">Rafraîchir</string> <string name="external_storage_error_msg">Aucun stockage externe n\'est disponible. Merci de connecter un volume de stockage externe pour que l\'application puisse fonctionner correctement.</string> <string name="chapters_label">Chapitres</string> @@ -83,7 +88,7 @@ <string name="auto_download_apply_to_items_message">Le nouveau paramètre <i>Téléchargement Automatique</i> sera automatiquement appliqué sur chaque nouvel épisode.\nVoulez-vous faire de même avec les épisodes précédents ?</string> <string name="auto_delete_label">Suppression automatique de l\'épisode</string> <string name="parallel_downloads_suffix">\u0020téléchargements parallèles</string> - <string name="feed_auto_download_global">Global défaut</string> + <string name="feed_auto_download_global">Option par défaut</string> <string name="feed_auto_download_always">Toujours</string> <string name="feed_auto_download_never">Jamais</string> <string name="send_label">Envoyer...</string> @@ -95,9 +100,9 @@ <item quantity="other">%d jours après avoir été écouté</item> </plurals> <!--'Add Feed' Activity labels--> - <string name="feedurl_label">URL du flux</string> - <string name="etxtFeedurlHint">URL du flux</string> - <string name="txtvfeedurl_label">Ajouter un podcast par son URL</string> + <string name="feedurl_label">Lien du flux</string> + <string name="etxtFeedurlHint">www.example.com/feed</string> + <string name="txtvfeedurl_label">Ajouter un podcast à partir de son lien</string> <string name="podcastdirectories_label">Trouver le podcast dans la bibliothèque</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> @@ -105,33 +110,37 @@ <string name="mark_all_read_label">Marquer tous les épisodes comme lus</string> <string name="mark_all_read_msg">Tous les épisodes ont été marqués comme lus</string> <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_read_feed_confirmation_msg">Confirmer le marquage de tous les épisodes de ce podcast comme lus</string> <string name="mark_all_seen_label">Marquer tous 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 comme vus.</string> <string name="show_info_label">Voir les détails</string> + <string name="show_feed_settings_label">Paramètres du podcast...</string> + <string name="feed_info_label">Infos du podcast</string> + <string name="feed_settings_label">Paramètres du podcast</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> + <string name="share_link_label">Partager le lien</string> + <string name="share_link_with_position_label">Partager le lien avec la position</string> <string name="share_file_label">Partager le fichier</string> - <string name="share_link_with_position_label">Partager lien avec position</string> - <string name="share_feed_url_label">Partager lien du flux</string> - <string name="share_item_url_label">Partager le lien de l\'épisode</string> - <string name="share_item_url_with_position_label">Partager le lien de l\'épisode avec la position</string> - <string name="feed_delete_confirmation_msg">Confirmer que vous voulez supprimer le flux \"%1$s\" et TOUS les épisodes que vous avez téléchargés.</string> - <string name="feed_remover_msg">Flux en cours de suppression</string> - <string name="load_complete_feed">Mettre à jour tout le flux</string> + <string name="share_feed_url_label">Partager le lien du flux</string> + <string name="share_item_url_label">Partager le lien du fichier</string> + <string name="share_item_url_with_position_label">Partager le lien du fichier avec la position</string> + <string name="feed_delete_confirmation_msg">Confirmer que vous voulez supprimer le podcast \"%1$s\" et TOUS ses épisodes téléchargés.</string> + <string name="feed_remover_msg">Podcast en cours de suppression</string> + <string name="load_complete_feed">Mettre à jour tout le podcast</string> <string name="hide_episodes_title">Cacher épisodes</string> - <string name="episode_actions">Appliquer les actions</string> - <string name="hide_unplayed_episodes_label">Non joués</string> + <string name="batch_edit">Edition groupée</string> + <string name="hide_unplayed_episodes_label">Non lus</string> <string name="hide_paused_episodes_label">En pause</string> - <string name="hide_played_episodes_label">Joués</string> - <string name="hide_queued_episodes_label">Rajouté à la liste de lecture</string> - <string name="hide_not_queued_episodes_label">Non rajouté à la liste de lecture</string> + <string name="hide_played_episodes_label">Lus</string> + <string name="hide_queued_episodes_label">Dans la liste de lecture</string> + <string name="hide_not_queued_episodes_label">Pas dans la liste de lecture</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="hide_has_media_label">Avec média</string> + <string name="hide_is_favorite_label">Est un favori</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> @@ -144,7 +153,8 @@ <string name="remove_label">Supprimer</string> <string name="delete_label">Effacer</string> <string name="delete_failed">Suppression du fichier impossible. Redémarrer pourrait aider.</string> - <string name="remove_episode_lable">Supprimer cet épisode</string> + <string name="remove_episode_lable">Supprimer</string> + <string name="mark_as_seen_label">Marquer comme vu</string> <string name="marked_as_seen_label">Marqué comme vu</string> <string name="mark_read_label">Marquer comme lu</string> <string name="marked_as_read_label">Les épisodes ont été marqués comme lus</string> @@ -168,6 +178,8 @@ <string name="download_failed">échoué</string> <string name="download_pending">Téléchargement en attente</string> <string name="download_running">Téléchargement en cours</string> + <string name="download_error_details">Détails</string> + <string name="download_error_details_message">%1$s \n\nLien du fichier :\n%2$s</string> <string name="download_error_device_not_found">Volume de stockage non trouvé</string> <string name="download_error_insufficient_space">Espace insuffisant</string> <string name="download_error_file_error">Accès au fichier impossible</string> @@ -185,7 +197,7 @@ <string name="download_canceled_autodownload_enabled_msg">Téléchargement annulé\n <i>Téléchargement Automatique</i> désactivé pour cet élément</string> <string name="download_report_title">Téléchargements terminés avec des erreurs</string> <string name="download_report_content_title">Rapport des téléchargements</string> - <string name="download_error_malformed_url">URL incorrecte</string> + <string name="download_error_malformed_url">Lien incorrecte</string> <string name="download_error_io_error">Erreur d\'E/S</string> <string name="download_error_request_error">Erreur de requête</string> <string name="download_error_db_access">Problème d\'accès à la base de données</string> @@ -218,6 +230,7 @@ <string name="playback_error_unknown">Erreur inconnue</string> <string name="no_media_playing_label">Aucune lecture</string> <string name="player_buffering_msg">Mise en mémoire</string> + <string name="player_go_to_picture_in_picture">Mode Picture-in-Picture</string> <string name="playbackservice_notification_title">Lecture de podcast en cours</string> <string name="unknown_media_key">AntennaPod - Touche média inconnue : %1$d</string> <!--Queue operations--> @@ -234,7 +247,9 @@ <string name="date">Date</string> <string name="duration">Durée</string> <string name="episode_title">Titre de l\'épisode</string> - <string name="feed_title">Nom du flux</string> + <string name="feed_title">Nom du podcast</string> + <string name="random">Aléatoire</string> + <string name="smart_shuffle">Tri intelligent</string> <string name="ascending">Ordre croissant</string> <string name="descending">Ordre décroissant</string> <string name="clear_queue_confirmation_msg">Veuillez confirmer que vous voulez bien supprimer TOUS les épisodes de la liste de lecture</string> @@ -272,30 +287,38 @@ <string name="enable_sonic">Activer Sonic</string> <!--Empty list labels--> <string name="no_items_label">Cette liste est vide.</string> - <string name="no_feeds_label">Vous n\'êtes encore abonné à aucun flux.</string> + <string name="no_feeds_label">Vous n\'êtes encore abonné à aucun podcast.</string> <string name="no_chapters_label">Cet épisode n\'a pas de chapitres.</string> - <string name="no_shownotes_label">Aucun descriptif pour cet épisode.</string> + <string name="no_shownotes_label">Aucune notes pour cet épisode.</string> <!--Preferences--> <string name="storage_pref">Stockage</string> <string name="project_pref">Projet</string> <string name="other_pref">Autres</string> <string name="about_pref">À propos</string> - <string name="queue_label">Liste</string> - <string name="services_label">Services</string> + <string name="queue_label">Liste de lecture</string> + <string name="integrations_label">Intégrations</string> <string name="flattr_label">Flattr</string> + <string name="flattr_summary">Service de micropaiement</string> + <string name="automation">Automatisation</string> + <string name="download_pref_details">Détails</string> + <string name="import_export_pref">Importation / Exportation</string> + <string name="appearance">Apparence</string> + <string name="external_elements">Eléments externes</string> + <string name="interruptions">Interruptions</string> + <string name="buttons">Boutons de lecture</string> + <string name="media_player">Lecteur multimédia</string> <string name="pref_episode_cleanup_title">Nettoyage des épisodes</string> <string name="pref_episode_cleanup_summary">Les épisodes qui ne sont pas dans la liste de lecture et qui ne sont pas marqués comme favoris peuvent être supprimés si l\'espace est insuffisant pour le téléchargement automatique de nouveaux épisodes</string> <string name="pref_pauseOnDisconnect_sum">Interrompre la lecture lorsque le casque ou le bluetooth sont déconnectés</string> - <string name="pref_unpauseOnHeadsetReconnect_sum">Reprendre la lecture quand les écouteurs sont reconnectés</string> - <string name="pref_unpauseOnBluetoothReconnect_sum">Reprendre la lecture quand le Bluetooth se reconnecte</string> + <string name="pref_unpauseOnHeadsetReconnect_sum">Reprendre la lecture quand les écouteurs sont connectés</string> + <string name="pref_unpauseOnBluetoothReconnect_sum">Reprendre la lecture quand le Bluetooth se connecte</string> <string name="pref_hardwareForwardButtonSkips_title">Le bouton \"saut avant\" saute l\'épisode</string> - <string name="pref_hardwareForwardButtonSkips_sum">Passer à l\'épisode suivant au lieu de faire un saut avant quand un bouton physique \"saut avant\" est pressé</string> <string name="pref_hardwarePreviousButtonRestarts_title">Le bouton \"saut arrière\" redémarre l\'épisode</string> <string name="pref_hardwarePreviousButtonRestarts_sum">Repartir de zéro au lieu de faire un saut arrière quand un bouton physique \"saut arrière\" est pressé</string> <string name="pref_followQueue_sum">Après la fin d\'un épisode, passer au suivant</string> <string name="pref_auto_delete_sum">Supprimer l\'épisode quand la lecture est finie</string> <string name="pref_auto_delete_title">Suppression automatique</string> - <string name="pref_smart_mark_as_played_sum">Les épisodes seront marqués comme lus même s\'il reste quelques secondes à jouer</string> + <string name="pref_smart_mark_as_played_sum">Les épisodes seront marqués comme lus même s\'il reste quelques secondes à écouter</string> <string name="pref_smart_mark_as_played_title">Marquer comme lu intelligemment</string> <string name="pref_skip_keeps_episodes_sum">Garder les épisodes quand ils sont passés</string> <string name="pref_skip_keeps_episodes_title">Garder les épisodes passés</string> @@ -303,20 +326,20 @@ <string name="pref_favorite_keeps_episodes_title">Garder les épisodes favoris</string> <string name="playback_pref">Lecture</string> <string name="network_pref">Réseau</string> - <string name="pref_autoUpdateIntervallOrTime_title">Mettre à jour l’intervalle ou l\'heure</string> + <string name="pref_autoUpdateIntervallOrTime_title">Intervalle / Heure de mise à jour</string> <string name="pref_autoUpdateIntervallOrTime_sum">Indiquer un intervalle ou une heure spécifique de mise à jour des flux</string> - <string name="pref_autoUpdateIntervallOrTime_message">Vous pouvez mettre en place un <i>intervalle</i> comme \"toutes les 2 heures\", une <i>heure précise</i> comme \"7:00\" ou désactiver les mises à jours automatique.\n\n<small>Note: Il est possible qu\'il y ait un délai car l\'heure de mise à jour peut être inexacte.</small></string> + <string name="pref_autoUpdateIntervallOrTime_message">Vous pouvez définir un <i>intervalle</i> comme \"toutes les 2 heures\" ou une <i>heure précise</i> comme \"7:00\" ou désactiver les mises à jours automatique.\n\n<small>Note: les heures de mise à jour ne sont pas précises. Vous pouvez avoir un petit délai.</small></string> <string name="pref_autoUpdateIntervallOrTime_Disable">Désactiver</string> - <string name="pref_autoUpdateIntervallOrTime_Interval">Définir intervalle</string> - <string name="pref_autoUpdateIntervallOrTime_TimeOfDay">Régler l\'heure</string> + <string name="pref_autoUpdateIntervallOrTime_Interval">Intervalle</string> + <string name="pref_autoUpdateIntervallOrTime_TimeOfDay">Heure</string> <string name="pref_autoUpdateIntervallOrTime_every">toutes les %1$s</string> <string name="pref_autoUpdateIntervallOrTime_at">à %1$s</string> <string name="pref_downloadMediaOnWifiOnly_sum">Ne télécharger les épisodes que par Wi-Fi</string> <string name="pref_followQueue_title">Lecture continue</string> <string name="pref_downloadMediaOnWifiOnly_title">Téléchargement en Wi-Fi</string> - <string name="pref_pauseOnHeadsetDisconnect_title">Déconnexion du casque</string> - <string name="pref_unpauseOnHeadsetReconnect_title">Reconnexion du casque</string> - <string name="pref_unpauseOnBluetoothReconnect_title">Reconnexion Bluetooth</string> + <string name="pref_pauseOnHeadsetDisconnect_title">Déconnexion des écouteurs ou du Bluetooth</string> + <string name="pref_unpauseOnHeadsetReconnect_title">Connexion des écouteurs</string> + <string name="pref_unpauseOnBluetoothReconnect_title">Connexion du Bluetooth</string> <string name="pref_mobileUpdate_title">Mises à jour mobile</string> <string name="pref_mobileUpdate_sum">Autoriser les mises à jour avec la connexion mobile</string> <string name="refreshing_label">Mise à jour en cours</string> @@ -338,7 +361,7 @@ <string name="pref_nav_drawer_feed_order_title">Définir l\'ordre des abonnements</string> <string name="pref_nav_drawer_feed_order_sum">Change l\'ordre de vos abonnements</string> <string name="pref_nav_drawer_feed_counter_title">Définir le compteur d\'abonnements</string> - <string name="pref_nav_drawer_feed_counter_sum">Changer l\'information affichée par le compteur d\'abonnements</string> + <string name="pref_nav_drawer_feed_counter_sum">Changer l\'information affichée par le compteur d\'abonnements. Cela change aussi l\'ordre des podcasts si ils sont triés par le compteur.</string> <string name="pref_set_theme_sum">Modifier l\'apparence d\'AntennaPod.</string> <string name="pref_automatic_download_title">Téléchargement automatique</string> <string name="pref_automatic_download_sum">Configurer le téléchargement automatique des épisodes.</string> @@ -352,6 +375,7 @@ <string name="pref_episode_cache_title">Épisodes stockés localement</string> <string name="pref_theme_title_light">Clair</string> <string name="pref_theme_title_dark">Sombre</string> + <string name="pref_theme_title_trueblack">Noir (pour écran AMOLED)</string> <string name="pref_episode_cache_unlimited">Illimité</string> <string name="pref_update_interval_hours_plural">heures</string> <string name="pref_update_interval_hours_singular">heure</string> @@ -375,25 +399,23 @@ <string name="pref_playback_speed_title">Vitesses de lecture</string> <string name="pref_playback_speed_sum">Définir les vitesses disponibles lors de la lecture audio</string> <string name="pref_fast_forward">Durée du saut avant</string> - <string name="pref_fast_forward_sum">Nombre de secondes à sauter quand le bouton \"saut avant\" est cliqué</string> + <string name="pref_fast_forward_sum">Nombre de secondes à sauter quand le bouton \"saut avant\" est pressé</string> <string name="pref_rewind">Durée du saut arrière</string> - <string name="pref_rewind_sum">Nombre de secondes à sauter quand le bouton \"saut arrière\" est cliqué</string> + <string name="pref_rewind_sum">Nombre de secondes à sauter quand le bouton \"saut arrière\" est pressé</string> <string name="pref_gpodnet_sethostname_title">Choisir un nom de domaine</string> <string name="pref_gpodnet_sethostname_use_default_host">Utiliser le nom de domaine par défaut</string> - <string name="pref_expandNotify_title">Etendre la notification</string> - <string name="pref_expandNotify_sum">Toujours étendre la notification pour montrer tous les boutons de lecture </string> <string name="pref_persistNotify_title">Boutons de lecture permanents</string> <string name="pref_persistNotify_sum">Garder les notifications et les boutons de lecture sur l\'écran de verouillage quand la lecture est en pause</string> <string name="pref_compact_notification_buttons_title">Définir les boutons de l\'écran de verrouillage</string> <string name="pref_compact_notification_buttons_sum">Change les boutons de lecture sur l\'écran de verrouillage. Le bouton de lecture/pause est toujours affiché.</string> <string name="pref_compact_notification_buttons_dialog_title">Choisir un maximum de %1$d éléments</string> <string name="pref_compact_notification_buttons_dialog_error">Vous ne pouvez pas choisir plus de %1$d éléments.</string> - <string name="pref_lockscreen_background_title">Changer l’arrière plan de l\'écran de déverrouillage</string> - <string name="pref_lockscreen_background_sum">Placer l\'image de l’épisode en arrière plan de l\'écran de déverrouillage. Cela aura aussi pour effet de montrer l\'image dans les autres applications.</string> + <string name="pref_lockscreen_background_title">Changer l’arrière plan de l\'écran de verrouillage</string> + <string name="pref_lockscreen_background_sum">Placer l\'image de l’épisode en arrière plan de l\'écran de verrouillage. Cela aura aussi pour effet de montrer l\'image dans les autres applications.</string> <string name="pref_showDownloadReport_title">Afficher le rapport de téléchargements</string> <string name="pref_showDownloadReport_sum">Si les téléchargements échouent, générer un rapport détaillé des échecs.</string> <string name="pref_expand_notify_unsupport_toast">Les versions d\'Android antérieures à 4.1 ne sont pas compatibles avec les notifications élargies</string> - <string name="pref_queueAddToFront_sum">Ajouter les nouveaux épisodes au début de la liste de lecture.</string> + <string name="pref_queueAddToFront_sum">Ajouter les nouveaux épisodes au début de la liste de lecture</string> <string name="pref_queueAddToFront_title">Mettre au début de la liste de lecture</string> <string name="pref_smart_mark_as_played_disabled">Désactivé</string> <string name="pref_image_cache_size_title">Taille du cache de l\'image</string> @@ -402,8 +424,7 @@ <string name="crash_report_sum">Envoyer le dernier rapport de crash par e-mail</string> <string name="send_email">Envoyer e-mail</string> <string name="experimental_pref">Expérimental</string> - <string name="pref_sonic_title">Lecteur multimédia Sonic</string> - <string name="pref_sonic_message">Utiliser le lecteur multimédia interne Sonic au lieu du lecteur natif d\'Android ou Prestissimo</string> + <string name="pref_media_player_message">Choisir le lecteur à utiliser pour lire les fichiers</string> <string name="pref_current_value">Valeur actuelle : %1$s</string> <string name="pref_proxy_title">Proxy</string> <string name="pref_proxy_sum">Paramétrer un réseau proxy</string> @@ -415,17 +436,22 @@ <string name="pref_cast_message_free_flavor">Chromecast nécessite des bibliothèques tierces qui sont désactivées dans cette version d\'AntennaPod</string> <string name="pref_enqueue_downloaded_title">Ajouter à la liste après téléchargement</string> <string name="pref_enqueue_downloaded_summary">Mettre les épisodes dans la la liste de lecture après téléchargement</string> + <string name="media_player_builtin">Lecteur natif d\'Android</string> + <string name="pref_videoBehavior_title">Sorti du lecteur pendant une vidéo</string> + <string name="pref_videoBehavior_sum">Définir ce qu\'il se passe si une vidéo est quittée pendant sa lecture</string> + <string name="stop_playback">Arrêter la lecture</string> + <string name="continue_playback">Continuer la lecture</string> <!--Auto-Flattr dialog--> <string name="auto_flattr_enable">Activer le paiement flattr automatique</string> - <string name="auto_flattr_after_percent">Lancer un paiement flattr pour un épisode dès que %d de l\'épisode a été joué</string> + <string name="auto_flattr_after_percent">Lancer un paiement flattr quand %d pourcent de l\'épisode a été lu</string> <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 les épisodes</string> <string name="found_in_shownotes_label">Trouvé dans les notes d\'épisodes</string> <string name="found_in_chapters_label">Trouvé dans les titres de chapitre</string> - <string name="found_in_authors_label">Trouvés en tant qu\'auteur</string> - <string name="found_in_feeds_label">Trouvés dans les flux</string> + <string name="found_in_authors_label">Trouvés dans les auteurs</string> + <string name="found_in_feeds_label">Trouvés dans les podcasts</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> @@ -437,7 +463,7 @@ <string name="opml_import_explanation_2">Utiliser une application tierce comme Dropbox, Google Drive ou votre gestionnaire de fichier favori pour ouvrir un fichier OPML</string> <string name="opml_import_explanation_3">De nombreuses applications comme Google Mail, Dropbox ou Google Drive et la plupart des gestionnaires de fichiers peuvent <i>ouvrir</i> les fichiers OPML <i>avec</i> AntennaPod.</string> <string name="start_import_label">Démarrer l\'importation</string> - <string name="opml_import_label">Importation OPML</string> + <string name="opml_import_label">Import OPML</string> <string name="opml_directory_error">ERREUR !</string> <string name="reading_opml_label">Lecture du fichier OPML en cours</string> <string name="opml_reader_error">Une erreur s\'est produite pendant la lecture du fichier OPML :</string> @@ -447,12 +473,12 @@ <string name="select_options_label">Choisir...</string> <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="opml_export_label">Export 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> - <string name="opml_export_success_sum">Le fichier .opml a été écrit ici :\u0020</string> + <string name="export_success_title">Export réussi</string> + <string name="export_success_sum">Le fichier a été exporté dans :\n\n%1$s</string> <string name="opml_import_ask_read_permission">L\'accès au stockage externe est requis pour lire le fichier OPML</string> <!--Sleep timer--> <string name="set_sleeptimer_label">Activation du minuteur d\'arrêt</string> @@ -565,25 +591,25 @@ <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> + <string name="search_fyyd_label">Chercher sur fyyd</string> <!--Episodes apply actions--> <string name="all_label">Tout</string> <string name="selected_all_label">Tous les épisodes ont été sélectionné</string> <string name="none_label">Aucun</string> <string name="deselected_all_label">Tous les épisodes ont été désélectionné</string> - <string name="played_label">Joués</string> - <string name="selected_played_label">Episodes joués sélectionnés</string> - <string name="unplayed_label">Non joués</string> - <string name="selected_unplayed_label">Episodes non joués sélectionnés</string> + <string name="played_label">Lus</string> + <string name="selected_played_label">Episodes lus sélectionnés</string> + <string name="unplayed_label">Non lus</string> + <string name="selected_unplayed_label">Episodes non lus sélectionnés</string> <string name="downloaded_label">Téléchargés</string> <string name="selected_downloaded_label">Episodes téléchargés sélectionnés</string> <string name="not_downloaded_label">Non téléchargés</string> <string name="selected_not_downloaded_label">Épisodes non téléchargés sélectionnés</string> - <string name="queued_label">Dans liste de lecture</string> + <string name="queued_label">Dans la liste de lecture</string> <string name="selected_queued_label">Episodes présents dans la liste de lecture sélectionnés</string> <string name="not_queued_label">En dehors de la 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="has_media">A 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> @@ -620,12 +646,12 @@ <string name="proxy_host_invalid_error">L\'hôte n\'est pas une adresse IP ou un domaine valide</string> <string name="proxy_port_invalid_error">Port non valide</string> <!--Database import/export--> - <string name="import_export">Importer/Exporter la base de données</string> - <string name="import_export_warning">Cette fonction expérimentale peut-être utilisée pour transférer vos abonnements et épisodes joués sur un autre appareil.\n\nLes bases de données exportées peuvent uniquement être importées sur la même version d\'AntennaPod. Dans le cas contraire, des dysfonctionnements peuvent survenir.\n\nAprès import, il est possible que des épisodes apparaissent téléchargés alors qu\'ils ne le sont pas. Appuyer sur le bouton de lecture pour qu\'AntennaPod le détecte.</string> + <string name="import_export">Import / Export de la base de données</string> + <string name="import_export_warning">Cette fonction expérimentale peut-être utilisée pour transférer vos abonnements et épisodes lus sur un autre appareil.\n\nLes bases de données exportées peuvent uniquement être importées sur la même version d\'AntennaPod. Dans le cas contraire, des dysfonctionnements peuvent apparaître.\n\nAprès import, il est possible que des épisodes apparaissent téléchargés alors qu\'ils ne le sont pas. Appuyer sur le bouton de lecture pour qu\'AntennaPod le détecte.</string> <string name="label_import">Importer</string> <string name="label_export">Exporter</string> <string name="import_select_file">Sélectionner le fichier à importer</string> - <string name="export_ok">Export réussi. La base de données a été écrite sur la carte SD.</string> + <string name="export_ok">Export réussi.</string> <string name="import_ok">Import réussi.\n\nAppuyer sur OK pour redémarrer AntennaPod</string> <!--Casting--> <string name="cast_media_route_menu_title">Lire sur...</string> @@ -643,4 +669,13 @@ <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 a rencontré une grave erreur</string> <string name="cast_failed_media_error_skipping">Erreur de lecture du média. Passage au suivant...</string> + <!--Notification channels--> + <string name="notification_channel_user_action">Action requise</string> + <string name="notification_channel_user_action_description">S\'affiche si une action est requise. Par exemple, un mot de passe à saisir.</string> + <string name="notification_channel_downloading">Téléchargement en cours</string> + <string name="notification_channel_downloading_description">S\'affiche lorsqu\'un téléchargement est en cours.</string> + <string name="notification_channel_playing">Lecture en cours</string> + <string name="notification_channel_playing_description">Permet de contrôler la lecture. C\'est la notification principale pendant la lecture d\'un podcast.</string> + <string name="notification_channel_error">Erreurs</string> + <string name="notification_channel_error_description">S\'affiche en cas de problème. Par exemple, un téléchargement ou une synchronisation qui échoue.</string> </resources> diff --git a/core/src/main/res/values-gl-rES/strings.xml b/core/src/main/res/values-gl-rES/strings.xml index 2dc04a5db..a2a4366ed 100644 --- a/core/src/main/res/values-gl-rES/strings.xml +++ b/core/src/main/res/values-gl-rES/strings.xml @@ -1,32 +1,36 @@ <?xml version='1.0' encoding='UTF-8'?> <resources xmlns:tools="http://schemas.android.com/tools"> <!--Activitiy and fragment titles--> + <string name="feed_update_receiver_name">Actualizar subscricións</string> <string name="feeds_label">Fontes</string> <string name="statistics_label">EstatÃsticas</string> - <string name="add_feed_label">Engadir Podcast</string> + <string name="add_feed_label">Engadir podcast</string> <string name="episodes_label">Episodios</string> <string name="all_episodes_short_label">Todo</string> + <string name="new_episodes_label">Novo</string> <string name="favorite_episodes_label">Favoritos</string> <string name="new_label">Novo</string> <string name="settings_label">Axustes</string> <string name="downloads_label">Descargas</string> - <string name="downloads_running_label">Descargando</string> + <string name="downloads_running_label">Funcionando</string> <string name="downloads_completed_label">Completado</string> <string name="downloads_log_label">Rexistro</string> - <string name="subscriptions_label">Suscricións</string> - <string name="subscriptions_list_label">Lista de suscricións</string> + <string name="subscriptions_label">Subscricións</string> + <string name="subscriptions_list_label">Lista de subscricións</string> <string name="cancel_download_label">Cancelar\nDescarga</string> <string name="playback_history_label">Historial de reprodución</string> <string name="gpodnet_main_label">gpodder.net</string> + <string name="gpodnet_summary">Sincronizar con outros dispositivos</string> <string name="gpodnet_auth_label">gpodder.net Conexión</string> <string name="free_space_label">%1$s libre</string> <string name="episode_cache_full_title">Caché de episodios chea</string> <string name="episode_cache_full_message">Acadouse o lÃmite de espazo na caché de episodios. Pode incrementalo nos Axustes do tamaño da caché.</string> + <string name="synchronizing">Sincronizando...</string> <!--Statistics fragment--> <string name="total_time_listened_to_podcasts">Tempo total dos podcast reproducidos:</string> <string name="statistics_details_dialog">%1$d de %2$d episodios iniciados.\n\nReproducidos %3$s de %4$s.</string> <string name="statistics_mode">Modo de estatÃsticas</string> - <string name="statistics_mode_normal">Calcular a duración que foi realmente reproducida. Reproducir dúas veces conta dobre, mentras que marcar como lido non conta</string> + <string name="statistics_mode_normal">Calcular a duración que foi realmente reproducida. Reproducir dúas veces conta dobre, mentres que marcar como lido non conta</string> <string name="statistics_mode_count_all">Sumar todos os podcast marcados como reproducidos</string> <string name="statistics_speed_not_counted">Aviso: A velocidade de reprodución non se ten en conta en ningún caso.</string> <!--Main activity--> @@ -34,7 +38,7 @@ <string name="drawer_close">Pechar menú</string> <string name="drawer_preferences">Preferencias da caixa</string> <string name="drawer_feed_order_unplayed_episodes">Ordenar polo contador</string> - <string name="drawer_feed_order_alphabetical">Ordenar alfabéticamente</string> + <string name="drawer_feed_order_alphabetical">Ordenar alfabeticamente</string> <string name="drawer_feed_order_last_update">Ordenar por data de publicación</string> <string name="drawer_feed_order_most_played">Ordenar por número de episodios reproducidos</string> <string name="drawer_feed_counter_new_unplayed">Número de episodios novos e non reproducidos</string> @@ -43,7 +47,7 @@ <string name="drawer_feed_counter_downloaded">Número de episodios descargados</string> <string name="drawer_feed_counter_none">Ningún</string> <!--Webview actions--> - <string name="open_in_browser_label">Abrir en navegador</string> + <string name="open_in_browser_label">Abrir no navegador</string> <string name="copy_url_label">Copiar URL</string> <string name="share_url_label">Compartir URL</string> <string name="copied_url_msg">Copiar URL ao portapapeis</string> @@ -56,15 +60,16 @@ <string name="yes">Si</string> <string name="no">Non</string> <string name="reset">Restablecer</string> - <string name="author_label">Autor</string> + <string name="author_label">Autor(es)</string> <string name="language_label">Idioma</string> <string name="url_label">URL</string> <string name="podcast_settings_label">Axustes</string> <string name="cover_label">Imaxe</string> <string name="error_label">Fallo</string> - <string name="error_msg_prefix">Houbo un fallo:</string> + <string name="error_msg_prefix">Produciuse un fallo:</string> + <string name="needs_storage_permission">PrecÃsase o permiso de almacenamento para esta operación</string> <string name="refresh_label">Actualizar</string> - <string name="external_storage_error_msg">Non se dispón de almacenamento externo. Por favor asegúrese de que o almacenamento externo está montado e asà o app poderá funcionar correctamente.</string> + <string name="external_storage_error_msg">Non se dispón de almacenamento externo. Por favor asegúrese de que o almacenamento externo está montado e asà o aplicativo poderá funcionar correctamente.</string> <string name="chapters_label">CapÃtulos</string> <string name="chapter_duration">Duración: %1$s</string> <string name="shownotes_label">Notas do episodio</string> @@ -105,25 +110,28 @@ <string name="mark_all_read_label">Marcar todo como reproducido</string> <string name="mark_all_read_msg">Marcáronse todos como reproducidos</string> <string name="mark_all_read_confirmation_msg">Por favor confirme que quere marcar todos os episodios como reproducidos.</string> - <string name="mark_all_read_feed_confirmation_msg">Por favor confirme que quere marcar todos os episodios de esta fonte como reproducidos.</string> + <string name="mark_all_read_feed_confirmation_msg">Por favor, confirme que quere marcar todos os episodios deste podcast como reproducidos.</string> <string name="mark_all_seen_label">Marcar como visto</string> <string name="mark_all_seen_msg">Marcáronse todos os episodios como vistos</string> <string name="mark_all_seen_confirmation_msg">Por favor confirme que quere marcar todos os episodios como vistos.</string> <string name="show_info_label">Mostrar información</string> + <string name="show_feed_settings_label">Mostrar axustes do podcast</string> + <string name="feed_info_label">Información do podcast</string> + <string name="feed_settings_label">Axustes do podcast</string> <string name="rename_feed_label">Mudar nome do podcast</string> - <string name="remove_feed_label">Quitar podcast</string> + <string name="remove_feed_label">Eliminar o podcast</string> <string name="share_label">Compartir...</string> - <string name="share_link_label">Compartir ligazón</string> + <string name="share_link_label">Compartir a URL do episodio</string> + <string name="share_link_with_position_label">Compartir a URL do ficheiro do episodio coa posición</string> <string name="share_file_label">Compartir ficheiro</string> - <string name="share_link_with_position_label">Compartir ligazón con posición</string> <string name="share_feed_url_label">Compartir URL da fonte</string> - <string name="share_item_url_label">Compartir a URL do ficheiro do episodio</string> - <string name="share_item_url_with_position_label">Compartir a URL do ficheiro do episodio con posición</string> - <string name="feed_delete_confirmation_msg">Por favor confirme que quere eliminar a fonte \"%1$s\" e TODOS os episodios de esta fonte anteriormente descargados.</string> - <string name="feed_remover_msg">Eliminando a fonte</string> - <string name="load_complete_feed">Actualizar completamente a fonte</string> + <string name="share_item_url_label">Compartir a URL do ficheiro multimedia</string> + <string name="share_item_url_with_position_label">Compartir a URL do ficheiro multimedia coa posición</string> + <string name="feed_delete_confirmation_msg">Por favor, confirme que quere eliminar o podcast \"%1$s\" e TODOS os seus episodios (incluÃdos os xa descargados).</string> + <string name="feed_remover_msg">Eliminando o podcast</string> + <string name="load_complete_feed">Actualizar o podcast completo</string> <string name="hide_episodes_title">Ocultar episodios</string> - <string name="episode_actions">Aplicar accións</string> + <string name="batch_edit">Edición por lote</string> <string name="hide_unplayed_episodes_label">Non reproducido</string> <string name="hide_paused_episodes_label">En pausa</string> <string name="hide_played_episodes_label">Reproducido</string> @@ -132,6 +140,7 @@ <string name="hide_downloaded_episodes_label">Descargado</string> <string name="hide_not_downloaded_episodes_label">Non descargado</string> <string name="hide_has_media_label">Ten medios</string> + <string name="hide_is_favorite_label">É favorito</string> <string name="filtered_label">Filtrado</string> <string name="refresh_failed_msg">{fa-exclamation-circle} Erro na última actualización</string> <string name="open_podcast">Abrir podcast</string> @@ -145,6 +154,7 @@ <string name="delete_label">Borrar</string> <string name="delete_failed">Non se puido eliminar o ficheiro. Reiniciar o dispositivo poderÃa axudar.</string> <string name="remove_episode_lable">Eliminar episodio</string> + <string name="mark_as_seen_label">Marcar como visto</string> <string name="marked_as_seen_label">Marcar como visto</string> <string name="mark_read_label">Marcar como reproducido</string> <string name="marked_as_read_label">Marcado como reproducido</string> @@ -168,6 +178,8 @@ <string name="download_failed">fallou</string> <string name="download_pending">Descarga pendente</string> <string name="download_running">Descarga en proceso</string> + <string name="download_error_details">Detalles</string> + <string name="download_error_details_message">%1$s\n\nURL do ficheiro:\n %2$s </string> <string name="download_error_device_not_found">Non se atopou dispositivo de almacenamento</string> <string name="download_error_insufficient_space">Non hai suficiente espacio</string> <string name="download_error_file_error">Fallo de ficheiro</string> @@ -182,7 +194,7 @@ <string name="download_error_forbidden">Non admitido</string> <string name="cancel_all_downloads_label">Cancelar todas as descargas</string> <string name="download_canceled_msg">Descarga cancelada</string> - <string name="download_canceled_autodownload_enabled_msg">Descarga cancelada\nDeshabilitouse <i>Descarga automática</i> para este elemento</string> + <string name="download_canceled_autodownload_enabled_msg">Descarga cancelada\nDesactivouse a <i>Descarga Automática</i> para este elemento</string> <string name="download_report_title">Descargas completadas con erro(s)</string> <string name="download_report_content_title">Informe da descarga</string> <string name="download_error_malformed_url">URL mal formada</string> @@ -204,8 +216,8 @@ <string name="authentication_notification_title">PrecÃsase autenticación</string> <string name="authentication_notification_msg">O recurso solicitado require un usuario e contrasinal</string> <string name="confirm_mobile_download_dialog_title">Confirme a descarga con datos do móbil</string> - <string name="confirm_mobile_download_dialog_message_not_in_queue">Descargar coa conexión de datos do móbil está deshabilitada nos axustes.\n\nPode escoller ben só engadir o episodio a cola ou pode permitir a descarga temporalmente.\n\n<small> A súa elección lembrarase durante 10 minutos.</small></string> - <string name="confirm_mobile_download_dialog_message">A descarga con datos móbiles está deshabilitada nos axustes.\n\nQuere permitir a descarga temporalmente?\n\n <small>A súa decisión lembrarase durante 10 minutos.</small></string> + <string name="confirm_mobile_download_dialog_message_not_in_queue">Descargar coa conexión de datos do móbil está desactivada nos axustes.\n\nPode escoller ben só engadir o episodio a cola ou pode permitir a descarga temporalmente.\n\n<small> A súa elección lembrarase durante 10 minutos.</small></string> + <string name="confirm_mobile_download_dialog_message">A descarga con datos móbiles está desactivada nos axustes.\n\nQuere permitir a descarga temporalmente?\n\n <small>A súa decisión lembrarase durante 10 minutos.</small></string> <string name="confirm_mobile_download_dialog_only_add_to_queue">Engadir a cola</string> <string name="confirm_mobile_download_dialog_enable_temporarily">Permitir temporalmente</string> <!--Mediaplayer messages--> @@ -218,13 +230,14 @@ <string name="playback_error_unknown">Fallo descoñecido</string> <string name="no_media_playing_label">Non reproducindo</string> <string name="player_buffering_msg">Almacenando</string> + <string name="player_go_to_picture_in_picture">Modo imaxe-en-imaxe</string> <string name="playbackservice_notification_title">Reproducindo podcast</string> <string name="unknown_media_key">AntennaPod - chave de medios descoñecida: %1$d</string> <!--Queue operations--> - <string name="lock_queue">Pechar a cola</string> - <string name="unlock_queue">Despechar a cola</string> - <string name="queue_locked">Cola pechada</string> - <string name="queue_unlocked">Cola despechada</string> + <string name="lock_queue">Bloquear a cola</string> + <string name="unlock_queue">Desbloquear a cola</string> + <string name="queue_locked">Cola bloqueada</string> + <string name="queue_unlocked">Cola desbloqueada</string> <string name="clear_queue_label">Limpar cola</string> <string name="undo">Desfacer</string> <string name="removed_from_queue">Elemento eliminado</string> @@ -234,7 +247,9 @@ <string name="date">Data</string> <string name="duration">Duración</string> <string name="episode_title">TÃtulo do episodio</string> - <string name="feed_title">TÃtulo da fonte</string> + <string name="feed_title">TÃtulo do podcast</string> + <string name="random">Aleatorio</string> + <string name="smart_shuffle">Barallado intelixente</string> <string name="ascending">Ascendente</string> <string name="descending">Descendente</string> <string name="clear_queue_confirmation_msg">Por favor confirme que quere limpar a cola e TODOS os episodios nela</string> @@ -243,15 +258,15 @@ <string name="flattr_auth_explanation">Pulse o botón inferior para iniciar o proceso de autenticación. Será redireccionado a pantalla de conexión en Flattr no seu navegador e pediralle permiso para que AntennaPod poida acceder. Despois de dar permiso, voltará a esta pantalla de xeito automático.</string> <string name="authenticate_label">Autenticar</string> <string name="return_home_label">Voltar ao inicio</string> - <string name="flattr_auth_success">Autenticouse correctamente! Xa pode enviar valoracións a Flattr desde o app.</string> + <string name="flattr_auth_success">Autenticouse correctamente! Xa pode enviar valoracións a Flattr desde o aplicativo.</string> <string name="no_flattr_token_title">Non se atopou o testemuño de Flattr</string> <string name="no_flattr_token_notification_msg">A súa conta de Flattr non semella estar conectada a AntennaPod. Toque aquà para autenticarse.</string> - <string name="no_flattr_token_msg">A súa conta de Flattr non semella estar conectada a AntennaPod. Ben pode conectar a súa conta a AntennaPod para interactuar en Flattr desde o app ou ben pode visitar o sitio web do elemento e darlle ao flattr desde alÃ.</string> + <string name="no_flattr_token_msg">A súa conta de Flattr non semella estar conectada a AntennaPod. Ben pode conectar a súa conta a AntennaPod para interactuar en Flattr desde o aplicativo ou ben pode visitar o sitio web do elemento e darlle ao flattr desde alÃ.</string> <string name="authenticate_now_label">Autenticar</string> <string name="action_forbidden_title">Acción non permitida</string> <string name="action_forbidden_msg">AntennaPod non ten permiso para esta acción. A razón poderÃa ser que o testemuño de acceso de AntennaPod ou a súa conta fosen rexeitados. Pode voltar a autenticarse ou visitar o sitio web do elemento.</string> <string name="access_revoked_title">Acceso rexeitado</string> - <string name="access_revoked_info">Eliminou correctamente o testemuño de acceso de AntennaPod a súa conta. Para completar o proceso deberá eliminar este aplicativo da lista de aplicativos autorizados nos axustes da súa conta na web de Flattr.</string> + <string name="access_revoked_info">Eliminou correctamente o token de acceso de AntennaPod á súa conta. Para completar o proceso deberá eliminar este aplicativo da lista de aplicativos autorizados nos axustes da súa conta na web de Flattr.</string> <!--Flattr--> <string name="flattr_click_success">Flateraches algo!</string> <string name="flattr_click_success_count">Flateraches %d cousas!</string> @@ -272,7 +287,7 @@ <string name="enable_sonic">Habilitar Sonic</string> <!--Empty list labels--> <string name="no_items_label">Non hai elementos na lista.</string> - <string name="no_feeds_label">AÃnda non está suscrito a ningunha fonte.</string> + <string name="no_feeds_label">AÃnda non está subscrito a ningún podcast.</string> <string name="no_chapters_label">Este episodio non ten capÃtulos.</string> <string name="no_shownotes_label">Este episodio non ten notas de episodio.</string> <!--Preferences--> @@ -281,15 +296,23 @@ <string name="other_pref">Outro</string> <string name="about_pref">Sobre</string> <string name="queue_label">Cola</string> - <string name="services_label">Servizos</string> + <string name="integrations_label">Integracións</string> <string name="flattr_label">Flattr</string> + <string name="flattr_summary">Servizo de micropagamentos</string> + <string name="automation">Automatizado</string> + <string name="download_pref_details">Detalles</string> + <string name="import_export_pref">Importar/Exportar</string> + <string name="appearance">Aspecto</string> + <string name="external_elements">Elementos externos</string> + <string name="interruptions">Interrupcións</string> + <string name="buttons">Botóns do control de reprodución</string> + <string name="media_player">Reprodutor de medios</string> <string name="pref_episode_cleanup_title">Limpeza de episodios</string> <string name="pref_episode_cleanup_summary">Os episodios que non están na cola e tampouco son favoritos deberÃan poder ser candidatos a ser eliminados si a función Descarga Automática precisa espazo para novos episodios.</string> <string name="pref_pauseOnDisconnect_sum">Deter a reprodución cando se desconectan os auriculares ou bluetooth</string> <string name="pref_unpauseOnHeadsetReconnect_sum">Retomar a reprodución cando se conectan os auriculares</string> <string name="pref_unpauseOnBluetoothReconnect_sum">Retomar a reprodución cando se reconecta o bluetooth</string> <string name="pref_hardwareForwardButtonSkips_title">O botón Adiante salta</string> - <string name="pref_hardwareForwardButtonSkips_sum">Cando se presiona o botón Adiante no dispositivo salta ao seguinte episodio en lugar de reproducir de xeito acelerado</string> <string name="pref_hardwarePreviousButtonRestarts_title">O botón Anterior reinicia</string> <string name="pref_hardwarePreviousButtonRestarts_sum">Cando se presiona Anterior no dispositivo reinicia o episodio no lugar de ir cara atrás</string> <string name="pref_followQueue_sum">Saltar ao seguinte elemento na cola cando remata o episodio</string> @@ -304,9 +327,9 @@ <string name="playback_pref">Reprodución</string> <string name="network_pref">Rede</string> <string name="pref_autoUpdateIntervallOrTime_title">Intervalo de actualización ou Hora do dÃa</string> - <string name="pref_autoUpdateIntervallOrTime_sum">Indicar un intervalo ou unha hora en concreto para actualizar automáticamente as fontes</string> - <string name="pref_autoUpdateIntervallOrTime_message">Pode establecer un <i>intervalo</i> como \"2 horas\", unha <i>hora do dÃa</i> en concreto como \"7:00 AM\" ou <i>deshabilitar</i>totalmente a actualización automática.\n\n<small>Aviso: indicar que pode haber un lixeiro retardo do momento da actualización.</small></string> - <string name="pref_autoUpdateIntervallOrTime_Disable">Deshabilitar</string> + <string name="pref_autoUpdateIntervallOrTime_sum">Indicar un intervalo ou unha hora en concreto para actualizar automaticamente as fontes</string> + <string name="pref_autoUpdateIntervallOrTime_message">Pode establecer un <i>intervalo</i> como \"2 horas\", unha <i>hora do dÃa</i> en concreto como \"7:00 AM\" ou <i>desactivar</i> totalmente a actualización automática.\n\n<small>Aviso: pode haber un lixeiro retardo do momento da actualización.</small></string> + <string name="pref_autoUpdateIntervallOrTime_Disable">Desactivar</string> <string name="pref_autoUpdateIntervallOrTime_Interval">Establecer intervalo</string> <string name="pref_autoUpdateIntervallOrTime_TimeOfDay">Establecer hora do dÃa</string> <string name="pref_autoUpdateIntervallOrTime_every">cada %1$s</string> @@ -335,10 +358,10 @@ <string name="pref_nav_drawer_sum">Personalice o aspecto da caixa de navegación</string> <string name="pref_nav_drawer_items_title">Estableza os elementos da Caixa de navegación</string> <string name="pref_nav_drawer_items_sum">Cambie os elementos que aparecerán na Caixa de navegación</string> - <string name="pref_nav_drawer_feed_order_title">Estableza a orde de suscrición</string> - <string name="pref_nav_drawer_feed_order_sum">Cambie a orde das súas suscricións</string> - <string name="pref_nav_drawer_feed_counter_title">Establecer o contador de suscricións</string> - <string name="pref_nav_drawer_feed_counter_sum">Cambie a información mostrada polo contador de suscricións</string> + <string name="pref_nav_drawer_feed_order_title">Estableza a orde das subscricións</string> + <string name="pref_nav_drawer_feed_order_sum">Cambie a orde das subscricións</string> + <string name="pref_nav_drawer_feed_counter_title">Establecer o contador de subscricións</string> + <string name="pref_nav_drawer_feed_counter_sum">Cambiar a información mostrada polo contador de subscricións. Tamén afecta á orde das subscricións se \"Orde das subscricións\" está establecida a \"Contador\".</string> <string name="pref_set_theme_sum">Cambiar o aspecto de AntennaPod.</string> <string name="pref_automatic_download_title">Descarga automática</string> <string name="pref_automatic_download_sum">Axuste a descarga automática de episodios.</string> @@ -352,20 +375,21 @@ <string name="pref_episode_cache_title">Caché de episodios</string> <string name="pref_theme_title_light">Claro</string> <string name="pref_theme_title_dark">Oscuro</string> + <string name="pref_theme_title_trueblack">Negro (listo para AMOLED)</string> <string name="pref_episode_cache_unlimited">Ilimitado</string> <string name="pref_update_interval_hours_plural">horas</string> <string name="pref_update_interval_hours_singular">hora</string> <string name="pref_update_interval_hours_manual">Manual</string> <string name="pref_gpodnet_authenticate_title">Conexión</string> - <string name="pref_gpodnet_authenticate_sum">Conectar coa súa conta gpodder.net para sincronizar as súas suscricións.</string> + <string name="pref_gpodnet_authenticate_sum">Conecte coa súa conta gpodder.net para sincronizar as súas subscricións.</string> <string name="pref_gpodnet_logout_title">Desconectar</string> <string name="pref_gpodnet_logout_toast">Desconectouse correctamente</string> <string name="pref_gpodnet_setlogin_information_title">Cambiar a información de conexión</string> <string name="pref_gpodnet_setlogin_information_sum">Cambiar a información de conexión da súa conta gpodder.net</string> <string name="pref_gpodnet_sync_changes_title">Sincronizar os cambios agora</string> - <string name="pref_gpodnet_sync_changes_sum">Sincronizar os datos de suscrición e estado dos episodios con gpodder.net</string> + <string name="pref_gpodnet_sync_changes_sum">Sincronizar os datos de subscrición e estado dos episodios con gpodder.net</string> <string name="pref_gpodnet_full_sync_title">Sincronice todo agora</string> - <string name="pref_gpodnet_full_sync_sum">Sincronizar todas as suscricións e estados de episodios con gpodder.net</string> + <string name="pref_gpodnet_full_sync_sum">Sincronizar todas as subscricións e estados de episodios 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">Sincronización iniciada</string> <string name="pref_gpodnet_full_sync_started">Sincronización completa iniciada</string> @@ -380,8 +404,6 @@ <string name="pref_rewind_sum">Personalice o número de segundos que se retrocede na reprodución cando se pulsa o botón retroceso</string> <string name="pref_gpodnet_sethostname_title">Establecer servidor</string> <string name="pref_gpodnet_sethostname_use_default_host">Utilizar servidor por omisión</string> - <string name="pref_expandNotify_title">Expandir notificación</string> - <string name="pref_expandNotify_sum">Expandir sempre a notificación para mostrar os botóns de reprodución</string> <string name="pref_persistNotify_title">Controles persistentes de reprodución</string> <string name="pref_persistNotify_sum">Manter notificación e controles na pantalla de bloqueo cando a reprodución está pausada.</string> <string name="pref_compact_notification_buttons_title">Establecer botóns de pantalla de bloqueo</string> @@ -395,15 +417,14 @@ <string name="pref_expand_notify_unsupport_toast">As versións de Android anteriores a 4.1 non teñen soporte para notificacións expandidas.</string> <string name="pref_queueAddToFront_sum">Engadir os novos episodios ao inicio da cola.</string> <string name="pref_queueAddToFront_title">Por no inicio da cola</string> - <string name="pref_smart_mark_as_played_disabled">Deshabilitado</string> + <string name="pref_smart_mark_as_played_disabled">Desactivado</string> <string name="pref_image_cache_size_title">Tamaño da caché de imaxes</string> <string name="pref_image_cache_size_sum">Tamaño da caché en disco para as imaxes.</string> <string name="crash_report_title">Informe de Desgracias</string> <string name="crash_report_sum">Enviar por email o informe de fallo xeral no aplicativo</string> <string name="send_email">Enviar email</string> <string name="experimental_pref">En probas</string> - <string name="pref_sonic_title">Sonic Media Player</string> - <string name="pref_sonic_message">Utilizar o sonic media player incluÃdo no lugar do reprodutor nativo de Android e Prestissimo</string> + <string name="pref_media_player_message">Escolla o reprodutor de medios para reproducir ficheiros</string> <string name="pref_current_value">Valor actual: %1$s</string> <string name="pref_proxy_title">Proxy</string> <string name="pref_proxy_sum">Establecer un proxy para a rede</string> @@ -412,9 +433,14 @@ <string name="pref_no_browser_found">Non se atopou un navegador web</string> <string name="pref_cast_title">Soporte Chromecast</string> <string name="pref_cast_message_play_flavor">Habilitar o soporte de reprodución remota nun dispositivo Cast (como o Chromecast, Altofalantes ou Android TV)</string> - <string name="pref_cast_message_free_flavor">Chromecast precisa software propietario de terceiras partes que están deshabilitadas en esta versión de AntennaPod</string> + <string name="pref_cast_message_free_flavor">Chromecast precisa software propietario de terceiras partes que están desactivadas en esta versión de AntennaPod</string> <string name="pref_enqueue_downloaded_title">Foron descargados os elementos da cola</string> <string name="pref_enqueue_downloaded_summary">Engadir os episodios descargados a cola</string> + <string name="media_player_builtin">Reprodutor android nativo</string> + <string name="pref_videoBehavior_title">Ao saÃr do vÃdeo</string> + <string name="pref_videoBehavior_sum">Comportamento cando saia do vÃdeo</string> + <string name="stop_playback">Para a reprodución</string> + <string name="continue_playback">Continuar a reprodución de audio</string> <!--Auto-Flattr dialog--> <string name="auto_flattr_enable">Hablitar o flattring automático</string> <string name="auto_flattr_after_percent">Flattr o episodio tan pronto como o %d por cento foi reproducido</string> @@ -424,8 +450,8 @@ <string name="search_hint">Buscar episodios</string> <string name="found_in_shownotes_label">Atopado nas notas do episodio</string> <string name="found_in_chapters_label">Atopado en capÃtulos</string> - <string name="found_in_authors_label">Atopado en autores</string> - <string name="found_in_feeds_label">Atopado en fontes</string> + <string name="found_in_authors_label">Atopado en autor(es)</string> + <string name="found_in_feeds_label">Atopado no podcast</string> <string name="search_status_no_results">Non se atoparon resultados</string> <string name="search_label">Buscar</string> <string name="found_in_title_label">Atopado no tÃtulo</string> @@ -451,12 +477,12 @@ <string name="html_export_label">Exportar HTML</string> <string name="exporting_label">Exportando...</string> <string name="export_error_label">Fallo ao exportar</string> - <string name="opml_export_success_title">Exportación OPML exitosa.</string> - <string name="opml_export_success_sum">O ficheiro .opml foi gardado en:\u0020</string> + <string name="export_success_title">Exportado con éxito</string> + <string name="export_success_sum">Escribeuse o ficheiro exportado en:\n\n%1$s</string> <string name="opml_import_ask_read_permission">PrecÃsase acceso ao almacenamento externo para ler o ficheiro OPML</string> <!--Sleep timer--> <string name="set_sleeptimer_label">Establecer apagado automático</string> - <string name="disable_sleeptimer_label">Deshabilitar o apagado automático</string> + <string name="disable_sleeptimer_label">Desactivar o apagado automático</string> <string name="enter_time_here_label">Introducir tempo</string> <string name="sleep_timer_label">Apagado automático</string> <string name="time_left_label">Tempo restante:\u0020</string> @@ -479,9 +505,9 @@ <item quantity="one">1 hora</item> <item quantity="other">%d horas</item> </plurals> - <string name="auto_enable_label">Habilitar automáticamente</string> + <string name="auto_enable_label">Habilitar automaticamente</string> <string name="sleep_timer_enabled_label">Apagado automático habilitado</string> - <string name="sleep_timer_disabled_label">Apagado automático deshabilitado</string> + <string name="sleep_timer_disabled_label">Apagado automático desactivado</string> <!--gpodder.net--> <string name="gpodnet_taglist_header">CATEGORÃAS</string> <string name="gpodnet_toplist_header">PODCASTS TOP</string> @@ -504,7 +530,7 @@ <string name="gpodnetauth_device_caption_errorEmpty">Non pode quedar baldeiro o titulo</string> <string name="gpodnetauth_device_butChoose">Escoller</string> <string name="gpodnetauth_finish_title">Conexión correcta!</string> - <string name="gpodnetauth_finish_descr">Parabéns! A súa conta gpodder.net está conectada ao dispositivo. AntennaPod poderá agora sincronizar automáticamente as súas suscricións no dispositivo na conta de gpodder.net</string> + <string name="gpodnetauth_finish_descr">Parabéns! A súa conta gpodder.net está conectada ao dispositivo. AntennaPod poderá agora sincronizar automaticamente as súas subscricións no dispositivo na conta de gpodder.net</string> <string name="gpodnetauth_finish_butsyncnow">Iniciar a sincronización</string> <string name="gpodnetauth_finish_butgomainscreen">Ir a pantalla principal</string> <string name="gpodnetsync_auth_error_title">fallo na autenticación en gpodder.net</string> @@ -530,14 +556,14 @@ <string name="folder_not_empty_dialog_title">O cartafol non está baldeiro</string> <string name="folder_not_empty_dialog_msg">O cartafol escollido non está baldeiro. As descargas de medios e outros ficheiros situaranse directamente en este cartafol. Proceder de todos xeitos?</string> <string name="set_to_default_folder">Escolla o cartafol por omisión</string> - <string name="pref_pausePlaybackForFocusLoss_sum">Pausar a reprodución en lugar de baixar o volume cando outro app quere reproducir un son.</string> + <string name="pref_pausePlaybackForFocusLoss_sum">Pausar a reprodución en lugar de baixar o volume cando outro aplicativo quere reproducir un son.</string> <string name="pref_pausePlaybackForFocusLoss_title">Pausa para interrupcións</string> <string name="pref_resumeAfterCall_sum">Retomar a reprodución despois de rematar a chamada telefónica</string> <string name="pref_resumeAfterCall_title">Retomar despois da chamada</string> <string name="pref_restart_required">AntennaPod debe reiniciarse para que esta opción se aplique.</string> <!--Online feed view--> - <string name="subscribe_label">Suscribir</string> - <string name="subscribed_label">Suscrito</string> + <string name="subscribe_label">Subscribir</string> + <string name="subscribed_label">Subscrito</string> <string name="downloading_label">Descargando...</string> <!--Content descriptions for image buttons--> <string name="rewind_label">Rebobinar</string> @@ -562,10 +588,10 @@ <!--Progress information--> <string name="progress_upgrading_database">Actualizando a base de datos</string> <!--AntennaPodSP--> - <string name="sp_apps_importing_feeds_msg">Importando as suscricións desde apps de propósito único...</string> + <string name="sp_apps_importing_feeds_msg">Importando as subscricións desde aplicativos de propósito único...</string> <string name="search_itunes_label">Buscar en iTunes</string> <string name="filter">Filtrado</string> - <string name="search_fyyd_label">Buscar fyyd</string> + <string name="search_fyyd_label">Buscar en fyyd</string> <!--Episodes apply actions--> <string name="all_label">Todo</string> <string name="selected_all_label">Seleccionar todos os episodios</string> @@ -593,7 +619,7 @@ <string name="sort_duration_short_long">Duración (Curto \u2192 Longo)</string> <string name="sort_duration_long_short">Duración (Longo \u2192 Curto)</string> <!--Rating dialog--> - <string name="rating_title">Gosta de AntennaPod?</string> + <string name="rating_title">Goza de AntennaPod?</string> <string name="rating_message">AgradecerÃamos que dedicase un intre a valorar AntennaPod.</string> <string name="rating_never_label">Pasa de min oh!</string> <string name="rating_later_label">Lembrar máis tarde</string> @@ -621,11 +647,11 @@ <string name="proxy_port_invalid_error">Porto non válido</string> <!--Database import/export--> <string name="import_export">Importar/Exportar base de datos</string> - <string name="import_export_warning">Esta función experimental utilÃzase para transferir as súas suscricións e episodios reproducidos en outro dispositivo.\n\nAs bases de datos exportadas só se poden importar si utiliza a misma versión de AntennaPod. De todos xeitos, esta función pode comportarse de xeito raro.\n\nDespois de importar, os episodios poderÃan ser mostrados como descargados sin telo sido. Simplemente pulse o botón de reprodución dos episodios para que AntennaPod detecte esto.</string> + <string name="import_export_warning">Esta función experimental utilÃzase para transferir as súas subscricións e episodios reproducidos noutro dispositivo.\n\nAs bases de datos exportadas só se poden importar se utiliza a misma versión de AntennaPod. De todos xeitos, esta función pode comportarse de xeito raro.\n\nDespois de importar, os episodios poderÃan ser mostrados como descargados sin telo sido. Simplemente pulse o botón de reprodución dos episodios para que AntennaPod detecte esto.</string> <string name="label_import">Importar</string> <string name="label_export">Exportar</string> <string name="import_select_file">Escolla o ficheiro a importar</string> - <string name="export_ok">Exportouse correctamente. A base de datos escribeuse na tarxeta SD.</string> + <string name="export_ok">Exportado con éxito.</string> <string name="import_ok">Importación correcta.\n\nPulse OK para reiniciar AntennaPod</string> <!--Casting--> <string name="cast_media_route_menu_title">Reproducir en...</string> @@ -643,4 +669,13 @@ <string name="cast_failed_seek">Non se puido cambiar a posición no dispositivo de emisión</string> <string name="cast_failed_receiver_player_error">O reprodutor receptor atopou un fallo grave</string> <string name="cast_failed_media_error_skipping">Fallo na reprodución de medios. Saltando...</string> + <!--Notification channels--> + <string name="notification_channel_user_action">Acción requerida</string> + <string name="notification_channel_user_action_description">Mostrado si a súa acción é requerida, por exemplo si precisa introducir o contrasinal.</string> + <string name="notification_channel_downloading">Descargando</string> + <string name="notification_channel_downloading_description">Mostrado durante a descarga actual.</string> + <string name="notification_channel_playing">Soando agora</string> + <string name="notification_channel_playing_description">Permite controlar a reprodución. Esta é a notificación principal que verá mentras reproduce un podcast.</string> + <string name="notification_channel_error">Fallos</string> + <string name="notification_channel_error_description">Mostrado si algo falla, por exemplo si a descarga ou a sincronización con gpodder fallan.</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 7e3333a37..2cb584c48 100644 --- a/core/src/main/res/values-hi-rIN/strings.xml +++ b/core/src/main/res/values-hi-rIN/strings.xml @@ -1,35 +1,75 @@ <?xml version='1.0' encoding='UTF-8'?> <resources xmlns:tools="http://schemas.android.com/tools"> <!--Activitiy and fragment titles--> + <string name="feed_update_receiver_name">सबà¥à¤¸à¥à¤•à¥à¤°à¤¿à¤ªà¥à¤¶à¤¨à¥à¤¸ का अदà¥à¤¯à¤¤à¤¨ </string> <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="new_episodes_label">नये</string> + <string name="favorite_episodes_label">पसंदीदा</string> <string name="new_label">नया</string> <string name="settings_label">सेटिंगà¥à¤¸</string> <string name="downloads_label">डाउनलोड</string> + <string name="downloads_running_label">जारी</string> + <string name="downloads_completed_label">संपनà¥à¤¨ हà¥à¤</string> + <string name="downloads_log_label">अà¤à¤¿à¤²à¥‡à¤–</string> + <string name="subscriptions_label">सबà¥à¤¸à¥à¤•à¥à¤°à¤¿à¤ªà¥à¤¶à¤¨à¥à¤¸</string> + <string name="subscriptions_list_label">सबà¥à¤¸à¥à¤•à¥à¤°à¤¿à¤ªà¥à¤¶à¤¨à¥à¤¸ की सूची</string> <string name="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 login</string> + <string name="gpodnet_summary">अनà¥à¤¯ उपकरण के साथ समकà¥à¤°à¤®à¤¿à¤• करें</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> + <string name="synchronizing">समकà¥à¤°à¤®à¤¿à¤• हो रहा है...</string> <!--Statistics fragment--> + <string name="total_time_listened_to_podcasts">चलाये गठपॉडकासà¥à¤Ÿ का कà¥à¤² समय:</string> + <string name="statistics_details_dialog">%2$d में से %1$d à¤à¤ªà¤¿à¤¸à¥‹à¤¡ शà¥à¤°à¥‚ किठगठहै.\n\n%4$s में से %3$sपूरे हà¥à¤ है। </string> + <string name="statistics_mode_normal">वासà¥à¤¤à¤µ में चलाई गयी अवधि की गणना करें। दो बार चलने पर दो बार गिना जायेगा, जबकि चल चूका सा चिहà¥à¤¨à¤¿à¤¤à¥‹ को नही गिना जायेगा।</string> + <string name="statistics_speed_not_counted">सूचना: पà¥à¤²à¥‡à¤¬à¥ˆà¤• गति को कà¤à¥€ à¤à¥€ धà¥à¤¯à¤¾à¤¨ में नहीं रखा जाता है।</string> <!--Main activity--> + <string name="drawer_open">मेनà¥à¤¯à¥‚ खोलें</string> + <string name="drawer_close">मेनà¥à¤¯à¥‚ बंद करें</string> + <string name="drawer_preferences">डà¥à¤°à¤¾à¤µà¤° की पà¥à¤°à¤¾à¤¥à¤®à¤¿à¤•à¤¤à¤¾à¤à¤‚</string> + <string name="drawer_feed_order_unplayed_episodes">काउंटर से कà¥à¤°à¤®à¤¬à¤¦à¥à¤§ करें</string> + <string name="drawer_feed_order_alphabetical">वरà¥à¤£à¤¾à¤¨à¥à¤•à¥à¤°à¤® से कà¥à¤°à¤®à¤¬à¤¦à¥à¤§ करें</string> + <string name="drawer_feed_order_last_update">पà¥à¤°à¤•à¤¾à¤¶à¤¨ तिथि से कà¥à¤°à¤®à¤¬à¤¦à¥à¤§ करें</string> + <string name="drawer_feed_order_most_played">चलाठगठà¤à¤ªà¤¿à¤¸à¥‹à¤¡ की संखà¥à¤¯à¤¾</string> + <string name="drawer_feed_counter_new_unplayed">नठऔर नहीं चलाठगठà¤à¤ªà¤¿à¤¸à¥‹à¤¡ की संखà¥à¤¯à¤¾</string> + <string name="drawer_feed_counter_new">नठà¤à¤ªà¤¿à¤¸à¥‹à¤¡ की संखà¥à¤¯à¤¾</string> + <string name="drawer_feed_counter_unplayed">नहीं चलाठगठà¤à¤ªà¤¿à¤¸à¥‹à¤¡ की संखà¥à¤¯à¤¾</string> + <string name="drawer_feed_counter_downloaded">डाउनलोड किठगठà¤à¤ªà¤¿à¤¸à¥‹à¤¡ की संखà¥à¤¯à¤¾</string> + <string name="drawer_feed_counter_none">शूनà¥à¤¯</string> <!--Webview actions--> <string name="open_in_browser_label">बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤° में खोलें</string> <string name="copy_url_label">कॉपी यूआरà¤à¤²</string> <string name="share_url_label">शेयर यूआरà¤à¤²</string> - <string name="copied_url_msg">यूआरà¤à¤² को कà¥à¤²à¤¿à¤ªà¤¬à¥‹à¤°à¥à¤¡ पर कॉपी कर लिया गया है</string> + <string name="copied_url_msg">यूआरà¤à¤² को कà¥à¤²à¤¿à¤ªà¤¬à¥‹à¤°à¥à¤¡ पर कॉपी किया गया है</string> + <string name="go_to_position_label">इस सà¥à¤¥à¤¾à¤¨ पर जाà¤à¤‚</string> <!--Playback history--> <string name="clear_history_label"> हिसà¥à¤Ÿà¥à¤°à¥€ हटाà¤à¤</string> <!--Other--> <string name="confirm_label">पà¥à¤·à¥à¤Ÿà¤¿ करें</string> <string name="cancel_label">रदà¥à¤¦ करें</string> - <string name="author_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> <string name="podcast_settings_label">सेटिंगà¥à¤¸</string> <string name="cover_label">तसà¥à¤µà¥€à¤°</string> <string name="error_label">तà¥à¤°à¥à¤Ÿà¤¿</string> <string name="error_msg_prefix">à¤à¤• तà¥à¤°à¥à¤Ÿà¤¿ हो गई:</string> + <string name="needs_storage_permission">इस कारà¥à¤¯ की पूरà¥à¤¤à¥€ के लिठसà¥à¤Ÿà¥‹à¤°à¥‡à¤œ अनà¥à¤®à¤¤à¤¿ की आवशà¥à¤¯à¤•à¤¤à¤¾ है</string> <string name="refresh_label">ताज़ा करें</string> <string name="external_storage_error_msg">कोई बाहरी à¤à¤‚डारण उपलबà¥à¤§ नहीं है.सà¥à¤¨à¤¿à¤¶à¥à¤šà¤¿à¤¤ करें कि आपने बाहरी à¤à¤‚डारण मà¥à¤¹à¤¿à¤® शà¥à¤°à¥‚ की है ताकि अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— ठीक से काम कर सकते हैं</string> <string name="chapters_label">अधà¥à¤¯à¤¾à¤¯</string> + <string name="chapter_duration">अवधि: %1$s</string> <string name="shownotes_label">नोटà¥à¤¸ दिखाà¤à¤</string> <string name="description_label">विवरण</string> <string name="most_recent_prefix">सबसे हाल का पà¥à¤°à¤•à¤°à¤£:\u0020</string> @@ -37,40 +77,100 @@ <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> <string name="auto_download_label">ऑटो डाउनलोड में शामिल करें</string> + <string name="auto_download_apply_to_items_title">पिछले à¤à¤ªà¤¿à¤¸à¥‹à¤¡ पर लागू करें</string> + <string name="auto_download_apply_to_items_message">नया <i>ऑटो डाउनलोड</i> सेटिंग सà¥à¤µà¤šà¤¾à¤²à¤¿à¤¤ रूप से नठà¤à¤ªà¤¿à¤¸à¥‹à¤¡ पर लागू की जाà¤à¤—ा।\nकà¥à¤¯à¤¾ आप इससे पहले पà¥à¤°à¤•à¤¾à¤¶à¤¿à¤¤ à¤à¤ªà¤¿à¤¸à¥‹à¤¡ पर à¤à¥€ लागू करना चाहते हैं?</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> + <string name="episode_cleanup_never">कà¤à¥€ नहीà¤</string> + <string name="episode_cleanup_queue_removal">जब क़तार में नहीं हो</string> + <string name="episode_cleanup_after_listening">समापà¥à¤¤à¤¿ के बाद</string> + <plurals name="episode_cleanup_days_after_listening"> + <item quantity="one">समापà¥à¤¤à¤¿ के 1 दिन बाद</item> + <item quantity="other">समापà¥à¤¤à¤¿ के %d दिन बाद</item> + </plurals> <!--'Add Feed' Activity labels--> <string name="feedurl_label">यूआरà¤à¤² फ़ीड</string> + <string name="etxtFeedurlHint">www.example.com/feed</string> <string name="txtvfeedurl_label">यूआरà¤à¤² दà¥à¤µà¤¾à¤°à¤¾ पॉडकासà¥à¤Ÿ जोड़ें</string> <string name="podcastdirectories_label">पॉडकासà¥à¤Ÿ निरà¥à¤¦à¥‡à¤¶à¤¿à¤•à¤¾</string> + <string name="podcastdirectories_descr">नठपॉडकासà¥à¤Ÿ के लिà¤, आप iTunes या fyyd खोज सकते हैं, या gpodder.net को नाम, शà¥à¤°à¥‡à¤£à¥€ या लोकपà¥à¤°à¤¿à¤¯à¤¤à¤¾ दà¥à¤µà¤¾à¤°à¤¾ बà¥à¤°à¤¾à¤‰à¤œà¤¼ कर सकते हैं।</string> + <string name="browse_gpoddernet_label">gpodder.net बà¥à¤°à¤¾à¤‰à¤œà¤¼ करें</string> <!--Actions on feeds--> <string name="mark_all_read_label">पढ़ने के रूप में सà¤à¥€ को चिहà¥à¤¨à¤¿à¤¤ करें</string> <string name="show_info_label">जानकारी दिखाà¤à¤</string> - <string name="remove_feed_label">पॉडकासà¥à¤Ÿ हटाà¤à¤ -</string> - <string name="share_link_label">शेयर वेबसाइट लिंक</string> - <string name="feed_remover_msg">फ़ीड निकाल रहा है</string> + <string name="show_feed_settings_label">पॉडकासà¥à¤Ÿ सेटिंग दिखाà¤à¤‚</string> + <string name="feed_info_label">पॉडकासà¥à¤Ÿ की जानकारी</string> + <string name="feed_settings_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> + <string name="share_link_with_position_label">सà¥à¤¥à¤¾à¤¨ के साथ à¤à¤ªà¤¿à¤¸à¥‹à¤¡ URL शेयर करे</string> + <string name="share_file_label">फाइल शेयर करे</string> + <string name="share_feed_url_label">फीड URL शेयर करे</string> + <string name="share_item_url_label">मीडिया फाइल शेयर करे</string> + <string name="share_item_url_with_position_label"> सà¥à¤¥à¤¾à¤¨ के साथ मीडिया फाइल शेयर करे</string> + <string name="feed_remover_msg">पॉडकासà¥à¤Ÿ हटाया जारहा है</string> + <string name="load_complete_feed">सारे पॉडकासà¥à¤Ÿ को रिफà¥à¤°à¥‡à¤¶ करें</string> + <string name="hide_episodes_title">à¤à¤ªà¤¿à¤¸à¥‹à¤¡ छà¥à¤ªà¤¾à¤</string> + <string name="batch_edit">जतà¥à¤¥à¤¾ संपादित करें</string> + <string name="hide_unplayed_episodes_label">नहीं चलाठगà¤</string> + <string name="hide_paused_episodes_label">रोके गà¤</string> + <string name="hide_played_episodes_label">चलाठगà¤</string> + <string name="hide_queued_episodes_label">क़तार किठगà¤</string> + <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="hide_is_favorite_label">पसंदीदा है</string> + <string name="filtered_label">छाने हà¥à¤</string> + <string name="refresh_failed_msg">{fa-exclamation-circle} पिछला रिफà¥à¤°à¥‡à¤¶ असफल हà¥à¤†</string> + <string name="open_podcast">पॉडकासà¥à¤Ÿ खोले</string> <!--actions on feeditems--> <string name="download_label">डाउनलोड</string> <string name="play_label">पà¥à¤²à¥‡</string> <string name="pause_label">रोकें</string> + <string name="stop_label">रोकें</string> <string name="stream_label">सà¥à¤Ÿà¥à¤°à¤¿à¤®</string> <string name="remove_label"> हटाà¤à¤</string> - <string name="mark_read_label">पà¥à¤¾ हà¥à¤† के रूप में चिहà¥à¤¨à¤¿à¤¤ करें</string> - <string name="mark_unread_label">ना पà¥à¤¾ हà¥à¤† के रूप में चिहà¥à¤¨à¤¿à¤¤ करें</string> + <string name="delete_label">डिलीट</string> + <string name="delete_failed">फ़ाइल डिलीट करने में असमरà¥à¤¥à¥¤ डिवाइस को रिबूट करने से मदद मिल सकती है।</string> + <string name="remove_episode_lable">à¤à¤ªà¤¿à¤¸à¥‹à¤¡ हटाà¤à¤‚</string> + <string name="mark_as_seen_label">देखा गया के रूप में चिहà¥à¤¨à¤¿à¤¤ करें</string> + <string name="marked_as_seen_label">देखा गया के रूप में चिहà¥à¤¨à¤¿à¤¤ किया गया</string> + <string name="mark_read_label">चलाया गया के रूप में चिहà¥à¤¨à¤¿à¤¤ करें</string> + <string name="marked_as_read_label">चलाया गया के रूप में चिहà¥à¤¨à¤¿à¤¤ किया गया</string> + <string name="mark_unread_label">नही चलाया गया के रूप में चिहà¥à¤¨à¤¿à¤¤ करें</string> <string name="add_to_queue_label">क़तार में जोड़ें</string> + <string name="added_to_queue_label">कांतर में जोड़े गà¤</string> <string name="remove_from_queue_label">क़तार से हटाà¤à¤</string> + <string name="add_to_favorite_label">पसंदीदा सूची में जोड़े</string> + <string name="added_to_favorites">पसंदीदा सूची में जोड़ा गया</string> + <string name="remove_from_favorite_label">पसंदीदा सूची से हटाà¤</string> + <string name="removed_from_favorites">पसंदीदा सूची से हटया गया</string> <string name="visit_website_label">वेबसाइट पर जाà¤à¤</string> <string name="support_label">इसे Flattr करें</string> <string name="skip_episode_label">à¤à¤ªà¤¿à¤¸à¥‹à¤¡ छोङें</string> + <string name="activate_auto_download">ऑटो डाउनलोड सकà¥à¤°à¤¿à¤¯ करें</string> + <string name="deactivate_auto_download">ऑटो डाउनलोड निषà¥à¤•à¥à¤°à¤¿à¤¯ करें</string> + <string name="reset_position">पà¥à¤²à¥‡à¤¬à¥ˆà¤• सà¥à¤¥à¤¿à¤¤à¤¿ रीसेट करें</string> + <string name="removed_item">आइटम हटया गया</string> <!--Download messages and labels--> - <string name="download_successful">सफल -</string> - <string name="download_failed">डाउनलोड विफल</string> + <string name="download_successful">सफल हà¥à¤†</string> + <string name="download_failed">असफल हà¥à¤†</string> <string name="download_pending">लंबित डाउनलोड</string> <string name="download_running">डाउनलोड चल रहा है</string> + <string name="download_error_details">विवरण</string> + <string name="download_error_details_message">%1$s \n\nफाइल URL:\n%2$s</string> <string name="download_error_device_not_found">सà¥à¤Ÿà¥‹à¤°à¥‡à¤œ डिवाइस नहीं मिला</string> <string name="download_error_insufficient_space">अपरà¥à¤¯à¤¾à¤ªà¥à¤¤ सà¥à¤¥à¤¾à¤¨</string> <string name="download_error_file_error">फ़ाइल तà¥à¤°à¥à¤Ÿà¤¿</string> @@ -80,13 +180,23 @@ <string name="download_error_unsupported_type">असमरà¥à¤¥à¤¿à¤¤ फ़ीड पà¥à¤°à¤•à¤¾à¤°</string> <string name="download_error_connection_error">कनेकà¥à¤¶à¤¨ तà¥à¤°à¥à¤Ÿà¤¿</string> <string name="download_error_unknown_host">अजà¥à¤žà¤¾à¤¤ होसà¥à¤Ÿ</string> + <string name="download_error_unauthorized">पà¥à¤°à¤®à¤¾à¤£à¥€à¤•à¤°à¤£ तà¥à¤°à¥à¤Ÿà¤¿</string> + <string name="download_error_file_type_type">फ़ाइल पà¥à¤°à¤•à¤¾à¤° तà¥à¤°à¥à¤Ÿà¤¿</string> + <string name="download_error_forbidden">निषिदà¥à¤§</string> <string name="cancel_all_downloads_label">सà¤à¥€ डाउनलोड रदà¥à¤¦ करें</string> <string name="download_canceled_msg">डाउनलोड रदà¥à¤¦</string> - <string name="download_report_title">डाउनलोड पूरा हो गया है</string> + <string name="download_canceled_autodownload_enabled_msg">डाउनलोड रदà¥à¤¦ हà¥à¤†\nइस आइटम के लिठ<i>ऑटडाउनलोड</i> अकà¥à¤·à¤® किया गया</string> + <string name="download_report_title">तà¥à¤°à¥à¤Ÿà¤¿ के साथ डाउनलोड संपनà¥à¤¨ हà¥à¤</string> + <string name="download_report_content_title">रिपोरà¥à¤Ÿ डाउनलोड करे</string> <string name="download_error_malformed_url">गलत URL</string> <string name="download_error_io_error">आईओ तà¥à¤°à¥à¤Ÿà¤¿</string> <string name="download_error_request_error">अनà¥à¤°à¥‹à¤§ तà¥à¤°à¥à¤Ÿà¤¿</string> <string name="download_error_db_access">डेटाबेस का उपयोग तà¥à¤°à¥à¤Ÿà¤¿</string> + <plurals name="downloads_left"> + <item quantity="one">%d डाउनलोड बाकी</item> + <item quantity="other">%d डाउनलोड बाकी</item> + </plurals> + <string name="downloads_processing">डाउनलोड पà¥à¤°à¥‹à¤¸à¥‡à¤¸ किये जारहे</string> <string name="download_notification_title">पॉडकासà¥à¤Ÿ डेटा डाउनलोड करें</string> <string name="download_report_content">%1$d डाउनलोड सफल रहा, %2$d में विफल रहा है</string> <string name="download_log_title_unknown">अजà¥à¤žà¤¾à¤¤ शीरà¥à¤·à¤•</string> @@ -94,6 +204,11 @@ <string name="download_type_media">मीडिया फ़ाइल</string> <string name="download_type_image">छवि</string> <string name="download_request_error_dialog_message_prefix">फाइल डाउनलोड करने के लिठपà¥à¤°à¤¯à¤¾à¤¸ करते समय à¤à¤• तà¥à¤°à¥à¤Ÿà¤¿ हà¥à¤ˆ:\u0020</string> + <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> <string name="player_stopped_msg">मीडिया नहीं चल रहा</string> @@ -105,12 +220,22 @@ <string name="no_media_playing_label">मीडिया नहीं चल रहा</string> <string name="player_buffering_msg">बफरिंग</string> <string name="playbackservice_notification_title">पà¥à¤²à¥‡à¤ˆà¤‚ग पॉडकासà¥à¤Ÿ</string> + <string name="unknown_media_key">à¤à¤¨à¥à¤Ÿà¥‡à¤¨à¤¾à¤ªà¥‰à¤¡ - अनजान मीडिया की: %1$d</string> <!--Queue operations--> <string name="clear_queue_label">कतार साफ</string> <string name="undo">पूरà¥à¤µà¤µà¤¤à¥ करें</string> <string name="removed_from_queue">आइटम हटाया</string> <string name="move_to_top_label">शीरà¥à¤· पर ले जाà¤à¤‚</string> <string name="move_to_bottom_label">नीचे जाà¤à¤‚</string> + <string name="date">दिनांक</string> + <string name="duration">अवधि</string> + <string name="episode_title">à¤à¤ªà¤¿à¤¸à¥‹à¤¡ का शीरà¥à¤·à¤•</string> + <string name="feed_title">पॉडकासà¥à¤Ÿ का शीरà¥à¤·à¤•</string> + <string name="random">कà¥à¤°à¤®à¤°à¤¹à¤¿à¤¤</string> + <string name="smart_shuffle">चतà¥à¤° मिशà¥à¤°à¤£</string> + <string name="ascending">आरोही</string> + <string name="descending">अवरोही</string> + <string name="clear_queue_confirmation_msg">कृपया पà¥à¤·à¥à¤Ÿà¤¿ करें कि आप सारे à¤à¤ªà¤¿à¤¸à¥‹à¤¡ के इस कतार को हटाना चाहते हैं</string> <!--Flattr--> <string name="flattr_auth_label">Flattr पंजीकरण करें</string> <string name="flattr_auth_explanation">पà¥à¤°à¤®à¤¾à¤£à¥€à¤•à¤°à¤£ पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ शà¥à¤°à¥‚ करने के लिठनीचे दिठगठबटन को दबाà¤à¤‚. आपके बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤° में flattr लॉगिन सà¥à¤•à¥à¤°à¥€à¤¨ को à¤à¥‡à¤œà¤¾ जाà¤à¤—ा और flattr बातें करने के लिठअनà¥à¤®à¤¤à¤¿ AntennaPod को देने के लिठकहा जाà¤à¤—ा. आपकि अनà¥à¤®à¤¤à¤¿ देने के बाद, आप सà¥à¤µà¤¤à¤ƒ ही इस सà¥à¤•à¥à¤°à¥€à¤¨ में वापस आ जाà¤à¤—ें.</string> @@ -128,23 +253,39 @@ <string name="flattr_click_success">सफलतापूरà¥à¤µà¤• यह बात Flattr किया</string> <string name="flattr_click_success_count">सफलतापूरà¥à¤µà¤• %d बातोंको Flattr किया</string> <string name="flattr_click_success_queue">Flattr गिनती: %s</string> - <string name="flattring_label">à¤à¤¨à¥à¤Ÿà¥‡à¤¨à¤¾à¤ªà¥‰à¤¡ Flattr </string> + <string name="flattring_label">à¤à¤¨à¥à¤Ÿà¥‡à¤¨à¤¾à¤ªà¥‰à¤¡ Flattr कररहा है</string> <!--Variable Speed--> <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_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> - <string name="services_label">सेवाà¤à¤‚</string> <string name="flattr_label">Flattr</string> + <string name="automation">सà¥à¤µà¤šà¤¾à¤²à¤¨</string> + <string name="download_pref_details">विवरण</string> + <string name="import_export_pref">आयात/निरà¥à¤¯à¤¾à¤¤</string> + <string name="appearance">दिखावट</string> + <string name="external_elements">बाहरी ततà¥à¤µ</string> + <string name="interruptions">रà¥à¤•à¤¾à¤µà¤Ÿà¥‡</string> + <string name="pref_episode_cleanup_title">à¤à¤ªà¤¿à¤¸à¥‹à¤¡ की सफाई</string> <string name="pref_followQueue_sum">पà¥à¤²à¥‡à¤¬à¥ˆà¤• के पूरा होने पर अगली पंकà¥à¤¤à¤¿ आइटम के लिठजाà¤à¤</string> <string name="playback_pref">पà¥à¤²à¥‡à¤¬à¥ˆà¤•</string> <string name="network_pref">संजाल</string> + <string name="pref_autoUpdateIntervallOrTime_Disable">अकà¥à¤·à¤® करें</string> + <string name="pref_autoUpdateIntervallOrTime_Interval">अंतराल निरà¥à¤§à¤¾à¤°à¤¿à¤¤ करें</string> + <string name="pref_autoUpdateIntervallOrTime_TimeOfDay">दिन का समय निरà¥à¤§à¤¾à¤°à¤¿à¤¤ करें</string> + <string name="pref_autoUpdateIntervallOrTime_every">पà¥à¤°à¤¤à¤¿ %1$s</string> + <string name="pref_autoUpdateIntervallOrTime_at">%1$s बजे </string> <string name="pref_downloadMediaOnWifiOnly_sum">केवल वाईफ़ाई पर मीडिया फ़ाइलें डाउनलोड करें</string> <string name="pref_followQueue_title">सतत पà¥à¤²à¥‡à¤¬à¥ˆà¤•</string> <string name="pref_downloadMediaOnWifiOnly_title">वाईफाई मीडिया डाउनलोड करें</string> @@ -179,6 +320,7 @@ <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_login_status"><![CDATA[ <i>%1$s</i> के रूप में <i>%2$s</i> डिवाइस के साथ लॉगिन किया गया ]]></string> <string name="pref_playback_speed_title">पà¥à¤²à¥‡à¤¬à¥ˆà¤• गति</string> <string name="pref_playback_speed_sum">चर गति ऑडियो पà¥à¤²à¥‡à¤¬à¥ˆà¤• के लिठउपलबà¥à¤§ गति बनाइà¤</string> <string name="pref_gpodnet_sethostname_title">होसà¥à¤Ÿà¤¨à¤¾à¤® सेट</string> @@ -199,7 +341,6 @@ <string name="deselect_all_label">सà¤à¥€ का चयन रदà¥à¤¦ करें</string> <string name="opml_export_label">OPML निरà¥à¤¯à¤¾à¤¤</string> <string name="export_error_label">निरà¥à¤¯à¤¾à¤¤ तà¥à¤°à¥à¤Ÿà¤¿</string> - <string name="opml_export_success_sum">.ompl फ़ाइल लिखा गया था:\u0020</string> <!--Sleep timer--> <string name="set_sleeptimer_label">सà¥à¤²à¥€à¤ª टाइमर सेट</string> <string name="disable_sleeptimer_label">सà¥à¤²à¥€à¤ª टाइमर अकà¥à¤·à¤®</string> @@ -247,7 +388,7 @@ <string name="folder_not_empty_dialog_msg">आपके दà¥à¤µà¤¾à¤°à¤¾ चà¥à¤¨à¥‡ गठफ़ोलà¥à¤¡à¤° खाली नहीं है. मीडिया डाउनलोड और अनà¥à¤¯ फ़ाइलें इस फ़ोलà¥à¤¡à¤° में सीधे रखा जाà¤à¤—ा. फिर à¤à¥€ जारी रखें?</string> <string name="set_to_default_folder">डिफ़ॉलà¥à¤Ÿ फ़ोलà¥à¤¡à¤° चà¥à¤¨à¥‡à¤‚</string> <string name="pref_pausePlaybackForFocusLoss_sum">पà¥à¤²à¥‡à¤¬à¥ˆà¤• रोकें बजाय धà¥à¤µà¤¨à¤¿à¤¯à¥‹à¤‚ को कम करने के अगर कोई अनà¥à¤¯ अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— इसे बजाना चाहता है </string> - <string name="pref_pausePlaybackForFocusLoss_title">रà¥à¤•à¤¾à¤µà¤Ÿ के लिठरोकें</string> + <string name="pref_pausePlaybackForFocusLoss_title">रà¥à¤•à¤¾à¤µà¤Ÿà¥‹ के लिठरोकें</string> <!--Online feed view--> <string name="subscribe_label">सदसà¥à¤¯à¤¤à¤¾ लें</string> <string name="subscribed_label">सदसà¥à¤¯à¤¤à¤¾ ली गई</string> @@ -263,4 +404,5 @@ <!--Database import/export--> <!--Casting--> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-hu/strings.xml b/core/src/main/res/values-hu/strings.xml index 878925133..71e1283ce 100644 --- a/core/src/main/res/values-hu/strings.xml +++ b/core/src/main/res/values-hu/strings.xml @@ -32,6 +32,7 @@ <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_order_most_played">Rendezés játszott epizódok 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> @@ -51,7 +52,6 @@ <string name="yes">Igen</string> <string name="no">Nem</string> <string name="reset">VisszaállÃtás</string> - <string name="author_label">SzerzÅ‘</string> <string name="language_label">Nyelv</string> <string name="url_label">URL</string> <string name="podcast_settings_label">BeállÃtások</string> @@ -61,6 +61,7 @@ <string name="refresh_label">FrissÃtés</string> <string name="external_storage_error_msg">Nem található külsÅ‘ tárhely. BiztosÃts egy külsÅ‘ tárhelyet hogy az alkalmazás működni tudjon.</string> <string name="chapters_label">Fejezetek</string> + <string name="chapter_duration">Hossz: %1$s</string> <string name="shownotes_label">Jegyzetek</string> <string name="description_label">LeÃrás</string> <string name="most_recent_prefix">Legfrissebb epizód:\u0020</string> @@ -82,7 +83,7 @@ <string name="feed_auto_download_never">Soha</string> <string name="send_label">Küldés…</string> <string name="episode_cleanup_never">Soha</string> - <string name="episode_cleanup_queue_removal">Ha nem várakozik</string> + <string name="episode_cleanup_queue_removal">Ha nincs sorbaállÃtva</string> <string name="episode_cleanup_after_listening">Befejezés után</string> <plurals name="episode_cleanup_days_after_listening"> <item quantity="one">1 nappal a befejezés után</item> @@ -99,28 +100,18 @@ <string name="mark_all_read_label">Az összes megjelölése lejátszottként</string> <string name="mark_all_read_msg">Az összes epizód lejátszottként megjelölve</string> <string name="mark_all_read_confirmation_msg">Biztosan megjelölöd az összes epizódot lejátszottként?</string> - <string name="mark_all_read_feed_confirmation_msg">Biztosan megjelölöd az összes epizódot az idÅ‘vonalon lejátszottként?</string> <string name="mark_all_seen_label">Az összes megjelölése megnézettként</string> - <string name="mark_all_seen_msg">Az összes epizód megnézettként megjelölve</string> <string name="mark_all_seen_confirmation_msg">Biztosan megjelölöd az összes epizódott megnézettként?</string> <string name="show_info_label">Információ mutatása</string> - <string name="rename_feed_label">Podcast átnevezése</string> - <string name="remove_feed_label">Podcast eltávolÃtása</string> <string name="share_label">Megosztás…</string> - <string name="share_link_label">Link megosztása</string> - <string name="share_link_with_position_label">Link megosztása pozÃcióval</string> + <string name="share_file_label">Fájl megosztása</string> <string name="share_feed_url_label">IdÅ‘vonal URL megosztása</string> - <string name="share_item_url_label">Epizód fájl URL megosztása</string> - <string name="share_item_url_with_position_label">Epizód fájl URL megosztása pozÃcióval</string> - <string name="feed_remover_msg">IdÅ‘vonal eltávolÃtása</string> - <string name="load_complete_feed">Teljes idÅ‘vonal frissÃtése</string> <string name="hide_episodes_title">Epizódok elrejtése</string> - <string name="episode_actions">Műveletek alkalmazása</string> <string name="hide_unplayed_episodes_label">Nem lejátszott</string> <string name="hide_paused_episodes_label">Szüneteltetett</string> <string name="hide_played_episodes_label">Lejátszott</string> - <string name="hide_queued_episodes_label">Várakozó</string> - <string name="hide_not_queued_episodes_label">Nem várakozó</string> + <string name="hide_queued_episodes_label">SorbaállÃtva</string> + <string name="hide_not_queued_episodes_label">Nincs sorbaállÃtva</string> <string name="hide_downloaded_episodes_label">Letöltött</string> <string name="hide_not_downloaded_episodes_label">Nem letöltött</string> <string name="hide_has_media_label">További tartalma van</string> @@ -137,12 +128,12 @@ <string name="delete_label">Törlés</string> <string name="remove_episode_lable">Epizód eltávolÃtása</string> <string name="marked_as_seen_label">Megtekintettként megjelölve</string> - <string name="mark_read_label">Lejátszottként megjelölés</string> + <string name="mark_read_label">Jelölés játszottnak</string> <string name="marked_as_read_label">Lejátszottként megjelölve</string> - <string name="mark_unread_label">Nem lejátszottként megjelölés</string> - <string name="add_to_queue_label">Várakozási sorhoz adás</string> - <string name="added_to_queue_label">Várakozási sorhoz adva</string> - <string name="remove_from_queue_label">Várakozási sorból eltávolÃtás</string> + <string name="mark_unread_label">Jelölés nem játszottnak</string> + <string name="add_to_queue_label">SorbaállÃtás</string> + <string name="added_to_queue_label">Hozzáadva a lejátszási sorhoz</string> + <string name="remove_from_queue_label">EltávolÃtás lejátszási sorból</string> <string name="add_to_favorite_label">Kedvencekhez adás</string> <string name="added_to_favorites">Kedvencekhez adva</string> <string name="remove_from_favorite_label">KedvencekbÅ‘l eltávolÃtás</string> @@ -159,6 +150,8 @@ <string name="download_failed">sikertelen</string> <string name="download_pending">Letöltés várakozik</string> <string name="download_running">Letöltés fut</string> + <string name="download_error_details">Részletek</string> + <string name="download_error_details_message">%1$s \n\nFájl URL:\n%2$s</string> <string name="download_error_device_not_found">Táreszköz nem található</string> <string name="download_error_insufficient_space">Túl kevés tárhely</string> <string name="download_error_file_error">Fájl Hiba</string> @@ -173,30 +166,208 @@ <string name="download_error_forbidden">Tiltott</string> <string name="cancel_all_downloads_label">Az összes letöltés visszavonása</string> <string name="download_canceled_msg">Letöltés visszavonva</string> + <string name="download_report_title">Letöltés befejezÅ‘dött, hibák léptek fel</string> + <string name="download_report_content_title">Jelentés letöltése</string> + <string name="download_error_request_error">Lekérési hiba</string> + <string name="download_error_db_access">Adatbázis hozzáférési hiba</string> + <plurals name="downloads_left"> + <item quantity="one">%d letöltés van hátra</item> + <item quantity="other">%d letöltés van hátra</item> + </plurals> + <string name="downloads_processing">Letöltések feldolgozása</string> + <string name="download_notification_title">Podcast adatok letöltése</string> + <string name="download_report_content">%1$d letöltés sikeres, %2$d sikertelen</string> + <string name="download_log_title_unknown">Ismeretlen cÃm</string> + <string name="download_type_feed">Csatorna</string> + <string name="download_type_media">Média fájl</string> + <string name="download_type_image">Kép</string> + <string name="authentication_notification_title">Bejelentkezés szükséges</string> + <string name="authentication_notification_msg">A kért forrás felhasználónevet és jelszót kér</string> + <string name="confirm_mobile_download_dialog_enable_temporarily">Ãtmenetileg engedélyez</string> <!--Mediaplayer messages--> + <string name="player_error_msg">Hiba!</string> + <string name="player_preparing_msg">ElÅ‘készÃtés</string> + <string name="player_ready_msg">Kész</string> + <string name="player_seeking_msg">Tekerés</string> + <string name="playback_error_server_died">Szerver kapcsolat megszakadt</string> + <string name="playback_error_unknown">Ismeretlen hiba</string> + <string name="player_buffering_msg">Pufferelés</string> + <string name="playbackservice_notification_title">Podcast lejátszása</string> <!--Queue operations--> + <string name="lock_queue">Lejátszási sor lezárása</string> + <string name="unlock_queue">Lejátszási sor feloldása</string> + <string name="queue_locked">Lejátszási sor lezárva</string> + <string name="queue_unlocked">Lejátszási sor feloldva</string> + <string name="clear_queue_label">Lejátszási sor tisztÃtása</string> + <string name="undo">Visszavonás</string> + <string name="removed_from_queue">Elem eltávolÃtva</string> + <string name="move_to_top_label">Mozgatás az elejére</string> + <string name="move_to_bottom_label">Mozgatás a végére</string> + <string name="sort">Rendezés</string> + <string name="date">Dátum</string> + <string name="duration">Hossz</string> + <string name="episode_title">Epizód cÃm</string> + <string name="ascending">NövekvÅ‘</string> + <string name="descending">CsökkenÅ‘</string> <!--Flattr--> + <string name="flattr_auth_label">Flattr bejelentkezés</string> + <string name="access_revoked_title">Hozzáférés megtagadva</string> <!--Flattr--> <!--Variable Speed--> + <string name="download_plugin_label">KiegészÃtÅ‘ letöltése</string> + <string name="no_playback_plugin_title">KiegészÃtÅ‘ nincs telepÃtve</string> + <string name="set_playback_speed_label">Lejátszási sebesség</string> + <string name="enable_sonic">Sonic engedélyezése</string> <!--Empty list labels--> + <string name="no_items_label">Nincs elem a listában</string> <!--Preferences--> + <string name="storage_pref">Tároló</string> + <string name="project_pref">Projekt</string> + <string name="other_pref">Egyebek</string> + <string name="about_pref">Rólam</string> + <string name="queue_label">Lejátszási sor</string> + <string name="flattr_label">Flattr</string> + <string name="pref_pauseOnDisconnect_sum">Lejátszás szüneteltetése fejhallgató és bluetooth leválasztásakor</string> + <string name="pref_hardwareForwardButtonSkips_title">ElÅ‘re gomb átugor</string> + <string name="pref_hardwarePreviousButtonRestarts_title">ElÅ‘zÅ‘ gomb újraindÃt</string> + <string name="pref_auto_delete_title">Autómata törlés</string> + <string name="pref_smart_mark_as_played_title">Intelligens játszottnak jelölés</string> + <string name="playback_pref">Lejátszás</string> + <string name="network_pref">Hálózat</string> + <string name="pref_autoUpdateIntervallOrTime_Interval">Intervallum</string> + <string name="pref_autoUpdateIntervallOrTime_TimeOfDay">IdÅ‘pont</string> + <string name="pref_autoUpdateIntervallOrTime_every">minden %1$s</string> + <string name="pref_autoUpdateIntervallOrTime_at">%1$s-kor</string> + <string name="pref_downloadMediaOnWifiOnly_sum">Média fájlok letöltése csak WiFi-n</string> + <string name="pref_followQueue_title">Folyamatos lejátszás</string> + <string name="pref_downloadMediaOnWifiOnly_title">WiFi média lejátszás</string> + <string name="pref_pauseOnHeadsetDisconnect_title">Fejhallgató leválasztása</string> + <string name="pref_unpauseOnHeadsetReconnect_title">Fejhallgató újracsatlakoztatása</string> + <string name="pref_unpauseOnBluetoothReconnect_title">Bluetooth újracsatlakozás</string> + <string name="pref_mobileUpdate_title">FrissÃtések mobiladat-kapcsolaton</string> + <string name="pref_mobileUpdate_sum">FrissÃtések engedélyezése mobiladat-kapcsolaton keresztül</string> + <string name="flattr_settings_label">Flattr beállÃtások</string> + <string name="pref_flattr_auth_title">Flattr bejelentkezés</string> + <string name="pref_revokeAccess_title">Hozzáférés megvonása</string> + <string name="user_interface_label">Felhasználói felület</string> + <string name="pref_set_theme_title">Téma kiválasztása</string> + <string name="pref_nav_drawer_title">Navigációs fiók testreszabása</string> + <string name="pref_nav_drawer_sum">Navigációs fiók kinézetének testreszabás</string> + <string name="pref_nav_drawer_items_title">Navigációs fiók elemeinek kiválaasztása</string> + <string name="pref_set_theme_sum">AntennaPod kinézetének megváltoztatása</string> + <string name="pref_automatic_download_title">Autómatikus letöltés</string> + <string name="pref_automatic_download_sum">Epizódok autómatikus letöltésének beállÃtása</string> + <string name="pref_autodl_wifi_filter_title">Wi-Fi szűrÅ‘ beállÃtása</string> + <string name="pref_parallel_downloads_title">Párhuzamos letöltések</string> + <string name="pref_episode_cache_title">Epizód gyorsÃtótár</string> + <string name="pref_theme_title_light">Világos</string> + <string name="pref_theme_title_dark">Sötét</string> + <string name="pref_update_interval_hours_plural">óra</string> + <string name="pref_update_interval_hours_singular">óra</string> + <string name="pref_gpodnet_authenticate_title">Bejelentkezés</string> + <string name="pref_gpodnet_authenticate_sum">Jelentkezz be a gpodder.net fiókodba a feliratkozások szinkronizálásához.</string> + <string name="pref_gpodnet_logout_title">Kijelentkezés</string> + <string name="pref_gpodnet_logout_toast">Kijelentkezés sikeres</string> + <string name="pref_gpodnet_sync_changes_title">Változások szinkronizálása most</string> + <string name="pref_gpodnet_full_sync_title">Teljes szinkronizálás most</string> + <string name="pref_playback_speed_title">Lejátszási sebesség</string> + <string name="pref_compact_notification_buttons_title">ZárképernyÅ‘ gombok beállÃtása</string> + <string name="pref_lockscreen_background_title">ZárképernyÅ‘ háttérkép</string> + <string name="pref_lockscreen_background_sum">ZárképernyÅ‘ háttérkép átállÃtása az epizód képeként.</string> + <string name="pref_image_cache_size_title">Kép gyorsÃtótár mérete</string> + <string name="pref_image_cache_size_sum">Kép gyorsÃtótár méretének a lemezen</string> + <string name="crash_report_title">Hibajelentés</string> + <string name="experimental_pref">KÃsérleti</string> + <string name="pref_proxy_title">Proxy</string> + <string name="pref_proxy_sum">Hálózati proxy beállÃtása</string> + <string name="pref_faq">GYIK</string> + <string name="pref_known_issues">Ismert hibák</string> + <string name="pref_no_browser_found">Nem található webböngészÅ‘</string> + <string name="pref_cast_title">Chromecast támogatás</string> <!--Auto-Flattr dialog--> <!--Search--> + <string name="search_hint">Epizódok keresése</string> + <string name="search_label">Keresés</string> <!--OPML import and export--> + <string name="start_import_label">Importálás indÃtása</string> + <string name="opml_import_label">OPML importálása</string> + <string name="opml_directory_error">HIBA!</string> + <string name="reading_opml_label">OPML fájl olvasása</string> <!--Sleep timer--> + <string name="sleep_timer_enabled_label">Elalvás idÅ‘zÃtÅ‘ engedélyezése</string> + <string name="sleep_timer_disabled_label">Elalvás idÅ‘zÃtÅ‘ kikapcsolása</string> <!--gpodder.net--> + <string name="gpodnet_taglist_header">KATEGÓRIÃK</string> + <string name="gpodnet_suggestions_header">AJÃNLÃSOK</string> + <string name="gpodnetauth_login_title">Bejelentkezés</string> + <string name="gpodnetauth_login_butLabel">Bejelentkezés</string> + <string name="username_label">Felhasználónév</string> + <string name="password_label">Jelszó</string> + <string name="gpodnetauth_device_title">Eszköz kiválasztása</string> + <string name="gpodnetsync_pref_report_successful">Sikeres</string> + <string name="gpodnetsync_pref_report_failed">Sikertelen</string> <!--Directory chooser--> + <string name="selected_folder_label">Kiválasztott mappa:</string> + <string name="create_folder_label">Mappa létrehozása</string> + <string name="create_folder_error_already_exists">Mappa már létezik</string> + <string name="folder_not_empty_dialog_title">Mappa nem üres</string> + <string name="set_to_default_folder">Alapértelmezett mappa kiválasztása</string> <!--Online feed view--> + <string name="subscribe_label">Feliratkozás</string> + <string name="subscribed_label">Feliratkozva</string> + <string name="downloading_label">Letöltés...</string> <!--Content descriptions for image buttons--> + <string name="media_type_audio_label">Hang</string> + <string name="media_type_video_label">Video</string> + <string name="load_next_page_label">KövetkezÅ‘ oldal betöltése</string> <!--Feed information screen--> <!--Progress information--> <!--AntennaPodSP--> + <string name="search_itunes_label">iTunes keresés</string> + <string name="search_fyyd_label">fyyd keresés</string> <!--Episodes apply actions--> + <string name="all_label">Mind</string> + <string name="downloaded_label">Letöltve</string> + <string name="not_downloaded_label">Nincs letöltve</string> + <string name="queued_label">SorbaállÃtva</string> + <string name="not_queued_label">Nincs sorbaállÃtva</string> <!--Sort--> + <string name="sort_title_a_z">CÃm (A \u2192 Z)</string> + <string name="sort_title_z_a">CÃm (Z \u2192 A)</string> + <string name="sort_date_new_old">Dátum (Új \u2192 Régi)</string> + <string name="sort_date_old_new">Dátum (Régi \u2192 Új)</string> + <string name="sort_duration_short_long">Hossz (Rövid \u2192 Hosszú)</string> + <string name="sort_duration_long_short">Hossz (Hosszú \u2192 Rövid)</string> <!--Rating dialog--> + <string name="rating_later_label">Kérdezz rákésÅ‘bb</string> <!--Audio controls--> + <string name="audio_controls">Hang vezérlÅ‘k</string> + <string name="playback_speed">Lejátszási sebesség</string> + <string name="volume">HangerÅ‘</string> + <string name="left_short">B</string> + <string name="right_short">J</string> + <string name="audio_effects">Hangeffektek</string> + <string name="stereo_to_mono">Lekeverés: Sztereót Monora</string> + <string name="sonic_only">Csak Sonic</string> <!--proxy settings--> + <string name="proxy_type_label">TÃpus</string> + <string name="host_label">Kiszolgáló</string> + <string name="port_label">Port</string> + <string name="optional_hint">(Opcionális)</string> + <string name="proxy_test_label">Teszt</string> + <string name="proxy_test_successful">Teszt sikeres</string> + <string name="proxy_test_failed">Teszt sikertelen</string> + <string name="proxy_host_empty_error">Kiszolgáló nem lehet üres</string> + <string name="proxy_port_invalid_error">Port nem helyes</string> <!--Database import/export--> + <string name="import_export">Adatbázis importálása/exportálása</string> + <string name="label_import">Importálás</string> + <string name="label_export">Exportálás</string> + <string name="import_select_file">Fájl kiálasztás importáláshoz</string> + <string name="export_ok">Exportálás sikeres</string> <!--Casting--> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <string name="cast_failed_setting_volume">Hiba a hangerÅ‘ beállÃtása közben</string> + <string name="cast_failed_media_error_skipping">Hiba a lejátszás közben. Ãtugrás...</string> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-id/strings.xml b/core/src/main/res/values-id/strings.xml index e6ff6d1e7..62254518d 100644 --- a/core/src/main/res/values-id/strings.xml +++ b/core/src/main/res/values-id/strings.xml @@ -151,4 +151,5 @@ <!--Database import/export--> <!--Casting--> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-is-rIS/strings.xml b/core/src/main/res/values-is-rIS/strings.xml index acf3abe75..2d9481b84 100644 --- a/core/src/main/res/values-is-rIS/strings.xml +++ b/core/src/main/res/values-is-rIS/strings.xml @@ -36,4 +36,5 @@ <!--Database import/export--> <!--Casting--> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-it-rIT/strings.xml b/core/src/main/res/values-it-rIT/strings.xml deleted file mode 100644 index 23c8ec1c0..000000000 --- a/core/src/main/res/values-it-rIT/strings.xml +++ /dev/null @@ -1,526 +0,0 @@ -<?xml version='1.0' encoding='UTF-8'?> -<resources xmlns:tools="http://schemas.android.com/tools"> - <!--Activitiy and fragment titles--> - <string name="feeds_label">Feed</string> - <string name="statistics_label">Statistiche</string> - <string name="add_feed_label">Aggiungi un podcast</string> - <string name="episodes_label">Episodi</string> - <string name="all_episodes_short_label">Tutti</string> - <string name="favorite_episodes_label">Preferiti</string> - <string name="new_label">Nuovo</string> - <string name="settings_label">Impostazioni</string> - <string name="downloads_label">Download</string> - <string name="downloads_running_label">In esecuzione</string> - <string name="downloads_completed_label">Completati</string> - <string name="downloads_log_label">Registro</string> - <string name="subscriptions_label">Abbonamenti</string> - <string name="subscriptions_list_label">Elenco degli Abbonamenti</string> - <string name="cancel_download_label">Annulla\nil Download</string> - <string name="playback_history_label">Cronologia delle riproduzioni</string> - <string name="gpodnet_main_label">gpodder.net</string> - <string name="gpodnet_auth_label">Accesso a gpodder.net</string> - <string name="free_space_label">%1$s disponibili</string> - <string name="episode_cache_full_title">Cache degli episodi piena</string> - <string name="episode_cache_full_message">Lo spazio di memoria della cache degli episodi è esaurito. Puoi aumentarlo nelle Impostazioni</string> - <!--Statistics fragment--> - <string name="total_time_listened_to_podcasts">Tempo totale di riproduzione:</string> - <string name="statistics_details_dialog">%1$d di %2$d episodi iniziati.\n\nRiprodotti %3$s di %4$s.</string> - <string name="statistics_mode">Modalità di statistica</string> - <string name="statistics_mode_normal">Calcola l\'attuale tempo di riproduzione. Riprodurre un podcast due volte verrà contato due volte, mentre segnarlo come riprodotto no.</string> - <string name="statistics_mode_count_all">Somma tutti i podcast segnati come riprodotti</string> - <string name="statistics_speed_not_counted">Avviso: La velocità di riproduzione non viene considerata.</string> - <!--Main activity--> - <string name="drawer_open">Apri il menù</string> - <string name="drawer_close">Chiudi il menù</string> - <string name="drawer_preferences">Preferenze del Drawer</string> - <string name="drawer_feed_order_unplayed_episodes">Ordina per contatore</string> - <string name="drawer_feed_order_alphabetical">Ordina alfabeticamente</string> - <string name="drawer_feed_order_last_update">Ordina per data di pubblicazione</string> - <string name="drawer_feed_order_most_played">Ordina per numero di episodi riprodotti</string> - <string name="drawer_feed_counter_new_unplayed">Numero di episodi nuovi e non riprodotti</string> - <string name="drawer_feed_counter_new">Numero di episodi nuovi</string> - <string name="drawer_feed_counter_unplayed">Numero di episodi non riprodotti</string> - <string name="drawer_feed_counter_downloaded">Numero di episodi scaricati</string> - <string name="drawer_feed_counter_none">Nulla</string> - <!--Webview actions--> - <string name="open_in_browser_label">Apri nel Browser</string> - <string name="copy_url_label">Copia URL</string> - <string name="share_url_label">Condividi URL</string> - <string name="copied_url_msg">URL copiato negli appunti</string> - <string name="go_to_position_label">Vai a questa posizione</string> - <!--Playback history--> - <string name="clear_history_label">Pulisci la cronologia</string> - <!--Other--> - <string name="confirm_label">Conferma</string> - <string name="cancel_label">Annulla</string> - <string name="yes">Sì</string> - <string name="no">No</string> - <string name="reset">Reimposta</string> - <string name="author_label">Autore</string> - <string name="language_label">Lingua</string> - <string name="url_label">URL</string> - <string name="podcast_settings_label">Impostazioni</string> - <string name="cover_label">Immagine</string> - <string name="error_label">Errore</string> - <string name="error_msg_prefix">È stato rilevato un errore:</string> - <string name="refresh_label">Aggiorna</string> - <string name="external_storage_error_msg">Non risulta disponibile lo spazio di archiviazione esterno. Assicurati che lo spazio di archiviazione sia montato per permettere all\'applicazione di funzionare correttamente.</string> - <string name="chapters_label">Capitoli</string> - <string name="chapter_duration">Durata: %1$s</string> - <string name="shownotes_label">Note dell\'episodio</string> - <string name="description_label">Descrizione</string> - <string name="most_recent_prefix">Episodio più recente:\u0020</string> - <string name="episodes_suffix">\u0020episodi</string> - <string name="length_prefix">Durata:\u0020</string> - <string name="size_prefix">Dimensione:\u0020</string> - <string name="processing_label">Elaborazione in corso</string> - <string name="loading_label">Caricamento...</string> - <string name="save_username_password_label">Salva nome utente e password</string> - <string name="close_label">Chiudi</string> - <string name="retry_label">Riprova</string> - <string name="auto_download_label">Includi nei download automatici</string> - <string name="auto_download_apply_to_items_title">Applica ai Precedenti Episodi</string> - <string name="auto_download_apply_to_items_message">L\'opzione <i>Download Automatico</i> verrà applicata ai nuovi episodi.\nVuoi anche applicarla agli episodi precedenti?</string> - <string name="auto_delete_label">Elimina Episodi Automaticamente</string> - <string name="parallel_downloads_suffix">\u0020download paralleli</string> - <string name="feed_auto_download_global">Impostazione Globale</string> - <string name="feed_auto_download_always">Sempre</string> - <string name="feed_auto_download_never">Mai</string> - <string name="send_label">Invia...</string> - <string name="episode_cleanup_never">Mai</string> - <string name="episode_cleanup_queue_removal">Quando non è in coda</string> - <string name="episode_cleanup_after_listening">Dopo il completamento</string> - <plurals name="episode_cleanup_days_after_listening"> - <item quantity="one">1 giorno dopo il completamento</item> - <item quantity="other">%d giorni dopo il completamento</item> - </plurals> - <!--'Add Feed' Activity labels--> - <string name="feedurl_label">URL del feed</string> - <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">Per trovare podcasts puoi cercare su iTunes o fyyd, oppure puoi esplorare gpodder.net per nome, categoria oppure popolarità .</string> - <string name="browse_gpoddernet_label">Esplora gpodder.net</string> - <!--Actions on feeds--> - <string name="mark_all_read_label">Segna tutti come riprodotti</string> - <string name="mark_all_read_msg">Segnati tutti gli episodi come riprodotti</string> - <string name="mark_all_read_confirmation_msg">Conferma che desideri segnare tutti gli episodi come riprodotti.</string> - <string name="mark_all_read_feed_confirmation_msg">Conferma che desideri segnare tutti gli episodi in questo feed come riprodotti.</string> - <string name="mark_all_seen_label">Segna tutti come visti</string> - <string name="mark_all_seen_msg">Segnati tutti gli episodi come visti</string> - <string name="mark_all_seen_confirmation_msg">Conferma che desideri segnare tutti gli episodi come visti.</string> - <string name="show_info_label">Informazioni</string> - <string name="rename_feed_label">Rinomina Podcast</string> - <string name="remove_feed_label">Rimuovi podcast</string> - <string name="share_label">Condividi...</string> - <string name="share_link_label">Condividi il link</string> - <string name="share_file_label">Condividi il file</string> - <string name="share_link_with_position_label">Condividi il Link con la Posizione</string> - <string name="share_feed_url_label">Condividi URL del Feed</string> - <string name="share_item_url_label">Condividi l\'URL dell\'episodio</string> - <string name="share_item_url_with_position_label">Condividi l\'URL del File dell\'epsiodio con la Posizione</string> - <string name="feed_delete_confirmation_msg">Conferma che desideri cancellare il feed \"%1$s\" e TUTTI i suoi episodi scaricati.</string> - <string name="feed_remover_msg">Rimozione del Feed in corso</string> - <string name="load_complete_feed">Ricarica il feed completo</string> - <string name="hide_episodes_title">Nascondi gli episodi</string> - <string name="episode_actions">Applica le azioni</string> - <string name="hide_unplayed_episodes_label">Non riprodotti</string> - <string name="hide_paused_episodes_label">In pausa</string> - <string name="hide_played_episodes_label">Riprodotti</string> - <string name="hide_queued_episodes_label">In coda</string> - <string name="hide_not_queued_episodes_label">Non in coda</string> - <string name="hide_downloaded_episodes_label">Scaricati</string> - <string name="hide_not_downloaded_episodes_label">Non scaricati</string> - <string name="filtered_label">Filtrati</string> - <string name="refresh_failed_msg">{fa-exclamation-circle} Ultimo aggiornamento fallito</string> - <string name="open_podcast">Apri Podcast</string> - <!--actions on feeditems--> - <string name="download_label">Download</string> - <string name="play_label">Riproduci</string> - <string name="pause_label">Pausa</string> - <string name="stop_label">Ferma</string> - <string name="stream_label">Stream</string> - <string name="remove_label">Rimuovi</string> - <string name="delete_label">Elimina</string> - <string name="remove_episode_lable">Rimuovi l\'episodio</string> - <string name="marked_as_seen_label">Segna come visto</string> - <string name="mark_read_label">Segna come riprodotto</string> - <string name="marked_as_read_label">Segnato come riprodotto</string> - <string name="mark_unread_label">Segna come non riprodotto</string> - <string name="add_to_queue_label">Aggiungi alla coda</string> - <string name="added_to_queue_label">Aggiunto alla coda</string> - <string name="remove_from_queue_label">Rimuovi dalla coda</string> - <string name="add_to_favorite_label">Aggiungi ai preferiti</string> - <string name="added_to_favorites">Aggiunto ai Preferiti</string> - <string name="remove_from_favorite_label">Rimuovi dai preferiti</string> - <string name="removed_from_favorites">Rimosso dai Preferiti</string> - <string name="visit_website_label">Visita il sito</string> - <string name="support_label">Carica questo su Flattr</string> - <string name="skip_episode_label">Salta l\'episodio</string> - <string name="activate_auto_download">Attiva il Download Automatico</string> - <string name="deactivate_auto_download">Disattiva il Download Automatico</string> - <string name="reset_position">Azzera la Posizione di Riproduzione</string> - <string name="removed_item">Elemento rimosso</string> - <!--Download messages and labels--> - <string name="download_successful">successo</string> - <string name="download_failed">fallito</string> - <string name="download_pending">Download in attesa</string> - <string name="download_running">Download in corso</string> - <string name="download_error_device_not_found">Spazio di archiviazione non trovato</string> - <string name="download_error_insufficient_space">Spazio insufficiente</string> - <string name="download_error_file_error">Errore del file</string> - <string name="download_error_http_data_error">Errore dei dati HTTP</string> - <string name="download_error_error_unknown">Errore sconosciuto</string> - <string name="download_error_parser_exception">Eccezione del decodificatore</string> - <string name="download_error_unsupported_type">Tipo di feed non supportato</string> - <string name="download_error_connection_error">Errore di connessione</string> - <string name="download_error_unknown_host">Host sconosciuto</string> - <string name="download_error_unauthorized">Errore di autenticazione</string> - <string name="download_error_file_type_type">Errore Formato FIle</string> - <string name="download_error_forbidden">Proibito</string> - <string name="cancel_all_downloads_label">Annulla tutti i download</string> - <string name="download_canceled_msg">Download annullato</string> - <string name="download_canceled_autodownload_enabled_msg">Download annullato\n<i>Download Automatico</i> disabilitato per questo elemento</string> - <string name="download_report_title">Download completato con un errore (o errori)</string> - <string name="download_report_content_title">Rapporto del Downoad</string> - <string name="download_error_malformed_url">URL malformato</string> - <string name="download_error_io_error">Errore IO</string> - <string name="download_error_request_error">Errore della richiesta</string> - <string name="download_error_db_access">Errore di accesso al database</string> - <plurals name="downloads_left"> - <item quantity="one">%d download rimanente</item> - <item quantity="other">%d download rimanenti</item> - </plurals> - <string name="downloads_processing">Elaborazione dei download in corso</string> - <string name="download_notification_title">Download podcast in corso</string> - <string name="download_report_content">%1$d download con successo, %2$d falliti</string> - <string name="download_log_title_unknown">Titolo Sconosciuto</string> - <string name="download_type_feed">Feed</string> - <string name="download_type_media">File multimediali</string> - <string name="download_type_image">Immagine</string> - <string name="download_request_error_dialog_message_prefix">Rilevato errore durante il download del file:\u0020</string> - <string name="authentication_notification_title">Autenticazione richiesta</string> - <string name="authentication_notification_msg">La risorsa che hai richiesto richiede un nome utente e una password</string> - <string name="confirm_mobile_download_dialog_title">Conferma il download su cellulare</string> - <string name="confirm_mobile_download_dialog_only_add_to_queue">Metti in Coda</string> - <string name="confirm_mobile_download_dialog_enable_temporarily">Consenti temporaneamente</string> - <!--Mediaplayer messages--> - <string name="player_error_msg">Errore!</string> - <string name="player_stopped_msg">Nessun media in riproduzione</string> - <string name="player_preparing_msg">Preparazione</string> - <string name="player_ready_msg">Pronto</string> - <string name="player_seeking_msg">Ricerca posizione</string> - <string name="playback_error_server_died">Server morto</string> - <string name="playback_error_unknown">Errore sconosciuto</string> - <string name="no_media_playing_label">Nessun elemento multimediale in riproduzione</string> - <string name="player_buffering_msg">Buffer in corso</string> - <string name="playbackservice_notification_title">Riproduzione del podcast in corso</string> - <string name="unknown_media_key">AntennaPod - Chiave dell\'elemento multimediale sconosciuta: %1$d</string> - <!--Queue operations--> - <string name="lock_queue">Blocca la coda</string> - <string name="unlock_queue">Sblocca la coda</string> - <string name="queue_locked">Coda bloccata</string> - <string name="queue_unlocked">Coda sbloccata</string> - <string name="clear_queue_label">Svuota la Coda</string> - <string name="undo">Undo</string> - <string name="removed_from_queue">Oggetto rimosso</string> - <string name="move_to_top_label">Sposta all\'inizio</string> - <string name="move_to_bottom_label">Sposta in fondo</string> - <string name="sort">Ordina</string> - <string name="date">Per data</string> - <string name="duration">Per durata</string> - <string name="episode_title">Titolo dell\'episodio</string> - <string name="feed_title">Titolo del 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> - <string name="authenticate_label">Autenticazione</string> - <string name="return_home_label">Ritorna alla pagina iniziale</string> - <string name="flattr_auth_success">Autenticazione avvenuta con successo! Adesso puoi microdonare con flattr dall\'interno dell\'app.</string> - <string name="no_flattr_token_title">Nessun token flattr trovato</string> - <string name="no_flattr_token_notification_msg">Il tuo account di Flattr non sembra essere collegato ad AntennaPod. Premi qui per autenticarti.</string> - <string name="no_flattr_token_msg">Il tuo account flattr non sembra essere collegato ad AntennaPod. Potresti collegare il tuo account ad AntennaPod per utilizzare flattr dall\'app oppure puoi visitare il sito per utilizzare flattr direttamente da lì.</string> - <string name="authenticate_now_label">Autenticati</string> - <string name="action_forbidden_title">Azione proibita</string> - <string name="action_forbidden_msg">AntennaPod non ha il permesso di effettuare questa azione. La ragione potrebbe essere che il token di accesso di AntennaPod al tuo account è stato revocato. Puoi eseguire la re-autenticazione o altrimenti visitare il sito web.</string> - <string name="access_revoked_title">Accesso revocato</string> - <string name="access_revoked_info">Hai revocato l\'accesso di AntennaPod al tuo account. Al fine di completare il processo devi rimuovere l\'app dalla lista delle applicazioni autorizzare nelle impostazioni del tuo account sul sito di flattr.</string> - <!--Flattr--> - <string name="flattr_click_success">Caricata una cosa su Flattr!</string> - <string name="flattr_click_success_count">Caricate %d cose su Flattr!</string> - <string name="flattr_click_success_queue">Caricato su Flattr: %s.</string> - <string name="flattr_click_failure_count">È stato fallito il caricamento su Flattr di %d cose!</string> - <string name="flattr_click_failure">Non caricato su Flattr: %s.</string> - <string name="flattr_click_enqueued">La cosa verrà caricata su Flattr più tardi</string> - <string name="flattring_thing">Caricamento su Flattr di %s in corso</string> - <string name="flattring_label">AntennaPod sta eseguendo Flattr</string> - <string name="flattrd_label">AntennaPod ha caricato su Flattr</string> - <string name="flattrd_failed_label">Caricamento su Flattr di AntennaPod fallito</string> - <string name="flattr_retrieving_status">Ricezione di cose caricate su Flattr in corso</string> - <!--Variable Speed--> - <string name="download_plugin_label">Scarica plugin</string> - <string name="no_playback_plugin_title">Plugin non installato</string> - <string name="set_playback_speed_label">Velocità di riproduzione</string> - <string name="enable_sonic">Abilita Sonic</string> - <!--Empty list labels--> - <string name="no_items_label">Non ci sono oggetti in questo elenco.</string> - <string name="no_feeds_label">Non sei ancora abbonato a nessun feed.</string> - <string name="no_chapters_label">Questo episodio non ha capitoli.</string> - <string name="no_shownotes_label">Questo episodio non ha note.</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> - <string name="queue_label">Coda</string> - <string name="services_label">Servizi</string> - <string name="flattr_label">Flattr</string> - <string name="pref_unpauseOnHeadsetReconnect_sum">Riprendi la riproduzione quando vengono riconnesse le cuffie</string> - <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_message">Puoi impostare un <i>intervallo</i> come \"ogni 2 ore\", impostare <i>un\'ora del giorno</i> specifica, come \"7:00\" oppure <i>disabilitare</i> gli aggiornamenti automatici del tutto.\n\n<small>Nota: I tempi di aggiornamento non sono perfetti. Potrai riscontrare dei brevi ritardi.</small></string> - <string name="pref_autoUpdateIntervallOrTime_Disable">Disabilita</string> - <string name="pref_autoUpdateIntervallOrTime_Interval">Imposta Intervallo</string> - <string name="pref_autoUpdateIntervallOrTime_every">ogni %1$s</string> - <string name="pref_autoUpdateIntervallOrTime_at">alle %1$s</string> - <string name="pref_downloadMediaOnWifiOnly_sum">Abilita il download dei media solo tramite WiFi</string> - <string name="pref_followQueue_title">Riproduzione Continua</string> - <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">Aggiornamenti su Reti a Consumo</string> - <string name="pref_mobileUpdate_sum">Permetti gli aggiornamenti tramite connessione dati mobile</string> - <string name="refreshing_label">Aggiornamento</string> - <string name="flattr_settings_label">Impostazioni Flattr</string> - <string name="pref_flattr_auth_title">Flattr sign-in</string> - <string name="pref_flattr_auth_sum">Collega il tuo account flattr per utilizzare flattr direttamente dall\'app</string> - <string name="pref_flattr_this_app_title">Supporta con flattr questa app</string> - <string name="pref_flattr_this_app_sum">Supporta lo sviluppo di AntennaPod tramite flattr. Grazie!</string> - <string name="pref_revokeAccess_title">Revoca l\'accesso</string> - <string name="pref_revokeAccess_sum">Revoca il permesso, a questa applicazione, di accedere al tuo account flattr.</string> - <string name="pref_auto_flattr_title">Flattr automatico</string> - <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 un 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> - <string name="pref_autodl_wifi_filter_title">Abilita il filtro Wi-Fi</string> - <string name="pref_autodl_wifi_filter_sum">Abilita il download automatico solo per alcune reti Wi-Fi selezionate.</string> - <string name="pref_automatic_download_on_battery_title">Scarica quando la batteria non è in carica</string> - <string name="pref_automatic_download_on_battery_sum">Permetti il download automatico quando la batteria non è in carica</string> - <string name="pref_parallel_downloads_title">Download Contemporanei</string> - <string name="pref_episode_cache_title">Cache degli Episodi</string> - <string name="pref_theme_title_light">Light</string> - <string name="pref_theme_title_dark">Dark</string> - <string name="pref_episode_cache_unlimited">Illimitato</string> - <string name="pref_update_interval_hours_plural">ore</string> - <string name="pref_update_interval_hours_singular">ora</string> - <string name="pref_update_interval_hours_manual">Manuale</string> - <string name="pref_gpodnet_authenticate_title">Login</string> - <string name="pref_gpodnet_authenticate_sum">Effettua il login con il tuo account gpodder.net per sincronizzare le tue sottoscrizioni.</string> - <string name="pref_gpodnet_logout_title">Logout</string> - <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_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> - <string name="pref_gpodnet_sethostname_title">Imposta l\'hostname</string> - <string name="pref_gpodnet_sethostname_use_default_host">Usa l\'host di default</string> - <string name="pref_expandNotify_title">Espandi le notifiche</string> - <string name="pref_expandNotify_sum">Espandi sempre le notifiche per mostrare i pulsanti di riproduzione.</string> - <string name="pref_persistNotify_title">Controlli di riproduzione persistenti</string> - <string name="pref_persistNotify_sum">Mantieni le notifiche e i controlli del blocco dello schermo quando la riproduzione è in pausa.</string> - <string name="pref_showDownloadReport_title">Mostra il Rapporto del Download</string> - <string name="pref_expand_notify_unsupport_toast">Le versioni di Android prima della 4.1 non supportano le notifiche estese.</string> - <string name="pref_queueAddToFront_sum">Aggiungi un nuovo episodio in testa alla coda.</string> - <string name="pref_queueAddToFront_title">Aggiungi in cima alla coda</string> - <string name="pref_smart_mark_as_played_disabled">Disabilitato</string> - <string name="pref_image_cache_size_title">Dimensione Cache delle Immagini</string> - <string name="send_email">Invia e-mail</string> - <string name="experimental_pref">Sperimentale</string> - <string name="pref_current_value">Valore corrente: %1$s</string> - <string name="pref_proxy_title">Proxy</string> - <string name="pref_faq">FAQ</string> - <string name="pref_known_issues">Problemi noti</string> - <string name="pref_cast_title">Supporto a Chromecast</string> - <!--Auto-Flattr dialog--> - <string name="auto_flattr_enable">Abilita l\'esecuzione automatica di Flattr</string> - <string name="auto_flattr_after_percent">Carica l\'episodio su Flattr appena è stato riprodotto al %d percento</string> - <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="found_in_chapters_label">Trovato nei capitoli</string> - <string name="search_status_no_results">Nessun risultato trovato</string> - <string name="search_label">Ricerca</string> - <string name="found_in_title_label">Trovato nel titolo</string> - <!--OPML import and export--> - <string name="opml_import_txtv_button_lable">I file OPML ti permettono di spostare i tuoi podcast da un programma ad un altro.</string> - <string name="start_import_label">Avvio importazione</string> - <string name="opml_import_label">Importazione OPML</string> - <string name="opml_directory_error">ERRORE!</string> - <string name="reading_opml_label">Lettura OPML file in corso</string> - <string name="opml_import_error_no_file">Nessun file selezionato!</string> - <string name="select_all_label">Seleziona tutti</string> - <string name="deselect_all_label">Deseleziona tutti</string> - <string name="choose_file_from_filesystem">Dal filesystem locale</string> - <string name="choose_file_from_external_application">Utilizza un\'applicazione esterna</string> - <string name="opml_export_label">Esportazione su OPML</string> - <string name="export_error_label">Errore di esportazione</string> - <string name="opml_export_success_title">Esportazione OPML avvenuta con successo.</string> - <string name="opml_export_success_sum">Il file .opml è stato scritto su:\u0020</string> - <!--Sleep timer--> - <string name="set_sleeptimer_label">Imposta timer</string> - <string name="disable_sleeptimer_label">Disabilita il timer di spegnimento</string> - <string name="enter_time_here_label">Tempo di spegnimento</string> - <string name="sleep_timer_label">Timer di spegnimento</string> - <string name="time_left_label">Tempo residuo:\u0020</string> - <string name="time_dialog_invalid_input">Input non valido, il campo deve essere un numero intero.</string> - <string name="timer_vibration_label">Vibra</string> - <string name="time_seconds">secondi</string> - <string name="time_minutes">minuti</string> - <string name="time_hours">ore</string> - <plurals name="time_seconds_quantified"> - <item quantity="one">1 secondo</item> - <item quantity="other">%d secondi</item> - </plurals> - <plurals name="time_minutes_quantified"> - <item quantity="one">1 minuto</item> - <item quantity="other">%d minuti</item> - </plurals> - <plurals name="time_hours_quantified"> - <item quantity="one">1 ora</item> - <item quantity="other">%d ore</item> - </plurals> - <string name="auto_enable_label">Abilita automaticamente</string> - <!--gpodder.net--> - <string name="gpodnet_taglist_header">CATEGORIE</string> - <string name="gpodnet_toplist_header">TOP PODCAST</string> - <string name="gpodnet_suggestions_header">SUGGERIMENTI</string> - <string name="gpodnet_search_hint">Cerca su gpodder.net</string> - <string name="gpodnetauth_login_title">Login</string> - <string name="gpodnetauth_login_descr">Benvenuto sul processo di login di gpodder.net. Per prima cosa, inserisci le tue informazioni di login:</string> - <string name="gpodnetauth_login_butLabel">Login</string> - <string name="gpodnetauth_login_register">Se non hai ancora un account, puoi crearne uno qui:\nhttps://gpodder.net/register/</string> - <string name="username_label">Username</string> - <string name="password_label">Password</string> - <string name="gpodnetauth_device_title">Scelta del dispositivo</string> - <string name="gpodnetauth_device_descr">Crea un nuovo dispositivo per utilizzare il tuo account gpodder.net o scegline uno esistente:</string> - <string name="gpodnetauth_device_deviceID">ID del dispositivo:\u0020</string> - <string name="gpodnetauth_device_caption">Caption</string> - <string name="gpodnetauth_device_butCreateNewDevice">Crea un nuovo dispositivo</string> - <string name="gpodnetauth_device_chooseExistingDevice">Scegli un dispositivo esistente:</string> - <string name="gpodnetauth_device_errorEmpty">L\'ID del dispositivo non può essere vuoto</string> - <string name="gpodnetauth_device_errorAlreadyUsed">ID di dispositivo già in uso</string> - <string name="gpodnetauth_device_butChoose">Scegli</string> - <string name="gpodnetauth_finish_title">Login effettuato!</string> - <string name="gpodnetauth_finish_descr">Congraturazioni! Il tuo account gpodder.net è stato collegato con il tuo dispositivo. Da ora AntennaPod sincronizzerà automaticamente le sottoscrizioni sul tuo dispositivo con il tuo account gpodder.net.</string> - <string name="gpodnetauth_finish_butsyncnow">Avvia la sincronizzazione</string> - <string name="gpodnetauth_finish_butgomainscreen">Vai alla schermata principale</string> - <string name="gpodnetsync_auth_error_title">errore di autenticazione su gpodder.net</string> - <string name="gpodnetsync_auth_error_descr">Nome utente o password errati</string> - <string name="gpodnetsync_error_title">gpodder.net errore di sincronizzazione</string> - <string name="gpodnetsync_error_descr">Rilevato un errore in fase di sincronizzazione:\u0020</string> - <!--Directory chooser--> - <string name="selected_folder_label">Seleziona la cartella:</string> - <string name="create_folder_label">Crea una cartella</string> - <string name="choose_data_directory">Scegli la directory per i dati</string> - <string name="create_folder_msg">Crea una nuova directory con nome \"%1$s\"?</string> - <string name="create_folder_success">Crea una nuova directory</string> - <string name="create_folder_error_no_write_access">Impossibile scrivere in questa directory</string> - <string name="create_folder_error_already_exists">La cartella esiste già </string> - <string name="create_folder_error">Non è stato possibile creare la cartella</string> - <string name="folder_does_not_exist_error">\"%1$s\" non esiste</string> - <string name="folder_not_readable_error">\"%1$s\" non è leggibile</string> - <string name="folder_not_writable_error">\"%1$s\" non è scrivibile</string> - <string name="folder_not_empty_dialog_title">La cartella non è vuota</string> - <string name="folder_not_empty_dialog_msg">La cartella che hai selezionato non è vuota. I download dei media e altri file saranno creati in questa cartella. Continuare?</string> - <string name="set_to_default_folder">Scegli la cartella predefinita</string> - <string name="pref_pausePlaybackForFocusLoss_sum">Sospendi la riproduzione invece di abbassare il volume quando un\'altra app emette un suono</string> - <string name="pref_pausePlaybackForFocusLoss_title">Pausa su interruzione</string> - <string name="pref_resumeAfterCall_title">Riprendi dopo la chiamata</string> - <!--Online feed view--> - <string name="subscribe_label">Abbonati</string> - <string name="subscribed_label">Abbonato</string> - <string name="downloading_label">Download in corso...</string> - <!--Content descriptions for image buttons--> - <string name="rewind_label">Riavvolgi</string> - <string name="fast_forward_label">Avanti veloce</string> - <string name="media_type_audio_label">Audio</string> - <string name="media_type_video_label">Video</string> - <string name="navigate_upwards_label">Naviga verso l\'alto</string> - <string name="status_downloading_label">L\'episodio sta venendo scaricato</string> - <string name="in_queue_label">L\'episodio è in coda</string> - <string name="drag_handle_content_description">Trascina per cambiare la posizione di questo oggetto</string> - <string name="load_next_page_label">Carica la pagina successiva</string> - <!--Feed information screen--> - <string name="authentication_label">Autenticazione</string> - <string name="authentication_descr">Cambia il tuo nome utente e la tua password per questo podcast e i suoi episodi.</string> - <string name="episode_filters_include">Includi</string> - <string name="episode_filters_exclude">Escludi</string> - <string name="keep_updated">Mantieni Aggiornato</string> - <!--Progress information--> - <!--AntennaPodSP--> - <string name="sp_apps_importing_feeds_msg">Importazione di sottoscrizioni da applicazioni monouso in corso...</string> - <string name="search_itunes_label">Cerca su iTunes</string> - <string name="filter">Filtro</string> - <!--Episodes apply actions--> - <string name="all_label">Tutto</string> - <string name="selected_all_label">Seleziona tutti gli Episodi</string> - <string name="none_label">Nulla</string> - <string name="deselected_all_label">De-seleziona tutti gli episodi</string> - <string name="played_label">Riprodotti</string> - <string name="selected_played_label">Selezionati gli episodi riprodotti</string> - <string name="unplayed_label">Non riprodotti</string> - <string name="selected_unplayed_label">Selezionati gli episodi non riprodotti</string> - <string name="downloaded_label">Scaricati</string> - <string name="selected_downloaded_label">Seleziona gli episodi scaricati</string> - <string name="not_downloaded_label">Non scaricati</string> - <string name="selected_not_downloaded_label">Seleziona gli episodi non scaricati</string> - <string name="queued_label">In coda</string> - <string name="selected_queued_label">Seleziona gli episodi in coda</string> - <string name="not_queued_label">Non in coda</string> - <string name="selected_not_queued_label">Seleziona gli episodi non in coda</string> - <string name="selected_has_media_label">Seleziona gli episodi con elementi multimediali</string> - <!--Sort--> - <string name="sort_title_a_z">Titolo (A \u2192 Z)</string> - <string name="sort_title_z_a">Titolo (Z \u2192 A)</string> - <string name="sort_date_new_old">Data (Nuovi \u2192 Vecchi)</string> - <string name="sort_date_old_new">Data (Vecchi \u2192 Nuovi)</string> - <string name="sort_duration_short_long">Durata (Corti \u2192 Lunghi)</string> - <string name="sort_duration_long_short">Durata (Lunghi \u2192 Corti)</string> - <!--Rating dialog--> - <string name="rating_title">Ti piace AntennaPod?</string> - <string name="rating_later_label">Ricordamelo più tardi</string> - <!--Audio controls--> - <string name="audio_controls">Controlli audio</string> - <string name="playback_speed">Velocità di riproduzione</string> - <string name="volume">Volume</string> - <string name="left_short">Sx</string> - <string name="right_short">Dx</string> - <string name="audio_effects">Effetti Audio</string> - <!--proxy settings--> - <string name="proxy_type_label">Tipo</string> - <string name="host_label">Host</string> - <string name="port_label">Porta</string> - <string name="optional_hint">(Opzionale)</string> - <string name="proxy_test_label">Test</string> - <string name="proxy_checking">Controllo in corso...</string> - <string name="proxy_test_successful">Test avvenuto con successo</string> - <string name="proxy_test_failed">Test fallito</string> - <string name="proxy_port_invalid_error">Porta non valida</string> - <!--Database import/export--> - <!--Casting--> - <string name="cast_media_route_menu_title">Riproduci su...</string> - <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> -</resources> diff --git a/core/src/main/res/values-it/strings.xml b/core/src/main/res/values-it/strings.xml index 45cd8d334..6084c3020 100644 --- a/core/src/main/res/values-it/strings.xml +++ b/core/src/main/res/values-it/strings.xml @@ -1,11 +1,13 @@ <?xml version='1.0' encoding='UTF-8'?> <resources xmlns:tools="http://schemas.android.com/tools"> <!--Activitiy and fragment titles--> + <string name="feed_update_receiver_name">Aggiorna sottoscrizioni</string> <string name="feeds_label">Feed</string> <string name="statistics_label">Statistiche</string> <string name="add_feed_label">Aggiungi un podcast</string> <string name="episodes_label">Episodi</string> <string name="all_episodes_short_label">Tutti</string> + <string name="new_episodes_label">Nuovo</string> <string name="favorite_episodes_label">Preferiti</string> <string name="new_label">Nuovo</string> <string name="settings_label">Impostazioni</string> @@ -18,10 +20,12 @@ <string name="cancel_download_label">Annulla\nil download</string> <string name="playback_history_label">Cronologia delle riproduzioni</string> <string name="gpodnet_main_label">gpodder.net</string> + <string name="gpodnet_summary">Sincronizza con altri dispositivi</string> <string name="gpodnet_auth_label">Accesso a gpodder.net</string> <string name="free_space_label">%1$s liberi</string> <string name="episode_cache_full_title">Cache degli episodi piena</string> <string name="episode_cache_full_message">Lo spazio di memoria della cache dell\'episodio è esaurito. Puoi aumentarlo nelle Impostazioni</string> + <string name="synchronizing">Sincronizzazione...</string> <!--Statistics fragment--> <string name="total_time_listened_to_podcasts">Tempo totale di riproduzione:</string> <string name="statistics_details_dialog">%1$d di %2$d episodi iniziati.\n\nRiprodotti %3$s di %4$s.</string> @@ -56,13 +60,14 @@ <string name="yes">Sì</string> <string name="no">No</string> <string name="reset">Reimposta</string> - <string name="author_label">Autore</string> + <string name="author_label">Autore(i)</string> <string name="language_label">Lingua</string> <string name="url_label">URL</string> <string name="podcast_settings_label">Impostazioni</string> <string name="cover_label">Immagine</string> <string name="error_label">Errore</string> <string name="error_msg_prefix">È avvenuto un errore:</string> + <string name="needs_storage_permission">Permessi di archiviazione obbligatori per questa azione</string> <string name="refresh_label">Ricarica</string> <string name="external_storage_error_msg">Non è stata trovata nessuna memoria esterna. Controlla che la memoria esterna sia montata in modo che l\'app possa rilevarla</string> <string name="chapters_label">Capitoli</string> @@ -105,24 +110,27 @@ <string name="mark_all_read_label">Segna tutti come riprodotti</string> <string name="mark_all_read_msg">Segnati tutti gli episodi come riprodotti</string> <string name="mark_all_read_confirmation_msg">Conferma che desideri segnare tutti gli episodi come riprodotti.</string> - <string name="mark_all_read_feed_confirmation_msg">Conferma che desideri segnare tutti gli episodi in questo feed come riprodotti.</string> + <string name="mark_all_read_feed_confirmation_msg">Per favore conferma che vuoi segnare tutti gli episodi di questo podcast come riprodotti.</string> <string name="mark_all_seen_label">Segna tutti come visti</string> - <string name="mark_all_seen_msg">Segnati tutti gli episodi come visti</string> + <string name="mark_all_seen_msg">Segna tutti gli episodi come visti</string> <string name="mark_all_seen_confirmation_msg">Conferma che desideri segnare tutti gli episodi come visti.</string> <string name="show_info_label">Mostra delle informazioni</string> - <string name="rename_feed_label">Rinomina Podcast</string> - <string name="remove_feed_label">Rimuovi Podcast</string> + <string name="show_feed_settings_label">Mostra impostazioni podcast</string> + <string name="feed_info_label">Info podcast</string> + <string name="feed_settings_label">Impostazioni podcast</string> + <string name="rename_feed_label">Rinomina podcast</string> + <string name="remove_feed_label">Rimuovi podcast</string> <string name="share_label">Condividi...</string> - <string name="share_link_label">Condividi il link</string> + <string name="share_link_label">Condividi URL episodio</string> + <string name="share_link_with_position_label">Condividi URL episodio con posizione</string> <string name="share_file_label">Condividi il file</string> - <string name="share_link_with_position_label">Condividi il Link con la Posizione</string> <string name="share_feed_url_label">Condividi URL del Feed</string> - <string name="share_item_url_label">Condividi l\'URL dell\'episodio</string> - <string name="share_item_url_with_position_label">Condividi l\'URL del File dell\'epsiodio con la Posizione</string> - <string name="feed_delete_confirmation_msg">Conferma che desideri cancellare il feed \"%1$s\" e TUTTI i suoi episodi scaricati.</string> - <string name="feed_remover_msg">Rimozione del Feed in corso</string> + <string name="share_item_url_label">Condividi URL Media File</string> + <string name="share_item_url_with_position_label">Condividi URL Media File con posizione</string> + <string name="feed_delete_confirmation_msg">Conferma che vuoi eliminare il podcast \"%1$s\" e TUTTI i suoi episodi (compresi quelli scaricati).</string> + <string name="feed_remover_msg">Rimozione podcast</string> + <string name="load_complete_feed">Aggiorna l\'intero podcast</string> <string name="hide_episodes_title">Nascondi gli episodi</string> - <string name="episode_actions">Applica le azioni</string> <string name="hide_unplayed_episodes_label">Non riprodotti</string> <string name="hide_paused_episodes_label">In pausa</string> <string name="hide_played_episodes_label">Riprodotti</string> @@ -130,6 +138,7 @@ <string name="hide_not_queued_episodes_label">Non in coda</string> <string name="hide_downloaded_episodes_label">Scaricati</string> <string name="hide_not_downloaded_episodes_label">Non scaricati</string> + <string name="hide_is_favorite_label">Preferito</string> <string name="filtered_label">Filtrati</string> <string name="refresh_failed_msg">{fa-exclamation-circle} Ultimo aggiornamento fallito</string> <string name="open_podcast">Apri il Podcast</string> @@ -141,7 +150,9 @@ <string name="stream_label">Stream</string> <string name="remove_label">Rimuovi</string> <string name="delete_label">Elimina</string> + <string name="delete_failed">Impossibile eliminare il file. Il riavvio del dispositivo potrebbe aiutare.</string> <string name="remove_episode_lable">Rimuovi l\'episodio</string> + <string name="mark_as_seen_label">Segna come visto</string> <string name="marked_as_seen_label">Segna come visto</string> <string name="mark_read_label">Segna come riprodotto</string> <string name="marked_as_read_label">Segnato come riprodotto</string> @@ -165,6 +176,8 @@ <string name="download_failed">fallito</string> <string name="download_pending">Download in attesa</string> <string name="download_running">Download in corso</string> + <string name="download_error_details">Dettagli</string> + <string name="download_error_details_message">%1$s \n\nFile URL:\n%2$s</string> <string name="download_error_device_not_found">Spazio di archiviazione non trovato</string> <string name="download_error_insufficient_space">Spazio Insufficiente</string> <string name="download_error_file_error">Errore del file</string> @@ -229,7 +242,6 @@ <string name="date">Per data</string> <string name="duration">Per durata</string> <string name="episode_title">Titolo dell\'episodio</string> - <string name="feed_title">Titolo del feed</string> <string name="ascending">Crescente</string> <string name="descending">Decrescente</string> <string name="clear_queue_confirmation_msg">Per favore conferma che vuoi rimuovere dalla coda TUTTI gli episodi in essa presenti.</string> @@ -266,7 +278,6 @@ <string name="enable_sonic">Abilita Sonic</string> <!--Empty list labels--> <string name="no_items_label">Non ci sono oggetti in questo elenco.</string> - <string name="no_feeds_label">Non sei ancora abbonato a nessun feed.</string> <string name="no_chapters_label">Questo episodio non ha capitoli.</string> <string name="no_shownotes_label">Questo episodio non ha note.</string> <!--Preferences--> @@ -275,12 +286,16 @@ <string name="other_pref">Altro</string> <string name="about_pref">Riguardo a</string> <string name="queue_label">Coda</string> - <string name="services_label">Servizi</string> <string name="flattr_label">Flattr</string> + <string name="pref_episode_cleanup_title">Pulizia dell\'episodio</string> + <string name="pref_episode_cleanup_summary">Gli episodi che non sono in coda e non sono preferiti dovrebbero essere idonei alla rimozione se Auto Download richiede spazio per nuovi episodi</string> + <string name="pref_pauseOnDisconnect_sum">Sospendi la riproduzione quando le cuffie o il bluetooth sono disconnessi</string> <string name="pref_unpauseOnHeadsetReconnect_sum">Riprendi la riproduzione quando le cuffie vengono ricollegate</string> + <string name="pref_unpauseOnBluetoothReconnect_sum">Reprendi la riproduzione quando le cuffie o il bluetooth sono disconnessi</string> <string name="pref_followQueue_sum">Passa al prossimo episodio in coda al termine della riproduzione</string> <string name="pref_auto_delete_sum">Elimina l\'episodio al termine della riproduzione</string> <string name="pref_auto_delete_title">Elimina Automaticamente</string> + <string name="pref_smart_mark_as_played_sum">Contrassegna gli episodi come riprodotti anche se rimane meno di un certo numero di secondi di tempo di riproduzione</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> @@ -336,8 +351,6 @@ <string name="pref_playback_speed_sum">Personalizza le velocità disponibili per la riproduzione audio a velocità variabile</string> <string name="pref_gpodnet_sethostname_title">Imposta il nome dell\'host</string> <string name="pref_gpodnet_sethostname_use_default_host">Utilizza l\'host predefinito</string> - <string name="pref_expandNotify_title">Espandi le notifiche</string> - <string name="pref_expandNotify_sum">Espandi sempre le notifiche per mostrare i pulsanti di riproduzione.</string> <string name="pref_persistNotify_title">Controlli di riproduzione persistenti</string> <string name="pref_persistNotify_sum">Mantieni le notifiche e i controlli del blocco dello schermo quando la riproduzione è in pausa.</string> <string name="pref_showDownloadReport_title">Mostra il Rapporto del Download</string> @@ -376,8 +389,6 @@ <string name="choose_file_from_external_application">Usa un\'applicazione esterna</string> <string name="opml_export_label">Esportazione OPML</string> <string name="export_error_label">Errore di esportazione</string> - <string name="opml_export_success_title">Esportazione OPML avvenuta con successo.</string> - <string name="opml_export_success_sum">Il file .opml è stato scritto su:\u0020</string> <!--Sleep timer--> <string name="set_sleeptimer_label">Imposta timer di spegnimento</string> <string name="disable_sleeptimer_label">Disabilita il timer di spegnimento</string> @@ -499,7 +510,9 @@ <string name="sort_duration_long_short">Durata (Lunghi \u2192 Corti)</string> <!--Rating dialog--> <string name="rating_title">Ti piace AntennaPod?</string> + <string name="rating_never_label">Lasciami solo</string> <string name="rating_later_label">Ricordamelo più tardi</string> + <string name="rating_now_label">Certo, facciamolo!</string> <!--Audio controls--> <string name="audio_controls">Controlli audio</string> <string name="playback_speed">Velocità di riproduzione</string> @@ -516,9 +529,13 @@ <string name="proxy_checking">Controllo in corso...</string> <string name="proxy_test_successful">Test avvenuto con successo</string> <string name="proxy_test_failed">Test fallito</string> + <string name="proxy_host_empty_error">Host non può essere vuoto</string> <string name="proxy_port_invalid_error">Porta non valida</string> <!--Database import/export--> + <string name="import_select_file">Seleziona il file da importare</string> + <string name="export_ok">Esportato con successo.</string> <!--Casting--> <string name="cast_media_route_menu_title">Riproduci su...</string> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-iw-rIL/strings.xml b/core/src/main/res/values-iw-rIL/strings.xml index 96475b40e..8699c3eee 100644 --- a/core/src/main/res/values-iw-rIL/strings.xml +++ b/core/src/main/res/values-iw-rIL/strings.xml @@ -2,58 +2,70 @@ <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="statistics_label">סטטיסטיקה</string> + <string name="add_feed_label">הוספת פודק×סט</string> <string name="episodes_label">פרקי×</string> - <string name="all_episodes_short_label">הכל</string> + <string name="all_episodes_short_label">הכול</string> <string name="favorite_episodes_label">מועדפי×</string> <string name="new_label">חדש</string> <string name="settings_label">הגדרות</string> <string name="downloads_label">הורדות</string> - <string name="downloads_running_label">פועל</string> - <string name="downloads_completed_label">סיי×</string> + <string name="downloads_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="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> - <string name="free_space_label">%1$s ×—×™× ×</string> - <string name="episode_cache_full_title">זכרון -המטמון של ×¤×¨×§×™× ×ž×œ×</string> - <string name="episode_cache_full_message">זכרון-המטמון של ×¤×¨×§×™× ×”×’×™×¢ לגבול שלו. ×פשר להגדיל ×ת גודל המטמון בהגדרות.</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_mode_normal">חשב זמן ×©× ×•×’×Ÿ בפועל. פרק ×©× ×•×’×Ÿ ×¤×¢×ž×™×™× × ×¡×¤×¨ פעמיי×, לעומת פרק שרק סומן ×›× ×•×’×Ÿ - ×©×œ× × ×¡×¤×¨.</string> + <string name="total_time_listened_to_podcasts">זמן × ×™×’×•×Ÿ הפודק××¡×˜×™× ×”×›×•×œ×œ:</string> + <string name="statistics_details_dialog">%1$d מתוך %2$d ×¤×¨×§×™× ×”×—×œ×•.\n\n× ×•×’× ×• %3$s מתוך %4$s.</string> + <string name="statistics_mode">מצב סטטיסטיקה</string> + <string name="statistics_mode_normal">חישוב זמן ×©× ×•×’×Ÿ בפועל. × ×’×™× ×” כפולה × ×¡×¤×¨×ª פעמיי×, בעוד שסימון ×›× ×•×’×Ÿ ×œ× × ×—×©×‘.</string> + <string name="statistics_mode_count_all">×¡×™×›×•× ×›×œ הפודק××¡×˜×™× ×©×¡×•×ž× ×• ×›× ×•×’× ×•</string> + <string name="statistics_speed_not_counted">לתשומת לבך: ×ין התייחסות למהירות ×”× ×’×™× ×”.</string> <!--Main activity--> - <string name="drawer_open">פתח תפריט</string> - <string name="drawer_close">סגור תפריט</string> - <string name="drawer_feed_order_alphabetical">מיין בסדר ×לפביתי</string> - <string name="drawer_feed_order_last_update">מיין לפי ת×ריך פרסו×</string> - <string name="drawer_feed_order_most_played">מיין לפי מספר ×¤×¨×§×™× ×©×”×•×©×ž×¢×• </string> + <string name="drawer_open">פתיחת תפריט</string> + <string name="drawer_close">סגירת תפריט</string> + <string name="drawer_preferences">העדפות מגירה</string> + <string name="drawer_feed_order_unplayed_episodes">מיון לפי ×ž×•× ×”</string> + <string name="drawer_feed_order_alphabetical">מיון בסדר ×לפביתי</string> + <string name="drawer_feed_order_last_update">מיון לפי ת×ריך פרסו×</string> + <string name="drawer_feed_order_most_played">מיון לפי מספר ×¤×¨×§×™× ×©×”×•×©×ž×¢×• </string> + <string name="drawer_feed_counter_new_unplayed">מספר ×¤×¨×§×™× ×—×“×©×™× ×•×›×לו שעדיין ×œ× ×”×ª× ×’× ×•</string> + <string name="drawer_feed_counter_new">מספר ×¤×¨×§×™× ×—×“×©×™×</string> + <string name="drawer_feed_counter_unplayed">מספר ×¤×¨×§×™× ×©×¢×•×“ ×œ× ×”×ª× ×’× ×•</string> + <string name="drawer_feed_counter_downloaded">מספר ×¤×¨×§×™× ×©×”×ª×§×‘×œ×•</string> + <string name="drawer_feed_counter_none">לל×</string> <!--Webview actions--> - <string name="open_in_browser_label">פתח בדפדפן</string> - <string name="copy_url_label">העתק כתובת ×תר</string> - <string name="share_url_label">שתף כתובת ×תר</string> - <string name="copied_url_msg">כתובת ×תרהועתקה ללוח.</string> - <string name="go_to_position_label">עבור ×œ×ž×™×§×•× ×–×”</string> + <string name="open_in_browser_label">פתיחה בדפדפן</string> + <string name="copy_url_label">העתקת כתובת</string> + <string name="share_url_label">שיתוף כתובת</string> + <string name="copied_url_msg">הכתובת הועתקה ללוח הגזירי×</string> + <string name="go_to_position_label">מעבר ×œ×ž×™×§×•× ×–×”</string> <!--Playback history--> - <string name="clear_history_label">× ×§×” היסטוריה</string> + <string name="clear_history_label">× ×™×§×•×™ היסטוריה</string> <!--Other--> <string name="confirm_label">×ישור</string> - <string name="cancel_label">בטל</string> + <string name="cancel_label">ביטול</string> <string name="yes">כן</string> <string name="no">ל×</string> - <string name="author_label">מחבר</string> + <string name="reset">×יפוס</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> <string name="error_msg_prefix">×ירעה שגי××”:</string> - <string name="refresh_label">×¨×¢× ×Ÿ</string> - <string name="external_storage_error_msg">×ין ×חסון ×—×™×¦×•× ×™ זמין. ×× × ×•×“× ×›×™ ×חסון ×—×™×¦×•× ×™ ×”×•× ×ž×•×ª×§×Ÿ כך שה×פליקציה תוכל לעבוד כמו שצריך.</string> + <string name="refresh_label">×¨×¢× ×•×Ÿ</string> + <string name="external_storage_error_msg">×ין ×חסון ×—×™×¦×•× ×™ זמין. × × ×œ×•×•×“× ×©×™×© ×חסון ×—×™×¦×•× ×™ מעוגן כדי שהיישומון יוכל לפעול כר×וי.</string> <string name="chapters_label">פרקי×</string> + <string name="chapter_duration">משך: %1$s</string> <string name="shownotes_label">הערות פרק</string> <string name="description_label">תי×ור</string> <string name="most_recent_prefix">הפרק ×”×חרון:\u0020</string> @@ -62,187 +74,268 @@ <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> - <string name="auto_download_label">כלול בהורדות ×וטומטיות</string> + <string name="save_username_password_label">שמירת ×©× ×ž×©×ª×ž×© וססמה</string> + <string name="close_label">סגירה</string> + <string name="retry_label">×œ× ×¡×•×ª שוב</string> + <string name="auto_download_label">לכלול בהורדות ×וטומטיות</string> + <string name="auto_download_apply_to_items_title">החלה על ×¤×¨×§×™× ×§×•×“×ž×™×</string> + <string name="auto_download_apply_to_items_message">הגדרות ×”<i>הורדה ×”×וטומטית</i> החדשות יחולו ×וטומטית על ×¤×¨×§×™× ×—×“×©×™×.\nלהחיל ×ותן ×’× ×¢×œ ×¤×¨×§×™× ×©×¤×•×¨×¡×ž×• בעבר?</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> + <string name="send_label">שליחה…</string> <string name="episode_cleanup_never">××£ פע×</string> + <string name="episode_cleanup_queue_removal">×›×שר ×œ× ×‘×ª×•×¨</string> <string name="episode_cleanup_after_listening">×חרי סיו×</string> <plurals name="episode_cleanup_days_after_listening"> <item quantity="one">×™×•× ×חרי סיו×</item> + <item quantity="two">%d ×™×ž×™× ×œ×חר ×¡×™×•× </item> + <item quantity="many">%d ×™×ž×™× ×œ×חר ×¡×™×•× </item> <item quantity="other">%d ×™×ž×™× ×œ×חר ×¡×™×•× </item> </plurals> <!--'Add Feed' Activity labels--> <string name="feedurl_label">כתובת ×”×–× ×”</string> - <string name="etxtFeedurlHint">כתובת של ×”×–× ×” ×ו ×תר ××™× ×˜×¨× ×˜</string> - <string name="txtvfeedurl_label">הוסף פודק×סט לפי כתובת ×תר</string> + <string name="etxtFeedurlHint">www.example.com/feed</string> + <string name="txtvfeedurl_label">הוספת פודק×סט לפי כתובת</string> <string name="podcastdirectories_label">חפש פודק×סט בספריה</string> - <string name="browse_gpoddernet_label">עיין ב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> - <string name="mark_all_read_msg">סמן ×ת כל ×”×¤×¨×§×™× ×›× ×§×¨×</string> - <string name="mark_all_read_confirmation_msg">×× × ×שר ש×תה רוצה לסמן ×ת כל ×¤×¨×§×™× ×›× ×§×¨××™×.</string> - <string name="mark_all_read_feed_confirmation_msg">×× × ×שר ש×תה רוצה לסמן ×ת כל ×¤×¨×§×™× ×‘×”×–× ×” זו ×›× ×§×¨××™×.</string> - <string name="mark_all_seen_label">סמן ×ת ×›×•×œ× ×›× ×¨×ו</string> - <string name="mark_all_seen_msg">סמן ×ת כל ×”×¤×¨×§×™× ×›× ×¨×ו</string> - <string name="mark_all_seen_confirmation_msg">×× × ×שר ש×תה רוצה לסמן ×ת כל ×¤×¨×§×™× ×›× ×¨×ו.</string> - <string name="show_info_label">הצג מידע</string> - <string name="rename_feed_label">×©× ×” ×©× ×¤×•×“×§×סט</string> - <string name="remove_feed_label">הסר פודק×סט</string> - <string name="share_label">שתף...</string> - <string name="share_link_label">שתף קישור ×תר</string> - <string name="feed_remover_msg">הסר ×”×–× ×”</string> - <string name="load_complete_feed">×¨×¢× ×Ÿ ×ת כל ×”×”×–× ×”</string> - <string name="hide_episodes_title">הסתר פרקי×</string> + <string name="mark_all_read_label">סימון הכול ×›× ×•×’× ×•</string> + <string name="mark_all_read_msg">סימון ×ת כל ×”×¤×¨×§×™× ×›× ×•×’× ×•</string> + <string name="mark_all_read_confirmation_msg">× × ×œ×שר ×©×‘×¨×¦×•× ×š לסמן ×ת כל ×”×¤×¨×§×™× ×›× ×•×’× ×•.</string> + <string name="mark_all_seen_label">סימון ×›×•×œ× ×›× ×¦×¤×•</string> + <string name="mark_all_seen_confirmation_msg">× × ×œ×שר ×©×‘×¨×¦×•× ×š לסמן ×ת כל ×”×¤×¨×§×™× ×›× ×¦×¤×•.</string> + <string name="show_info_label">הצגת מידע</string> + <string name="share_label">שיתוף…</string> + <string name="share_file_label">שיתוף כתובת</string> + <string name="share_feed_url_label">שיתוף כתובת ×”×–× ×”</string> + <string name="hide_episodes_title">הסתרת פרקי×</string> + <string name="hide_unplayed_episodes_label">×œ× × ×•×’×Ÿ</string> + <string name="hide_paused_episodes_label">מושהה</string> + <string name="hide_played_episodes_label">× ×•×’×Ÿ</string> + <string name="hide_queued_episodes_label">בתור</string> + <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> <!--actions on feeditems--> - <string name="download_label">הורד</string> - <string name="play_label">× ×’×Ÿ</string> - <string name="pause_label">השהה</string> - <string name="stop_label">עצור</string> - <string name="stream_label">הזר×</string> - <string name="remove_label">הסר</string> - <string name="remove_episode_lable">הסר פרק</string> - <string name="mark_read_label">סמן ×›× ×§×¨×</string> - <string name="marked_as_read_label">סומן ×›× ×§×¨×</string> - <string name="mark_unread_label">סמן ×›×œ× × ×§×¨×</string> - <string name="add_to_queue_label">הוסף לתור</string> + <string name="download_label">הורדה</string> + <string name="play_label">× ×™×’×•×Ÿ</string> + <string name="pause_label">השהיה</string> + <string name="stop_label">עצירה</string> + <string name="stream_label">הזרמה</string> + <string name="remove_label">הסרה</string> + <string name="delete_label">מחיקה</string> + <string name="delete_failed">×œ× × ×™×ª×Ÿ למחוק קובץ. הפעלת המכשיר מחדש עשויה לסייע.</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> + <string name="add_to_queue_label">הוספה לתור</string> <string name="added_to_queue_label">התווסף לתור</string> - <string name="remove_from_queue_label">הסר מהתור</string> + <string name="remove_from_queue_label">הסרה מהתור</string> <string name="add_to_favorite_label">התווסף למועדפי×</string> - <string name="visit_website_label">בקר ב×תר</string> - <string name="support_label">×ª×¨×•× ×‘×מצעות Flattr</string> - <string name="skip_episode_label">דלג על הפרק</string> + <string name="added_to_favorites">התווסף למועדפי×</string> + <string name="remove_from_favorite_label">הסרה מהמועדפי×</string> + <string name="removed_from_favorites">הוסר מהמועדפי×</string> + <string name="visit_website_label">ביקור ב×תר</string> + <string name="support_label">תרומה ×¢× Flattr</string> + <string name="skip_episode_label">דילוג על פרק</string> + <string name="activate_auto_download">הפעלת הורדה ×וטומטית</string> + <string name="deactivate_auto_download">השבתת הורדה ×וטומטית</string> + <string name="reset_position">×יפוס ×ž×™×§×•× ×”× ×’×™× ×”</string> + <string name="removed_item">פריט הוסר</string> <!--Download messages and labels--> <string name="download_successful">הצלחה</string> - <string name="download_failed">כישלון</string> - <string name="download_pending">הורדה עתידית</string> + <string name="download_failed">כשל</string> + <string name="download_pending">הורדה ×ž×ž×ª×™× ×”</string> <string name="download_running">הורדה מתבצעת</string> - <string name="download_error_device_not_found">התקן ×יחסון ×œ× × ×ž×¦×</string> - <string name="download_error_insufficient_space">×ין די שטח ×יחסון</string> + <string name="download_error_details">פרטי×</string> + <string name="download_error_details_message">%1$s \n\nכתובת הקובץ:\n%2$s</string> + <string name="download_error_device_not_found">התקן ×”×חסון ×œ× × ×ž×¦×</string> + <string name="download_error_insufficient_space">×ין די שטח ×חסון</string> <string name="download_error_file_error">שגי×ת קובץ</string> - <string name="download_error_http_data_error">שגי×ת מידע HTTP</string> + <string name="download_error_http_data_error">שגי×ת × ×ª×•× ×™ HTTP</string> <string name="download_error_error_unknown">שגי××” ×œ× ×™×“×•×¢×”</string> - <string name="download_error_parser_exception">שגי×ת ×ª×•×›× ×™×ª × ×™×ª×•×—</string> + <string name="download_error_parser_exception">שגי×ת ×ž×¤×¢× ×—</string> <string name="download_error_unsupported_type">סוג ×”×”×–× ×” ××™× ×• × ×ª×ž×š</string> <string name="download_error_connection_error">שגי×ת חיבור</string> <string name="download_error_unknown_host">שרת ×œ× ×™×“×•×¢</string> <string name="download_error_unauthorized">שגי×ת ×ימות</string> - <string name="cancel_all_downloads_label">בטל ×ת כל ההורדות</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_report_title">הורדות הושלמו</string> - <string name="download_error_malformed_url">כתובת ×תר שגויה</string> + <string name="download_canceled_autodownload_enabled_msg">ההורדה בוטלה\n×”<i>הורדה ×”×וטומטית</i> הושבתה עבור פריט ×–×”</string> + <string name="download_report_title">הורדות הושלמו ×¢× ×©×’×™××” ×חת ×ו יותר</string> + <string name="download_report_content_title">דוח הורדה</string> + <string name="download_error_malformed_url">כתובת שגויה</string> <string name="download_error_io_error">שגי×ת קלט פלט</string> <string name="download_error_request_error">שגי×ת בקשה</string> <string name="download_error_db_access">שגי×ת גישה למסד ×”× ×ª×•× ×™×</string> - <string name="downloads_processing">מעבד הורדות</string> - <string name="download_notification_title">מוריד פודק×סט</string> - <string name="download_report_content">%1$d הורדות הצליחו, %2$d × ×™×›×©×œ×•</string> + <plurals name="downloads_left"> + <item quantity="one">× ×•×ª×¨×” הורדה %d</item> + <item quantity="two">× ×•×ª×¨×• %d הורדות</item> + <item quantity="many">× ×•×ª×¨×• %d הורדות</item> + <item quantity="other">× ×•×ª×¨×• %d הורדות</item> + </plurals> + <string name="downloads_processing">ההורדות בהליכי עיבוד</string> + <string name="download_notification_title">× ×ª×•× ×™ הפודק×סט מתקבלי×</string> + <string name="download_report_content">%1$d הורדות הצליחו, %2$d × ×›×©×œ×•</string> <string name="download_log_title_unknown">כותרת ×œ× ×™×“×•×¢×”</string> <string name="download_type_feed">×”×–× ×”</string> <string name="download_type_media">קובץ מדיה</string> <string name="download_type_image">×ª×ž×•× ×”</string> - <string name="download_request_error_dialog_message_prefix">שגי××” ×ירעה בעת ×”× ×™×¡×™×•×Ÿ הורדת הקובץ:\u0020</string> - <string name="authentication_notification_title">× ×™×“×¨×© ×ימות</string> - <string name="authentication_notification_msg">המש×ב ×ותה ביקשת דורש ×©× ×ž×©×ª×ž×© וססמה</string> + <string name="download_request_error_dialog_message_prefix">×ירעה שגי××” בעת ×”× ×™×¡×™×•×Ÿ הורדת הקובץ:\u0020</string> + <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_message_not_in_queue">הורדה דרך חיבור × ×ª×•× ×™× ×©×œ רשת סלולרית מושבת דרך ההגדרות.\n\n× ×™×ª×Ÿ לבחור בין הוספת הפרק לתור ×ו ל×פשר להוריד ×ותו ב×ופן ×–×ž× ×™.\n\n<small>הבחירה שלך תישמר למשך 10 דקות.</small></string> + <string name="confirm_mobile_download_dialog_message">הורדה דרך חיבור × ×ª×•× ×™× ×©×œ רשת סלולרית מושבת דרך ההגדרות.\n\nל×פשר ×ת ההורדה ב×ופן ×–×ž× ×™?\n\n<small>הבחירה שלך תישמר למשך 10 דקות.</small></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> - <string name="player_stopped_msg">מדיה ×œ× ×ž×ª× ×’× ×ª</string> - <string name="player_preparing_msg">×ž×ª×›×•× ×Ÿ</string> - <string name="player_ready_msg">מוכן</string> - <string name="player_seeking_msg">מחפש</string> - <string name="playback_error_server_died">שרת מת</string> + <string name="player_stopped_msg">×ין מדיה ×ž×ª× ×’× ×ª</string> + <string name="player_preparing_msg">×‘×”×›× ×”</string> + <string name="player_ready_msg">×‘×”×ž×ª× ×”</string> + <string name="player_seeking_msg">מתבצע ×יתור</string> + <string name="playback_error_server_died">השרת ×œ× ×ž×’×™×‘</string> <string name="playback_error_unknown">שגי××” ×œ× ×™×“×•×¢×”</string> - <string name="no_media_playing_label">מדיה ×œ× ×ž×ª× ×’× ×ª</string> - <string name="player_buffering_msg">×ž×ž×œ× ×—×•×¦×¥</string> - <string name="playbackservice_notification_title">×ž× ×’×Ÿ פודק×סט</string> - <string name="unknown_media_key">×× ×˜× ×”-פוד - מפתח מדיה ×œ× ×™×“×•×¢: %1$d</string> + <string name="no_media_playing_label">×ין מדיה ×ž×ª× ×’× ×ª</string> + <string name="player_buffering_msg">החוצץ מתמל×</string> + <string name="playbackservice_notification_title">פודק×סט ×ž×ª× ×’×Ÿ</string> + <string name="unknown_media_key">×× ×˜× ×”Ö¾×¤Ö¼×•Ö¹×“ - מפתח מדיה ×œ× ×™×“×•×¢: %1$d</string> <!--Queue operations--> - <string name="clear_queue_label">× ×§×” תור</string> - <string name="undo">בטל</string> - <string name="removed_from_queue">הסר פריט</string> - <string name="move_to_top_label">העבר למעלה</string> - <string name="move_to_bottom_label">העבר למטה</string> - <string name="sort">מיין</string> + <string name="lock_queue">× ×¢×™×œ×ª תור</string> + <string name="unlock_queue">שחרור תור</string> + <string name="queue_locked">התור × × ×¢×œ</string> + <string name="queue_unlocked">התור שוחרר ×ž× ×¢×™×œ×”</string> + <string name="clear_queue_label">× ×™×§×•×™ תור</string> + <string name="undo">ביטול</string> + <string name="removed_from_queue">פריט הוסר</string> + <string name="move_to_top_label">העברה למעלה</string> + <string name="move_to_bottom_label">העברה למטה</string> + <string name="sort">מיון</string> <string name="date">ת×ריך</string> <string name="duration">משך</string> + <string name="episode_title">כותרת הפרק</string> <string name="ascending">בסדר עולה</string> <string name="descending">בסדר יורד</string> - <string name="clear_queue_confirmation_msg">×× × ×שר ש×תה רוצה ×œ× ×§×•×ª ×ת התור מכל ×”×¤×¨×§×™× ×©×‘×•</string> + <string name="clear_queue_confirmation_msg">× × ×œ×שר ×ת ×¤×™× ×•×™ התור מכל ×”×¤×¨×§×™× ×©×‘×•</string> <!--Flattr--> - <string name="flattr_auth_label">×›× ×™×¡×” ל-Fattr</string> - <string name="flattr_auth_explanation">לחץ על הכפתור למטה כדי להתחיל ×ת תהליך ×”×ימות. ×תה תועבר למסך ×›× ×™×¡×ª flattr בדפדפן שלך ותתבקש לתת ל×× ×˜× ×”-פוד רשות ×œ×ª×¨×•× ×‘×מצעות flattr. ל×חר שקבלת ×ישור, תוכל לחזור למסך ×–×” ב×ופן ×וטומטי.</string> + <string name="flattr_auth_label">×›× ×™×¡×” ל־Fattr</string> + <string name="flattr_auth_explanation">× × ×œ×œ×—×•×¥ על הכפתור שלמטה כדי להתחיל ×ת תהליך ×”×ימות. פעולה זו תעביר ×ותך למסך ×”×›× ×™×¡×” של Flattr בדפדפן שלך ותופיע בקשה ל×פשר ל×× ×˜× ×”Ö¾×¤Ö¼×•Ö¹×“ לבצע פעולות ב־Flattr. ל×חר מתן ההרש××”, המערכת תחזיר ×ותך למסך ×–×” ×וטומטית.</string> <string name="authenticate_label">×ימות</string> - <string name="return_home_label">חזור למסך הבית</string> - <string name="flattr_auth_success">×”×ימות הצליח! עכשיו ×תה יכול ×œ×ª×¨×•× ×‘×מצעות flattr מתוך ×”×פליקציה.</string> - <string name="no_flattr_token_title">×סימון flattr ×œ× × ×ž×¦×</string> - <string name="no_flattr_token_notification_msg">חשבון ×”-flattr שלך ××™× ×• מחובר ל×× ×˜× ×”-פוד. הקש ×›×ן ל×ימות.</string> - <string name="no_flattr_token_msg">חשבון ×”-flattr שלך ××™× ×• מחובר ל×× ×˜× ×”-פוד. ×תה יכול לקשר×ת ×œ×—×©×‘×•× ×š ל×× ×˜× ×”-פוד ×œ×ª×¨×•× ×‘×מצעות flattr מתוך ×”×פליקציה ×ו ש×תה יכול לבקר ב×תר ×”××™× ×˜×¨× ×˜ של הדבר לו תרצה לתרו×.</string> - <string name="authenticate_now_label">×מת</string> + <string name="return_home_label">חזרה למסך הבית</string> + <string name="flattr_auth_success">×”×ימות הצליח! כעת יש לך ×פשרות ×œ×ª×¨×•× ×¢× Flattr מתוך היישומון.</string> + <string name="no_flattr_token_title">×œ× × ×ž×¦× ×סימון Flattr</string> + <string name="no_flattr_token_notification_msg">× ×¨××” ×›×™ חשבון ×”Ö¾Flattr שלך ××™× ×• מחובר ל×× ×˜× ×”Ö¾×¤Ö¼×•Ö¹×“. יש לגעת ×›×ן ל×ימות.</string> + <string name="no_flattr_token_msg">× ×¨××” ×›×™ חשבון ×”Ö¾Flattr שלך ××™× ×• מחובר ל×× ×˜× ×”Ö¾×¤Ö¼×•Ö¹×“. יש לך ×פשרות לחבר ×ת ×—×©×‘×•× ×š ל×× ×˜× ×”Ö¾×¤Ö¼×•Ö¹×“ כדי ×œ×ª×¨×•× ×¢× Flattr מתוך היישומון ×ו לבקר ב×תר של מה ×©×‘×¨×¦×•× ×š ×œ×ª×¨×•× ×œ×• ×¢× Flattr.</string> + <string name="authenticate_now_label">×ימות</string> <string name="action_forbidden_title">הפעולה ×סורה</string> - <string name="action_forbidden_msg">ל×× ×˜× ×”-פוד ×ין הרש××” לפעולה זו. הסיבה לכך יכולה להיות ש×סימון הגישה של ×× ×˜× ×”-פוד לחשבון שלך בוטל. ×תה יכול לבצע ×ימות מחדש ×ו לבקר ב×תר ×”××™× ×˜×¨× ×˜ של הדבר במקו×.</string> + <string name="action_forbidden_msg">ל×× ×˜× ×”Ö¾×¤Ö¼×•Ö¹×“ ×ין הרש××” לבצע פעולה זו. הסיבה לכך עשויה להיות ש×סימון הגישה של ×× ×˜× ×”Ö¾×¤Ö¼×•Ö¹×“ לחשבון שלך × ×©×œ×œ. × ×™×ª×Ÿ ל×מת מחדש ×ו לבקר ב×תר המיועד במקו×.</string> <string name="access_revoked_title">גישה בוטלה</string> - <string name="access_revoked_info">×סימון הגישה של ×× ×˜× ×”-פוד ×œ×—×©×‘×•× ×š בוטל. על ×ž× ×ª ×œ×”×©×œ×™× ×ת התהליך, ×תה צריך להסיר ×™×™×©×•× ×–×” מהרשימת ×”×™×™×©×•×ž×™× ×©×ושרו בהגדרות ×”×—×©×‘×•× ×š ב×תר flattr.</string> + <string name="access_revoked_info">×סימון הגישה של ×× ×˜× ×”Ö¾×¤×•×“ ×œ×—×©×‘×•× ×š בוטל. על ×ž× ×ª ×œ×”×©×œ×™× ×ת התהליך, ×תה צריך להסיר ×™×™×©×•× ×–×” מהרשימת ×”×™×™×©×•×ž×™× ×©×ושרו בהגדרות ×”×—×©×‘×•× ×š ב×תר flattr.</string> <!--Flattr--> - <string name="flattr_click_success">תרמת ב-Flattr!</string> - <string name="flattr_click_success_count">תרמת ב-Flattr %d פעמי×! </string> + <string name="flattr_click_success">תרמת ב־Flattr!</string> + <string name="flattr_click_success_count">תרמת ב־Flattr %d פעמי×!</string> <string name="flattr_click_success_queue">תרומות Flattr: %s.</string> - <string name="flattr_click_failure_count">כישלון ×œ×ª×¨×•× ×‘-Flattr %d!</string> - <string name="flattr_click_failure">×œ× × ×ª×¨× ×‘-Flattr: %s.</string> - <string name="flattr_click_enqueued">תרומות ב-Flattr מ×וחר יותר</string> - <string name="flattring_thing">×ª×•×¨× ×‘-Flattr %s</string> - <string name="flattring_label">×× ×˜× ×”-פוד ×ª×•×¨× ×‘-Flattr</string> - <string name="flattrd_label">×× ×˜× ×”-פוד ×ª×¨× ×‘-Flattr</string> - <string name="flattrd_failed_label">כישלון תרומת ×× ×˜× ×”-פוד ב-Flattr</string> - <string name="flattr_retrieving_status">×יחזור תרומות Flattr</string> + <string name="flattr_click_failure_count">התרומה ב־Flattr %d × ×›×©×œ×”!</string> + <string name="flattr_click_failure">×œ× × ×ª×¨× ×‘Ö¾Flattr: %s.</string> + <string name="flattr_click_enqueued">×œ×ª×¨×•× ×‘Ö¾Flattr מ×וחר יותר</string> + <string name="flattring_thing">תרומה ב־Flattr %s</string> + <string name="flattring_label">תרומה ב־Flattr ×¢× ×× ×˜× ×”Ö¾×¤Ö¼×•Ö¹×“</string> + <string name="flattrd_label">תרומה ב־Flattr ×¢× ×× ×˜× ×”Ö¾×¤Ö¼×•Ö¹×“</string> + <string name="flattrd_failed_label">התרומה ב×× ×˜× ×”Ö¾×¤Ö¼×•Ö¹×“ ×¢× Flattr × ×›×©×œ×”</string> + <string name="flattr_retrieving_status">תרומות Flattr מתקבלות</string> <!--Variable Speed--> - <string name="download_plugin_label">הורד תוסף</string> + <string name="download_plugin_label">הורדת תוסף</string> <string name="no_playback_plugin_title">תוסף ×œ× ×ž×•×ª×§×Ÿ</string> + <string name="no_playback_plugin_or_sonic_msg">כדי ×©×ª×›×•× ×ª המהירות ×”×ž×©×ª× ×” תפעל, מומלץ להפעיל ×ת × ×’×Ÿ המדיה ×”×ž×•×‘× ×” ×‘×©× Sonic [מ־Android 4.1 ו×ילך].\n\nלחלופין, × ×™×ª×Ÿ להוריד תוסף צד שלישי ×‘×©× <i>Prestissimo</i> ×ž×”×—× ×•×ª Play.\nכל תקלה שמופיעה ב־Prestissimo ××™× ×” ב×חריות ×× ×˜× ×”Ö¾×¤Ö¼×•Ö¹×“ ויש לדווח עליה ×œ×‘×¢×œ×™× ×¢×œ התוסף.</string> <string name="set_playback_speed_label">מהירויות × ×™×’×•×Ÿ</string> + <string name="enable_sonic">הפעלת 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="about_pref">על ×ודות</string> <string name="queue_label">תור</string> - <string name="services_label">שירותי×</string> <string name="flattr_label">Flattr</string> - <string name="pref_unpauseOnHeadsetReconnect_sum">המשך ×ת ×”× ×™×’×•×Ÿ כשה××•×–× ×™×•×ª מחוברות מחדש</string> - <string name="pref_followQueue_sum">עבור לפריט ×”×‘× ×‘×ª×•×¨ ×›×שר ×”× ×™×’×•×Ÿ מסתיי×</string> - <string name="pref_auto_delete_sum">מחק פרק ×›×”× ×™×’×•×Ÿ מסתיי×</string> + <string name="pref_episode_cleanup_title">× ×™×§×•×™ פרקי×</string> + <string name="pref_episode_cleanup_summary">×¤×¨×§×™× ×©××™× × ×‘×ª×•×¨ ו××™× × ×‘×ž×•×¢×“×¤×™× ××ž×•×¨×™× ×œ×¢× ×•×ª ×œ×ª× ××™× ×©×œ הסרה במקרה שההורדה ×”×וטומטית זקוקה ×œ×ž×§×•× ×œ×¤×¨×§×™× ×—×“×©×™×</string> + <string name="pref_pauseOnDisconnect_sum">השהיית ×”× ×’×™× ×” ×›×שר ×”××•×–× ×™×•×ª ×ו ×”Ö¾Bluetooth ×ž× ×•×ª×§×™×</string> + <string name="pref_unpauseOnHeadsetReconnect_sum">להמשיך ×ת ×”× ×™×’×•×Ÿ כשה××•×–× ×™×•×ª מחוברות מחדש</string> + <string name="pref_unpauseOnBluetoothReconnect_sum">להמשיך ×ת ×”× ×’×™× ×” ×¢× ×—×™×‘×•×¨ מחדש של ×”Ö¾Bluetooth</string> + <string name="pref_hardwareForwardButtonSkips_title">כפתור קדימה מדלג</string> + <string name="pref_hardwarePreviousButtonRestarts_title">כפתור ×חורה מתחיל מחדש</string> + <string name="pref_hardwarePreviousButtonRestarts_sum">לחיצה על כפתור החומרה ×חורה מדלג מתחיל מחדש ×ת × ×’×™× ×ª הפרק ×”× ×•×›×—×™ ×‘×ž×§×•× ×œ×—×–×•×¨ ×חורה בפרק</string> + <string name="pref_followQueue_sum">לעבור לפריט ×”×‘× ×‘×ª×•×¨ ×›×שר ×”× ×™×’×•×Ÿ מסתיי×</string> + <string name="pref_auto_delete_sum">מחיקת פרק ×›×©×”× ×™×’×•×Ÿ מסתיי×</string> <string name="pref_auto_delete_title">מחיקה ×וטומטית</string> + <string name="pref_smart_mark_as_played_sum">סימון ×¤×¨×§×™× ×›× ×•×’× ×• ×פילו ×× × ×©×רו כמה ×©× ×™×•×ª ×œ× ×’×™× ×”</string> + <string name="pref_smart_mark_as_played_title">סימון ×—×›× ×›× ×•×’× ×•</string> + <string name="pref_skip_keeps_episodes_sum">להש×יר ×¤×¨×§×™× ×œ×ž×¨×•×ª שדילגת עליה×</string> + <string name="pref_skip_keeps_episodes_title">להש×יר ×¤×¨×§×™× ×©×“×•×œ×’×•</string> + <string name="pref_favorite_keeps_episodes_sum">להש×יר ×¤×¨×§×™× ×©×¡×•×ž× ×• כמועדפי×</string> + <string name="pref_favorite_keeps_episodes_title">להש×יר ×¤×¨×§×™× ×ž×•×¢×“×¤×™×</string> <string name="playback_pref">× ×™×’×•×Ÿ</string> <string name="network_pref">רשת</string> - <string name="pref_downloadMediaOnWifiOnly_sum">הורד קבצי מדיה רק דרך חיבור ××™× ×˜×¨× ×˜ ×לחוטי</string> + <string name="pref_autoUpdateIntervallOrTime_title">זמן בין ×¢×“×›×•× ×™× ×ו מועד ביו×</string> + <string name="pref_autoUpdateIntervallOrTime_sum">× × ×œ×¦×™×™×Ÿ הפרש זמן ×ו מועד ×‘×™×•× ×œ×¨×¢× ×•×Ÿ ×”×”×–× ×•×ª ×וטומטית</string> + <string name="pref_autoUpdateIntervallOrTime_message">× ×™×ª×Ÿ להגדיר <i>הפרש זמן</i> כגון „כל שעתיי×â€, להגדיר <i>מועד ביו×</i> כגון „7:00†×ו <i>להשבית</i> ×¢×“×›×•× ×™× ××•×˜×•×ž×˜×™×™× ×œ×לתר.\n\n<small>לתשומת לבך: מועדי העדכון ××™× × ×ž×“×•×™×§×™×. יתכן עיכוב קל בפעולות.</small></string> + <string name="pref_autoUpdateIntervallOrTime_Disable">השבתה</string> + <string name="pref_autoUpdateIntervallOrTime_Interval">הגדרת הפרש זמן</string> + <string name="pref_autoUpdateIntervallOrTime_TimeOfDay">הגדרת הזמן ביו×</string> + <string name="pref_autoUpdateIntervallOrTime_every">כל %1$s</string> + <string name="pref_autoUpdateIntervallOrTime_at">ב־%1$s</string> + <string name="pref_downloadMediaOnWifiOnly_sum">הורדת קובצי מדיה רק דרך רשת ×לחוטית</string> <string name="pref_followQueue_title">× ×™×’×•×Ÿ מתמשך</string> - <string name="pref_downloadMediaOnWifiOnly_title">הורדת מדיה דרך ××™× ×˜×¨× ×˜ ×לחוטי</string> + <string name="pref_downloadMediaOnWifiOnly_title">הורדת מדיה דרך רשת ×לחוטית</string> <string name="pref_pauseOnHeadsetDisconnect_title">× ×™×ª×•×§ ××•×–× ×™×•×ª</string> <string name="pref_unpauseOnHeadsetReconnect_title">חיבור ××•×–× ×™×•×ª מחדש</string> - <string name="pref_mobileUpdate_title">עידכון דרך רשת סלולרית</string> - <string name="pref_mobileUpdate_sum">×פשר ×¢×™×“×›×•× ×™× ×“×¨×š רשת סלולרית</string> - <string name="refreshing_label">×ž×¨×¢× ×Ÿ</string> + <string name="pref_unpauseOnBluetoothReconnect_title">חיבור Bluetooth מחדש</string> + <string name="pref_mobileUpdate_title">עדכון דרך רשת סלולרית</string> + <string name="pref_mobileUpdate_sum">ל×פשר ×¢×“×›×•× ×™× ×“×¨×š רשת סלולרית</string> + <string name="refreshing_label">מתבצע ×¨×¢× ×•×Ÿ</string> <string name="flattr_settings_label">הגדרות Flattr</string> - <string name="pref_flattr_auth_title">×›× ×™×¡×” ל-Fattr</string> - <string name="pref_flattr_auth_sum">×”×™×›× ×¡ לחשבון שלך לflattr ×œ×ª×¨×•× ×™×©×™×¨×•×ª מתוך ×”×פליקציה.</string> + <string name="pref_flattr_auth_title">×›× ×™×¡×” ל־Fattr</string> + <string name="pref_flattr_auth_sum">× ×™×ª×Ÿ ×œ×”×™×›× ×¡ לחשבון שלך ב־Flattr כדי ×œ×ª×¨×•× ×™×©×™×¨×•×ª מתוך היישומון.</string> <string name="pref_flattr_this_app_title">×ª×¨×•× ×‘×מצעות Flattr ל×פליקציה זו</string> - <string name="pref_flattr_this_app_sum">תמוך בפיתוח ×× ×˜× ×”-פוד בתרומה ×¢× Flattr. תודה!</string> - <string name="pref_revokeAccess_title">בטל גישה</string> - <string name="pref_revokeAccess_sum">בטל הרש×ת גישה לחשבון flattr ×œ×™×™×©×•× ×–×”.</string> + <string name="pref_flattr_this_app_sum">× ×™×ª×Ÿ לתמוך בפיתוח של ×× ×˜× ×”Ö¾×¤Ö¼×•Ö¹×“ על ידי תרומה ב־Flattr. תודה!</string> + <string name="pref_revokeAccess_title">ביטול גישה גישה</string> + <string name="pref_revokeAccess_sum">שלילת הרש×ות הגישה לחשבון ×”Ö¾Flattr שלך מיישומון ×–×”.</string> <string name="pref_auto_flattr_title">תרומות Flattr ×וטומטיות</string> - <string name="pref_auto_flattr_sum">הגדר תרומות flattr ×וטומטיות</string> - <string name="user_interface_label">ממשק משתמש</string> - <string name="pref_set_theme_title">בחר ערכת × ×•×©×</string> - <string name="pref_set_theme_sum">×©× ×” ×ת מר××” ×× ×˜× ×”-פוד</string> + <string name="pref_auto_flattr_sum">הגדרת תרומות Flattr ×וטומטיות</string> + <string name="user_interface_label">×ž× ×©×§ משתמש</string> + <string name="pref_set_theme_title">בחירת ערכת עיצוב</string> + <string name="pref_nav_drawer_title">הת×מת מגירת ×”× ×™×•×•×˜</string> + <string name="pref_nav_drawer_sum">הת×מת תצוגת מגירת ×”× ×™×•×•×˜.</string> + <string name="pref_nav_drawer_items_title">הגדרת פריטי מגירת × ×™×•×•×˜</string> + <string name="pref_nav_drawer_items_sum">החלפת ×”×¤×¨×™×˜×™× ×©×ž×•×¤×™×¢×™× ×‘×ž×’×™×¨×ª ×”× ×™×•×•×˜.</string> + <string name="pref_nav_drawer_feed_order_title">הגדרת סדר ×ž×™× ×•×™×™×</string> + <string name="pref_nav_drawer_feed_order_sum">×©×™× ×•×™ סדר ×”×ž×™× ×•×™×™× ×©×œ×š</string> + <string name="pref_nav_drawer_feed_counter_title">הגדרת ×ž×•× ×” ×ž×™× ×•×™×™×</string> + <string name="pref_set_theme_sum">×©×™× ×•×™ המר××” של ×× ×˜× ×”Ö¾×¤Ö¼×•Ö¹×“</string> <string name="pref_automatic_download_title">הורדה ×וטומטית</string> - <string name="pref_automatic_download_sum">הגדר הורדה ×טומטית של פרקי×.</string> - <string name="pref_autodl_wifi_filter_title">×פשר ×¡×™× ×•×Ÿ ××™× ×˜×¨× ×˜ ×לחוטי</string> - <string name="pref_autodl_wifi_filter_sum">×פשר הורדה ×וטומטית דרך רשתות ×לחוטייות × ×‘×—×¨×•×ª.</string> - <string name="pref_automatic_download_on_battery_title">הורדה ×›×©×œ× ×˜×•×¢×Ÿ</string> - <string name="pref_automatic_download_on_battery_sum">×פשר הורדה ×וטומטית כשהסוללה ××™× ×” × ×˜×¢× ×ª</string> + <string name="pref_automatic_download_sum">הגדרת הורדה ×טומטית של פרקי×.</string> + <string name="pref_autodl_wifi_filter_title">הפעלת ×¡×™× ×•×Ÿ רשתות ×לחוטיות</string> + <string name="pref_autodl_wifi_filter_sum">ל×פשר הורדה ×וטומטית רק דרך רשתות ×לחוטיות × ×‘×—×¨×•×ª.</string> + <string name="pref_autodl_allow_on_mobile_title">הורדה דרך רשת סלולרית</string> + <string name="pref_autodl_allow_on_mobile_sum">ל×פשר הורדה ×וטומטית דרך חיבור × ×ª×•× ×™× ×©×œ רשת סלולרית.</string> + <string name="pref_automatic_download_on_battery_title">להוריד ×©×œ× ×‘×–×ž×Ÿ ×˜×¢×™× ×”</string> + <string name="pref_automatic_download_on_battery_sum">ל×פשר הורדה ×וטומטית ×›×שר הסוללה ××™× ×” ×‘×˜×¢×™× ×”</string> <string name="pref_parallel_downloads_title">הורדות במקביל</string> <string name="pref_episode_cache_title">מטמון פרקי×</string> <string name="pref_theme_title_light">בהיר</string> @@ -252,128 +345,291 @@ <string name="pref_update_interval_hours_singular">שעה</string> <string name="pref_update_interval_hours_manual">×™×“× ×™</string> <string name="pref_gpodnet_authenticate_title">×›× ×™×¡×”</string> - <string name="pref_gpodnet_authenticate_sum">×›× ×¡ ×¢× ×—×©×‘×•×Ÿ gpodder.net שלך על ×ž× ×ª ×œ×¡× ×›×¨×Ÿ ×ת ההרשמות שלך.</string> - <string name="pref_gpodnet_logout_title">×”×ª× ×ª×§×•×ª</string> - <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_authenticate_sum">× ×™×ª×Ÿ ×œ×”×™×›× ×¡ ×œ×—×©×‘×•× ×š ב־gpodder.net כדי ×œ×¡× ×›×¨×Ÿ ×ת ×”×ž×™× ×•×™×™× ×©×œ×š.</string> + <string name="pref_gpodnet_logout_title">יצי××”</string> + <string name="pref_gpodnet_logout_toast">הצלחת לצ×ת</string> + <string name="pref_gpodnet_setlogin_information_title">×©×™× ×•×™ פרטי ×”×›× ×™×¡×”</string> + <string name="pref_gpodnet_setlogin_information_sum">×©×™× ×•×™ פרטי ×”×›× ×™×¡×” לחשבון ×”Ö¾gpodder.net שלך.</string> + <string name="pref_gpodnet_sync_changes_title">×¡× ×›×¨×•×Ÿ ×”×©×™× ×•×™×™× ×›×¢×ª</string> + <string name="pref_gpodnet_sync_changes_sum">×¡× ×›×¨×•×Ÿ ×©×™× ×•×™×™ מצב ×‘×ž×™× ×•×™×™× ×•×‘×¤×¨×§×™× ×ž×•×œ gpodder.net.</string> + <string name="pref_gpodnet_full_sync_title">×¡× ×›×¨×•×Ÿ ×ž×œ× ×›×¢×ª</string> + <string name="pref_gpodnet_full_sync_sum">×¡× ×›×¨×•×Ÿ כל ×”×ž×™× ×•×™×™× ×•×ž×¦×‘×™ ×”×¤×¨×§×™× ×¢× gpodder.net.</string> + <string name="pref_gpodnet_sync_sum_last_sync_line">× ×™×¡×™×•×Ÿ ×”×¡× ×›×¨×•×Ÿ ×”×חרון: %1$s (%2$s)</string> + <string name="pref_gpodnet_sync_started">×”×¡× ×›×¨×•×Ÿ התחיל</string> + <string name="pref_gpodnet_full_sync_started">החל ×¡× ×›×¨×•×Ÿ מל×</string> + <string name="pref_gpodnet_login_status"><![CDATA[× ×›× ×¡×ª ×‘×©× <i>%1$s</i> ×¢× ×”×”×ª×§×Ÿ <i>%2$s</i>]]></string> + <string name="pref_gpodnet_notifications_title">הצגת התרעות שגי×ות ×¡× ×›×¨×•×Ÿ</string> + <string name="pref_gpodnet_notifications_sum">הגדרה זו ××™× ×” חלה על שגי×ות ×ימות.</string> <string name="pref_playback_speed_title">מהירויות × ×™×’×•×Ÿ</string> - <string name="pref_playback_speed_sum">הת×מת המהיריות ×”×–×ž×™× ×•×ª ×œ× ×™×’×•×Ÿ במהירות ×ž×©×ª× ×”</string> - <string name="pref_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_persistNotify_sum">שמר בקרי הודעה ומסך × ×¢×™×œ×” בעת השהיית השמעה.</string> - <string name="pref_expand_notify_unsupport_toast">גרס×ות ×× ×“×¨×•×™×“ ×œ×¤× ×™ 4.1 ×œ× ×ª×•×ž×›×•×ª בהודעות מורחבות.</string> - <string name="pref_queueAddToFront_sum">הוסף ×¤×¨×§×™× ×—×“×©×™× ×œ×¨×ש התור.</string> - <string name="pref_queueAddToFront_title">הוסף לר×ש התור.</string> + <string name="pref_playback_speed_sum">בחירת המהירויות ×”×–×ž×™× ×•×ª למהירות × ×’×™× ×” ×ž×©×ª× ×”</string> + <string name="pref_fast_forward">זמן דילוג בה×צה קדימה</string> + <string name="pref_fast_forward_sum">הת×מת מספר ×”×©× ×™×•×ª של הקפיצה קדימה בעת לחיצה על כפתור ×”×”×צה</string> + <string name="pref_rewind">זמן בקפיצה ×חורה</string> + <string name="pref_rewind_sum">הת×מת מספר ×”×©× ×™×•×ª של הקפיצה ×חורה בעת לחיצה על כפתור החזרה</string> + <string name="pref_gpodnet_sethostname_title">הגדרת ×©× ×ž×רח</string> + <string name="pref_gpodnet_sethostname_use_default_host">שימוש ×‘×©× ×ž×רח כבררת מחדל</string> + <string name="pref_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> + <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_lockscreen_background_sum">הגדרת רקע מסך ×”× ×¢×™×œ×” ×œ×ª×ž×•× ×” של הפרק ×©×ž×ª× ×’×Ÿ כעת. כתופעת לוו××™, ×”×ª×ž×•× ×” תופיע ×’× ×‘×™×™×©×•×ž×™ צד שלישי.</string> + <string name="pref_showDownloadReport_title">הצגת דוח הורדה</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_smart_mark_as_played_disabled">מושבת</string> + <string name="pref_image_cache_size_title">גודל מטמון ×”×ª×ž×•× ×•×ª</string> + <string name="pref_image_cache_size_sum">×”× ×¤×— ×‘×›×•× ×Ÿ שעשוי לשמש למטמון של ×ª×ž×•× ×•×ª.</string> + <string name="crash_report_title">דיווח על קריסה</string> + <string name="crash_report_sum">שליחת דיווח הקריסה ×”×¢×“×›× ×™ ביותר דרך דו×״ל</string> + <string name="send_email">שליחת דו×״ל</string> + <string name="experimental_pref">× ×™×¡×™×•× ×™</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">שו״ת</string> + <string name="pref_known_issues">תקלות ידועות</string> + <string name="pref_no_browser_found">×œ× × ×ž×¦× ×“×¤×“×¤×Ÿ.</string> + <string name="pref_cast_title">תמיכה ב־Chromecast</string> + <string name="pref_cast_message_play_flavor">הפעלת תמיכה ×‘× ×’×™× ×ª מדיה על ×”×ª×§× ×™ שידור ×ž×¨×•×—×§×™× (כגון Chromecast, ×¨×ž×§×•×œ×™× ×“×™×’×™×˜×œ×™×™× ×ו Android TV)</string> + <string name="pref_cast_message_free_flavor">לתמיכה ב־Chromecast × ×“×¨×©×•×ª ספריות ×§× ×™×™× ×™×•×ª מ×ת צד־שלישי שמושבתות בגרסה זו של ×× ×˜× ×”Ö¾×¤Ö¼×•Ö¹×“</string> + <string name="pref_enqueue_downloaded_title">הוספת הורדות לתור</string> + <string name="pref_enqueue_downloaded_summary">הוספת ×¤×¨×§×™× ×©×”×ª×§×‘×œ×• לתור</string> <!--Auto-Flattr dialog--> - <string name="auto_flattr_enable">הפעל תרומות flattr ×וטומטיות</string> - <string name="auto_flattr_after_percent">×ª×¨×•× ×‘×מצעות flattr ×›×©× ×•×’×Ÿ %d ××—×•×–×™× ×ž×”×¤×¨×§</string> - <string name="auto_flattr_ater_beginning">×ª×¨×•× ×‘×מצעות flattr ×›×©× ×™×’×•×Ÿ פרק מתחיל</string> - <string name="auto_flattr_ater_end">×ª×¨×•× ×‘×מצעות flattr ×›×©× ×™×’×•×Ÿ פרק מסתיי×</string> + <string name="auto_flattr_enable">הפעלת תרומות Flattr ×וטומטיות</string> + <string name="auto_flattr_after_percent">×œ×ª×¨×•× ×œ×¤×¨×§ ×›×שר ×”×ª× ×’× ×• %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_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_explanation_1">בחר × ×ª×™×‘ קובץ ספציפי במערכת ×”×§×‘×¦×™× ×”×ž×§×•×ž×™×ª.</string> - <string name="opml_import_explanation_2">השתמש ×‘×™×™×©×•×ž×™× ×—×™×¦×•× ×™×™× ×›×ž×• Dropbox, Google Drive ×ו ×ž× ×”×œ ×”×§×‘×¦×™× ×”×הוב עליך לפתוח קובץ OPML.</string> - <string name="opml_import_explanation_3">×™×™×©×•×ž×™× ×¨×‘×™× ×›×ž×• Google Mail, Dropbox, Google Drive ורוב ×ž× ×”×œ×™ ×”×§×‘×¦×™× ×™×›×•×œ×™× <i>לפתוח</i> קבצי OPML <i>×¢×</i> ×× ×˜× ×”-פוד.</string> - <string name="start_import_label">התחל יבו×</string> - <string name="opml_import_label">×™×‘×•× OPML</string> + <string name="opml_import_txtv_button_lable">קובצי OPML מ××¤×©×¨×™× ×œ×š להעביר ×ת הפודק××¡×˜×™× ×©×œ×š ממכשיר ×חד ×œ×ž×©× ×”×•.</string> + <string name="opml_import_option">×פשרות %1$d</string> + <string name="opml_import_explanation_1">× × ×œ×‘×—×•×¨ × ×ª×™×‘ קובץ ×ž×¡×•×™× ×ž×ž×¢×¨×›×ª ×”×§×‘×¦×™× ×”×ž×§×•×ž×™×ª.</string> + <string name="opml_import_explanation_2">× ×™×ª×Ÿ להשתמש ×‘×™×™×©×•×ž×™× ×—×™×¦×•× ×™×™× ×›×ž×• Dropbox,†Google Drive ×ו ×ž× ×”×œ ×”×§×‘×¦×™× ×”×ž×•×¢×“×£ עליך כדי לפתוח קובץ OPML.</string> + <string name="opml_import_explanation_3">×™×™×©×•×ž×™× ×¨×‘×™× ×›×’×•×Ÿ Google Mail,†Dropbox,†Google Drive ורוב ×ž× ×”×œ×™ ×”×§×‘×¦×™× ×™×›×•×œ×™× <i>לפתוח</i> קובצי OPML <i>×¢×</i> ×× ×˜× ×”Ö¾×¤Ö¼×•Ö¹×“.</string> + <string name="start_import_label">התחלת ייבו×</string> + <string name="opml_import_label">×™×™×‘×•× OPML</string> <string name="opml_directory_error">שגי××”!</string> - <string name="reading_opml_label">×§×•×¨× ×§×•×‘×¥ OPML</string> - <string name="select_all_label">בחר הכל</string> - <string name="deselect_all_label">בטל בחירות</string> + <string name="reading_opml_label">קרי×ת קובץ OPML</string> + <string name="opml_reader_error">×ירעה שגי××” בעת קרי×ת מסמך ×”Ö¾OPML:</string> + <string name="opml_import_error_no_file">×œ× × ×‘×—×¨ קובץ!</string> + <string name="select_all_label">בחירת הכול</string> + <string name="deselect_all_label">ביטול הבחירה</string> + <string name="select_options_label">בחירה…</string> <string name="choose_file_from_filesystem">ממערכת ×”×§×‘×¦×™× ×”×ž×§×•×ž×™×ª</string> - <string name="choose_file_from_external_application">השתמש ב×פליקציה ×—×™×¦×•× ×™×ª</string> - <string name="opml_export_label">×™×¦×•× OPML</string> - <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="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="export_success_title">×”×™×™×¦×•× ×”×¦×œ×™×—</string> + <string name="export_success_sum">הקובץ ×©×™×™×•×¦× × ×›×ª×‘ ×ל:\n\n%1$s</string> + <string name="opml_import_ask_read_permission">× ×“×¨×©×ª גישה ל×חסון ×—×™×¦×•× ×™ כדי ×œ×§×¨×•× ×ת קובץ ×”Ö¾OPML</string> <!--Sleep timer--> - <string name="set_sleeptimer_label">קבע טיימר ×©×™× ×”</string> - <string name="disable_sleeptimer_label">בטל טיימר ×©×™× ×”</string> - <string name="enter_time_here_label">קבע זמן</string> - <string name="sleep_timer_label">טיימר ×©×™× ×”</string> - <string name="time_left_label">זמן × ×•×ª×¨:\u0020</string> - <string name="time_dialog_invalid_input">קלט ×œ× ×—×•×§×™, זמן חייב להיות מספר של×</string> + <string name="set_sleeptimer_label">הגדרת מתזמן ×©×™× ×”</string> + <string name="disable_sleeptimer_label">השבתת מתזמן ×©×™× ×”</string> + <string name="enter_time_here_label">הגדרת שעה</string> + <string name="sleep_timer_label">מתזמן ×©×™× ×”</string> + <string name="time_left_label">זמן ×©× ×•×ª×¨:\u0020</string> + <string name="time_dialog_invalid_input">קלט שגוי, השעה חייב להיות מספר ×©×œ× ×•×—×™×•×‘×™</string> + <string name="timer_about_to_expire_label"><b>×›×שר ספירת המתזמן עומדת להסתיי×:</b></string> + <string name="shake_to_reset_label">לשקשק כדי ל×פס ×ת המתזמן</string> + <string name="timer_vibration_label">לרטוט</string> + <string name="time_seconds">×©× ×™×•×ª</string> + <string name="time_minutes">דקות</string> + <string name="time_hours">שעות</string> + <plurals name="time_seconds_quantified"> + <item quantity="one">×©× ×™×™×” ×חת</item> + <item quantity="two">%d ×©× ×™×•×ª</item> + <item quantity="many">%d ×©× ×™×•×ª</item> + <item quantity="other">%d ×©× ×™×•×ª</item> + </plurals> + <plurals name="time_minutes_quantified"> + <item quantity="one">דקה ×חת</item> + <item quantity="two">%d דקות</item> + <item quantity="many">%d דקות</item> + <item quantity="other">%d דקות</item> + </plurals> + <plurals name="time_hours_quantified"> + <item quantity="one">שעה</item> + <item quantity="two">שעתיי×</item> + <item quantity="many">%d שעות</item> + <item quantity="other">%d שעות</item> + </plurals> + <string name="auto_enable_label">הפעלה ×וטומטית</string> + <string name="sleep_timer_enabled_label">מתזמן ×”×©×™× ×” פעיל</string> + <string name="sleep_timer_disabled_label">מתזמן ×”×©×™× ×” מושבת</string> <!--gpodder.net--> <string name="gpodnet_taglist_header">קטגוריות</string> - <string name="gpodnet_toplist_header">פודק××¡×˜×™× ×‘×›×™×¨×™×</string> + <string name="gpodnet_toplist_header">פודק××¡×˜×™× ×ž×•×‘×™×œ×™×</string> <string name="gpodnet_suggestions_header">המלצות</string> - <string name="gpodnet_search_hint">חפש ב-gpodder.net</string> - <string name="gpodnetauth_login_title">התחברות</string> - <string name="gpodnetauth_login_descr">ברוך ×”×‘× ×œ×”×ª×—×‘×¨×•×ª ל-gpodder.net. ר×שית, הקלד ×ת פרטי ×”×›× ×™×¡×” שלך:</string> - <string name="gpodnetauth_login_butLabel">התחברות</string> - <string name="gpodnetauth_login_register">×× ×ין לך עדיין חשבון, תוכל לפתוח ×חד דרך: \nhttps://gpodder.net/register/</string> - <string name="username_label">×©× ×ž×©×ª×ž×©:</string> - <string name="password_label">ססמה:</string> + <string name="gpodnet_search_hint">חיפוש ב־gpodder.net</string> + <string name="gpodnetauth_login_title">×›× ×™×¡×”</string> + <string name="gpodnetauth_login_descr">ברוך בו×ך לתהליך ×”×›× ×™×¡×” ל־gpodder.net. ר×שית, עליך להקליד ×ת פרטי ×”×›× ×™×¡×” שלך:</string> + <string name="gpodnetauth_login_butLabel">×›× ×™×¡×”</string> + <string name="gpodnetauth_login_register">×× ×¢×“×™×™×Ÿ ×ין לך חשבון, × ×™×ª×Ÿ ליצור ×חד ×›×ן:‎\nhttps://gpodder.net/register/‎</string> + <string name="username_label">×©× ×ž×©×ª×ž×©</string> + <string name="password_label">ססמה</string> <string name="gpodnetauth_device_title">בחירת מכשיר</string> - <string name="gpodnetauth_device_descr">צור מכשיר חדש לשימוש עבור חשבון gpodder.net ×ו לבחר ×חד קיי×:</string> + <string name="gpodnetauth_device_descr">× ×™×ª×Ÿ ליצור התקן חדש לשימוש ×¢× ×”×—×©×‘×•×Ÿ שלך ב־gpodder.net ×ו לבחור בהתקן חדש:</string> <string name="gpodnetauth_device_deviceID">מזהה מכשיר:\u0020</string> <string name="gpodnetauth_device_caption">כותרת</string> - <string name="gpodnetauth_device_butCreateNewDevice">צור מכשיר חדש</string> - <string name="gpodnetauth_device_chooseExistingDevice">בחר מכשיר קיי×:</string> - <string name="gpodnetauth_device_errorEmpty">מזהה המכשיר ××™× ×• יכול להיות ריק</string> - <string name="gpodnetauth_device_errorAlreadyUsed">מזהה המכשיר בשימוש</string> - <string name="gpodnetauth_device_butChoose">בחר</string> - <string name="gpodnetauth_finish_title">התחברות מוצלחת!</string> - <string name="gpodnetauth_finish_descr">מזל טוב! חשבון gpodder.net שלך מקושר כעת ×¢× ×”×ž×›×©×™×¨ שלך. ×× ×˜× ×”-פוד מעתה ×™×¡× ×›×¨×Ÿ ב×ופן ×וטומטי הרשמות במכשיר שלך ×¢× ×—×©×‘×•×Ÿ gpodder.net שלך.</string> - <string name="gpodnetauth_finish_butsyncnow">התחל ×¡× ×›×¨×•×Ÿ כעת</string> - <string name="gpodnetauth_finish_butgomainscreen">עבור למסך הר×שי</string> - <string name="gpodnetsync_auth_error_title">שגי×ת ×ימות של gpodder.net</string> + <string name="gpodnetauth_device_butCreateNewDevice">יצירת מכשיר חדש</string> + <string name="gpodnetauth_device_chooseExistingDevice">בחירת מכשיר קיי×:</string> + <string name="gpodnetauth_device_errorEmpty">מזהה המכשיר ×œ× ×™×›×•×œ להיש×ר ריק</string> + <string name="gpodnetauth_device_errorAlreadyUsed">מזהה המכשיר כבר בשימוש</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 שלך מקושר כעת ×¢× ×”×ž×›×©×™×¨ שלך. מעתה כל ×”×ž×™× ×•×™×™× ×©×œ×š ×™×¡×•× ×›×¨× ×• ×וטומטית על ידי ×× ×˜× ×”Ö¾×¤Ö¼×•Ö¹×“ מהמכשיר שלך לחשבון ×”Ö¾gpodder.net שלך.</string> + <string name="gpodnetauth_finish_butsyncnow">התחלת ×¡× ×›×¨×•×Ÿ כעת</string> + <string name="gpodnetauth_finish_butgomainscreen">מעבר למסך הר×שי</string> + <string name="gpodnetsync_auth_error_title">שגי×ת ×ימות מול gpodder.net</string> <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_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> + <string name="selected_folder_label">תיקייה × ×‘×—×¨×ª:</string> + <string name="create_folder_label">יצירת תיקייה</string> <string name="choose_data_directory">בחר תיקיית מידע</string> - <string name="create_folder_msg">צור תיקיה חדשה ×‘×©× \"%1$s\"?</string> - <string name="create_folder_success">תיקיה חדשה × ×•×¦×¨×”</string> - <string name="create_folder_error_no_write_access">×œ× × ×™×ª×Ÿ לכתוב לתיקה זו</string> - <string name="create_folder_error_already_exists">תיקה כבר קיימת</string> - <string name="create_folder_error">×œ× × ×™×ª×Ÿ ליצור תיקיה</string> - <string name="folder_not_empty_dialog_title">התיקיה ××™× ×” ריקה</string> - <string name="folder_not_empty_dialog_msg">התיקייה שבחרת ××™× ×” ריקה. הורדות מדיה ×•×§×‘×¦×™× ××—×¨×™× ×™×”×™×• ממוקמות ישירות בתיקייה זו. להמשיך בכל ×–×ת?</string> - <string name="set_to_default_folder">בחר תיקיית ברירת מחדל</string> - <string name="pref_pausePlaybackForFocusLoss_sum">השהה × ×™×’×•×Ÿ ×‘×ž×§×•× ×”×—×œ×©×ª עוצמת שמע כש×פליקציה ×חרת ×ž× ×’× ×ª</string> - <string name="pref_pausePlaybackForFocusLoss_title">השהה בזמן הפרעה</string> + <string name="choose_data_directory_message">× × ×œ×‘×—×•×¨ ×ת בסיס תיקיית ×”× ×ª×•× ×™× ×©×œ×š. תת־התיקיות ×ª×™×•×•×¦×¨× ×” על ידי ×× ×˜× ×”Ö¾×¤Ö¼×•Ö¹×“ בהת××.</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> + <string name="create_folder_error_already_exists">התיקייה כבר קיימת</string> + <string name="create_folder_error">×œ× × ×™×ª×Ÿ ליצור תיקייה</string> + <string name="folder_does_not_exist_error">„%1$sâ€ ×œ× ×§×™×™×</string> + <string name="folder_not_readable_error">„%1$s†××™× ×• קרי×</string> + <string name="folder_not_writable_error">„%1$sâ€ ×—×¡×•× ×œ×›×ª×™×‘×”</string> + <string name="folder_not_empty_dialog_title">התיקייה ××™× ×” ריקה</string> + <string name="folder_not_empty_dialog_msg">התיקייה שבחרת ××™× ×” ריקה. הורדות מדיה ×•×§×‘×¦×™× ××—×¨×™× ×™×ž×•×§×ž×• ישירות בתיקייה זו. להמשיך בכל ×–×ת?</string> + <string name="set_to_default_folder">× × ×œ×‘×—×•×¨ תיקיית בררת מחדל</string> + <string name="pref_pausePlaybackForFocusLoss_sum">השהיית ×”× ×™×’×•×Ÿ ×‘×ž×§×•× ×”× ×ž×›×ª עצמת השמע ×›×שר יישומון ×חר ×ž×¢×•× ×™×™×Ÿ ×œ× ×’×Ÿ צלילי×</string> + <string name="pref_pausePlaybackForFocusLoss_title">להשהות במהלך הפרעות</string> + <string name="pref_resumeAfterCall_sum">להמשיך ×‘× ×’×™× ×” ל×חר השלמת שיחת הטלפון</string> + <string name="pref_resumeAfterCall_title">להמשיך ל×חר שיחה</string> + <string name="pref_restart_required">יש להפעיל ×ת ×× ×˜× ×”Ö¾×¤Ö¼×•Ö¹×“ מחדש כדי ×©×”×©×™× ×•×™×™× ×™×™×›× ×¡×• לתוקף.</string> <!--Online feed view--> - <string name="subscribe_label">הרש×</string> - <string name="subscribed_label">× ×¨×©×</string> + <string name="subscribe_label">הרשמה</string> + <string name="subscribed_label">× ×¨×©×ž×ª</string> + <string name="downloading_label">מתבצעת הורדה…</string> <!--Content descriptions for image buttons--> - <string name="rewind_label">דלג ל×חור</string> - <string name="fast_forward_label">הרץ קדימה</string> + <string name="rewind_label">חזרה ל×חור</string> + <string name="fast_forward_label">הרצה קדימה</string> <string name="media_type_audio_label">שמע</string> <string name="media_type_video_label">ויד×ו</string> - <string name="navigate_upwards_label">× ×•×•×˜ למעלה</string> + <string name="navigate_upwards_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> + <string name="load_next_page_label">×˜×¢×™× ×ª הדף הב×</string> <!--Feed information screen--> <string name="authentication_label">×ימות</string> - <string name="authentication_descr">×©× ×” ×ת ×©× ×”×ž×©×ª×ž×© והסיסמה שלך לפודק×סט ×•×¤×¨×§×™× ×©×œ×•.</string> + <string name="authentication_descr">×©×™× ×•×™ ×©× ×”×ž×©×ª×ž×© והססמה שלך לפודק×סט ×”×–×” ×•×œ×¤×¨×§×™× ×©×œ×•.</string> + <string name="auto_download_settings_label">הגדרות הורדה ×וטומטית</string> + <string name="episode_filters_label">×ž×¡× ×Ÿ פרקי×</string> + <string name="episode_filters_description">רשימת ×”×ž×•× ×—×™× ×‘×”× ×™×¢×©×” שימוש כדי להחליט ×× ×œ×”×›×œ×™×œ ×ו להחריג פרק כלשהו במהלך הורדה ×וטומטית</string> + <string name="episode_filters_include">להכליל</string> + <string name="episode_filters_exclude">להחריג</string> + <string name="episode_filters_hint">×ž×™×œ×™× ×‘×•×“×“×•×ª \n\"×וסף מילי×\"</string> + <string name="keep_updated">לשמור על ×¢×“×›× ×™×•×ª</string> <!--Progress information--> + <string name="progress_upgrading_database">מסד ×”× ×ª×•× ×™× ×ž×©×ª×“×¨×’</string> <!--AntennaPodSP--> - <string name="sp_apps_importing_feeds_msg">×ž×™×™×‘× ×¨×™×©×•× ×ž×פליקציות יעודיות...</string> - <string name="search_itunes_label">חפש בiTunes</string> + <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> + <string name="none_label">לל×</string> + <string name="deselected_all_label">××£ פרק ×œ× × ×‘×—×¨</string> + <string name="played_label">× ×•×’× ×•</string> + <string name="selected_played_label">בחירת ×¤×¨×§×™× ×©× ×•×’× ×•</string> + <string name="unplayed_label">×œ× × ×•×’× ×•</string> + <string name="selected_unplayed_label">בחירת ×¤×¨×§×™× ×©×œ× × ×•×’× ×•</string> + <string name="downloaded_label">הורדו</string> + <string name="selected_downloaded_label">בחירת ×¤×¨×§×™× ×©×”×•×¨×“×•</string> + <string name="not_downloaded_label">×œ× ×”×•×¨×“×•</string> + <string name="selected_not_downloaded_label">בחירת ×¤×¨×§×™× ×©×œ× ×”×•×¨×“×•</string> + <string name="queued_label">בתור</string> + <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> + <string name="sort_date_new_old">ת×ריך (חדש \u2192 ישן)</string> + <string name="sort_date_old_new">ת×ריך (ישן \u2192 חדש)</string> + <string name="sort_duration_short_long">משך (קצר \u2192 ×רוך)</string> + <string name="sort_duration_long_short">משך (קצר \u2192 ×רוך)</string> <!--Rating dialog--> - <string name="rating_title">××•×”×‘×™× ×ת ×”×פליקציה?</string> + <string name="rating_title">היישומון ×× ×˜× ×”Ö¾×¤Ö¼×•Ö¹×“ × ×•×©× ×—×Ÿ ×‘×¢×™× ×™×š?</string> + <string name="rating_message">מ×וד × ×©×ž×— לקבל דירוג על ×× ×˜× ×”Ö¾×¤Ö¼×•Ö¹×“ ×× ×™×© לך זמן לכך.</string> <string name="rating_never_label">×œ× ×ª×•×“×”</string> <string name="rating_later_label">×¤×¢× ×חרת</string> - <string name="rating_now_label">בטח!</string> + <string name="rating_now_label">בטח, × ×œ×š על ×–×”!</string> <!--Audio controls--> + <string name="audio_controls">פקדי שמע</string> + <string name="playback_speed">מהירות × ×’×™× ×”</string> + <string name="volume">עצמת שמע</string> + <string name="left_short">L</string> + <string name="right_short">R</string> + <string name="audio_effects">××¤×§×˜×™× ×©×œ שמע</string> + <string name="stereo_to_mono">×יחוד: סטרי×ו ×œ×ž×•× ×•</string> + <string name="sonic_only">Sonic בלבד</string> <!--proxy settings--> + <string name="proxy_type_label">סוג</string> + <string name="host_label">מ×רח</string> + <string name="port_label">פתחה</string> + <string name="optional_hint">(רשות)</string> + <string name="proxy_test_label">בדיקה</string> + <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> <!--Database import/export--> + <string name="import_export">ייבו×/×™×™×¦×•× ×ž×¡×“ × ×ª×•× ×™×</string> + <string name="import_export_warning">×ª×›×•× ×” × ×™×¡×™×•× ×™×ª זו יכולה לשמש לטובת העברת ×”×ž×™× ×•×™×™× ×•×”×¤×¨×§×™× ×©× ×™×’× ×ª להתקן ×חר.\n\n× ×™×ª×Ÿ ×œ×™×™×‘× ×ž×¡×“×™ × ×ª×•× ×™× ×©×™×•×¦×ו רק ל×ותה הגרסה של ×× ×˜× ×”Ö¾×¤Ö¼×•Ö¹×“. ×חרת, ×ª×›×•× ×” זו עשויה לגרור ×”×ª× ×”×’×•×ª בלתי צפויה.\n\nל×חר הייבו×, יתכן שחלק ×ž×”×¤×¨×§×™× ×™×•×¤×™×¢×• ×›×ילו כבר הורדת ××•×ª× ×œ×ž×¨×•×ª שבפועל ×œ× ×¢×©×™×ª ×–×ת. עליך פשוט ללחוץ על כפתור ×”× ×’×™× ×” של ×”×¤×¨×§×™× ×›×“×™ ש×× ×˜× ×”Ö¾×¤Ö¼×•Ö¹×“ יוכל לזהות ×–×ת.</string> + <string name="label_import">ייבו×</string> + <string name="label_export">ייצו×</string> + <string name="import_select_file">בחירת קובץ לייבו×</string> + <string name="export_ok">×”×™×™×¦×•× ×”×¦×œ×™×—.</string> + <string name="import_ok">×”×™×™×‘×•× ×”×¦×œ×™×—.\n\n× × ×œ×œ×—×•×¥ על ×ישור כדי להפעיל ×ת ×× ×˜× ×”Ö¾×¤Ö¼×•Ö¹×“ מחדש</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> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-ja/strings.xml b/core/src/main/res/values-ja/strings.xml index c5ea6357f..566817243 100644 --- a/core/src/main/res/values-ja/strings.xml +++ b/core/src/main/res/values-ja/strings.xml @@ -1,11 +1,13 @@ <?xml version='1.0' encoding='UTF-8'?> <resources xmlns:tools="http://schemas.android.com/tools"> <!--Activitiy and fragment titles--> + <string name="feed_update_receiver_name">è³¼èªã‚’æ›´æ–°</string> <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="new_episodes_label">æ–°è¦</string> <string name="favorite_episodes_label">ãŠæ°—ã«å…¥ã‚Š</string> <string name="new_label">æ–°</string> <string name="settings_label">è¨å®š</string> @@ -18,10 +20,12 @@ <string name="cancel_download_label">ダウンãƒãƒ¼ãƒ‰ã‚’ã‚ャンセル</string> <string name="playback_history_label">å†ç”Ÿå±¥æ´</string> <string name="gpodnet_main_label">gpodder.net</string> + <string name="gpodnet_summary">ä»–ã®ãƒ‡ãƒã‚¤ã‚¹ã¨åŒæœŸ</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> + <string name="synchronizing">åŒæœŸã—ã¦ã„ã¾ã™â€¦</string> <!--Statistics fragment--> <string name="total_time_listened_to_podcasts">ãƒãƒƒãƒ‰ã‚ャストをå†ç”Ÿã—ãŸåˆè¨ˆæ™‚é–“:</string> <string name="statistics_details_dialog">%2$d ã‹ã‚‰ %1$d ã®ã‚¨ãƒ”ソードãŒé–‹å§‹ã—ã¾ã—ãŸã€‚\n\n%4$s ã‹ã‚‰%3$s ã‚’å†ç”Ÿã—ã¾ã—ãŸã€‚</string> @@ -63,6 +67,7 @@ <string name="cover_label">æ˜ åƒ</string> <string name="error_label">エラー</string> <string name="error_msg_prefix">エラーãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚</string> + <string name="needs_storage_permission">ã“ã®æ“作ã«ã¯ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã®ã‚¢ã‚¯ã‚»ã‚¹è¨±å¯ãŒå¿…è¦ã§ã™</string> <string name="refresh_label">æ›´æ–°</string> <string name="external_storage_error_msg">外部ストレージãŒåˆ©ç”¨ã§ãã¾ã›ã‚“。アプリãŒæ£å¸¸ã«å‹•ä½œã§ãるよã†ã«ã€å¤–部ストレージãŒãƒžã‚¦ãƒ³ãƒˆã•ã‚Œã¦ã„ã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。</string> <string name="chapters_label">ãƒãƒ£ãƒ—ター</string> @@ -104,25 +109,28 @@ <string name="mark_all_read_label">ã™ã¹ã¦å†ç”Ÿæ¸ˆã¨ã—ã¦ãƒžãƒ¼ã‚¯</string> <string name="mark_all_read_msg">ã™ã¹ã¦ã®ã‚¨ãƒ”ソードをå†ç”Ÿæ¸ˆã«ã—ã¾ã—ãŸ</string> <string name="mark_all_read_confirmation_msg">å†ç”Ÿæ¸ˆã¨ã—ã¦ãƒžãƒ¼ã‚¯ã™ã‚‹ã™ã¹ã¦ã®ã‚¨ãƒ”ソードを確èªã—ã¦ãã ã•ã„。</string> - <string name="mark_all_read_feed_confirmation_msg">å†ç”Ÿæ¸ˆã¨ã—ã¦ãƒžãƒ¼ã‚¯ã™ã‚‹ã“ã®ãƒ•ã‚£ãƒ¼ãƒ‰ã®ã™ã¹ã¦ã®ã‚¨ãƒ”ソードを確èªã—ã¦ãã ã•ã„。</string> + <string name="mark_all_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="show_feed_settings_label">ãƒãƒƒãƒ‰ã‚ャストè¨å®šã‚’表示</string> + <string name="feed_info_label">ãƒãƒƒãƒ‰ã‚ãƒ£ã‚¹ãƒˆæƒ…å ±</string> + <string name="feed_settings_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> + <string name="share_link_label">エピソード URLを共有</string> + <string name="share_link_with_position_label">エピソード URL ã‚’ä½ç½®ã¨å…±ã«å…±æœ‰</string> <string name="share_file_label">ファイルを共有</string> - <string name="share_link_with_position_label">å ´æ‰€ã¨ãƒªãƒ³ã‚¯ã‚’共有</string> <string name="share_feed_url_label">フィード URLを共有</string> - <string name="share_item_url_label">エピソードファイル URLを共有</string> - <string name="share_item_url_with_position_label">エピソードファイル URL ã‚’ä½ç½®ã¨å…±ã«å…±æœ‰</string> - <string name="feed_delete_confirmation_msg">フィード \"%1$s\" ã¨ã€ã“ã®ãƒ•ã‚£ãƒ¼ãƒ‰ã®ã™ã¹ã¦ã®ãƒ€ã‚¦ãƒ³ãƒãƒ¼ãƒ‰ã—ãŸã‚¨ãƒ”ソードを削除ã™ã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。</string> - <string name="feed_remover_msg">フィードã®å‰Šé™¤ä¸</string> - <string name="load_complete_feed">フィードをã™ã¹ã¦æ›´æ–°</string> + <string name="share_item_url_label">メディアファイル URLを共有</string> + <string name="share_item_url_with_position_label">メディアファイル URL ã‚’ä½ç½®ã¨å…±ã«å…±æœ‰</string> + <string name="feed_delete_confirmation_msg">ãƒãƒƒãƒ‰ã‚ャスト \"%1$s\" ã¨ã™ã¹ã¦ã®ï¼ˆãƒ€ã‚¦ãƒ³ãƒãƒ¼ãƒ‰æ¸ˆã‚’å«ã‚€ï¼‰ã‚¨ãƒ”ソードを削除ã™ã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。</string> + <string name="feed_remover_msg">ãƒãƒƒãƒ‰ã‚ャストを削除ã—ã¦ã„ã¾ã™</string> + <string name="load_complete_feed">ãƒãƒƒãƒ‰ã‚ャストをã™ã¹ã¦æ›´æ–°</string> <string name="hide_episodes_title">エピソードをéžè¡¨ç¤ºã«ã™ã‚‹</string> - <string name="episode_actions">æ“作をé©ç”¨</string> + <string name="batch_edit">一括編集</string> <string name="hide_unplayed_episodes_label">未å†ç”Ÿ</string> <string name="hide_paused_episodes_label">一時åœæ¢ã—ã¾ã—ãŸ</string> <string name="hide_played_episodes_label">å†ç”Ÿã—ã¾ã—ãŸ</string> @@ -131,6 +139,7 @@ <string name="hide_downloaded_episodes_label">ダウンãƒãƒ¼ãƒ‰ã—ã¾ã—ãŸ</string> <string name="hide_not_downloaded_episodes_label">ダウンãƒãƒ¼ãƒ‰ã—ã¦ã„ã¾ã›ã‚“</string> <string name="hide_has_media_label">メディアã‚ã‚Š</string> + <string name="hide_is_favorite_label">ãŠæ°—ã«å…¥ã‚Š</string> <string name="filtered_label">フィルターã—ã¾ã—ãŸ</string> <string name="refresh_failed_msg">{fa-exclamation-circle} å‰å›žæ›´æ–°ã«å¤±æ•—ã—ã¾ã—ãŸ</string> <string name="open_podcast">ãƒãƒƒãƒ‰ã‚ャストを開ã</string> @@ -144,6 +153,7 @@ <string name="delete_label">削除</string> <string name="delete_failed">ファイルを削除ã§ãã¾ã›ã‚“。デãƒã‚¤ã‚¹ã‚’å†èµ·å‹•ã—ã¦ã¿ã¦ãã ã•ã„。</string> <string name="remove_episode_lable">エピソードを削除</string> + <string name="mark_as_seen_label">å‚照済</string> <string name="marked_as_seen_label">å‚照済ã¨ã—ã¦ãƒžãƒ¼ã‚¯</string> <string name="mark_read_label">å†ç”Ÿæ¸ˆã¨ã—ã¦ãƒžãƒ¼ã‚¯</string> <string name="marked_as_read_label">å†ç”Ÿæ¸ˆã¨ã—ã¦ãƒžãƒ¼ã‚¯ã—ã¾ã—ãŸ</string> @@ -167,6 +177,8 @@ <string name="download_failed">失敗</string> <string name="download_pending">ダウンãƒãƒ¼ãƒ‰ã¯ä¿ç•™ä¸</string> <string name="download_running">ダウンãƒãƒ¼ãƒ‰å®Ÿè¡Œä¸</string> + <string name="download_error_details">詳細</string> + <string name="download_error_details_message">%1$s \n\nファイル URL:\n%2$s</string> <string name="download_error_device_not_found">ストレージ デãƒã‚¤ã‚¹ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“</string> <string name="download_error_insufficient_space">スペースãŒä¸è¶³ã—ã¦ã„ã¾ã™</string> <string name="download_error_file_error">ファイルエラー</string> @@ -216,6 +228,7 @@ <string name="playback_error_unknown">ä¸æ˜Žãªã‚¨ãƒ©ãƒ¼</string> <string name="no_media_playing_label">å†ç”Ÿã™ã‚‹ãƒ¡ãƒ‡ã‚£ã‚¢ãŒã‚ã‚Šã¾ã›ã‚“</string> <string name="player_buffering_msg">ãƒãƒƒãƒ•ã‚¡ãƒ¼ä¸</string> + <string name="player_go_to_picture_in_picture">ピクãƒãƒ£-イン-ピクãƒãƒ£ モード</string> <string name="playbackservice_notification_title">ãƒãƒƒãƒ‰ã‚ャストをå†ç”Ÿä¸</string> <string name="unknown_media_key">AntennaPod - ä¸æ˜Žãªãƒ¡ãƒ‡ã‚£ã‚¢ã‚ー: %1$d</string> <!--Queue operations--> @@ -232,7 +245,9 @@ <string name="date">日付</string> <string name="duration">継続時間</string> <string name="episode_title">エピソード タイトル</string> - <string name="feed_title">フィード タイトル</string> + <string name="feed_title">ãƒãƒƒãƒ‰ã‚ャストã®ã‚¿ã‚¤ãƒˆãƒ«</string> + <string name="random">ランダム</string> + <string name="smart_shuffle">スマートシャッフル</string> <string name="ascending">æ˜‡é †</string> <string name="descending">é™é †</string> <string name="clear_queue_confirmation_msg">クリアã™ã‚‹ã€ã‚ューã«å«ã¾ã‚Œã‚‹ã™ã¹ã¦ã®ã‚¨ãƒ”ソードを確èªã—ã¦ãã ã•ã„。</string> @@ -270,7 +285,7 @@ <string name="enable_sonic">Sonic を有効ã«ã™ã‚‹</string> <!--Empty list labels--> <string name="no_items_label">ã“ã®ãƒªã‚¹ãƒˆã«ã¯ã‚¢ã‚¤ãƒ†ãƒ ãŒã‚ã‚Šã¾ã›ã‚“。</string> - <string name="no_feeds_label">ã¾ã フィードを何も購èªã—ã¦ã„ã¾ã›ã‚“。</string> + <string name="no_feeds_label">ã¾ã ãƒãƒƒãƒ‰ã‚ャストを何も購èªã—ã¦ã„ã¾ã›ã‚“。</string> <string name="no_chapters_label">ã“ã®ã‚¨ãƒ”ソードã«ãƒãƒ£ãƒ—ターã¯ã‚ã‚Šã¾ã›ã‚“。</string> <string name="no_shownotes_label">ã“ã®ã‚¨ãƒ”ソードã«ã‚·ãƒ§ãƒ¼ãƒŽãƒ¼ãƒˆã¯ã‚ã‚Šã¾ã›ã‚“。</string> <!--Preferences--> @@ -279,15 +294,23 @@ <string name="other_pref">ãã®ä»–</string> <string name="about_pref">ã«ã¤ã„ã¦</string> <string name="queue_label">ã‚ュー</string> - <string name="services_label">サービス</string> + <string name="integrations_label">çµ±åˆ</string> <string name="flattr_label">Flattr</string> + <string name="flattr_summary">マイクãƒãƒšã‚¤ãƒ¡ãƒ³ãƒˆ サービス</string> + <string name="automation">自動</string> + <string name="download_pref_details">詳細</string> + <string name="import_export_pref">インãƒãƒ¼ãƒˆ/エクスãƒãƒ¼ãƒˆ</string> + <string name="appearance">外観</string> + <string name="external_elements">外部è¦ç´ </string> + <string name="interruptions">割り込ã¿</string> + <string name="buttons">å†ç”Ÿã‚³ãƒ³ãƒˆãƒãƒ¼ãƒ«ãƒœã‚¿ãƒ³</string> + <string name="media_player">メディアプレーヤー</string> <string name="pref_episode_cleanup_title">エピソード クリーンアップ</string> <string name="pref_episode_cleanup_summary">ã‚ューã«å«ã¾ã‚Œã¦ãŠã‚‰ãšã€ãŠæ°—ã«å…¥ã‚Šã§ã¯ãªã„エピソードã¯ã€è‡ªå‹•ãƒ€ã‚¦ãƒ³ãƒãƒ¼ãƒ‰ã§æ–°ã—ã„エピソードã®ãŸã‚ã«ã‚¹ãƒšãƒ¼ã‚¹ãŒå¿…è¦ãªå ´åˆã€é™¤åŽ»ã®å¯¾è±¡ã«ãªã‚Šã¾ã™</string> <string name="pref_pauseOnDisconnect_sum">ヘッドフォンã¾ãŸã¯Bluetoothã®æŽ¥ç¶šãŒåˆ‡æ–ã•ã‚ŒãŸæ™‚ã€å†ç”Ÿã‚’一時åœæ¢ã—ã¾ã™</string> <string name="pref_unpauseOnHeadsetReconnect_sum">ヘッドフォンãŒå†æŽ¥ç¶šã•ã‚ŒãŸæ™‚ã«å†ç”Ÿã‚’å†é–‹ã—ã¾ã™</string> <string name="pref_unpauseOnBluetoothReconnect_sum">BluetoothãŒå†æŽ¥ç¶šã•ã‚ŒãŸæ™‚ã«å†ç”Ÿã‚’å†é–‹ã—ã¾ã™</string> <string name="pref_hardwareForwardButtonSkips_title">æ—©é€ã‚Šãƒœã‚¿ãƒ³ã§ã‚¹ã‚ップ</string> - <string name="pref_hardwareForwardButtonSkips_sum">ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ã®æ—©é€ã‚Šãƒœã‚¿ãƒ³ã‚’押ã—ãŸã¨ãã«ã€æ—©é€ã‚Šã®ä»£ã‚ã‚Šã«æ¬¡ã®ã‚¨ãƒ”ソードã«ã‚¹ã‚ップã—ã¾ã™</string> <string name="pref_hardwarePreviousButtonRestarts_title">戻るボタンã§å†é–‹</string> <string name="pref_hardwarePreviousButtonRestarts_sum">ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ã®æˆ»ã‚‹ãƒœã‚¿ãƒ³ã‚’押ã—ãŸã¨ãã«ã€å·»ã戻ã—ã®ä»£ã‚ã‚Šã«ç¾åœ¨ã®ã‚¨ãƒ”ソードã®å†ç”Ÿã‚’å†é–‹ã—ã¾ã™</string> <string name="pref_followQueue_sum">å†ç”ŸãŒå®Œäº†ã—ãŸæ™‚ã«æ¬¡ã®ã‚ューã®ã‚¢ã‚¤ãƒ†ãƒ ã«ç§»å‹•ã—ã¾ã™</string> @@ -336,7 +359,7 @@ <string name="pref_nav_drawer_feed_order_title">è³¼èªæ³¨æ–‡ã‚’セット</string> <string name="pref_nav_drawer_feed_order_sum">è³¼èªã®æ³¨æ–‡ã‚’変更ã—ã¾ã™</string> <string name="pref_nav_drawer_feed_counter_title">è³¼èªã‚«ã‚¦ãƒ³ã‚¿ãƒ¼ã‚’セット</string> - <string name="pref_nav_drawer_feed_counter_sum">è³¼èªã‚«ã‚¦ãƒ³ã‚¿ãƒ¼ã§è¡¨ç¤ºã•ã‚Œã‚‹æƒ…å ±ã‚’å¤‰æ›´ã—ã¾ã™</string> + <string name="pref_nav_drawer_feed_counter_sum">è³¼èªã‚«ã‚¦ãƒ³ã‚¿ãƒ¼ã«è¡¨ç¤ºã•ã‚Œã‚‹æƒ…å ±ã‚’å¤‰æ›´ã—ã¾ã™ã€‚ \'è³¼èªé †\' ㌠\'カウンター\' ã«è¨å®šã•ã‚Œã¦ã„ã‚‹å ´åˆã¯ã€è³¼èªã®ä¸¦ã³æ›¿ãˆã«ã‚‚影響ã—ã¾ã™ã€‚</string> <string name="pref_set_theme_sum">AntennaPodã®å¤–観を変更ã—ã¾ã™ã€‚</string> <string name="pref_automatic_download_title">自動ダウンãƒãƒ¼ãƒ‰</string> <string name="pref_automatic_download_sum">エピソードã®è‡ªå‹•ãƒ€ã‚¦ãƒ³ãƒãƒ¼ãƒ‰ã‚’構æˆã—ã¾ã™ã€‚</string> @@ -350,6 +373,7 @@ <string name="pref_episode_cache_title">エピソードã‚ャッシュ</string> <string name="pref_theme_title_light">ライト</string> <string name="pref_theme_title_dark">ダーク</string> + <string name="pref_theme_title_trueblack">é»’ (AMOLED 対応)</string> <string name="pref_episode_cache_unlimited">無制é™</string> <string name="pref_update_interval_hours_plural">時間</string> <string name="pref_update_interval_hours_singular">時間</string> @@ -378,8 +402,6 @@ <string name="pref_rewind_sum">å·»ã戻ã—ボタンãŒã‚¯ãƒªãƒƒã‚¯ã•ã‚ŒãŸã¨ãã«å¾Œæ–¹ã«ã‚¸ãƒ£ãƒ³ãƒ—ã™ã‚‹ç§’数をカスタマイズã—ã¾ã™</string> <string name="pref_gpodnet_sethostname_title">ホストåをセット</string> <string name="pref_gpodnet_sethostname_use_default_host">デフォルトホストを使用</string> - <string name="pref_expandNotify_title">拡張通知</string> - <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> @@ -400,8 +422,7 @@ <string name="crash_report_sum">メールã§æœ€æ–°ã®ã‚¯ãƒ©ãƒƒã‚·ãƒ¥ãƒ¬ãƒãƒ¼ãƒˆã‚’é€ä¿¡ã—ã¾ã™</string> <string name="send_email">メールをé€ä¿¡</string> <string name="experimental_pref">実験的</string> - <string name="pref_sonic_title">Sonic メディアプレーヤー</string> - <string name="pref_sonic_message">Android 標準ã®ãƒ¡ãƒ‡ã‚£ã‚¢ãƒ—レーヤー㨠Prestissimo ã®ä»£ã‚ã‚Šã«ã€å†…蔵ã®ã‚½ãƒ‹ãƒƒã‚¯ãƒ¡ãƒ‡ã‚£ã‚¢ãƒ—レーヤーを使用ã—ã¾ã™</string> + <string name="pref_media_player_message">ファイルをå†ç”Ÿã™ã‚‹ãƒ¡ãƒ‡ã‚£ã‚¢ãƒ—レーヤーをé¸æŠž</string> <string name="pref_current_value">ç¾åœ¨ã®å€¤: %1$s</string> <string name="pref_proxy_title">プãƒã‚ã‚·</string> <string name="pref_proxy_sum">ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ プãƒã‚ã‚·ã®è¨å®š</string> @@ -413,6 +434,11 @@ <string name="pref_cast_message_free_flavor">Chromecast 㯠AntennaPod ã®ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ç„¡åŠ¹ã«ãªã£ã¦ã„るサードパーティ独自ã®ãƒ©ã‚¤ãƒ–ラリーãŒå¿…è¦ã§ã™</string> <string name="pref_enqueue_downloaded_title">ダウンãƒãƒ¼ãƒ‰ã®ã‚ューã«å…¥ã‚Œã‚‹</string> <string name="pref_enqueue_downloaded_summary">ダウンãƒãƒ¼ãƒ‰ã—ãŸã‚¨ãƒ”ソードをã‚ューã«è¿½åŠ ã—ã¾ã™</string> + <string name="media_player_builtin">ビルトイン Android プレーヤー</string> + <string name="pref_videoBehavior_title">ビデオ終了時</string> + <string name="pref_videoBehavior_sum">ビデオå†ç”Ÿã‹ã‚‰é·ç§»æ™‚ã®å‹•ä½œ</string> + <string name="stop_playback">å†ç”Ÿåœæ¢</string> + <string name="continue_playback">音声ã®å†ç”Ÿã‚’続ã‘ã‚‹</string> <!--Auto-Flattr dialog--> <string name="auto_flattr_enable">自動Flattrを有効ã«ã™ã‚‹</string> <string name="auto_flattr_after_percent">%d ï¼…å†ç”Ÿã—ãŸã‚‰ã‚¨ãƒ”ソードをFlattr </string> @@ -423,7 +449,7 @@ <string name="found_in_shownotes_label">ショーノートã§è¦‹ã¤ã‹ã‚Šã¾ã—ãŸ</string> <string name="found_in_chapters_label">ãƒãƒ£ãƒ—ターã§è¦‹ã¤ã‹ã‚Šã¾ã—ãŸ</string> <string name="found_in_authors_label">作者ã§è¦‹ã¤ã‹ã‚Šã¾ã—ãŸ</string> - <string name="found_in_feeds_label">フィードã§è¦‹ã¤ã‹ã‚Šã¾ã—ãŸ</string> + <string name="found_in_feeds_label">ãƒãƒƒãƒ‰ã‚ャストã§è¦‹ã¤ã‹ã‚Šã¾ã—ãŸ</string> <string name="search_status_no_results">見ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ</string> <string name="search_label">検索</string> <string name="found_in_title_label">タイトルã§è¦‹ã¤ã‹ã‚Šã¾ã—ãŸ</string> @@ -449,8 +475,8 @@ <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> - <string name="opml_export_success_sum">.opml ファイルを書ãè¾¼ã¿ã¾ã—ãŸ:\u0020</string> + <string name="export_success_title">エクスãƒãƒ¼ãƒˆã—ã¾ã—ãŸ</string> + <string name="export_success_sum">エクスãƒãƒ¼ãƒˆã—ãŸãƒ•ã‚¡ã‚¤ãƒ«ã‚’書ãè¾¼ã¿ã¾ã—ãŸ:\n\n%1$s</string> <string name="opml_import_ask_read_permission">OPML ファイルをèªã¿è¾¼ã‚€ãŸã‚ã«ã€å¤–部ストレージã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒå¿…è¦ã§ã™</string> <!--Sleep timer--> <string name="set_sleeptimer_label">スリープタイマーをセット</string> @@ -620,7 +646,7 @@ <string name="label_import">インãƒãƒ¼ãƒˆ</string> <string name="label_export">エクスãƒãƒ¼ãƒˆ</string> <string name="import_select_file">インãƒãƒ¼ãƒˆã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠžã—ã¦ãã ã•ã„</string> - <string name="export_ok">エクスãƒãƒ¼ãƒˆãŒæˆåŠŸã—ã¾ã—ãŸã€‚データベースã¯SDカードã«æ›¸ãè¾¼ã¾ã‚Œã¾ã—ãŸã€‚</string> + <string name="export_ok">エクスãƒãƒ¼ãƒˆã—ã¾ã—ãŸã€‚</string> <string name="import_ok">インãƒãƒ¼ãƒˆãŒæˆåŠŸã—ã¾ã—ãŸã€‚\n\nOKを押ã—ã¦AntennaPodã‚’å†èµ·å‹•ã—ã¦ãã ã•ã„。</string> <!--Casting--> <string name="cast_media_route_menu_title">…ã§å†ç”Ÿ</string> @@ -638,4 +664,13 @@ <string name="cast_failed_seek">ã‚ャストデãƒã‚¤ã‚¹ã®æ–°ã—ã„ä½ç½®ã¸ã®ç§»å‹•ã«å¤±æ•—ã—ã¾ã—ãŸ</string> <string name="cast_failed_receiver_player_error">レシーãƒãƒ¼ãƒ—レーヤーã§æ·±åˆ»ãªã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ</string> <string name="cast_failed_media_error_skipping">メディアã®å†ç”Ÿæ™‚ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚スã‚ップã—ã¦ã„ã¾ã™â€¦</string> + <!--Notification channels--> + <string name="notification_channel_user_action">æ“作ãŒå¿…è¦</string> + <string name="notification_channel_user_action_description">ãŸã¨ãˆã°ãƒ‘スワードを入力ã™ã‚‹å¿…è¦ãŒã‚ã‚‹å ´åˆãªã©ã€æ“作ãŒå¿…è¦ãªå ´åˆã«è¡¨ç¤ºã•ã‚Œã¾ã™ã€‚</string> + <string name="notification_channel_downloading">ダウンãƒãƒ¼ãƒ‰ä¸</string> + <string name="notification_channel_downloading_description">ç¾åœ¨ã®ãƒ€ã‚¦ãƒ³ãƒãƒ¼ãƒ‰ãŒè¡¨ç¤ºã•ã‚Œã¾ã™ã€‚</string> + <string name="notification_channel_playing">ç¾åœ¨å†ç”Ÿä¸</string> + <string name="notification_channel_playing_description">å†ç”Ÿã‚’コントãƒãƒ¼ãƒ«ã§ãã¾ã™ã€‚ã“ã‚Œã¯ãƒãƒƒãƒ‰ã‚ャストå†ç”Ÿä¸ã®ãƒ¡ã‚¤ãƒ³é€šçŸ¥ã§ã™ã€‚</string> + <string name="notification_channel_error">エラー</string> + <string name="notification_channel_error_description">ダウンãƒãƒ¼ãƒ‰ã‚„ gpodder ã®åŒæœŸã«å¤±æ•—ã—ãŸå ´åˆãªã©ã€ä½•ã‹å•é¡ŒãŒç™ºç”Ÿã—ãŸå ´åˆã«è¡¨ç¤ºã•ã‚Œã¾ã™ã€‚</string> </resources> diff --git a/core/src/main/res/values-kn-rIN/strings.xml b/core/src/main/res/values-kn-rIN/strings.xml index f62c6b2de..14ccf4e42 100644 --- a/core/src/main/res/values-kn-rIN/strings.xml +++ b/core/src/main/res/values-kn-rIN/strings.xml @@ -101,4 +101,5 @@ <!--Database import/export--> <!--Casting--> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-ko-rKR/strings.xml b/core/src/main/res/values-ko-rKR/strings.xml index acf3abe75..2d9481b84 100644 --- a/core/src/main/res/values-ko-rKR/strings.xml +++ b/core/src/main/res/values-ko-rKR/strings.xml @@ -36,4 +36,5 @@ <!--Database import/export--> <!--Casting--> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-ko/strings.xml b/core/src/main/res/values-ko/strings.xml index a3ec4de96..c776885ea 100644 --- a/core/src/main/res/values-ko/strings.xml +++ b/core/src/main/res/values-ko/strings.xml @@ -122,7 +122,6 @@ <string name="feed_remover_msg">피드 ì‚ì œí•˜ëŠ” 중</string> <string name="load_complete_feed">ì „ì²´ 피드 ìƒˆë¡œê³ ì¹¨</string> <string name="hide_episodes_title">ì—피소드 ê°ì¶”기</string> - <string name="episode_actions">ë™ìž‘ ì ìš©</string> <string name="hide_unplayed_episodes_label">ìž¬ìƒ ì•ˆ 함</string> <string name="hide_paused_episodes_label">ì¼ì‹œ 중지</string> <string name="hide_played_episodes_label">재ìƒí•¨</string> @@ -167,6 +166,8 @@ <string name="download_failed">실패</string> <string name="download_pending">다운로드 지연 중</string> <string name="download_running">다운로드 실행 중</string> + <string name="download_error_details">ìžì„¸ížˆ</string> + <string name="download_error_details_message">%1$s \n\níŒŒì¼ URL:\n%2$s</string> <string name="download_error_device_not_found">ì €ìž¥ 장치가 없습니다</string> <string name="download_error_insufficient_space">ì €ìž¥ ê³µê°„ì´ ë¶€ì¡±í•©ë‹ˆë‹¤</string> <string name="download_error_file_error">íŒŒì¼ ì˜¤ë¥˜</string> @@ -279,7 +280,6 @@ <string name="other_pref">기타</string> <string name="about_pref">ì •ë³´</string> <string name="queue_label">대기열</string> - <string name="services_label">서비스</string> <string name="flattr_label">Flattr</string> <string name="pref_episode_cleanup_title">ì—피소드 ì •ë¦¬</string> <string name="pref_episode_cleanup_summary">ëŒ€ê¸°ì—´ì— ì—†ê³ ì¦ê²¨ì°¾ê¸°ì— 넣지 ì•Šì€ ì—피소드는 ìžë™ 다운로드ì—ì„œ 새 ì—í”¼ì†Œë“œì— ê³µê°„ì´ í•„ìš”í• ê²½ìš° ì œê±°ë 수 있습니다.</string> @@ -400,8 +400,6 @@ <string name="crash_report_sum">ìµœê·¼ì˜ ì´ìƒ 종료 ë³´ê³ ì„œë¥¼ ì´ë©”ì¼ë¡œ 보냅니다.</string> <string name="send_email">ì´ë©”ì¼ ë³´ë‚´ê¸°</string> <string name="experimental_pref">실험ì 기능</string> - <string name="pref_sonic_title">소닉 미디어 í”Œë ˆì´ì–´</string> - <string name="pref_sonic_message">내장 소닉 미디어 í”Œë ˆì´ì–´ë¥¼ 안드로ì´ë“œ ê³ ìœ ë¯¸ë””ì–´ í”Œë ˆì´ì–´ì™€ Prestissimo ëŒ€ì‹ ì‚¬ìš©í•©ë‹ˆë‹¤.</string> <string name="pref_current_value">현재 ê°’: %1$s</string> <string name="pref_proxy_title">프ë¡ì‹œ</string> <string name="pref_proxy_sum">ë„¤íŠ¸ì›Œí¬ í”„ë¡ì‹œ ì„¤ì •</string> @@ -449,8 +447,8 @@ <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> - <string name="opml_export_success_sum">OPML 파ì¼ì„ 다ìŒì— ì €ìž¥í–ˆìŠµë‹ˆë‹¤:\u0020</string> + <string name="export_success_title">내보내기 성공</string> + <string name="export_success_sum">내보낸 파ì¼ì„ 다ìŒì— ì €ìž¥í–ˆìŠµë‹ˆë‹¤:\n\n%1$s</string> <string name="opml_import_ask_read_permission">OPML 파ì¼ì„ ì½ìœ¼ë ¤ë©´ 외부 ì €ìž¥ì†Œ ì ‘ê·¼ì´ í•„ìš”í•©ë‹ˆë‹¤</string> <!--Sleep timer--> <string name="set_sleeptimer_label">취침 타ì´ë¨¸ ì„¤ì •</string> @@ -615,6 +613,13 @@ <string name="proxy_host_invalid_error">호스트가 올바른 IP 주소 ë˜ëŠ” ë„ë©”ì¸ì´ 아닙니다</string> <string name="proxy_port_invalid_error">í¬íŠ¸ê°€ 올바르지 않습니다</string> <!--Database import/export--> + <string name="import_export">ë°ì´í„°ë² ì´ìŠ¤ ê°€ì ¸ì˜¤ê¸°/내보내기</string> + <string name="import_export_warning">실험ì ì¸ ê¸°ëŠ¥ìœ¼ë¡œ êµ¬ë… ì •ë³´ì™€ 재ìƒí•œ ì—피소드 ì •ë³´ë¥¼ 다른 장치로 ì˜®ê¸°ëŠ”ë° ì‚¬ìš©í•©ë‹ˆë‹¤.\n\n내보낸 ë°ì´í„°ë² ì´ìŠ¤ëŠ” ê°™ì€ ë²„ì „ì˜ ì•ˆí…Œë‚˜íŒŸì„ ì‚¬ìš©í• ê²½ìš°ì—만 ê°€ì ¸ì˜¬ 수 있습니다. ê°™ì€ ë²„ì „ì´ ì•„ë‹ˆë©´ 예ìƒì¹˜ 못하게 ë™ìž‘í• ìˆ˜ 있습니다.\n\nê°€ì ¸ì˜¨ í›„ì— ë‹¤ìš´ë¡œë“œí•˜ì§€ ì•Šì€ ì—피소드가 다운로드한 것으로 표시ë 수 있습니다. ê·¸ 경우 해당 ì—í”¼ì†Œë“œì˜ ìž¬ìƒ ë²„íŠ¼ì„ ëˆ„ë¥´ë©´ 안테나팟ì—ì„œ 다운로드 여부를 확ì¸í•´ ì¤ë‹ˆë‹¤.</string> + <string name="label_import">ê°€ì ¸ì˜¤ê¸°</string> + <string name="label_export">내보내기</string> + <string name="import_select_file">ê°€ì ¸ì˜¬ 파ì¼ì„ ì„ íƒí•˜ì‹ì‹œì˜¤</string> + <string name="export_ok">내보내기 성공</string> + <string name="import_ok">내보내기 성공.\n\nì•ˆí…Œë‚˜íŒŸì„ ë‹¤ì‹œ ì‹œìž‘í•˜ë ¤ë©´ 확ì¸ì„ 누르ì‹ì‹œì˜¤</string> <!--Casting--> <string name="cast_media_route_menu_title">다른 장치ì—ì„œ 재ìƒ...</string> <string name="cast_disconnect_label">ìºìŠ¤íŠ¸ 세션 ì—°ê²° ëŠê¸°</string> @@ -631,4 +636,5 @@ <string name="cast_failed_seek">ìºìŠ¤íŠ¸ ìž¥ì¹˜ì— ìƒˆ ìž¬ìƒ ìœ„ì¹˜ë¡œ ì´ë™í•˜ëŠ”ë° ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤</string> <string name="cast_failed_receiver_player_error">리시버 í”Œë ˆì´ì–´ì—ì„œ 심ê°í•œ 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤</string> <string name="cast_failed_media_error_skipping">미디어 재ìƒì— 오류. 건너ëœë‹ˆë‹¤...</string> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-lt/strings.xml b/core/src/main/res/values-lt/strings.xml index 7736c148b..3ca4270ce 100644 --- a/core/src/main/res/values-lt/strings.xml +++ b/core/src/main/res/values-lt/strings.xml @@ -1,11 +1,13 @@ <?xml version='1.0' encoding='UTF-8'?> <resources xmlns:tools="http://schemas.android.com/tools"> <!--Activitiy and fragment titles--> + <string name="feed_update_receiver_name">Atnaujinti prenumeratas</string> <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="new_episodes_label">Nauji</string> <string name="favorite_episodes_label">MÄ—giami</string> <string name="new_label">Nauji</string> <string name="settings_label">Nustatymai</string> @@ -56,7 +58,7 @@ <string name="yes">Taip</string> <string name="no">Ne</string> <string name="reset">Nustatyti iÅ¡ naujo</string> - <string name="author_label">Autorius</string> + <string name="author_label">Autorius (-iai)</string> <string name="language_label">Kalba</string> <string name="url_label">URL</string> <string name="podcast_settings_label">Nustatymai</string> @@ -93,6 +95,7 @@ <plurals name="episode_cleanup_days_after_listening"> <item quantity="one">PraÄ—jus 1 dienai nuo perklausymo</item> <item quantity="few">PraÄ—jus %d dienoms nuo perklausymo</item> + <item quantity="many">PraÄ—jus %d dienų nuo perklausymo</item> <item quantity="other">PraÄ—jus %d dienų nuo perklausymo</item> </plurals> <!--'Add Feed' Activity labels--> @@ -106,25 +109,21 @@ <string name="mark_all_read_label">PažymÄ—ti visus kaip perklausytus</string> <string name="mark_all_read_msg">Visi epizodai pažymÄ—ti kaip perklausyti</string> <string name="mark_all_read_confirmation_msg">Patvirtinkite, jog norite pažymÄ—ti visus epizodus kaip perklausytus.</string> - <string name="mark_all_read_feed_confirmation_msg">Patvirtinkite, jog norite pažymÄ—ti visus Å¡io sklaidos kanalo epizodus kaip perklausytus.</string> <string name="mark_all_seen_label">PažymÄ—ti visus kaip matytus</string> - <string name="mark_all_seen_msg">Visi epizodai pažymÄ—ti kaip matyti</string> + <string name="mark_all_seen_msg">PažymÄ—ti visus epizodus kaip matytus</string> <string name="mark_all_seen_confirmation_msg">Patvirtinkite, jog norite pažymÄ—ti visus epizodus kaip matytus.</string> <string name="show_info_label">Rodyti informacijÄ…</string> + <string name="feed_info_label">TinklalaidÄ—s informacija</string> <string name="rename_feed_label">Pervadinti tinklalaidÄ™</string> <string name="remove_feed_label">PaÅ¡alinti tinklalaidÄ™</string> <string name="share_label">Dalintis...</string> - <string name="share_link_label">Dalintis nuoroda</string> + <string name="share_link_label">Dalintis epizodo URL</string> + <string name="share_link_with_position_label">Dalintis epizodo URL su pozicija</string> <string name="share_file_label">Dalintis failu</string> - <string name="share_link_with_position_label">Dalintis nuoroda su pozicija</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="share_item_url_with_position_label">Dalintis epizodo failo adresu su pozicija</string> - <string name="feed_delete_confirmation_msg">Patvirtinkite, jog norite iÅ¡trinti sklaidos kanalÄ… „%1$s“ bei VISUS atsisiųstus Å¡io sklaidos kanalo epizodus.</string> - <string name="feed_remover_msg">Å alinamas sklaidos kanalas</string> - <string name="load_complete_feed">Atnaujinti visÄ… sklaidos kanalÄ…</string> + <string name="share_item_url_label">Dalintis medijos failo URL</string> + <string name="share_item_url_with_position_label">Dalintis medijos failo adresu su pozicija</string> <string name="hide_episodes_title">SlÄ—pti epizodus</string> - <string name="episode_actions">Pritaikyti veiksmus</string> <string name="hide_unplayed_episodes_label">Neperklausyti</string> <string name="hide_paused_episodes_label">Pristabdyti</string> <string name="hide_played_episodes_label">Perklausyti</string> @@ -193,6 +192,7 @@ <plurals name="downloads_left"> <item quantity="one">Liko %d atsiuntimas</item> <item quantity="few">Liko %d atsiuntimai</item> + <item quantity="many">Liko %d atsiuntimų</item> <item quantity="other">Liko %d atsiuntimų</item> </plurals> <string name="downloads_processing">Apdorojami atsiuntimai</string> @@ -236,7 +236,7 @@ <string name="date">Data</string> <string name="duration">TrukmÄ—</string> <string name="episode_title">Epizodo pavadinimas</string> - <string name="feed_title">Sklaidos kanalo pavadinimas</string> + <string name="feed_title">TinklalaidÄ—s pavadinimas</string> <string name="ascending">DidÄ—janÄia tvarka</string> <string name="descending">MažėjanÄia tvarka</string> <string name="clear_queue_confirmation_msg">Patvirtinkite, jog norite paÅ¡alinti VISUS epizodus iÅ¡ perklausos eilÄ—s</string> @@ -274,7 +274,6 @@ <string name="enable_sonic">Ä®jungti „Sonic“</string> <!--Empty list labels--> <string name="no_items_label">Å iame sÄ…raÅ¡e nÄ—ra elementų.</string> - <string name="no_feeds_label">Kol kas neprenumeruojate jokio sklaidos kanalo.</string> <string name="no_chapters_label">Å is epizodas neturi skyrių.</string> <string name="no_shownotes_label">Å is epizodas neturi užrašų.</string> <!--Preferences--> @@ -283,15 +282,16 @@ <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="integrations_label">Integracijos</string> <string name="flattr_label">Flattr</string> + <string name="appearance">IÅ¡vaizda</string> + <string name="media_player">Medijos grotuvas</string> <string name="pref_episode_cleanup_title">Epizodų valymas</string> <string name="pref_episode_cleanup_summary">Epizodai, nesantys eilÄ—je ar tarp mÄ—giamųjų, gali bÅ«ti iÅ¡trinti automatinio atsiuntimo metu pritrÅ«kus laisvos vietos naujiems epizodams </string> <string name="pref_pauseOnDisconnect_sum">Pristabdyti atkÅ«rimÄ…, kai atjungiamos ausinÄ—s ar „Bluetooth“</string> <string name="pref_unpauseOnHeadsetReconnect_sum">PratÄ™sti atkÅ«rimÄ…, kai ausinÄ—s pakartotinai prijungiamos</string> <string name="pref_unpauseOnBluetoothReconnect_sum">PratÄ™sti atkÅ«rimÄ…, kai pakartotinai prisijungiama prie „Bluetooth“</string> <string name="pref_hardwareForwardButtonSkips_title">Mygtukas „pirmyn“ perÅ¡oka epizodÄ…</string> - <string name="pref_hardwareForwardButtonSkips_sum">Paspaudus aparatinį mygtukÄ… „pirmyn“ perÅ¡okti į kitÄ… epizodÄ… vietoje greito persukimo į priekį.</string> <string name="pref_hardwarePreviousButtonRestarts_title">Mygtukas „ankstesnis“ paleidžia iÅ¡ naujo</string> <string name="pref_hardwarePreviousButtonRestarts_sum">Paspaudus aparatinį mygtukÄ… „ankstesnis“ paleisti dabartinį epizodÄ… nuo pradžių vietoj epizodo perÅ¡okimo</string> <string name="pref_followQueue_sum">AtkÅ«rimui pasibaigus perÅ¡okti į kitÄ… eilÄ—s elementÄ…</string> @@ -340,7 +340,6 @@ <string name="pref_nav_drawer_feed_order_title">Nustatyti prenumeratų tvarkÄ…</string> <string name="pref_nav_drawer_feed_order_sum">Keiskite prenumeratų tvarkÄ…</string> <string name="pref_nav_drawer_feed_counter_title">Nustatyti prenumeratų skaitliukÄ…</string> - <string name="pref_nav_drawer_feed_counter_sum">Keisti prenumeratų skaitliuko rodomÄ… informacijÄ…</string> <string name="pref_set_theme_sum">Keisti AntennaPod iÅ¡vaizdÄ….</string> <string name="pref_automatic_download_title">Automatinis atsiuntimas</string> <string name="pref_automatic_download_sum">KonfigÅ«ruoti automatinį epizodų atsiuntimÄ….</string> @@ -382,8 +381,6 @@ <string name="pref_rewind_sum">Derinkite, per kiek sekundžių Å¡oktelÄ—ti atgal kai paspaudžiamas atsukimo atgal mygtukas</string> <string name="pref_gpodnet_sethostname_title">Nustatyti serverį</string> <string name="pref_gpodnet_sethostname_use_default_host">Naudoti numatytÄ…jį serverį</string> - <string name="pref_expandNotify_title">IÅ¡plÄ—sti praneÅ¡imus</string> - <string name="pref_expandNotify_sum">IÅ¡plÄ—sti programos praneÅ¡imus, kad bÅ«tų atvaizduojami atkÅ«rimo valdymo mygtukai.</string> <string name="pref_persistNotify_title">PastovÅ«s atkÅ«rimo valdikliai</string> <string name="pref_persistNotify_sum">Pristabdžius atkÅ«rimÄ… palikti valdiklius ekrano užrakte bei programų praneÅ¡imuose. </string> <string name="pref_compact_notification_buttons_title">Nustatyti ekrano užrakto mygtukus</string> @@ -404,8 +401,6 @@ <string name="crash_report_sum">Siųsti paskiausios strigties praneÅ¡imÄ… el. paÅ¡tu</string> <string name="send_email">Siųsti el. laiÅ¡kÄ…</string> <string name="experimental_pref">Eksperimentinis</string> - <string name="pref_sonic_title">„Sonic“ medijos leistuvÄ—</string> - <string name="pref_sonic_message">Naudoti įtaisytÄ…jÄ… „Sonic“ medijos leistuvÄ™ vietoje savosios „Android“ medijos leistuvÄ—s ir „Prestissimo“ </string> <string name="pref_current_value">DabartinÄ— reikÅ¡mÄ—: %1$s</string> <string name="pref_proxy_title">Ä®galiotasis serveris</string> <string name="pref_proxy_sum">Nustatyti įgaliotÄ…jį tinklo serverį</string> @@ -426,8 +421,6 @@ <string name="search_hint">IeÅ¡koti epizodų</string> <string name="found_in_shownotes_label">Rasta laidos užraÅ¡uose</string> <string name="found_in_chapters_label">Rasta skyriuose</string> - <string name="found_in_authors_label">Rasta autoriuose</string> - <string name="found_in_feeds_label">Rasta sklaidos kanaluose</string> <string name="search_status_no_results">Nieko nerasta</string> <string name="search_label">PaieÅ¡ka</string> <string name="found_in_title_label">Rasta pavadinime</string> @@ -453,8 +446,6 @@ <string name="html_export_label">HTML eksportas</string> <string name="exporting_label">Eksportuojama...</string> <string name="export_error_label">Eksporto klaida</string> - <string name="opml_export_success_title">OPML eksportas sÄ—kmingas.</string> - <string name="opml_export_success_sum">.opml failas iÅ¡saugotas į:\u0020</string> <string name="opml_import_ask_read_permission">Norint nuskaityti OPML failÄ… reikalinga prieiga prie neÅ¡iojamos atmintinÄ—s</string> <!--Sleep timer--> <string name="set_sleeptimer_label">Nustatyti miego laikmatį</string> @@ -472,16 +463,19 @@ <plurals name="time_seconds_quantified"> <item quantity="one">1 sekundÄ—</item> <item quantity="few">%d sekundÄ—s</item> + <item quantity="many">%d sekundžių</item> <item quantity="other">%d sekundžių</item> </plurals> <plurals name="time_minutes_quantified"> <item quantity="one">1 minutÄ—</item> <item quantity="few">%d minutÄ—s</item> + <item quantity="many">%d minuÄių</item> <item quantity="other">%d minuÄių</item> </plurals> <plurals name="time_hours_quantified"> <item quantity="one">1 valanda</item> <item quantity="few">%d valandos</item> + <item quantity="many">%d valandų</item> <item quantity="other">%d valandų</item> </plurals> <string name="auto_enable_label">Ä®jungti automatiÅ¡kai</string> @@ -634,7 +628,6 @@ Po importavimo, epizodai gali bÅ«ti per klaidÄ… pažymÄ—ti kaip atsisiųsti. Tie <string name="label_import">Importuoti</string> <string name="label_export">Eksportuoti</string> <string name="import_select_file">Pasirinkite failÄ…, kurį norite importuoti</string> - <string name="export_ok">Eksportas sÄ—kmingas. Duomenų bazÄ— iÅ¡saugota SD kortelÄ—je.</string> <string name="import_ok">Importuota sÄ—kmingai. Spauskite „OK“, kad paleisti „AntennaPod“ iÅ¡ naujo.</string> @@ -654,4 +647,7 @@ Spauskite „OK“, kad paleisti „AntennaPod“ iÅ¡ naujo.</string> <string name="cast_failed_seek">PerÅ¡okti į naujÄ… pozicijÄ… „Chromecast“ įrenginyje nepavyko</string> <string name="cast_failed_receiver_player_error">Imtuvo leistuvÄ™ iÅ¡tiko rimta klaida</string> <string name="cast_failed_media_error_skipping">Ä®vyko medijos atkÅ«rimo klaida. Praleidžiama...</string> + <!--Notification channels--> + <string name="notification_channel_downloading">AtsiunÄiama</string> + <string name="notification_channel_error">Klaidos</string> </resources> diff --git a/core/src/main/res/values-mk/strings.xml b/core/src/main/res/values-mk/strings.xml new file mode 100644 index 000000000..1bb5aa651 --- /dev/null +++ b/core/src/main/res/values-mk/strings.xml @@ -0,0 +1,54 @@ +<?xml version='1.0' encoding='UTF-8'?> +<resources xmlns:tools="http://schemas.android.com/tools"> + <!--Activitiy and fragment titles--> + <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="new_episodes_label">Ðови</string> + <string name="favorite_episodes_label">Омилени</string> + <!--Statistics fragment--> + <!--Main activity--> + <!--Webview actions--> + <!--Playback history--> + <!--Other--> + <string name="no">Ðе</string> + <string name="reset">РеÑет</string> + <string name="author_label">Ðвтор</string> + <string name="language_label">Јазик</string> + <string name="url_label">УРЛ</string> + <string name="chapters_label">Поглавја</string> + <!--'Add Feed' Activity labels--> + <!--Actions on feeds--> + <!--actions on feeditems--> + <string name="delete_label">Избриши</string> + <!--Download messages and labels--> + <!--Mediaplayer messages--> + <!--Queue operations--> + <string name="date">Датум</string> + <!--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--> + <!--Database import/export--> + <!--Casting--> + <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> +</resources> diff --git a/core/src/main/res/values-nb/strings.xml b/core/src/main/res/values-nb/strings.xml index 65dc5565b..dafc7eb60 100644 --- a/core/src/main/res/values-nb/strings.xml +++ b/core/src/main/res/values-nb/strings.xml @@ -42,7 +42,6 @@ <string name="cancel_label">Avbryt</string> <string name="yes">Ja</string> <string name="no">Nei</string> - <string name="author_label">Opphavsperson</string> <string name="language_label">SprÃ¥k</string> <string name="url_label">URL</string> <string name="podcast_settings_label">Innstillinger</string> @@ -85,17 +84,10 @@ <string name="mark_all_read_label">Marker alle som avspilt</string> <string name="mark_all_read_msg">Marker alle episoder som avspilt</string> <string name="mark_all_read_confirmation_msg">Vennligst bekreft at du ønsker Ã¥ markere alle episoder som avspilt.</string> - <string name="mark_all_read_feed_confirmation_msg">Vennligst bekreft at du ønsker Ã¥ markere alle episoder i denne strømmen som avspilt.</string> <string name="mark_all_seen_label">Marker alle som sett</string> <string name="show_info_label">Vis informasjon</string> - <string name="remove_feed_label">Fjern podcast</string> - <string name="share_link_label">Del lenke</string> - <string name="share_link_with_position_label">Del lenke med plassering</string> <string name="share_feed_url_label">Del strømmens URL</string> - <string name="feed_remover_msg">Fjerner strøm</string> - <string name="load_complete_feed">Oppdater hele strømmen</string> <string name="hide_episodes_title">Skjul episoder</string> - <string name="episode_actions">Lagre handlinger</string> <string name="hide_unplayed_episodes_label">Ikke avspilt</string> <string name="hide_paused_episodes_label">Pauset</string> <string name="hide_played_episodes_label">Avspilt</string> @@ -226,18 +218,15 @@ <string name="enable_sonic">Skru pÃ¥ Sonic</string> <!--Empty list labels--> <string name="no_items_label">Det er ingen objekter pÃ¥ denne listen.</string> - <string name="no_feeds_label">Du abonnerer ikke pÃ¥ noen strømmer enda.</string> <!--Preferences--> <string name="other_pref">Annet</string> <string name="about_pref">Om</string> <string name="queue_label">Queue</string> - <string name="services_label">Tjenester</string> <string name="flattr_label">Flattr</string> <string name="pref_episode_cleanup_title">Episodeopprydding</string> <string name="pref_pauseOnDisconnect_sum">Sett playback pÃ¥ pause nÃ¥r hodetelefoner eller bluetooth er frakoblet</string> <string name="pref_unpauseOnHeadsetReconnect_sum">Gjenoppta avspilling nÃ¥r hodetelefoner gjeninnkoples</string> <string name="pref_unpauseOnBluetoothReconnect_sum">Fortsett avspilling nÃ¥r bluetooth er tilkoblet igjen</string> - <string name="pref_hardwareForwardButtonSkips_sum">Ved pressing av hardware forover-knapp hopp til neste episode istedenfor forover-spoling</string> <string name="pref_followQueue_sum">Hopp til neste element i køen nÃ¥r avspillingen er ferdig</string> <string name="pref_auto_delete_sum">Slett episode nÃ¥r avspillingen er ferdig</string> <string name="pref_auto_delete_title">Automatisk sletting</string> @@ -279,7 +268,6 @@ <string name="pref_nav_drawer_feed_order_title">Velg rekkefølge pÃ¥ abbonement</string> <string name="pref_nav_drawer_feed_order_sum">Endre rekkefølgen pÃ¥ abbonementene dine</string> <string name="pref_nav_drawer_feed_counter_title">Velg abbonementsteller</string> - <string name="pref_nav_drawer_feed_counter_sum">Endre informasjonen vist av abonnementstelleren</string> <string name="pref_set_theme_sum">Endre utseendet til AntennaPod</string> <string name="pref_automatic_download_title">Automatisk nedlasting</string> <string name="pref_automatic_download_sum">Konfigurer automatisk nedlasting av episoder.</string> @@ -305,8 +293,6 @@ <string name="pref_playback_speed_sum">Egendefiner hastighetene tilgjengelig for variabel avspillingshastighet</string> <string name="pref_gpodnet_sethostname_title">Sett vertsnavn</string> <string name="pref_gpodnet_sethostname_use_default_host">Bruk standard vert</string> - <string name="pref_expandNotify_title">Utvid varsel</string> - <string name="pref_expandNotify_sum">Utvider alltid varselet for Ã¥ inkludere avspillingsknapper.</string> <string name="pref_persistNotify_title">Vedvarende avspillingskontroller</string> <string name="pref_persistNotify_sum">Behold varsel- og lÃ¥seskjermkontroller nÃ¥r avspilling er satt pÃ¥ pause.</string> <string name="pref_lockscreen_background_title">Angi som bakgrunn pÃ¥ lÃ¥seskjermen</string> @@ -350,8 +336,6 @@ <string name="choose_file_from_external_application">Bruk ekstern applikasjon</string> <string name="opml_export_label">OPML-eksportering</string> <string name="export_error_label">Eksporteringserror</string> - <string name="opml_export_success_title">OPML-import vellykket.</string> - <string name="opml_export_success_sum">.opml-filen ble skrevet til:\u0020</string> <!--Sleep timer--> <string name="set_sleeptimer_label">Sett opp sovetimer</string> <string name="disable_sleeptimer_label">Deaktiver sovetimer</string> @@ -480,4 +464,5 @@ <!--Database import/export--> <!--Casting--> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-nl/strings.xml b/core/src/main/res/values-nl/strings.xml index 2756adc53..b2b368e8a 100644 --- a/core/src/main/res/values-nl/strings.xml +++ b/core/src/main/res/values-nl/strings.xml @@ -1,38 +1,42 @@ <?xml version='1.0' encoding='UTF-8'?> <resources xmlns:tools="http://schemas.android.com/tools"> <!--Activitiy and fragment titles--> + <string name="feed_update_receiver_name">Abonnementen bijwerken</string> <string name="feeds_label">Feeds</string> <string name="statistics_label">Statistieken</string> <string name="add_feed_label">Podcast toevoegen</string> <string name="episodes_label">Afleveringen</string> <string name="all_episodes_short_label">Alle</string> + <string name="new_episodes_label">Nieuw</string> <string name="favorite_episodes_label">Favorieten</string> <string name="new_label">Nieuw</string> <string name="settings_label">Instellingen</string> <string name="downloads_label">Downloads</string> <string name="downloads_running_label">Bezig</string> <string name="downloads_completed_label">Voltooid</string> - <string name="downloads_log_label">Geschiedenis</string> - <string name="subscriptions_label">Feeds</string> - <string name="subscriptions_list_label">Lijst met feeds</string> - <string name="cancel_download_label">Annuleer download</string> + <string name="downloads_log_label">Logboek</string> + <string name="subscriptions_label">Abonnementen</string> + <string name="subscriptions_list_label">Lijst met abonnementen</string> + <string name="cancel_download_label">Download\nafbreken</string> <string name="playback_history_label">Afspeelgeschiedenis</string> <string name="gpodnet_main_label">gpodder.net</string> - <string name="gpodnet_auth_label">gpodder.net login</string> + <string name="gpodnet_summary">Synchroniseren met andere apparaten</string> + <string name="gpodnet_auth_label">Inloggen op gpodder.net</string> <string name="free_space_label">%1$s beschikbaar</string> - <string name="episode_cache_full_title">Afleveringen cache is vol</string> - <string name="episode_cache_full_message">Het maximum aantal gecachte afleveringen is bereikt. U kunt het maximum verhogen in de instellingen.</string> + <string name="episode_cache_full_title">Afleveringscache is vol</string> + <string name="episode_cache_full_message">Het maximum aantal gecachete afleveringen is bereikt. Je kunt het maximum verhogen in de instellingen.</string> + <string name="synchronizing">Bezig met synchroniseren…</string> <!--Statistics fragment--> <string name="total_time_listened_to_podcasts">Totale duur van afgespeelde podcasts:</string> - <string name="statistics_details_dialog">%1$d van de %2$d afleveringen gestart.\n\n%3$s van de %4$s afgespeeld.</string> + <string name="statistics_details_dialog">%1$d van %2$d afleveringen gestart.\n\n%3$s van %4$s afgespeeld.</string> <string name="statistics_mode">Rekenmethode</string> - <string name="statistics_mode_normal">Bereken de daadwerkelijke speeltijd. Tweemaal afspelen wordt twee keer gerekend; als \'afgespeeld\' markeren wordt niet meegeteld.</string> - <string name="statistics_mode_count_all">Duur van de podcasts optelle die als \'afgespeeld\' zijn gemarkeerd.</string> - <string name="statistics_speed_not_counted">Let op: Met de afspeelsnelheid wordt geen rekening gehouden.</string> + <string name="statistics_mode_normal">Bereken de daadwerkelijke speeltijd. Tweemaal afspelen wordt twee keer gerekend; gemarkeerd als \'afgespeeld\' wordt niet meegeteld.</string> + <string name="statistics_mode_count_all">Duur van de podcasts optellen die gemarkeerd zijn als \'afgespeeld\' zijn</string> + <string name="statistics_speed_not_counted">Let op: er wordt geen rekening gehouden met de afspeelsnelheid.</string> <!--Main activity--> <string name="drawer_open">Menu openen</string> <string name="drawer_close">Menu sluiten</string> - <string name="drawer_preferences">Menu voorkeuren</string> + <string name="drawer_preferences">Menuvoorkeuren</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 publicatie</string> @@ -41,89 +45,93 @@ <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> + <string name="drawer_feed_counter_none">Geen</string> <!--Webview actions--> - <string name="open_in_browser_label">In de browser openen</string> + <string name="open_in_browser_label">Openen in browser</string> <string name="copy_url_label">URL kopiëren</string> <string name="share_url_label">URL delen</string> - <string name="copied_url_msg">URL naar klembord gekopieerd.</string> - <string name="go_to_position_label">Ga naar specifiek tijdstip</string> + <string name="copied_url_msg">URL is gekopieerd naar het klembord</string> + <string name="go_to_position_label">Ga naar deze positie</string> <!--Playback history--> <string name="clear_history_label">Geschiedenis wissen</string> <!--Other--> - <string name="confirm_label">Bevestig</string> + <string name="confirm_label">Bevestigen</string> <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="reset">Standaardwaarden</string> + <string name="author_label">Maker(s)</string> <string name="language_label">Taal</string> <string name="url_label">URL</string> <string name="podcast_settings_label">Instellingen</string> <string name="cover_label">Beeld</string> <string name="error_label">Fout</string> <string name="error_msg_prefix">Er is een fout opgetreden:</string> + <string name="needs_storage_permission">Machtiging voor gebruik van opslag voor deze functie vereist</string> <string name="refresh_label">Verversen</string> - <string name="external_storage_error_msg">Geen externe opslag beschikbaar. Zorg ervoor dat de externe opslag gemonteerd is, zodat de app goed kan werken.</string> + <string name="external_storage_error_msg">Geen externe opslag beschikbaar. Zorg ervoor dat de externe opslag is aangekoppeld, zodat de app goed kan werken.</string> <string name="chapters_label">Hoofdstukken</string> <string name="chapter_duration">Duur: %1$s</string> - <string name="shownotes_label">Shownotes</string> - <string name="description_label">Beschrijving</string> + <string name="shownotes_label">Notities</string> + <string name="description_label">Omschrijving</string> <string name="most_recent_prefix">Meest recente aflevering:\u0020</string> <string name="episodes_suffix">\u0020afleveringen</string> - <string name="length_prefix">Lengte:\u0020</string> + <string name="length_prefix">Duur:\u0020</string> <string name="size_prefix">Grootte:\u0020</string> - <string name="processing_label">Aan het verwerken</string> - <string name="loading_label">Laden…</string> + <string name="processing_label">Bezig met verwerken...</string> + <string name="loading_label">Bezig met laden...</string> <string name="save_username_password_label">Gebruikersnaam en wachtwoord opslaan</string> <string name="close_label">Sluiten</string> - <string name="retry_label">Opnieuw proberen</string> + <string name="retry_label">Opnieuw</string> <string name="auto_download_label">Meenemen bij automatisch downloaden</string> - <string name="auto_download_apply_to_items_title">Toepassen op bestaande afleveringen</string> - <string name="auto_download_apply_to_items_message">De instelling voor <i>Automatisch downloaden</i> wordt automatisch toegepast op toekomstige afleveringen.\nWilt u het ook toepassen op eerder gepubliceerde afleveringen?</string> - <string name="auto_delete_label">Afleveringen automatisch\nverwijderen</string> - <string name="parallel_downloads_suffix">\u0020parallele downloads</string> + <string name="auto_download_apply_to_items_title">Toepassen op vorige afleveringen</string> + <string name="auto_download_apply_to_items_message">De instelling voor <i>Automatisch downloaden</i> wordt automatisch toegepast op toekomstige afleveringen.\nWil je het ook toepassen op eerder gepubliceerde afleveringen?</string> + <string name="auto_delete_label">Aflevering automatisch verwijderen</string> + <string name="parallel_downloads_suffix">\u0020gelijktijdige downloads</string> <string name="feed_auto_download_global">Standaardinstelling</string> <string name="feed_auto_download_always">Altijd</string> <string name="feed_auto_download_never">Nooit</string> - <string name="send_label">Versturen…</string> + <string name="send_label">Versturen...</string> <string name="episode_cleanup_never">Nooit</string> - <string name="episode_cleanup_queue_removal">Wanneer niet in de wachtrij</string> - <string name="episode_cleanup_after_listening">Wanneer aflevering volledig is afgespeeld</string> + <string name="episode_cleanup_queue_removal">Indien niet in de wachtrij</string> + <string name="episode_cleanup_after_listening">Als aflevering volledig is afgespeeld</string> <plurals name="episode_cleanup_days_after_listening"> - <item quantity="one">1 dag nadat de aflevering als afgespeeld is gemarkeerd</item> - <item quantity="other">%d dagen nadat de aflevering als afgespeeld is gemarkeerd</item> + <item quantity="one">1 dag nadat de aflevering is gemarkeerd als afgespeeld</item> + <item quantity="other">%d dagen nadat de aflevering is gemarkeerd als afgespeeld</item> </plurals> <!--'Add Feed' Activity labels--> - <string name="feedurl_label">Feed URL</string> + <string name="feedurl_label">Feed-URL</string> <string name="etxtFeedurlHint">www.voorbeeld.nl/feed</string> <string name="txtvfeedurl_label">Podcast toevoegen via URL</string> - <string name="podcastdirectories_label">Podcast vinden in de gids</string> - <string name="podcastdirectories_descr">U kunt nieuwe podcasts zoeken op naam, categorie of populariteit in de gpodder.net database, of de iTunes winkel doorzoeken.</string> - <string name="browse_gpoddernet_label">gpodder.net doorbladeren</string> + <string name="podcastdirectories_label">Podcast zoeken in de gids</string> + <string name="podcastdirectories_descr">Je kunt nieuwe podcasts vinden op naam, categorie of populariteit in de gpodder.net-databank of via iTunes of fyyd.</string> + <string name="browse_gpoddernet_label">Blader door gpodder.net</string> <!--Actions on feeds--> - <string name="mark_all_read_label">Alles als afgespeeld markeren</string> - <string name="mark_all_read_msg">Alle afleveringen als afgespeeld markeren</string> - <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="mark_all_read_label">Alles markeren als afgespeeld</string> + <string name="mark_all_read_msg">Alle afleveringen zijn gemarkeerd als afgespeeld</string> + <string name="mark_all_read_confirmation_msg">Bevestig dat je alle afleveringen wilt markeren als afgespeeld.</string> + <string name="mark_all_read_feed_confirmation_msg">Bevestig dat je alle afleveringen van deze podcast wilt markeren als afgespeeld.</string> + <string name="mark_all_seen_label">Alles markeren als bekeken</string> + <string name="mark_all_seen_msg">Alle afleveringen zijn gemarkeerd als bekeken</string> + <string name="mark_all_seen_confirmation_msg">Bevestig dat je alle afleveringen wilt markeren als bekeken.</string> + <string name="show_info_label">Informatie tonen</string> + <string name="show_feed_settings_label">Podcast-instellingen tonen</string> + <string name="feed_info_label">Podcast-informatie</string> + <string name="feed_settings_label">Podcast-instellingen</string> + <string name="rename_feed_label">Podcastnaam wijzigen</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> - <string name="share_file_label">Deel bestand</string> - <string name="share_link_with_position_label">Link van de aflevering met tijdstip delen</string> - <string name="share_feed_url_label">URL van de feed delen</string> - <string name="share_item_url_label">URL van het mediabestand delen</string> - <string name="share_item_url_with_position_label">URL van mediabestand met tijdstip delen</string> - <string name="feed_delete_confirmation_msg">Bevestig dat u de feed <i>%1$s</i> en ALLE (ook gedownloade) afleveringen van deze podcast wilt verwijderen.</string> - <string name="feed_remover_msg">Feed verwijderen</string> - <string name="load_complete_feed">Hele feed vernieuwen</string> + <string name="share_label">Delen...</string> + <string name="share_link_label">URL van aflevering delen</string> + <string name="share_link_with_position_label">URL van aflevering delen, op specifieke positie</string> + <string name="share_file_label">Bestand delen</string> + <string name="share_feed_url_label">URL van feed delen</string> + <string name="share_item_url_label">URL van mediabestand delen</string> + <string name="share_item_url_with_position_label">URL van mediabestand delen, op specifieke positie</string> + <string name="feed_delete_confirmation_msg">Bevestig dat je de podcast \"%1$s\" en ALLE (ook gedownloade) bijbehorende afleveringen wilt verwijderen.</string> + <string name="feed_remover_msg">Podcast verwijderen</string> + <string name="load_complete_feed">Gehele podcast verversen</string> <string name="hide_episodes_title">Afleveringen verbergen</string> - <string name="episode_actions">Afleveringen beheren</string> + <string name="batch_edit">Bulkbewerking</string> <string name="hide_unplayed_episodes_label">Niet afgespeeld</string> <string name="hide_paused_episodes_label">Gepauzeerd</string> <string name="hide_played_episodes_label">Afgespeeld</string> @@ -132,335 +140,353 @@ <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="hide_is_favorite_label">Gemarkeerd als favoriet</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> + <string name="refresh_failed_msg">{fa-exclamation-circle} Vorige verversing mislukt</string> + <string name="open_podcast">Podcast openen</string> <!--actions on feeditems--> - <string name="download_label">Download</string> - <string name="play_label">Spelen</string> - <string name="pause_label">Pauze</string> - <string name="stop_label">Stop</string> - <string name="stream_label">Stream</string> + <string name="download_label">Downloaden</string> + <string name="play_label">Afspelen</string> + <string name="pause_label">Pauzeren</string> + <string name="stop_label">Stoppen</string> + <string name="stream_label">Streamen</string> <string name="remove_label">Verwijderen</string> <string name="delete_label">Verwijderen</string> - <string name="delete_failed">Kan bestand niet verwijderen. Het kan misschien helpen om je apparaat opnieuw op te starten.</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> - <string name="add_to_queue_label">Voeg toe aan wachtrij</string> - <string name="added_to_queue_label">Aan wachtrij toegevoegd</string> - <string name="remove_from_queue_label">Verwijder van wachtrij</string> + <string name="delete_failed">Kan bestand niet verwijderen; start je apparaat opnieuw op.</string> + <string name="remove_episode_lable">Aflevering verwijderen</string> + <string name="mark_as_seen_label">Markeren als bekeken</string> + <string name="marked_as_seen_label">Gemarkeerd als bekeken</string> + <string name="mark_read_label">Markeren als afgespeeld</string> + <string name="marked_as_read_label">Gemarkeerd als afgespeeld</string> + <string name="mark_unread_label">Markeren als niet-afgespeeld</string> + <string name="add_to_queue_label">Toevoegen aan wachtrij</string> + <string name="added_to_queue_label">Toegevoegd aan wachtrij</string> + <string name="remove_from_queue_label">Verwijderen uit wachtrij</string> <string name="add_to_favorite_label">Toevoegen aan favorieten</string> - <string name="added_to_favorites">Aan favorieten toegevoegd</string> + <string name="added_to_favorites">Toegevoegd aan favorieten</string> <string name="remove_from_favorite_label">Verwijderen uit favorieten</string> <string name="removed_from_favorites">Verwijderd uit favorieten</string> <string name="visit_website_label">Website bezoeken</string> <string name="support_label">Flattr dit</string> <string name="skip_episode_label">Aflevering overslaan</string> <string name="activate_auto_download">Automatisch downloaden activeren</string> - <string name="deactivate_auto_download">Automatisch downloaden deactiveren</string> - <string name="reset_position">Afspeelpositie resetten</string> + <string name="deactivate_auto_download">Automatisch downloaden de-activeren</string> + <string name="reset_position">Afspeelpositie herstellen</string> <string name="removed_item">Aflevering verwijderd</string> <!--Download messages and labels--> - <string name="download_successful">succesvol</string> + <string name="download_successful">voltooid</string> <string name="download_failed">mislukt</string> - <string name="download_pending">Download in afwachting</string> - <string name="download_running">Aan het downloaden</string> - <string name="download_error_device_not_found">Opslagmedium niet gevonden</string> + <string name="download_pending">Download staat in wachtrij</string> + <string name="download_running">Bezig met downloaden</string> + <string name="download_error_details">Details</string> + <string name="download_error_details_message">%1$s \n\nURL van bestand:\n%2$s</string> + <string name="download_error_device_not_found">Opslagmedium niet aangetroffen</string> <string name="download_error_insufficient_space">Onvoldoende ruimte</string> <string name="download_error_file_error">Bestandsfout</string> - <string name="download_error_http_data_error">HTTP data fout</string> + <string name="download_error_http_data_error">HTTP-gegevensfout</string> <string name="download_error_error_unknown">Onbekende fout</string> - <string name="download_error_parser_exception">Parser Exception</string> - <string name="download_error_unsupported_type">Niet ondersteunde feed soort</string> + <string name="download_error_parser_exception">Verwerkingsuitzondering</string> + <string name="download_error_unsupported_type">Niet-ondersteunde feedsoort</string> <string name="download_error_connection_error">Verbindingsfout</string> <string name="download_error_unknown_host">Onbekende host</string> - <string name="download_error_unauthorized">Authenticatie fout</string> - <string name="download_error_file_type_type">Fout met bestandsformaat</string> - <string name="download_error_forbidden">Actie niet mogelijk</string> - <string name="cancel_all_downloads_label">Alle downloads annuleren</string> - <string name="download_canceled_msg">Download geannuleerd</string> - <string name="download_canceled_autodownload_enabled_msg">Downloaden geannuleerd\n<i>Automatisch downloaden</i> uitgezet voor deze aflevering</string> - <string name="download_report_title">Downloads afgerond met fouten</string> + <string name="download_error_unauthorized">Authenticatiefout</string> + <string name="download_error_file_type_type">Bestandssoortfout</string> + <string name="download_error_forbidden">Niet mogelijk</string> + <string name="cancel_all_downloads_label">Alle downloads afbreken</string> + <string name="download_canceled_msg">Download afgebroken</string> + <string name="download_canceled_autodownload_enabled_msg">Download afgebroken\n<i>Automatisch downloaden</i> uitgeschakeld voor deze aflevering</string> + <string name="download_report_title">Downloads afgerond, maar met fout(en)</string> <string name="download_report_content_title">Downloadrapport</string> - <string name="download_error_malformed_url">Misvormde URL</string> - <string name="download_error_io_error">IO fout</string> - <string name="download_error_request_error">Fout in de aanvraag</string> - <string name="download_error_db_access">Databasetoegangsfout</string> + <string name="download_error_malformed_url">Onjuist opgemaakte URL</string> + <string name="download_error_io_error">Invoer-/uitvoerfout</string> + <string name="download_error_request_error">Opvraagfout</string> + <string name="download_error_db_access">Fout bij databanktoegang</string> <plurals name="downloads_left"> <item quantity="one">Nog %d download</item> <item quantity="other">Nog %d downloads</item> </plurals> - <string name="downloads_processing">Downloads verwerken</string> - <string name="download_notification_title">Podcastgegevens aan het downloaden</string> - <string name="download_report_content">%1$d downloads geslaagd, %2$d mislukt</string> + <string name="downloads_processing">Bezig met verwerken van downloads</string> + <string name="download_notification_title">Bezig met downloaden van podcastgegevens</string> + <string name="download_report_content">%1$d downloads voltooid, %2$d mislukt</string> <string name="download_log_title_unknown">Onbekende titel</string> <string name="download_type_feed">Feed</string> <string name="download_type_media">Mediabestand</string> - <string name="download_type_image">Beeld</string> - <string name="download_request_error_dialog_message_prefix">Er is een fout opgetreden bij het ​​downloaden van bestand:\u0020</string> + <string name="download_type_image">Afbeelding</string> + <string name="download_request_error_dialog_message_prefix">Er is een fout opgetreden bij het ​​downloaden van het bestand:\u0020</string> <string name="authentication_notification_title">Authenticatie vereist</string> - <string name="authentication_notification_msg">De opgevraagde bron vereist een gebruikersnaam en een wachtwoord</string> - <string name="confirm_mobile_download_dialog_title">Bevestig downloaden over mobiel netwerk</string> - <string name="confirm_mobile_download_dialog_message_not_in_queue">Het downloaden via mobiele verbindingen is uitgezet in de instellingen.\n\nU kunt er voor kiezen om slechts de aflevering aan de wachtrij toe te voegen, of om downloaden via mobiele netwerken tijdelijk toe te staan.\n<small>Uw keuze is 10 minuten geldig.</small></string> - <string name="confirm_mobile_download_dialog_message">Het downloaden via mobiele verbindingen is uitgezet in de instellingen.\n\nWilt u dit tijdelijk toestaan?\n<small>Uw keuze is 10 minuten geldig.</small></string> + <string name="authentication_notification_msg">De opgevraagde bron vereist een gebruikersnaam en wachtwoord</string> + <string name="confirm_mobile_download_dialog_title">Bevestig downloaden via mobiel internet</string> + <string name="confirm_mobile_download_dialog_message_not_in_queue">Downloaden via mobiel internet is uitgeschakeld in de instellingen.\n\nJe kunt er voor kiezen om de aflevering alleen toe te voegen aan de wachtrij of om downloaden via mobiele internet tijdelijk toe te staan.\n<small>Je keuze wordt 10 minuten onthouden.</small></string> + <string name="confirm_mobile_download_dialog_message">Downloaden via mobiel internet is uitgeschakeld in de instellingen.\n\nWil je dit tijdelijk toestaan?\n<small>Je keuze wordt 10 minuten onthouden.</small></string> <string name="confirm_mobile_download_dialog_only_add_to_queue">Toevoegen aan wachtrij</string> <string name="confirm_mobile_download_dialog_enable_temporarily">Tijdelijk toestaan</string> <!--Mediaplayer messages--> <string name="player_error_msg">Fout!</string> <string name="player_stopped_msg">Geen media aan het afspelen</string> - <string name="player_preparing_msg">Voorbereiding</string> + <string name="player_preparing_msg">Bezig met voorbereiden</string> <string name="player_ready_msg">Klaar</string> - <string name="player_seeking_msg">Aan het opzoeken</string> - <string name="playback_error_server_died">Server antwoord niet</string> + <string name="player_seeking_msg">Bezig met zoeken</string> + <string name="playback_error_server_died">Serververbinding verbroken</string> <string name="playback_error_unknown">Onbekende fout</string> <string name="no_media_playing_label">Geen media aan het afspelen</string> - <string name="player_buffering_msg">Buffering</string> - <string name="playbackservice_notification_title">Podcast aan het afspelen</string> - <string name="unknown_media_key">AntennaPod - Mediaknop onbekend: %1$d</string> + <string name="player_buffering_msg">Bezig met bufferen</string> + <string name="player_go_to_picture_in_picture">Picture-in-picture-modus</string> + <string name="playbackservice_notification_title">Bezig met afspelen van podcast</string> + <string name="unknown_media_key">AntennaPod - onbekende mediatoets: %1$d</string> <!--Queue operations--> - <string name="lock_queue">Wachtrij vastzetten</string> + <string name="lock_queue">Wachtrij vergrendelen</string> <string name="unlock_queue">Wachtrij ontgrendelen</string> <string name="queue_locked">Wachtrij vergrendeld</string> <string name="queue_unlocked">Wachtrij ontgrendeld</string> - <string name="clear_queue_label">Wachtrij leeg maken</string> + <string name="clear_queue_label">Wachtrij leegmaken</string> <string name="undo">Ongedaan maken</string> <string name="removed_from_queue">Item verwijderd</string> <string name="move_to_top_label">Naar boven verplaatsen</string> <string name="move_to_bottom_label">Naar beneden verplaatsen</string> <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="duration">Duur</string> + <string name="episode_title">Afleveringstitel</string> + <string name="feed_title">Podcast-titel</string> + <string name="random">Willekeurig</string> + <string name="smart_shuffle">Slim willekeurig afspelen</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> + <string name="clear_queue_confirmation_msg">Bevestig dat je ALLE afleveringen wilt verwijderen uit de wachtrij</string> <!--Flattr--> - <string name="flattr_auth_label">Flattr login</string> - <string name="flattr_auth_explanation">Druk op onderstaande knop om het verificatieproces te starten. U wordt doorgestuurd naar het Flattr inlogscherm in uw browser en u wordt gevraagd om toestemming aan AntennaPod te geven om dingen te Flattr\'en. Nadat u toestemming heeft gegeven, keert u automatisch terug naar dit scherm.</string> + <string name="flattr_auth_label">Inloggen op Flattr</string> + <string name="flattr_auth_explanation">Druk op onderstaande knop om het verificatieproces te starten. Het Flattr-inlogscherm wordt geopend in je browser en je wordt gevraagd om AntennaPod te machtigingen om dingen te Flattr\'en. Daarna keer je automatisch terug naar dit scherm.</string> <string name="authenticate_label">Authenticeren</string> - <string name="return_home_label">Terug naar de startscherm</string> - <string name="flattr_auth_success">Authenticatie is geslaagd! U kunt nu dingen vanuit de app Flattr\'en.</string> - <string name="no_flattr_token_title">Geen Flattr token gevonden</string> - <string name="no_flattr_token_notification_msg">Het lijkt er op dat uw Flattr account niet is verbonden met AntennaPod. Klik hier om te authenticeren.</string> - <string name="no_flattr_token_msg">Uw Flattr account lijkt niet aangesloten te zijn op AntennaPod. U kunt uw account aan AntennaPod sluiten om dingen vanuit de app te Flattr\'en, of u kunt op de website van het ding terecht om het daar te Flattr\'en.</string> + <string name="return_home_label">Terug naar startscherm</string> + <string name="flattr_auth_success">Authenticatie geslaagd! Je kunt nu dingen vanuit de app Flattr\'en.</string> + <string name="no_flattr_token_title">Geen Flattr-toegangssleutel gevonden</string> + <string name="no_flattr_token_notification_msg">Het lijkt er op dat je Flattr-account niet gekoppeld is aan AntennaPod. Druk hier om te authenticeren.</string> + <string name="no_flattr_token_msg">Je Flattr-account lijkt niet gekoppeld te zijn aan AntennaPod. Je kunt je account koppelen om dingen vanuit de app te Flattr\'en, of je kunt op de website van het ding terecht om het daar te Flattr\'en.</string> <string name="authenticate_now_label">Authenticeren</string> - <string name="action_forbidden_title">Actie verboden</string> - <string name="action_forbidden_msg">AntennaPod heeft geen toestemming voor deze actie. De reden hiervoor zou kunnen zijn dat de toegang token van AntennaPod voor uw account ingetrokken is. U kunt opnieuw authenticeren, of de website van het ding bezoeken.</string> + <string name="action_forbidden_title">Niet toegestaan</string> + <string name="action_forbidden_msg">AntennaPod heeft geen toestemming voor deze actie. De reden hiervoor zou kunnen zijn dat de toegangssleutel van AntennaPod voor je account is ingetrokken. Je kunt opnieuw authenticeren, of de website van het ding bezoeken.</string> <string name="access_revoked_title">Toegang ingetrokken</string> - <string name="access_revoked_info">U heeft met succes het toegangstoken van AntennaPod tot uw account ingetrokken. Om het proces te voltooien, moet u deze app uit de lijst van goedgekeurde applicaties in uw accountinstellingen op de Flattr website verwijderen.</string> + <string name="access_revoked_info">Je heb de toegangssleutel van AntennaPod tot je account ingetrokken. Om het proces te voltooien, moet je deze app verwijderen uit de lijst met goedgekeurde applicaties in je accountinstellingen op de Flattr-website.</string> <!--Flattr--> - <string name="flattr_click_success">Een ding geflattr\'d</string> + <string name="flattr_click_success">Een ding geflattr\'d!</string> <string name="flattr_click_success_count">%d dingen geflattr\'d!</string> <string name="flattr_click_success_queue">Geflattr\'d: %s.</string> - <string name="flattr_click_failure_count">Kon %d dingen niet flattr\'n!</string> + <string name="flattr_click_failure_count">Kan %d dingen niet flattr\'n!</string> <string name="flattr_click_failure">Niet geflattr\'d: %s.</string> <string name="flattr_click_enqueued">Ding wordt later geflattr\'d</string> - <string name="flattring_thing">%s aan het flattren</string> + <string name="flattring_thing">Bezig met flattr\'n van%s</string> <string name="flattring_label">AntennaPod is aan het flattren</string> <string name="flattrd_label">AntennaPod heeft geflattr\'d</string> - <string name="flattrd_failed_label">AntennaPod flattr niet gelukt</string> - <string name="flattr_retrieving_status">Geflattr\'de dingen aan het ontvangen</string> + <string name="flattrd_failed_label">AntennaPod-flattr mislukt</string> + <string name="flattr_retrieving_status">Bezig met ontvangen van geflattr\'de dingen</string> <!--Variable Speed--> - <string name="download_plugin_label">Plugin downloaden</string> - <string name="no_playback_plugin_title">Plugin niet geïnstalleerd</string> - <string name="no_playback_plugin_or_sonic_msg">Om variabele afspeelsnelheid te kunnen gebruiken, raden wij u aan om de ingebouwde Sonic mediaspeler te activeren [Android 4.1+]\n\nEventueel kunt u de externe plugin <i>Prestissimo</i> downloaden van de Play Store.\nProblemen bij het gebruik van deze plugin zijn niet de verantwoordelijkheid van AntennaPod en moeten gemeld worden bij de ontwikkelaar van de plugin.</string> + <string name="download_plugin_label">Plug-in downloaden</string> + <string name="no_playback_plugin_title">Plug-in niet geïnstalleerd</string> + <string name="no_playback_plugin_or_sonic_msg">Om variabele afspeelsnelheid te kunnen gebruiken, bevelen wij aan om de ingebouwde Sonic-mediaspeler te activeren [Android 4.1 en hoger]\n\nEvt. kun je de externe plug-in <i>Prestissimo</i> downloaden via de Play Store.\nWij zijn niet verantwoordelijk voor problemen met deze plug-in zijn; meld ze bij de plug-inontwikkelaar.</string> <string name="set_playback_speed_label">Afspeelsnelheden</string> <string name="enable_sonic">Sonic inschakelen</string> <!--Empty list labels--> - <string name="no_items_label">Er zijn geen items in deze lijst.</string> - <string name="no_feeds_label">U bent nog tot geen enkele feed geabonneerd.</string> - <string name="no_chapters_label">Deze aflevering heeft geen hoofdstukken.</string> - <string name="no_shownotes_label">Deze aflevering heeft geen shownotes.</string> + <string name="no_items_label">Er staan geen items op deze lijst.</string> + <string name="no_feeds_label">Je hebt nog geen abonnement op een podcast.</string> + <string name="no_chapters_label">Deze aflevering bevat geen hoofdstukken.</string> + <string name="no_shownotes_label">Deze aflevering bevat geen shownotities.</string> <!--Preferences--> - <string name="storage_pref">Geheugen</string> + <string name="storage_pref">Opslag</string> <string name="project_pref">Project</string> <string name="other_pref">Overig</string> <string name="about_pref">Over AntennaPod</string> <string name="queue_label">Wachtrij</string> - <string name="services_label">Services</string> + <string name="integrations_label">Integraties</string> <string name="flattr_label">Flattr</string> + <string name="flattr_summary">Dienst voor microbetalingen</string> + <string name="automation">Automatische acties</string> + <string name="download_pref_details">Details</string> + <string name="import_export_pref">Importeren/Exporteren</string> + <string name="appearance">Uiterlijk</string> + <string name="external_elements">Externe elementen</string> + <string name="interruptions">Onderbrekingen</string> + <string name="buttons">Knoppen voor afspeelbediening</string> + <string name="media_player">Mediaspeler</string> <string name="pref_episode_cleanup_title">Automatisch opschonen</string> - <string name="pref_episode_cleanup_summary">Afleveringen die niet in de wachtrij staan én niet als favoriet gemarkeerd zijn, mogen verwijderd worden als Automatisch Downloaden ruimte nodig heeft voor nieuwe afleveringen</string> - <string name="pref_pauseOnDisconnect_sum">Afspelen pauzeren wanneer de koptelefoon wordt losgekoppeld of de bluetooth verbinding wordt verbroken</string> - <string name="pref_unpauseOnHeadsetReconnect_sum">Afspelen hervatten wanneer de koptelefoon opnieuw wordt aangesloten</string> - <string name="pref_unpauseOnBluetoothReconnect_sum">Afspelen hervatten wanneer de bluetooth verbinding hervat wordt</string> - <string name="pref_hardwareForwardButtonSkips_title">\'Volgende\' knop voor overslaan</string> - <string name="pref_hardwareForwardButtonSkips_sum">Aflevering overslaan ipv vooruitspoelen wanneer op een fysieke \'volgende\' knop wordt gedrukt</string> - <string name="pref_hardwarePreviousButtonRestarts_title">Vorige voor opnieuw afspelen</string> - <string name="pref_hardwarePreviousButtonRestarts_sum">Aflevering afspelen vanaf het begin ipv terugspoelen wanneer op een fysieke \'vorige\' knop wordt gedrukt</string> + <string name="pref_episode_cleanup_summary">Afleveringen die niet op de wachtrij staan én geen favoriet zijn, mogen verwijderd worden als Automatisch downloaden ruimte nodig heeft voor nieuwe afleveringen</string> + <string name="pref_pauseOnDisconnect_sum">Afspelen pauzeren als de koptelefoon wordt losgekoppeld of de Bluetooth-verbinding wordt verbroken</string> + <string name="pref_unpauseOnHeadsetReconnect_sum">Afspelen hervatten als de koptelefoon opnieuw wordt aangesloten</string> + <string name="pref_unpauseOnBluetoothReconnect_sum">Afspelen hervatten als de Bluetooth-verbinding hervat wordt</string> + <string name="pref_hardwareForwardButtonSkips_title">\'Volgende\' voor overslaan</string> + <string name="pref_hardwarePreviousButtonRestarts_title">\'Vorige\' voor opnieuw afspelen</string> + <string name="pref_hardwarePreviousButtonRestarts_sum">Aflevering afspelen vanaf het begin i.p.v. terugspoelen als er 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> - <string name="pref_smart_mark_as_played_sum">Afleveringen als afgespeeld markeren wanneer deze nog maar een bepaald aantal seconden duurt</string> - <string name="pref_smart_mark_as_played_title">Slimme afgespeeld markering</string> - <string name="pref_skip_keeps_episodes_sum">Afleveringen bewaren en in de wachtrij houden als u op \'overslaan\' klikt</string> + <string name="pref_smart_mark_as_played_sum">Afleveringen als afgespeeld markeren als deze nog maar een bepaald aantal seconden duren</string> + <string name="pref_smart_mark_as_played_title">Slimme afgespeeld-markering</string> + <string name="pref_skip_keeps_episodes_sum">Afleveringen bewaren als ze worden overgeslagen</string> <string name="pref_skip_keeps_episodes_title">Overgeslagen afleveringen bewaren</string> <string name="pref_favorite_keeps_episodes_sum">Afleveringen bewaren als ze als favoriet gemarkeerd zijn</string> <string name="pref_favorite_keeps_episodes_title">Favoriete afleveringen bewaren</string> <string name="playback_pref">Afspelen</string> <string name="network_pref">Netwerk</string> - <string name="pref_autoUpdateIntervallOrTime_title">Feed update interval of tijdstip</string> - <string name="pref_autoUpdateIntervallOrTime_sum">Specificeer een interval of tijdstip waarop feeds automatisch vernieuwd moeten worden</string> - <string name="pref_autoUpdateIntervallOrTime_message">U kunt een <i>interval</i> zoals \'elke twee uur\' of een specifiek <i>tijdstip</i> zoals \'07:00 uur\' instellen, of het automatisch verversen van feeds uitzetten.\n\n<small>Let op: tijdstippen voor updates zijn niet precies. Er kan een kleine vertraging plaatsvinden.</small></string> + <string name="pref_autoUpdateIntervallOrTime_title">Bijwerktussenpoos of -tijdstip</string> + <string name="pref_autoUpdateIntervallOrTime_sum">Geef een tussenpoos of tijdstip op waarop feeds automatisch ververst moeten worden</string> + <string name="pref_autoUpdateIntervallOrTime_message">Je kunt een <i>tussenpoos</i> zoals \'elke twee uur\' instellen, een specifiek <i>tijdstip</i> zoals \'07:00 uur\' of het automatisch verversen van feeds uitschakelen.\n\n<small>Let op: tijdstippen zijn niet precies; er kan een kleine vertraging zijn.</small></string> <string name="pref_autoUpdateIntervallOrTime_Disable">Uitschakelen</string> - <string name="pref_autoUpdateIntervallOrTime_Interval">Interval instellen</string> + <string name="pref_autoUpdateIntervallOrTime_Interval">Tussenpoos instellen</string> <string name="pref_autoUpdateIntervallOrTime_TimeOfDay">Tijdstip instellen</string> <string name="pref_autoUpdateIntervallOrTime_every">elke %1$s</string> - <string name="pref_autoUpdateIntervallOrTime_at">op %1$s</string> - <string name="pref_downloadMediaOnWifiOnly_sum">Download mediabestanden alleen via WiFi</string> - <string name="pref_followQueue_title">Continu afspelen</string> - <string name="pref_downloadMediaOnWifiOnly_title">WiFi download van media</string> - <string name="pref_pauseOnHeadsetDisconnect_title">Pauzeren bij loskoppeling</string> - <string name="pref_unpauseOnHeadsetReconnect_title">Aansluiten koptelefoon</string> - <string name="pref_unpauseOnBluetoothReconnect_title">Verbinden met bluetooth</string> - <string name="pref_mobileUpdate_title">Mobiele updates</string> - <string name="pref_mobileUpdate_sum">Updates toestaan ​​via de mobiele dataverbinding</string> - <string name="refreshing_label">Aan het verversen</string> - <string name="flattr_settings_label">Flattr settings</string> - <string name="pref_flattr_auth_title">Flattr accountgegevens</string> - <string name="pref_flattr_auth_sum">Log in je Flattr account om dingen rechtstreeks vanuit de app te flattr\'en.</string> + <string name="pref_autoUpdateIntervallOrTime_at">om %1$s</string> + <string name="pref_downloadMediaOnWifiOnly_sum">Mediabestanden alleen downloaden via Wi-Fi</string> + <string name="pref_followQueue_title">Doorlopend afspelen</string> + <string name="pref_downloadMediaOnWifiOnly_title">Media downloaden via Wi-Fi</string> + <string name="pref_pauseOnHeadsetDisconnect_title">Loskoppelen van hoofdtelefoon</string> + <string name="pref_unpauseOnHeadsetReconnect_title">Opnieuw aansluiten van hoofdtelefoon</string> + <string name="pref_unpauseOnBluetoothReconnect_title">Opnieuw verbinden met Bluetooth</string> + <string name="pref_mobileUpdate_title">Bijwerken via mobiel internet</string> + <string name="pref_mobileUpdate_sum">Bijwerken toestaan via mobiele internetverbinding</string> + <string name="refreshing_label">Bezig met verversen...</string> + <string name="flattr_settings_label">Flattr-instellingen</string> + <string name="pref_flattr_auth_title">Inloggen op Flattr</string> + <string name="pref_flattr_auth_sum">Log in op je Flattr-account om dingen vanuit de app te flattr\'en.</string> <string name="pref_flattr_this_app_title">Flattr deze app</string> - <string name="pref_flattr_this_app_sum">Ondersteun de ontwikkeling van AntennaPod door het te flattr\'en. Bedankt!</string> - <string name="pref_revokeAccess_title">Toegang intrekken</string> - <string name="pref_revokeAccess_sum">Trek de toegang van deze app in tot je Flattr account.</string> - <string name="pref_auto_flattr_title">Automatische Flattr</string> + <string name="pref_flattr_this_app_sum">Ondersteun de ontwikkeling van AntennaPod door te flattr\'en. Bedankt!</string> + <string name="pref_revokeAccess_title">Machtiging intrekken</string> + <string name="pref_revokeAccess_sum">Trek de machtiging van deze app in op je Flattr account.</string> + <string name="pref_auto_flattr_title">Automatisch flattr\'en</string> <string name="pref_auto_flattr_sum">Automatisch flattr\'en instellen</string> - <string name="user_interface_label">User Interface</string> - <string name="pref_set_theme_title">Kies kleurschema</string> - <string name="pref_nav_drawer_title">Menu aanpassen</string> - <string name="pref_nav_drawer_sum">Het uiterlijk en andere instellingen van het menu aanpassen.</string> - <string name="pref_nav_drawer_items_title">Menu-items instellen</string> - <string name="pref_nav_drawer_items_sum">Aanpassen welke items in het menu worden getoond</string> - <string name="pref_nav_drawer_feed_order_title">Feed volgorde instellen</string> - <string name="pref_nav_drawer_feed_order_sum">De volgorde van uw feeds instellen</string> + <string name="user_interface_label">Uiterlijk</string> + <string name="pref_set_theme_title">Thema kiezen</string> + <string name="pref_nav_drawer_title">Navigatiemenu aanpassen</string> + <string name="pref_nav_drawer_sum">Pas het uiterlijk van het navigatiemenu aan.</string> + <string name="pref_nav_drawer_items_title">Menu-items kiezen</string> + <string name="pref_nav_drawer_items_sum">Kies welke items moeten worden getoond in het navigatiemenu.</string> + <string name="pref_nav_drawer_feed_order_title">Abonnementsvolgorde instellen</string> + <string name="pref_nav_drawer_feed_order_sum">Stel de volgorde van je abonnementen in</string> <string name="pref_nav_drawer_feed_counter_title">Teller instellen</string> - <string name="pref_nav_drawer_feed_counter_sum">Pas aan welke aantallen in het menu worden getoond</string> - <string name="pref_set_theme_sum">Verander het uiterlijk van AntennaPod.</string> + <string name="pref_nav_drawer_feed_counter_sum">Wijzig de door de teller getoonde informatie. Is ook van toepassing op de sortering als \'Abonnementsvolgorde\' is ingesteld op \'Teller\'.</string> + <string name="pref_set_theme_sum">Pas het uiterlijk van AntennaPod aan.</string> <string name="pref_automatic_download_title">Automatisch downloaden</string> - <string name="pref_automatic_download_sum">Configureer het automatisch downloaden van afleveringen.</string> - <string name="pref_autodl_wifi_filter_title">Wi-Fi filter inschakelen</string> - <string name="pref_autodl_wifi_filter_sum">Automatisch downloaden alleen toestaan voor geselecteerde Wi-Fi-netwerken.</string> - <string name="pref_autodl_allow_on_mobile_title">Downloaden via mobiele verbinding</string> - <string name="pref_autodl_allow_on_mobile_sum">Het automatisch downloaden van afleveringen via een mobiele internetverbinding toestaan.</string> - <string name="pref_automatic_download_on_battery_title">Downloaden zonder opladen</string> + <string name="pref_automatic_download_sum">Stel het automatisch downloaden van afleveringen in.</string> + <string name="pref_autodl_wifi_filter_title">Wi-Fi-filter inschakelen</string> + <string name="pref_autodl_wifi_filter_sum">Automatisch downloaden alleen toestaan via gekozen Wi-Fi-netwerken.</string> + <string name="pref_autodl_allow_on_mobile_title">Downloaden via mobiel internet</string> + <string name="pref_autodl_allow_on_mobile_sum">Automatisch downloaden toestaan via een mobiele internetverbinding.</string> + <string name="pref_automatic_download_on_battery_title">Downloaden als het apparaat niet wordt opgeladen</string> <string name="pref_automatic_download_on_battery_sum">Downloaden toestaan als het apparaat niet wordt opgeladen</string> <string name="pref_parallel_downloads_title">Gelijktijdige downloads</string> - <string name="pref_episode_cache_title">Afleveringen cache</string> + <string name="pref_episode_cache_title">Afleveringscache</string> <string name="pref_theme_title_light">Licht</string> <string name="pref_theme_title_dark">Donker</string> + <string name="pref_theme_title_trueblack">Zwart (geschikt voor AMOLED)</string> <string name="pref_episode_cache_unlimited">Onbeperkt</string> <string name="pref_update_interval_hours_plural">uur</string> <string name="pref_update_interval_hours_singular">uur</string> <string name="pref_update_interval_hours_manual">Handmatig</string> <string name="pref_gpodnet_authenticate_title">Inloggen</string> - <string name="pref_gpodnet_authenticate_sum">Log in met je gpodder.net account om je abonnementen te synchroniseren.</string> - <string name="pref_gpodnet_logout_title">Log uit</string> - <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_authenticate_sum">Log in met je gpodder.net-account om je abonnementen te synchroniseren.</string> + <string name="pref_gpodnet_logout_title">Uitloggen</string> + <string name="pref_gpodnet_logout_toast">Uitgelogd</string> + <string name="pref_gpodnet_setlogin_information_title">Inloggegevens wijzigen</string> + <string name="pref_gpodnet_setlogin_information_sum">Wijzig de inloggegevens van je gpodder.net-account.</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_sync_changes_sum">Synchroniseer gewijzigde abonnementen en afleveringsstatussen 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_full_sync_sum">Synchroniseer alle abonnementen en afleveringsstatussen met gpodder.net.</string> + <string name="pref_gpodnet_sync_sum_last_sync_line">Vorige 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_title">Melding tonen bij synchronisatiefouten</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_playback_speed_sum">Pas de beschikbare snelheden aan voor de variabele audio-afspeelsnelheid</string> <string name="pref_fast_forward">Snelheid van vooruitspoelen</string> - <string name="pref_fast_forward_sum">Pas het aantal seconden aan waarmee wordt vooruitgespoeld per klik op de knop</string> - <string name="pref_rewind">Snelheid terugspoelen</string> - <string name="pref_rewind_sum">Pas het aantal seconden aan waarmee wordt teruggespoeld per klik op de knop</string> - <string name="pref_gpodnet_sethostname_title">Definieer hostname</string> - <string name="pref_gpodnet_sethostname_use_default_host">Gebruik standaard host</string> - <string name="pref_expandNotify_title">Bedienen via melding</string> - <string name="pref_expandNotify_sum">Altijd de bedieningsknoppen tonen bij de melding in het notificatiecentrum.</string> - <string name="pref_persistNotify_title">Behoud bedieningsknoppen</string> - <string name="pref_persistNotify_sum">Ook bedieningsknoppen in het notificatiecentrum en op het vergrendelingsscherm behouden als het afspelen gepauzeerd wordt.</string> + <string name="pref_fast_forward_sum">Pas het aantal seconden aan waarmee wordt vooruitgespoeld per druk op de knop</string> + <string name="pref_rewind">Snelheid van terugspoelen</string> + <string name="pref_rewind_sum">Pas het aantal seconden aan waarmee wordt teruggespoeld per druk op de knop</string> + <string name="pref_gpodnet_sethostname_title">Hostnaam instellen</string> + <string name="pref_gpodnet_sethostname_use_default_host">Standaardhost gebruiken</string> + <string name="pref_persistNotify_title">Bedieningsknoppen behouden</string> + <string name="pref_persistNotify_sum">Ook bedieningsknoppen op het meldings- en vergrendelscherm behouden als het afspelen gepauzeerd wordt.</string> <string name="pref_compact_notification_buttons_title">Bedieningsknoppen vergrendelscherm</string> - <string name="pref_compact_notification_buttons_sum">Bedieningsknopppen voor op het vergrendelscherm kiezen. De play/pauze knop wordt altijd getoond.</string> - <string name="pref_compact_notification_buttons_dialog_title">Selecteer maximaal %1$d knoppen.</string> - <string name="pref_compact_notification_buttons_dialog_error">U kunt slechts maximaal %1$d knoppen selecteren.</string> + <string name="pref_compact_notification_buttons_sum">Kies de bedieningsknoppen voor het vergrendelscherm. De knop afspelen/pauzeren wordt altijd getoond.</string> + <string name="pref_compact_notification_buttons_dialog_title">Kies maximaal %1$d knoppen</string> + <string name="pref_compact_notification_buttons_dialog_error">Je kunt maximaal %1$d knoppen kiezen.</string> <string name="pref_lockscreen_background_title">Achtergrondafbeelding vergrendelscherm</string> - <string name="pref_lockscreen_background_sum">Laat de afbeelding van de huidige aflevering zien op het vergrendelscherm. Ten gevolge van deze functie is de afbeelding ook beschikbaar voor andere apps.</string> - <string name="pref_showDownloadReport_title">Laat downloadrapport zien</string> - <string name="pref_showDownloadReport_sum">Genereer een rapport met fout-details als downloads mislukken</string> - <string name="pref_expand_notify_unsupport_toast">Android versies lager dan 4.1 ondersteunen geen knoppen in het notificatiecentrum.</string> + <string name="pref_lockscreen_background_sum">Toon de afbeelding van de huidige aflevering op het vergrendelscherm. Hierdoor is de afbeelding ook beschikbaar voor andere apps.</string> + <string name="pref_showDownloadReport_title">Downloadrapportage tonen</string> + <string name="pref_showDownloadReport_sum">Genereer een rapport met foutdetails als downloads mislukken.</string> + <string name="pref_expand_notify_unsupport_toast">Android-versies lager dan 4.1 ondersteunen geen knoppen op meldingen.</string> <string name="pref_queueAddToFront_sum">Nieuwe afleveringen aan het begin van de wachtrij toevoegen.</string> <string name="pref_queueAddToFront_title">Bovenaan wachtrij toevoegen</string> <string name="pref_smart_mark_as_played_disabled">Uitgeschakeld</string> - <string name="pref_image_cache_size_title">Grootte cachegeheugen</string> - <string name="pref_image_cache_size_sum">De groote van het cachegeheugen voor afbeeldingen aanpassen.</string> - <string name="crash_report_title">Crashreport</string> - <string name="crash_report_sum">Verstuur laatste crashreport via email</string> - <string name="send_email">Verstuur email</string> - <string name="experimental_pref">Experimentele functie(s)</string> - <string name="pref_sonic_title">Sonic mediaspeler</string> - <string name="pref_sonic_message">Gebruik AntennaPod\'s ingebouwde Sonic mediaspeler als een alternatief voor Prestissimo en de mediaspeler van Android.</string> + <string name="pref_image_cache_size_title">Grootte van afbeeldingscache</string> + <string name="pref_image_cache_size_sum">Pas de grootte aan van het cachegeheugen voor afbeeldingen.</string> + <string name="crash_report_title">Crashrapportage</string> + <string name="crash_report_sum">Verstuur laatste crashrapportage via e-mail</string> + <string name="send_email">E-mail versturen</string> + <string name="experimental_pref">Experimenteel</string> + <string name="pref_media_player_message">Kies welke mediaspeler gebruikt moet worden voor het afspelen van bestanden</string> <string name="pref_current_value">Huidige instelling: %1$s</string> <string name="pref_proxy_title">Proxy</string> <string name="pref_proxy_sum">Netwerkproxy instellen</string> - <string name="pref_faq">FAQ - veelgestelde vragen</string> - <string name="pref_known_issues">Reeds bekende bugs</string> - <string name="pref_no_browser_found">Geen browser gevonden</string> - <string name="pref_cast_title">Chromecast</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> + <string name="pref_faq">Veelgestelde vragen</string> + <string name="pref_known_issues">Bekende problemen</string> + <string name="pref_no_browser_found">Geen browser aangetroffen.</string> + <string name="pref_cast_title">Chromecast-ondersteuning</string> + <string name="pref_cast_message_play_flavor">Ondersteuning activeren voor draadloos afspelen via Cast-apparaten (zoals Chromecast, luidsprekers of Android TV)</string> + <string name="pref_cast_message_free_flavor">Voor Chromecast is software van derden vereist die niet beschikbaar is in deze versie van AntennaPod</string> <string name="pref_enqueue_downloaded_title">Gedownloade afleveringen in wachtrij</string> <string name="pref_enqueue_downloaded_summary">Voeg gedownloade afleveringen toe aan de wachtrij</string> + <string name="media_player_builtin">Ingebouwde Android-speler</string> + <string name="pref_videoBehavior_title">Bij verlaten van video</string> + <string name="pref_videoBehavior_sum">Wat te doen bij het verlaten van een spelende video</string> + <string name="stop_playback">Afspelen stoppen</string> + <string name="continue_playback">Audio af blijven spelen</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> + <string name="auto_flattr_enable">Automatisch flattr\'en inschakelen</string> + <string name="auto_flattr_after_percent">Flattr een aflevering zodra deze %d procent is afgespeeld</string> + <string name="auto_flattr_ater_beginning">Flattr de aflevering als het afspelen begint</string> + <string name="auto_flattr_ater_end">Flattr de aflevering als afspelen is gestopt</string> <!--Search--> <string name="search_hint">Zoeken naar afleveringen</string> - <string name="found_in_shownotes_label">Gevonden in de shownotes</string> + <string name="found_in_shownotes_label">Gevonden in de shownotities</string> <string name="found_in_chapters_label">Gevonden in de hoofdstukken</string> - <string name="found_in_authors_label">Gevonden in de makers</string> - <string name="found_in_feeds_label">Gevonden in de feeds</string> + <string name="found_in_authors_label">Gevonden bij de maker(s)</string> + <string name="found_in_feeds_label">Gevonden in de podcast</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_txtv_button_lable">Met OPML-bestanden kun je podcasts van de ene naar de andere podcatcher verplaatsen.</string> <string name="opml_import_option">Optie %1$d</string> - <string name="opml_import_explanation_1">Kies een bestand van een specifieke locatie via bestandsbeheer.</string> - <string name="opml_import_explanation_2">Kies een OPML bestand via een andere app, zoals Dropbox en Google Drive, of via uw bestandsbeheerder.</string> - <string name="opml_import_explanation_3">Ga naar een OPML bestand in apps zoals GMail, Dropbox en Google Drive om het met AntennaPod te openen.</string> - <string name="start_import_label">Start importeren</string> + <string name="opml_import_explanation_1">Kies een bestand via de bestandsbeheer.</string> + <string name="opml_import_explanation_2">Kies een OPML-bestand via een andere app, zoals Dropbox of Google Drive, of via je bestandsbeheerder.</string> + <string name="opml_import_explanation_3">Apps as Gmail, Dropbox, Google Drive en de meeste bestandsbeheerders kunnen OPML-bestanden <i>openen</i> <i>met</i> AntennaPod.</string> + <string name="start_import_label">Importeren starten</string> <string name="opml_import_label">OPML importeren</string> <string name="opml_directory_error">FOUT!</string> - <string name="reading_opml_label">OPML-bestand aan het lezen</string> - <string name="opml_reader_error">Er is iets misgegaan met het lezen van het OPML-bestand:</string> - <string name="opml_import_error_no_file">Geen bestand geselecteerd!</string> + <string name="reading_opml_label">Bezig met uitlezen van OPML-bestand...</string> + <string name="opml_reader_error">Er is iets misgegaan tijdens het lezen van het OPML-bestand:</string> + <string name="opml_import_error_no_file">Geen bestand gekozen!</string> <string name="select_all_label">Alles selecteren</string> - <string name="deselect_all_label">Alles deselecteren</string> - <string name="select_options_label">Selecteren…</string> + <string name="deselect_all_label">Alles de-selecteren</string> + <string name="select_options_label">Selecteren...</string> <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> - <string name="opml_export_success_sum"> Het OPML-bestand is in \u0020 geplaatst</string> + <string name="opml_export_label">OPML exporteren</string> + <string name="html_export_label">HTML exporteren</string> + <string name="exporting_label">Bezig met exporteren...</string> + <string name="export_error_label">Exportfout</string> + <string name="export_success_title">Geëxporteerd</string> + <string name="export_success_sum">Het geëxporteerde bestand is opgeslagen in:\n\n%1$s</string> <string name="opml_import_ask_read_permission">Toegang tot externe locaties is nodig om het OPML-bestand te kunnen lezen</string> <!--Sleep timer--> - <string name="set_sleeptimer_label">Slaap timer instellen</string> - <string name="disable_sleeptimer_label">Slaap timer uitschakelen</string> - <string name="enter_time_here_label">Voer tijd in</string> - <string name="sleep_timer_label">Slaap timer</string> + <string name="set_sleeptimer_label">Slaaptimer instellen</string> + <string name="disable_sleeptimer_label">Slaaptimer uitschakelen</string> + <string name="enter_time_here_label">Voer een tijd in</string> + <string name="sleep_timer_label">Slaaptimer</string> <string name="time_left_label">Resterende tijd:\u0020</string> - <string name="time_dialog_invalid_input">Ongeldige invoer, de tijd moet een geheel getal zijn</string> + <string name="time_dialog_invalid_input">Ongeldige invoer; de tijd moet een geheel getal zijn</string> <string name="timer_about_to_expire_label"><b>Als de timer bijna afloopt:</b></string> <string name="shake_to_reset_label">Schudden om opnieuw in te stellen</string> <string name="timer_vibration_label">Trillen</string> @@ -480,65 +506,65 @@ <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> + <string name="sleep_timer_enabled_label">Slaaptimer ingeschakeld</string> + <string name="sleep_timer_disabled_label">Slaaptimer uitgeschakeld</string> <!--gpodder.net--> <string name="gpodnet_taglist_header">CATEGORIEËN</string> - <string name="gpodnet_toplist_header">TOP PODCASTS</string> + <string name="gpodnet_toplist_header">POPULAIRE PODCASTS</string> <string name="gpodnet_suggestions_header">SUGGESTIES</string> - <string name="gpodnet_search_hint">Zoek gpodder.net</string> - <string name="gpodnetauth_login_title">Log in</string> - <string name="gpodnetauth_login_descr">Welkom bij het inlogproces van gpodder.net. Typ eerst je accountgegevens:</string> - <string name="gpodnetauth_login_butLabel">Log in</string> - <string name="gpodnetauth_login_register">Als u nog geen account heeft, kunt u er hier een aanmaken:\nhttps://gpodder.net/register/</string> + <string name="gpodnet_search_hint">gpodder.net doorzoeken</string> + <string name="gpodnetauth_login_title">Inloggen</string> + <string name="gpodnetauth_login_descr">Welkom bij het inlogproces van gpodder.net. Typ eerst je inloggegevens:</string> + <string name="gpodnetauth_login_butLabel">Inloggen</string> + <string name="gpodnetauth_login_register">Als je nog geen account hebt, dan kun je je hier registreren:\nhttps://gpodder.net/register/</string> <string name="username_label">Gebruikersnaam</string> <string name="password_label">Wachtwoord</string> - <string name="gpodnetauth_device_title">Apparaatselectie</string> - <string name="gpodnetauth_device_descr">Maak een nieuw apparaat aan om voor je gpodder.net account te gebruiken of kies een bestaande:</string> - <string name="gpodnetauth_device_deviceID">Device ID:\u0020</string> - <string name="gpodnetauth_device_caption">Apparaatnaam</string> - <string name="gpodnetauth_device_butCreateNewDevice">Maak een nieuw apparaat aan</string> - <string name="gpodnetauth_device_chooseExistingDevice">Kies een bestaand apparaat:</string> - <string name="gpodnetauth_device_errorEmpty">Apparaat ID mag niet leeg zijn</string> - <string name="gpodnetauth_device_errorAlreadyUsed">Apparaat ID al in gebruik</string> - <string name="gpodnetauth_device_caption_errorEmpty">Apparaatomschrijving kan niet leeg zijn</string> - <string name="gpodnetauth_device_butChoose">Kies</string> - <string name="gpodnetauth_finish_title">Login succesvol</string> - <string name="gpodnetauth_finish_descr">Gefeliciteerd! Jou gpodder.net account is nu verbonden met je apparaat. AntennaPod zal voortaan abonnementen op je apparaat automatisch met je gpodder.net account synchroniseren.</string> - <string name="gpodnetauth_finish_butsyncnow">Synchronisatie nu starten</string> + <string name="gpodnetauth_device_title">Apparaatkeuze</string> + <string name="gpodnetauth_device_descr">Creëer een nieuw apparaat voor je gpodder.net-account of kies een bestaand:</string> + <string name="gpodnetauth_device_deviceID">Apparaat-ID:\u0020</string> + <string name="gpodnetauth_device_caption">Omschrijving</string> + <string name="gpodnetauth_device_butCreateNewDevice">Nieuw apparaat creëren</string> + <string name="gpodnetauth_device_chooseExistingDevice">Bestaand apparaat kiezen:</string> + <string name="gpodnetauth_device_errorEmpty">Apparaat-ID mag niet blanco zijn</string> + <string name="gpodnetauth_device_errorAlreadyUsed">Apparaat-ID wordt al gebruikt</string> + <string name="gpodnetauth_device_caption_errorEmpty">Apparaatomschrijving mag niet blanco zijn</string> + <string name="gpodnetauth_device_butChoose">Kiezen</string> + <string name="gpodnetauth_finish_title">Ingelogd!</string> + <string name="gpodnetauth_finish_descr">Gefeliciteerd! Je gpodder.net-account is nu gekoppeld aan je apparaat. AntennaPod zal voortaan abonnementen automatisch synchroniseren met je gpodder.net-account.</string> + <string name="gpodnetauth_finish_butsyncnow">Nu synchroniseren</string> <string name="gpodnetauth_finish_butgomainscreen">Terug naar hoofdscherm</string> - <string name="gpodnetsync_auth_error_title">gpodder.net authenticatie fout</string> - <string name="gpodnetsync_auth_error_descr">Ongeldig gebruikersnaam of wachtwoord</string> - <string name="gpodnetsync_error_title">gpodder.net synchronisatie fout</string> + <string name="gpodnetsync_auth_error_title">gpodder.net - authenticatiefout</string> + <string name="gpodnetsync_auth_error_descr">Onjuiste gebruikersnaam of wachtwoord</string> + <string name="gpodnetsync_error_title">gpodder.net - synchronisatiefout</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> + <string name="gpodnetsync_pref_report_successful">Voltooid</string> + <string name="gpodnetsync_pref_report_failed">Mislukt</string> <!--Directory chooser--> - <string name="selected_folder_label">Geselecteerde map:</string> - <string name="create_folder_label">Map aanmaken</string> - <string name="choose_data_directory">Kies data map</string> - <string name="choose_data_directory_message">Kies de hoofdmap voor uw data. AntennaPod zal de benodigde submappen creeëren.</string> - <string name="choose_data_directory_permission_rationale">Toegang tot de externe opslag is nodig om de data-map aan te passen</string> - <string name="create_folder_msg">Maak een nieuwe map aan met de naam \"%1$s\"?</string> - <string name="create_folder_success">Nieuwe map aangemaakt</string> - <string name="create_folder_error_no_write_access">Kan in deze map niet schrijven</string> + <string name="selected_folder_label">Gekozen map:</string> + <string name="create_folder_label">Map creëren</string> + <string name="choose_data_directory">Kies de gegevensmap</string> + <string name="choose_data_directory_message">Kies de hoofdmap voor je gegevens. AntennaPod zal de benodigde submappen creëren.</string> + <string name="choose_data_directory_permission_rationale">Toegang tot externe opslag is nodig om de gegevensmap te wijzigen</string> + <string name="create_folder_msg">Wil je een nieuwe map creëren met de naam \"%1$s\"?</string> + <string name="create_folder_success">Nieuwe map gecreëerd</string> + <string name="create_folder_error_no_write_access">Kan niet schrijven naar map</string> <string name="create_folder_error_already_exists">Map bestaat al</string> - <string name="create_folder_error">Kon map niet aanmaken</string> + <string name="create_folder_error">Kan map niet creëren</string> <string name="folder_does_not_exist_error">\"%1$s\" bestaat niet</string> - <string name="folder_not_readable_error">\"%1$s\" kan niet gelezen worden</string> - <string name="folder_not_writable_error">in \"%1$s\" kan geen data geschreven worden</string> + <string name="folder_not_readable_error">\"%1$s\" kan niet worden uitgelezen</string> + <string name="folder_not_writable_error">Kan niet wegschrijven naar \"%1$s\"</string> <string name="folder_not_empty_dialog_title">Map is niet leeg</string> - <string name="folder_not_empty_dialog_msg">De map die u heeft gekozen is niet leeg. Gedownloade media en andere bestanden zullen rechtstreeks in deze map geplaatst worden. Toch doorgaan?</string> - <string name="set_to_default_folder">Kies default map</string> - <string name="pref_pausePlaybackForFocusLoss_sum">Het afspelen onderbreken in plaats van het volume te verlagen wanneer er een andere app geluiden af wil spelen</string> + <string name="folder_not_empty_dialog_msg">De map die je hebt gekozen is niet leeg. Gedownloade media en andere bestanden worden rechtstreeks in deze map geplaatst. Wil je toch doorgaan?</string> + <string name="set_to_default_folder">Standaardmap kiezen</string> + <string name="pref_pausePlaybackForFocusLoss_sum">Het afspelen onderbreken in plaats van het volume te verlagen als een andere app geluiden wil afspelen</string> <string name="pref_pausePlaybackForFocusLoss_title">Pauzeren bij onderbrekingen</string> - <string name="pref_resumeAfterCall_sum">Afspelen hervatten na beëindigen telefoongesprek</string> + <string name="pref_resumeAfterCall_sum">Afspelen hervatten na beëindigen van telefoongesprek</string> <string name="pref_resumeAfterCall_title">Hervatten na gesprek</string> - <string name="pref_restart_required">AntennaPod moet opnieuw worden opgestart om deze wijziging door te voeren.</string> + <string name="pref_restart_required">AntennaPod moet opnieuw worden gestart om deze wijziging toe te passen.</string> <!--Online feed view--> <string name="subscribe_label">Abonneren</string> <string name="subscribed_label">Geabonneerd</string> - <string name="downloading_label">Downloaden…</string> + <string name="downloading_label">Bezig met downloaden...</string> <!--Content descriptions for image buttons--> <string name="rewind_label">Terugspoelen</string> <string name="fast_forward_label">Vooruitspoelen</string> @@ -546,45 +572,45 @@ <string name="media_type_video_label">Video</string> <string name="navigate_upwards_label">Navigeer naar boven</string> <string name="status_downloading_label">Aflevering wordt gedownload</string> - <string name="in_queue_label">Aflevering is in de queue</string> - <string name="drag_handle_content_description">Item verslepen om het te verplaatsen</string> + <string name="in_queue_label">Aflevering staat in de wachtrij</string> + <string name="drag_handle_content_description">Versleep dit item om de positie te veranderen</string> <string name="load_next_page_label">Volgende pagina laden</string> <!--Feed information screen--> <string name="authentication_label">Authenticatie</string> - <string name="authentication_descr">Gebruikersnaam en wachtwoord aanpassen voor deze podcast</string> + <string name="authentication_descr">Gebruikersnaam en wachtwoord wijzigen voor deze podcast en bijbehorende afleveringen.</string> <string name="auto_download_settings_label">Instellingen voor Automatisch downloaden</string> - <string name="episode_filters_label">Afleveringenfilter</string> + <string name="episode_filters_label">Afleveringsfilter</string> <string name="episode_filters_description">Lijst van zoektermen die bepalen of een aflevering meegenomen of uitgesloten wordt bij automatisch downloaden</string> <string name="episode_filters_include">Meenemen</string> <string name="episode_filters_exclude">Uitsluiten</string> <string name="episode_filters_hint">Losse woorden \n\"Meerdere tussen aanhalingstekens\"</string> - <string name="keep_updated">Up to date houden</string> + <string name="keep_updated">Bijgewerkt houden</string> <!--Progress information--> - <string name="progress_upgrading_database">Database upgraden</string> + <string name="progress_upgrading_database">Bezig met upgraden van databank...</string> <!--AntennaPodSP--> - <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="sp_apps_importing_feeds_msg">Bezig met importeren van abonnementen uit eenmalige apps...</string> + <string name="search_itunes_label">iTunes doorzoeken</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> + <string name="selected_all_label">Alle afleveringen geselecteerd</string> <string name="none_label">Geen</string> - <string name="deselected_all_label">Alle afleveringen deselecteren</string> + <string name="deselected_all_label">Alle afleveringen gede-selecteerd</string> <string name="played_label">Afgespeeld</string> - <string name="selected_played_label">Alle afgespeelde afleveringen selecteren</string> + <string name="selected_played_label">Alle afgespeelde afleveringen geselecteerd</string> <string name="unplayed_label">Niet afgespeeld</string> - <string name="selected_unplayed_label">Niet afgespeelde afleveringen geselecteerd</string> + <string name="selected_unplayed_label">Niet-afgespeelde afleveringen geselecteerd</string> <string name="downloaded_label">Gedownload</string> - <string name="selected_downloaded_label">Gedownloadde afleveringen geselecteerd</string> + <string name="selected_downloaded_label">Gedownloade afleveringen geselecteerd</string> <string name="not_downloaded_label">Niet gedownload</string> - <string name="selected_not_downloaded_label">Niet gedownloadde afleveringen geselecteerd</string> + <string name="selected_not_downloaded_label">Niet-gedownloade afleveringen geselecteerd</string> <string name="queued_label">In de wachtrij</string> - <string name="selected_queued_label">Afleveringen in de wachtrij selecteren</string> + <string name="selected_queued_label">Afleveringen in de wachtrij geselecteerd</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> + <string name="selected_has_media_label">Afleveringen met media geselecteerd</string> <!--Sort--> <string name="sort_title_a_z">Titel (A \u2192 Z)</string> <string name="sort_title_z_a">Titel (A \u2192 A)</string> @@ -593,9 +619,9 @@ <string name="sort_duration_short_long">Lengte (kort \u2192 lang)</string> <string name="sort_duration_long_short">Lengte (lang \u2192 kort)</string> <!--Rating dialog--> - <string name="rating_title">Wat vind u van AntennaPod?</string> - <string name="rating_message">We zouden het op prijs stellen als u even de tijd kunt nemen om AntennaPod te beoordelen.</string> - <string name="rating_never_label">Nee, bedankt.</string> + <string name="rating_title">Wat vind je van AntennaPod?</string> + <string name="rating_message">We stellen het op prijs als je even de tijd neemt om AntennaPod te beoordelen.</string> + <string name="rating_never_label">Nee, bedankt</string> <string name="rating_later_label">Herinner me later</string> <string name="rating_now_label">Ja, doen we!</string> <!--Audio controls--> @@ -604,43 +630,52 @@ <string name="volume">Volume</string> <string name="left_short">L</string> <string name="right_short">R</string> - <string name="audio_effects">Terugmixen</string> + <string name="audio_effects">Audio-effecten</string> <string name="stereo_to_mono">Stereo terugmixen tot monogeluid op beide kanalen</string> <string name="sonic_only">Sonic vereist</string> <!--proxy settings--> <string name="proxy_type_label">Type</string> <string name="host_label">Host</string> <string name="port_label">Poort</string> - <string name="optional_hint">(Optioneel)</string> + <string name="optional_hint">(optioneel)</string> <string name="proxy_test_label">Testen</string> - <string name="proxy_checking">Controleren…</string> - <string name="proxy_test_successful">Test succesvol</string> + <string name="proxy_checking">Bezig met controleren...</string> + <string name="proxy_test_successful">Test geslaagd</string> <string name="proxy_test_failed">Test mislukt</string> - <string name="proxy_host_empty_error">Host kan niet leeg zijn</string> - <string name="proxy_host_invalid_error">Host is geen geldig IP-adres of domein</string> - <string name="proxy_port_invalid_error">Poortnummer ongeldig</string> + <string name="proxy_host_empty_error">Host mag niet blanco zijn</string> + <string name="proxy_host_invalid_error">Host is geen geldig IP-adres of domeinnaam</string> + <string name="proxy_port_invalid_error">Ongeldig poortnummer</string> <!--Database import/export--> - <string name="import_export">Database im-/exporteren</string> - <string name="import_export_warning">Hiermee kun je de podcasts waarop je geabonneerd bent en de afgespeelde afleveringen naar een ander apparaat kopiëren\n\nGeëxporteerde databases kunnen alleen geïmporteerd worden in dezelfde versie van AntennaPod (zie \'Over AntennaPod\' in de instellingen). Het importeren naar een andere versie kan onverwachte problemen opleveren.\n\nNa het importeren kunnen afleveringen als \'gedownload\' aangemerkt zijn, terwijl dit niet het geval is. Druk op de afspeelknop naast de afleveringen om AntennaPod dit te laten detecteren.</string> + <string name="import_export">Databank im-/exporteren</string> + <string name="import_export_warning">Met deze experimentele functie kun je je abonnementen en afgespeelde afleveringen overzetten naar een ander apparaat.\n\nGeëxporteerde databanken kunnen alleen worden geïmporteerd in dezelfde versie van AntennaPod, anders kunnen zich problemen voordoen.\n\nNa het importeren kunnen afleveringen als \'gedownload\' aangemerkt zijn, terwijl dit niet het geval is. Druk op de afspeelknop om AntennaPod dit te laten detecteren.</string> <string name="label_import">Importeren</string> <string name="label_export">Exporteren</string> - <string name="import_select_file">Selecteer bestand om te importeren</string> - <string name="export_ok">Succesvol geëxporteerd. De database is naar de SD-kaart geschreven.</string> - <string name="import_ok">Succesvol geïmporteerd\n\nDruk op OK om AntennaPod te herstarten.</string> + <string name="import_select_file">Kies een te importeren bestand</string> + <string name="export_ok">Export voltooid.</string> + <string name="import_ok">Geïmporteerd.\n\nDruk op Oké om AntennaPod opnieuw te starten.</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> - <string name="cast_failed_to_pause">Pauzeren van afspelen is mislukt</string> + <string name="cast_disconnect_label">Cast-verbinding verbreken</string> + <string name="cast_not_castable">De geselecteerde media is niet compatibel met het cast-apparaat</string> + <string name="cast_failed_to_play">Afspelen mislukt</string> + <string name="cast_failed_to_stop">Stoppen mislukt</string> + <string name="cast_failed_to_pause">Pauzeren mislukt</string> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> - <string name="cast_failed_setting_volume">Het aanpassen van het volume is mislukt</string> - <string name="cast_failed_no_connection">Er is geen verbinding met het Cast apparaat</string> - <string name="cast_failed_no_connection_trans">De verbinding met het Cast apparaat is verloren. Antennapod probeert de verbinding te herstellen. Wacht aub een paar seconden en probeer opnieuw.</string> - <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> + <string name="cast_failed_setting_volume">Volume aanpassen mislukt</string> + <string name="cast_failed_no_connection">Er is geen verbinding met het Cast-apparaat</string> + <string name="cast_failed_no_connection_trans">De verbinding met het Cast-apparaat is verbroken; Antennapod probeert de verbinding te herstellen. Wacht een paar seconden en probeer het opnieuw.</string> + <string name="cast_failed_perform_action">Actie kan niet worden uitgevoerd</string> + <string name="cast_failed_status_request">Synchroniseren met Cast-apparaat mislukt</string> + <string name="cast_failed_seek">Opzoeken van nieuwe positie op Cast-apparaat mislukt</string> + <string name="cast_failed_receiver_player_error">Ernstige fout opgetreden op het afspelende Cast-apparaat</string> + <string name="cast_failed_media_error_skipping">Kan media niet afspelen. Bezig met overslaan...</string> + <!--Notification channels--> + <string name="notification_channel_user_action">Actie vereist</string> + <string name="notification_channel_user_action_description">Tonen als een actie vereist is, bijvoorbeeld als je een wachtwoord moet invoeren.</string> + <string name="notification_channel_downloading">Bezig met downloaden...</string> + <string name="notification_channel_downloading_description">Tonen als er iets wordt gedownload.</string> + <string name="notification_channel_playing">Nu aan het afspelen</string> + <string name="notification_channel_playing_description">Hiermee kun je het afspelen bedienen. Dit is de voornaamste melding tijdens het afspelen van een podcast.</string> + <string name="notification_channel_error">Foutmeldingen</string> + <string name="notification_channel_error_description">Tonen als er iets is misgegaan, bijvoorbeeld als downloaden of synchroniseren mislukt is.</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 2e3b9bd53..de0892b73 100644 --- a/core/src/main/res/values-no-rNB/strings.xml +++ b/core/src/main/res/values-no-rNB/strings.xml @@ -54,7 +54,6 @@ <string name="yes">Ja</string> <string name="no">Nei</string> <string name="reset">Tilbakestill</string> - <string name="author_label">Opphavsperson</string> <string name="language_label">SprÃ¥k</string> <string name="url_label">URL</string> <string name="podcast_settings_label">Innstillinger</string> @@ -102,25 +101,13 @@ <string name="mark_all_read_label">Marker alle som avspilt</string> <string name="mark_all_read_msg">Marker alle episoder som avspilt</string> <string name="mark_all_read_confirmation_msg">Vennligst bekreft at du ønsker Ã¥ markere alle episoder som avspilt.</string> - <string name="mark_all_read_feed_confirmation_msg">Vennligst bekreft at du ønsker Ã¥ markere alle episoder i denne strømmen som avspilt.</string> <string name="mark_all_seen_label">Marker alle som sett</string> - <string name="mark_all_seen_msg">Marker alle episoder som sett</string> <string name="mark_all_seen_confirmation_msg">Vennligst bekreft at du ønsker Ã¥ markere alle episoder som sett.</string> <string name="show_info_label">Vis informasjon</string> - <string name="rename_feed_label">Endre navn pÃ¥ podcast</string> - <string name="remove_feed_label">Fjern podcast</string> <string name="share_label">Del ...</string> - <string name="share_link_label">Del lenke</string> <string name="share_file_label">Del fil</string> - <string name="share_link_with_position_label">Del lenke med plassering</string> <string name="share_feed_url_label">Del strømmens URL</string> - <string name="share_item_url_label">Del episodens URL</string> - <string name="share_item_url_with_position_label">Del episodens URL med posisjon</string> - <string name="feed_delete_confirmation_msg">Vennligst bekreft at du ønsker Ã¥ slette strømmen \"%1$s\" og alle episoder fra denne strømmen som du har lastet ned.</string> - <string name="feed_remover_msg">Fjerner strøm</string> - <string name="load_complete_feed">Oppdater hele strømmen</string> <string name="hide_episodes_title">Skjul episoder</string> - <string name="episode_actions">Lagre handlinger</string> <string name="hide_unplayed_episodes_label">Ikke avspilt</string> <string name="hide_paused_episodes_label">Pauset</string> <string name="hide_played_episodes_label">Avspilt</string> @@ -227,7 +214,6 @@ <string name="date">PÃ¥ dato</string> <string name="duration">PÃ¥ varighet</string> <string name="episode_title">Episodetittel</string> - <string name="feed_title">Strømtittel</string> <string name="ascending">Økende</string> <string name="descending">Synkende</string> <string name="clear_queue_confirmation_msg">Vennligst bekreft at du ønsker Ã¥ slette ALLE elementer i køen</string> @@ -264,7 +250,6 @@ <string name="enable_sonic">Skru pÃ¥ Sonic</string> <!--Empty list labels--> <string name="no_items_label">Det er ingen objekter pÃ¥ denne listen.</string> - <string name="no_feeds_label">Du abonnerer ikke pÃ¥ noen strømmer enda.</string> <string name="no_chapters_label">Denne episoden har ingen kapitler.</string> <string name="no_shownotes_label">Denne episoden har ingen shownotater</string> <!--Preferences--> @@ -273,13 +258,11 @@ <string name="other_pref">Annet</string> <string name="about_pref">Om</string> <string name="queue_label">Queue</string> - <string name="services_label">Tjenester</string> <string name="flattr_label">Flattr</string> <string name="pref_episode_cleanup_title">Episodeopprydding</string> <string name="pref_pauseOnDisconnect_sum">Sett playback pÃ¥ pause nÃ¥r hodetelefoner eller bluetooth er frakoblet</string> <string name="pref_unpauseOnHeadsetReconnect_sum">Gjenoppta avspilling nÃ¥r hodetelefoner gjeninnkoples</string> <string name="pref_unpauseOnBluetoothReconnect_sum">Fortsett avspilling nÃ¥r bluetooth er tilkoblet igjen</string> - <string name="pref_hardwareForwardButtonSkips_sum">Ved pressing av hardware forover-knapp hopp til neste episode istedenfor forover-spoling</string> <string name="pref_hardwarePreviousButtonRestarts_title">Forriv</string> <string name="pref_followQueue_sum">Hopp til neste element i køen nÃ¥r avspillingen er ferdig</string> <string name="pref_auto_delete_sum">Slett episode nÃ¥r avspillingen er ferdig</string> @@ -327,7 +310,6 @@ <string name="pref_nav_drawer_feed_order_title">Velg rekkefølge pÃ¥ abbonement</string> <string name="pref_nav_drawer_feed_order_sum">Endre rekkefølgen pÃ¥ abbonementene dine</string> <string name="pref_nav_drawer_feed_counter_title">Velg abbonementsteller</string> - <string name="pref_nav_drawer_feed_counter_sum">Endre informasjonen vist av abonnementstelleren</string> <string name="pref_set_theme_sum">Endre utseendet til AntennaPod</string> <string name="pref_automatic_download_title">Automatisk nedlasting</string> <string name="pref_automatic_download_sum">Konfigurer automatisk nedlasting av episoder.</string> @@ -362,8 +344,6 @@ <string name="pref_playback_speed_sum">Egendefiner hastighetene tilgjengelig for variabel avspillingshastighet</string> <string name="pref_gpodnet_sethostname_title">Sett vertsnavn</string> <string name="pref_gpodnet_sethostname_use_default_host">Bruk standard vert</string> - <string name="pref_expandNotify_title">Utvid varsel</string> - <string name="pref_expandNotify_sum">Utvider alltid varselet for Ã¥ inkludere avspillingsknapper.</string> <string name="pref_persistNotify_title">Vedvarende avspillingskontroller</string> <string name="pref_persistNotify_sum">Behold varsel- og lÃ¥seskjermkontroller nÃ¥r avspilling er satt pÃ¥ pause.</string> <string name="pref_compact_notification_buttons_title">Velg lÃ¥seskjermsknapper</string> @@ -381,8 +361,6 @@ <string name="crash_report_sum">Send den siste kræsj-rapporten via e-post</string> <string name="send_email">Send e-post</string> <string name="experimental_pref">Eksperimentell</string> - <string name="pref_sonic_title">Sonic mediaspiller</string> - <string name="pref_sonic_message">Bruk innebygd Sonic mediaspiller som en erstatning for Androids mediaspiller og Prestissimo</string> <string name="pref_faq">FAQ</string> <string name="pref_known_issues">Kjente problemer</string> <string name="pref_no_browser_found">Ingen nettleser funnet.</string> @@ -421,8 +399,6 @@ <string name="html_export_label">HTML eksport</string> <string name="exporting_label">Eksporterer...</string> <string name="export_error_label">Eksporteringserror</string> - <string name="opml_export_success_title">OPML-import vellykket.</string> - <string name="opml_export_success_sum">.opml-filen ble skrevet til:\u0020</string> <string name="opml_import_ask_read_permission">Tilgang til ekstern lagring er nødvendig for Ã¥ lese OPML filen</string> <!--Sleep timer--> <string name="set_sleeptimer_label">Sett opp sovetimer</string> @@ -592,4 +568,5 @@ <string name="cast_failed_to_stop">Feilter Ã¥ stoppe avspillingen av media</string> <string name="cast_failed_to_pause">Feilet Ã¥ pause avspillingen av media</string> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-no/strings.xml b/core/src/main/res/values-no/strings.xml index acf3abe75..2d9481b84 100644 --- a/core/src/main/res/values-no/strings.xml +++ b/core/src/main/res/values-no/strings.xml @@ -36,4 +36,5 @@ <!--Database import/export--> <!--Casting--> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-pl-rPL/strings.xml b/core/src/main/res/values-pl-rPL/strings.xml index 4839ef60c..d77236577 100644 --- a/core/src/main/res/values-pl-rPL/strings.xml +++ b/core/src/main/res/values-pl-rPL/strings.xml @@ -22,6 +22,7 @@ <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> + <string name="synchronizing">Synchronizowanie...</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> @@ -56,7 +57,6 @@ <string name="yes">Tak</string> <string name="no">Nie</string> <string name="reset">Reset</string> - <string name="author_label">Autor</string> <string name="language_label">JÄ™zyk</string> <string name="url_label">URL</string> <string name="podcast_settings_label">Ustawienia</string> @@ -107,24 +107,13 @@ <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="mark_all_seen_msg">Zaznacz wszystkie Odcinki jako obejrzane</string> <string name="mark_all_seen_confirmation_msg">ProszÄ™ potwierdzić chęć zaznaczenia wszystkich odcinków jako obejrzanych.</string> <string name="show_info_label">Pokaż informacje</string> - <string name="rename_feed_label">ZmieÅ„ nazwÄ™ podcast-u</string> - <string name="remove_feed_label">UsuÅ„ podcast</string> <string name="share_label">UdostÄ™pnij...</string> - <string name="share_link_label">UdostÄ™pnij stronÄ™</string> - <string name="share_link_with_position_label">UdostÄ™pnij link z aktualnÄ… pozycjÄ…</string> + <string name="share_file_label">UdostÄ™pnij plik</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 kanaÅ‚u \"%1$s\" 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> @@ -144,6 +133,7 @@ <string name="stream_label">StrumieÅ„</string> <string name="remove_label">UsuÅ„</string> <string name="delete_label">UsuÅ„</string> + <string name="delete_failed">Nie można usunąć pliku. Restart urzÄ…dzenia może w tym pomóc.</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> @@ -168,6 +158,9 @@ <string name="download_failed">Operacja nie powiodÅ‚a siÄ™</string> <string name="download_pending">Pobieranie w toku</string> <string name="download_running">Pobieram</string> + <string name="download_error_details">Szczegóły</string> + <string name="download_error_details_message">%1$s \n\nAdres pliku:\n%2$s +</string> <string name="download_error_device_not_found">Nie znaleziono urzÄ…dzenia docelowego</string> <string name="download_error_insufficient_space">NiewystarczajÄ…ca ilość pamiÄ™ci</string> <string name="download_error_file_error">BÅ‚Ä…d pliku</string> @@ -236,7 +229,6 @@ <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> @@ -274,7 +266,6 @@ <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--> @@ -283,7 +274,6 @@ <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> @@ -291,7 +281,6 @@ <string name="pref_unpauseOnHeadsetReconnect_sum">Wznów odtwarzanie kiedy sÅ‚uchawki zostanÄ… podÅ‚Ä…czone ponownie</string> <string name="pref_unpauseOnBluetoothReconnect_sum">Wznów odtwarzanie po przywróceniu poÅ‚Ä…czenia Bluetooth</string> <string name="pref_hardwareForwardButtonSkips_title">Przycisk \'Do przodu\' pomija odcinek</string> - <string name="pref_hardwareForwardButtonSkips_sum">PrzyciÅ›niÄ™cie fizycznego przycisku \'Do przodu\' przeskakuje do nastÄ™pnego odcinka zamiast przewijania</string> <string name="pref_hardwarePreviousButtonRestarts_title">Przycisk wstecz restartuje</string> <string name="pref_hardwarePreviousButtonRestarts_sum">Podczas odtwarzania przycisk wstecz restartuje zamiast przewijać</string> <string name="pref_followQueue_sum">Przeskocz do nastÄ™pnego elementu kolejki po zakoÅ„czeniu odtwarzania</string> @@ -301,6 +290,8 @@ <string name="pref_smart_mark_as_played_title">Inteligentnie oznacz jako odtworzone</string> <string name="pref_skip_keeps_episodes_sum">Zachowuje pominiÄ™te odcinki w kolejce</string> <string name="pref_skip_keeps_episodes_title">Zachowaj pominiÄ™te odcinki</string> + <string name="pref_favorite_keeps_episodes_sum">Zachowaj odcinki gdy sÄ… oznaczone jako Ulubione</string> + <string name="pref_favorite_keeps_episodes_title">Zachowaj Ulubione 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> @@ -338,12 +329,13 @@ <string name="pref_nav_drawer_feed_order_title">Ustaw kolejność subskrypcji</string> <string name="pref_nav_drawer_feed_order_sum">ZmieÅ„ kolejność subskrybowanych kanałów</string> <string name="pref_nav_drawer_feed_counter_title">Ustaw licznik subskrypcji</string> - <string name="pref_nav_drawer_feed_counter_sum">ZmieÅ„ informacjÄ™ wyÅ›wietlanÄ… przez licznik subskrypcji</string> <string name="pref_set_theme_sum">ZmieÅ„ wyglÄ…d AntennaPod.</string> <string name="pref_automatic_download_title">Automatyczne pobieranie</string> <string name="pref_automatic_download_sum">Skonfiguruj automatyczne pobieranie odcinków.</string> <string name="pref_autodl_wifi_filter_title">WÅ‚Ä…cz filtr Wi-Fi</string> <string name="pref_autodl_wifi_filter_sum">Zezwól na automatyczne pobieranie tylko dla okreÅ›lonych sieci Wi-Fi.</string> + <string name="pref_autodl_allow_on_mobile_title">Pobierz przy użyciu komórkowego transferu danych</string> + <string name="pref_autodl_allow_on_mobile_sum">Zezwól na automatyczne pobieranie przy użyciu komórkowego transferu danych</string> <string name="pref_automatic_download_on_battery_title">Pobieraj, gdy nie Å‚aduje</string> <string name="pref_automatic_download_on_battery_sum">Zezwól na automatyczne pobieranie, gdy bateria nie jest Å‚adowana.</string> <string name="pref_parallel_downloads_title">Liczba równolegÅ‚ych pobieraÅ„</string> @@ -378,8 +370,6 @@ <string name="pref_rewind_sum">Dostosuj liczbÄ™ sekund do przeskoczenia przy klikniÄ™ciu przewijania 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> @@ -400,8 +390,6 @@ <string name="crash_report_sum">WyÅ›lij ostatni raport o bÅ‚Ä™dach przez e-mail</string> <string name="send_email">WyÅ›lij e-mail</string> <string name="experimental_pref">Eksperymentalne</string> - <string name="pref_sonic_title">Odtwarzacz mediów Sonic</string> - <string name="pref_sonic_message">Użyj wbudowanego odtwarzacza Sonic jako oprogramowanie zastÄ™pcze do natywnego odtwarzacza Android i Prestissimo</string> <string name="pref_current_value">Aktualna wartość: %1$s</string> <string name="pref_proxy_title">Proxy</string> <string name="pref_proxy_sum">Ustaw proxy sieciowe</string> @@ -411,6 +399,7 @@ <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> + <string name="pref_enqueue_downloaded_title">Rzeczy z kolejki pobrane</string> <string name="pref_enqueue_downloaded_summary">Dodaj pobrane odcinki do kolejki</string> <!--Auto-Flattr dialog--> <string name="auto_flattr_enable">WÅ‚Ä…cz automatyczne wspieranie na flattr.</string> @@ -421,8 +410,6 @@ <string name="search_hint">Szukaj odcinków</string> <string name="found_in_shownotes_label">Znalezione w notatkach dotyczÄ…cych show</string> <string name="found_in_chapters_label">Znaleziono w rozdziaÅ‚ach</string> - <string name="found_in_authors_label">Znaleziono wÅ›ród autorów</string> - <string name="found_in_feeds_label">Znaleziono wÅ›ród kanałów</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> @@ -448,8 +435,8 @@ <string name="html_export_label">Eksport HTML</string> <string name="exporting_label">Eksportowanie...</string> <string name="export_error_label">BÅ‚Ä…d eksportu</string> - <string name="opml_export_success_title">Eksport OPML udany.</string> - <string name="opml_export_success_sum">Plik .opml zostaÅ‚ zapisany do:\u0020</string> + <string name="export_success_title">Export zakoÅ„czony powodzeniem</string> + <string name="export_success_sum">Wyeksportowany plik zostaÅ‚ zapisany w:\n\n %1$s</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> @@ -624,6 +611,13 @@ https://gpodder.net/register/</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> <!--Database import/export--> + <string name="import_export">Import/Export bazy danych</string> + <string name="import_export_warning">Ta eksperymentalna funkcja może zostać użyta do przeniesienia Twoich subskrypcji i już obejrzanych odcinków na inne urzÄ…dzenie.\n\n Wyeksportowana baza może zostać zaimportowana jedynie takÄ… samÄ… wersjÄ… programu AntennaPod. W innym przypadku może to spowodować nieprzewidziane zachowanie programu.\n\n Po zaimportowaniu, odcinki mogÄ… być pokazane jako pobrane pomimo tego iż nie zostaÅ‚y pobrane. Wystarczy kliknąć odtwórz odcinek aby AntennaPod wykryÅ‚ poprawny stan pliku.</string> + <string name="label_import">Import</string> + <string name="label_export">Export</string> + <string name="import_select_file">Wybierz plik do Importowania</string> + <string name="export_ok">Export zakoÅ„czony powodzeniem</string> + <string name="import_ok">Import zakoÅ„czony powodzeniem.\n\nNaciÅ›nij OK aby zrestartować AntennaPod</string> <!--Casting--> <string name="cast_media_route_menu_title">Odtwarzaj na...</string> <string name="cast_disconnect_label">RozÅ‚Ä…cz sesjÄ™</string> @@ -640,4 +634,5 @@ https://gpodder.net/register/</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> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-pl/strings.xml b/core/src/main/res/values-pl/strings.xml index 097417900..6a640a0ee 100644 --- a/core/src/main/res/values-pl/strings.xml +++ b/core/src/main/res/values-pl/strings.xml @@ -67,7 +67,6 @@ <!--Empty list labels--> <!--Preferences--> <string name="queue_label">Kolejka</string> - <string name="services_label">UsÅ‚ugi</string> <string name="pref_downloadMediaOnWifiOnly_sum">Pobieraj pliki tylko przez WiFi</string> <string name="refreshing_label">OdÅ›wieżanie</string> <string name="user_interface_label">Interfejs Użytkownika</string> @@ -97,4 +96,5 @@ <!--Database import/export--> <!--Casting--> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-pt-rBR/strings.xml b/core/src/main/res/values-pt-rBR/strings.xml index fc8633b1f..57ec3573c 100644 --- a/core/src/main/res/values-pt-rBR/strings.xml +++ b/core/src/main/res/values-pt-rBR/strings.xml @@ -1,6 +1,7 @@ <?xml version='1.0' encoding='UTF-8'?> <resources xmlns:tools="http://schemas.android.com/tools"> <!--Activitiy and fragment titles--> + <string name="feed_update_receiver_name">Atualizar Assinaturas</string> <string name="feeds_label">Feeds</string> <string name="statistics_label">EstatÃsticas</string> <string name="add_feed_label">Adicionar Podcast</string> @@ -56,7 +57,6 @@ <string name="yes">Sim</string> <string name="no">Não</string> <string name="reset">Resetar</string> - <string name="author_label">Autor</string> <string name="language_label">Idioma</string> <string name="url_label">URL</string> <string name="podcast_settings_label">Configurações</string> @@ -105,24 +105,12 @@ <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="mark_all_seen_msg">Todos os episódios marcados como vistos</string> <string name="mark_all_seen_confirmation_msg">Confirme se deseja marcar todos os episódios como vistos.</string> <string name="show_info_label">Mostrar informação</string> - <string name="rename_feed_label">Renomear o Podcast</string> - <string name="remove_feed_label">Remover Podcast</string> <string name="share_label">Compartilhar...</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 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">Confirme se deseja deletar o feed \"%1$s\" e todos os episódios baixados desse 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 reproduzido</string> <string name="hide_paused_episodes_label">Pausado</string> <string name="hide_played_episodes_label">Reproduzido</string> @@ -232,7 +220,6 @@ <string name="date">Data</string> <string name="duration">Duração</string> <string name="episode_title">Titulo do Episodio</string> - <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ê deseja limpar TODOS episódios da fila</string> @@ -270,7 +257,6 @@ <string name="enable_sonic">Habilitar Sonic</string> <!--Empty list labels--> <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.</string> <!--Preferences--> @@ -279,7 +265,6 @@ <string name="other_pref">Outros</string> <string name="about_pref">Sobre</string> <string name="queue_label">Fila</string> - <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 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> @@ -287,7 +272,6 @@ <string name="pref_unpauseOnHeadsetReconnect_sum">Continuar a reprodução quando os fones de ouvido forem reconectados</string> <string name="pref_unpauseOnBluetoothReconnect_sum">Continuar a reprodução quando o bluetooth reconectar</string> <string name="pref_hardwareForwardButtonSkips_title">Botão avançar pula</string> - <string name="pref_hardwareForwardButtonSkips_sum">Quando pressionar um botão fÃsico, avançar para o próximo episódio ao invés de avançar a reprodução</string> <string name="pref_hardwarePreviousButtonRestarts_title">Botão anterior reinicia</string> <string name="pref_hardwarePreviousButtonRestarts_sum">Reinicia a reprodução atual ao pressionar o botão fÃsico anterior ao invés de retroceder</string> <string name="pref_followQueue_sum">Pular para próximo item da fila quando a reprodução terminar</string> @@ -333,8 +317,7 @@ <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> - <string name="pref_nav_drawer_feed_counter_sum">Mudar a informação exibida pelo contador de assinaturas</string> + <string name="pref_nav_drawer_feed_counter_title">Configurar Contador de Assinaturas</string> <string name="pref_set_theme_sum">Altera a aparência do AntennaPod</string> <string name="pref_automatic_download_title">Download automático</string> <string name="pref_automatic_download_sum">Configurar download automático de episódios.</string> @@ -374,8 +357,6 @@ <string name="pref_rewind_sum">Personalize os segundos para voltar quando o botão retroceder for clicado</string> <string name="pref_gpodnet_sethostname_title">Configurar hostname</string> <string name="pref_gpodnet_sethostname_use_default_host">Usar host padrão</string> - <string name="pref_expandNotify_title">Expandir Notificação</string> - <string name="pref_expandNotify_sum">Sempre expandir a notificação para mostrar os botões de reprodução.</string> <string name="pref_persistNotify_title">Controles de Reprodução Persistentes</string> <string name="pref_persistNotify_sum">Manter a notificação e controles na tela de bloqueio enquanto a reprodução está pausada.</string> <string name="pref_compact_notification_buttons_title">Configurar Botões da tela de bloqueio</string> @@ -396,8 +377,6 @@ <string name="crash_report_sum">Enviar o relatório da última falha por e-mail</string> <string name="send_email">Enviar e-mail</string> <string name="experimental_pref">Experimental</string> - <string name="pref_sonic_title">Sonic Media Player</string> - <string name="pref_sonic_message">Utilizar o reprodutor de mÃdia Sonic no lugar do reprodutor de mÃdia nativo do Android e do Prestissimo</string> <string name="pref_current_value">Valor atual: %1$s</string> <string name="pref_proxy_title">Proxy</string> <string name="pref_proxy_sum">Configurar um proxy da rede</string> @@ -417,8 +396,6 @@ <string name="search_hint">Buscar por episódios</string> <string name="found_in_shownotes_label">Encontrados em exibir descrição</string> <string name="found_in_chapters_label">Encontrado nos capÃtulos</string> - <string name="found_in_authors_label">Encontrados em autores</string> - <string name="found_in_feeds_label">Encontrados em feeds</string> <string name="search_status_no_results">Nenhum resultado encontrado</string> <string name="search_label">Pesquisar</string> <string name="found_in_title_label">Encontrado no tÃtulo</string> @@ -444,8 +421,6 @@ <string name="html_export_label">Exportar HTML</string> <string name="exporting_label">Exportando...</string> <string name="export_error_label">Erro na exportação</string> - <string name="opml_export_success_title">Exportação do OPML realizada com sucesso.</string> - <string name="opml_export_success_sum">O arquivo .opml foi gravado em:\u0020</string> <string name="opml_import_ask_read_permission">Acesso ao armazenamento externo é necessária para ler o arquivo OPML</string> <!--Sleep timer--> <string name="set_sleeptimer_label">Configura desligamento automático</string> @@ -629,4 +604,5 @@ <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 grave</string> <string name="cast_failed_media_error_skipping">Erro ao reproduzir mÃdia. Pulando...</string> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-pt/strings.xml b/core/src/main/res/values-pt/strings.xml index 8be0b8443..2f7941097 100644 --- a/core/src/main/res/values-pt/strings.xml +++ b/core/src/main/res/values-pt/strings.xml @@ -1,11 +1,13 @@ <?xml version='1.0' encoding='UTF-8'?> <resources xmlns:tools="http://schemas.android.com/tools"> <!--Activitiy and fragment titles--> + <string name="feed_update_receiver_name">Atualizar subscrições</string> <string name="feeds_label">Fontes</string> <string name="statistics_label">EstatÃsticas</string> <string name="add_feed_label">Adicionar podcast</string> <string name="episodes_label">Episódios</string> <string name="all_episodes_short_label">Todos</string> + <string name="new_episodes_label">Novos</string> <string name="favorite_episodes_label">Favoritos</string> <string name="new_label">Novos</string> <string name="settings_label">Definições</string> @@ -18,10 +20,12 @@ <string name="cancel_download_label">Cancelar\ndescarga</string> <string name="playback_history_label">Histórico de reprodução</string> <string name="gpodnet_main_label">gpodder.net</string> + <string name="gpodnet_summary">Sincronizar com outros dispositivos</string> <string name="gpodnet_auth_label">Dados gpodder.net</string> <string name="free_space_label">%1$s disponÃvel</string> <string name="episode_cache_full_title">Cache de episódios cheia</string> <string name="episode_cache_full_message">Atingido o limite máximo de itens em cache. Pode aumentar o tamanho de cache nas definições.</string> + <string name="synchronizing">A sincronizar...</string> <!--Statistics fragment--> <string name="total_time_listened_to_podcasts">Tempo total dos podcasts reproduzidos:</string> <string name="statistics_details_dialog">%1$d de %2$d episódios iniciados.\n\nReproduzidos %3$s de %4$s.</string> @@ -51,18 +55,19 @@ <!--Playback history--> <string name="clear_history_label">Limpar histórico</string> <!--Other--> - <string name="confirm_label">Confirmar</string> + <string name="confirm_label">Confirmação</string> <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="author_label">Autor(es)</string> <string name="language_label">Idioma</string> <string name="url_label">URL</string> <string name="podcast_settings_label">Definições</string> <string name="cover_label">Imagem</string> <string name="error_label">Erro</string> <string name="error_msg_prefix">Ocorreu um erro:</string> + <string name="needs_storage_permission">Tem que permitir o acesso ao armazenamento para esta operação</string> <string name="refresh_label">Atualizar</string> <string name="external_storage_error_msg">Cartão SD não disponÃvel. Certifique-se de que inseriu o cartão corretamente para que a aplicação funcione corretamente.</string> <string name="chapters_label">CapÃtulos</string> @@ -105,25 +110,28 @@ <string name="mark_all_read_label">Marcar tudo como reproduzido</string> <string name="mark_all_read_msg">Marcar todos os episódios como reproduzidos</string> <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="mark_all_read_feed_confirmation_msg">Tem a certeza de que deseja marcar como reproduzidos todos os episódios deste podcast?</string> + <string name="mark_all_seen_label">Marcar tudo como reproduzido</string> + <string name="mark_all_seen_msg">Marcar todos como reproduzidos</string> + <string name="mark_all_seen_confirmation_msg">Tem a certeza de que deseja marcar todos os episódios como vistos?</string> <string name="show_info_label">Mostrar informações</string> + <string name="show_feed_settings_label">Mostrar definições do podcast</string> + <string name="feed_info_label">Informações do podcast</string> + <string name="feed_settings_label">Definições do podcast</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> + <string name="share_link_label">Partilhar URL do episódio</string> + <string name="share_link_with_position_label">Partilhar URL do episódio (com posição)</string> <string name="share_file_label">Partilhar ficheiro</string> - <string name="share_link_with_position_label">Partilhar ligação com posição</string> <string name="share_feed_url_label">Partilhar URL da fonte</string> - <string name="share_item_url_label">Partilhar URL do episódio</string> - <string name="share_item_url_with_position_label">Partilhar URL do episódio com posição</string> - <string name="feed_delete_confirmation_msg">Tem a certeza de que deseja remover a fonte \"%1$s\" e TODOS os episódios descarregados?</string> - <string name="feed_remover_msg">Remover fonte</string> - <string name="load_complete_feed">Atualizar todas as páginas da fonte</string> + <string name="share_item_url_label">Partilhar URL do ficheiro multimédia</string> + <string name="share_item_url_with_position_label">Partilhar URL do ficheiro multimédia (com posição)</string> + <string name="feed_delete_confirmation_msg">Tem a certeza de que deseja remover o podcast \"%1$s\" e TODOS os seus episódios (inclusive descarregados)?</string> + <string name="feed_remover_msg">A remover podcast</string> + <string name="load_complete_feed">Atualizar podcast</string> <string name="hide_episodes_title">Ocultar episódios</string> - <string name="episode_actions">Aplicar ações</string> + <string name="batch_edit">Edição em lote</string> <string name="hide_unplayed_episodes_label">Não reproduzidos</string> <string name="hide_paused_episodes_label">Em pausa</string> <string name="hide_played_episodes_label">Reproduzidos</string> @@ -132,6 +140,7 @@ <string name="hide_downloaded_episodes_label">Descarregados</string> <string name="hide_not_downloaded_episodes_label">Não descarregados</string> <string name="hide_has_media_label">Tem ficheiro</string> + <string name="hide_is_favorite_label">É favorito</string> <string name="filtered_label">Filtrados</string> <string name="refresh_failed_msg">{fa-exclamation-circle} Última atualização falhada</string> <string name="open_podcast">Abrir podcast</string> @@ -145,7 +154,8 @@ <string name="delete_label">Apagar</string> <string name="delete_failed">Episódio não apagado. Experimente reiniciar o dispositivo.</string> <string name="remove_episode_lable">Remover episódio</string> - <string name="marked_as_seen_label">Marcar como visto</string> + <string name="mark_as_seen_label">Marcar como reproduzido</string> + <string name="marked_as_seen_label">Marcar como reproduzido</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> @@ -168,6 +178,8 @@ <string name="download_failed">falha</string> <string name="download_pending">Descarga pendente</string> <string name="download_running">Descarga atual</string> + <string name="download_error_details">Detalhes</string> + <string name="download_error_details_message">%1$s \n\Ficheiro URL:\n%2$s</string> <string name="download_error_device_not_found">Cartão SD não encontrado</string> <string name="download_error_insufficient_space">Espaço insuficiente</string> <string name="download_error_file_error">Erro no ficheiro</string> @@ -218,6 +230,7 @@ <string name="playback_error_unknown">Erro desconhecido</string> <string name="no_media_playing_label">Nada em reprodução</string> <string name="player_buffering_msg">A processar...</string> + <string name="player_go_to_picture_in_picture">Modo \'picture-in-picture\'</string> <string name="playbackservice_notification_title">Reproduzir podcast</string> <string name="unknown_media_key">Tecla multimédia desconhecida: %1$d</string> <!--Queue operations--> @@ -234,7 +247,9 @@ <string name="date">Data</string> <string name="duration">Duração</string> <string name="episode_title">TÃtulo do episódio</string> - <string name="feed_title">TÃtulo da fonte</string> + <string name="feed_title">TÃtulo do podcast</string> + <string name="random">Aleatório</string> + <string name="smart_shuffle">Mistura inteligente</string> <string name="ascending">Crescente</string> <string name="descending">Decrescente</string> <string name="clear_queue_confirmation_msg">Tem a certeza de que deseja remover todos os episódios da fila de reprodução?</string> @@ -272,7 +287,7 @@ <string name="enable_sonic">Ativar Sonic</string> <!--Empty list labels--> <string name="no_items_label">Não existem itens nesta lista</string> - <string name="no_feeds_label">Ainda não possui quaisquer fontes</string> + <string name="no_feeds_label">Ainda não tem quaisquer podcasts subscritos.</string> <string name="no_chapters_label">Este episódio não tem capÃtulos.</string> <string name="no_shownotes_label">Este episódio não tem notas.</string> <!--Preferences--> @@ -281,15 +296,23 @@ <string name="other_pref">Outras</string> <string name="about_pref">Sobre</string> <string name="queue_label">Fila</string> - <string name="services_label">Serviços</string> + <string name="integrations_label">Integrações</string> <string name="flattr_label">Flattr</string> + <string name="flattr_summary">Serviço de micro pagamentos</string> + <string name="automation">Automatização</string> + <string name="download_pref_details">Detalhes</string> + <string name="import_export_pref">Importar/Exportar</string> + <string name="appearance">Aparência</string> + <string name="external_elements">Elementos externos</string> + <string name="interruptions">Interrupções</string> + <string name="buttons">Botões para controlo de reprodução</string> + <string name="media_player">Reprodutor multimédia</string> <string name="pref_episode_cleanup_title">Limpeza de episódios</string> <string name="pref_episode_cleanup_summary">Os episódios que não estejam na fila e não sejam favoritos podem ser elegÃveis para serem removidos se a Descarga automática necessitar de espaço para novos episódios.</string> <string name="pref_pauseOnDisconnect_sum">Pausa na reprodução ao desligar os auscultadores ou o bluetooth</string> <string name="pref_unpauseOnHeadsetReconnect_sum">Continuar reprodução ao ligar os auscultadores</string> <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> @@ -338,7 +361,7 @@ <string name="pref_nav_drawer_feed_order_title">Definir ordem de subscrição</string> <string name="pref_nav_drawer_feed_order_sum">Alterar a ordem das suas subscrições</string> <string name="pref_nav_drawer_feed_counter_title">Definir contador de subscrições</string> - <string name="pref_nav_drawer_feed_counter_sum">Alterar a informação mostrada no contador de subscrições</string> + <string name="pref_nav_drawer_feed_counter_sum">Alterar a informação mostrada no contador de subscrições. Também afeta as subscrições se \'Ordem de subscrição\' estiver definida como \'Contador\'.</string> <string name="pref_set_theme_sum">Alterar a aparência do AntennaPod</string> <string name="pref_automatic_download_title">Descarga automática</string> <string name="pref_automatic_download_sum">Configurar a descarga automática dos episódios</string> @@ -352,12 +375,13 @@ <string name="pref_episode_cache_title">Cache de episódios</string> <string name="pref_theme_title_light">Claro</string> <string name="pref_theme_title_dark">Escuro</string> + <string name="pref_theme_title_trueblack">Preto (AMOLED)</string> <string name="pref_episode_cache_unlimited">Sem limite</string> <string name="pref_update_interval_hours_plural">horas</string> <string name="pref_update_interval_hours_singular">hora</string> <string name="pref_update_interval_hours_manual">Manual</string> <string name="pref_gpodnet_authenticate_title">Acesso</string> - <string name="pref_gpodnet_authenticate_sum">Aceda à sua conta gpodder.net para poder sincronizar as subscrições</string> + <string name="pref_gpodnet_authenticate_sum">Aceda à sua conta gpodder.net para poder sincronizar as subscrições.</string> <string name="pref_gpodnet_logout_title">Sair</string> <string name="pref_gpodnet_logout_toast">Sessão terminada</string> <string name="pref_gpodnet_setlogin_information_title">Alterar informação de acesso</string> @@ -380,8 +404,6 @@ <string name="pref_rewind_sum">Personalizar o número de segundos a recuar ao clicar no botão de recuo rápido</string> <string name="pref_gpodnet_sethostname_title">Definir nome de servidor</string> <string name="pref_gpodnet_sethostname_use_default_host">Utilizar predefinições</string> - <string name="pref_expandNotify_title">Expansão de notificação</string> - <string name="pref_expandNotify_sum">Expandir sempre a notificação para mostrar os botões de reprodução</string> <string name="pref_persistNotify_title">Controlos de reprodução</string> <string name="pref_persistNotify_sum">Manter controlos de notificação e ecrã de bloqueio ao colocar a reprodução em pausa</string> <string name="pref_compact_notification_buttons_title">Definir botões do ecrã de bloqueio</string> @@ -402,8 +424,7 @@ <string name="crash_report_sum">Enviar o relatório de erros por e-mail</string> <string name="send_email">Enviar e-mail</string> <string name="experimental_pref">Experimental</string> - <string name="pref_sonic_title">Reprodutor multimédia Sonic</string> - <string name="pref_sonic_message">Utilizar o Sonic Media Player como substituto do reprodutor nativo do Android e do Prestissimo</string> + <string name="pref_media_player_message">Selecione o reprodutor multimédia a utilizar</string> <string name="pref_current_value">Valor atual: %1$s</string> <string name="pref_proxy_title">Proxy</string> <string name="pref_proxy_sum">Definir um proxy de rede</string> @@ -415,6 +436,11 @@ <string name="pref_cast_message_free_flavor">O Chromecast necessita de bibliotecas proprietárias de terceiros que estão desativadas nesta versão do AntennaPod</string> <string name="pref_enqueue_downloaded_title">Colocar descargas na fila</string> <string name="pref_enqueue_downloaded_summary">Adicionar à fila os episódios descarregados</string> + <string name="media_player_builtin">Reprodutor nativo Android</string> + <string name="pref_videoBehavior_title">Ao sair do vÃdeo</string> + <string name="pref_videoBehavior_sum">Comportamento ao sair da reprodução do vÃdeo</string> + <string name="stop_playback">Parar reprodução</string> + <string name="continue_playback">Continuar reprodução de áudio</string> <!--Auto-Flattr dialog--> <string name="auto_flattr_enable">Ativar flattr automático</string> <string name="auto_flattr_after_percent">Flattr de episódios ao atingir %d porcento de reprodução</string> @@ -424,8 +450,8 @@ <string name="search_hint">Pesquisar por episódios</string> <string name="found_in_shownotes_label">Encontrado nas notas</string> <string name="found_in_chapters_label">Encontrado nos capÃtulos</string> - <string name="found_in_authors_label">Encontrado em autores</string> - <string name="found_in_feeds_label">Encontrado em fontes</string> + <string name="found_in_authors_label">Localizado em autor(es)</string> + <string name="found_in_feeds_label">Localizado em podcast</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> @@ -451,8 +477,8 @@ <string name="html_export_label">Exportação HTML</string> <string name="exporting_label">A exportar...</string> <string name="export_error_label">Erro de exportação</string> - <string name="opml_export_success_title">Exportação efetuada</string> - <string name="opml_export_success_sum">O ficheiro .opml foi guardado em:\u0020</string> + <string name="export_success_title">Exportação com sucesso</string> + <string name="export_success_sum">O ficheiro exportado foi guardado em:\n\n%1$s</string> <string name="opml_import_ask_read_permission">Requer acesso ao armazenamento externo para ler o ficheiro OPML</string> <!--Sleep timer--> <string name="set_sleeptimer_label">Definir temporizador</string> @@ -619,6 +645,14 @@ <string name="proxy_host_empty_error">Servidor não pode estar vazio</string> <string name="proxy_host_invalid_error">O servidor não tem um endereço ou domÃnio válido</string> <string name="proxy_port_invalid_error">Porta inválido</string> + <!--Database import/export--> + <string name="import_export">Importação/exportação da base de dados</string> + <string name="import_export_warning">Esta função experimental pode ser usada para transferir as suas subscrições e episódios para outros dispositivos.\n\nAs bases de dados exportadas apenas podem ser importadas se usar a mesma versão do AntennaPod. Caso contrário, esta função poderá produzir efeitos inesperados.\n\nDepois da importação, os episódios poderão ser apresentados como tendo sido descarregados mesmo que não seja verdade. Prima o botão de reprodução dos episódios para que o AntennaPod detete a situação.</string> + <string name="label_import">Importar</string> + <string name="label_export">Exportar</string> + <string name="import_select_file">Selecione o ficheiro a importar</string> + <string name="export_ok">Exportação com sucesso.</string> + <string name="import_ok">Importação bem sucedida.\n\nPor favor prima OK para reiniciar o AntennaPod</string> <!--Casting--> <string name="cast_media_route_menu_title">Reproduzir em...</string> <string name="cast_disconnect_label">Desligar da última sessão</string> @@ -635,4 +669,13 @@ <string name="cast_failed_seek">Falha ao procurar a nova posição no dispositivo</string> <string name="cast_failed_receiver_player_error">O reprodutor encontrou um erro crÃtico</string> <string name="cast_failed_media_error_skipping">Erro de reprodução. A ignorar...</string> + <!--Notification channels--> + <string name="notification_channel_user_action">Requer ação</string> + <string name="notification_channel_user_action_description">Mostrar se for necessária uma ação como, por exemplo, digitar uma palavra-passe.</string> + <string name="notification_channel_downloading">A descarregar</string> + <string name="notification_channel_downloading_description">Mostrar durante a descarga.</string> + <string name="notification_channel_playing">Reprodução atual</string> + <string name="notification_channel_playing_description">Permite o controlo da reprodução. Esta será a notificação que verá ao reproduzir um podcast.</string> + <string name="notification_channel_error">Erros</string> + <string name="notification_channel_error_description">Mostrar se ocorrerem erros como, por exemplo, não for possÃvel a descarga.</string> </resources> diff --git a/core/src/main/res/values-ro-rRO/strings.xml b/core/src/main/res/values-ro-rRO/strings.xml index d39e48bbc..92b2da8f9 100644 --- a/core/src/main/res/values-ro-rRO/strings.xml +++ b/core/src/main/res/values-ro-rRO/strings.xml @@ -2,25 +2,38 @@ <resources xmlns:tools="http://schemas.android.com/tools"> <!--Activitiy and fragment titles--> <string name="feeds_label">Feeduri</string> + <string name="statistics_label">Statistici</string> + <string name="add_feed_label">Adaugă podcast</string> + <string name="episodes_label">Episoade</string> + <string name="all_episodes_short_label">Toate</string> + <string name="favorite_episodes_label">Favorite</string> <string name="new_label">Nou</string> <string name="settings_label">Setări</string> <string name="downloads_label">Descărcări</string> + <string name="downloads_running_label">Active</string> + <string name="downloads_completed_label">Complete</string> + <string name="downloads_log_label">Jurnal</string> <string name="cancel_download_label">Anulează descărcare</string> <string name="playback_history_label">Istorie ascultare</string> <string name="gpodnet_main_label">gpodder.net</string> <string name="gpodnet_auth_label">autentificare gpodder.net</string> <!--Statistics fragment--> <!--Main activity--> + <string name="drawer_open">Deschide meniul</string> + <string name="drawer_close">ÃŽnchide meniul</string> <!--Webview actions--> <string name="open_in_browser_label">Deschide în browser</string> <string name="copy_url_label">Copiază URL</string> <string name="share_url_label">ÃŽmparte URL</string> <string name="copied_url_msg">URL copiat în clipboard</string> + <string name="go_to_position_label">Mergi la poziÈ›ia</string> <!--Playback history--> <string name="clear_history_label">GoleÈ™te istoric</string> <!--Other--> <string name="confirm_label">Confirmă</string> <string name="cancel_label">Anulează</string> + <string name="yes">Da</string> + <string name="no">Nu</string> <string name="author_label">Autor</string> <string name="language_label">Limbă</string> <string name="podcast_settings_label">Setări</string> @@ -29,6 +42,7 @@ <string name="refresh_label">Reîncarcă</string> <string name="external_storage_error_msg">Nu exista stocare externă. AsiguraÈ›i-vă că stocarea externă este conectată pentru ca aplicaÈ›ia să funcÈ›ioneze corespunzător.</string> <string name="chapters_label">Capitole</string> + <string name="chapter_duration">Durata: %1$s</string> <string name="shownotes_label">NotiÈ›e</string> <string name="description_label">Descriere</string> <string name="most_recent_prefix">Cel mai recent episod:\u0020</string> @@ -39,6 +53,13 @@ <string name="save_username_password_label">Salvează numele de utilizator È™i parola</string> <string name="close_label">închide</string> <string name="retry_label">Reîncearcă</string> + <string name="auto_delete_label">Șterge epidosul automat</string> + <string name="feed_auto_download_always">ÃŽntotdeauna</string> + <string name="feed_auto_download_never">Niciodată</string> + <string name="send_label">Trimite...</string> + <string name="episode_cleanup_never">Niciodată</string> + <string name="episode_cleanup_queue_removal">Când nu e în coadă</string> + <string name="episode_cleanup_after_listening">După terminare</string> <!--'Add Feed' Activity labels--> <string name="feedurl_label">Adresă feed</string> <!--Actions on feeds--> @@ -123,7 +144,6 @@ <string name="other_pref">Altele</string> <string name="about_pref">Despre</string> <string name="queue_label">Coadă</string> - <string name="services_label">Servicii</string> <string name="flattr_label">Flattr</string> <string name="pref_followQueue_sum">Sari la următorul element din coadă cand se termină ascultarea</string> <string name="playback_pref">Ascultare</string> @@ -174,7 +194,6 @@ <string name="deselect_all_label">Deselectează toate</string> <string name="opml_export_label">Exportă OPML</string> <string name="export_error_label">Eroare exportare</string> - <string name="opml_export_success_sum">FiÈ™ierul .opml a fost scris în:\u0020</string> <!--Sleep timer--> <string name="set_sleeptimer_label">Setează cronometru somn</string> <string name="disable_sleeptimer_label">OpreÈ™te cronometru somn</string> @@ -227,4 +246,5 @@ <!--Database import/export--> <!--Casting--> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-ru/strings.xml b/core/src/main/res/values-ru/strings.xml index 5e7f8dd73..076a54048 100644 --- a/core/src/main/res/values-ru/strings.xml +++ b/core/src/main/res/values-ru/strings.xml @@ -1,11 +1,13 @@ <?xml version='1.0' encoding='UTF-8'?> <resources xmlns:tools="http://schemas.android.com/tools"> <!--Activitiy and fragment titles--> + <string name="feed_update_receiver_name">Обновить подпиÑки</string> <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="new_episodes_label">Ðовые</string> <string name="favorite_episodes_label">Избранное</string> <string name="new_label">Ðовые</string> <string name="settings_label">ÐаÑтройки</string> @@ -18,10 +20,12 @@ <string name="cancel_download_label">Отменить загрузку</string> <string name="playback_history_label">Журнал</string> <string name="gpodnet_main_label">gpodder.net</string> + <string name="gpodnet_summary">Синхронизировать Ñ Ð´Ñ€ÑƒÐ³Ð¸Ð¼Ð¸ уÑтройÑтвами</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> + <string name="synchronizing">СинхронизациÑ…</string> <!--Statistics fragment--> <string name="total_time_listened_to_podcasts">Общее Ð²Ñ€ÐµÐ¼Ñ Ð¿Ñ€Ð¾ÑÐ»ÑƒÑˆÐ¸Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð´ÐºÐ°Ñтов:</string> <string name="statistics_details_dialog">%1$d из %2$d выпуÑков начато.\n\nПроÑлушано %3$s из %4$s.</string> @@ -56,13 +60,14 @@ <string name="yes">Да</string> <string name="no">Ðет</string> <string name="reset">СброÑ</string> - <string name="author_label">Ðвтор</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> <string name="error_msg_prefix">Произошла ошибка:</string> + <string name="needs_storage_permission">Ð”Ð»Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ñтой операции нужно разрешить доÑтуп к хранилищу</string> <string name="refresh_label">Обновить</string> <string name="external_storage_error_msg">Внешний ноÑитель недоÑтупен. УбедитеÑÑŒ что внешний ноÑитель уÑтановлен, иначе приложение не Ñможет нормально работать.</string> <string name="chapters_label">Главы</string> @@ -107,25 +112,28 @@ <string name="mark_all_read_label">Отметить как проÑлушанное</string> <string name="mark_all_read_msg">Отметить вÑе выпуÑки как проÑлушанные</string> <string name="mark_all_read_confirmation_msg">Подтвердите, что хотите пометить вÑе Ñпизоды как проÑлушанные.</string> - <string name="mark_all_read_feed_confirmation_msg">Подтвердите, что хотите пометить вÑе Ñпизоды в Ñтом канале как проÑлушанные.</string> + <string name="mark_all_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="show_feed_settings_label">Показать наÑтройки подкаÑта</string> + <string name="feed_info_label">Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ подкаÑте</string> + <string name="feed_settings_label">ÐаÑтройки подкаÑта</string> <string name="rename_feed_label">Переименовать подкаÑÑ‚</string> <string name="remove_feed_label">Удалить подкаÑÑ‚</string> <string name="share_label">ПоделитьÑÑ…</string> - <string name="share_link_label">ПоделитьÑÑ ÑÑылкой</string> + <string name="share_link_label">ПоделитьÑÑ ÑÑылкой на выпуÑк</string> + <string name="share_link_with_position_label">ПоделитьÑÑ ÑÑылкой на выпуÑк Ñ Ð¾Ñ‚Ð¼ÐµÑ‚ÐºÐ¾Ð¹ времени</string> <string name="share_file_label">ПоделитьÑÑ Ñ„Ð°Ð¹Ð»Ð¾Ð¼</string> - <string name="share_link_with_position_label">ПоделитьÑÑ ÑÑылкой Ñ Ð¾Ñ‚Ð¼ÐµÑ‚ÐºÐ¾Ð¹ времени</string> <string name="share_feed_url_label">ПоделитьÑÑ ÑÑылкой на канал</string> - <string name="share_item_url_label">ПоделитьÑÑ ÑÑылкой на файл выпуÑка</string> - <string name="share_item_url_with_position_label">ПоделитьÑÑ ÑÑылкой на файл выпуÑка Ñ Ð¾Ñ‚Ð¼ÐµÑ‚ÐºÐ¾Ð¹ времени</string> - <string name="feed_delete_confirmation_msg">Подтвердите, что хотите удалить канал \"%1$s\" и ВСЕ Ñкачанные Ñпизоды Ñтого канала.</string> - <string name="feed_remover_msg">Удаление канала</string> - <string name="load_complete_feed">Обновить веÑÑŒ канал</string> + <string name="share_item_url_label">ПоделитьÑÑ ÑÑылкой на файл</string> + <string name="share_item_url_with_position_label">ПоделитьÑÑ ÑÑылкой на файл Ñ Ð¾Ñ‚Ð¼ÐµÑ‚ÐºÐ¾Ð¹ времени</string> + <string name="feed_delete_confirmation_msg">Подтвердите желание удалить подкаÑÑ‚ \"%1$s\" и ВСЕ его Ñпизоды, в том чиÑле и Ñкачанные.</string> + <string name="feed_remover_msg">Удаление подкаÑта</string> + <string name="load_complete_feed">Обновить веÑÑŒ подкаÑÑ‚</string> <string name="hide_episodes_title">Скрыть выпуÑки</string> - <string name="episode_actions">Применить дейÑтвиÑ</string> + <string name="batch_edit">Ð“Ñ€ÑƒÐ¿Ð¿Ð¾Ð²Ð°Ñ Ð¾Ð±Ñ€Ð°Ð±Ð¾Ñ‚ÐºÐ°</string> <string name="hide_unplayed_episodes_label">ÐепроÑлушанное</string> <string name="hide_paused_episodes_label">ПриоÑтановленное</string> <string name="hide_played_episodes_label">ПроÑлушанное</string> @@ -134,6 +142,7 @@ <string name="hide_downloaded_episodes_label">Загружено</string> <string name="hide_not_downloaded_episodes_label">Ðе загружено</string> <string name="hide_has_media_label">С файлами</string> + <string name="hide_is_favorite_label">Избранные</string> <string name="filtered_label">Отфильтровано</string> <string name="refresh_failed_msg">{fa-exclamation-circle} ПоÑледнее обновление не удалоÑÑŒ</string> <string name="open_podcast">Открыть подкаÑÑ‚</string> @@ -147,6 +156,7 @@ <string name="delete_label">Удалить</string> <string name="delete_failed">Ðевозможно удалить файл. Попробуйте перезагрузить уÑтройÑтво.</string> <string name="remove_episode_lable">Удалить выпуÑк</string> + <string name="mark_as_seen_label">ПроÑмотрено</string> <string name="marked_as_seen_label">Отмечено как проÑмотренное</string> <string name="mark_read_label">Отметить как проÑлушанное</string> <string name="marked_as_read_label">Помечено как проÑлушанное</string> @@ -170,6 +180,11 @@ <string name="download_failed">не удалоÑÑŒ</string> <string name="download_pending">Загрузка в ожидании</string> <string name="download_running">Загрузка в процеÑÑе</string> + <string name="download_error_details">Подробнее</string> + <string name="download_error_details_message">%1$s + +URL файла: +%2$s</string> <string name="download_error_device_not_found">УÑтройÑтво Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð½Ðµ найдено</string> <string name="download_error_insufficient_space">ÐедоÑтаточно меÑта</string> <string name="download_error_file_error">Ошибка файла</string> @@ -222,6 +237,7 @@ <string name="playback_error_unknown">ÐеизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°</string> <string name="no_media_playing_label">Ðичего не воÑпроизводитÑÑ</string> <string name="player_buffering_msg">БуферизациÑ</string> + <string name="player_go_to_picture_in_picture">Картинка в картинке</string> <string name="playbackservice_notification_title">ВоÑпроизведение подкаÑта</string> <string name="unknown_media_key">AntennaPod - неизвеÑтный ключ ноÑителÑ: %1$d</string> <!--Queue operations--> @@ -238,7 +254,9 @@ <string name="date">По дате</string> <string name="duration">По продолжительноÑти</string> <string name="episode_title">Ðазвание выпуÑка</string> - <string name="feed_title">Ðазвание канала</string> + <string name="feed_title">Ðазвание подкаÑта</string> + <string name="random">Случайно</string> + <string name="smart_shuffle">Умное перемешивание</string> <string name="ascending">По возраÑтанию</string> <string name="descending">По убыванию</string> <string name="clear_queue_confirmation_msg">Подтвердите, что хотите очиÑтить очередь от ВСЕХ Ñпизодов.</string> @@ -276,7 +294,7 @@ <string name="enable_sonic">Включить Sonic</string> <!--Empty list labels--> <string name="no_items_label">СпиÑок пуÑÑ‚</string> - <string name="no_feeds_label">Ð’Ñ‹ ещё не подпиÑаны ни на один канал.</string> + <string name="no_feeds_label">Ð’Ñ‹ ещё не подпиÑаны ни на один подкаÑÑ‚.</string> <string name="no_chapters_label">Ðтот выпуÑк не Ñодержит оглавлениÑ.</string> <string name="no_shownotes_label">Ðтот выпуÑк не Ñодержит примечаний.</string> <!--Preferences--> @@ -285,15 +303,23 @@ <string name="other_pref">Прочее</string> <string name="about_pref">О программе</string> <string name="queue_label">Очередь</string> - <string name="services_label">СервиÑÑ‹</string> + <string name="integrations_label">ИнтеграциÑ</string> <string name="flattr_label">Flattr</string> + <string name="flattr_summary">УÑлуга микроплатежей</string> + <string name="automation">ÐвтоматизациÑ</string> + <string name="download_pref_details">Подробнее</string> + <string name="import_export_pref">Импорт/ÑкÑпорт</string> + <string name="appearance">Внешний вид</string> + <string name="external_elements">Внешние органы управлениÑ</string> + <string name="interruptions">ПрерываниÑ</string> + <string name="buttons">Кнопки ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð²Ð¾Ñпроизведением</string> + <string name="media_player">Проигрыватель</string> <string name="pref_episode_cleanup_title">Удаление выпуÑков</string> <string name="pref_episode_cleanup_summary">ВыпуÑки, которые не ÑтоÑÑ‚ в очереди и не отмечены как избранные могут быть удалены Ð´Ð»Ñ Ð¾ÑÐ²Ð¾Ð±Ð¾Ð¶Ð´ÐµÐ½Ð¸Ñ Ð¼ÐµÑта под Ðвтозагрузку.</string> <string name="pref_pauseOnDisconnect_sum">ПриоÑтановить воÑпроизведение, когда наушники или bluetooth отключены</string> <string name="pref_unpauseOnHeadsetReconnect_sum">Продолжать воÑпроизведение поÑле Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð½Ð°ÑƒÑˆÐ½Ð¸ÐºÐ¾Ð²</string> <string name="pref_unpauseOnBluetoothReconnect_sum">Продолжать воÑпроизведение поÑле воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ bluetooth-ÑоединениÑ</string> <string name="pref_hardwareForwardButtonSkips_title">ПропуÑкать кнопкой перемотки вперёд</string> - <string name="pref_hardwareForwardButtonSkips_sum">При нажатии на физичеÑкую кнопку перемотки вперёд переходить к Ñледующему выпуÑку вмеÑто перемотки</string> <string name="pref_hardwarePreviousButtonRestarts_title">Ð’ начало кнопкой перемотки назад</string> <string name="pref_hardwarePreviousButtonRestarts_sum">При нажатии на физичеÑкую кнопку перемотки назад переходить к началу выпуÑка вмеÑто перемотки назад</string> <string name="pref_followQueue_sum">ПоÑле Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð²Ð¾ÑÐ¿Ñ€Ð¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¿ÐµÑ€ÐµÐ¹Ñ‚Ð¸ к Ñледующему в очереди</string> @@ -342,7 +368,7 @@ <string name="pref_nav_drawer_feed_order_title">УпорÑдочить подпиÑки</string> <string name="pref_nav_drawer_feed_order_sum">Выбрать порÑдок Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñок</string> <string name="pref_nav_drawer_feed_counter_title">Выбрать Ñчётчик подпиÑок</string> - <string name="pref_nav_drawer_feed_counter_sum">Выбрать какую информацию показывать в Ñчётчике подпиÑок</string> + <string name="pref_nav_drawer_feed_counter_sum">Выбрать какую информацию показывать в Ñчётчике подпиÑок. ВлиÑет также на очерёдноÑÑ‚ÑŒ подпиÑок, еÑли Ñортировка подпиÑок производитÑÑ Ð¿Ð¾ Ñчётчику.</string> <string name="pref_set_theme_sum">Изменить тему Ð¾Ñ„Ð¾Ñ€Ð¼Ð»ÐµÐ½Ð¸Ñ AntennaPod</string> <string name="pref_automatic_download_title">ÐвтоматичеÑÐºÐ°Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ°</string> <string name="pref_automatic_download_sum">ÐаÑтроить автоматичеÑкую загрузку выпуÑков.</string> @@ -356,6 +382,7 @@ <string name="pref_episode_cache_title">КÑш выпуÑков</string> <string name="pref_theme_title_light">СветлаÑ</string> <string name="pref_theme_title_dark">ТёмнаÑ</string> + <string name="pref_theme_title_trueblack">Ð§Ñ‘Ñ€Ð½Ð°Ñ (Ð´Ð»Ñ AMOLED)</string> <string name="pref_episode_cache_unlimited">Ðеограничен</string> <string name="pref_update_interval_hours_plural">ч.</string> <string name="pref_update_interval_hours_singular">ч.</string> @@ -384,8 +411,6 @@ <string name="pref_rewind_sum">ÐаÑтройте длину шага в Ñекундах при нажатии кнопки перемотки назад</string> <string name="pref_gpodnet_sethostname_title">Задать Ð¸Ð¼Ñ ÑƒÐ·Ð»Ð°</string> <string name="pref_gpodnet_sethostname_use_default_host">ИÑпользовать узел по умолчанию</string> - <string name="pref_expandNotify_title">Развёрнутое уведомление</string> - <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> @@ -406,8 +431,7 @@ <string name="crash_report_sum">ОтоÑлать поÑледний отчёт о Ñбое по e-mail</string> <string name="send_email">Отправить Email</string> <string name="experimental_pref">ÐкÑпериментальные наÑтройки</string> - <string name="pref_sonic_title">Проигрывать через Sonic</string> - <string name="pref_sonic_message">ЗадейÑтвовать вÑтроенный медиа проигрыватель Sonic вмеÑто Ñтандартного из ОС Android и Prestissimo</string> + <string name="pref_media_player_message">Выберите каким проигрывателем Ñледует воÑпроизводить файлы</string> <string name="pref_current_value">Текущее значение: %1$s</string> <string name="pref_proxy_title">ПрокÑи</string> <string name="pref_proxy_sum">ÐаÑтройки прокÑи</string> @@ -419,6 +443,11 @@ <string name="pref_cast_message_free_flavor">Ð”Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Chromecast требуютÑÑ ÑобÑтвенничеÑкие библиотеки третьей Ñтороны, которые не включены в данную верÑию AntennaPod</string> <string name="pref_enqueue_downloaded_title">ДобавлÑÑ‚ÑŒ загруженные в очередь</string> <string name="pref_enqueue_downloaded_summary">ДобавлÑÑ‚ÑŒ загруженные выпуÑки в очередь</string> + <string name="media_player_builtin">Ð’Ñтроенный в Android проигрыватель</string> + <string name="pref_videoBehavior_title">При завершении видео</string> + <string name="pref_videoBehavior_sum">При Ñворачивании Ð¿Ñ€Ð¾Ð¸Ð³Ñ€Ñ‹Ð²Ð°Ñ‚ÐµÐ»Ñ Ð²Ð¸Ð´ÐµÐ¾</string> + <string name="stop_playback">оÑтановить воÑпроизведение</string> + <string name="continue_playback">Продолжить воÑпроизведение звука</string> <!--Auto-Flattr dialog--> <string name="auto_flattr_enable">Включить автоматичеÑкую поддержку через Flattr</string> <string name="auto_flattr_after_percent">Поддерживать через Flattr Ñпизоды, проÑлушанные на %d процентов</string> @@ -428,8 +457,8 @@ <string name="search_hint">Ðайти выпуÑки</string> <string name="found_in_shownotes_label">Ðайдено в примечаниÑÑ… к выпуÑку</string> <string name="found_in_chapters_label">Ðайдено в главах</string> - <string name="found_in_authors_label">Ðайдено в авторах</string> - <string name="found_in_feeds_label">Ðайдено в каналах</string> + <string name="found_in_authors_label">Ðайдено Ñреди авторов</string> + <string name="found_in_feeds_label">Ðайдено в подкаÑтах</string> <string name="search_status_no_results">Ðичего не найдено</string> <string name="search_label">ПоиÑк</string> <string name="found_in_title_label">Ðайдено в заголовке</string> @@ -455,8 +484,10 @@ <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> - <string name="opml_export_success_sum">Файл OPML был запиÑан в:\u0020</string> + <string name="export_success_title">ÐкÑпорт завершён уÑпешно</string> + <string name="export_success_sum">ÐкÑпорт оÑущеÑтвлён в файл: + +%1$s</string> <string name="opml_import_ask_read_permission">Ð”Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð° OPML необходим доÑтуп к внешнему хранилищу</string> <!--Sleep timer--> <string name="set_sleeptimer_label">УÑтановить таймер Ñна</string> @@ -635,7 +666,7 @@ <string name="label_import">Импорт</string> <string name="label_export">ÐкÑпорт</string> <string name="import_select_file">Выберите импортируемый файл</string> - <string name="export_ok">УÑпешно ÑкÑпортировано. База данных была запиÑана на карту памÑти.</string> + <string name="export_ok">УÑпешно ÑкÑпортировано.</string> <string name="import_ok">УÑпешно импортировано.\n\nПожалуйÑта, нажмите OK, чтобы перезапуÑтить AntennaPod</string> <!--Casting--> <string name="cast_media_route_menu_title">ВоÑпроизвеÑти на…</string> @@ -653,4 +684,13 @@ <string name="cast_failed_seek">Ðе удалоÑÑŒ выполнить перемотку на уÑтройÑтве Google cast</string> <string name="cast_failed_receiver_player_error">Ð¡ÐµÑ€ÑŒÑ‘Ð·Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° воÑÐ¿Ñ€Ð¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð² уÑтройÑтве Google cast</string> <string name="cast_failed_media_error_skipping">Ошибка воÑпроизведениÑ. ПропуÑкаю…</string> + <!--Notification channels--> + <string name="notification_channel_user_action">ТребуетÑÑ Ð´ÐµÐ¹Ñтвие</string> + <string name="notification_channel_user_action_description">ПоказываетÑÑ, когда требуетÑÑ Ð´ÐµÐ¹Ñтвие, например, Ð´Ð»Ñ Ð²Ð²Ð¾Ð´Ð° паролÑ.</string> + <string name="notification_channel_downloading">Идёт загрузка</string> + <string name="notification_channel_downloading_description">ПоказываетÑÑ Ð²Ð¾ Ð²Ñ€ÐµÐ¼Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸.</string> + <string name="notification_channel_playing">Идёт воÑпроизведение</string> + <string name="notification_channel_playing_description">ПозволÑет управлÑÑ‚ÑŒ воÑпроизведением. ОÑновное уведомление, показываетÑÑ Ð¿Ñ€Ð¸ воÑпроизведении подкаÑта.</string> + <string name="notification_channel_error">Ошибки</string> + <string name="notification_channel_error_description">ПоказываетÑÑ ÐµÑли что-то пошло не так, к примеру, неудавшаÑÑÑ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ° или ÑÐ¸Ð½Ñ…Ñ€Ð¾Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ Ñ gpodder.</string> </resources> diff --git a/core/src/main/res/values-sv-rSE/strings.xml b/core/src/main/res/values-sv-rSE/strings.xml index cb7474ed4..d56307e07 100644 --- a/core/src/main/res/values-sv-rSE/strings.xml +++ b/core/src/main/res/values-sv-rSE/strings.xml @@ -1,11 +1,13 @@ <?xml version='1.0' encoding='UTF-8'?> <resources xmlns:tools="http://schemas.android.com/tools"> <!--Activitiy and fragment titles--> + <string name="feed_update_receiver_name">Uppdatera Prenumerationer</string> <string name="feeds_label">Flöden</string> <string name="statistics_label">Statistik</string> <string name="add_feed_label">Lägg till Podcast</string> <string name="episodes_label">Episoder</string> <string name="all_episodes_short_label">Alla</string> + <string name="new_episodes_label">Nytt</string> <string name="favorite_episodes_label">Favoriter</string> <string name="new_label">Nya</string> <string name="settings_label">Inställningar</string> @@ -18,10 +20,12 @@ <string name="cancel_download_label">Avbryt\nNedladdning</string> <string name="playback_history_label">Uppspelningshistorik</string> <string name="gpodnet_main_label">gpodder.net</string> + <string name="gpodnet_summary">Synkronisera med andra enheter</string> <string name="gpodnet_auth_label">Inloggning till gpodder.net</string> <string name="free_space_label">%1$s kvar</string> <string name="episode_cache_full_title">Episodcachen är full</string> <string name="episode_cache_full_message">Episodcachens gräns har nÃ¥tts. Du kan öka cachens storlek i inställningarna.</string> + <string name="synchronizing">Synkroniserar...</string> <!--Statistics fragment--> <string name="total_time_listened_to_podcasts">Total uppspelningstid:</string> <string name="statistics_details_dialog">%1$d av %2$d episoder startade.\n\nSpelat %3$s av %4$s.</string> @@ -56,13 +60,14 @@ <string name="yes">Ja</string> <string name="no">Nej</string> <string name="reset">Ã…terställ</string> - <string name="author_label">Skapare</string> + <string name="author_label">Författare</string> <string name="language_label">SprÃ¥k</string> <string name="url_label">URL</string> <string name="podcast_settings_label">Inställningar</string> <string name="cover_label">Bild</string> <string name="error_label">Fel</string> <string name="error_msg_prefix">Ett fel inträffade:</string> + <string name="needs_storage_permission">LagringtillstÃ¥nd behövs för denna Ã¥tgärd</string> <string name="refresh_label">Uppdatera</string> <string name="external_storage_error_msg">Ingen extern lagring är tillgänglig. Se till att montera en extern lagringsenhet sÃ¥ att appen kan fungera korrekt.</string> <string name="chapters_label">Kapitel</string> @@ -105,25 +110,28 @@ <string name="mark_all_read_label">Markera alla som spelade</string> <string name="mark_all_read_msg">Markera alla Episoder som spelade</string> <string name="mark_all_read_confirmation_msg">Bekräfta att du verkligen vill markera alla episoder som spelade.</string> - <string name="mark_all_read_feed_confirmation_msg">Bekräfta att du verkligen vill markera alla episoder i detta flöde som spelade.</string> + <string name="mark_all_read_feed_confirmation_msg">Bekräfta att du vill markera alla episider i denna podcast som spelade.</string> <string name="mark_all_seen_label">Markera alla som sedda</string> - <string name="mark_all_seen_msg">Markera alla Episoder som sedda</string> + <string name="mark_all_seen_msg">Markerade alla episoder som sedda</string> <string name="mark_all_seen_confirmation_msg">Bekräfta att du vill markera alla episoder som sedda.</string> <string name="show_info_label">Visa information</string> - <string name="rename_feed_label">Byt namn pÃ¥ Podcast</string> - <string name="remove_feed_label">Ta bort Podcast</string> + <string name="show_feed_settings_label">Visa podcastinställningar</string> + <string name="feed_info_label">Podcastinfo</string> + <string name="feed_settings_label">Podcastinställningar</string> + <string name="rename_feed_label">Byt namn pÃ¥ podcast</string> + <string name="remove_feed_label">Ta bort podcast</string> <string name="share_label">Dela…</string> - <string name="share_link_label">Dela Länk</string> + <string name="share_link_label">Dela Episod-URL</string> + <string name="share_link_with_position_label">Dela Episod-URL med Position</string> <string name="share_file_label">Dela Fil</string> - <string name="share_link_with_position_label">Dela Länk med Position</string> <string name="share_feed_url_label">Dela Flödets URL</string> - <string name="share_item_url_label">Dela Episoden Fil-URL</string> - <string name="share_item_url_with_position_label">Dela Episodens Fil-URL med Position</string> - <string name="feed_delete_confirmation_msg">Bekräfta att du vill ta bort flödet \"%1$s\" och ALLA episoder du laddat ned frÃ¥n detta flöde.</string> - <string name="feed_remover_msg">Tar bort Flöde</string> - <string name="load_complete_feed">Uppdatera hela Flödet</string> + <string name="share_item_url_label">Dela Mediafilens URL</string> + <string name="share_item_url_with_position_label">Dela Mediafilens URL med Position</string> + <string name="feed_delete_confirmation_msg">Bekräfta att du vill ta bort podcast \"%1$s\" och ALLA dess episoder (inklusive nedladdade episoder).</string> + <string name="feed_remover_msg">Tar bort podcast</string> + <string name="load_complete_feed">Uppdatera hela podcasten</string> <string name="hide_episodes_title">Dölj Episoder</string> - <string name="episode_actions">Applicera Ã¥tgärder</string> + <string name="batch_edit">Batchredigering</string> <string name="hide_unplayed_episodes_label">Ospelade</string> <string name="hide_paused_episodes_label">Pausade</string> <string name="hide_played_episodes_label">Spelad</string> @@ -132,6 +140,7 @@ <string name="hide_downloaded_episodes_label">Nedladdade</string> <string name="hide_not_downloaded_episodes_label">Ej nedladdade</string> <string name="hide_has_media_label">Har media</string> + <string name="hide_is_favorite_label">Är favorit</string> <string name="filtered_label">Filtrerad</string> <string name="refresh_failed_msg">{fa-exclamation-circle} Senaste uppdateringen misslyckades</string> <string name="open_podcast">Öppna Podcast</string> @@ -145,6 +154,7 @@ <string name="delete_label">Ta bort</string> <string name="delete_failed">Kunde inte ta bort filen. Testa att starta om enheten.</string> <string name="remove_episode_lable">Ta bort Episod</string> + <string name="mark_as_seen_label">Markera som sedd</string> <string name="marked_as_seen_label">Markera som sedd</string> <string name="mark_read_label">Markera som spelad</string> <string name="marked_as_read_label">Markera som spelad</string> @@ -168,6 +178,8 @@ <string name="download_failed">misslyckades</string> <string name="download_pending">Avvaktar nedladdning</string> <string name="download_running">Nedladdning pÃ¥gÃ¥r</string> + <string name="download_error_details">Detaljer</string> + <string name="download_error_details_message">%1$s \n\nFil-URL:\n%2$s</string> <string name="download_error_device_not_found">Hittade ingen lagringsenhet</string> <string name="download_error_insufficient_space">Otillräckligt Utrymme</string> <string name="download_error_file_error">Filfel</string> @@ -218,6 +230,7 @@ <string name="playback_error_unknown">Okänt fel</string> <string name="no_media_playing_label">Inget media spelar</string> <string name="player_buffering_msg">Buffrar</string> + <string name="player_go_to_picture_in_picture">Bild-i-bild läge</string> <string name="playbackservice_notification_title">Spelar podcast</string> <string name="unknown_media_key">AntannaPod - Okänd mediaknapp: %1$d</string> <!--Queue operations--> @@ -234,7 +247,9 @@ <string name="date">Datum</string> <string name="duration">Längd</string> <string name="episode_title">Episodtitel</string> - <string name="feed_title">Flödestitel</string> + <string name="feed_title">Podcasttitel</string> + <string name="random">Slumpa</string> + <string name="smart_shuffle">Smart Blandning</string> <string name="ascending">Stigande</string> <string name="descending">Fallande</string> <string name="clear_queue_confirmation_msg">Bekräfta att du vill rensa kön frÃ¥n ALLA episoder.</string> @@ -272,7 +287,7 @@ <string name="enable_sonic">Aktivera Sonic</string> <!--Empty list labels--> <string name="no_items_label">Det finns inget i denna lista.</string> - <string name="no_feeds_label">Du har inte prenumererat pÃ¥ nÃ¥got flöde ännu.</string> + <string name="no_feeds_label">Du har inte prenumererat pÃ¥ nÃ¥gra podcasts än.</string> <string name="no_chapters_label">Denna episod har inga kapitel.</string> <string name="no_shownotes_label">Denna episod har inga shownotes.</string> <!--Preferences--> @@ -281,15 +296,23 @@ <string name="other_pref">Annat</string> <string name="about_pref">Om</string> <string name="queue_label">Kö</string> - <string name="services_label">Tjänster</string> + <string name="integrations_label">Integrationer</string> <string name="flattr_label">Flattr</string> + <string name="flattr_summary">Mikrobetalningstjänst</string> + <string name="automation">Automatisering</string> + <string name="download_pref_details">Detaljer</string> + <string name="import_export_pref">Importera/Exportera</string> + <string name="appearance">Utseende</string> + <string name="external_elements">Externa element</string> + <string name="interruptions">Avbrott</string> + <string name="buttons">Uppspelningsknappar</string> + <string name="media_player">Mediaspelare</string> <string name="pref_episode_cleanup_title">Episodupprensning</string> <string name="pref_episode_cleanup_summary">Episoder som inte är i kön och inte är favoriter kan tas bort om Automatisk Nedladdning behöver utrymme för nya episoder</string> <string name="pref_pauseOnDisconnect_sum">Pausa uppspelningen när hörlurar eller bluetooth kopplas ifrÃ¥n.</string> <string name="pref_unpauseOnHeadsetReconnect_sum">Fortsätt uppspelningen när hörlurarna Ã¥teransluts</string> <string name="pref_unpauseOnBluetoothReconnect_sum">Fortsätt uppspelningen när bluetooth Ã¥teransluts</string> <string name="pref_hardwareForwardButtonSkips_title">Knappen spola fram hoppar</string> - <string name="pref_hardwareForwardButtonSkips_sum">Hoppa till nästa episod istället för att snabbspola vid tryck pÃ¥ hÃ¥rdvaruknappen</string> <string name="pref_hardwarePreviousButtonRestarts_title">Knappen föregÃ¥ende startar om</string> <string name="pref_hardwarePreviousButtonRestarts_sum">Starta om den nuvarande episoden när du trycker pÃ¥ hÃ¥rdvaruknappen för föregÃ¥ende istället för att spola tillbaka</string> <string name="pref_followQueue_sum">Hoppa till nästa i kön när uppspelningen är klar</string> @@ -338,7 +361,7 @@ <string name="pref_nav_drawer_feed_order_title">Välj Prenumerationsordning</string> <string name="pref_nav_drawer_feed_order_sum">Ändra ordningen pÃ¥ dina prenumerationer</string> <string name="pref_nav_drawer_feed_counter_title">Val För Prenumerationsräknaren</string> - <string name="pref_nav_drawer_feed_counter_sum">Ändra informationen som visas av prenumerationsräknaren</string> + <string name="pref_nav_drawer_feed_counter_sum">Ändra informationen som visas vid prenumerationsräknaren. PÃ¥verkar även sorteringen av prenumerationer om \'Prenumerationsordning\' är satt till \'Räknare\'.</string> <string name="pref_set_theme_sum">Ändra utseendet pÃ¥ AntennaPod.</string> <string name="pref_automatic_download_title">Automatisk Nedladdning</string> <string name="pref_automatic_download_sum">Konfigurera automatisk nedladdning av episoder.</string> @@ -352,6 +375,7 @@ <string name="pref_episode_cache_title">Episodcache</string> <string name="pref_theme_title_light">Ljust</string> <string name="pref_theme_title_dark">Mörkt</string> + <string name="pref_theme_title_trueblack">Svart (AMOLED redo)</string> <string name="pref_episode_cache_unlimited">Obegränsat</string> <string name="pref_update_interval_hours_plural">timmar</string> <string name="pref_update_interval_hours_singular">timme</string> @@ -380,8 +404,6 @@ <string name="pref_rewind_sum">Anpassa antalet sekunder att hoppa bakÃ¥t när snabbspolningsknappen bakÃ¥t används</string> <string name="pref_gpodnet_sethostname_title">Sätt värdnamn</string> <string name="pref_gpodnet_sethostname_use_default_host">Använd standardvärden</string> - <string name="pref_expandNotify_title">Expandera aviseringen</string> - <string name="pref_expandNotify_sum">Expandera alltid aviseringen för att visa uppspelningskontrollerna.</string> <string name="pref_persistNotify_title">BestÃ¥ende Uppspelningskontroller</string> <string name="pref_persistNotify_sum">BehÃ¥ll avisering och kontroller pÃ¥ lÃ¥sskärmen när uppspelningen pausas.</string> <string name="pref_compact_notification_buttons_title">Sätt LÃ¥sskärmens Knappar</string> @@ -402,8 +424,7 @@ <string name="crash_report_sum">Sänd den senaste krashrapporten via e-post</string> <string name="send_email">Sänd e-post</string> <string name="experimental_pref">Experimentellt</string> - <string name="pref_sonic_title">Sonic Mediaspelare</string> - <string name="pref_sonic_message">Använd den inbyggda Sonic mediaspelare som ersättning för Androids egna mediaspelare och Prestissimo</string> + <string name="pref_media_player_message">Välj vilken mediaspelare som ska spela filer</string> <string name="pref_current_value">Nuvarande värde: %1$s</string> <string name="pref_proxy_title">Proxy</string> <string name="pref_proxy_sum">Använd en nätverksproxy</string> @@ -415,6 +436,11 @@ <string name="pref_cast_message_free_flavor">Chromecast kräver propretiära tredjepartsbibliotek som inte är inkluderade i denna version av AntennaPod</string> <string name="pref_enqueue_downloaded_title">Köa Nedladdade</string> <string name="pref_enqueue_downloaded_summary">Lägg nedladdade episoder i uppspelningskön</string> + <string name="media_player_builtin">Andriods inbyggda spelare</string> + <string name="pref_videoBehavior_title">Vid avslutande av video</string> + <string name="pref_videoBehavior_sum">Beteende när videouppspelning avslutas</string> + <string name="stop_playback">Stoppa uppspelning</string> + <string name="continue_playback">Fortsätt ljuduppspelning</string> <!--Auto-Flattr dialog--> <string name="auto_flattr_enable">Aktivera automatisk Flattring</string> <string name="auto_flattr_after_percent">Flattra episoden sÃ¥ snart %d procent har spelats</string> @@ -424,8 +450,8 @@ <string name="search_hint">Sök efter episoder</string> <string name="found_in_shownotes_label">Hittad i shownotes</string> <string name="found_in_chapters_label">Hittad i kapitel</string> - <string name="found_in_authors_label">Hittad i författare</string> - <string name="found_in_feeds_label">Hittad i flöden</string> + <string name="found_in_authors_label">Hittade i författare</string> + <string name="found_in_feeds_label">Hittade i podcast</string> <string name="search_status_no_results">Inga resultat hittades</string> <string name="search_label">Sök</string> <string name="found_in_title_label">Hittad i titeln</string> @@ -451,8 +477,8 @@ <string name="html_export_label">HTML export</string> <string name="exporting_label">Exporterar…</string> <string name="export_error_label">Exporteringsfel</string> - <string name="opml_export_success_title">OPML Exportering lyckades.</string> - <string name="opml_export_success_sum">.opml filen skrevs till:\u0020</string> + <string name="export_success_title">Exporten lyckades</string> + <string name="export_success_sum">Den exporterade filen skrevs till:\n\n%1$s</string> <string name="opml_import_ask_read_permission">TillgÃ¥ng till extern lagring krävs för att läsa OPML-filen</string> <!--Sleep timer--> <string name="set_sleeptimer_label">Ställ in sömntimer</string> @@ -619,6 +645,14 @@ <string name="proxy_host_empty_error">Värd mÃ¥ste fyllas i</string> <string name="proxy_host_invalid_error">Värd är inte en giltig IP adress eller domän</string> <string name="proxy_port_invalid_error">Porten är inte giltig</string> + <!--Database import/export--> + <string name="import_export">Databas-Import/Export</string> + <string name="import_export_warning">Denna experimentella funktion kan användas för att föra över dina prenumerationer och spelade episoder till en annan enhet.\n\nExporterade databaser kan bara importeras med samma version av AntennaPod. Annars kommer en import att leda till oförutsägbara konsekvenser.\n\nEfter en import kan episoder visas som nedladdade även om de inte är det. Tryck bara pÃ¥ uppspelningsknappen pÃ¥ episoden för att AntennaPod ska kolla det igen.</string> + <string name="label_import">Import</string> + <string name="label_export">Export</string> + <string name="import_select_file">Välj fil att importera</string> + <string name="export_ok">Exporten lyckades.</string> + <string name="import_ok">Importen lyckades.\n\nTryck OK för att starta om AntennaPod</string> <!--Casting--> <string name="cast_media_route_menu_title">Spela pÃ¥...</string> <string name="cast_disconnect_label">Koppla loss castningen</string> @@ -635,4 +669,13 @@ <string name="cast_failed_seek">Misslyckades att söka till den nya positionen pÃ¥ cast-enheten</string> <string name="cast_failed_receiver_player_error">Mottagande uppspelaren har stött pÃ¥ ett allvarligt fel</string> <string name="cast_failed_media_error_skipping">Fel vid uppspelning av media. Hoppar över...</string> + <!--Notification channels--> + <string name="notification_channel_user_action">Ã…tgärd krävs</string> + <string name="notification_channel_user_action_description">Visas om din Ã¥tgärd är obligatorisk, till exempel om du behöver ange ett lösenord.</string> + <string name="notification_channel_downloading">Laddar ner</string> + <string name="notification_channel_downloading_description">Visas under tiden som nedladdning pÃ¥gÃ¥r.</string> + <string name="notification_channel_playing">Uppspelning pÃ¥gÃ¥r</string> + <string name="notification_channel_playing_description">Medger kontroll över uppspelning. Detta är huvudnotifieringen som du ser när en podcast spelas.</string> + <string name="notification_channel_error">Fel</string> + <string name="notification_channel_error_description">Visas om nÃ¥got blev fel, exempelvis om nedladdning eller gpodder synkronisering misslyckas.</string> </resources> diff --git a/core/src/main/res/values-sw-rKE/strings.xml b/core/src/main/res/values-sw-rKE/strings.xml index acf3abe75..2d9481b84 100644 --- a/core/src/main/res/values-sw-rKE/strings.xml +++ b/core/src/main/res/values-sw-rKE/strings.xml @@ -36,4 +36,5 @@ <!--Database import/export--> <!--Casting--> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-te/strings.xml b/core/src/main/res/values-te/strings.xml index 93db7b76f..d73db283a 100644 --- a/core/src/main/res/values-te/strings.xml +++ b/core/src/main/res/values-te/strings.xml @@ -3,6 +3,7 @@ <!--Activitiy and fragment titles--> <string name="feeds_label">ఫీడà±à°²à±</string> <string name="statistics_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> @@ -13,33 +14,63 @@ <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> <string name="free_space_label">%1$s ఖాళీ</string> <!--Statistics fragment--> + <string name="statistics_mode">గణాంకాల రీతి</string> <!--Main activity--> + <string name="drawer_open">మెనూని తెరà±à°µà±</string> + <string name="drawer_close">మెనూని మూసివేయి</string> <string name="drawer_feed_counter_none">à°à°®à±€à°²à±‡à°µà±</string> <!--Webview actions--> <!--Playback history--> + <string name="clear_history_label">à°šà°°à°¿à°¤à±à°°à°¨à± à°¤à±à°¡à°¿à°šà°¿à°µà±‡à°¯à°¿</string> <!--Other--> + <string name="confirm_label">నిరà±à°§à°¾à°°à°¿à°‚à°šà±</string> <string name="cancel_label">à°°à°¦à±à°¦à±à°šà±‡à°¯à°¿</string> <string name="yes">à°…à°µà±à°¨à±</string> <string name="no">కాదà±</string> <string name="language_label">à°à°¾à°·</string> <string name="podcast_settings_label">అమరికలà±</string> + <string name="cover_label">బొమà±à°®</string> + <string name="error_label">పొరపాటà±</string> + <string name="error_msg_prefix">పొరపాటౠజరిగింది:</string> + <string name="chapters_label">చాపà±à°Ÿà°°à±à°²à±</string> + <string name="chapter_duration">నిడివి: %1$s</string> <string name="description_label">వివరణ</string> + <string name="most_recent_prefix">à°…à°¤à±à°¯à°‚à°¤ ఇటీవలి ఎపిసోడà±:\u0020</string> + <string name="episodes_suffix">\u0020ఎపిసోడà±à°²à±</string> <string name="length_prefix">నిడివి:\u0020</string> + <string name="size_prefix">పరిమాణం:\u0020</string> <string name="loading_label">వసà±à°¤à±‹à°‚ది…</string> + <string name="save_username_password_label">వాడà±à°•à°°à°¿ పేరà±à°¨à±€ సంకేతపదానà±à°¨à±€ à°à°¦à±à°°à°ªà°°à°šà±</string> <string name="close_label">మూసివేయి</string> + <string name="retry_label">మళà±à°³à±€ à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà±</string> <string name="feed_auto_download_always">à°Žà°²à±à°²à°ªà±à°ªà±à°¡à±‚</string> <string name="send_label">పంపించà±â€¦</string> + <plurals name="episode_cleanup_days_after_listening"> + <item quantity="one">à°®à±à°—à°¿à°‚à°šà°¿à°¨ 1 రోజౠతరà±à°µà°¾à°¤</item> + <item quantity="other">à°®à±à°—à°¿à°‚à°šà°¿à°¨ %d రోజà±à°² తరà±à°µà°¾à°¤</item> + </plurals> <!--'Add Feed' Activity labels--> + <string name="feedurl_label">ఫీడౠచిరà±à°¨à°¾à°®à°¾</string> + <string name="etxtFeedurlHint">www.example.com/feed</string> <!--Actions on feeds--> + <string name="show_info_label">సమాచారం చూపించà±</string> <string name="share_label">పంచà±à°•à±‹à°‚డి…</string> <!--actions on feeditems--> + <string name="download_label">దింపà±à°•à±‹</string> <string name="play_label">ఆడించà±</string> <string name="pause_label">నిలà±à°ªà±</string> <string name="stop_label">ఆపివేయి</string> + <string name="remove_label">తొలగించà±</string> <string name="delete_label">తొలగించà±</string> <!--Download messages and labels--> + <string name="download_error_details">వివరాలà±</string> + <string name="download_type_feed">ఫీడà±</string> <!--Mediaplayer messages--> <!--Queue operations--> <string name="date">తేదీ</string> @@ -51,15 +82,22 @@ <!--Variable Speed--> <!--Empty list labels--> <!--Preferences--> + <string name="other_pref">ఇతర</string> <string name="about_pref">à°—à±à°°à°¿à°‚à°šà°¿</string> - <string name="services_label">సేవలà±</string> <string name="network_pref">నెటà±â€Œà°µà°°à±à°•à±</string> + <string name="pref_autoUpdateIntervallOrTime_Disable">అచేతనించà±</string> + <string name="pref_autoUpdateIntervallOrTime_every">à°ªà±à°°à°¤à±€ %1$s</string> + <string name="pref_theme_title_light">లేత</string> + <string name="pref_theme_title_dark">నలà±à°²à°¨à°¿</string> + <string name="pref_episode_cache_unlimited">అపరిమితం</string> <string name="pref_update_interval_hours_plural">à°—à°‚à°Ÿà°²à±</string> <string name="pref_update_interval_hours_singular">à°—à°‚à°Ÿ</string> <string name="experimental_pref">à°ªà±à°°à°¯à±‹à°—ాతà±à°®à°•à°‚</string> <string name="pref_proxy_title">à°ªà±à°°à°¾à°•à±à°¸à±€</string> + <string name="pref_known_issues">తెలిసిన సమసà±à°¯à°²à±</string> <!--Auto-Flattr dialog--> <!--Search--> + <string name="search_label">వెతà±à°•à±</string> <!--OPML import and export--> <string name="select_all_label">à°…à°¨à±à°¨à±€ à°Žà°‚à°šà±à°•à±‹à°‚à°¡à°¿</string> <!--Sleep timer--> @@ -80,9 +118,14 @@ </plurals> <!--gpodder.net--> <string name="gpodnet_taglist_header">వరà±à°—ాలà±</string> + <string name="gpodnet_toplist_header">మేటి పాడà±â€Œà°•à°¾à°¸à±à°Ÿà±à°²à±</string> + <string name="gpodnet_suggestions_header">సలహాలà±</string> <string name="username_label">వాడà±à°•à°°à°¿ పేరà±</string> <string name="password_label">సంకేతపదం</string> + <string name="gpodnetsync_pref_report_successful">విజయవంతం</string> + <string name="gpodnetsync_pref_report_failed">విఫలమైంది</string> <!--Directory chooser--> + <string name="folder_not_empty_dialog_title">సంచయం ఖాళీగా లేదà±</string> <!--Online feed view--> <!--Content descriptions for image buttons--> <!--Feed information screen--> @@ -99,6 +142,10 @@ <string name="proxy_type_label">à°°à°•à°‚</string> <string name="optional_hint">(à°à°šà±à°šà°¿à°•à°‚)</string> <!--Database import/export--> + <string name="label_import">దిగà±à°®à°¤à°¿</string> + <string name="label_export">దిగà±à°®à°¤à°¿</string> + <string name="export_ok">à°Žà°—à±à°®à°¤à°¿ విజయవంతం.</string> <!--Casting--> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-tr/strings.xml b/core/src/main/res/values-tr/strings.xml index 9d9aa95e8..a980a1224 100644 --- a/core/src/main/res/values-tr/strings.xml +++ b/core/src/main/res/values-tr/strings.xml @@ -48,7 +48,6 @@ <string name="yes">Evet</string> <string name="no">Hayır</string> <string name="reset">Sıfırla</string> - <string name="author_label">Yayıncı</string> <string name="language_label">Dil</string> <string name="url_label">URL</string> <string name="podcast_settings_label">Ayarlar</string> @@ -94,23 +93,12 @@ <string name="mark_all_read_label">Hepsini oynatıldı olarak iÅŸaretle</string> <string name="mark_all_read_msg">Tüm bölümleri oynatıldı olarak iÅŸaretle</string> <string name="mark_all_read_confirmation_msg">Lütfen tüm bölümleri oynatıldı olarak iÅŸaretlemek istediÄŸinizi onaylayın.</string> - <string name="mark_all_read_feed_confirmation_msg">Lütfen bu besleme içindeki tüm bölümleri oynatıldı olarak iÅŸaretlemek istediÄŸinizi onaylayın.</string> <string name="mark_all_seen_label">Hepsini görüldü olarak iÅŸaretle</string> - <string name="mark_all_seen_msg">Tüm bölümler görüldü olarak iÅŸaretlendi</string> <string name="mark_all_seen_confirmation_msg">Lütfen tüm bölümleri görüldü olarak iÅŸaretlemek istediÄŸinizi onaylayın.</string> <string name="show_info_label">Bilgiyi göster</string> - <string name="rename_feed_label">Cep yayınını yeniden adlandır</string> - <string name="remove_feed_label">Cep yayını kaldır</string> <string name="share_label">PaylaÅŸ...</string> - <string name="share_link_label">Link\'i paylaÅŸ</string> - <string name="share_link_with_position_label">Link\'i Konumla birlikte paylaÅŸ</string> <string name="share_feed_url_label">Besleme Adresini PaylaÅŸ</string> - <string name="share_item_url_label">Bölüm Dosyası Adresini PaylaÅŸ</string> - <string name="share_item_url_with_position_label">Bölüm Dosyası Adresini Konumla birlikte paylaÅŸ</string> - <string name="feed_remover_msg">Besleme kaldırılıyor</string> - <string name="load_complete_feed">Tüm beslemeyi yenile</string> <string name="hide_episodes_title">Bölümleri gizle</string> - <string name="episode_actions">Eylemleri uygula</string> <string name="hide_unplayed_episodes_label">Oynatılmadı</string> <string name="hide_paused_episodes_label">Duraklatıldı</string> <string name="hide_played_episodes_label">Oynatıldı</string> @@ -220,7 +208,6 @@ <string name="date">Tarih</string> <string name="duration">Süre</string> <string name="episode_title">Blüm baÅŸlığı</string> - <string name="feed_title">Besleme baÅŸlığı</string> <string name="ascending">Artan</string> <string name="descending">Azalan</string> <string name="clear_queue_confirmation_msg">Lütfen içerisindeki BÃœTÃœN ölümlerle birlikte kuyruÄŸu temizleme isteÄŸinizi onaylayın.</string> @@ -257,14 +244,12 @@ <string name="enable_sonic">Sonic\'i EtkinleÅŸtir</string> <!--Empty list labels--> <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> - <string name="services_label">Servisler</string> <string name="flattr_label">Flattr</string> <string name="pref_episode_cleanup_title">Bölüm TemizliÄŸi</string> <string name="pref_pauseOnDisconnect_sum">Kulaklıklar çıkarıldığında veya bluetooth baÄŸlantısı kesildiÄŸinde çalmayı duraklat</string> @@ -330,8 +315,6 @@ <string name="pref_playback_speed_sum">DeÄŸiÅŸken hızlı ses yürütmesi için kullanılabilir hızları özelleÅŸtirin</string> <string name="pref_gpodnet_sethostname_title">Sunucu ismini ayarla</string> <string name="pref_gpodnet_sethostname_use_default_host">Varsayılan sunucuyu kullan</string> - <string name="pref_expandNotify_title">Bildirimi GeniÅŸlet</string> - <string name="pref_expandNotify_sum">Çalma tuÅŸlarını göstermek için bildirimi her zaman geniÅŸlet.</string> <string name="pref_persistNotify_title">Kalıcı oynatma kontrolleri</string> <string name="pref_persistNotify_sum">Çalma duraklatıldığında bildirim ve ekran kilidi ayarlarını sakla.</string> <string name="pref_showDownloadReport_title">Ä°ndirme Raporunu Göster</string> @@ -374,8 +357,6 @@ <string name="choose_file_from_external_application">Harici uygulama kullan</string> <string name="opml_export_label">OPML dışa aktar</string> <string name="export_error_label">Dışa aktarma hatası</string> - <string name="opml_export_success_title">Opml dışa aktarma baÅŸarılı.</string> - <string name="opml_export_success_sum">.opml dosyasy yazıldı: \u0020</string> <!--Sleep timer--> <string name="set_sleeptimer_label">Zamanlayıcıyı ayarla</string> <string name="disable_sleeptimer_label">Zamanlayıcıyı devre dışı bırak</string> @@ -508,4 +489,5 @@ <!--Database import/export--> <!--Casting--> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-uk-rUA/strings.xml b/core/src/main/res/values-uk-rUA/strings.xml index 18ca0713b..0afc1e8c2 100644 --- a/core/src/main/res/values-uk-rUA/strings.xml +++ b/core/src/main/res/values-uk-rUA/strings.xml @@ -1,11 +1,13 @@ <?xml version='1.0' encoding='UTF-8'?> <resources xmlns:tools="http://schemas.android.com/tools"> <!--Activitiy and fragment titles--> + <string name="feed_update_receiver_name">Оновити підпиÑки</string> <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="new_episodes_label">Ðові</string> <string name="favorite_episodes_label">Улюблені</string> <string name="new_label">Ðові</string> <string name="settings_label">ÐалаштуваннÑ</string> @@ -15,18 +17,20 @@ <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="cancel_download_label">СкаÑувати\nзавантаженнÑ</string> + <string name="playback_history_label">ІÑÑ‚Ð¾Ñ€Ñ–Ñ Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ</string> <string name="gpodnet_main_label">gpodder.net</string> + <string name="gpodnet_summary">Ð¡Ð¸Ð½Ñ…Ñ€Ð¾Ð½Ð¸Ð·Ð°Ñ†Ñ–Ñ Ð· іншими приÑтроÑми</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> + <string name="synchronizing">СинхронізуєтьÑÑ…</string> <!--Statistics fragment--> <string name="total_time_listened_to_podcasts">Загальний Ñ‡Ð°Ñ Ð¿Ñ€Ð¾Ñлуханих подкаÑтів:</string> <string name="statistics_details_dialog">%1$d з %2$d епізодів почато.\n\nПроÑлухано %3$s з %4$s.</string> <string name="statistics_mode">Режим ÑтатиÑтики</string> - <string name="statistics_mode_normal">ОбчиÑлити триваліÑÑ‚ÑŒ проÑлуханого. ПроÑлухане двічі враховуєтьÑÑ Ð´Ð²Ñ–Ñ‡Ð¸, але проÑто позначене Ñк проÑлухане не враховуєтьÑÑ </string> + <string name="statistics_mode_normal">ОбчиÑлити триваліÑÑ‚ÑŒ дійÑно проÑлуханого. ПроÑлухане двічі враховуєтьÑÑ Ð´Ð²Ñ–Ñ‡Ñ–, але проÑто позначене Ñк проÑлухане не враховуєтьÑÑ </string> <string name="statistics_mode_count_all">ПідÑумувати вÑÑ– подкаÑти позначені Ñк проÑлухані</string> <string name="statistics_speed_not_counted">ЗауваженнÑ: ШвидкіÑÑ‚ÑŒ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð²Ð°Ð½Ð½Ñ Ð½Ðµ беретьÑÑ Ð´Ð¾ уваги.</string> <!--Main activity--> @@ -34,9 +38,9 @@ <string name="drawer_close">Сховати меню</string> <string name="drawer_preferences">ÐаÑтройки меню навігації</string> <string name="drawer_feed_order_unplayed_episodes">Сортувати за лічильником</string> - <string name="drawer_feed_order_alphabetical">Ð¡Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð° абеткою</string> + <string name="drawer_feed_order_alphabetical">Сортувати за абеткою</string> <string name="drawer_feed_order_last_update">Сортувати за датою публікації</string> - <string name="drawer_feed_order_most_played">Ð¡Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð° кількіÑÑ‚ÑŽ проÑлуханих епізодів</string> + <string name="drawer_feed_order_most_played">Сортувати за кількіÑÑ‚ÑŽ проÑлуханих епізодів</string> <string name="drawer_feed_counter_new_unplayed">КількіÑÑ‚ÑŒ нових та непроÑлуханих епізодів</string> <string name="drawer_feed_counter_new">КількіÑÑ‚ÑŒ нових епізодів</string> <string name="drawer_feed_counter_unplayed">КількіÑÑ‚ÑŒ непроÑлуханих епізодів</string> @@ -49,20 +53,21 @@ <string name="copied_url_msg">URL Ñкопійовано в буфер</string> <string name="go_to_position_label">До цієї позиції</string> <!--Playback history--> - <string name="clear_history_label">Забути</string> + <string name="clear_history_label">ОчиÑтити Ñ–Ñторію</string> <!--Other--> <string name="confirm_label"> Підтвердити</string> <string name="cancel_label">СкаÑувати</string> <string name="yes">Так</string> <string name="no">ÐÑ–</string> <string name="reset">ПерезапуÑк</string> - <string name="author_label">Ðвтор</string> + <string name="author_label">Ðвтор(и)</string> <string name="language_label">Мова</string> <string name="url_label">URL</string> <string name="podcast_settings_label">ÐалаштуваннÑ</string> <string name="cover_label">ЗображеннÑ</string> <string name="error_label">Помилка</string> <string name="error_msg_prefix">ТрапилаÑÑŒ помілка:</string> + <string name="needs_storage_permission">Ð”Ð»Ñ Ñ†Ñ–Ñ”Ñ— операції потрібен дозвіл на доÑтуп до пам’ÑÑ‚Ñ–</string> <string name="refresh_label">Оновити</string> <string name="external_storage_error_msg">Ðемає доÑтупної карти пам\'ÑÑ‚Ñ–. Зовнішній ноÑій потрібен Ð´Ð»Ñ ÐºÐ¾Ñ€ÐµÐºÑ‚Ð½Ð¾Ñ— роботи додатку</string> <string name="chapters_label">Глави</string> @@ -80,10 +85,10 @@ <string name="retry_label">Повторити знову</string> <string name="auto_download_label">Включити до автозавантаженнÑ</string> <string name="auto_download_apply_to_items_title">ЗаÑтоÑувати до попередніх епізодів</string> - <string name="auto_download_apply_to_items_message">Ðове Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ <i>Ðвтозагрузка</i> буде автоматично заÑтоÑоване до нових епізодів.\nБажаєте також заÑтоÑувати його до тих епізодів що було опубліковано раніше?</string> + <string name="auto_download_apply_to_items_message">Ðове Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ <i>ÐвтозавантаженнÑ</i> буде автоматично заÑтоÑоване до нових епізодів.\nБажаєте також заÑтоÑувати його до тих епізодів що були опубліковані раніше?</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_global">За замовчуваннÑм</string> <string name="feed_auto_download_always">Завжди</string> <string name="feed_auto_download_never">Ðіколи</string> <string name="send_label">Відправити…</string> @@ -93,6 +98,7 @@ <plurals name="episode_cleanup_days_after_listening"> <item quantity="one">1 день піÑÐ»Ñ Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ</item> <item quantity="few">%d дні піÑÐ»Ñ Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ</item> + <item quantity="many">%d днів піÑÐ»Ñ Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ</item> <item quantity="other">%d днів піÑÐ»Ñ Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ</item> </plurals> <!--'Add Feed' Activity labels--> @@ -103,36 +109,42 @@ <string name="podcastdirectories_descr">Ðові подкаÑти можна шукати на iTunes або fyyd, або переглÑнути gpodder.net за іменами, категоріÑми або популÑрніÑÑ‚ÑŽ.</string> <string name="browse_gpoddernet_label">ПереглÑнути gpodder.net</string> <!--Actions on feeds--> - <string name="mark_all_read_label">Позначити вÑÑ– Ñк грані</string> - <string name="mark_all_read_msg">Позначено вÑÑ– епізоди Ñк грані</string> - <string name="mark_all_read_confirmation_msg">Будь лаÑка, підтвердіть що ви бажаєте позначити вÑÑ– епізоди Ñк грані.</string> - <string name="mark_all_read_feed_confirmation_msg">Будь лаÑка, підтвердіть що ви бажаєте позначити вÑÑ– епізоди цього канала Ñк грані.</string> + <string name="mark_all_read_label">Позначити вÑÑ– Ñк відтворені</string> + <string name="mark_all_read_msg">Позначено вÑÑ– епізоди Ñк відтворені</string> + <string name="mark_all_read_confirmation_msg">Будь лаÑка, підтвердіть що ви бажаєте позначити вÑÑ– епізоди Ñк відтворені.</string> + <string name="mark_all_read_feed_confirmation_msg">Будь лаÑка, підтвердіть, що ви бажаєте позначити вÑÑ– епізоди цього подкаÑту Ñк відтворені. </string> <string name="mark_all_seen_label">Позначити вÑÑ– Ñк переглÑнуті</string> <string name="mark_all_seen_msg">Ð’ÑÑ– епізоди позначено Ñк переглÑнуті</string> <string name="mark_all_seen_confirmation_msg">Будь лаÑка, підтвердіть що ви бажаєте позначити вÑÑ– епізоди Ñк переглÑнуті.</string> <string name="show_info_label">ІнформаціÑ</string> + <string name="show_feed_settings_label">Показати Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ð´ÐºÐ°Ñту</string> + <string name="feed_info_label">Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ подкаÑÑ‚</string> + <string name="feed_settings_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> + <string name="share_link_label">ПоділитиÑÑŒ поÑиланнÑм на епізод</string> + <string name="share_link_with_position_label">ПоділітьÑÑ Ð¿Ð¾ÑиланнÑм на епізод з позицією</string> <string name="share_file_label">ПоділитиÑÑŒ файлом</string> - <string name="share_link_with_position_label">ПоділитиÑÑŒ поÑиланнÑм на позицію</string> <string name="share_feed_url_label">ПоділитиÑÑŒ поÑиланнÑм на канал</string> - <string name="share_item_url_label">ПоділитиÑÑŒ поÑиланнÑм на файл епізода</string> - <string name="share_item_url_with_position_label">ПоділитиÑÑŒ поÑиланнÑм на файл епізода з позицією</string> - <string name="feed_delete_confirmation_msg">Будь лаÑка, підтвердіть що ви бажаєте видалити канал \"%1$s\" Ñ– ВСІ епізоди цього канала Ñкі ви завантажили.</string> - <string name="feed_remover_msg">УдалÑÑŽ канал</string> - <string name="load_complete_feed">Оновити канал цілком</string> + <string name="share_item_url_label">ПоділитиÑÑŒ поÑиланнÑм на медіа-файл</string> + <string name="share_item_url_with_position_label">ПоділитиÑÑŒ поÑиланнÑм на медіа-файл з позицією</string> + <string name="feed_delete_confirmation_msg">Будь лаÑка, підтвердіть що ви бажаєте видалити подкаÑÑ‚ \"%1$s\" Ñ– ВСІ його епізоди (разом з завантаженими).</string> + <string name="feed_remover_msg">Ð’Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð¿Ð¾Ð´ÐºÐ°Ñта</string> + <string name="load_complete_feed">Оновити веÑÑŒ подкаÑÑ‚</string> <string name="hide_episodes_title">Приховати епізоди</string> - <string name="episode_actions">ЗаÑтоÑувати дії</string> - <string name="hide_unplayed_episodes_label">Ðеграні</string> - <string name="hide_paused_episodes_label">Ðа паузі</string> - <string name="hide_played_episodes_label">Грані</string> + <string name="batch_edit">Групове редагуваннÑ</string> + <string name="select_all_above">Вибрати вÑе вище</string> + <string name="select_all_below">Вибрати вÑе нижче</string> + <string name="hide_unplayed_episodes_label">Ðевідтворені</string> + <string name="hide_paused_episodes_label">Призупинені</string> + <string name="hide_played_episodes_label">Відтворені</string> <string name="hide_queued_episodes_label">Ð’ черзі</string> <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="hide_has_media_label">Зі звуком або відео</string> + <string name="hide_is_favorite_label">Ð’ улюблених</string> <string name="filtered_label">Фільтровані</string> <string name="refresh_failed_msg">{fa-exclamation-circle} ОÑтаннє Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð±ÑƒÐ»Ð¾ невдалим</string> <string name="open_podcast">Відкрити подкаÑÑ‚</string> @@ -146,10 +158,11 @@ <string name="delete_label">Видалити</string> <string name="delete_failed">Файл не видалено. Можливо, Ð¿ÐµÑ€ÐµÐ·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¸Ñтрою допоможе.</string> <string name="remove_episode_lable">Видалити епізод</string> + <string name="mark_as_seen_label">Позначити Ñк переглÑнутий</string> <string name="marked_as_seen_label">Позначено Ñк переглÑнутий</string> - <string name="mark_read_label">Позначити Ñк граний</string> - <string name="marked_as_read_label">Позначено Ñк граний</string> - <string name="mark_unread_label">Позначити Ñк не граний</string> + <string name="mark_read_label">Позначити Ñк відтворений</string> + <string name="marked_as_read_label">Позначено Ñк відтворений</string> + <string name="mark_unread_label">Позначити Ñк не відтворений</string> <string name="add_to_queue_label">Додати до черги</string> <string name="added_to_queue_label">Додано до черги</string> <string name="remove_from_queue_label">Видалити з черги</string> @@ -162,24 +175,26 @@ <string name="skip_episode_label">ПропуÑтити епізод</string> <string name="activate_auto_download">Включити автозавантаженнÑ</string> <string name="deactivate_auto_download">Виключити автозавантаженнÑ</string> - <string name="reset_position">Вернути початкову позицію відтвореннÑ</string> + <string name="reset_position">Скинути позицію відтвореннÑ</string> <string name="removed_item">Видалено</string> <!--Download messages and labels--> <string name="download_successful">уÑпішно</string> <string name="download_failed">з помилками</string> <string name="download_pending">Потрібно завантажити</string> <string name="download_running">ЗавантаженнÑ</string> - <string name="download_error_device_not_found">Ðемає куди зберігати</string> - <string name="download_error_insufficient_space">Мало міÑцÑ</string> + <string name="download_error_details">Докладно</string> + <string name="download_error_details_message">%1$s \n\nПоÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° файл:\n%2$s</string> + <string name="download_error_device_not_found">ПриÑтрій Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… не знайдено</string> + <string name="download_error_insufficient_space">ÐедоÑтатній проÑÑ‚Ñ–Ñ€ Ð´Ð»Ñ Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ</string> <string name="download_error_file_error">Помилка файлу</string> <string name="download_error_http_data_error">Помилка HTTP</string> <string name="download_error_error_unknown">ЩоÑÑŒ трапилоÑÑŒ</string> <string name="download_error_parser_exception">Помилка парÑера</string> - <string name="download_error_unsupported_type">Ðе підтримую канали такого типа</string> + <string name="download_error_unsupported_type">Ðепідтримуваний тип каналу</string> <string name="download_error_connection_error">Помилка з\'єднаннÑ</string> - <string name="download_error_unknown_host">Ðевідомий host</string> - <string name="download_error_unauthorized">Помилка автентифікації</string> - <string name="download_error_file_type_type">Помилка типа файла</string> + <string name="download_error_unknown_host">Ðевідомий хоÑÑ‚</string> + <string name="download_error_unauthorized">Помилка аутентифікації</string> + <string name="download_error_file_type_type">Помилка типу файлу</string> <string name="download_error_forbidden">Заборонено</string> <string name="cancel_all_downloads_label">СкаÑувати вÑÑ– завантаженнÑ</string> <string name="download_canceled_msg">Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ ÑкаÑоване</string> @@ -193,21 +208,22 @@ <plurals name="downloads_left"> <item quantity="one">%d Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð·Ð°Ð»Ð¸ÑˆÐ¸Ð»Ð¾ÑÑŒ</item> <item quantity="few">%d Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð·Ð°Ð»Ð¸ÑˆÐ¸Ð»Ð¾ÑÑŒ</item> + <item quantity="many">%d завантажень залишилоÑÑŒ</item> <item quantity="other">%d завантажень залишилоÑÑŒ</item> </plurals> <string name="downloads_processing">Обробка завантаженого</string> <string name="download_notification_title">Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… подкаÑту</string> <string name="download_report_content">ЗавантажилоÑÑŒ %1$d уÑпішно, %2$d з помилками</string> - <string name="download_log_title_unknown">Ðевідома назва</string> + <string name="download_log_title_unknown">Ðевідомий заголовок</string> <string name="download_type_feed">Канал</string> <string name="download_type_media">Файл з медіа</string> <string name="download_type_image">ЗображеннÑ</string> <string name="download_request_error_dialog_message_prefix">Помилка при завантажені файлу:\u0020</string> <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_message_not_in_queue">Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ‡ÐµÑ€ÐµÐ· мобільний зв\'Ñзок вимкнено в наÑтройках.\n\nУвімкнути тимчаÑово або тільки додати до черги?\n\n<small>Ваш вибір буде запам\'Ñтовано на 10 хвилин.</small></string> - <string name="confirm_mobile_download_dialog_message">Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ‡ÐµÑ€ÐµÐ· мобільний зв\'Ñзок вимкнено в наÑтройках.\n\nУвімкнути тимчаÑово?\n\n<small>Ваш вибір буде запам\'Ñтовано на 10 хвилин.</small></string> + <string name="confirm_mobile_download_dialog_title">ÐŸÑ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½ÑŒ через мобільні мережі</string> + <string name="confirm_mobile_download_dialog_message_not_in_queue">Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ‡ÐµÑ€ÐµÐ· мобільні мережі вимкнено в наÑтройках.\n\nВибрати Ð´Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ ÐµÐ¿Ñ–Ð·Ð¾Ð´Ñƒ до черги чи тимчаÑове завантаженнÑ?\n\n<small>Ваш вибір запам\'ÑтаєтьÑÑ Ð½Ð° 10 хвилин.</small></string> + <string name="confirm_mobile_download_dialog_message">Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ‡ÐµÑ€ÐµÐ· мобільні мережі вимкнено в наÑтройках.\n\nУвімкнути тимчаÑово?\n\n<small>Ваш вибір запам\'ÑтаєтьÑÑ Ð½Ð° 10 хвилин.</small></string> <string name="confirm_mobile_download_dialog_only_add_to_queue">Лише додати до черги</string> <string name="confirm_mobile_download_dialog_enable_temporarily">Увімкнути тимчаÑово</string> <!--Mediaplayer messages--> @@ -220,13 +236,14 @@ <string name="playback_error_unknown">Ðевідома помилка</string> <string name="no_media_playing_label">Ðемає що грати</string> <string name="player_buffering_msg">Буферізую</string> + <string name="player_go_to_picture_in_picture">Режим Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð² зображенні</string> <string name="playbackservice_notification_title">Грає подкаÑÑ‚</string> <string name="unknown_media_key">AntennaPod - Ðевідомий медіа ключ: %1$d</string> <!--Queue operations--> <string name="lock_queue">Заблокувати чергу</string> <string name="unlock_queue">Розблокувати чергу</string> <string name="queue_locked">Чергу заблоковано</string> - <string name="queue_unlocked">Чергу разблоковано</string> + <string name="queue_unlocked">Чергу розблоковано</string> <string name="clear_queue_label">ОчиÑтити чергу</string> <string name="undo">СкаÑувати</string> <string name="removed_from_queue">Видалено</string> @@ -235,8 +252,10 @@ <string name="sort">ВпорÑдкувати</string> <string name="date">За датою</string> <string name="duration">За триваліÑÑ‚ÑŽ</string> - <string name="episode_title">Ðазва епізода</string> - <string name="feed_title">Ðазва канала</string> + <string name="episode_title">Ðазва епізоду</string> + <string name="feed_title">Ðазва подкаÑта</string> + <string name="random">Випадково</string> + <string name="smart_shuffle">Розумне перемішуваннÑ</string> <string name="ascending">За зроÑтаннÑм</string> <string name="descending">За ÑпаданнÑм</string> <string name="clear_queue_confirmation_msg">Будь лаÑка, підтвердіть що ви бажаєте вилучити вÑÑ– епізоди з черги.</string> @@ -274,7 +293,7 @@ <string name="enable_sonic">Включити Sonic</string> <!--Empty list labels--> <string name="no_items_label">Ðічого в цьому ÑпиÑку</string> - <string name="no_feeds_label">Ðемає підпиÑаних каналів </string> + <string name="no_feeds_label">Ви ще не підпиÑалиÑÑ Ð½Ð° жодні подкаÑти.</string> <string name="no_chapters_label">Ð’ цьому епізоді немає розділів.</string> <string name="no_shownotes_label">До цього епізода немає нотаток.</string> <!--Preferences--> @@ -283,40 +302,49 @@ <string name="other_pref">Інше</string> <string name="about_pref">Про програму</string> <string name="queue_label">Черга</string> - <string name="services_label">СервіÑи</string> + <string name="integrations_label">Інтеграції</string> <string name="flattr_label">Flattr</string> - <string name="pref_episode_cleanup_title">Ð§Ð¸Ñ‰ÐµÐ½Ð½Ñ ÐµÐ¿Ñ–Ð·Ð¾Ð´Ñ–Ð²</string> + <string name="flattr_summary">Ð¡ÐµÑ€Ð²Ñ–Ñ Ð¼Ñ–ÐºÑ€Ð¾Ð¿Ð»Ð°Ñ‚ÐµÐ¶Ñ–Ð²</string> + <string name="automation">ÐвтоматизаціÑ</string> + <string name="download_pref_details">Детально</string> + <string name="import_export_pref">Імпорт/ЕкÑпорт</string> + <string name="appearance">ВиглÑд</string> + <string name="external_elements">Зовнішні елементи</string> + <string name="interruptions">ТимчаÑові паузи</string> + <string name="buttons">Кнопки ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñм</string> + <string name="media_player">Медіа програвач</string> + <string name="pref_episode_cleanup_title">ÐžÑ‡Ð¸Ñ‰ÐµÐ½Ð½Ñ ÐµÐ¿Ñ–Ð·Ð¾Ð´Ñ–Ð²</string> <string name="pref_episode_cleanup_summary">Епізоди що не знаходÑÑ‚ÑŒÑÑ Ð² черзі та не помічені Ñк улюблені можуть бути видалені Ñкщо Ðвтозавантажувач потребуватиме міÑце Ð´Ð»Ñ Ð½Ð¾Ð²Ð¸Ñ… епізодів.</string> - <string name="pref_pauseOnDisconnect_sum">ЗупинÑтиÑÑŒ коли навушники або блютуз від’єднано</string> + <string name="pref_pauseOnDisconnect_sum">ЗупинÑти Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ¾Ð»Ð¸ навушники або блютуз від’єднано</string> <string name="pref_unpauseOnHeadsetReconnect_sum">Поновити Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ¾Ð»Ð¸ навушники повторно під’єднано</string> <string name="pref_unpauseOnBluetoothReconnect_sum">Поновити Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ¾Ð»Ð¸ блютуз повторно під’єднано</string> <string name="pref_hardwareForwardButtonSkips_title">Кнопка перемотки пропуÑкає</string> - <string name="pref_hardwareForwardButtonSkips_sum">При натиÑканні апаратної кнопки перемотки перейти до наÑтупного епізода заміÑÑ‚ÑŒ перемотки.</string> + <string name="pref_hardwareForwardButtonSkips_sum">При натиÑканні кнопки вперед на Ð±Ð»ÑŽÑ‚ÑƒÑ Ð¿Ñ€Ð¸Ñтрої, переходьте до наÑтупного епізоду заміÑÑ‚ÑŒ швидкого перемотуваннÑ</string> <string name="pref_hardwarePreviousButtonRestarts_title">Кнопка \"назад\" повертає до початку</string> <string name="pref_hardwarePreviousButtonRestarts_sum">При натиÑканні апаратної кнопки \"назад\", заміÑÑ‚ÑŒ перемотки, розпочати Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð²Ð°Ð½Ð½Ñ Ð¿Ð¾Ñ‚Ð¾Ñ‡Ð½Ð¾Ð³Ð¾ епізода заново</string> <string name="pref_followQueue_sum">Перейти до наÑтупного епізода в черзі коли поточний закінчено</string> <string name="pref_auto_delete_sum">Видалити епізод піÑÐ»Ñ Ð¿Ð¾Ð²Ð½Ð¾Ð³Ð¾ відтвореннÑ</string> <string name="pref_auto_delete_title">ÐвтовидаленнÑ</string> - <string name="pref_smart_mark_as_played_sum">Позначити епізоди Ñк грані навіть Ñкщо залишилоÑÑŒ менш ніж зазначене чиÑло Ñекунд до ÐºÑ–Ð½Ñ†Ñ Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ</string> + <string name="pref_smart_mark_as_played_sum">Позначити епізоди Ñк відтворені, навіть Ñкщо залишилоÑÑŒ менш ніж зазначене чиÑло Ñекунд до ÐºÑ–Ð½Ñ†Ñ Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ</string> <string name="pref_smart_mark_as_played_title">Розумне Ð¿Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ñлуханих епізодів</string> - <string name="pref_skip_keeps_episodes_sum">Зберігати епізоди що пропущені при програванні </string> - <string name="pref_skip_keeps_episodes_title">Зберігати пропущені при програванні епізоди </string> + <string name="pref_skip_keeps_episodes_sum">Зберігати пропущені епізоди при програванні </string> + <string name="pref_skip_keeps_episodes_title">Зберігати пропущені епізоди</string> <string name="pref_favorite_keeps_episodes_sum">Зберігати епізоди що помічені Ñк улюблені</string> <string name="pref_favorite_keeps_episodes_title">Зберігати улюблені епізоди</string> <string name="playback_pref">ВідтвореннÑ</string> <string name="network_pref">Мережа</string> <string name="pref_autoUpdateIntervallOrTime_title">ЧаÑтота оновлень або Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð² зазначений чаÑ</string> - <string name="pref_autoUpdateIntervallOrTime_sum">Визначити інтервал чаÑу або визначити Ñ‡Ð°Ñ Ñ‰Ð¾Ð´Ð½Ñ Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ</string> - <string name="pref_autoUpdateIntervallOrTime_message">Можливо вÑтановити <i>інтервал</i> Ñк то \"кожні 2 години\", вÑтановити <i>Ñ‡Ð°Ñ Ñ‰Ð¾Ð´Ð½Ñ</i> Ñк то \"7:00\" або <i>відключити</i> автоматичне Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð²Ð·Ð°Ð³Ð°Ð»Ñ–.\n\n<small>Зверніть увагу: Ð§Ð°Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð½Ðµ Ñ” точним. Можливі короткі затримки.</small></string> + <string name="pref_autoUpdateIntervallOrTime_sum">Вкажіть інтервал або певний Ñ‡Ð°Ñ Ð´Ð¾Ð±Ð¸, щоб оновити канали автоматично</string> + <string name="pref_autoUpdateIntervallOrTime_message">Можливо вÑтановити <i>інтервал</i> Ñк то \"кожні 2 години\", вÑтановити <i>Ñ‡Ð°Ñ Ð´Ð½Ñ</i> Ñк то \"7:00\" або повніÑÑ‚ÑŽ <i>вимкнути</i> автоматичне оновленнÑ.\n\n<small>Зверніть увагу: ЧаÑи Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð½Ðµ Ñ” точними. Можливі короткі затримки.</small></string> <string name="pref_autoUpdateIntervallOrTime_Disable">Вимкнути</string> <string name="pref_autoUpdateIntervallOrTime_Interval">Інтервал</string> - <string name="pref_autoUpdateIntervallOrTime_TimeOfDay">Ð’Ñтановити Ñ‡Ð°Ñ Ñ‰Ð¾Ð´Ð½Ñ</string> + <string name="pref_autoUpdateIntervallOrTime_TimeOfDay">Ð’Ñтановити годину</string> <string name="pref_autoUpdateIntervallOrTime_every">кожні %1$s</string> - <string name="pref_autoUpdateIntervallOrTime_at">на %1$s</string> + <string name="pref_autoUpdateIntervallOrTime_at">о %1$s</string> <string name="pref_downloadMediaOnWifiOnly_sum">Завантажувати тільки через Wifi</string> <string name="pref_followQueue_title">Грати безперервно</string> <string name="pref_downloadMediaOnWifiOnly_title">Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ‡ÐµÑ€ÐµÐ· Wifi</string> - <string name="pref_pauseOnHeadsetDisconnect_title">Ðавушники витÑгнуті</string> + <string name="pref_pauseOnHeadsetDisconnect_title">Ðавушники від\'єднані</string> <string name="pref_unpauseOnHeadsetReconnect_title">Повторне Ð¿Ñ–Ð´â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð½Ð°Ð²ÑƒÑˆÐ½Ð¸ÐºÑ–Ð²</string> <string name="pref_unpauseOnBluetoothReconnect_title">Повторне Ð¿Ñ–Ð´â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð±Ð»ÑŽÑ‚ÑƒÐ·</string> <string name="pref_mobileUpdate_title">Мобільне оновленнÑ</string> @@ -325,7 +353,7 @@ <string name="flattr_settings_label">ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Flattr</string> <string name="pref_flattr_auth_title">Увійти до Flattr</string> <string name="pref_flattr_auth_sum">Увійти в облікову flattr Ð´Ð»Ñ Ð¿Ñ–Ð´Ñ‚Ñ€Ð¸Ð¼ÐºÐ¸ авторів напрÑму з додатку</string> - <string name="pref_flattr_this_app_title">Flattr цій додаток</string> + <string name="pref_flattr_this_app_title">Підтримати цей додаток за допомогою Flattr</string> <string name="pref_flattr_this_app_sum">Підтримайте розробку AntennaPod за допомогою flattr. ДÑкую!</string> <string name="pref_revokeAccess_title">Відкликати доÑтуп</string> <string name="pref_revokeAccess_sum">Відкликати дозвіл на доÑтуп до вашого flattr з цього додатку</string> @@ -340,20 +368,21 @@ <string name="pref_nav_drawer_feed_order_title">Ð’Ñтановити порÑдок підпиÑок</string> <string name="pref_nav_drawer_feed_order_sum">Змінити порÑдок ваших підпиÑок</string> <string name="pref_nav_drawer_feed_counter_title">Ðалаштувати лічильник підпиÑок</string> - <string name="pref_nav_drawer_feed_counter_sum">Змінити інформацію Ñку відображає лічильник підпиÑок</string> + <string name="pref_nav_drawer_feed_counter_sum">Змініть інформацію, що відображаєтьÑÑ Ð»Ñ–Ñ‡Ð¸Ð»ÑŒÐ½Ð¸ÐºÐ¾Ð¼ підпиÑки. Також впливає на ÑÐ¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ–Ð´Ð¿Ð¸Ñок, Ñкщо Ð´Ð»Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð° \"ПорÑдок підпиÑок\" вÑтановлено Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \"Лічильник\".</string> <string name="pref_set_theme_sum">Змінити виглÑд AntennaPod</string> <string name="pref_automatic_download_title">ÐвтозавантаженнÑ</string> <string name="pref_automatic_download_sum">ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð°Ð²Ñ‚Ð¾Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ ÐµÐ¿Ñ–Ð·Ð¾Ð´Ñ–Ð²</string> <string name="pref_autodl_wifi_filter_title">Увімкнути фільтр Wi-Fi</string> <string name="pref_autodl_wifi_filter_sum">Дозволити Ð°Ð²Ñ‚Ð¾Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ‚Ñ–Ð»ÑŒÐºÐ¸ в цих Wi-Fi мережах</string> - <string name="pref_autodl_allow_on_mobile_title">Завантажувати через мобільне з’єднаннÑ</string> - <string name="pref_autodl_allow_on_mobile_sum">Дозволити автоматичне Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ‡ÐµÑ€ÐµÐ· мобільне з’єднаннÑ.</string> + <string name="pref_autodl_allow_on_mobile_title">Завантажувати через мобільні мережі</string> + <string name="pref_autodl_allow_on_mobile_sum">Дозволити автоматичне Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ‡ÐµÑ€ÐµÐ· мобільні мережі.</string> <string name="pref_automatic_download_on_battery_title">Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð±ÐµÐ· зарÑдного приÑтрою</string> - <string name="pref_automatic_download_on_battery_sum">Дозволити Ð°Ð²Ñ‚Ð¾Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ ÐºÐ¾Ð»Ð¸ зарÑдний приÑтрій не підключено</string> + <string name="pref_automatic_download_on_battery_sum">Дозволити Ð°Ð²Ñ‚Ð¾Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ ÐºÐ¾Ð»Ð¸ зарÑдний приÑтрій не підключений</string> <string name="pref_parallel_downloads_title">Паралельні завантаженнÑ</string> <string name="pref_episode_cache_title">Кеш епізодів</string> <string name="pref_theme_title_light">Світла</string> <string name="pref_theme_title_dark">Темна</string> + <string name="pref_theme_title_trueblack">Чорна (Ð´Ð»Ñ AMOLED)</string> <string name="pref_episode_cache_unlimited">Без обмежень</string> <string name="pref_update_interval_hours_plural">годин</string> <string name="pref_update_interval_hours_singular">година</string> @@ -365,33 +394,33 @@ <string name="pref_gpodnet_setlogin_information_title">Змінити інформацію Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ñƒ</string> <string name="pref_gpodnet_setlogin_information_sum">Змінити інформацію щодо облікового запиÑу gpodder.net</string> <string name="pref_gpodnet_sync_changes_title">Синхронізувати зміни негайно</string> - <string name="pref_gpodnet_sync_changes_sum">Синхронізувати підпиÑки та зміни Ñтана епізодів з gpodder.net</string> + <string name="pref_gpodnet_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_login_status"><![CDATA[Ви увійшли Ñк <i>%1$s</i> з приÑтрою <i>%2$s</i>]]></string> <string name="pref_gpodnet_notifications_title">ПовідомлÑти про помилки Ñинхронізації</string> <string name="pref_gpodnet_notifications_sum">Це Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ðµ заÑтоÑовуєтьÑÑ Ð´Ð¾ помилок автентифікації.</string> <string name="pref_playback_speed_title">ШвидкіÑÑ‚ÑŒ програваннÑ</string> <string name="pref_playback_speed_sum">ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÑˆÐ²Ñ–Ð´ÐºÐ¾ÑÑ‚Ñ– доÑтупно Ð´Ð»Ñ Ð·Ð¼Ñ–Ð½Ð½Ð¾Ñ— швидкоÑÑ‚Ñ– програваннÑ</string> - <string name="pref_fast_forward">Ð§Ð°Ñ Ð¿Ñ€Ð¾Ð¿ÑƒÑка кнопкой перемотки вперед</string> - <string name="pref_fast_forward_sum">Ðалаштувати кількіÑÑ‚ÑŒ Ñекунд Ñкі пропуÑкаютьÑÑ Ð¿Ñ€Ð¸ натиÑканні кнопки перемотки вперед</string> - <string name="pref_rewind">Ð§Ð°Ñ Ð¿Ñ€Ð¾Ð¿ÑƒÑка кнопкой перемотки назад</string> - <string name="pref_rewind_sum">Ðалаштувати кількіÑÑ‚ÑŒ Ñекунд Ñкі відмотуютьÑÑ Ð¿Ñ€Ð¸ натиÑканні кнопки перемотки назад</string> + <string name="pref_fast_forward">ЧаÑ, що пропуÑкаєтьÑÑ ÐºÐ½Ð¾Ð¿ÐºÐ¾ÑŽ перемотки вперед</string> + <string name="pref_fast_forward_sum">Ðалаштувати кількіÑÑ‚ÑŒ Ñекунд, Ñкі пропуÑкаютьÑÑ Ð¿Ñ€Ð¸ натиÑканні кнопки перемотки вперед</string> + <string name="pref_rewind">ЧаÑ, що пропуÑкаєтьÑÑ ÐºÐ½Ð¾Ð¿ÐºÐ¾ÑŽ відмотки назад</string> + <string name="pref_rewind_sum">Ðалаштувати кількіÑÑ‚ÑŒ Ñекунд Ñкі відмотуютьÑÑ Ð¿Ñ€Ð¸ натиÑканні кнопки відмотки назад</string> <string name="pref_gpodnet_sethostname_title">Ð’Ñтановити ім\'Ñ Ñ…Ð¾Ñта</string> <string name="pref_gpodnet_sethostname_use_default_host">ВикориÑтати хоÑÑ‚ по замовчанню</string> - <string name="pref_expandNotify_title">Розгорнути повідомленнÑ</string> - <string name="pref_expandNotify_sum">Завжди розгортати повідомленнÑ, щоб показати кнопки керуваннÑ.</string> + <string name="pref_expandNotify_title">ВиÑокий пріоритет ÑповіщеннÑ</string> + <string name="pref_expandNotify_sum">Зазвичай це розширює ÑповіщеннÑ, щоб показати кнопки відтвореннÑ.</string> <string name="pref_persistNotify_title">Завжди показувати елементи ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñм</string> <string name="pref_persistNotify_sum">Показувати Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ‚Ð° елементи ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð° екрані Ð±Ð»Ð¾ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð² режимі паузи.</string> <string name="pref_compact_notification_buttons_title">Ðалаштувати кнопки на екрані блокуваннÑ</string> <string name="pref_compact_notification_buttons_sum">Змінити кнопки на екрані блокуваннÑ. Кнопки програваннÑ/пауза завжди включені.</string> <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_lockscreen_background_sum">Ð’Ñтановити картинку поточного епізода Ñк фон екрана блокуваннÑ. Побічний ефект - це Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð±ÑƒÐ´Ðµ також видно в інших додатках.</string> + <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_expand_notify_unsupport_toast">Android до верÑÑ–Ñ— 4.1 не підтримує розширені повідомленнÑ.</string> @@ -404,8 +433,7 @@ <string name="crash_report_sum">ÐадіÑлати е-пошту зі звітом про оÑтанній збій</string> <string name="send_email">ÐадіÑлати е-пошту</string> <string name="experimental_pref">ЕкÑпериментальні</string> - <string name="pref_sonic_title">Sonic Media Player</string> - <string name="pref_sonic_message">ЗаÑтоÑувати вбудований програвач sonic заміÑÑ‚ÑŒ програвача Android та Prestissimo</string> + <string name="pref_media_player_message">Оберіть медіа плеєр Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð²</string> <string name="pref_current_value">Поточне значеннÑ: %1$s</string> <string name="pref_proxy_title">ПрокÑÑ–</string> <string name="pref_proxy_sum">ЗаÑтоÑувати прокÑÑ– Ñервер</string> @@ -417,6 +445,22 @@ <string name="pref_cast_message_free_flavor">Ð”Ð»Ñ Ð¿Ñ–Ð´Ñ‚Ñ€Ð¸Ð¼ÐºÐ¸ Chromecast потрібні бібліотеки Ñкі не включені в цю верÑÑ–ÑŽ AntennaPod</string> <string name="pref_enqueue_downloaded_title">Додати Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð´Ð¾ черги</string> <string name="pref_enqueue_downloaded_summary">Додавати завантажені епізоди до черги</string> + <string name="media_player_builtin">Стандартний плеєр Android</string> + <string name="pref_videoBehavior_title"> При виході з відеорежиму</string> + <string name="pref_videoBehavior_sum">Поведінка при виході з відео</string> + <string name="stop_playback">Зупинити програваннÑ</string> + <string name="continue_playback">Продовжити Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð°ÑƒÐ´Ñ–Ð¾</string> + <string name="behavior">Поведінка</string> + <string name="pref_back_button_behavior_title">Поведінка кнопки \"Ðазад\"</string> + <string name="pref_back_button_behavior_sum">Зміна поведінки кнопки \"Ðазад\".</string> + <string name="back_button_default">За замовчуваннÑм</string> + <string name="back_button_open_drawer">Відкрити меню навігації</string> + <string name="back_button_double_tap">ÐатиÑніть двічі, щоб вийти</string> + <string name="back_button_show_prompt">Підтвердіть вихід</string> + <string name="close_prompt">ДійÑно закрити AntennaPod?</string> + <string name="double_tap_toast">ÐатиÑніть кнопку назад ще раз, щоб вийти</string> + <string name="back_button_go_to_page">Перейти на Ñторінку…</string> + <string name="back_button_go_to_page_title">Вибрати Ñторінку</string> <!--Auto-Flattr dialog--> <string name="auto_flattr_enable">Включити автоматичне Ð·Ð°Ð¾Ñ…Ð¾Ñ‡ÐµÐ½Ð½Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ñ–Ð² через ÑÐµÑ€Ð²Ñ–Ñ flattr</string> <string name="auto_flattr_after_percent">Заохотити автора через Flattr щойно %d відÑотків епізода було відтворено</string> @@ -427,7 +471,7 @@ <string name="found_in_shownotes_label">Знайдено в нотатках епізода</string> <string name="found_in_chapters_label">Знайдено в главах</string> <string name="found_in_authors_label">Знайдено в авторах</string> - <string name="found_in_feeds_label">Знайдено в каналах</string> + <string name="found_in_feeds_label">Знайдено в подкаÑÑ‚Ñ–</string> <string name="search_status_no_results">Жодних результатів немає</string> <string name="search_label">Пошук</string> <string name="found_in_title_label">Знайдено у назві</string> @@ -435,15 +479,15 @@ <!--OPML import and export--> <string name="opml_import_txtv_button_lable">OPML файли дозволÑÑŽÑ‚ вам перенеÑти подкаÑти з однієї программи до іншої</string> <string name="opml_import_option">Варіант %1$d</string> - <string name="opml_import_explanation_1">Виберіть локальну папку.</string> + <string name="opml_import_explanation_1">Виберіть шлÑÑ… до файлу з локальної файлової ÑиÑтеми.</string> <string name="opml_import_explanation_2">Вибрати OPML файл за допомогою таких додатків Ñк Dropbox, Google Drive або файловий менеджер.</string> - <string name="opml_import_explanation_3">Багато додатків таких Ñк Google Mail, Dropbox, Google Drive та більшіÑÑ‚ÑŒ файлових менеджерів здатні <i>відкрити</i> OPML файли <i>длÑ</i> AntennaPod.</string> + <string name="opml_import_explanation_3">Багато додатків, таких Ñк Google Mail, Dropbox, Google Drive та більшіÑÑ‚ÑŒ файлових менеджерів, здатні <i>відкривати</i> OPML файли <i>за допомогою</i> AntennaPod.</string> <string name="start_import_label">Почати імпорт</string> - <string name="opml_import_label">OPML імпорт</string> + <string name="opml_import_label">Імпорт OPML</string> <string name="opml_directory_error">Помилка!</string> <string name="reading_opml_label">Читаємо OPML файл</string> <string name="opml_reader_error">Помилка при читанні документа OPML:</string> - <string name="opml_import_error_no_file">Жодного файла не обрано!</string> + <string name="opml_import_error_no_file">Жодного файлу не обрано!</string> <string name="select_all_label">Обрати вÑе</string> <string name="deselect_all_label">Убрати виділеннÑ</string> <string name="select_options_label">Обрати…</string> @@ -453,9 +497,9 @@ <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> - <string name="opml_export_success_sum">OPML файл запиÑаний в:\u0020</string> - <string name="opml_import_ask_read_permission">Щоб прочитати файл OPML потрібен доÑтуп до зовнішньої пам’Ñти</string> + <string name="export_success_title">УÑпішний екÑпорт</string> + <string name="export_success_sum">Файл було запиÑано в:\n\n%1$s</string> + <string name="opml_import_ask_read_permission">Щоб прочитати файл OPML потрібен доÑтуп до зовнішнього ноÑÑ–Ñ</string> <!--Sleep timer--> <string name="set_sleeptimer_label">Таймер Ñну</string> <string name="disable_sleeptimer_label">Вимкнути заÑинаннÑ</string> @@ -472,16 +516,19 @@ <plurals name="time_seconds_quantified"> <item quantity="one">1 Ñекунда</item> <item quantity="few">%d Ñекунди</item> + <item quantity="many">%d Ñекунд</item> <item quantity="other">%d Ñекунд</item> </plurals> <plurals name="time_minutes_quantified"> <item quantity="one">1 хвилина</item> <item quantity="few">%d хвилини</item> + <item quantity="many">%d хвилин</item> <item quantity="other">%d хвилин</item> </plurals> <plurals name="time_hours_quantified"> <item quantity="one">1 година</item> <item quantity="few">%d години</item> + <item quantity="many">%d годин</item> <item quantity="other">%d годин</item> </plurals> <string name="auto_enable_label">Увімкнути автоматично</string> @@ -522,7 +569,7 @@ <string name="selected_folder_label">Обрати папку:</string> <string name="create_folder_label">Ðова папка</string> <string name="choose_data_directory">Обрати папку</string> - <string name="choose_data_directory_message">Оберіть, будь лаÑка, базовий каталог Ð´Ð»Ñ Ð´Ð°Ð½Ð¸Ñ…. AntennaPod Ñтворить відповідні підрозділи. </string> + <string name="choose_data_directory_message">Оберіть, будь лаÑка, базовий каталог даних. AntennaPod Ñтворить відповідні підрозділи.</string> <string name="choose_data_directory_permission_rationale">Ð”Ð»Ñ Ð·Ð¼Ñ–Ð½Ð¸ папки Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… потрібен доÑтуп до зовнішнього ноÑÑ–Ñ</string> <string name="create_folder_msg">Створити папку з ім\'Ñм \"%1$s\"?</string> <string name="create_folder_success">Створена нова папка</string> @@ -537,8 +584,8 @@ <string name="set_to_default_folder">Обрати папку по замовчанню</string> <string name="pref_pausePlaybackForFocusLoss_sum">ПризупинÑти Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð²Ð°Ð½Ð½Ñ Ð·Ð°Ð¼Ñ–ÑÑ‚ÑŒ Ð·Ð½Ð¸Ð¶ÐµÐ½Ð½Ñ Ð³ÑƒÑ‡Ð½Ð¾ÑÑ‚Ñ– коли інша програма хоче програти звук</string> <string name="pref_pausePlaybackForFocusLoss_title">Пауза в разі перериваннÑ</string> - <string name="pref_resumeAfterCall_sum">Відновити Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¿Ñ–ÑÐ»Ñ Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ Ð´Ð·Ð²Ñ–Ð½ÐºÐ°</string> - <string name="pref_resumeAfterCall_title">Відновити піÑÐ»Ñ Ð´Ð·Ð²Ñ–Ð½ÐºÐ°</string> + <string name="pref_resumeAfterCall_sum">Поновити Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¿Ñ–ÑÐ»Ñ Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ Ð´Ð·Ð²Ñ–Ð½ÐºÐ°</string> + <string name="pref_resumeAfterCall_title">Поновити піÑÐ»Ñ Ð´Ð·Ð²Ñ–Ð½ÐºÐ°</string> <string name="pref_restart_required">Ð”Ð»Ñ Ð·Ð°ÑтоÑÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð¼Ñ–Ð½ потрібно перезапуÑтити AntennaPod</string> <!--Online feed view--> <string name="subscribe_label">ПідпиÑатиÑÑ</string> @@ -559,10 +606,10 @@ <string name="authentication_descr">Змінити ваші логін та пароль Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ°Ñта та епізодів</string> <string name="auto_download_settings_label">ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð°Ð²Ñ‚Ð¾Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ</string> <string name="episode_filters_label">Фільтр епізодів</string> - <string name="episode_filters_description">Перелік термінів що викориÑтовуютьÑÑ Ð´Ð»Ñ Ð²Ð¸Ñ€Ñ–ÑˆÐµÐ½Ð½Ñ Ñ‡Ð¸ завантажувати епізод автоматично</string> + <string name="episode_filters_description">Перелік термінів, що викориÑтовуютьÑÑ Ð´Ð»Ñ Ð²Ð¸Ñ€Ñ–ÑˆÐµÐ½Ð½Ñ Ñ‡Ð¸ Ñлід завантажувати епізод автоматично</string> <string name="episode_filters_include">Включити</string> - <string name="episode_filters_exclude">Вилучити</string> - <string name="episode_filters_hint">Окремі Ñлова \n\"Слова Разом\"</string> + <string name="episode_filters_exclude">Виключити</string> + <string name="episode_filters_hint">Окремі Ñлова \n\"Кілька Ñлів\"</string> <string name="keep_updated">Підтримувати оновленим</string> <!--Progress information--> <string name="progress_upgrading_database">ÐžÐ½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð±Ð°Ð·Ð¸ даних</string> @@ -575,11 +622,11 @@ <string name="all_label">Ð’ÑÑ–</string> <string name="selected_all_label">Обрано вÑÑ– епізоди</string> <string name="none_label">Жодного</string> - <string name="deselected_all_label">Жодного епізода обрано</string> - <string name="played_label">ПереглÑнуті</string> - <string name="selected_played_label">Обрано переглÑнуті епізоди</string> - <string name="unplayed_label">ÐепереглÑнуті</string> - <string name="selected_unplayed_label">Обрано непереглÑнуті епізоди</string> + <string name="deselected_all_label">Жодного епізода не обрано</string> + <string name="played_label">Відтворені</string> + <string name="selected_played_label">Обрано відтворені епізоди</string> + <string name="unplayed_label">Ðевідтворені</string> + <string name="selected_unplayed_label">Обрано невідтворені епізоди</string> <string name="downloaded_label">Завантажені</string> <string name="selected_downloaded_label">Обрано завантажені епізоди</string> <string name="not_downloaded_label">Ðезавантажені</string> @@ -588,8 +635,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> + <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> @@ -598,7 +645,7 @@ <string name="sort_duration_short_long">ТриваліÑÑ‚ÑŒ (Короткі \u2192 Довгі)</string> <string name="sort_duration_long_short">ТриваліÑÑ‚ÑŒ (Довгі \u2192 Короткі)</string> <!--Rating dialog--> - <string name="rating_title">Оцінити AntennaPod?</string> + <string name="rating_title">ПодобаєтьÑÑ AntennaPod?</string> <string name="rating_message">Ми будемо вдÑчні Ñкщо ви поÑтавите Ñвою оцінку AntennaPod.</string> <string name="rating_never_label">Ðе зараз</string> <string name="rating_later_label">Ðагадати згодом</string> @@ -623,10 +670,18 @@ <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> + <string name="proxy_port_invalid_error">Порт недійÑний</string> + <!--Database import/export--> + <string name="import_export">Імпортувати/ЕкÑпортувати базу данних</string> + <string name="import_export_warning">Ð¦Ñ ÐµÐºÑпериментальна Ñ„ÑƒÐ½ÐºÑ†Ñ–Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑтовуєтьÑÑ Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ½ÐµÑÐµÐ½Ð½Ñ Ð²Ð°ÑˆÐ¸Ñ… підпиÑок та вже проÑлуханих епізодів до іншого приÑтрою.\n\nЕкÑпортована база даних може бути імпортована тією ж Ñамою верÑією AntennaPod. Інакше, результат може бути непередбаченим.\n\nПіÑÐ»Ñ Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ, епізоди можуть відображатиÑÑ Ñк завантажені, навіть Ñкщо вони такими не Ñ”. ПроÑто натиÑніть кнопку Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÐµÐ¿Ñ–Ð·Ð¾Ð´Ñ–Ð², щоб AntennaPod виÑвив це.</string> + <string name="label_import">Імпортувати</string> + <string name="label_export">ЕкÑпортувати</string> + <string name="import_select_file">Обрати файл Ð´Ð»Ñ Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚Ñƒ</string> + <string name="export_ok">УÑпішний екÑпорт</string> + <string name="import_ok">Імпорт пройшов уÑпішно.\n\nБудь лаÑка, натиÑніть ОК щоб перезапуÑтити AntennaPod</string> <!--Casting--> <string name="cast_media_route_menu_title">Грати на…</string> - <string name="cast_disconnect_label">Від’єднатиÑÑŒ від приÑÑ‚Ñ€Ð¾Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð²Ð°Ð½Ð½Ñ</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> @@ -634,10 +689,19 @@ <!--<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_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> + <!--Notification channels--> + <string name="notification_channel_user_action">Потрібна діÑ</string> + <string name="notification_channel_user_action_description">ВідображаєтьÑÑ, Ñкщо потрібна ваша діÑ, наприклад, Ñкщо потрібно ввеÑти пароль.</string> + <string name="notification_channel_downloading">ЗавантаженнÑ</string> + <string name="notification_channel_downloading_description">ПоказуєтьÑÑ Ð¿Ñ–Ð´ Ñ‡Ð°Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ.</string> + <string name="notification_channel_playing">ПрограєтьÑÑ Ð·Ð°Ñ€Ð°Ð·</string> + <string name="notification_channel_playing_description">ДозволÑÑ” керувати відтвореннÑм. Це оÑновне ÑповіщеннÑ, Ñке ви бачите під Ñ‡Ð°Ñ Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¿Ð¾Ð´ÐºÐ°Ñту.</string> + <string name="notification_channel_error">Помилки</string> + <string name="notification_channel_error_description">ВідображаєтьÑÑ, Ñкщо щоÑÑŒ пішло не так, наприклад, Ñкщо не вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ або Ñинхронізувати з gpodder.</string> </resources> diff --git a/core/src/main/res/values-v21/styles.xml b/core/src/main/res/values-v21/styles.xml index 503337c95..c53000c4f 100644 --- a/core/src/main/res/values-v21/styles.xml +++ b/core/src/main/res/values-v21/styles.xml @@ -6,6 +6,19 @@ <style name="Theme.AntennaPod.Dark" parent="Theme.Base.AntennaPod.Dark"> <item name="android:windowContentTransitions">true</item> </style> + <style name="Theme.AntennaPod.TrueBlack" parent="Theme.Base.AntennaPod.TrueBlack"> + <item name="android:windowContentTransitions">true</item> + <item name="android:navigationBarColor">@color/black</item> + <item name="android:colorAccent">@color/white</item> + <item name="android:colorPrimary">@color/black</item> + <item name="android:colorPrimaryDark">@color/black</item> + </style> + <style name="Theme.AntennaPod.TrueBlack.NoTitle" parent="Theme.Base.AntennaPod.TrueBlack.NoTitle"> + <item name="android:navigationBarColor">@color/black</item> + <item name="android:colorAccent">@color/white</item> + <item name="android:colorPrimary">@color/black</item> + <item name="android:colorPrimaryDark">@color/black</item> + </style> <style name="Widget.AntennaPod.Button" parent="Widget.AppCompat.Button"> <item name="textAllCaps">true</item> diff --git a/core/src/main/res/values-v23/styles.xml b/core/src/main/res/values-v23/styles.xml new file mode 100644 index 000000000..5cd274e68 --- /dev/null +++ b/core/src/main/res/values-v23/styles.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + + <style name="Theme.AntennaPod.Light.NoTitle" parent="Theme.Base.AntennaPod.Light.NoTitle"> + <item name="android:windowLightStatusBar">true</item> + <item name="colorPrimaryDark">@color/primary_light</item> + </style> + + <style name="Theme.AntennaPod.Light" parent="Theme.Base.AntennaPod.Light"> + <item name="android:windowLightStatusBar">true</item> + <item name="colorPrimaryDark">@color/primary_light</item> + </style> +</resources> diff --git a/core/src/main/res/values-vi-rVN/strings.xml b/core/src/main/res/values-vi-rVN/strings.xml index acf3abe75..2d9481b84 100644 --- a/core/src/main/res/values-vi-rVN/strings.xml +++ b/core/src/main/res/values-vi-rVN/strings.xml @@ -36,4 +36,5 @@ <!--Database import/export--> <!--Casting--> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-vi/strings.xml b/core/src/main/res/values-vi/strings.xml index 00ed733d1..0982d2b14 100644 --- a/core/src/main/res/values-vi/strings.xml +++ b/core/src/main/res/values-vi/strings.xml @@ -48,7 +48,6 @@ <string name="yes">Có</string> <string name="no">Không</string> <string name="reset">Äặt lại</string> - <string name="author_label">Tác giả</string> <string name="language_label">Ngôn ngữ</string> <string name="url_label">Liên kết</string> <string name="podcast_settings_label">Thiết láºp</string> @@ -93,20 +92,11 @@ <string name="mark_all_read_msg">Äánh dấu đã nghe tất cả các táºp</string> <string name="mark_all_read_confirmation_msg">Hãy xác nháºn bạn muốn đánh dấu đã nghe tất cả các táºp.</string> <string name="mark_all_seen_label">Äánh dấu đã xem tất cả</string> - <string name="mark_all_seen_msg">Äánh dấu đã xem tất cả các táºp</string> <string name="mark_all_seen_confirmation_msg">Hãy xác nháºn bạn muốn đánh dấu đã xem tất cả các táºp.</string> <string name="show_info_label">Hiện thông tin</string> - <string name="rename_feed_label">Äổi tên podcast</string> - <string name="remove_feed_label">Xoá podcast</string> <string name="share_label">Chia sẻ…</string> - <string name="share_link_label">Chia sẻ liên kết</string> - <string name="share_link_with_position_label">Chia sẻ liên kết cùng vị trà phát</string> <string name="share_feed_url_label">Chia sẻ liên kết feed</string> - <string name="share_item_url_label">Chia sẻ liên kết của táºp nà y</string> - <string name="share_item_url_with_position_label">Chia sẻ liên kết và vị trà phát táºp nà y</string> - <string name="feed_remover_msg">Äang xoá feed</string> <string name="hide_episodes_title">Ẩn các táºp</string> - <string name="episode_actions">Ãp dụng hà nh Ä‘á»™ng</string> <string name="hide_unplayed_episodes_label">ChÆ°a nghe</string> <string name="hide_paused_episodes_label">Äang tạm dừng</string> <string name="hide_played_episodes_label">Äã nghe</string> @@ -204,7 +194,6 @@ <string name="date">Ngà y</string> <string name="duration">Thá»i lượng</string> <string name="episode_title">Tiêu Ä‘á» táºp</string> - <string name="feed_title">Tiêu Ä‘á» feed</string> <string name="ascending">Tăng dần</string> <string name="descending">Giảm dần</string> <!--Flattr--> @@ -233,7 +222,6 @@ <string name="pref_pauseOnDisconnect_sum">Tạm dừng khi tai nghe hoặc thiết bị Bluetooth bị ngắt kết nối</string> <string name="pref_unpauseOnHeadsetReconnect_sum">Tiếp tục phát khi tai nghe được kết nối lại</string> <string name="pref_unpauseOnBluetoothReconnect_sum">Tiếp tục phát khi thiết bị Bluetooth được kết nối lại</string> - <string name="pref_hardwareForwardButtonSkips_sum">Khi ấn nút tua nhanh (nút cứng), không tua mà chuyến sang táºp tiếp theo</string> <string name="pref_hardwarePreviousButtonRestarts_title">Nghe lại khi ấn nút tua lại</string> <string name="pref_hardwarePreviousButtonRestarts_sum">Khi ấn nút tua lại (nút cứng), không tua lại mà phát lại táºp Ä‘ang nghe</string> <string name="pref_followQueue_sum">Chuyển đến mục đợi phát tiếp theo khi nghe xong</string> @@ -309,4 +297,5 @@ <!--Database import/export--> <!--Casting--> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-zh-rCN/strings.xml b/core/src/main/res/values-zh-rCN/strings.xml index 3eda888f9..02e78171c 100644 --- a/core/src/main/res/values-zh-rCN/strings.xml +++ b/core/src/main/res/values-zh-rCN/strings.xml @@ -18,17 +18,19 @@ <string name="cancel_download_label">å–消下载</string> <string name="playback_history_label">æ’放历å²</string> <string name="gpodnet_main_label">gpodder.net</string> + <string name="gpodnet_summary">与其他设备åŒæ¥</string> <string name="gpodnet_auth_label">gpodder.net 登录</string> - <string name="free_space_label">%1$så¯ç”¨</string> + <string name="free_space_label">%1$s å¯ç”¨</string> <string name="episode_cache_full_title">曲目缓å˜å·²æ»¡</string> <string name="episode_cache_full_message">已达到曲目缓å˜é™åˆ¶ï¼Œå¯ä»¥åœ¨è®¾ç½®ä¸æ高缓å˜å¤§å°ã€‚</string> + <string name="synchronizing">æ£åœ¨åŒæ¥â€¦</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> + <string name="statistics_details_dialog">å¬è¿‡äº†æ€»è®¡ %2$d 期æ’客ä¸çš„ %1$d 期。\n\næ’放了总计 %4$s ä¸çš„ %3$s。</string> <string name="statistics_mode">统计模å¼</string> - <string name="statistics_mode_normal">计算实际æ’放时长。æ’放两次的情况被æ£ç¡®è¯†åˆ«ä¸ºä¸¤æ¬¡ï¼Œä½†æ˜¯è¢«æ ‡è®°ä¸ºæœªæ’放状æ€çš„都没有被æ£ç¡®è¯†åˆ«æ”¶å¬æ¬¡æ•°ã€‚</string> - <string name="statistics_mode_count_all">统计所有带有已æ’放æ’å®¢æ ‡è®°çš„æ•°é‡</string> - <string name="statistics_speed_not_counted">注æ„:回放速度ä¸åœ¨è€ƒè™‘范围之内。</string> + <string name="statistics_mode_normal">计算实际上的æ’放次数与时长。æ’æ”¾è¿‡ä¸¤æ¬¡åˆ™å°†è¢«è¯†åˆ«ä¸ºä¸¤æ¬¡ï¼Œä½†æ˜¯è¢«æ‰‹åŠ¨æ ‡è®°ä¸ºå·²æ’放状æ€çš„ä¸ç®—。</string> + <string name="statistics_mode_count_all">统计æ’放次数时仅统计所有带有已æ’放æ’å®¢æ ‡è®°çš„æ•°é‡</string> + <string name="statistics_speed_not_counted">注æ„:æ’放速度ä¸åœ¨è€ƒè™‘范围之内。</string> <!--Main activity--> <string name="drawer_open">打开èœå•</string> <string name="drawer_close">å…³é—èœå•</string> @@ -63,10 +65,11 @@ <string name="cover_label">图片</string> <string name="error_label">错误</string> <string name="error_msg_prefix">出错:</string> + <string name="needs_storage_permission">æ¤æ“作需è¦å˜å‚¨æƒé™ã€‚</string> <string name="refresh_label">刷新</string> <string name="external_storage_error_msg">没有å¯ç”¨çš„外部å˜å‚¨. 请确ä¿å®‰è£…外部å˜å‚¨å™¨, è¿™æ ·æœ¬åº”ç”¨æ‰å¯ä»¥æ£å¸¸å·¥ä½œ.</string> <string name="chapters_label">ç« èŠ‚</string> - <string name="chapter_duration">时长: %1$s</string> + <string name="chapter_duration">时长:%1$s</string> <string name="shownotes_label">笔记</string> <string name="description_label">æè¿°</string> <string name="most_recent_prefix">最近曲目:\u0020</string> @@ -74,13 +77,13 @@ <string name="length_prefix">长度:\u0020</string> <string name="size_prefix">大å°:\u0020</string> <string name="processing_label">处ç†ä¸</string> - <string name="loading_label">æ£åœ¨åŠ è½½</string> + <string name="loading_label">æ£åœ¨åŠ 载…</string> <string name="save_username_password_label">ä¿å˜ç”¨æˆ·å密ç </string> <string name="close_label">å…³é—</string> <string name="retry_label">é‡è¯•</string> <string name="auto_download_label">包å«åˆ°è‡ªåŠ¨ä¸‹è½½</string> <string name="auto_download_apply_to_items_title"> 应用到之å‰çš„曲目ä¸</string> - <string name="auto_download_apply_to_items_message">æ–°çš„ <i>自动下载</i> 的设定将会自动应用到新曲目ä¸ã€‚\nä½ æƒ³åº”ç”¨åˆ°ä¹‹å‰çš„曲目å—?</string> + <string name="auto_download_apply_to_items_message">æ–°çš„ <i>自动下载</i> 设置将会自动应用到新的节目上。\nä½ æƒ³åº”ç”¨åˆ°ä¹‹å‰çš„节目å—?</string> <string name="auto_delete_label">è‡ªåŠ¨åˆ é™¤å‰§é›†</string> <string name="parallel_downloads_suffix">\u0020 并行下载</string> <string name="feed_auto_download_global">全局默认</string> @@ -104,25 +107,13 @@ <string name="mark_all_read_label">å…¨éƒ¨æ ‡è¯†å·²è¯»</string> <string name="mark_all_read_msg">å°†æ‰€æœ‰æ›²ç›®æ ‡è®°ä¸ºå·²æ’放</string> <string name="mark_all_read_confirmation_msg">请确认您è¦å°†æ‰€æœ‰æ›²ç›®æ ‡ä¸ºå·²æ’放</string> - <string name="mark_all_read_feed_confirmation_msg">请确认您è¦å°†è¯¥è®¢é˜…ä¸‹çš„æ‰€æœ‰æ›²ç›®æ ‡ä¸ºå·²æ’放</string> <string name="mark_all_seen_label">所有å¯è§</string> - <string name="mark_all_seen_msg">å°†æ‰€æœ‰æ›²ç›®æ ‡è®°ä¸ºå·²è¯»</string> <string name="mark_all_seen_confirmation_msg">请确认您è¦å°†æ‰€æœ‰æ›²ç›®æ ‡è®°ä¸ºå·²è¯»ã€‚</string> <string name="show_info_label">查看信æ¯</string> - <string name="rename_feed_label">é‡å‘½åæ’客</string> - <string name="remove_feed_label">åˆ é™¤æ’客</string> <string name="share_label">分享</string> - <string name="share_link_label">分享网站链接</string> <string name="share_file_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">请确认您è¦åˆ 除订阅 \"%1$s\" 包括 所有 æ¤è®¢é˜…ä¸çš„已下载曲目。</string> - <string name="feed_remover_msg">åˆ é™¤è®¢é˜…</string> - <string name="load_complete_feed">刷新全部订阅</string> <string name="hide_episodes_title">éšè—曲目</string> - <string name="episode_actions">å¯ç”¨</string> <string name="hide_unplayed_episodes_label">未æ’放</string> <string name="hide_paused_episodes_label">已暂åœ</string> <string name="hide_played_episodes_label">å·²æ’放</string> @@ -231,7 +222,6 @@ <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> @@ -268,7 +258,6 @@ <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--> @@ -277,7 +266,6 @@ <string name="other_pref">其他</string> <string name="about_pref">关于</string> <string name="queue_label">æ’放列表</string> - <string name="services_label">æœåŠ¡</string> <string name="flattr_label">Flattr</string> <string name="pref_episode_cleanup_title">清ç†æ›²ç›®</string> <string name="pref_pauseOnDisconnect_sum">æš‚åœæ’放曲目当耳机或è“牙é‡æ–°è¿žæŽ¥</string> @@ -326,7 +314,6 @@ <string name="pref_nav_drawer_feed_order_title">设置订阅的排åºæ–¹å¼</string> <string name="pref_nav_drawer_feed_order_sum">改å˜ä½ 的订阅的排åºæ–¹å¼</string> <string name="pref_nav_drawer_feed_counter_title">设定订阅数</string> - <string name="pref_nav_drawer_feed_counter_sum">改å˜è®¢é˜…数所代表的信æ¯</string> <string name="pref_set_theme_sum">æ”¹å˜ AntennaPod 外观</string> <string name="pref_automatic_download_title">自动下载</string> <string name="pref_automatic_download_sum">é…置自动下载的曲目</string> @@ -362,8 +349,6 @@ <string name="pref_rewind_sum">自定义æ¯æ¬¡å€’回节目的秒数</string> <string name="pref_gpodnet_sethostname_title">设置主机å</string> <string name="pref_gpodnet_sethostname_use_default_host">使用默认主机</string> - <string name="pref_expandNotify_title">扩展通知</string> - <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> @@ -384,8 +369,6 @@ <string name="crash_report_sum">通过 E-mail å‘é€æœ€åŽå´©æºƒæŠ¥å‘Š</string> <string name="send_email">å‘é€ E-mail</string> <string name="experimental_pref">实验性</string> - <string name="pref_sonic_title">音频媒体æ’放器</string> - <string name="pref_sonic_message">使用内置音频媒体æ’放器代替 Android 原生媒体æ’放器</string> <string name="pref_current_value">当å‰å€¼ï¼š%1$s</string> <string name="pref_proxy_title">代ç†</string> <string name="pref_proxy_sum">选择一个网络代ç†</string> @@ -404,7 +387,6 @@ <!--Search--> <string name="search_hint">查找节目</string> <string name="found_in_chapters_label">ç« èŠ‚ä¸æŸ¥æ‰¾</string> - <string name="found_in_feeds_label">Feeds ä¸æŸ¥æ‰¾</string> <string name="search_status_no_results">没有找到任何结果</string> <string name="search_label">æœç´¢</string> <string name="found_in_title_label">æ ‡é¢˜ä¸æŸ¥æ‰¾</string> @@ -430,8 +412,6 @@ <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> - <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> @@ -598,4 +578,5 @@ <!--<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> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-zh-rHK/strings.xml b/core/src/main/res/values-zh-rHK/strings.xml index acf3abe75..2d9481b84 100644 --- a/core/src/main/res/values-zh-rHK/strings.xml +++ b/core/src/main/res/values-zh-rHK/strings.xml @@ -36,4 +36,5 @@ <!--Database import/export--> <!--Casting--> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values-zh-rTW/strings.xml b/core/src/main/res/values-zh-rTW/strings.xml index 87f749c37..f00904eda 100644 --- a/core/src/main/res/values-zh-rTW/strings.xml +++ b/core/src/main/res/values-zh-rTW/strings.xml @@ -56,7 +56,6 @@ <string name="yes">是</string> <string name="no">å¦</string> <string name="reset">é‡ç½®</string> - <string name="author_label">作者</string> <string name="language_label">語言</string> <string name="url_label">éˆæŽ¥</string> <string name="podcast_settings_label">è¨ç½®</string> @@ -104,25 +103,13 @@ <string name="mark_all_read_label">全部標記為已æ’放</string> <string name="mark_all_read_msg">全部劇集標記為已æ’放</string> <string name="mark_all_read_confirmation_msg">請確èªä½ è¦å°‡æ‰€æœ‰åŠ‡é›†æ¨™è¨˜ç‚ºå·²æ’放。</string> - <string name="mark_all_read_feed_confirmation_msg">請確èªä½ è¦å°‡æ¤æ’放æºçš„所有劇集標記為已æ’放。</string> <string name="mark_all_seen_label">標記為已讀</string> - <string name="mark_all_seen_msg">全部劇集標記為已讀</string> <string name="mark_all_seen_confirmation_msg">請確èªä½ è¦å°‡æ‰€æœ‰åŠ‡é›†æ¨™è¨˜ç‚ºå·²è®€ã€‚</string> <string name="show_info_label">顯示資料</string> - <string name="rename_feed_label">é‡å‘½åæ’客</string> - <string name="remove_feed_label">移除æ’客</string> <string name="share_label">分享</string> - <string name="share_link_label">分享éˆæŽ¥</string> <string name="share_file_label">分享文件</string> - <string name="share_link_with_position_label">分享éˆæŽ¥èˆ‡ä½ç½®</string> <string name="share_feed_url_label">分享æ’客æºéˆæŽ¥</string> - <string name="share_item_url_label">分享劇集文件éˆæŽ¥</string> - <string name="share_item_url_with_position_label">分享劇集文件éˆæŽ¥å’Œä½ç½®</string> - <string name="feed_delete_confirmation_msg">請確èªæ‚¨å³å°‡åˆªé™¤æ’客æº\"%1$s\" 和它所有的劇集。</string> - <string name="feed_remover_msg">移除æ’客æº</string> - <string name="load_complete_feed">刷新完æˆæ’客æº</string> <string name="hide_episodes_title">éš±è—劇集</string> - <string name="episode_actions">應用</string> <string name="hide_unplayed_episodes_label">未æ’放</string> <string name="hide_paused_episodes_label">æš«åœ</string> <string name="hide_played_episodes_label">å·²æ’放</string> @@ -232,7 +219,6 @@ <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> @@ -270,7 +256,6 @@ <string name="enable_sonic">啟用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--> @@ -279,7 +264,6 @@ <string name="other_pref">其他</string> <string name="about_pref">關於</string> <string name="queue_label">隊列</string> - <string name="services_label">æœå‹™</string> <string name="flattr_label">Flattr</string> <string name="pref_episode_cleanup_title">劇集清ç†</string> <string name="pref_episode_cleanup_summary">如果自動下載需è¦ç©ºé–“用於新的劇集,則ä¸åœ¨éšŠåˆ—ä¸ä¸¦ä¸”ä¸æ˜¯æœ€æ„›çš„劇集將被移除。</string> @@ -287,7 +271,6 @@ <string name="pref_unpauseOnHeadsetReconnect_sum">當耳機å†æ¬¡é€£æŽ¥æ™‚繼續æ’放</string> <string name="pref_unpauseOnBluetoothReconnect_sum">當è—牙å†æ¬¡é€£æŽ¥æ™‚繼續æ’放</string> <string name="pref_hardwareForwardButtonSkips_title">快進按鈕跳éŽ</string> - <string name="pref_hardwareForwardButtonSkips_sum">當按下一個實體的快進按鈕時,跳éŽä¸‹ä¸€å€‹åŠ‡é›†è€Œä¸é€²è¡Œå¿«é€²</string> <string name="pref_hardwarePreviousButtonRestarts_title">後退éµé‡æ–°æ’放</string> <string name="pref_hardwarePreviousButtonRestarts_sum">當按下一個實體éµçš„後退按鈕時,é‡æ–°æ’放本劇集而ä¸æ˜¯å¾Œé€€</string> <string name="pref_followQueue_sum">當æ’放完畢時自動跳至列表ä¸çš„ä¸‹ä¸€å€‹é …ç›®</string> @@ -319,4 +302,5 @@ <!--Database import/export--> <!--Casting--> <!--<string name="cast_failed_to_connect">Could not connect to the device</string>--> + <!--Notification channels--> </resources> diff --git a/core/src/main/res/values/arrays.xml b/core/src/main/res/values/arrays.xml index 9d9a2453d..6d310e0e5 100644 --- a/core/src/main/res/values/arrays.xml +++ b/core/src/main/res/values/arrays.xml @@ -55,6 +55,18 @@ <item>-1</item> </string-array> + <string-array name="mobile_update_entries"> + <item>@string/pref_mobileUpdate_nothing</item> + <item>@string/pref_mobileUpdate_images</item> + <item>@string/pref_mobileUpdate_everything</item> + </string-array> + + <string-array name="mobile_update_values"> + <item>nothing</item> + <item>images</item> + <item>everything</item> + </string-array> + <string-array name="episode_cleanup_entries"> <item>@string/episode_cleanup_queue_removal</item> <item>0</item> @@ -68,10 +80,11 @@ <string-array name="episode_cleanup_values"> <item>-1</item> <item>0</item> - <item>1</item> - <item>3</item> - <item>5</item> - <item>7</item> + <item>12</item> + <item>24</item> + <item>72</item> + <item>120</item> + <item>168</item> <item>-2</item> </string-array> @@ -137,10 +150,12 @@ <string-array name="theme_options"> <item>@string/pref_theme_title_light</item> <item>@string/pref_theme_title_dark</item> + <item>@string/pref_theme_title_trueblack</item> </string-array> <string-array name="theme_values"> <item>0</item> <item>1</item> + <item>2</item> </string-array> <string-array name="nav_drawer_titles"> @@ -181,6 +196,28 @@ <item>3</item> </string-array> + <string-array name="media_player_options"> + <item>@string/media_player_builtin</item> + <item>@string/media_player_sonic</item> + <item>@string/media_player_exoplayer</item> + </string-array> + + <string-array name="media_player_values"> + <item>builtin</item> + <item>sonic</item> + <item>exoplayer</item> + </string-array> + + <string-array name="media_player_options_no_sonic"> + <item>@string/media_player_builtin</item> + <item>@string/media_player_exoplayer</item> + </string-array> + + <string-array name="media_player_values_no_sonic"> + <item>builtin</item> + <item>exoplayer</item> + </string-array> + <string-array name="episode_filter_options"> <item>@string/hide_unplayed_episodes_label</item> <item>@string/hide_paused_episodes_label</item> @@ -190,6 +227,7 @@ <item>@string/hide_downloaded_episodes_label</item> <item>@string/hide_not_downloaded_episodes_label</item> <item>@string/hide_has_media_label</item> + <item>@string/hide_is_favorite_label</item> </string-array> <string-array name="episode_filter_values"> @@ -201,6 +239,7 @@ <item>downloaded</item> <item>not_downloaded</item> <item>has_media</item> + <item>is_favorite</item> </string-array> <string-array name="image_cache_size_options"> @@ -246,4 +285,37 @@ <item>stop</item> <item>continue</item> </string-array> + + <string-array name="batch_long_press_options"> + <item>@string/select_all_above</item> + <item>@string/select_all_below</item> + </string-array> + + <string-array name="back_button_behavior_options"> + <item>@string/back_button_default</item> + <item>@string/back_button_go_to_page</item> + <item>@string/back_button_open_drawer</item> + <item>@string/back_button_double_tap</item> + <item>@string/back_button_show_prompt</item> + </string-array> + + <string-array name="back_button_behavior_values"> + <item>default</item> + <item>page</item> + <item>drawer</item> + <item>doubletap</item> + <item>prompt</item> + </string-array> + + <string-array name="back_button_go_to_pages"> + <item>@string/queue_label</item> + <item>@string/episodes_label</item> + <item>@string/subscriptions_label</item> + </string-array> + + <string-array name="back_button_go_to_pages_tags"> + <item>QueueFragment</item> + <item>EpisodesFragment</item> + <item>SubscriptionFragment</item> + </string-array> </resources> diff --git a/core/src/main/res/values/attrs.xml b/core/src/main/res/values/attrs.xml index b005d4dc3..5311d6cd2 100644 --- a/core/src/main/res/values/attrs.xml +++ b/core/src/main/res/values/attrs.xml @@ -12,6 +12,7 @@ <attr name="av_rewind" format="reference"/> <attr name="content_discard" format="reference"/> <attr name="content_new" format="reference"/> + <attr name="content_remove_from_queue" format="reference"/> <attr name="storage" format="reference"/> <attr name="statistics" format="reference"/> <attr name="feed" format="reference"/> @@ -47,19 +48,29 @@ <attr name="ic_sleep" format="reference"/> <attr name="ic_sleep_off" format="reference"/> <attr name="checkbox_multiple" format="reference"/> - <attr name="ic_check_box" format="reference"/> - <attr name="ic_check_box_outline" format="reference"/> - <attr name="ic_indeterminate_check_box" format="reference"/> + <attr name="ic_select_all" format="reference"/> + <attr name="ic_select_none" format="reference"/> <attr name="ic_sort" format="reference"/> <attr name="ic_sd_storage" format="reference"/> <attr name="ic_create_new_folder" format="reference"/> <attr name="ic_cast_disconnect" format="reference"/> <attr name="ic_swap" format="reference"/> + <attr name="ic_cellphone_text" format="reference"/> + <attr name="ic_question_answer" format="reference" /> + <attr name="ic_bug" format="reference" /> + <attr name="ic_known_issues" format="reference" /> <attr name="master_switch_background" format="color"/> + <attr name="currently_playing_background" format="color"/> <!-- Used in itemdescription --> <attr name="non_transparent_background" format="reference"/> <attr name="overlay_background" format="color"/> <attr name="nav_drawer_background" format="color"/> + <attr name="drawer_activated_color" format="color"/> + + <attr name="about_screen_background" format="color"/> + <attr name="about_screen_card_background" format="color"/> + <attr name="about_screen_card_border" format="color"/> + <attr name="about_screen_font_color" format="color"/> </resources> diff --git a/core/src/main/res/values/colors.xml b/core/src/main/res/values/colors.xml index c9a5b3d6a..5d820f3cf 100644 --- a/core/src/main/res/values/colors.xml +++ b/core/src/main/res/values/colors.xml @@ -22,14 +22,18 @@ <color name="image_readability_tint">#80000000</color> <color name="feed_image_bg">#50000000</color> + <color name="selection_background_color_trueblack">#286E8A</color> <color name="selection_background_color_dark">#286E8A</color> <color name="selection_background_color_light">#81CFEA</color> <!-- Theme colors --> <color name="primary_light">#FFFFFF</color> - + <color name="primary_darktheme">#212121</color> + <color name="nav_drawer_background_dark">#3B3B3B</color> + <color name="nav_drawer_highlighted_dark">#212121</color> <color name="highlight_light">#DDDDDD</color> <color name="highlight_dark">#414141</color> + <color name="highlight_trueblack">#414141</color> <color name="antennapod_blue">#147BAF</color> diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index 44288b24a..3d730516e 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -70,13 +70,14 @@ <string name="yes">Yes</string> <string name="no">No</string> <string name="reset">Reset</string> - <string name="author_label">Author</string> + <string name="author_label">Author(s)</string> <string name="language_label">Language</string> <string name="url_label">URL</string> <string name="podcast_settings_label">Settings</string> <string name="cover_label">Picture</string> <string name="error_label">Error</string> <string name="error_msg_prefix">An error occurred:</string> + <string name="needs_storage_permission">Storage permission is needed for this operation</string> <string name="refresh_label">Refresh</string> <string name="external_storage_error_msg">No external storage is available. Please make sure that external storage is mounted so that the app can work properly.</string> <string name="chapters_label">Chapters</string> @@ -104,10 +105,15 @@ <string name="episode_cleanup_never">Never</string> <string name="episode_cleanup_queue_removal">When not in queue</string> <string name="episode_cleanup_after_listening">After finishing</string> + <plurals name="episode_cleanup_hours_after_listening"> + <item quantity="one">1 hour after finishing</item> + <item quantity="other">%d hours after finishing</item> + </plurals> <plurals name="episode_cleanup_days_after_listening"> <item quantity="one">1 day after finishing</item> <item quantity="other">%d days after finishing</item> </plurals> + <string name="num_selected_label">%d selected</string> <!-- 'Add Feed' Activity labels --> <string name="feedurl_label">Feed URL</string> @@ -121,28 +127,30 @@ <string name="mark_all_read_label">Mark all as played</string> <string name="mark_all_read_msg">Marked all Episodes as played</string> <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_read_feed_confirmation_msg">Please confirm that you want to mark all episodes in this podcast 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_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="show_feed_settings_label">Show feed settings</string> - <string name="feed_info_label">Feed info</string> - <string name="feed_settings_label">Feed settings</string> - <string name="rename_feed_label">Rename Podcast</string> - <string name="remove_feed_label">Remove Podcast</string> + <string name="show_feed_settings_label">Show podcast settings</string> + <string name="feed_info_label">Podcast info</string> + <string name="feed_settings_label">Podcast settings</string> + <string name="rename_feed_label">Rename podcast</string> + <string name="remove_feed_label">Remove podcast</string> <string name="share_label">Share…</string> - <string name="share_link_label">Share Link</string> + <string name="share_link_label">Share Episode URL</string> + <string name="share_link_with_position_label">Share Episode URL with Position</string> <string name="share_file_label">Share File</string> - <string name="share_link_with_position_label">Share Link with Position</string> <string name="share_feed_url_label">Share Feed URL</string> - <string name="share_item_url_label">Share Episode File URL</string> - <string name="share_item_url_with_position_label">Share Episode File URL with Position</string> - <string name="feed_delete_confirmation_msg">Please confirm that you want to delete the feed \"%1$s\" and ALL episodes of this feed that you have downloaded.</string> - <string name="feed_remover_msg">Removing Feed</string> - <string name="load_complete_feed">Refresh complete Feed</string> + <string name="share_item_url_label">Share Media File URL</string> + <string name="share_item_url_with_position_label">Share Media File URL with Position</string> + <string name="feed_delete_confirmation_msg">Please confirm that you want to delete the podcast \"%1$s\" and ALL its episodes (including downloaded episodes).</string> + <string name="feed_remover_msg">Removing podcast</string> + <string name="load_complete_feed">Refresh complete podcast</string> <string name="hide_episodes_title">Hide Episodes</string> <string name="batch_edit">Batch edit</string> + <string name="select_all_above">Select all above</string> + <string name="select_all_below">Select all below</string> <string name="hide_unplayed_episodes_label">Unplayed</string> <string name="hide_paused_episodes_label">Paused</string> <string name="hide_played_episodes_label">Played</string> @@ -151,12 +159,17 @@ <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="hide_is_favorite_label">Is favorite</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> <!-- actions on feeditems --> <string name="download_label">Download</string> + <plurals name="downloading_batch_label"> + <item quantity="one">Downloading %d episode.</item> + <item quantity="other">Downloading %d episodes.</item> + </plurals> <string name="play_label">Play</string> <string name="pause_label">Pause</string> <string name="stop_label">Stop</string> @@ -164,14 +177,35 @@ <string name="remove_label">Remove</string> <string name="delete_label">Delete</string> <string name="delete_failed">Unable to delete file. Rebooting the device could help.</string> - <string name="remove_episode_lable">Remove Episode</string> + <string name="delete_episode_label">Delete Episode</string> + <plurals name="deleted_episode_batch_label"> + <item quantity="one">%d episode deleted.</item> + <item quantity="other">%d episodes deleted.</item> + </plurals> + <string name="mark_as_seen_label">Mark as seen</string> <string name="marked_as_seen_label">Marked as seen</string> <string name="mark_read_label">Mark as played</string> <string name="marked_as_read_label">Marked as played</string> + <plurals name="marked_read_batch_label"> + <item quantity="one">%d episode marked as played.</item> + <item quantity="other">%d episodes marked as played.</item> + </plurals> <string name="mark_unread_label">Mark as unplayed</string> + <plurals name="marked_unread_batch_label"> + <item quantity="one">%d episode marked as unplayed.</item> + <item quantity="other">%d episodes marked as unplayed.</item> + </plurals> <string name="add_to_queue_label">Add to Queue</string> <string name="added_to_queue_label">Added to Queue</string> + <plurals name="added_to_queue_batch_label"> + <item quantity="one">%d episode added to queue.</item> + <item quantity="other">%d episodes added to queue.</item> + </plurals> <string name="remove_from_queue_label">Remove from Queue</string> + <plurals name="removed_from_queue_batch_label"> + <item quantity="one">%d episode removed from queue.</item> + <item quantity="other">%d episodes removed from queue.</item> + </plurals> <string name="add_to_favorite_label">Add to Favorites</string> <string name="added_to_favorites">Added to Favorites</string> <string name="remove_from_favorite_label">Remove from Favorites</string> @@ -224,6 +258,7 @@ <string name="download_type_media">Media file</string> <string name="download_type_image">Image</string> <string name="download_request_error_dialog_message_prefix">An error occurred when trying to download the file:\u0020</string> + <string name="null_value_podcast_error">No podcast was provided that could be shown.</string> <string name="authentication_notification_title">Authentication required</string> <string name="authentication_notification_msg">The resource you requested requires a username and a password</string> <string name="confirm_mobile_download_dialog_title">Confirm Mobile Download</string> @@ -261,7 +296,7 @@ <string name="date">Date</string> <string name="duration">Duration</string> <string name="episode_title">Episode title</string> - <string name="feed_title">Feed title</string> + <string name="feed_title">Podcast title</string> <string name="random">Random</string> <string name="smart_shuffle">Smart Shuffle</string> <string name="ascending">Ascending</string> @@ -304,10 +339,25 @@ <string name="enable_sonic">Enable Sonic</string> <!-- Empty list labels --> - <string name="no_items_label">There are no items in this list.</string> - <string name="no_feeds_label">You haven\'t subscribed to any feeds yet.</string> + <string name="no_items_header_label">No queued episodes</string> + <string name="no_items_label">You can add episodes to the queue by long-pressing or downloading them.</string> + <string name="no_feeds_label">You haven\'t subscribed to any podcasts yet.</string> <string name="no_chapters_label">This episode has no chapters.</string> <string name="no_shownotes_label">This episode has no shownotes.</string> + <string name="no_run_downloads_head_label">No downloads running</string> + <string name="no_run_downloads_label">You can download episodes on the podcast details screen.</string> + <string name="no_comp_downloads_head_label">No downloaded episodes</string> + <string name="no_comp_downloads_label">You can download episodes on the podcast details screen.</string> + <string name="no_log_downloads_head_label">No download log</string> + <string name="no_log_downloads_label">Download logs will appear here when available.</string> + <string name="no_history_head_label">No History</string> + <string name="no_history_label">After you listen to an episode, it will appear here.</string> + <string name="no_all_episodes_head_label">No Episodes</string> + <string name="no_all_episodes_label">When you add a podcast, the episodes will be shown here.</string> + <string name="no_new_episodes_head_label">No new episodes</string> + <string name="no_new_episodes_label">When new episodes arrive, they will be shown here.</string> + <string name="no_fav_episodes_head_label">No favorite episodes</string> + <string name="no_fav_episodes_label">You can add episodes to the favorites by long-pressing them.</string> <!-- Preferences --> <string name="storage_pref">Storage</string> @@ -321,10 +371,11 @@ <string name="automation">Automation</string> <string name="download_pref_details">Details</string> <string name="import_export_pref">Import/Export</string> + <string name="import_export_search_keywords">backup, restore</string> <string name="appearance">Appearance</string> <string name="external_elements">External elements</string> <string name="interruptions">Interruptions</string> - <string name="buttons">Buttons</string> + <string name="buttons">Playback control buttons</string> <string name="media_player">Media player</string> <string name="pref_episode_cleanup_title">Episode Cleanup</string> <string name="pref_episode_cleanup_summary">Episodes that aren\'t in the queue and aren\'t favorites should be eligible for removal if Auto Download needs space for new episodes</string> @@ -332,7 +383,7 @@ <string name="pref_unpauseOnHeadsetReconnect_sum">Resume playback when the headphones are reconnected</string> <string name="pref_unpauseOnBluetoothReconnect_sum">Resume playback when bluetooth reconnects</string> <string name="pref_hardwareForwardButtonSkips_title">Forward Button Skips</string> - <string name="pref_hardwareForwardButtonSkips_sum">When pressing a hardware forward button skip to the next episode instead of fast-forwarding</string> + <string name="pref_hardwareForwardButtonSkips_sum">When pressing a forward button on a bluetooth-connected device 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> @@ -362,6 +413,9 @@ <string name="pref_unpauseOnBluetoothReconnect_title">Bluetooth Reconnect</string> <string name="pref_mobileUpdate_title">Mobile Updates</string> <string name="pref_mobileUpdate_sum">Allow updates over the mobile data connection</string> + <string name="pref_mobileUpdate_nothing">Nothing</string> + <string name="pref_mobileUpdate_images">Images only</string> + <string name="pref_mobileUpdate_everything">Everything</string> <string name="refreshing_label">Refreshing</string> <string name="flattr_settings_label">Flattr settings</string> <string name="pref_flattr_auth_title">Flattr sign-in</string> @@ -381,7 +435,7 @@ <string name="pref_nav_drawer_feed_order_title">Set Subscription Order</string> <string name="pref_nav_drawer_feed_order_sum">Change the order of your subscriptions</string> <string name="pref_nav_drawer_feed_counter_title">Set Subscription Counter</string> - <string name="pref_nav_drawer_feed_counter_sum">Change the information displayed by the subscription counter</string> + <string name="pref_nav_drawer_feed_counter_sum">Change the information displayed by the subscription counter. Also affects the sorting of subscriptions if \'Subscription Order\' is set to \'Counter\'.</string> <string name="pref_set_theme_sum">Change the appearance of AntennaPod.</string> <string name="pref_automatic_download_title">Automatic Download</string> <string name="pref_automatic_download_sum">Configure the automatic download of episodes.</string> @@ -395,6 +449,7 @@ <string name="pref_episode_cache_title">Episode Cache</string> <string name="pref_theme_title_light">Light</string> <string name="pref_theme_title_dark">Dark</string> + <string name="pref_theme_title_trueblack">Black (AMOLED ready)</string> <string name="pref_episode_cache_unlimited">Unlimited</string> <string name="pref_update_interval_hours_plural">hours</string> <string name="pref_update_interval_hours_singular">hour</string> @@ -423,8 +478,8 @@ <string name="pref_rewind_sum">Customize the number of seconds to jump backwards when the rewind button is clicked</string> <string name="pref_gpodnet_sethostname_title">Set hostname</string> <string name="pref_gpodnet_sethostname_use_default_host">Use default host</string> - <string name="pref_expandNotify_title">Expand Notification</string> - <string name="pref_expandNotify_sum">Always expand the notification to show playback buttons.</string> + <string name="pref_expandNotify_title">High Notification priority</string> + <string name="pref_expandNotify_sum">This usually expands the notification to show playback buttons.</string> <string name="pref_persistNotify_title">Persistent Playback Controls</string> <string name="pref_persistNotify_sum">Keep notification and lockscreen controls when playback is paused.</string> <string name="pref_compact_notification_buttons_title">Set Lockscreen Buttons</string> @@ -445,8 +500,7 @@ <string name="crash_report_sum">Send the latest crash report via e-mail</string> <string name="send_email">Send e-mail</string> <string name="experimental_pref">Experimental</string> - <string name="pref_sonic_title">Sonic Media Player</string> - <string name="pref_sonic_message">Use built-in sonic media player as a replacement for Android\'s native mediaplayer and Prestissimo</string> + <string name="pref_media_player_message">Select which media player to use to play files</string> <string name="pref_current_value">Current value: %1$s</string> <string name="pref_proxy_title">Proxy</string> <string name="pref_proxy_sum">Set a network proxy</string> @@ -458,10 +512,27 @@ <string name="pref_cast_message_free_flavor">Chromecast requires third party proprietary libraries that are disabled in this version of AntennaPod</string> <string name="pref_enqueue_downloaded_title">Enqueue Downloaded</string> <string name="pref_enqueue_downloaded_summary">Add downloaded episodes to the queue</string> - <string name="pref_videoBehavior_title">Video behavior</string> + <string name="media_player_builtin">Built-in Android player</string> + <string name="media_player_sonic" translatable="false">Sonic Media Player</string> + <string name="media_player_exoplayer" translatable="false">ExoPlayer</string> + <string name="pref_skip_silence_title">Skip Silence in Audio</string> + <string name="pref_videoBehavior_title">Upon exiting video</string> <string name="pref_videoBehavior_sum">Behavior when leaving video playback</string> <string name="stop_playback">Stop playback</string> - <string name="continue_playback">Continue playback</string> + <string name="continue_playback">Continue audio playback</string> + <string name="behavior">Behavior</string> + <string name="pref_back_button_behavior_title">Back Button Behavior</string> + <string name="pref_back_button_behavior_sum">Change behavior of the back button.</string> + <string name="back_button_default">Default</string> + <string name="back_button_open_drawer">Open navigation drawer</string> + <string name="back_button_double_tap">Double tap to exit</string> + <string name="back_button_show_prompt">Confirm to exit</string> + <string name="close_prompt">Are you sure you want to close AntennaPod?</string> + <string name="double_tap_toast">Tap back button again to exit</string> + <string name="back_button_go_to_page">Go to page…</string> + <string name="back_button_go_to_page_title">Select page</string> + <string name="pref_delete_removes_from_queue_title">Delete removes from Queue</string> + <string name="pref_delete_removes_from_queue_sum">Automatically remove an episode from the queue when it is deleted.</string> <!-- Auto-Flattr dialog --> <string name="auto_flattr_enable">Enable automatic flattring</string> @@ -473,8 +544,8 @@ <string name="search_hint">Search for episodes</string> <string name="found_in_shownotes_label">Found in show notes</string> <string name="found_in_chapters_label">Found in chapters</string> - <string name="found_in_authors_label">Found in authors</string> - <string name="found_in_feeds_label">Found in feeds</string> + <string name="found_in_authors_label">Found in author(s)</string> + <string name="found_in_feeds_label">Found in podcast</string> <string name="search_status_no_results">No results were found</string> <string name="search_label">Search</string> <string name="found_in_title_label">Found in title</string> @@ -672,6 +743,7 @@ <string name="audio_effects">Audio Effects</string> <string name="stereo_to_mono">Downmix: Stereo to mono</string> <string name="sonic_only">Sonic only</string> + <string name="exoplayer_only">ExoPlayer only</string> <!-- proxy settings --> <string name="proxy_type_label">Type</string> diff --git a/core/src/main/res/values/styles.xml b/core/src/main/res/values/styles.xml index 3a215588e..e9a7a2f64 100644 --- a/core/src/main/res/values/styles.xml +++ b/core/src/main/res/values/styles.xml @@ -26,6 +26,7 @@ <item type="attr" name="av_rewind">@drawable/ic_fast_rewind_grey600_24dp</item> <item type="attr" name="content_discard">@drawable/ic_delete_grey600_24dp</item> <item type="attr" name="content_new">@drawable/ic_add_grey600_24dp</item> + <item type="attr" name="content_remove_from_queue">@drawable/ic_remove_grey600</item> <item type="attr" name="feed">@drawable/ic_feed_grey600_24dp</item> <item type="attr" name="location_web_site">@drawable/ic_web_grey600_24dp</item> <item type="attr" name="navigation_accept">@drawable/ic_done_grey600_24dp</item> @@ -43,6 +44,7 @@ <item type="attr" name="dragview_background">@drawable/ic_drag_vertical_grey600_48dp</item> <item type="attr" name="dragview_float_background">@color/white</item> <item type="attr" name="nav_drawer_background">@color/white</item> + <item type="attr" name="drawer_activated_color">@color/highlight_light</item> <item type="attr" name="ic_new">@drawable/ic_new_releases_grey600_24dp</item> <item type="attr" name="ic_history">@drawable/ic_history_grey600_24dp</item> <item type="attr" name="ic_folder">@drawable/ic_folder_grey600_24dp</item> @@ -59,15 +61,26 @@ <item type="attr" name="ic_filter">@drawable/ic_filter_grey600_24dp</item> <item type="attr" name="ic_sleep">@drawable/ic_sleep_grey600_24dp</item> <item type="attr" name="ic_sleep_off">@drawable/ic_sleep_off_grey600_24dp</item> - <item type="attr" name="ic_check_box">@drawable/ic_check_box_grey600_24dp</item> - <item type="attr" name="ic_check_box_outline">@drawable/ic_check_box_outline_blank_grey600_24dp</item> - <item type="attr" name="ic_indeterminate_check_box">@drawable/ic_indeterminate_check_box_grey600_24dp</item> + <item type="attr" name="ic_select_all">@drawable/ic_select_all_grey600</item> + <item type="attr" name="ic_select_none">@drawable/ic_select_none_grey600</item> <item type="attr" name="ic_sort">@drawable/ic_sort_grey600_24dp</item> <item type="attr" name="ic_sd_storage">@drawable/ic_sd_storage_grey600_36dp</item> <item type="attr" name="ic_create_new_folder">@drawable/ic_create_new_folder_grey600_24dp</item> <item type="attr" name="ic_cast_disconnect">@drawable/ic_cast_disconnect_grey600_36dp</item> + <item type="attr" name="ic_cellphone_text">@drawable/ic_cellphone_text_grey600_24dp</item> + <item type="attr" name="ic_question_answer">@drawable/ic_forum_grey600_24dp</item> + <item type="attr" name="ic_bug">@drawable/ic_bug_grey600_24dp</item> + <item type="attr" name="ic_known_issues">@drawable/ic_format_list_bulleted_grey600_24dp</item> + <item type="attr" name="master_switch_background">@color/master_switch_background_light</item> + <item type="attr" name="currently_playing_background">@color/highlight_light</item> + <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item> + + <item type="attr" name="about_screen_background">#e5e5e5</item> + <item type="attr" name="about_screen_card_background">#ffffff</item> + <item type="attr" name="about_screen_card_border">#d2d2d2</item> + <item type="attr" name="about_screen_font_color">#000000</item> </style> <style name="Theme.AntennaPod.Dark" parent="Theme.Base.AntennaPod.Dark"> @@ -76,6 +89,8 @@ <style name="Theme.Base.AntennaPod.Dark" parent="Theme.AppCompat"> <item name="colorAccent">@color/holo_blue_dark</item> + <item name="colorPrimary">@color/primary_darktheme</item> + <item name="colorPrimaryDark">@color/primary_darktheme</item> <item name="colorControlNormal">@color/white</item> <item name="buttonStyle">@style/Widget.AntennaPod.Button</item> <item name="progressBarTheme">@style/ProgressBarDark</item> @@ -95,6 +110,7 @@ <item type="attr" name="av_rewind">@drawable/ic_fast_rewind_white_24dp</item> <item type="attr" name="content_discard">@drawable/ic_delete_white_24dp</item> <item type="attr" name="content_new">@drawable/ic_add_white_24dp</item> + <item type="attr" name="content_remove_from_queue">@drawable/ic_remove_white</item> <item type="attr" name="feed">@drawable/ic_feed_white_24dp</item> <item type="attr" name="location_web_site">@drawable/ic_web_white_24dp</item> <item type="attr" name="navigation_accept">@drawable/ic_done_white_24dp</item> @@ -111,7 +127,8 @@ <item type="attr" name="overlay_drawable">@drawable/overlay_drawable_dark</item> <item type="attr" name="dragview_background">@drawable/ic_drag_vertical_white_48dp</item> <item type="attr" name="dragview_float_background">@color/black</item> - <item type="attr" name="nav_drawer_background">#3B3B3B</item> + <item type="attr" name="nav_drawer_background">@color/nav_drawer_background_dark</item> + <item type="attr" name="drawer_activated_color">@color/nav_drawer_highlighted_dark</item> <item type="attr" name="ic_new">@drawable/ic_new_releases_white_24dp</item> <item type="attr" name="ic_history">@drawable/ic_history_white_24dp</item> <item type="attr" name="ic_folder">@drawable/ic_folder_white_24dp</item> @@ -128,17 +145,49 @@ <item type="attr" name="ic_filter">@drawable/ic_filter_white_24dp</item> <item type="attr" name="ic_sleep">@drawable/ic_sleep_white_24dp</item> <item type="attr" name="ic_sleep_off">@drawable/ic_sleep_off_white_24dp</item> - <item type="attr" name="ic_check_box">@drawable/ic_check_box_white_24dp</item> - <item type="attr" name="ic_check_box_outline">@drawable/ic_check_box_outline_blank_white_24dp</item> - <item type="attr" name="ic_indeterminate_check_box">@drawable/ic_indeterminate_check_box_white_24dp</item> + <item type="attr" name="ic_select_all">@drawable/ic_select_all_white</item> + <item type="attr" name="ic_select_none">@drawable/ic_select_none_white</item> <item type="attr" name="ic_sort">@drawable/ic_sort_white_24dp</item> <item type="attr" name="ic_sd_storage">@drawable/ic_sd_storage_white_36dp</item> <item type="attr" name="ic_create_new_folder">@drawable/ic_create_new_folder_white_24dp</item> <item type="attr" name="ic_cast_disconnect">@drawable/ic_cast_disconnect_white_36dp</item> + <item type="attr" name="ic_cellphone_text">@drawable/ic_cellphone_text_white_24dp</item> + <item type="attr" name="ic_question_answer">@drawable/ic_baseline_question_answer_white_24dp</item> + <item type="attr" name="ic_bug">@drawable/ic_bug_white_24dp</item> + <item type="attr" name="ic_known_issues">@drawable/ic_format_list_bulleted_white_24dp</item> <item type="attr" name="master_switch_background">@color/master_switch_background_dark</item> + <item type="attr" name="currently_playing_background">@color/highlight_dark</item> <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item> + + <item type="attr" name="about_screen_background">#303030</item> + <item type="attr" name="about_screen_card_background">#424242</item> + <item type="attr" name="about_screen_card_border">#262626</item> + <item type="attr" name="about_screen_font_color">#ffffff</item> + </style> + + <style name="Theme.AntennaPod.TrueBlack" parent="Theme.Base.AntennaPod.TrueBlack"> + <!-- Room for API dependent attributes --> </style> + <style name="Theme.Base.AntennaPod.TrueBlack" parent="Theme.Base.AntennaPod.Dark"> + <item name="progressBarTheme">@style/ProgressBarTrueBlack</item> + <item type="attr" name="non_transparent_background">@color/black</item> + <item type="attr" name="overlay_background">@color/black</item> + <item type="attr" name="overlay_drawable">@drawable/overlay_drawable_dark_trueblack</item> + <item type="attr" name="dragview_background">@drawable/ic_drag_vertical_white_48dp</item> + <item type="attr" name="dragview_float_background">@color/black</item> + <item type="attr" name="nav_drawer_background">@color/black</item> + <item type="attr" name="drawer_activated_color">@color/highlight_trueblack</item> + <item name="android:textColorPrimary">@color/white</item> + <item name="android:color">@color/white</item> + <item name="android:colorBackground">@color/black</item> + <item name="android:windowBackground">@color/black</item> + <item name="android:actionBarStyle">@color/black</item> + <item name="colorPrimary">@color/black</item> + <item name="colorPrimaryDark">@color/black</item> + </style> + + <style name="Theme.AntennaPod.Light.NoTitle" parent="Theme.Base.AntennaPod.Light.NoTitle"> <!-- Room for API dependent attributes --> </style> @@ -165,6 +214,7 @@ <item type="attr" name="av_rewind">@drawable/ic_fast_rewind_grey600_24dp</item> <item type="attr" name="content_discard">@drawable/ic_delete_grey600_24dp</item> <item type="attr" name="content_new">@drawable/ic_add_grey600_24dp</item> + <item type="attr" name="content_remove_from_queue">@drawable/ic_remove_grey600</item> <item type="attr" name="feed">@drawable/ic_feed_grey600_24dp</item> <item type="attr" name="location_web_site">@drawable/ic_web_grey600_24dp</item> <item type="attr" name="navigation_accept">@drawable/ic_done_grey600_24dp</item> @@ -182,6 +232,7 @@ <item type="attr" name="dragview_background">@drawable/ic_drag_vertical_grey600_48dp</item> <item type="attr" name="dragview_float_background">@color/white</item> <item type="attr" name="nav_drawer_background">@color/white</item> + <item type="attr" name="drawer_activated_color">@color/highlight_light</item> <item type="attr" name="ic_new">@drawable/ic_new_releases_grey600_24dp</item> <item type="attr" name="ic_history">@drawable/ic_history_grey600_24dp</item> <item type="attr" name="ic_folder">@drawable/ic_folder_grey600_24dp</item> @@ -198,15 +249,24 @@ <item type="attr" name="ic_filter">@drawable/ic_filter_grey600_24dp</item> <item type="attr" name="ic_sleep">@drawable/ic_sleep_grey600_24dp</item> <item type="attr" name="ic_sleep_off">@drawable/ic_sleep_off_grey600_24dp</item> - <item type="attr" name="ic_check_box">@drawable/ic_check_box_grey600_24dp</item> - <item type="attr" name="ic_check_box_outline">@drawable/ic_check_box_outline_blank_grey600_24dp</item> - <item type="attr" name="ic_indeterminate_check_box">@drawable/ic_indeterminate_check_box_grey600_24dp</item> + <item type="attr" name="ic_select_all">@drawable/ic_select_all_grey600</item> + <item type="attr" name="ic_select_none">@drawable/ic_select_none_grey600</item> <item type="attr" name="ic_sort">@drawable/ic_sort_grey600_24dp</item> <item type="attr" name="ic_sd_storage">@drawable/ic_sd_storage_grey600_36dp</item> <item type="attr" name="ic_create_new_folder">@drawable/ic_create_new_folder_grey600_24dp</item> <item type="attr" name="ic_cast_disconnect">@drawable/ic_cast_disconnect_grey600_36dp</item> + <item type="attr" name="ic_cellphone_text">@drawable/ic_cellphone_text_grey600_24dp</item> + <item type="attr" name="ic_question_answer">@drawable/ic_forum_grey600_24dp</item> + <item type="attr" name="ic_bug">@drawable/ic_bug_grey600_24dp</item> + <item type="attr" name="ic_known_issues">@drawable/ic_format_list_bulleted_grey600_24dp</item> <item type="attr" name="master_switch_background">@color/master_switch_background_light</item> + <item type="attr" name="currently_playing_background">@color/highlight_light</item> <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item> + + <item type="attr" name="about_screen_background">#e5e5e5</item> + <item type="attr" name="about_screen_card_background">#ffffff</item> + <item type="attr" name="about_screen_card_border">#d2d2d2</item> + <item type="attr" name="about_screen_font_color">#000000</item> </style> <style name="Theme.AntennaPod.Dark.NoTitle" parent="Theme.Base.AntennaPod.Dark.NoTitle"> @@ -218,6 +278,8 @@ <item name="windowActionModeOverlay">true</item> <item name="progressBarTheme">@style/ProgressBarDark</item> <item name="colorAccent">@color/holo_blue_dark</item> + <item name="colorPrimary">@color/primary_darktheme</item> + <item name="colorPrimaryDark">@color/primary_darktheme</item> <item name="colorControlNormal">@color/white</item> <item name="buttonStyle">@style/Widget.AntennaPod.Button</item> <item name="alertDialogTheme">@style/AntennaPod.Dialog.Dark</item> @@ -236,6 +298,7 @@ <item type="attr" name="content_discard">@drawable/ic_delete_white_24dp</item> <item type="attr" name="content_new">@drawable/ic_add_white_24dp</item> <item type="attr" name="feed">@drawable/ic_feed_white_24dp</item> + <item type="attr" name="content_remove_from_queue">@drawable/ic_remove_white</item> <item type="attr" name="location_web_site">@drawable/ic_web_white_24dp</item> <item type="attr" name="navigation_accept">@drawable/ic_done_white_24dp</item> <item type="attr" name="navigation_cancel">@drawable/ic_cancel_white_24dp</item> @@ -251,7 +314,8 @@ <item type="attr" name="overlay_drawable">@drawable/overlay_drawable_dark</item> <item type="attr" name="dragview_background">@drawable/ic_drag_vertical_white_48dp</item> <item type="attr" name="dragview_float_background">@color/black</item> - <item type="attr" name="nav_drawer_background">#3B3B3B</item> + <item type="attr" name="nav_drawer_background">@color/nav_drawer_background_dark</item> + <item type="attr" name="drawer_activated_color">@color/nav_drawer_highlighted_dark</item> <item type="attr" name="ic_new">@drawable/ic_new_releases_white_24dp</item> <item type="attr" name="ic_history">@drawable/ic_history_white_24dp</item> <item type="attr" name="ic_folder">@drawable/ic_folder_white_24dp</item> @@ -268,19 +332,54 @@ <item type="attr" name="ic_filter">@drawable/ic_filter_white_24dp</item> <item type="attr" name="ic_sleep">@drawable/ic_sleep_white_24dp</item> <item type="attr" name="ic_sleep_off">@drawable/ic_sleep_off_white_24dp</item> - <item type="attr" name="ic_check_box">@drawable/ic_check_box_white_24dp</item> - <item type="attr" name="ic_check_box_outline">@drawable/ic_check_box_outline_blank_white_24dp</item> - <item type="attr" name="ic_indeterminate_check_box">@drawable/ic_indeterminate_check_box_white_24dp</item> + <item type="attr" name="ic_select_all">@drawable/ic_select_all_white</item> + <item type="attr" name="ic_select_none">@drawable/ic_select_none_white</item> <item type="attr" name="ic_sort">@drawable/ic_sort_white_24dp</item> <item type="attr" name="ic_sd_storage">@drawable/ic_sd_storage_white_36dp</item> <item type="attr" name="ic_create_new_folder">@drawable/ic_create_new_folder_white_24dp</item> <item type="attr" name="ic_cast_disconnect">@drawable/ic_cast_disconnect_white_36dp</item> + <item type="attr" name="ic_cellphone_text">@drawable/ic_cellphone_text_white_24dp</item> + <item type="attr" name="ic_question_answer">@drawable/ic_baseline_question_answer_white_24dp</item> + <item type="attr" name="ic_bug">@drawable/ic_bug_white_24dp</item> + <item type="attr" name="ic_known_issues">@drawable/ic_format_list_bulleted_white_24dp</item> <item type="attr" name="master_switch_background">@color/master_switch_background_dark</item> + <item type="attr" name="currently_playing_background">@color/highlight_dark</item> <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item> + + <item type="attr" name="about_screen_background">#303030</item> + <item type="attr" name="about_screen_card_background">#424242</item> + <item type="attr" name="about_screen_card_border">#262626</item> + <item type="attr" name="about_screen_font_color">#ffffff</item> + </style> + + <style name="Theme.AntennaPod.TrueBlack.NoTitle" parent="Theme.Base.AntennaPod.TrueBlack.NoTitle"> + <!-- Room for API dependent attributes --> </style> + <style name="Theme.Base.AntennaPod.TrueBlack.NoTitle" parent="Theme.Base.AntennaPod.Dark.NoTitle"> + <item name="progressBarTheme">@style/ProgressBarTrueBlack</item> + <item type="attr" name="non_transparent_background">@color/black</item> + <item type="attr" name="overlay_background">@color/black</item> + <item type="attr" name="overlay_drawable">@drawable/overlay_drawable_dark_trueblack</item> + <item type="attr" name="dragview_background">@drawable/ic_drag_vertical_white_48dp</item> + <item type="attr" name="dragview_float_background">@color/black</item> + <item type="attr" name="nav_drawer_background">@color/black</item> + <item type="attr" name="drawer_activated_color">@color/highlight_trueblack</item> + <item type="attr" name="currently_playing_background">@color/highlight_trueblack</item> + <item name="android:textColorPrimary">@color/white</item> + <item name="android:color">@color/white</item> + <item name="android:colorBackground">@color/black</item> + <item name="android:windowBackground">@color/black</item> + <item name="android:actionBarStyle">@color/black</item> + <item name="colorPrimary">@color/black</item> + <item name="colorPrimaryDark">@color/black</item> + </style> + + <style name="Theme.AntennaPod.Dark.Splash" parent="Theme.AppCompat.NoActionBar"> <item name="android:windowBackground">@drawable/bg_splash</item> + <item name="colorPrimary">@color/ic_launcher_background</item> + <item name="colorPrimaryDark">@color/ic_launcher_background</item> </style> <style name="Theme.AntennaPod.VideoPlayer" parent="@style/Theme.AntennaPod.Dark"> @@ -366,4 +465,9 @@ <item name="android:progressDrawable">@drawable/progress_bar_horizontal_dark</item> </style> + <style name="ProgressBarTrueBlack"> + <item name="android:indeterminateOnly">false</item> + <item name="android:progressDrawable">@drawable/progress_bar_horizontal_trueblack</item> + </style> + </resources> 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 f12f1d806..9af76cf86 100644 --- a/core/src/play/java/de/danoeh/antennapod/core/ClientConfig.java +++ b/core/src/play/java/de/danoeh/antennapod/core/ClientConfig.java @@ -14,6 +14,7 @@ import de.danoeh.antennapod.core.util.NetworkUtils; * Apps using the core module of AntennaPod should register implementations of all interfaces here. */ public class ClientConfig { + private ClientConfig(){} /** * Should be used when setting User-Agent header for HTTP-requests. diff --git a/core/src/play/java/de/danoeh/antennapod/core/cast/CastManager.java b/core/src/play/java/de/danoeh/antennapod/core/cast/CastManager.java index 27fb7344d..5198a76bd 100644 --- a/core/src/play/java/de/danoeh/antennapod/core/cast/CastManager.java +++ b/core/src/play/java/de/danoeh/antennapod/core/cast/CastManager.java @@ -1440,12 +1440,6 @@ public class CastManager extends BaseCastManager implements OnFailedListener { return idleReason; } - private void onMessageSendFailed(int errorCode) { - for (CastConsumer consumer : castConsumers) { - consumer.onDataMessageSendFailed(errorCode); - } - } - /* * This is called by onStatusUpdated() of the RemoteMediaPlayer */ diff --git a/core/src/play/java/de/danoeh/antennapod/core/cast/CastUtils.java b/core/src/play/java/de/danoeh/antennapod/core/cast/CastUtils.java index f0a7214c9..88da6a0ec 100644 --- a/core/src/play/java/de/danoeh/antennapod/core/cast/CastUtils.java +++ b/core/src/play/java/de/danoeh/antennapod/core/cast/CastUtils.java @@ -13,7 +13,6 @@ import java.util.Calendar; import java.util.List; import de.danoeh.antennapod.core.feed.Feed; -import de.danoeh.antennapod.core.feed.FeedImage; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.storage.DBReader; @@ -24,6 +23,8 @@ import de.danoeh.antennapod.core.util.playback.Playable; * Helper functions for Cast support. */ public class CastUtils { + private CastUtils(){} + private static final String TAG = "CastUtils"; public static final String KEY_MEDIA_ID = "de.danoeh.antennapod.core.cast.MediaId"; @@ -97,9 +98,9 @@ public class CastUtils { if (subtitle != null) { metadata.putString(MediaMetadata.KEY_SUBTITLE, subtitle); } - FeedImage image = feedItem.getImage(); - if (image != null && !TextUtils.isEmpty(image.getDownload_url())) { - metadata.addImage(new WebImage(Uri.parse(image.getDownload_url()))); + + if (!TextUtils.isEmpty(feedItem.getImageUrl())) { + metadata.addImage(new WebImage(Uri.parse(feedItem.getImageUrl()))); } Calendar calendar = Calendar.getInstance(); calendar.setTime(media.getItem().getPubDate()); diff --git a/core/src/play/java/de/danoeh/antennapod/core/cast/RemoteMedia.java b/core/src/play/java/de/danoeh/antennapod/core/cast/RemoteMedia.java index 894e85a90..1c6dd30c4 100644 --- a/core/src/play/java/de/danoeh/antennapod/core/cast/RemoteMedia.java +++ b/core/src/play/java/de/danoeh/antennapod/core/cast/RemoteMedia.java @@ -24,7 +24,6 @@ import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.feed.MediaType; -import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.util.ChapterUtils; import de.danoeh.antennapod.core.util.playback.Playable; @@ -131,14 +130,6 @@ public class RemoteMedia implements Playable { return feedUrl; } - public FeedMedia lookForFeedMedia() { - FeedItem feedItem = DBReader.getFeedItem(feedUrl, itemIdentifier); - if (feedItem == null) { - return null; - } - return feedItem.getMedia(); - } - @Override public void writeToPreferences(SharedPreferences.Editor prefEditor) { //it seems pointless to do it, since the session should be kept by the remote device. 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 0cca2ffa4..a6b732a4f 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 @@ -151,7 +151,6 @@ public class PlaybackServiceFlavorHelper { // hardware volume buttons control the local device volume mediaRouter.setMediaSessionCompat(null); unregisterWifiBroadcastReceiver(); - callback.setupNotification(false, info); } }; } @@ -181,7 +180,6 @@ public class PlaybackServiceFlavorHelper { // hardware volume buttons control the remote device volume mediaRouter.setMediaSessionCompat(callback.getMediaSession()); registerWifiBroadcastReceiver(); - callback.setupNotification(true, info); } private void switchMediaPlayer(@NonNull PlaybackServiceMediaPlayer newPlayer, 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 79e058d0c..487849ef5 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 @@ -515,8 +515,8 @@ public class RemotePSMP extends PlaybackServiceMediaPlayer { } @Override - public void setSpeed(float speed) { - throw new UnsupportedOperationException("Setting playback speed unsupported for Remote Playback"); + public void setPlaybackParams(float speed, boolean skipSilence) { + //Can be safely ignored as neither set speed not skipSilence is supported } @Override diff --git a/core/src/test/java/de/danoeh/antennapod/core/feed/FeedImageMother.java b/core/src/test/java/de/danoeh/antennapod/core/feed/FeedImageMother.java deleted file mode 100644 index 0fb4992ba..000000000 --- a/core/src/test/java/de/danoeh/antennapod/core/feed/FeedImageMother.java +++ /dev/null @@ -1,9 +0,0 @@ -package de.danoeh.antennapod.core.feed; - -class FeedImageMother { - - public static FeedImage anyFeedImage() { - return new FeedImage(0, "image", null, "http://example.com/picture", false); - } - -} diff --git a/core/src/test/java/de/danoeh/antennapod/core/feed/FeedItemMother.java b/core/src/test/java/de/danoeh/antennapod/core/feed/FeedItemMother.java index 3d7c4fe5f..b78cecc23 100644 --- a/core/src/test/java/de/danoeh/antennapod/core/feed/FeedItemMother.java +++ b/core/src/test/java/de/danoeh/antennapod/core/feed/FeedItemMother.java @@ -2,14 +2,14 @@ package de.danoeh.antennapod.core.feed; import java.util.Date; -import static de.danoeh.antennapod.core.feed.FeedImageMother.anyFeedImage; import static de.danoeh.antennapod.core.feed.FeedMother.anyFeed; class FeedItemMother { + private static final String IMAGE_URL = "http://example.com/image"; static FeedItem anyFeedItemWithImage() { FeedItem item = new FeedItem(0, "Item", "Item", "url", new Date(), FeedItem.PLAYED, anyFeed()); - item.setImage(anyFeedImage()); + item.setImageUrl(IMAGE_URL); return item; } diff --git a/core/src/test/java/de/danoeh/antennapod/core/feed/FeedItemTest.java b/core/src/test/java/de/danoeh/antennapod/core/feed/FeedItemTest.java index 92aacd9d7..857827219 100644 --- a/core/src/test/java/de/danoeh/antennapod/core/feed/FeedItemTest.java +++ b/core/src/test/java/de/danoeh/antennapod/core/feed/FeedItemTest.java @@ -5,67 +5,88 @@ import org.junit.Test; import static de.danoeh.antennapod.core.feed.FeedItemMother.anyFeedItemWithImage; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; public class FeedItemTest { private FeedItem original; - private FeedImage originalImage; private FeedItem changedFeedItem; @Before public void setUp() { original = anyFeedItemWithImage(); - originalImage = original.getImage(); changedFeedItem = anyFeedItemWithImage(); } @Test public void testUpdateFromOther_feedItemImageDownloadUrlChanged() throws Exception { setNewFeedItemImageDownloadUrl(); - original.updateFromOther(changedFeedItem); - - feedItemImageWasUpdated(); + assertFeedItemImageWasUpdated(); } @Test public void testUpdateFromOther_feedItemImageRemoved() throws Exception { feedItemImageRemoved(); - original.updateFromOther(changedFeedItem); - - feedItemImageWasNotUpdated(); + assertFeedItemImageWasNotUpdated(); } @Test public void testUpdateFromOther_feedItemImageAdded() throws Exception { - feedItemHadNoImage(); + original.setImageUrl(null); setNewFeedItemImageDownloadUrl(); - original.updateFromOther(changedFeedItem); + assertFeedItemImageWasUpdated(); + } + + /** + * Test that a played item loses that state after being marked as new. + */ + @Test + public void testMarkPlayedItemAsNew_itemNotPlayed() { + original.setPlayed(true); + original.setNew(); - feedItemImageWasUpdated(); + assertFalse(original.isPlayed()); } - private void feedItemHadNoImage() { - original.setImage(null); + /** + * Test that a new item loses that state after being marked as played. + */ + @Test + public void testMarkNewItemAsPlayed_itemNotNew() { + original.setNew(); + original.setPlayed(true); + + assertFalse(original.isNew()); + } + + /** + * Test that a new item loses that state after being marked as not played. + */ + @Test + public void testMarkNewItemAsNotPlayed_itemNotNew() { + original.setNew(); + original.setPlayed(false); + + assertFalse(original.isNew()); } private void setNewFeedItemImageDownloadUrl() { - changedFeedItem.getImage().setDownload_url("http://example.com/new_picture"); + changedFeedItem.setImageUrl("http://example.com/new_picture"); } private void feedItemImageRemoved() { - changedFeedItem.setImage(null); + changedFeedItem.setImageUrl(null); } - private void feedItemImageWasUpdated() { - assertEquals(original.getImage().getDownload_url(), changedFeedItem.getImage().getDownload_url()); + private void assertFeedItemImageWasUpdated() { + assertEquals(original.getImageUrl(), changedFeedItem.getImageUrl()); } - private void feedItemImageWasNotUpdated() { - assertTrue(originalImage == original.getImage()); + private void assertFeedItemImageWasNotUpdated() { + assertEquals(anyFeedItemWithImage().getImageUrl(), original.getImageUrl()); } }
\ No newline at end of file diff --git a/core/src/test/java/de/danoeh/antennapod/core/feed/FeedMediaMother.java b/core/src/test/java/de/danoeh/antennapod/core/feed/FeedMediaMother.java new file mode 100644 index 000000000..d95b8787c --- /dev/null +++ b/core/src/test/java/de/danoeh/antennapod/core/feed/FeedMediaMother.java @@ -0,0 +1,13 @@ +package de.danoeh.antennapod.core.feed; + +class FeedMediaMother { + + private static final String EPISODE_URL = "http://example.com/episode"; + private static final long SIZE = 42; + private static final String MIME_TYPE = "audio/mp3"; + + static FeedMedia anyFeedMedia() { + return new FeedMedia(null, EPISODE_URL, SIZE, MIME_TYPE); + } + +} diff --git a/core/src/test/java/de/danoeh/antennapod/core/feed/FeedMediaTest.java b/core/src/test/java/de/danoeh/antennapod/core/feed/FeedMediaTest.java new file mode 100644 index 000000000..f27a54f84 --- /dev/null +++ b/core/src/test/java/de/danoeh/antennapod/core/feed/FeedMediaTest.java @@ -0,0 +1,72 @@ +package de.danoeh.antennapod.core.feed; + +import org.junit.Before; +import org.junit.Test; + +import static de.danoeh.antennapod.core.feed.FeedMediaMother.anyFeedMedia; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class FeedMediaTest { + + private FeedMedia media; + + @Before + public void setUp() { + media = anyFeedMedia(); + } + + /** + * Downloading a media from a not new and not played item should not change the item state. + */ + @Test + public void testDownloadMediaOfNotNewAndNotPlayedItem_unchangedItemState() { + FeedItem item = mock(FeedItem.class); + when(item.isNew()).thenReturn(false); + when(item.isPlayed()).thenReturn(false); + + media.setItem(item); + media.setDownloaded(true); + + verify(item, never()).setNew(); + verify(item, never()).setPlayed(true); + verify(item, never()).setPlayed(false); + } + + /** + * Downloading a media from a played item (thus not new) should not change the item state. + */ + @Test + public void testDownloadMediaOfPlayedItem_unchangedItemState() { + FeedItem item = mock(FeedItem.class); + when(item.isNew()).thenReturn(false); + when(item.isPlayed()).thenReturn(true); + + media.setItem(item); + media.setDownloaded(true); + + verify(item, never()).setNew(); + verify(item, never()).setPlayed(true); + verify(item, never()).setPlayed(false); + } + + /** + * Downloading a media from a new item (thus not played) should change the item to not played. + */ + @Test + public void testDownloadMediaOfNewItem_changedToNotPlayedItem() { + FeedItem item = mock(FeedItem.class); + when(item.isNew()).thenReturn(true); + when(item.isPlayed()).thenReturn(false); + + media.setItem(item); + media.setDownloaded(true); + + verify(item).setPlayed(false); + verify(item, never()).setNew(); + verify(item, never()).setPlayed(true); + } + +} diff --git a/core/src/test/java/de/danoeh/antennapod/core/feed/FeedMother.java b/core/src/test/java/de/danoeh/antennapod/core/feed/FeedMother.java index fecc8e377..f46797d28 100644 --- a/core/src/test/java/de/danoeh/antennapod/core/feed/FeedMother.java +++ b/core/src/test/java/de/danoeh/antennapod/core/feed/FeedMother.java @@ -1,13 +1,11 @@ package de.danoeh.antennapod.core.feed; -import static de.danoeh.antennapod.core.feed.FeedImageMother.anyFeedImage; - class FeedMother { + public static final String IMAGE_URL = "http://example.com/image"; public static Feed anyFeed() { - FeedImage image = anyFeedImage(); return new Feed(0, null, "title", "http://example.com", "This is the description", - "http://example.com/payment", "Daniel", "en", null, "http://example.com/feed", image, + "http://example.com/payment", "Daniel", "en", null, "http://example.com/feed", IMAGE_URL, null, "http://example.com/feed", true); } diff --git a/core/src/test/java/de/danoeh/antennapod/core/feed/FeedTest.java b/core/src/test/java/de/danoeh/antennapod/core/feed/FeedTest.java index 55f3bdafe..4717041f4 100644 --- a/core/src/test/java/de/danoeh/antennapod/core/feed/FeedTest.java +++ b/core/src/test/java/de/danoeh/antennapod/core/feed/FeedTest.java @@ -3,7 +3,6 @@ package de.danoeh.antennapod.core.feed; import org.junit.Before; import org.junit.Test; -import static de.danoeh.antennapod.core.feed.FeedImageMother.anyFeedImage; import static de.danoeh.antennapod.core.feed.FeedMother.anyFeed; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -12,52 +11,43 @@ import static org.junit.Assert.assertTrue; public class FeedTest { private Feed original; - private FeedImage originalImage; private Feed changedFeed; @Before public void setUp() { original = anyFeed(); - originalImage = original.getImage(); changedFeed = anyFeed(); } @Test public void testCompareWithOther_feedImageDownloadUrlChanged() throws Exception { setNewFeedImageDownloadUrl(); - feedHasChanged(); } @Test public void testCompareWithOther_sameFeedImage() throws Exception { - changedFeed.setImage(anyFeedImage()); - + changedFeed.setImageUrl(FeedMother.IMAGE_URL); feedHasNotChanged(); } @Test public void testCompareWithOther_feedImageRemoved() throws Exception { feedImageRemoved(); - feedHasNotChanged(); } @Test public void testUpdateFromOther_feedImageDownloadUrlChanged() throws Exception { setNewFeedImageDownloadUrl(); - original.updateFromOther(changedFeed); - feedImageWasUpdated(); } @Test public void testUpdateFromOther_feedImageRemoved() throws Exception { feedImageRemoved(); - original.updateFromOther(changedFeed); - feedImageWasNotUpdated(); } @@ -65,9 +55,7 @@ public class FeedTest { public void testUpdateFromOther_feedImageAdded() throws Exception { feedHadNoImage(); setNewFeedImageDownloadUrl(); - original.updateFromOther(changedFeed); - feedImageWasUpdated(); } @@ -76,11 +64,11 @@ public class FeedTest { } private void feedHadNoImage() { - original.setImage(null); + original.setImageUrl(null); } private void setNewFeedImageDownloadUrl() { - changedFeed.getImage().setDownload_url("http://example.com/new_picture"); + changedFeed.setImageUrl("http://example.com/new_picture"); } private void feedHasChanged() { @@ -88,15 +76,15 @@ public class FeedTest { } private void feedImageRemoved() { - changedFeed.setImage(null); + changedFeed.setImageUrl(null); } private void feedImageWasUpdated() { - assertEquals(original.getImage().getDownload_url(), changedFeed.getImage().getDownload_url()); + assertEquals(original.getImageUrl(), changedFeed.getImageUrl()); } private void feedImageWasNotUpdated() { - assertTrue(originalImage == original.getImage()); + assertEquals(anyFeed().getImageUrl(), original.getImageUrl()); } }
\ No newline at end of file diff --git a/core/src/test/java/de/danoeh/antennapod/core/service/download/DownloadServiceTest.java b/core/src/test/java/de/danoeh/antennapod/core/service/download/DownloadServiceTest.java deleted file mode 100644 index e40de2064..000000000 --- a/core/src/test/java/de/danoeh/antennapod/core/service/download/DownloadServiceTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package de.danoeh.antennapod.core.service.download; - - -import org.junit.Test; - -import java.util.ArrayList; -import java.util.List; - -import de.danoeh.antennapod.core.feed.Feed; -import de.danoeh.antennapod.core.feed.FeedImage; -import de.danoeh.antennapod.core.feed.FeedItem; - -import static org.junit.Assert.assertEquals; - -public class DownloadServiceTest { - - @Test - public void testRemoveDuplicateImages() { - List<FeedItem> items = new ArrayList<>(); - for (int i = 0; i < 50; i++) { - FeedItem item = new FeedItem(); - String url = (i % 5 == 0) ? "dupe_url" : String.format("url_%d", i); - item.setImage(new FeedImage(null, url, "")); - items.add(item); - } - Feed feed = new Feed(); - feed.setItems(items); - - DownloadService.removeDuplicateImages(feed); - - assertEquals(50, items.size()); - for (int i = 0; i < items.size(); i++) { - FeedItem item = items.get(i); - String want = (i == 0) ? "dupe_url" : (i % 5 == 0) ? null : String.format("url_%d", i); - assertEquals(want, item.getImageLocation()); - } - } -} diff --git a/core/src/test/java/de/danoeh/antennapod/core/storage/APCleanupAlgorithmTest.java b/core/src/test/java/de/danoeh/antennapod/core/storage/APCleanupAlgorithmTest.java new file mode 100644 index 000000000..946181d52 --- /dev/null +++ b/core/src/test/java/de/danoeh/antennapod/core/storage/APCleanupAlgorithmTest.java @@ -0,0 +1,20 @@ +package de.danoeh.antennapod.core.storage; + +import org.junit.Test; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import static org.junit.Assert.assertEquals; + +public class APCleanupAlgorithmTest { + + @Test + public void testCalcMostRecentDateForDeletion() throws Exception { + APCleanupAlgorithm algo = new APCleanupAlgorithm(24); + Date curDateForTest = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").parse("2018-11-13T14:08:56-0800"); + Date resExpected = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").parse("2018-11-12T14:08:56-0800"); + Date resActual = algo.calcMostRecentDateForDeletion(curDateForTest); + assertEquals("cutoff for retaining most recent 1 day", resExpected, resActual); + } +} diff --git a/core/src/test/java/de/danoeh/antennapod/core/util/ConverterTest.java b/core/src/test/java/de/danoeh/antennapod/core/util/ConverterTest.java new file mode 100644 index 000000000..54e5462d0 --- /dev/null +++ b/core/src/test/java/de/danoeh/antennapod/core/util/ConverterTest.java @@ -0,0 +1,39 @@ +package de.danoeh.antennapod.core.util; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * Test class for converter + */ +public class ConverterTest { + + @Test + public void testGetDurationStringLong() { + String expected = "13:05:10"; + int input = 47110000; + assertEquals(expected, Converter.getDurationStringLong(input)); + } + + @Test + public void testGetDurationStringShort() { + String expected = "13:05"; + assertEquals(expected, Converter.getDurationStringShort(47110000, true)); + assertEquals(expected, Converter.getDurationStringShort(785000, false)); + } + + @Test + public void testDurationStringLongToMs() { + String input = "01:20:30"; + long expected = 4830000; + assertEquals(expected, Converter.durationStringLongToMs(input)); + } + + @Test + public void testDurationStringShortToMs() { + String input = "8:30"; + assertEquals(30600000, Converter.durationStringShortToMs(input, true)); + assertEquals(510000, Converter.durationStringShortToMs(input, false)); + } +} diff --git a/app/src/androidTest/java/de/test/antennapod/util/RewindAfterPauseUtilTest.java b/core/src/test/java/de/danoeh/antennapod/core/util/RewindAfterPauseUtilTest.java index d564d0492..dc64f6ae0 100644 --- a/app/src/androidTest/java/de/test/antennapod/util/RewindAfterPauseUtilTest.java +++ b/core/src/test/java/de/danoeh/antennapod/core/util/RewindAfterPauseUtilTest.java @@ -1,14 +1,15 @@ -package de.test.antennapod.util; +package de.danoeh.antennapod.core.util; -import junit.framework.TestCase; +import org.junit.Test; -import de.danoeh.antennapod.core.util.RewindAfterPauseUtils; +import static org.junit.Assert.assertEquals; /** * Tests for {@link RewindAfterPauseUtils}. */ -public class RewindAfterPauseUtilTest extends TestCase { +public class RewindAfterPauseUtilTest { + @Test public void testCalculatePositionWithRewindNoRewind() { final int ORIGINAL_POSITION = 10000; long lastPlayed = System.currentTimeMillis(); @@ -17,6 +18,7 @@ public class RewindAfterPauseUtilTest extends TestCase { assertEquals(ORIGINAL_POSITION, position); } + @Test public void testCalculatePositionWithRewindSmallRewind() { final int ORIGINAL_POSITION = 10000; long lastPlayed = System.currentTimeMillis() - RewindAfterPauseUtils.ELAPSED_TIME_FOR_SHORT_REWIND - 1000; @@ -25,6 +27,7 @@ public class RewindAfterPauseUtilTest extends TestCase { assertEquals(ORIGINAL_POSITION - RewindAfterPauseUtils.SHORT_REWIND, position); } + @Test public void testCalculatePositionWithRewindMediumRewind() { final int ORIGINAL_POSITION = 10000; long lastPlayed = System.currentTimeMillis() - RewindAfterPauseUtils.ELAPSED_TIME_FOR_MEDIUM_REWIND - 1000; @@ -33,6 +36,7 @@ public class RewindAfterPauseUtilTest extends TestCase { assertEquals(ORIGINAL_POSITION - RewindAfterPauseUtils.MEDIUM_REWIND, position); } + @Test public void testCalculatePositionWithRewindLongRewind() { final int ORIGINAL_POSITION = 30000; long lastPlayed = System.currentTimeMillis() - RewindAfterPauseUtils.ELAPSED_TIME_FOR_LONG_REWIND - 1000; @@ -41,6 +45,7 @@ public class RewindAfterPauseUtilTest extends TestCase { assertEquals(ORIGINAL_POSITION - RewindAfterPauseUtils.LONG_REWIND, position); } + @Test public void testCalculatePositionWithRewindNegativeNumber() { final int ORIGINAL_POSITION = 100; long lastPlayed = System.currentTimeMillis() - RewindAfterPauseUtils.ELAPSED_TIME_FOR_LONG_REWIND - 1000; diff --git a/app/src/androidTest/java/de/test/antennapod/util/URIUtilTest.java b/core/src/test/java/de/danoeh/antennapod/core/util/URIUtilTest.java index 2cca6b4dc..3feb4d376 100644 --- a/app/src/androidTest/java/de/test/antennapod/util/URIUtilTest.java +++ b/core/src/test/java/de/danoeh/antennapod/core/util/URIUtilTest.java @@ -1,19 +1,21 @@ -package de.test.antennapod.util; +package de.danoeh.antennapod.core.util; -import android.test.AndroidTestCase; +import org.junit.Test; -import de.danoeh.antennapod.core.util.URIUtil; +import static org.junit.Assert.assertEquals; /** * Test class for URIUtil */ -public class URIUtilTest extends AndroidTestCase { +public class URIUtilTest { + @Test public void testGetURIFromRequestUrlShouldNotEncode() { final String testUrl = "http://example.com/this%20is%20encoded"; assertEquals(testUrl, URIUtil.getURIFromRequestUrl(testUrl).toString()); } + @Test public void testGetURIFromRequestUrlShouldEncode() { final String testUrl = "http://example.com/this is not encoded"; final String expected = "http://example.com/this%20is%20not%20encoded"; diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar Binary files differindex 99340b4ad..29953ea14 100644 --- a/gradle/wrapper/gradle-wrapper.jar +++ b/gradle/wrapper/gradle-wrapper.jar diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ea720f986..e0b3fb8d7 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-bin.zip diff --git a/project.properties b/project.properties deleted file mode 100644 index a8561fa99..000000000 --- a/project.properties +++ /dev/null @@ -1,13 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system use, -# "ant.properties", and override values to adapt the script to your -# project structure. - -# Project target. -proguard.config=proguard.cfg -target=android-19 - |