Merge branch 'develop'
This commit is contained in:
commit
12c5819380
36
.circleci/config.yml
Normal file
36
.circleci/config.yml
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
version: 2
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
docker:
|
||||||
|
- image: circleci/android:api-26-alpha
|
||||||
|
|
||||||
|
working_directory: ~/AntennaPod
|
||||||
|
|
||||||
|
environment:
|
||||||
|
GRADLE_OPTS: '-Dorg.gradle.jvmargs="-Xmx1536m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError"'
|
||||||
|
_JAVA_OPTIONS: "-Xms256m -Xmx1280m"
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
|
||||||
|
- restore_cache:
|
||||||
|
keys:
|
||||||
|
- v1-android-{{ checksum "build.gradle" }}
|
||||||
|
# fallback to using the latest cache if no exact match is found
|
||||||
|
- v1-android-
|
||||||
|
|
||||||
|
- run:
|
||||||
|
command: ./gradlew assembleDebug :core:testPlayDebugUnitTest -PdisablePreDex
|
||||||
|
no_output_timeout: 1800
|
||||||
|
|
||||||
|
- store_artifacts:
|
||||||
|
path: app/build/outputs/apk
|
||||||
|
destination: apks
|
||||||
|
|
||||||
|
- save_cache:
|
||||||
|
paths:
|
||||||
|
- ~/.android
|
||||||
|
- ~/.gradle
|
||||||
|
- ~/android
|
||||||
|
key: v1-android-{{ checksum "build.gradle" }}
|
@ -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>
|
|
33
.project
33
.project
@ -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>
|
|
17
.travis.yml
17
.travis.yml
@ -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
|
|
@ -7,6 +7,7 @@ source_lang = en
|
|||||||
trans.ast_ES = core/src/main/res/values-b+ast/strings.xml
|
trans.ast_ES = core/src/main/res/values-b+ast/strings.xml
|
||||||
trans.ar = core/src/main/res/values-ar/strings.xml
|
trans.ar = core/src/main/res/values-ar/strings.xml
|
||||||
trans.az = core/src/main/res/values-az/strings.xml
|
trans.az = core/src/main/res/values-az/strings.xml
|
||||||
|
trans.bg = core/src/main/res/values-bg/strings.xml
|
||||||
trans.ca = core/src/main/res/values-ca/strings.xml
|
trans.ca = core/src/main/res/values-ca/strings.xml
|
||||||
trans.ca_ES = core/src/main/res/values-ca-rES/strings.xml
|
trans.ca_ES = core/src/main/res/values-ca-rES/strings.xml
|
||||||
trans.cs_CZ = core/src/main/res/values-cs-rCZ/strings.xml
|
trans.cs_CZ = core/src/main/res/values-cs-rCZ/strings.xml
|
||||||
@ -32,6 +33,7 @@ trans.kn_IN = core/src/main/res/values-kn-rIN/strings.xml
|
|||||||
trans.ko = core/src/main/res/values-ko/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.ko_KR = core/src/main/res/values-ko-rKR/strings.xml
|
||||||
trans.lt = core/src/main/res/values-lt/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.nb = core/src/main/res/values-nb/strings.xml
|
||||||
trans.no = core/src/main/res/values-no/strings.xml
|
trans.no = core/src/main/res/values-no/strings.xml
|
||||||
trans.nl = core/src/main/res/values-nl/strings.xml
|
trans.nl = core/src/main/res/values-nl/strings.xml
|
||||||
|
26
CHANGELOG.md
26
CHANGELOG.md
@ -1,6 +1,32 @@
|
|||||||
Change Log
|
Change Log
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
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
|
||||||
|
-------------
|
||||||
|
|
||||||
|
* Fix database corruption
|
||||||
|
* Improvements to Feed parsing
|
||||||
|
|
||||||
|
Version 1.6.4
|
||||||
|
-------------
|
||||||
|
|
||||||
|
* Fixes issues on Android Oreo
|
||||||
|
* Avoids duplicate chapters
|
||||||
|
* Experimental: Database import & export
|
||||||
|
|
||||||
Version 1.6.3
|
Version 1.6.3
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
@ -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"
|
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png"
|
||||||
alt="Get it on Google Play"
|
alt="Get it on Google Play"
|
||||||
height="90">](https://play.google.com/store/apps/details?id=de.danoeh.antennapod)
|
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"
|
alt="Get it on F-Droid"
|
||||||
height="90">](https://f-droid.org/app/de.danoeh.antennapod)
|
height="90">](https://f-droid.org/app/de.danoeh.antennapod)
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import org.apache.tools.ant.filters.ReplaceTokens
|
import org.apache.tools.ant.filters.ReplaceTokens
|
||||||
|
|
||||||
apply plugin: "com.android.application"
|
apply plugin: "com.android.application"
|
||||||
apply plugin: "me.tatarka.retrolambda"
|
|
||||||
apply plugin: 'com.github.triplet.play'
|
apply plugin: 'com.github.triplet.play'
|
||||||
apply plugin: 'com.getkeepsafe.dexcount'
|
apply plugin: 'com.getkeepsafe.dexcount'
|
||||||
|
|
||||||
@ -15,7 +14,7 @@ buildscript {
|
|||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.8.1'
|
classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.8.2'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,9 +83,17 @@ android {
|
|||||||
applicationIdSuffix ".debug"
|
applicationIdSuffix ".debug"
|
||||||
resValue "string", "provider_authority", "de.danoeh.antennapod.debug.provider"
|
resValue "string", "provider_authority", "de.danoeh.antennapod.debug.provider"
|
||||||
buildConfigField STRING, FLATTR_APP_KEY, mFlattrAppKey
|
buildConfigField STRING, FLATTR_APP_KEY, mFlattrAppKey
|
||||||
buildConfigField STRING, FLATTR_APP_SECRET, mFlattrAppSecret
|
buildConfigField STRING, FLATTR_APP_SECRET, mFlattrAppSecret
|
||||||
|
dexcount {
|
||||||
|
if (project.hasProperty("enableDexcountInDebug")) {
|
||||||
|
runOnEachPackage enableDexcountInDebug.toBoolean()
|
||||||
|
} else { // default to not running dexcount
|
||||||
|
runOnEachPackage false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
release {
|
release {
|
||||||
|
resValue "string", "provider_authority", "de.danoeh.antennapod.provider"
|
||||||
minifyEnabled true
|
minifyEnabled true
|
||||||
proguardFile "proguard.cfg"
|
proguardFile "proguard.cfg"
|
||||||
signingConfig signingConfigs.releaseConfig
|
signingConfig signingConfigs.releaseConfig
|
||||||
@ -113,10 +120,13 @@ android {
|
|||||||
additionalParameters "--no-version-vectors"
|
additionalParameters "--no-version-vectors"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flavorDimensions "market"
|
||||||
productFlavors {
|
productFlavors {
|
||||||
free {
|
free {
|
||||||
|
dimension "market"
|
||||||
}
|
}
|
||||||
play {
|
play {
|
||||||
|
dimension "market"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,59 +135,55 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
configurations {
|
|
||||||
freeDebugCompile
|
|
||||||
freeReleaseCompile
|
|
||||||
playDebugCompile
|
|
||||||
playReleaseCompile
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
freeDebugCompile project(path: ":core", configuration: "freeDebug")
|
freeImplementation project(":core")
|
||||||
freeReleaseCompile project(path: ":core", configuration: "freeRelease")
|
|
||||||
// free build hack: skip some dependencies
|
// free build hack: skip some dependencies
|
||||||
if (!doFreeBuild()) {
|
if (!doFreeBuild()) {
|
||||||
playDebugCompile project(path: ":core", configuration: "playDebug")
|
playImplementation project(":core")
|
||||||
playReleaseCompile project(path: ":core", configuration: "playRelease")
|
|
||||||
} else {
|
} else {
|
||||||
System.out.println("app: free build hack, skipping some dependencies")
|
System.out.println("app: free build hack, skipping some dependencies")
|
||||||
}
|
}
|
||||||
compile "com.android.support:support-v4:$supportVersion"
|
implementation "com.android.support:support-v4:$supportVersion"
|
||||||
compile "com.android.support:appcompat-v7:$supportVersion"
|
implementation "com.android.support:appcompat-v7:$supportVersion"
|
||||||
compile "com.android.support:design:$supportVersion"
|
implementation "com.android.support:design:$supportVersion"
|
||||||
compile "com.android.support:gridlayout-v7:$supportVersion"
|
implementation "com.android.support:preference-v14:$supportVersion"
|
||||||
compile "com.android.support:percent:$supportVersion"
|
implementation "com.android.support:gridlayout-v7:$supportVersion"
|
||||||
compile "com.android.support:recyclerview-v7:$supportVersion"
|
implementation "com.android.support:percent:$supportVersion"
|
||||||
compile "org.apache.commons:commons-lang3:$commonslangVersion"
|
implementation "com.android.support:recyclerview-v7:$supportVersion"
|
||||||
compile("org.shredzone.flattr4j:flattr4j-core:$flattr4jVersion") {
|
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"
|
exclude group: "org.json", module: "json"
|
||||||
}
|
}
|
||||||
compile "commons-io:commons-io:$commonsioVersion"
|
implementation "commons-io:commons-io:$commonsioVersion"
|
||||||
compile "org.jsoup:jsoup:$jsoupVersion"
|
implementation "org.jsoup:jsoup:$jsoupVersion"
|
||||||
compile "com.github.bumptech.glide:glide:$glideVersion"
|
implementation "com.github.bumptech.glide:glide:$glideVersion"
|
||||||
compile "com.squareup.okhttp3:okhttp:$okhttpVersion"
|
implementation "com.squareup.okhttp3:okhttp:$okhttpVersion"
|
||||||
compile "com.squareup.okhttp3:okhttp-urlconnection:$okhttpVersion"
|
implementation "com.squareup.okhttp3:okhttp-urlconnection:$okhttpVersion"
|
||||||
compile "com.squareup.okio:okio:$okioVersion"
|
implementation "com.squareup.okio:okio:$okioVersion"
|
||||||
compile "de.greenrobot:eventbus:$eventbusVersion"
|
implementation "de.greenrobot:eventbus:$eventbusVersion"
|
||||||
compile "io.reactivex:rxandroid:$rxAndroidVersion"
|
implementation "io.reactivex:rxandroid:$rxAndroidVersion"
|
||||||
compile "io.reactivex:rxjava:$rxJavaVersion"
|
implementation "io.reactivex:rxjava:$rxJavaVersion"
|
||||||
// And ProGuard rules for RxJava!
|
// And ProGuard rules for RxJava!
|
||||||
compile "com.artemzin.rxjava:proguard-rules:$rxJavaRulesVersion"
|
implementation "com.artemzin.rxjava:proguard-rules:$rxJavaRulesVersion"
|
||||||
compile "com.joanzapata.iconify:android-iconify-fontawesome:$iconifyVersion"
|
implementation "com.joanzapata.iconify:android-iconify-fontawesome:$iconifyVersion"
|
||||||
compile "com.joanzapata.iconify:android-iconify-material:$iconifyVersion"
|
implementation "com.joanzapata.iconify:android-iconify-material:$iconifyVersion"
|
||||||
compile("com.afollestad.material-dialogs:commons:$materialDialogsVersion") {
|
implementation("com.afollestad.material-dialogs:commons:$materialDialogsVersion") {
|
||||||
transitive = true
|
transitive = true
|
||||||
}
|
}
|
||||||
compile "com.yqritc:recyclerview-flexibledivider:$recyclerviewFlexibledividerVersion"
|
implementation "com.yqritc:recyclerview-flexibledivider:$recyclerviewFlexibledividerVersion"
|
||||||
compile("com.githang:viewpagerindicator:2.5@aar") {
|
implementation("com.githang:viewpagerindicator:2.5.1@aar") {
|
||||||
exclude module: "support-v4"
|
exclude module: "support-v4"
|
||||||
}
|
}
|
||||||
|
|
||||||
compile "com.github.shts:TriangleLabelView:$triangleLabelViewVersion"
|
implementation "com.github.shts:TriangleLabelView:$triangleLabelViewVersion"
|
||||||
|
|
||||||
compile "com.github.AntennaPod:AntennaPod-AudioPlayer:$audioPlayerVersion"
|
implementation "com.github.AntennaPod:AntennaPod-AudioPlayer:$audioPlayerVersion"
|
||||||
|
|
||||||
compile 'com.github.mfietz:fyydlin:v0.3'
|
implementation 'com.github.mfietz:fyydlin:v0.3'
|
||||||
|
implementation 'com.github.ByteHamster:SearchPreference:v1.0.8'
|
||||||
|
|
||||||
|
androidTestImplementation "com.jayway.android.robotium:robotium-solo:$robotiumSoloVersion"
|
||||||
}
|
}
|
||||||
|
|
||||||
play {
|
play {
|
||||||
|
@ -125,3 +125,13 @@
|
|||||||
-keep class com.squareup.moshi.** { *; }
|
-keep class com.squareup.moshi.** { *; }
|
||||||
-keep interface com.squareup.moshi.** { *; }
|
-keep interface com.squareup.moshi.** { *; }
|
||||||
-keep public class retrofit2.adapter.rxjava.RxJavaCallAdapterFactory { *; }
|
-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
|
||||||
|
|
||||||
|
34
app/sampledata/episodes.json
Normal file
34
app/sampledata/episodes.json
Normal file
@ -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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
2
app/sampledata/inplaylist
Normal file
2
app/sampledata/inplaylist
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
@null
|
||||||
|
@drawable/ic_list_grey600_24dp
|
3
app/sampledata/secondaryaction
Normal file
3
app/sampledata/secondaryaction
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
@drawable/ic_play_arrow_grey600_36dp
|
||||||
|
@drawable/ic_file_download_grey600_24dp
|
||||||
|
@drawable/ic_cancel_grey600_24dp
|
@ -0,0 +1,37 @@
|
|||||||
|
package de.test.antennapod.feed;
|
||||||
|
|
||||||
|
import android.test.AndroidTestCase;
|
||||||
|
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||||
|
|
||||||
|
public class FeedItemTest extends AndroidTestCase {
|
||||||
|
private static final String TEXT_LONG = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
|
||||||
|
private static final String TEXT_SHORT = "Lorem ipsum";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If one of `description` or `content:encoded` is null, use the other one.
|
||||||
|
*/
|
||||||
|
public void testShownotesNullValues() throws Exception {
|
||||||
|
testShownotes(null, TEXT_LONG);
|
||||||
|
testShownotes(TEXT_LONG, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If `description` is reasonably longer than `content:encoded`, use `description`.
|
||||||
|
*/
|
||||||
|
public void testShownotesLength() throws Exception {
|
||||||
|
testShownotes(TEXT_SHORT, TEXT_LONG);
|
||||||
|
testShownotes(TEXT_LONG, TEXT_SHORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the shownotes equal TEXT_LONG, using the given `description` and `content:encoded`
|
||||||
|
* @param description Description of the feed item
|
||||||
|
* @param contentEncoded `content:encoded` of the feed item
|
||||||
|
*/
|
||||||
|
private void testShownotes(String description, String contentEncoded) throws Exception {
|
||||||
|
FeedItem item = new FeedItem();
|
||||||
|
item.setDescription(description);
|
||||||
|
item.setContentEncoded(contentEncoded);
|
||||||
|
assertEquals(TEXT_LONG, item.loadShownotes().call());
|
||||||
|
}
|
||||||
|
}
|
@ -2,14 +2,16 @@ package de.test.antennapod.gpodnet;
|
|||||||
|
|
||||||
import android.test.AndroidTestCase;
|
import android.test.AndroidTestCase;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import de.danoeh.antennapod.core.gpoddernet.GpodnetService;
|
import de.danoeh.antennapod.core.gpoddernet.GpodnetService;
|
||||||
import de.danoeh.antennapod.core.gpoddernet.GpodnetServiceException;
|
import de.danoeh.antennapod.core.gpoddernet.GpodnetServiceException;
|
||||||
import de.danoeh.antennapod.core.gpoddernet.model.GpodnetDevice;
|
import de.danoeh.antennapod.core.gpoddernet.model.GpodnetDevice;
|
||||||
import de.danoeh.antennapod.core.gpoddernet.model.GpodnetTag;
|
import de.danoeh.antennapod.core.gpoddernet.model.GpodnetTag;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import static java.util.Collections.singletonList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test class for GpodnetService
|
* Test class for GpodnetService
|
||||||
@ -55,7 +57,7 @@ public class GPodnetServiceTest extends AndroidTestCase {
|
|||||||
authenticate();
|
authenticate();
|
||||||
String[] URLS = {"http://bitsundso.de/feed", "http://gamesundso.de/feed", "http://cre.fm/feed/mp3/", "http://freakshow.fm/feed/m4a/"};
|
String[] URLS = {"http://bitsundso.de/feed", "http://gamesundso.de/feed", "http://cre.fm/feed/mp3/", "http://freakshow.fm/feed/m4a/"};
|
||||||
List<String> subscriptions = Arrays.asList(URLS[0], URLS[1]);
|
List<String> subscriptions = Arrays.asList(URLS[0], URLS[1]);
|
||||||
List<String> removed = Arrays.asList(URLS[0]);
|
List<String> removed = singletonList(URLS[0]);
|
||||||
List<String> added = Arrays.asList(URLS[2], URLS[3]);
|
List<String> added = Arrays.asList(URLS[2], URLS[3]);
|
||||||
service.uploadSubscriptions(USER, "radio", subscriptions);
|
service.uploadSubscriptions(USER, "radio", subscriptions);
|
||||||
service.uploadChanges(USER, "radio", added, removed);
|
service.uploadChanges(USER, "radio", added, removed);
|
||||||
|
@ -17,7 +17,6 @@ import javax.xml.parsers.ParserConfigurationException;
|
|||||||
|
|
||||||
import de.danoeh.antennapod.core.feed.Chapter;
|
import de.danoeh.antennapod.core.feed.Chapter;
|
||||||
import de.danoeh.antennapod.core.feed.Feed;
|
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.FeedItem;
|
||||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||||
import de.danoeh.antennapod.core.syndication.handler.FeedHandler;
|
import de.danoeh.antennapod.core.syndication.handler.FeedHandler;
|
||||||
@ -32,8 +31,8 @@ import de.test.antennapod.util.syndication.feedgenerator.RSS2Generator;
|
|||||||
public class FeedHandlerTest extends InstrumentationTestCase {
|
public class FeedHandlerTest extends InstrumentationTestCase {
|
||||||
private static final String FEEDS_DIR = "testfeeds";
|
private static final String FEEDS_DIR = "testfeeds";
|
||||||
|
|
||||||
File file = null;
|
private File file = null;
|
||||||
OutputStream outputStream = null;
|
private OutputStream outputStream = null;
|
||||||
|
|
||||||
protected void setUp() throws Exception {
|
protected void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
@ -82,15 +81,7 @@ public class FeedHandlerTest extends InstrumentationTestCase {
|
|||||||
assertEquals(feed.getLink(), parsedFeed.getLink());
|
assertEquals(feed.getLink(), parsedFeed.getLink());
|
||||||
assertEquals(feed.getDescription(), parsedFeed.getDescription());
|
assertEquals(feed.getDescription(), parsedFeed.getDescription());
|
||||||
assertEquals(feed.getPaymentLink(), parsedFeed.getPaymentLink());
|
assertEquals(feed.getPaymentLink(), parsedFeed.getPaymentLink());
|
||||||
|
assertEquals(feed.getImageUrl(), parsedFeed.getImageUrl());
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (feed.getItems() != null) {
|
if (feed.getItems() != null) {
|
||||||
assertNotNull(parsedFeed.getItems());
|
assertNotNull(parsedFeed.getItems());
|
||||||
@ -119,14 +110,7 @@ public class FeedHandlerTest extends InstrumentationTestCase {
|
|||||||
assertEquals(media.getMime_type(), parsedMedia.getMime_type());
|
assertEquals(media.getMime_type(), parsedMedia.getMime_type());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.hasItemImage()) {
|
assertEquals(item.getImageUrl(), parsedFeed.getImageUrl());
|
||||||
assertTrue(parsedItem.hasItemImage());
|
|
||||||
FeedImage image = item.getImage();
|
|
||||||
FeedImage parsedImage = parsedItem.getImage();
|
|
||||||
|
|
||||||
assertEquals(image.getTitle(), parsedImage.getTitle());
|
|
||||||
assertEquals(image.getDownload_url(), parsedImage.getDownload_url());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.getChapters() != null) {
|
if (item.getChapters() != null) {
|
||||||
assertNotNull(parsedItem.getChapters());
|
assertNotNull(parsedItem.getChapters());
|
||||||
@ -158,14 +142,10 @@ public class FeedHandlerTest extends InstrumentationTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Feed createTestFeed(int numItems, boolean withImage, boolean withFeedMedia, boolean withChapters) {
|
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",
|
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);
|
"http://example.com/feed", true);
|
||||||
feed.setItems(new ArrayList<FeedItem>());
|
feed.setItems(new ArrayList<>());
|
||||||
|
|
||||||
for (int i = 0; i < numItems; i++) {
|
for (int i = 0; i < numItems; i++) {
|
||||||
FeedItem item = new FeedItem(0, "item-" + i, "http://example.com/item-" + i,
|
FeedItem item = new FeedItem(0, "item-" + i, "http://example.com/item-" + i,
|
||||||
|
@ -23,8 +23,8 @@ import de.danoeh.antennapod.core.feed.FeedItem;
|
|||||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||||
import de.danoeh.antennapod.core.feed.FeedPreferences;
|
import de.danoeh.antennapod.core.feed.FeedPreferences;
|
||||||
import de.danoeh.antennapod.core.feed.MediaType;
|
import de.danoeh.antennapod.core.feed.MediaType;
|
||||||
import de.danoeh.antennapod.core.service.playback.PlaybackServiceMediaPlayer;
|
|
||||||
import de.danoeh.antennapod.core.service.playback.LocalPSMP;
|
import de.danoeh.antennapod.core.service.playback.LocalPSMP;
|
||||||
|
import de.danoeh.antennapod.core.service.playback.PlaybackServiceMediaPlayer;
|
||||||
import de.danoeh.antennapod.core.service.playback.PlayerStatus;
|
import de.danoeh.antennapod.core.service.playback.PlayerStatus;
|
||||||
import de.danoeh.antennapod.core.storage.PodDBAdapter;
|
import de.danoeh.antennapod.core.storage.PodDBAdapter;
|
||||||
import de.danoeh.antennapod.core.util.playback.Playable;
|
import de.danoeh.antennapod.core.util.playback.Playable;
|
||||||
|
@ -9,10 +9,10 @@ import java.util.List;
|
|||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import de.danoeh.antennapod.core.event.QueueEvent;
|
||||||
import de.danoeh.antennapod.core.feed.EventDistributor;
|
import de.danoeh.antennapod.core.feed.EventDistributor;
|
||||||
import de.danoeh.antennapod.core.feed.Feed;
|
import de.danoeh.antennapod.core.feed.Feed;
|
||||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||||
import de.danoeh.antennapod.core.event.QueueEvent;
|
|
||||||
import de.danoeh.antennapod.core.service.playback.PlaybackServiceTaskManager;
|
import de.danoeh.antennapod.core.service.playback.PlaybackServiceTaskManager;
|
||||||
import de.danoeh.antennapod.core.storage.PodDBAdapter;
|
import de.danoeh.antennapod.core.storage.PodDBAdapter;
|
||||||
import de.danoeh.antennapod.core.util.playback.Playable;
|
import de.danoeh.antennapod.core.util.playback.Playable;
|
||||||
|
@ -27,12 +27,12 @@ import static de.test.antennapod.storage.DBTestUtils.saveFeedlist;
|
|||||||
public class DBCleanupTests extends InstrumentationTestCase {
|
public class DBCleanupTests extends InstrumentationTestCase {
|
||||||
|
|
||||||
private static final String TAG = "DBTasksTest";
|
private static final String TAG = "DBTasksTest";
|
||||||
protected static final int EPISODE_CACHE_SIZE = 5;
|
static final int EPISODE_CACHE_SIZE = 5;
|
||||||
private final int cleanupAlgorithm;
|
private final int cleanupAlgorithm;
|
||||||
|
|
||||||
protected Context context;
|
Context context;
|
||||||
|
|
||||||
protected File destFolder;
|
private File destFolder;
|
||||||
|
|
||||||
public DBCleanupTests() {
|
public DBCleanupTests() {
|
||||||
this.cleanupAlgorithm = UserPreferences.EPISODE_CLEANUP_DEFAULT;
|
this.cleanupAlgorithm = UserPreferences.EPISODE_CLEANUP_DEFAULT;
|
||||||
@ -104,9 +104,9 @@ public class DBCleanupTests extends InstrumentationTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void populateItems(final int numItems, Feed feed, List<FeedItem> items,
|
void populateItems(final int numItems, Feed feed, List<FeedItem> items,
|
||||||
List<File> files, int itemState, boolean addToQueue,
|
List<File> files, int itemState, boolean addToQueue,
|
||||||
boolean addToFavorites) throws IOException {
|
boolean addToFavorites) throws IOException {
|
||||||
for (int i = 0; i < numItems; i++) {
|
for (int i = 0; i < numItems; i++) {
|
||||||
Date itemDate = new Date(numItems - i);
|
Date itemDate = new Date(numItems - i);
|
||||||
Date playbackCompletionDate = null;
|
Date playbackCompletionDate = null;
|
||||||
|
@ -5,7 +5,6 @@ import android.test.FlakyTest;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import de.danoeh.antennapod.core.feed.Feed;
|
import de.danoeh.antennapod.core.feed.Feed;
|
||||||
|
@ -18,6 +18,8 @@ import de.danoeh.antennapod.core.storage.DBReader;
|
|||||||
import de.danoeh.antennapod.core.storage.DBTasks;
|
import de.danoeh.antennapod.core.storage.DBTasks;
|
||||||
import de.danoeh.antennapod.core.storage.PodDBAdapter;
|
import de.danoeh.antennapod.core.storage.PodDBAdapter;
|
||||||
|
|
||||||
|
import static java.util.Collections.singletonList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test class for DBTasks
|
* Test class for DBTasks
|
||||||
*/
|
*/
|
||||||
@ -125,7 +127,7 @@ public class DBTasksTest extends InstrumentationTestCase {
|
|||||||
public void testUpdateFeedMediaUrlResetState() {
|
public void testUpdateFeedMediaUrlResetState() {
|
||||||
final Feed feed = new Feed("url", null, "title");
|
final Feed feed = new Feed("url", null, "title");
|
||||||
FeedItem item = new FeedItem(0, "item", "id", "link", new Date(), FeedItem.PLAYED, feed);
|
FeedItem item = new FeedItem(0, "item", "id", "link", new Date(), FeedItem.PLAYED, feed);
|
||||||
feed.setItems(Arrays.asList(item));
|
feed.setItems(singletonList(item));
|
||||||
|
|
||||||
PodDBAdapter adapter = PodDBAdapter.getInstance();
|
PodDBAdapter adapter = PodDBAdapter.getInstance();
|
||||||
adapter.open();
|
adapter.open();
|
||||||
@ -138,7 +140,7 @@ public class DBTasksTest extends InstrumentationTestCase {
|
|||||||
|
|
||||||
FeedMedia media = new FeedMedia(item, "url", 1024, "mime/type");
|
FeedMedia media = new FeedMedia(item, "url", 1024, "mime/type");
|
||||||
item.setMedia(media);
|
item.setMedia(media);
|
||||||
feed.setItems(Arrays.asList(item));
|
feed.setItems(singletonList(item));
|
||||||
|
|
||||||
final Feed newFeed = DBTasks.updateFeed(context, feed)[0];
|
final Feed newFeed = DBTasks.updateFeed(context, feed)[0];
|
||||||
assertTrue(feed != newFeed);
|
assertTrue(feed != newFeed);
|
||||||
|
@ -19,7 +19,7 @@ import de.danoeh.antennapod.core.util.flattr.FlattrStatus;
|
|||||||
/**
|
/**
|
||||||
* Utility methods for DB* tests.
|
* Utility methods for DB* tests.
|
||||||
*/
|
*/
|
||||||
public class DBTestUtils {
|
class DBTestUtils {
|
||||||
|
|
||||||
private DBTestUtils(){}
|
private DBTestUtils(){}
|
||||||
/**
|
/**
|
||||||
|
@ -15,9 +15,7 @@ import java.util.concurrent.Future;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
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.Feed;
|
||||||
import de.danoeh.antennapod.core.feed.FeedImage;
|
|
||||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||||
import de.danoeh.antennapod.core.feed.SimpleChapter;
|
import de.danoeh.antennapod.core.feed.SimpleChapter;
|
||||||
@ -124,89 +122,13 @@ public class DBWriterTest extends InstrumentationTestCase {
|
|||||||
assertNull(media.getFile_url());
|
assertNull(media.getFile_url());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDeleteFeed() throws IOException, ExecutionException, InterruptedException, TimeoutException {
|
public void testDeleteFeed() throws ExecutionException, InterruptedException, IOException, TimeoutException {
|
||||||
File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
|
File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
|
||||||
assertNotNull(destFolder);
|
assertNotNull(destFolder);
|
||||||
|
|
||||||
Feed feed = new Feed("url", null, "title");
|
Feed feed = new Feed("url", null, "title");
|
||||||
feed.setItems(new ArrayList<>());
|
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);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
File enc = new File(destFolder, "file " + i);
|
|
||||||
assertTrue(enc.createNewFile());
|
|
||||||
itemFiles.add(enc);
|
|
||||||
|
|
||||||
FeedMedia media = new FeedMedia(0, item, 1, 1, 1, "mime_type", enc.getAbsolutePath(), "download_url", true, null, 0, 0);
|
|
||||||
item.setMedia(media);
|
|
||||||
|
|
||||||
item.setChapters(new ArrayList<Chapter>());
|
|
||||||
item.getChapters().add(new SimpleChapter(0, "item " + i, item, "example.com"));
|
|
||||||
}
|
|
||||||
|
|
||||||
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.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();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testDeleteFeedNoImage() 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<>();
|
List<File> itemFiles = new ArrayList<>();
|
||||||
// create items with downloaded media files
|
// create items with downloaded media files
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
@ -261,13 +183,7 @@ public class DBWriterTest extends InstrumentationTestCase {
|
|||||||
|
|
||||||
Feed feed = new Feed("url", null, "title");
|
Feed feed = new Feed("url", null, "title");
|
||||||
feed.setItems(null);
|
feed.setItems(null);
|
||||||
|
feed.setImageUrl("url");
|
||||||
// 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);
|
|
||||||
|
|
||||||
PodDBAdapter adapter = PodDBAdapter.getInstance();
|
PodDBAdapter adapter = PodDBAdapter.getInstance();
|
||||||
adapter.open();
|
adapter.open();
|
||||||
@ -275,21 +191,14 @@ public class DBWriterTest extends InstrumentationTestCase {
|
|||||||
adapter.close();
|
adapter.close();
|
||||||
|
|
||||||
assertTrue(feed.getId() != 0);
|
assertTrue(feed.getId() != 0);
|
||||||
assertTrue(feed.getImage().getId() != 0);
|
|
||||||
|
|
||||||
DBWriter.deleteFeed(getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
|
DBWriter.deleteFeed(getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
|
||||||
|
|
||||||
// check if files still exist
|
|
||||||
assertFalse(imgFile.exists());
|
|
||||||
|
|
||||||
adapter = PodDBAdapter.getInstance();
|
adapter = PodDBAdapter.getInstance();
|
||||||
adapter.open();
|
adapter.open();
|
||||||
Cursor c = adapter.getFeedCursor(feed.getId());
|
Cursor c = adapter.getFeedCursor(feed.getId());
|
||||||
assertTrue(c.getCount() == 0);
|
assertTrue(c.getCount() == 0);
|
||||||
c.close();
|
c.close();
|
||||||
c = adapter.getImageCursor(String.valueOf(image.getId()));
|
|
||||||
assertTrue(c.getCount() == 0);
|
|
||||||
c.close();
|
|
||||||
adapter.close();
|
adapter.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,12 +209,7 @@ public class DBWriterTest extends InstrumentationTestCase {
|
|||||||
Feed feed = new Feed("url", null, "title");
|
Feed feed = new Feed("url", null, "title");
|
||||||
feed.setItems(new ArrayList<>());
|
feed.setItems(new ArrayList<>());
|
||||||
|
|
||||||
// create Feed image
|
feed.setImageUrl("url");
|
||||||
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
|
// create items
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
@ -320,24 +224,18 @@ public class DBWriterTest extends InstrumentationTestCase {
|
|||||||
adapter.close();
|
adapter.close();
|
||||||
|
|
||||||
assertTrue(feed.getId() != 0);
|
assertTrue(feed.getId() != 0);
|
||||||
assertTrue(feed.getImage().getId() != 0);
|
|
||||||
for (FeedItem item : feed.getItems()) {
|
for (FeedItem item : feed.getItems()) {
|
||||||
assertTrue(item.getId() != 0);
|
assertTrue(item.getId() != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DBWriter.deleteFeed(getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
|
DBWriter.deleteFeed(getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
|
||||||
|
|
||||||
// check if files still exist
|
|
||||||
assertFalse(imgFile.exists());
|
|
||||||
|
|
||||||
adapter = PodDBAdapter.getInstance();
|
adapter = PodDBAdapter.getInstance();
|
||||||
adapter.open();
|
adapter.open();
|
||||||
Cursor c = adapter.getFeedCursor(feed.getId());
|
Cursor c = adapter.getFeedCursor(feed.getId());
|
||||||
assertTrue(c.getCount() == 0);
|
assertTrue(c.getCount() == 0);
|
||||||
c.close();
|
c.close();
|
||||||
c = adapter.getImageCursor(String.valueOf(image.getId()));
|
|
||||||
assertTrue(c.getCount() == 0);
|
|
||||||
c.close();
|
|
||||||
for (FeedItem item : feed.getItems()) {
|
for (FeedItem item : feed.getItems()) {
|
||||||
c = adapter.getFeedItemCursor(String.valueOf(item.getId()));
|
c = adapter.getFeedItemCursor(String.valueOf(item.getId()));
|
||||||
assertTrue(c.getCount() == 0);
|
assertTrue(c.getCount() == 0);
|
||||||
@ -346,65 +244,6 @@ public class DBWriterTest extends InstrumentationTestCase {
|
|||||||
adapter.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();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testDeleteFeedWithQueueItems() throws ExecutionException, InterruptedException, TimeoutException {
|
public void testDeleteFeedWithQueueItems() throws ExecutionException, InterruptedException, TimeoutException {
|
||||||
File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
|
File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
|
||||||
assertNotNull(destFolder);
|
assertNotNull(destFolder);
|
||||||
@ -412,11 +251,7 @@ public class DBWriterTest extends InstrumentationTestCase {
|
|||||||
Feed feed = new Feed("url", null, "title");
|
Feed feed = new Feed("url", null, "title");
|
||||||
feed.setItems(new ArrayList<>());
|
feed.setItems(new ArrayList<>());
|
||||||
|
|
||||||
// create Feed image
|
feed.setImageUrl("url");
|
||||||
File imgFile = new File(destFolder, "image");
|
|
||||||
FeedImage image = new FeedImage(0, "image", imgFile.getAbsolutePath(), "url", true);
|
|
||||||
image.setOwner(feed);
|
|
||||||
feed.setImage(image);
|
|
||||||
|
|
||||||
List<File> itemFiles = new ArrayList<>();
|
List<File> itemFiles = new ArrayList<>();
|
||||||
// create items with downloaded media files
|
// create items with downloaded media files
|
||||||
@ -437,7 +272,6 @@ public class DBWriterTest extends InstrumentationTestCase {
|
|||||||
adapter.close();
|
adapter.close();
|
||||||
|
|
||||||
assertTrue(feed.getId() != 0);
|
assertTrue(feed.getId() != 0);
|
||||||
assertTrue(feed.getImage().getId() != 0);
|
|
||||||
for (FeedItem item : feed.getItems()) {
|
for (FeedItem item : feed.getItems()) {
|
||||||
assertTrue(item.getId() != 0);
|
assertTrue(item.getId() != 0);
|
||||||
assertTrue(item.getMedia().getId() != 0);
|
assertTrue(item.getMedia().getId() != 0);
|
||||||
@ -460,9 +294,6 @@ public class DBWriterTest extends InstrumentationTestCase {
|
|||||||
Cursor c = adapter.getFeedCursor(feed.getId());
|
Cursor c = adapter.getFeedCursor(feed.getId());
|
||||||
assertTrue(c.getCount() == 0);
|
assertTrue(c.getCount() == 0);
|
||||||
c.close();
|
c.close();
|
||||||
c = adapter.getImageCursor(String.valueOf(image.getId()));
|
|
||||||
assertTrue(c.getCount() == 0);
|
|
||||||
c.close();
|
|
||||||
for (FeedItem item : feed.getItems()) {
|
for (FeedItem item : feed.getItems()) {
|
||||||
c = adapter.getFeedItemCursor(String.valueOf(item.getId()));
|
c = adapter.getFeedItemCursor(String.valueOf(item.getId()));
|
||||||
assertTrue(c.getCount() == 0);
|
assertTrue(c.getCount() == 0);
|
||||||
@ -484,11 +315,7 @@ public class DBWriterTest extends InstrumentationTestCase {
|
|||||||
Feed feed = new Feed("url", null, "title");
|
Feed feed = new Feed("url", null, "title");
|
||||||
feed.setItems(new ArrayList<>());
|
feed.setItems(new ArrayList<>());
|
||||||
|
|
||||||
// create Feed image
|
feed.setImageUrl("url");
|
||||||
File imgFile = new File(destFolder, "image");
|
|
||||||
FeedImage image = new FeedImage(0, "image", imgFile.getAbsolutePath(), "url", true);
|
|
||||||
image.setOwner(feed);
|
|
||||||
feed.setImage(image);
|
|
||||||
|
|
||||||
List<File> itemFiles = new ArrayList<>();
|
List<File> itemFiles = new ArrayList<>();
|
||||||
// create items with downloaded media files
|
// create items with downloaded media files
|
||||||
@ -509,7 +336,6 @@ public class DBWriterTest extends InstrumentationTestCase {
|
|||||||
adapter.close();
|
adapter.close();
|
||||||
|
|
||||||
assertTrue(feed.getId() != 0);
|
assertTrue(feed.getId() != 0);
|
||||||
assertTrue(feed.getImage().getId() != 0);
|
|
||||||
for (FeedItem item : feed.getItems()) {
|
for (FeedItem item : feed.getItems()) {
|
||||||
assertTrue(item.getId() != 0);
|
assertTrue(item.getId() != 0);
|
||||||
assertTrue(item.getMedia().getId() != 0);
|
assertTrue(item.getMedia().getId() != 0);
|
||||||
@ -522,9 +348,6 @@ public class DBWriterTest extends InstrumentationTestCase {
|
|||||||
Cursor c = adapter.getFeedCursor(feed.getId());
|
Cursor c = adapter.getFeedCursor(feed.getId());
|
||||||
assertTrue(c.getCount() == 0);
|
assertTrue(c.getCount() == 0);
|
||||||
c.close();
|
c.close();
|
||||||
c = adapter.getImageCursor(String.valueOf(image.getId()));
|
|
||||||
assertTrue(c.getCount() == 0);
|
|
||||||
c.close();
|
|
||||||
for (FeedItem item : feed.getItems()) {
|
for (FeedItem item : feed.getItems()) {
|
||||||
c = adapter.getFeedItemCursor(String.valueOf(item.getId()));
|
c = adapter.getFeedItemCursor(String.valueOf(item.getId()));
|
||||||
assertTrue(c.getCount() == 0);
|
assertTrue(c.getCount() == 0);
|
||||||
@ -539,7 +362,7 @@ public class DBWriterTest extends InstrumentationTestCase {
|
|||||||
private FeedMedia playbackHistorySetup(Date playbackCompletionDate) {
|
private FeedMedia playbackHistorySetup(Date playbackCompletionDate) {
|
||||||
final Context context = getInstrumentation().getTargetContext();
|
final Context context = getInstrumentation().getTargetContext();
|
||||||
Feed feed = new Feed("url", null, "title");
|
Feed feed = new Feed("url", null, "title");
|
||||||
feed.setItems(new ArrayList<FeedItem>());
|
feed.setItems(new ArrayList<>());
|
||||||
FeedItem item = new FeedItem(0, "title", "id", "link", new Date(), FeedItem.PLAYED, feed);
|
FeedItem item = new FeedItem(0, "title", "id", "link", new Date(), FeedItem.PLAYED, feed);
|
||||||
FeedMedia media = new FeedMedia(0, item, 10, 0, 1, "mime", null, "url", false, playbackCompletionDate, 0, 0);
|
FeedMedia media = new FeedMedia(0, item, 10, 0, 1, "mime", null, "url", false, playbackCompletionDate, 0, 0);
|
||||||
feed.getItems().add(item);
|
feed.getItems().add(item);
|
||||||
@ -791,7 +614,7 @@ public class DBWriterTest extends InstrumentationTestCase {
|
|||||||
public void testMarkFeedRead() throws InterruptedException, ExecutionException, TimeoutException {
|
public void testMarkFeedRead() throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
final int NUM_ITEMS = 10;
|
final int NUM_ITEMS = 10;
|
||||||
Feed feed = new Feed("url", null, "title");
|
Feed feed = new Feed("url", null, "title");
|
||||||
feed.setItems(new ArrayList<FeedItem>());
|
feed.setItems(new ArrayList<>());
|
||||||
for (int i = 0; i < NUM_ITEMS; i++) {
|
for (int i = 0; i < NUM_ITEMS; i++) {
|
||||||
FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.UNPLAYED, feed);
|
FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.UNPLAYED, feed);
|
||||||
feed.getItems().add(item);
|
feed.getItems().add(item);
|
||||||
|
@ -15,6 +15,7 @@ import java.util.List;
|
|||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
import de.danoeh.antennapod.activity.MainActivity;
|
import de.danoeh.antennapod.activity.MainActivity;
|
||||||
import de.danoeh.antennapod.activity.OnlineFeedViewActivity;
|
import de.danoeh.antennapod.activity.OnlineFeedViewActivity;
|
||||||
|
import de.danoeh.antennapod.activity.PreferenceActivity;
|
||||||
import de.danoeh.antennapod.core.feed.Feed;
|
import de.danoeh.antennapod.core.feed.Feed;
|
||||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||||
import de.danoeh.antennapod.core.storage.PodDBAdapter;
|
import de.danoeh.antennapod.core.storage.PodDBAdapter;
|
||||||
@ -22,7 +23,6 @@ import de.danoeh.antennapod.fragment.DownloadsFragment;
|
|||||||
import de.danoeh.antennapod.fragment.EpisodesFragment;
|
import de.danoeh.antennapod.fragment.EpisodesFragment;
|
||||||
import de.danoeh.antennapod.fragment.PlaybackHistoryFragment;
|
import de.danoeh.antennapod.fragment.PlaybackHistoryFragment;
|
||||||
import de.danoeh.antennapod.fragment.QueueFragment;
|
import de.danoeh.antennapod.fragment.QueueFragment;
|
||||||
import de.danoeh.antennapod.preferences.PreferenceController;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User interface tests for MainActivity
|
* User interface tests for MainActivity
|
||||||
@ -96,7 +96,7 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
|
|||||||
public void testClickNavDrawer() throws Exception {
|
public void testClickNavDrawer() throws Exception {
|
||||||
uiTestUtils.addLocalFeedData(false);
|
uiTestUtils.addLocalFeedData(false);
|
||||||
|
|
||||||
UserPreferences.setHiddenDrawerItems(new ArrayList<String>());
|
UserPreferences.setHiddenDrawerItems(new ArrayList<>());
|
||||||
|
|
||||||
// queue
|
// queue
|
||||||
openNavDrawer();
|
openNavDrawer();
|
||||||
@ -155,11 +155,11 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
|
|||||||
public void testGoToPreferences() {
|
public void testGoToPreferences() {
|
||||||
openNavDrawer();
|
openNavDrawer();
|
||||||
solo.clickOnText(solo.getString(R.string.settings_label));
|
solo.clickOnText(solo.getString(R.string.settings_label));
|
||||||
solo.waitForActivity(PreferenceController.getPreferenceActivity());
|
solo.waitForActivity(PreferenceActivity.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDrawerPreferencesHideSomeElements() {
|
public void testDrawerPreferencesHideSomeElements() {
|
||||||
UserPreferences.setHiddenDrawerItems(new ArrayList<String>());
|
UserPreferences.setHiddenDrawerItems(new ArrayList<>());
|
||||||
openNavDrawer();
|
openNavDrawer();
|
||||||
solo.clickLongOnText(solo.getString(R.string.queue_label));
|
solo.clickLongOnText(solo.getString(R.string.queue_label));
|
||||||
solo.waitForDialogToOpen();
|
solo.waitForDialogToOpen();
|
||||||
@ -190,7 +190,7 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testDrawerPreferencesHideAllElements() {
|
public void testDrawerPreferencesHideAllElements() {
|
||||||
UserPreferences.setHiddenDrawerItems(new ArrayList<String>());
|
UserPreferences.setHiddenDrawerItems(new ArrayList<>());
|
||||||
String[] titles = getInstrumentation().getTargetContext().getResources().getStringArray(R.array.nav_drawer_titles);
|
String[] titles = getInstrumentation().getTargetContext().getResources().getStringArray(R.array.nav_drawer_titles);
|
||||||
|
|
||||||
openNavDrawer();
|
openNavDrawer();
|
||||||
@ -209,7 +209,7 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testDrawerPreferencesHideCurrentElement() {
|
public void testDrawerPreferencesHideCurrentElement() {
|
||||||
UserPreferences.setHiddenDrawerItems(new ArrayList<String>());
|
UserPreferences.setHiddenDrawerItems(new ArrayList<>());
|
||||||
|
|
||||||
openNavDrawer();
|
openNavDrawer();
|
||||||
String downloads = solo.getString(R.string.downloads_label);
|
String downloads = solo.getString(R.string.downloads_label);
|
||||||
|
@ -33,8 +33,8 @@ import de.danoeh.antennapod.core.storage.PodDBAdapter;
|
|||||||
public class PlaybackSonicTest extends ActivityInstrumentationTestCase2<MainActivity> {
|
public class PlaybackSonicTest extends ActivityInstrumentationTestCase2<MainActivity> {
|
||||||
|
|
||||||
private static final String TAG = PlaybackTest.class.getSimpleName();
|
private static final String TAG = PlaybackTest.class.getSimpleName();
|
||||||
public static final int EPISODES_DRAWER_LIST_INDEX = 1;
|
private static final int EPISODES_DRAWER_LIST_INDEX = 1;
|
||||||
public static final int QUEUE_DRAWER_LIST_INDEX = 0;
|
private static final int QUEUE_DRAWER_LIST_INDEX = 0;
|
||||||
|
|
||||||
private Solo solo;
|
private Solo solo;
|
||||||
private UITestUtils uiTestUtils;
|
private UITestUtils uiTestUtils;
|
||||||
|
@ -30,8 +30,8 @@ import de.danoeh.antennapod.core.storage.PodDBAdapter;
|
|||||||
public class PlaybackTest extends ActivityInstrumentationTestCase2<MainActivity> {
|
public class PlaybackTest extends ActivityInstrumentationTestCase2<MainActivity> {
|
||||||
|
|
||||||
private static final String TAG = PlaybackTest.class.getSimpleName();
|
private static final String TAG = PlaybackTest.class.getSimpleName();
|
||||||
public static final int EPISODES_DRAWER_LIST_INDEX = 1;
|
private static final int EPISODES_DRAWER_LIST_INDEX = 1;
|
||||||
public static final int QUEUE_DRAWER_LIST_INDEX = 0;
|
private static final int QUEUE_DRAWER_LIST_INDEX = 0;
|
||||||
|
|
||||||
private Solo solo;
|
private Solo solo;
|
||||||
private UITestUtils uiTestUtils;
|
private UITestUtils uiTestUtils;
|
||||||
|
@ -3,7 +3,6 @@ package de.test.antennapod.ui;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.test.ActivityInstrumentationTestCase2;
|
import android.test.ActivityInstrumentationTestCase2;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.robotium.solo.Solo;
|
import com.robotium.solo.Solo;
|
||||||
import com.robotium.solo.Timeout;
|
import com.robotium.solo.Timeout;
|
||||||
@ -56,6 +55,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
} else {
|
} else {
|
||||||
otherTheme = R.string.pref_theme_title_light;
|
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.clickOnText(solo.getString(R.string.pref_set_theme_title));
|
||||||
solo.waitForDialogToOpen();
|
solo.waitForDialogToOpen();
|
||||||
solo.clickOnText(solo.getString(otherTheme));
|
solo.clickOnText(solo.getString(otherTheme));
|
||||||
@ -70,6 +70,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
} else {
|
} else {
|
||||||
otherTheme = R.string.pref_theme_title_light;
|
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.clickOnText(solo.getString(R.string.pref_set_theme_title));
|
||||||
solo.waitForDialogToOpen(1000);
|
solo.waitForDialogToOpen(1000);
|
||||||
solo.clickOnText(solo.getString(otherTheme));
|
solo.clickOnText(solo.getString(otherTheme));
|
||||||
@ -77,6 +78,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testExpandNotification() {
|
public void testExpandNotification() {
|
||||||
|
solo.clickOnText(solo.getString(R.string.user_interface_label));
|
||||||
final int priority = UserPreferences.getNotifyPriority();
|
final int priority = UserPreferences.getNotifyPriority();
|
||||||
solo.clickOnText(solo.getString(R.string.pref_expandNotify_title));
|
solo.clickOnText(solo.getString(R.string.pref_expandNotify_title));
|
||||||
assertTrue(solo.waitForCondition(() -> priority != UserPreferences.getNotifyPriority(), Timeout.getLargeTimeout()));
|
assertTrue(solo.waitForCondition(() -> priority != UserPreferences.getNotifyPriority(), Timeout.getLargeTimeout()));
|
||||||
@ -85,7 +87,10 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testEnablePersistentPlaybackControls() {
|
public void testEnablePersistentPlaybackControls() {
|
||||||
|
solo.clickOnText(solo.getString(R.string.user_interface_label));
|
||||||
final boolean persistNotify = UserPreferences.isPersistNotify();
|
final boolean persistNotify = UserPreferences.isPersistNotify();
|
||||||
|
solo.scrollDown();
|
||||||
|
solo.scrollDown();
|
||||||
solo.clickOnText(solo.getString(R.string.pref_persistNotify_title));
|
solo.clickOnText(solo.getString(R.string.pref_persistNotify_title));
|
||||||
assertTrue(solo.waitForCondition(() -> persistNotify != UserPreferences.isPersistNotify(), Timeout.getLargeTimeout()));
|
assertTrue(solo.waitForCondition(() -> persistNotify != UserPreferences.isPersistNotify(), Timeout.getLargeTimeout()));
|
||||||
solo.clickOnText(solo.getString(R.string.pref_persistNotify_title));
|
solo.clickOnText(solo.getString(R.string.pref_persistNotify_title));
|
||||||
@ -93,14 +98,16 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testSetLockscreenButtons() {
|
public void testSetLockscreenButtons() {
|
||||||
|
solo.clickOnText(solo.getString(R.string.user_interface_label));
|
||||||
|
solo.scrollDown();
|
||||||
String[] buttons = res.getStringArray(R.array.compact_notification_buttons_options);
|
String[] buttons = res.getStringArray(R.array.compact_notification_buttons_options);
|
||||||
solo.clickOnText(solo.getString(R.string.pref_compact_notification_buttons_title));
|
solo.clickOnText(solo.getString(R.string.pref_compact_notification_buttons_title));
|
||||||
solo.waitForDialogToOpen(1000);
|
solo.waitForDialogToOpen(1000);
|
||||||
// First uncheck every checkbox
|
// First uncheck every checkbox
|
||||||
for (int i=0; i<buttons.length; i++) {
|
for (String button : buttons) {
|
||||||
assertTrue(solo.searchText(buttons[i]));
|
assertTrue(solo.searchText(button));
|
||||||
if (solo.isTextChecked(buttons[i])) {
|
if (solo.isTextChecked(button)) {
|
||||||
solo.clickOnText(buttons[i]);
|
solo.clickOnText(button);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Now try to check all checkboxes
|
// Now try to check all checkboxes
|
||||||
@ -111,13 +118,16 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
assertTrue(!solo.isTextChecked(buttons[2]));
|
assertTrue(!solo.isTextChecked(buttons[2]));
|
||||||
solo.clickOnText(solo.getString(R.string.confirm_label));
|
solo.clickOnText(solo.getString(R.string.confirm_label));
|
||||||
solo.waitForDialogToClose(1000);
|
solo.waitForDialogToClose(1000);
|
||||||
assertTrue(solo.waitForCondition(() -> UserPreferences.showRewindOnCompactNotification(), Timeout.getLargeTimeout()));
|
assertTrue(solo.waitForCondition(UserPreferences::showRewindOnCompactNotification, Timeout.getLargeTimeout()));
|
||||||
assertTrue(solo.waitForCondition(() -> UserPreferences.showFastForwardOnCompactNotification(), Timeout.getLargeTimeout()));
|
assertTrue(solo.waitForCondition(UserPreferences::showFastForwardOnCompactNotification, Timeout.getLargeTimeout()));
|
||||||
assertTrue(solo.waitForCondition(() -> !UserPreferences.showSkipOnCompactNotification(), Timeout.getLargeTimeout()));
|
assertTrue(solo.waitForCondition(() -> !UserPreferences.showSkipOnCompactNotification(), Timeout.getLargeTimeout()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testEnqueueAtFront() {
|
public void testEnqueueAtFront() {
|
||||||
|
solo.clickOnText(solo.getString(R.string.playback_pref));
|
||||||
final boolean enqueueAtFront = UserPreferences.enqueueAtFront();
|
final boolean enqueueAtFront = UserPreferences.enqueueAtFront();
|
||||||
|
solo.scrollDown();
|
||||||
|
solo.scrollDown();
|
||||||
solo.clickOnText(solo.getString(R.string.pref_queueAddToFront_title));
|
solo.clickOnText(solo.getString(R.string.pref_queueAddToFront_title));
|
||||||
assertTrue(solo.waitForCondition(() -> enqueueAtFront != UserPreferences.enqueueAtFront(), Timeout.getLargeTimeout()));
|
assertTrue(solo.waitForCondition(() -> enqueueAtFront != UserPreferences.enqueueAtFront(), Timeout.getLargeTimeout()));
|
||||||
solo.clickOnText(solo.getString(R.string.pref_queueAddToFront_title));
|
solo.clickOnText(solo.getString(R.string.pref_queueAddToFront_title));
|
||||||
@ -125,6 +135,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testHeadPhonesDisconnect() {
|
public void testHeadPhonesDisconnect() {
|
||||||
|
solo.clickOnText(solo.getString(R.string.playback_pref));
|
||||||
final boolean pauseOnHeadsetDisconnect = UserPreferences.isPauseOnHeadsetDisconnect();
|
final boolean pauseOnHeadsetDisconnect = UserPreferences.isPauseOnHeadsetDisconnect();
|
||||||
solo.clickOnText(solo.getString(R.string.pref_pauseOnHeadsetDisconnect_title));
|
solo.clickOnText(solo.getString(R.string.pref_pauseOnHeadsetDisconnect_title));
|
||||||
assertTrue(solo.waitForCondition(() -> pauseOnHeadsetDisconnect != UserPreferences.isPauseOnHeadsetDisconnect(), Timeout.getLargeTimeout()));
|
assertTrue(solo.waitForCondition(() -> pauseOnHeadsetDisconnect != UserPreferences.isPauseOnHeadsetDisconnect(), Timeout.getLargeTimeout()));
|
||||||
@ -133,9 +144,10 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testHeadPhonesReconnect() {
|
public void testHeadPhonesReconnect() {
|
||||||
|
solo.clickOnText(solo.getString(R.string.playback_pref));
|
||||||
if(UserPreferences.isPauseOnHeadsetDisconnect() == false) {
|
if(UserPreferences.isPauseOnHeadsetDisconnect() == false) {
|
||||||
solo.clickOnText(solo.getString(R.string.pref_pauseOnHeadsetDisconnect_title));
|
solo.clickOnText(solo.getString(R.string.pref_pauseOnHeadsetDisconnect_title));
|
||||||
assertTrue(solo.waitForCondition(() -> UserPreferences.isPauseOnHeadsetDisconnect(), Timeout.getLargeTimeout()));
|
assertTrue(solo.waitForCondition(UserPreferences::isPauseOnHeadsetDisconnect, Timeout.getLargeTimeout()));
|
||||||
}
|
}
|
||||||
final boolean unpauseOnHeadsetReconnect = UserPreferences.isUnpauseOnHeadsetReconnect();
|
final boolean unpauseOnHeadsetReconnect = UserPreferences.isUnpauseOnHeadsetReconnect();
|
||||||
solo.clickOnText(solo.getString(R.string.pref_unpauseOnHeadsetReconnect_title));
|
solo.clickOnText(solo.getString(R.string.pref_unpauseOnHeadsetReconnect_title));
|
||||||
@ -145,9 +157,10 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testBluetoothReconnect() {
|
public void testBluetoothReconnect() {
|
||||||
|
solo.clickOnText(solo.getString(R.string.playback_pref));
|
||||||
if(UserPreferences.isPauseOnHeadsetDisconnect() == false) {
|
if(UserPreferences.isPauseOnHeadsetDisconnect() == false) {
|
||||||
solo.clickOnText(solo.getString(R.string.pref_pauseOnHeadsetDisconnect_title));
|
solo.clickOnText(solo.getString(R.string.pref_pauseOnHeadsetDisconnect_title));
|
||||||
assertTrue(solo.waitForCondition(() -> UserPreferences.isPauseOnHeadsetDisconnect(), Timeout.getLargeTimeout()));
|
assertTrue(solo.waitForCondition(UserPreferences::isPauseOnHeadsetDisconnect, Timeout.getLargeTimeout()));
|
||||||
}
|
}
|
||||||
final boolean unpauseOnBluetoothReconnect = UserPreferences.isUnpauseOnBluetoothReconnect();
|
final boolean unpauseOnBluetoothReconnect = UserPreferences.isUnpauseOnBluetoothReconnect();
|
||||||
solo.clickOnText(solo.getString(R.string.pref_unpauseOnBluetoothReconnect_title));
|
solo.clickOnText(solo.getString(R.string.pref_unpauseOnBluetoothReconnect_title));
|
||||||
@ -157,7 +170,10 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testContinuousPlayback() {
|
public void testContinuousPlayback() {
|
||||||
|
solo.clickOnText(solo.getString(R.string.playback_pref));
|
||||||
final boolean continuousPlayback = UserPreferences.isFollowQueue();
|
final boolean continuousPlayback = UserPreferences.isFollowQueue();
|
||||||
|
solo.scrollDown();
|
||||||
|
solo.scrollDown();
|
||||||
solo.clickOnText(solo.getString(R.string.pref_followQueue_title));
|
solo.clickOnText(solo.getString(R.string.pref_followQueue_title));
|
||||||
assertTrue(solo.waitForCondition(() -> continuousPlayback != UserPreferences.isFollowQueue(), Timeout.getLargeTimeout()));
|
assertTrue(solo.waitForCondition(() -> continuousPlayback != UserPreferences.isFollowQueue(), Timeout.getLargeTimeout()));
|
||||||
solo.clickOnText(solo.getString(R.string.pref_followQueue_title));
|
solo.clickOnText(solo.getString(R.string.pref_followQueue_title));
|
||||||
@ -165,6 +181,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testAutoDelete() {
|
public void testAutoDelete() {
|
||||||
|
solo.clickOnText(solo.getString(R.string.storage_pref));
|
||||||
final boolean autoDelete = UserPreferences.isAutoDelete();
|
final boolean autoDelete = UserPreferences.isAutoDelete();
|
||||||
solo.clickOnText(solo.getString(R.string.pref_auto_delete_title));
|
solo.clickOnText(solo.getString(R.string.pref_auto_delete_title));
|
||||||
assertTrue(solo.waitForCondition(() -> autoDelete != UserPreferences.isAutoDelete(), Timeout.getLargeTimeout()));
|
assertTrue(solo.waitForCondition(() -> autoDelete != UserPreferences.isAutoDelete(), Timeout.getLargeTimeout()));
|
||||||
@ -173,6 +190,9 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testPlaybackSpeeds() {
|
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.clickOnText(solo.getString(R.string.pref_playback_speed_title));
|
||||||
solo.waitForDialogToOpen(1000);
|
solo.waitForDialogToOpen(1000);
|
||||||
assertTrue(solo.searchText(res.getStringArray(R.array.playback_speed_values)[0]));
|
assertTrue(solo.searchText(res.getStringArray(R.array.playback_speed_values)[0]));
|
||||||
@ -181,6 +201,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testPauseForInterruptions() {
|
public void testPauseForInterruptions() {
|
||||||
|
solo.clickOnText(solo.getString(R.string.playback_pref));
|
||||||
final boolean pauseForFocusLoss = UserPreferences.shouldPauseForFocusLoss();
|
final boolean pauseForFocusLoss = UserPreferences.shouldPauseForFocusLoss();
|
||||||
solo.clickOnText(solo.getString(R.string.pref_pausePlaybackForFocusLoss_title));
|
solo.clickOnText(solo.getString(R.string.pref_pausePlaybackForFocusLoss_title));
|
||||||
assertTrue(solo.waitForCondition(() -> pauseForFocusLoss != UserPreferences.shouldPauseForFocusLoss(), Timeout.getLargeTimeout()));
|
assertTrue(solo.waitForCondition(() -> pauseForFocusLoss != UserPreferences.shouldPauseForFocusLoss(), Timeout.getLargeTimeout()));
|
||||||
@ -189,6 +210,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testDisableUpdateInterval() {
|
public void testDisableUpdateInterval() {
|
||||||
|
solo.clickOnText(solo.getString(R.string.network_pref));
|
||||||
solo.clickOnText(solo.getString(R.string.pref_autoUpdateIntervallOrTime_sum));
|
solo.clickOnText(solo.getString(R.string.pref_autoUpdateIntervallOrTime_sum));
|
||||||
solo.waitForDialogToOpen();
|
solo.waitForDialogToOpen();
|
||||||
solo.clickOnText(solo.getString(R.string.pref_autoUpdateIntervallOrTime_Disable));
|
solo.clickOnText(solo.getString(R.string.pref_autoUpdateIntervallOrTime_Disable));
|
||||||
@ -196,6 +218,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testSetUpdateInterval() {
|
public void testSetUpdateInterval() {
|
||||||
|
solo.clickOnText(solo.getString(R.string.network_pref));
|
||||||
solo.clickOnText(solo.getString(R.string.pref_autoUpdateIntervallOrTime_title));
|
solo.clickOnText(solo.getString(R.string.pref_autoUpdateIntervallOrTime_title));
|
||||||
solo.waitForDialogToOpen();
|
solo.waitForDialogToOpen();
|
||||||
solo.clickOnText(solo.getString(R.string.pref_autoUpdateIntervallOrTime_Interval));
|
solo.clickOnText(solo.getString(R.string.pref_autoUpdateIntervallOrTime_Interval));
|
||||||
@ -208,6 +231,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testMobileUpdates() {
|
public void testMobileUpdates() {
|
||||||
|
solo.clickOnText(solo.getString(R.string.network_pref));
|
||||||
final boolean mobileUpdates = UserPreferences.isAllowMobileUpdate();
|
final boolean mobileUpdates = UserPreferences.isAllowMobileUpdate();
|
||||||
solo.clickOnText(solo.getString(R.string.pref_mobileUpdate_title));
|
solo.clickOnText(solo.getString(R.string.pref_mobileUpdate_title));
|
||||||
assertTrue(solo.waitForCondition(() -> mobileUpdates != UserPreferences.isAllowMobileUpdate(), Timeout.getLargeTimeout()));
|
assertTrue(solo.waitForCondition(() -> mobileUpdates != UserPreferences.isAllowMobileUpdate(), Timeout.getLargeTimeout()));
|
||||||
@ -216,6 +240,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testSetSequentialDownload() {
|
public void testSetSequentialDownload() {
|
||||||
|
solo.clickOnText(solo.getString(R.string.network_pref));
|
||||||
solo.clickOnText(solo.getString(R.string.pref_parallel_downloads_title));
|
solo.clickOnText(solo.getString(R.string.pref_parallel_downloads_title));
|
||||||
solo.waitForDialogToOpen();
|
solo.waitForDialogToOpen();
|
||||||
solo.clearEditText(0);
|
solo.clearEditText(0);
|
||||||
@ -225,6 +250,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testSetParallelDownloads() {
|
public void testSetParallelDownloads() {
|
||||||
|
solo.clickOnText(solo.getString(R.string.network_pref));
|
||||||
solo.clickOnText(solo.getString(R.string.pref_parallel_downloads_title));
|
solo.clickOnText(solo.getString(R.string.pref_parallel_downloads_title));
|
||||||
solo.waitForDialogToOpen();
|
solo.waitForDialogToOpen();
|
||||||
solo.clearEditText(0);
|
solo.clearEditText(0);
|
||||||
@ -234,6 +260,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testSetParallelDownloadsInvalidInput() {
|
public void testSetParallelDownloadsInvalidInput() {
|
||||||
|
solo.clickOnText(solo.getString(R.string.network_pref));
|
||||||
solo.clickOnText(solo.getString(R.string.pref_parallel_downloads_title));
|
solo.clickOnText(solo.getString(R.string.pref_parallel_downloads_title));
|
||||||
solo.waitForDialogToOpen();
|
solo.waitForDialogToOpen();
|
||||||
solo.clearEditText(0);
|
solo.clearEditText(0);
|
||||||
@ -249,6 +276,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
String[] values = res.getStringArray(R.array.episode_cache_size_values);
|
String[] values = res.getStringArray(R.array.episode_cache_size_values);
|
||||||
String entry = entries[entries.length/2];
|
String entry = entries[entries.length/2];
|
||||||
final int value = Integer.valueOf(values[values.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.clickOnText(solo.getString(R.string.pref_automatic_download_title));
|
||||||
solo.waitForText(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));
|
solo.clickOnText(solo.getString(R.string.pref_episode_cache_title));
|
||||||
@ -262,6 +290,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
String[] values = res.getStringArray(R.array.episode_cache_size_values);
|
String[] values = res.getStringArray(R.array.episode_cache_size_values);
|
||||||
String minEntry = entries[0];
|
String minEntry = entries[0];
|
||||||
final int minValue = Integer.valueOf(values[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.clickOnText(solo.getString(R.string.pref_automatic_download_title));
|
||||||
solo.waitForText(solo.getString(R.string.pref_automatic_download_title));
|
solo.waitForText(solo.getString(R.string.pref_automatic_download_title));
|
||||||
if(!UserPreferences.isEnableAutodownload()) {
|
if(!UserPreferences.isEnableAutodownload()) {
|
||||||
@ -279,6 +308,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
String[] values = res.getStringArray(R.array.episode_cache_size_values);
|
String[] values = res.getStringArray(R.array.episode_cache_size_values);
|
||||||
String maxEntry = entries[entries.length-1];
|
String maxEntry = entries[entries.length-1];
|
||||||
final int maxValue = Integer.valueOf(values[values.length-1]);
|
final int maxValue = Integer.valueOf(values[values.length-1]);
|
||||||
|
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_automatic_download_title));
|
||||||
solo.waitForText(solo.getString(R.string.pref_automatic_download_title));
|
solo.waitForText(solo.getString(R.string.pref_automatic_download_title));
|
||||||
if(!UserPreferences.isEnableAutodownload()) {
|
if(!UserPreferences.isEnableAutodownload()) {
|
||||||
@ -292,6 +322,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
|
|
||||||
public void testAutomaticDownload() {
|
public void testAutomaticDownload() {
|
||||||
final boolean automaticDownload = UserPreferences.isEnableAutodownload();
|
final boolean automaticDownload = UserPreferences.isEnableAutodownload();
|
||||||
|
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_automatic_download_title));
|
||||||
solo.waitForText(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));
|
solo.clickOnText(solo.getString(R.string.pref_automatic_download_title));
|
||||||
@ -313,6 +344,8 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testEpisodeCleanupQueueOnly() {
|
public void testEpisodeCleanupQueueOnly() {
|
||||||
|
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.clickOnText(solo.getString(R.string.pref_episode_cleanup_title));
|
||||||
solo.waitForText(solo.getString(R.string.episode_cleanup_queue_removal));
|
solo.waitForText(solo.getString(R.string.episode_cleanup_queue_removal));
|
||||||
solo.clickOnText(solo.getString(R.string.episode_cleanup_queue_removal));
|
solo.clickOnText(solo.getString(R.string.episode_cleanup_queue_removal));
|
||||||
@ -324,6 +357,8 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testEpisodeCleanupNeverAlg() {
|
public void testEpisodeCleanupNeverAlg() {
|
||||||
|
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.clickOnText(solo.getString(R.string.pref_episode_cleanup_title));
|
||||||
solo.waitForText(solo.getString(R.string.episode_cleanup_never));
|
solo.waitForText(solo.getString(R.string.episode_cleanup_never));
|
||||||
solo.clickOnText(solo.getString(R.string.episode_cleanup_never));
|
solo.clickOnText(solo.getString(R.string.episode_cleanup_never));
|
||||||
@ -335,6 +370,8 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testEpisodeCleanupClassic() {
|
public void testEpisodeCleanupClassic() {
|
||||||
|
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.clickOnText(solo.getString(R.string.pref_episode_cleanup_title));
|
||||||
solo.waitForText(solo.getString(R.string.episode_cleanup_after_listening));
|
solo.waitForText(solo.getString(R.string.episode_cleanup_after_listening));
|
||||||
solo.clickOnText(solo.getString(R.string.episode_cleanup_after_listening));
|
solo.clickOnText(solo.getString(R.string.episode_cleanup_after_listening));
|
||||||
@ -350,6 +387,8 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testEpisodeCleanupNumDays() {
|
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.clickOnText(solo.getString(R.string.pref_episode_cleanup_title));
|
||||||
solo.waitForText(solo.getString(R.string.episode_cleanup_after_listening));
|
solo.waitForText(solo.getString(R.string.episode_cleanup_after_listening));
|
||||||
solo.clickOnText("5");
|
solo.clickOnText("5");
|
||||||
@ -369,6 +408,9 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
int seconds = UserPreferences.getRewindSecs();
|
int seconds = UserPreferences.getRewindSecs();
|
||||||
int deltas[] = res.getIntArray(R.array.seek_delta_values);
|
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));
|
solo.clickOnText(solo.getString(R.string.pref_rewind));
|
||||||
solo.waitForDialogToOpen();
|
solo.waitForDialogToOpen();
|
||||||
|
|
||||||
@ -387,6 +429,9 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testFastForwardChange() {
|
public void testFastForwardChange() {
|
||||||
|
solo.clickOnText(solo.getString(R.string.playback_pref));
|
||||||
|
solo.scrollDown();
|
||||||
|
solo.scrollDown();
|
||||||
for (int i = 2; i > 0; i--) { // repeat twice to catch any error where fastforward is tracking rewind
|
for (int i = 2; i > 0; i--) { // repeat twice to catch any error where fastforward is tracking rewind
|
||||||
int seconds = UserPreferences.getFastForwardSecs();
|
int seconds = UserPreferences.getFastForwardSecs();
|
||||||
int deltas[] = res.getIntArray(R.array.seek_delta_values);
|
int deltas[] = res.getIntArray(R.array.seek_delta_values);
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
package de.test.antennapod.ui;
|
package de.test.antennapod.ui;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.os.Build;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import junit.framework.Assert;
|
import junit.framework.Assert;
|
||||||
@ -20,14 +18,12 @@ import java.util.ArrayList;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import de.danoeh.antennapod.R;
|
|
||||||
import de.danoeh.antennapod.activity.MainActivity;
|
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.EventDistributor;
|
||||||
import de.danoeh.antennapod.core.feed.Feed;
|
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.FeedItem;
|
||||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||||
import de.danoeh.antennapod.core.event.QueueEvent;
|
|
||||||
import de.danoeh.antennapod.core.storage.PodDBAdapter;
|
import de.danoeh.antennapod.core.storage.PodDBAdapter;
|
||||||
import de.danoeh.antennapod.core.util.playback.PlaybackController;
|
import de.danoeh.antennapod.core.util.playback.PlaybackController;
|
||||||
import de.danoeh.antennapod.fragment.ExternalPlayerFragment;
|
import de.danoeh.antennapod.fragment.ExternalPlayerFragment;
|
||||||
@ -39,27 +35,25 @@ import de.test.antennapod.util.syndication.feedgenerator.RSS2Generator;
|
|||||||
* Utility methods for UI tests.
|
* Utility methods for UI tests.
|
||||||
* Starts a web server that hosts feeds, episodes and images.
|
* Starts a web server that hosts feeds, episodes and images.
|
||||||
*/
|
*/
|
||||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
class UITestUtils {
|
||||||
public class UITestUtils {
|
|
||||||
|
|
||||||
private static final String TAG = UITestUtils.class.getSimpleName();
|
private static final String TAG = UITestUtils.class.getSimpleName();
|
||||||
|
|
||||||
private static final String DATA_FOLDER = "test/UITestUtils";
|
private static final String DATA_FOLDER = "test/UITestUtils";
|
||||||
|
|
||||||
public static final int NUM_FEEDS = 5;
|
private static final int NUM_FEEDS = 5;
|
||||||
public static final int NUM_ITEMS_PER_FEED = 10;
|
private static final int NUM_ITEMS_PER_FEED = 10;
|
||||||
|
|
||||||
public static final int HOME_VIEW = (Build.VERSION.SDK_INT >= 11) ? android.R.id.home : R.id.home;
|
private static final String TEST_FILE_NAME = "3sec.mp3";
|
||||||
public static final String TEST_FILE_NAME = "3sec.mp3";
|
|
||||||
|
|
||||||
|
|
||||||
private Context context;
|
private final Context context;
|
||||||
private HTTPBin server = new HTTPBin();
|
private final HTTPBin server = new HTTPBin();
|
||||||
private File destDir;
|
private File destDir;
|
||||||
private File hostedFeedDir;
|
private File hostedFeedDir;
|
||||||
private File hostedMediaDir;
|
private File hostedMediaDir;
|
||||||
|
|
||||||
public List<Feed> hostedFeeds = new ArrayList<>();
|
public final List<Feed> hostedFeeds = new ArrayList<>();
|
||||||
|
|
||||||
public UITestUtils(Context context) {
|
public UITestUtils(Context context) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
@ -141,12 +135,9 @@ public class UITestUtils {
|
|||||||
public void addHostedFeedData() throws IOException {
|
public void addHostedFeedData() throws IOException {
|
||||||
if (feedDataHosted) throw new IllegalStateException("addHostedFeedData was called twice on the same instance");
|
if (feedDataHosted) throw new IllegalStateException("addHostedFeedData was called twice on the same instance");
|
||||||
for (int i = 0; i < NUM_FEEDS; i++) {
|
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,
|
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);
|
"http://example.com/feed/src/" + i, false);
|
||||||
image.setOwner(feed);
|
|
||||||
|
|
||||||
// create items
|
// create items
|
||||||
List<FeedItem> items = new ArrayList<>();
|
List<FeedItem> items = new ArrayList<>();
|
||||||
@ -192,12 +183,6 @@ public class UITestUtils {
|
|||||||
List<FeedItem> queue = new ArrayList<>();
|
List<FeedItem> queue = new ArrayList<>();
|
||||||
for (Feed feed : hostedFeeds) {
|
for (Feed feed : hostedFeeds) {
|
||||||
feed.setDownloaded(true);
|
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) {
|
if (downloadEpisodes) {
|
||||||
for (FeedItem item : feed.getItems()) {
|
for (FeedItem item : feed.getItems()) {
|
||||||
if (item.hasMedia()) {
|
if (item.hasMedia()) {
|
||||||
|
@ -38,9 +38,6 @@ public class UITestUtilsTest extends InstrumentationTestCase {
|
|||||||
|
|
||||||
for (Feed feed : feeds) {
|
for (Feed feed : feeds) {
|
||||||
testUrlReachable(feed.getDownload_url());
|
testUrlReachable(feed.getDownload_url());
|
||||||
if (feed.getImage() != null) {
|
|
||||||
testUrlReachable(feed.getImage().getDownload_url());
|
|
||||||
}
|
|
||||||
for (FeedItem item : feed.getItems()) {
|
for (FeedItem item : feed.getItems()) {
|
||||||
if (item.hasMedia()) {
|
if (item.hasMedia()) {
|
||||||
testUrlReachable(item.getMedia().getDownload_url());
|
testUrlReachable(item.getMedia().getDownload_url());
|
||||||
@ -66,9 +63,6 @@ public class UITestUtilsTest extends InstrumentationTestCase {
|
|||||||
|
|
||||||
for (Feed feed : uiTestUtils.hostedFeeds) {
|
for (Feed feed : uiTestUtils.hostedFeeds) {
|
||||||
assertTrue(feed.getId() != 0);
|
assertTrue(feed.getId() != 0);
|
||||||
if (feed.getImage() != null) {
|
|
||||||
assertTrue(feed.getImage().getId() != 0);
|
|
||||||
}
|
|
||||||
for (FeedItem item : feed.getItems()) {
|
for (FeedItem item : feed.getItems()) {
|
||||||
assertTrue(item.getId() != 0);
|
assertTrue(item.getId() != 0);
|
||||||
if (item.hasMedia()) {
|
if (item.hasMedia()) {
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
package de.test.antennapod.util;
|
package de.test.antennapod.util;
|
||||||
|
|
||||||
|
import android.test.AndroidTestCase;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import de.danoeh.antennapod.core.util.FileNameGenerator;
|
import de.danoeh.antennapod.core.util.FileNameGenerator;
|
||||||
import android.test.AndroidTestCase;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
|
|
||||||
public class FilenameGeneratorTest extends AndroidTestCase {
|
public class FilenameGeneratorTest extends AndroidTestCase {
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package de.test.antennapod.util;
|
package de.test.antennapod.util;
|
||||||
|
|
||||||
import junit.framework.*;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import de.danoeh.antennapod.core.util.*;
|
import de.danoeh.antennapod.core.util.RewindAfterPauseUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link RewindAfterPauseUtils}.
|
* Tests for {@link RewindAfterPauseUtils}.
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package de.test.antennapod.util;
|
package de.test.antennapod.util;
|
||||||
|
|
||||||
import android.test.AndroidTestCase;
|
import android.test.AndroidTestCase;
|
||||||
|
|
||||||
import de.danoeh.antennapod.core.util.URIUtil;
|
import de.danoeh.antennapod.core.util.URIUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package de.test.antennapod.util;
|
package de.test.antennapod.util;
|
||||||
|
|
||||||
import android.test.AndroidTestCase;
|
import android.test.AndroidTestCase;
|
||||||
|
|
||||||
import de.danoeh.antennapod.core.util.URLChecker;
|
import de.danoeh.antennapod.core.util.URLChecker;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,7 +45,7 @@ public class HTTPBin extends NanoHTTPD {
|
|||||||
private static final String MIME_HTML = "text/html";
|
private static final String MIME_HTML = "text/html";
|
||||||
private static final String MIME_PLAIN = "text/plain";
|
private static final String MIME_PLAIN = "text/plain";
|
||||||
|
|
||||||
private List<File> servedFiles;
|
private final List<File> servedFiles;
|
||||||
|
|
||||||
public HTTPBin() {
|
public HTTPBin() {
|
||||||
super(PORT);
|
super(PORT);
|
||||||
|
@ -88,15 +88,15 @@ public abstract class NanoHTTPD {
|
|||||||
* This is required as the Keep-Alive HTTP connections would otherwise
|
* This is required as the Keep-Alive HTTP connections would otherwise
|
||||||
* block the socket reading thread forever (or as long the browser is open).
|
* block the socket reading thread forever (or as long the browser is open).
|
||||||
*/
|
*/
|
||||||
public static final int SOCKET_READ_TIMEOUT = 5000;
|
private static final int SOCKET_READ_TIMEOUT = 5000;
|
||||||
/**
|
/**
|
||||||
* Common mime type for dynamic content: plain text
|
* Common mime type for dynamic content: plain text
|
||||||
*/
|
*/
|
||||||
public static final String MIME_PLAINTEXT = "text/plain";
|
private static final String MIME_PLAINTEXT = "text/plain";
|
||||||
/**
|
/**
|
||||||
* Common mime type for dynamic content: html
|
* Common mime type for dynamic content: html
|
||||||
*/
|
*/
|
||||||
public static final String MIME_HTML = "text/html";
|
private static final String MIME_HTML = "text/html";
|
||||||
/**
|
/**
|
||||||
* Pseudo-Parameter to use to store the actual query string in the parameters map for later re-processing.
|
* Pseudo-Parameter to use to store the actual query string in the parameters map for later re-processing.
|
||||||
*/
|
*/
|
||||||
@ -104,7 +104,7 @@ public abstract class NanoHTTPD {
|
|||||||
private final String hostname;
|
private final String hostname;
|
||||||
private final int myPort;
|
private final int myPort;
|
||||||
private ServerSocket myServerSocket;
|
private ServerSocket myServerSocket;
|
||||||
private Set<Socket> openConnections = new HashSet<>();
|
private final Set<Socket> openConnections = new HashSet<>();
|
||||||
private Thread myThread;
|
private Thread myThread;
|
||||||
/**
|
/**
|
||||||
* Pluggable strategy for asynchronously executing requests.
|
* Pluggable strategy for asynchronously executing requests.
|
||||||
@ -118,14 +118,14 @@ public abstract class NanoHTTPD {
|
|||||||
/**
|
/**
|
||||||
* Constructs an HTTP server on given port.
|
* Constructs an HTTP server on given port.
|
||||||
*/
|
*/
|
||||||
public NanoHTTPD(int port) {
|
NanoHTTPD(int port) {
|
||||||
this(null, port);
|
this(null, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an HTTP server on given hostname and port.
|
* Constructs an HTTP server on given hostname and port.
|
||||||
*/
|
*/
|
||||||
public NanoHTTPD(String hostname, int port) {
|
private NanoHTTPD(String hostname, int port) {
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
this.myPort = port;
|
this.myPort = port;
|
||||||
setTempFileManagerFactory(new DefaultTempFileManagerFactory());
|
setTempFileManagerFactory(new DefaultTempFileManagerFactory());
|
||||||
@ -168,44 +168,38 @@ public abstract class NanoHTTPD {
|
|||||||
myServerSocket = new ServerSocket();
|
myServerSocket = new ServerSocket();
|
||||||
myServerSocket.bind((hostname != null) ? new InetSocketAddress(hostname, myPort) : new InetSocketAddress(myPort));
|
myServerSocket.bind((hostname != null) ? new InetSocketAddress(hostname, myPort) : new InetSocketAddress(myPort));
|
||||||
|
|
||||||
myThread = new Thread(new Runnable() {
|
myThread = new Thread(() -> {
|
||||||
@Override
|
do {
|
||||||
public void run() {
|
try {
|
||||||
do {
|
final Socket finalAccept = myServerSocket.accept();
|
||||||
try {
|
registerConnection(finalAccept);
|
||||||
final Socket finalAccept = myServerSocket.accept();
|
finalAccept.setSoTimeout(SOCKET_READ_TIMEOUT);
|
||||||
registerConnection(finalAccept);
|
final InputStream inputStream = finalAccept.getInputStream();
|
||||||
finalAccept.setSoTimeout(SOCKET_READ_TIMEOUT);
|
asyncRunner.exec(() -> {
|
||||||
final InputStream inputStream = finalAccept.getInputStream();
|
OutputStream outputStream = null;
|
||||||
asyncRunner.exec(new Runnable() {
|
try {
|
||||||
@Override
|
outputStream = finalAccept.getOutputStream();
|
||||||
public void run() {
|
TempFileManager tempFileManager = tempFileManagerFactory.create();
|
||||||
OutputStream outputStream = null;
|
HTTPSession session = new HTTPSession(tempFileManager, inputStream, outputStream, finalAccept.getInetAddress());
|
||||||
try {
|
while (!finalAccept.isClosed()) {
|
||||||
outputStream = finalAccept.getOutputStream();
|
session.execute();
|
||||||
TempFileManager tempFileManager = tempFileManagerFactory.create();
|
|
||||||
HTTPSession session = new HTTPSession(tempFileManager, inputStream, outputStream, finalAccept.getInetAddress());
|
|
||||||
while (!finalAccept.isClosed()) {
|
|
||||||
session.execute();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
// When the socket is closed by the client, we throw our own SocketException
|
|
||||||
// to break the "keep alive" loop above.
|
|
||||||
if (!(e instanceof SocketException && "NanoHttpd Shutdown".equals(e.getMessage()))) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
safeClose(outputStream);
|
|
||||||
safeClose(inputStream);
|
|
||||||
safeClose(finalAccept);
|
|
||||||
unRegisterConnection(finalAccept);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
} catch (Exception e) {
|
||||||
} catch (IOException e) {
|
// When the socket is closed by the client, we throw our own SocketException
|
||||||
}
|
// to break the "keep alive" loop above.
|
||||||
} while (!myServerSocket.isClosed());
|
if (!(e instanceof SocketException && "NanoHttpd Shutdown".equals(e.getMessage()))) {
|
||||||
}
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
safeClose(outputStream);
|
||||||
|
safeClose(inputStream);
|
||||||
|
safeClose(finalAccept);
|
||||||
|
unRegisterConnection(finalAccept);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
|
} while (!myServerSocket.isClosed());
|
||||||
});
|
});
|
||||||
myThread.setDaemon(true);
|
myThread.setDaemon(true);
|
||||||
myThread.setName("NanoHttpd Main Listener");
|
myThread.setName("NanoHttpd Main Listener");
|
||||||
@ -232,7 +226,7 @@ public abstract class NanoHTTPD {
|
|||||||
*
|
*
|
||||||
* @param socket the {@link Socket} for the connection.
|
* @param socket the {@link Socket} for the connection.
|
||||||
*/
|
*/
|
||||||
public synchronized void registerConnection(Socket socket) {
|
private synchronized void registerConnection(Socket socket) {
|
||||||
openConnections.add(socket);
|
openConnections.add(socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,14 +236,14 @@ public abstract class NanoHTTPD {
|
|||||||
* @param socket
|
* @param socket
|
||||||
* the {@link Socket} for the connection.
|
* the {@link Socket} for the connection.
|
||||||
*/
|
*/
|
||||||
public synchronized void unRegisterConnection(Socket socket) {
|
private synchronized void unRegisterConnection(Socket socket) {
|
||||||
openConnections.remove(socket);
|
openConnections.remove(socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forcibly closes all connections that are open.
|
* Forcibly closes all connections that are open.
|
||||||
*/
|
*/
|
||||||
public synchronized void closeAllConnections() {
|
private synchronized void closeAllConnections() {
|
||||||
for (Socket socket : openConnections) {
|
for (Socket socket : openConnections) {
|
||||||
safeClose(socket);
|
safeClose(socket);
|
||||||
}
|
}
|
||||||
@ -259,7 +253,7 @@ public abstract class NanoHTTPD {
|
|||||||
return myServerSocket == null ? -1 : myServerSocket.getLocalPort();
|
return myServerSocket == null ? -1 : myServerSocket.getLocalPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean wasStarted() {
|
private boolean wasStarted() {
|
||||||
return myServerSocket != null && myThread != null;
|
return myServerSocket != null && myThread != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,7 +288,7 @@ public abstract class NanoHTTPD {
|
|||||||
* @param session The HTTP session
|
* @param session The HTTP session
|
||||||
* @return HTTP response, see class Response for details
|
* @return HTTP response, see class Response for details
|
||||||
*/
|
*/
|
||||||
public Response serve(IHTTPSession session) {
|
Response serve(IHTTPSession session) {
|
||||||
Map<String, String> files = new ArrayMap<>();
|
Map<String, String> files = new ArrayMap<>();
|
||||||
Method method = session.getMethod();
|
Method method = session.getMethod();
|
||||||
if (Method.PUT.equals(method) || Method.POST.equals(method)) {
|
if (Method.PUT.equals(method) || Method.POST.equals(method)) {
|
||||||
@ -318,7 +312,7 @@ public abstract class NanoHTTPD {
|
|||||||
* @param str the percent encoded <code>String</code>
|
* @param str the percent encoded <code>String</code>
|
||||||
* @return expanded form of the input, for example "foo%20bar" becomes "foo bar"
|
* @return expanded form of the input, for example "foo%20bar" becomes "foo bar"
|
||||||
*/
|
*/
|
||||||
protected String decodePercent(String str) {
|
private String decodePercent(String str) {
|
||||||
String decoded = null;
|
String decoded = null;
|
||||||
try {
|
try {
|
||||||
decoded = URLDecoder.decode(str, "UTF8");
|
decoded = URLDecoder.decode(str, "UTF8");
|
||||||
@ -347,7 +341,7 @@ public abstract class NanoHTTPD {
|
|||||||
* @param queryString a query string pulled from the URL.
|
* @param queryString a query string pulled from the URL.
|
||||||
* @return a map of <code>String</code> (parameter name) to <code>List<String></code> (a list of the values supplied).
|
* @return a map of <code>String</code> (parameter name) to <code>List<String></code> (a list of the values supplied).
|
||||||
*/
|
*/
|
||||||
protected Map<String, List<String>> decodeParameters(String queryString) {
|
private Map<String, List<String>> decodeParameters(String queryString) {
|
||||||
Map<String, List<String>> parms = new ArrayMap<>();
|
Map<String, List<String>> parms = new ArrayMap<>();
|
||||||
if (queryString != null) {
|
if (queryString != null) {
|
||||||
StringTokenizer st = new StringTokenizer(queryString, "&");
|
StringTokenizer st = new StringTokenizer(queryString, "&");
|
||||||
@ -378,7 +372,7 @@ public abstract class NanoHTTPD {
|
|||||||
*
|
*
|
||||||
* @param asyncRunner new strategy for handling threads.
|
* @param asyncRunner new strategy for handling threads.
|
||||||
*/
|
*/
|
||||||
public void setAsyncRunner(AsyncRunner asyncRunner) {
|
private void setAsyncRunner(AsyncRunner asyncRunner) {
|
||||||
this.asyncRunner = asyncRunner;
|
this.asyncRunner = asyncRunner;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,7 +387,7 @@ public abstract class NanoHTTPD {
|
|||||||
*
|
*
|
||||||
* @param tempFileManagerFactory new strategy for handling temp files.
|
* @param tempFileManagerFactory new strategy for handling temp files.
|
||||||
*/
|
*/
|
||||||
public void setTempFileManagerFactory(TempFileManagerFactory tempFileManagerFactory) {
|
private void setTempFileManagerFactory(TempFileManagerFactory tempFileManagerFactory) {
|
||||||
this.tempFileManagerFactory = tempFileManagerFactory;
|
this.tempFileManagerFactory = tempFileManagerFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -448,9 +442,9 @@ public abstract class NanoHTTPD {
|
|||||||
* themselves up when no longer needed.</p>
|
* themselves up when no longer needed.</p>
|
||||||
*/
|
*/
|
||||||
public interface TempFile {
|
public interface TempFile {
|
||||||
OutputStream open() throws Exception;
|
OutputStream open();
|
||||||
|
|
||||||
void delete() throws Exception;
|
void delete();
|
||||||
|
|
||||||
String getName();
|
String getName();
|
||||||
}
|
}
|
||||||
@ -528,12 +522,12 @@ public abstract class NanoHTTPD {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OutputStream open() throws Exception {
|
public OutputStream open() {
|
||||||
return fstream;
|
return fstream;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete() throws Exception {
|
public void delete() {
|
||||||
safeClose(fstream);
|
safeClose(fstream);
|
||||||
file.delete();
|
file.delete();
|
||||||
}
|
}
|
||||||
@ -563,7 +557,7 @@ public abstract class NanoHTTPD {
|
|||||||
/**
|
/**
|
||||||
* Headers for the HTTP response. Use addHeader() to add lines.
|
* Headers for the HTTP response. Use addHeader() to add lines.
|
||||||
*/
|
*/
|
||||||
private Map<String, String> header = new ArrayMap<>();
|
private final Map<String, String> header = new ArrayMap<>();
|
||||||
/**
|
/**
|
||||||
* The request method that spawned this response.
|
* The request method that spawned this response.
|
||||||
*/
|
*/
|
||||||
@ -616,7 +610,7 @@ public abstract class NanoHTTPD {
|
|||||||
/**
|
/**
|
||||||
* Sends given response to the socket.
|
* Sends given response to the socket.
|
||||||
*/
|
*/
|
||||||
protected void send(OutputStream outputStream) {
|
void send(OutputStream outputStream) {
|
||||||
String mime = mimeType;
|
String mime = mimeType;
|
||||||
SimpleDateFormat gmtFrmt = new SimpleDateFormat("E, d MMM yyyy HH:mm:ss 'GMT'", Locale.US);
|
SimpleDateFormat gmtFrmt = new SimpleDateFormat("E, d MMM yyyy HH:mm:ss 'GMT'", Locale.US);
|
||||||
gmtFrmt.setTimeZone(TimeZone.getTimeZone("GMT"));
|
gmtFrmt.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||||
@ -661,13 +655,13 @@ public abstract class NanoHTTPD {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void sendContentLengthHeaderIfNotAlreadyPresent(PrintWriter pw, Map<String, String> header, int size) {
|
void sendContentLengthHeaderIfNotAlreadyPresent(PrintWriter pw, Map<String, String> header, int size) {
|
||||||
if (!headerAlreadySent(header, "content-length")) {
|
if (!headerAlreadySent(header, "content-length")) {
|
||||||
pw.print("Content-Length: "+ size +"\r\n");
|
pw.print("Content-Length: "+ size +"\r\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void sendConnectionHeaderIfNotAlreadyPresent(PrintWriter pw, Map<String, String> header) {
|
void sendConnectionHeaderIfNotAlreadyPresent(PrintWriter pw, Map<String, String> header) {
|
||||||
if (!headerAlreadySent(header, "connection")) {
|
if (!headerAlreadySent(header, "connection")) {
|
||||||
pw.print("Connection: keep-alive\r\n");
|
pw.print("Connection: keep-alive\r\n");
|
||||||
}
|
}
|
||||||
@ -694,7 +688,7 @@ public abstract class NanoHTTPD {
|
|||||||
outputStream.write(buff, 0, read);
|
outputStream.write(buff, 0, read);
|
||||||
outputStream.write(CRLF);
|
outputStream.write(CRLF);
|
||||||
}
|
}
|
||||||
outputStream.write(String.format("0\r\n\r\n").getBytes());
|
outputStream.write("0\r\n\r\n".getBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendAsFixedLength(OutputStream outputStream, int pending) throws IOException {
|
private void sendAsFixedLength(OutputStream outputStream, int pending) throws IOException {
|
||||||
@ -844,7 +838,7 @@ public abstract class NanoHTTPD {
|
|||||||
public static final int BUFSIZE = 8192;
|
public static final int BUFSIZE = 8192;
|
||||||
private final TempFileManager tempFileManager;
|
private final TempFileManager tempFileManager;
|
||||||
private final OutputStream outputStream;
|
private final OutputStream outputStream;
|
||||||
private PushbackInputStream inputStream;
|
private final PushbackInputStream inputStream;
|
||||||
private int splitbyte;
|
private int splitbyte;
|
||||||
private int rlen;
|
private int rlen;
|
||||||
private String uri;
|
private String uri;
|
||||||
@ -1144,17 +1138,19 @@ public abstract class NanoHTTPD {
|
|||||||
|
|
||||||
String value = "";
|
String value = "";
|
||||||
if (item.get("content-type") == null) {
|
if (item.get("content-type") == null) {
|
||||||
|
StringBuilder tmp = new StringBuilder();
|
||||||
while (mpline != null && !mpline.contains(boundary)) {
|
while (mpline != null && !mpline.contains(boundary)) {
|
||||||
mpline = in.readLine();
|
mpline = in.readLine();
|
||||||
if (mpline != null) {
|
if (mpline != null) {
|
||||||
int d = mpline.indexOf(boundary);
|
int d = mpline.indexOf(boundary);
|
||||||
if (d == -1) {
|
if (d == -1) {
|
||||||
value += mpline;
|
tmp.append(mpline);
|
||||||
} else {
|
} else {
|
||||||
value += mpline.substring(0, d - 2);
|
tmp.append(mpline.substring(0, d - 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
value = tmp.toString();
|
||||||
} else {
|
} else {
|
||||||
if (boundarycount > bpositions.length) {
|
if (boundarycount > bpositions.length) {
|
||||||
throw new ResponseException(Response.Status.INTERNAL_ERROR, "Error processing request");
|
throw new ResponseException(Response.Status.INTERNAL_ERROR, "Error processing request");
|
||||||
@ -1326,7 +1322,9 @@ public abstract class NanoHTTPD {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Cookie {
|
public static class Cookie {
|
||||||
private String n, v, e;
|
private final String n;
|
||||||
|
private final String v;
|
||||||
|
private final String e;
|
||||||
|
|
||||||
public Cookie(String name, String value, String expires) {
|
public Cookie(String name, String value, String expires) {
|
||||||
n = name;
|
n = name;
|
||||||
@ -1366,8 +1364,8 @@ public abstract class NanoHTTPD {
|
|||||||
* @author LordFokas
|
* @author LordFokas
|
||||||
*/
|
*/
|
||||||
public class CookieHandler implements Iterable<String> {
|
public class CookieHandler implements Iterable<String> {
|
||||||
private ArrayMap<String, String> cookies = new ArrayMap<>();
|
private final ArrayMap<String, String> cookies = new ArrayMap<>();
|
||||||
private ArrayList<Cookie> queue = new ArrayList<>();
|
private final ArrayList<Cookie> queue = new ArrayList<>();
|
||||||
|
|
||||||
public CookieHandler(Map<String, String> httpHeaders) {
|
public CookieHandler(Map<String, String> httpHeaders) {
|
||||||
String raw = httpHeaders.get("cookie");
|
String raw = httpHeaders.get("cookie");
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package de.test.antennapod.util.syndication;
|
package de.test.antennapod.util.syndication;
|
||||||
|
|
||||||
import android.test.InstrumentationTestCase;
|
import android.test.InstrumentationTestCase;
|
||||||
import de.danoeh.antennapod.core.util.syndication.FeedDiscoverer;
|
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
|
||||||
@ -9,6 +9,8 @@ import java.io.File;
|
|||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import de.danoeh.antennapod.core.util.syndication.FeedDiscoverer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test class for FeedDiscoverer
|
* Test class for FeedDiscoverer
|
||||||
*/
|
*/
|
||||||
|
@ -19,7 +19,7 @@ public class AtomGenerator implements FeedGenerator{
|
|||||||
|
|
||||||
private static final String NS_ATOM = "http://www.w3.org/2005/Atom";
|
private static final String NS_ATOM = "http://www.w3.org/2005/Atom";
|
||||||
|
|
||||||
public static final long FEATURE_USE_RFC3339LOCAL = 1;
|
private static final long FEATURE_USE_RFC3339LOCAL = 1;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeFeed(Feed feed, OutputStream outputStream, String encoding, long flags) throws IOException {
|
public void writeFeed(Feed feed, OutputStream outputStream, String encoding, long flags) throws IOException {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package de.test.antennapod.util.syndication.feedgenerator;
|
package de.test.antennapod.util.syndication.feedgenerator;
|
||||||
|
|
||||||
import de.danoeh.antennapod.core.feed.Feed;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import de.danoeh.antennapod.core.feed.Feed;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a machine-readable, platform-independent representation of a Feed object.
|
* Generates a machine-readable, platform-independent representation of a Feed object.
|
||||||
*/
|
*/
|
||||||
@ -24,5 +24,5 @@ public interface FeedGenerator {
|
|||||||
* @param encoding The encoding to use. Must not be null.
|
* @param encoding The encoding to use. Must not be null.
|
||||||
* @param flags Optional argument for enabling implementation-dependent features.
|
* @param flags Optional argument for enabling implementation-dependent features.
|
||||||
*/
|
*/
|
||||||
public void writeFeed(Feed feed, OutputStream outputStream, String encoding, long flags) throws IOException;
|
void writeFeed(Feed feed, OutputStream outputStream, String encoding, long flags) throws IOException;
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import java.io.IOException;
|
|||||||
/**
|
/**
|
||||||
* Utility methods for FeedGenerator
|
* Utility methods for FeedGenerator
|
||||||
*/
|
*/
|
||||||
public class GeneratorUtil {
|
class GeneratorUtil {
|
||||||
private GeneratorUtil(){}
|
private GeneratorUtil(){}
|
||||||
|
|
||||||
public static void addPaymentLink(XmlSerializer xml, String paymentLink, boolean withNamespace) throws IOException {
|
public static void addPaymentLink(XmlSerializer xml, String paymentLink, boolean withNamespace) throws IOException {
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
package de.test.antennapod.util.syndication.feedgenerator;
|
package de.test.antennapod.util.syndication.feedgenerator;
|
||||||
|
|
||||||
import android.util.Xml;
|
import android.util.Xml;
|
||||||
import de.danoeh.antennapod.core.feed.Feed;
|
|
||||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
|
||||||
import de.danoeh.antennapod.core.util.DateUtils;
|
|
||||||
import org.xmlpull.v1.XmlSerializer;
|
import org.xmlpull.v1.XmlSerializer;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import de.danoeh.antennapod.core.feed.Feed;
|
||||||
|
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||||
|
import de.danoeh.antennapod.core.util.DateUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates RSS 2.0 feeds. See FeedGenerator for more information.
|
* Creates RSS 2.0 feeds. See FeedGenerator for more information.
|
||||||
*/
|
*/
|
||||||
|
@ -2,6 +2,6 @@ package de.danoeh.antennapod.config;
|
|||||||
|
|
||||||
import de.danoeh.antennapod.core.CastCallbacks;
|
import de.danoeh.antennapod.core.CastCallbacks;
|
||||||
|
|
||||||
public class CastCallbackImpl implements CastCallbacks {
|
class CastCallbackImpl implements CastCallbacks {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import de.danoeh.antennapod.core.preferences.UserPreferences;
|
|||||||
/**
|
/**
|
||||||
* Implements functions from PreferenceController that are flavor dependent.
|
* Implements functions from PreferenceController that are flavor dependent.
|
||||||
*/
|
*/
|
||||||
public class PreferenceControllerFlavorHelper {
|
class PreferenceControllerFlavorHelper {
|
||||||
|
|
||||||
static void setupFlavoredUI(PreferenceController.PreferenceUI ui) {
|
static void setupFlavoredUI(PreferenceController.PreferenceUI ui) {
|
||||||
ui.findPreference(UserPreferences.PREF_CAST_ENABLED).setEnabled(false);
|
ui.findPreference(UserPreferences.PREF_CAST_ENABLED).setEnabled(false);
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="de.danoeh.antennapod"
|
package="de.danoeh.antennapod"
|
||||||
android:installLocation="auto"
|
android:installLocation="auto"
|
||||||
android:versionCode="1060402"
|
android:versionCode="1070000"
|
||||||
android:versionName="1.6.4.2">
|
android:versionName="1.7.0">
|
||||||
<!--
|
<!--
|
||||||
Version code schema:
|
Version code schema:
|
||||||
"1.2.3-SNAPSHOT" -> 1020300
|
"1.2.3-SNAPSHOT" -> 1020300
|
||||||
@ -33,11 +33,12 @@
|
|||||||
|
|
||||||
<application
|
<application
|
||||||
android:name="de.danoeh.antennapod.PodcastApp"
|
android:name="de.danoeh.antennapod.PodcastApp"
|
||||||
android:icon="@drawable/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:backupAgent=".core.backup.OpmlBackupAgent"
|
android:backupAgent=".core.backup.OpmlBackupAgent"
|
||||||
android:restoreAnyVersion="true"
|
android:restoreAnyVersion="true"
|
||||||
android:logo="@drawable/ic_launcher">
|
android:logo="@mipmap/ic_launcher">
|
||||||
<meta-data android:name="com.google.android.gms.car.notification.SmallIcon"
|
<meta-data android:name="com.google.android.gms.car.notification.SmallIcon"
|
||||||
android:resource="@drawable/ic_notification" />
|
android:resource="@drawable/ic_notification" />
|
||||||
<meta-data
|
<meta-data
|
||||||
@ -96,15 +97,6 @@
|
|||||||
android:name=".activity.DownloadAuthenticationActivity"
|
android:name=".activity.DownloadAuthenticationActivity"
|
||||||
android:launchMode="singleInstance"/>
|
android:launchMode="singleInstance"/>
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".activity.PreferenceActivityGingerbread"
|
|
||||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
|
||||||
android:label="@string/settings_label">
|
|
||||||
<meta-data
|
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
|
||||||
android:value="de.danoeh.antennapod.activity.MainActivity"/>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".activity.PreferenceActivity"
|
android:name=".activity.PreferenceActivity"
|
||||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||||
@ -114,16 +106,25 @@
|
|||||||
android:value="de.danoeh.antennapod.activity.MainActivity"/>
|
android:value="de.danoeh.antennapod.activity.MainActivity"/>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity android:name=".activity.FeedInfoActivity">
|
<activity
|
||||||
|
android:name=".activity.FeedInfoActivity"
|
||||||
|
android:label="@string/feed_info_label">
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".activity.FeedSettingsActivity"
|
||||||
|
android:windowSoftInputMode="stateHidden"
|
||||||
|
android:label="@string/feed_settings_label">
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<service
|
<service
|
||||||
android:name=".service.PlayerWidgetService"
|
android:name=".core.service.PlayerWidgetJobService"
|
||||||
|
android:permission="android.permission.BIND_JOB_SERVICE"
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:exported="false">
|
android:exported="false">
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<receiver android:name=".receiver.PlayerWidget">
|
<receiver android:name=".core.receiver.PlayerWidget">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
|
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
@ -176,6 +177,13 @@
|
|||||||
android:name="android.support.PARENT_ACTIVITY"
|
android:name="android.support.PARENT_ACTIVITY"
|
||||||
android:value="de.danoeh.antennapod.activity.PreferenceActivity"/>
|
android:value="de.danoeh.antennapod.activity.PreferenceActivity"/>
|
||||||
</activity>
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name=".activity.ImportExportActivity"
|
||||||
|
android:label="@string/import_export">
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.PARENT_ACTIVITY"
|
||||||
|
android:value="de.danoeh.antennapod.activity.PreferenceActivity"/>
|
||||||
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".activity.OpmlImportFromPathActivity"
|
android:name=".activity.OpmlImportFromPathActivity"
|
||||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||||
@ -224,7 +232,8 @@
|
|||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".activity.VideoplayerActivity"
|
android:name=".activity.VideoplayerActivity"
|
||||||
android:configChanges="keyboardHidden|orientation"
|
android:configChanges="keyboardHidden|orientation|screenSize|screenLayout|smallestScreenSize"
|
||||||
|
android:supportsPictureInPicture="true"
|
||||||
android:screenOrientation="sensorLandscape">
|
android:screenOrientation="sensorLandscape">
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
android:name="android.support.PARENT_ACTIVITY"
|
||||||
|
91
app/src/main/assets/LICENSE_SIL.txt
Normal file
91
app/src/main/assets/LICENSE_SIL.txt
Normal file
@ -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.
|
Binary file not shown.
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 59 KiB |
@ -41,10 +41,8 @@ public class PodcastApp extends Application {
|
|||||||
.detectLeakedSqlLiteObjects()
|
.detectLeakedSqlLiteObjects()
|
||||||
.penaltyLog()
|
.penaltyLog()
|
||||||
.penaltyDropBox();
|
.penaltyDropBox();
|
||||||
if (Build.VERSION.SDK_INT >= 11) {
|
builder.detectActivityLeaks();
|
||||||
builder.detectActivityLeaks();
|
builder.detectLeakedClosableObjects();
|
||||||
builder.detectLeakedClosableObjects();
|
|
||||||
}
|
|
||||||
if(Build.VERSION.SDK_INT >= 16) {
|
if(Build.VERSION.SDK_INT >= 16) {
|
||||||
builder.detectLeakedRegistrationObjects();
|
builder.detectLeakedRegistrationObjects();
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,7 @@ import java.nio.charset.Charset;
|
|||||||
|
|
||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||||
import rx.Observable;
|
import rx.Single;
|
||||||
import rx.Subscriber;
|
|
||||||
import rx.Subscription;
|
import rx.Subscription;
|
||||||
import rx.android.schedulers.AndroidSchedulers;
|
import rx.android.schedulers.AndroidSchedulers;
|
||||||
import rx.schedulers.Schedulers;
|
import rx.schedulers.Schedulers;
|
||||||
@ -34,10 +33,8 @@ public class AboutActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
private static final String TAG = AboutActivity.class.getSimpleName();
|
private static final String TAG = AboutActivity.class.getSimpleName();
|
||||||
|
|
||||||
private WebView webview;
|
private WebView webView;
|
||||||
private LinearLayout webviewContainer;
|
private LinearLayout webViewContainer;
|
||||||
private int depth = 0;
|
|
||||||
|
|
||||||
private Subscription subscription;
|
private Subscription subscription;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -46,28 +43,25 @@ public class AboutActivity extends AppCompatActivity {
|
|||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
getSupportActionBar().setDisplayShowHomeEnabled(true);
|
getSupportActionBar().setDisplayShowHomeEnabled(true);
|
||||||
setContentView(R.layout.about);
|
setContentView(R.layout.about);
|
||||||
webviewContainer = (LinearLayout) findViewById(R.id.webvContainer);
|
webViewContainer = (LinearLayout) findViewById(R.id.webViewContainer);
|
||||||
webview = (WebView) findViewById(R.id.webvAbout);
|
webView = (WebView) findViewById(R.id.webViewAbout);
|
||||||
webview.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
|
webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
|
||||||
if (UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) {
|
if (UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) {
|
||||||
if (Build.VERSION.SDK_INT >= 11
|
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
|
||||||
&& Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
|
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
||||||
webview.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
|
||||||
}
|
}
|
||||||
webview.setBackgroundColor(Color.TRANSPARENT);
|
webView.setBackgroundColor(Color.TRANSPARENT);
|
||||||
}
|
}
|
||||||
webview.setWebViewClient(new WebViewClient() {
|
webView.setWebViewClient(new WebViewClient() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
||||||
if(url.startsWith("http")) {
|
if (!url.startsWith("http")) {
|
||||||
depth++;
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
url = url.replace("file:///android_asset/", "");
|
url = url.replace("file:///android_asset/", "");
|
||||||
loadAsset(url);
|
loadAsset(url);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -75,69 +69,65 @@ public class AboutActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void loadAsset(String filename) {
|
private void loadAsset(String filename) {
|
||||||
subscription = Observable.create(new Observable.OnSubscribe<String>() {
|
subscription = Single.create(subscriber -> {
|
||||||
@Override
|
InputStream input = null;
|
||||||
public void call(Subscriber<? super String> subscriber) {
|
try {
|
||||||
InputStream input = null;
|
TypedArray res = AboutActivity.this.getTheme().obtainStyledAttributes(
|
||||||
try {
|
new int[] { R.attr.about_screen_font_color, R.attr.about_screen_background,
|
||||||
TypedArray res = AboutActivity.this.getTheme().obtainStyledAttributes(
|
R.attr.about_screen_card_background, R.attr.about_screen_card_border});
|
||||||
new int[] { android.R.attr.textColorPrimary });
|
String fontColor = String.format("#%06X", 0xFFFFFF & res.getColor(0, 0));
|
||||||
int colorResource = res.getColor(0, 0);
|
String backgroundColor = String.format("#%06X", 0xFFFFFF & res.getColor(1, 0));
|
||||||
String colorString = String.format("#%06X", 0xFFFFFF & colorResource);
|
String cardBackground = String.format("#%06X", 0xFFFFFF & res.getColor(2, 0));
|
||||||
res.recycle();
|
String cardBorder = String.format("#%06X", 0xFFFFFF & res.getColor(3, 0));
|
||||||
input = getAssets().open(filename);
|
res.recycle();
|
||||||
String webViewData = IOUtils.toString(input, Charset.defaultCharset());
|
input = getAssets().open(filename);
|
||||||
if(!webViewData.startsWith("<!DOCTYPE html>")) {
|
String webViewData = IOUtils.toString(input, Charset.defaultCharset());
|
||||||
//webViewData = webViewData.replace("\n\n", "</p><p>");
|
if (!webViewData.startsWith("<!DOCTYPE html>")) {
|
||||||
webViewData = webViewData.replace("%", "%");
|
webViewData = webViewData.replace("%", "%");
|
||||||
webViewData =
|
webViewData =
|
||||||
"<!DOCTYPE html>" +
|
"<!DOCTYPE html>" +
|
||||||
"<html>" +
|
"<html>" +
|
||||||
"<head>" +
|
"<head>" +
|
||||||
" <meta http-equiv=\"Content-Type\" content=\"text/html;charset=UTF-8\">" +
|
" <meta http-equiv=\"Content-Type\" content=\"text/html;charset=UTF-8\">" +
|
||||||
" <style type=\"text/css\">" +
|
" <style type=\"text/css\">" +
|
||||||
" @font-face {" +
|
" @font-face {" +
|
||||||
" font-family: 'Roboto-Light';" +
|
" font-family: 'Roboto-Light';" +
|
||||||
" src: url('file:///android_asset/Roboto-Light.ttf');" +
|
" src: url('file:///android_asset/Roboto-Light.ttf');" +
|
||||||
" }" +
|
" }" +
|
||||||
" * {" +
|
" * {" +
|
||||||
" color: %s;" +
|
" color: @fontcolor@;" +
|
||||||
" font-family: roboto-Light;" +
|
" font-family: roboto-Light;" +
|
||||||
" font-size: 8pt;" +
|
" font-size: 8pt;" +
|
||||||
" }" +
|
" }" +
|
||||||
" </style>" +
|
" </style>" +
|
||||||
"</head><body><p>" + webViewData + "</p></body></html>";
|
"</head><body><p>" + webViewData + "</p></body></html>";
|
||||||
webViewData = webViewData.replace("\n", "<br/>");
|
webViewData = webViewData.replace("\n", "<br/>");
|
||||||
depth++;
|
}
|
||||||
} else {
|
webViewData = webViewData.replace("@fontcolor@", fontColor);
|
||||||
depth = 0;
|
webViewData = webViewData.replace("@background@", backgroundColor);
|
||||||
}
|
webViewData = webViewData.replace("@card_background@", cardBackground);
|
||||||
webViewData = String.format(webViewData, colorString);
|
webViewData = webViewData.replace("@card_border@", cardBorder);
|
||||||
subscriber.onNext(webViewData);
|
subscriber.onSuccess(webViewData);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
subscriber.onError(e);
|
Log.e(TAG, Log.getStackTraceString(e));
|
||||||
} finally {
|
subscriber.onError(e);
|
||||||
IOUtils.closeQuietly(input);
|
} finally {
|
||||||
}
|
IOUtils.closeQuietly(input);
|
||||||
subscriber.onCompleted();
|
}
|
||||||
}
|
})
|
||||||
})
|
|
||||||
.subscribeOn(Schedulers.newThread())
|
.subscribeOn(Schedulers.newThread())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(
|
.subscribe(
|
||||||
webviewData ->
|
webViewData ->
|
||||||
webview.loadDataWithBaseURL("file:///android_asset/", webviewData, "text/html", "utf-8", "about:blank"),
|
webView.loadDataWithBaseURL("file:///android_asset/", webViewData.toString(), "text/html", "utf-8", "file:///android_asset/" + filename.toString()),
|
||||||
error -> Log.e(TAG, Log.getStackTraceString(error))
|
error -> Log.e(TAG, Log.getStackTraceString(error))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
Log.d(TAG, "depth: " + depth);
|
if (webView.canGoBack()) {
|
||||||
if(depth == 1) {
|
webView.goBack();
|
||||||
loadAsset("about.html");
|
|
||||||
} else if(depth > 1) {
|
|
||||||
webview.goBack();
|
|
||||||
} else {
|
} else {
|
||||||
super.onBackPressed();
|
super.onBackPressed();
|
||||||
}
|
}
|
||||||
@ -159,9 +149,9 @@ public class AboutActivity extends AppCompatActivity {
|
|||||||
if(subscription != null) {
|
if(subscription != null) {
|
||||||
subscription.unsubscribe();
|
subscription.unsubscribe();
|
||||||
}
|
}
|
||||||
if (webviewContainer != null && webview != null) {
|
if (webViewContainer != null && webView != null) {
|
||||||
webviewContainer.removeAllViews();
|
webViewContainer.removeAllViews();
|
||||||
webview.destroy();
|
webView.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,41 +6,31 @@ import android.text.TextUtils;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import de.danoeh.antennapod.core.feed.MediaType;
|
import de.danoeh.antennapod.core.feed.MediaType;
|
||||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||||
import de.danoeh.antennapod.core.service.playback.PlaybackService;
|
import de.danoeh.antennapod.core.service.playback.PlaybackService;
|
||||||
import de.danoeh.antennapod.core.util.playback.ExternalMedia;
|
|
||||||
import de.danoeh.antennapod.dialog.VariableSpeedDialog;
|
import de.danoeh.antennapod.dialog.VariableSpeedDialog;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activity for playing audio files.
|
* Activity for playing audio files.
|
||||||
*/
|
*/
|
||||||
public class AudioplayerActivity extends MediaplayerInfoActivity {
|
public class AudioplayerActivity extends MediaplayerInfoActivity {
|
||||||
public static final String TAG = "AudioPlayerActivity";
|
private static final String TAG = "AudioPlayerActivity";
|
||||||
|
|
||||||
private AtomicBoolean isSetup = new AtomicBoolean(false);
|
private final AtomicBoolean isSetup = new AtomicBoolean(false);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
if (TextUtils.equals(getIntent().getAction(), Intent.ACTION_VIEW)) {
|
if (TextUtils.equals(getIntent().getAction(), Intent.ACTION_VIEW)) {
|
||||||
Intent intent = getIntent();
|
playExternalMedia(getIntent(), MediaType.AUDIO);
|
||||||
Log.d(TAG, "Received VIEW intent: " + intent.getData().getPath());
|
|
||||||
ExternalMedia media = new ExternalMedia(intent.getData().getPath(),
|
|
||||||
MediaType.AUDIO);
|
|
||||||
Intent launchIntent = new Intent(this, PlaybackService.class);
|
|
||||||
launchIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, media);
|
|
||||||
launchIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED,
|
|
||||||
true);
|
|
||||||
launchIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM, false);
|
|
||||||
launchIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY,
|
|
||||||
true);
|
|
||||||
startService(launchIntent);
|
|
||||||
} else if (PlaybackService.isCasting()) {
|
} else if (PlaybackService.isCasting()) {
|
||||||
Intent intent = PlaybackService.getPlayerActivityIntent(this);
|
Intent intent = PlaybackService.getPlayerActivityIntent(this);
|
||||||
if (!intent.getComponent().getClassName().equals(AudioplayerActivity.class.getName())) {
|
if (intent.getComponent() != null &&
|
||||||
|
!intent.getComponent().getClassName().equals(AudioplayerActivity.class.getName())) {
|
||||||
saveCurrentFragment();
|
saveCurrentFragment();
|
||||||
finish();
|
finish();
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
@ -95,7 +85,7 @@ public class AudioplayerActivity extends MediaplayerInfoActivity {
|
|||||||
UserPreferences.setPlaybackSpeed(String.valueOf(speed));
|
UserPreferences.setPlaybackSpeed(String.valueOf(speed));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String speedStr = String.format("%.2fx", speed);
|
String speedStr = new DecimalFormat("0.00x").format(speed);
|
||||||
butPlaybackSpeed.setText(speedStr);
|
butPlaybackSpeed.setText(speedStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,9 +13,9 @@ import de.danoeh.antennapod.core.service.playback.PlaybackService;
|
|||||||
* Activity for controlling the remote playback on a Cast device.
|
* Activity for controlling the remote playback on a Cast device.
|
||||||
*/
|
*/
|
||||||
public class CastplayerActivity extends MediaplayerInfoActivity {
|
public class CastplayerActivity extends MediaplayerInfoActivity {
|
||||||
public static final String TAG = "CastPlayerActivity";
|
private static final String TAG = "CastPlayerActivity";
|
||||||
|
|
||||||
private AtomicBoolean isSetup = new AtomicBoolean(false);
|
private final AtomicBoolean isSetup = new AtomicBoolean(false);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
@ -3,15 +3,14 @@ package de.danoeh.antennapod.activity;
|
|||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v7.app.ActionBarActivity;
|
import android.support.v7.app.ActionBar;
|
||||||
import android.util.Log;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
|
|
||||||
import de.danoeh.antennapod.BuildConfig;
|
|
||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||||
import de.danoeh.antennapod.core.service.download.DownloadRequest;
|
import de.danoeh.antennapod.core.service.download.DownloadRequest;
|
||||||
@ -23,8 +22,7 @@ import de.danoeh.antennapod.core.storage.DownloadRequester;
|
|||||||
* Other arguments are optional.
|
* Other arguments are optional.
|
||||||
* The activity's result will be the same DownloadRequest with the entered username and password.
|
* The activity's result will be the same DownloadRequest with the entered username and password.
|
||||||
*/
|
*/
|
||||||
public class DownloadAuthenticationActivity extends ActionBarActivity {
|
public class DownloadAuthenticationActivity extends AppCompatActivity {
|
||||||
private static final String TAG = "DownloadAuthenticationActivity";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The download request object that contains information about the resource that requires a username and a password
|
* The download request object that contains information about the resource that requires a username and a password
|
||||||
@ -36,47 +34,39 @@ public class DownloadAuthenticationActivity extends ActionBarActivity {
|
|||||||
*/
|
*/
|
||||||
public static final String ARG_SEND_TO_DOWNLOAD_REQUESTER_BOOL = "send_to_downloadrequester";
|
public static final String ARG_SEND_TO_DOWNLOAD_REQUESTER_BOOL = "send_to_downloadrequester";
|
||||||
|
|
||||||
public static final String RESULT_REQUEST = "request";
|
private static final String RESULT_REQUEST = "request";
|
||||||
|
|
||||||
private EditText etxtUsername;
|
private EditText etxtUsername;
|
||||||
private EditText etxtPassword;
|
private EditText etxtPassword;
|
||||||
private Button butConfirm;
|
|
||||||
private Button butCancel;
|
|
||||||
private TextView txtvDescription;
|
|
||||||
|
|
||||||
private DownloadRequest request;
|
|
||||||
private boolean sendToDownloadRequester;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
setTheme(UserPreferences.getTheme());
|
setTheme(UserPreferences.getTheme());
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
getSupportActionBar().hide();
|
ActionBar actionBar = getSupportActionBar();
|
||||||
setContentView(R.layout.download_authentication_activity);
|
if (actionBar != null) {
|
||||||
|
actionBar.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
setContentView(R.layout.download_authentication_activity);
|
||||||
|
TextView txtvDescription = (TextView) findViewById(R.id.txtvDescription);
|
||||||
etxtUsername = (EditText) findViewById(R.id.etxtUsername);
|
etxtUsername = (EditText) findViewById(R.id.etxtUsername);
|
||||||
etxtPassword = (EditText) findViewById(R.id.etxtPassword);
|
etxtPassword = (EditText) findViewById(R.id.etxtPassword);
|
||||||
butConfirm = (Button) findViewById(R.id.butConfirm);
|
Button butConfirm = (Button) findViewById(R.id.butConfirm);
|
||||||
butCancel = (Button) findViewById(R.id.butCancel);
|
Button butCancel = (Button) findViewById(R.id.butCancel);
|
||||||
txtvDescription = (TextView) findViewById(R.id.txtvDescription);
|
|
||||||
|
|
||||||
Validate.isTrue(getIntent().hasExtra(ARG_DOWNLOAD_REQUEST), "Download request missing");
|
Validate.isTrue(getIntent().hasExtra(ARG_DOWNLOAD_REQUEST), "Download request missing");
|
||||||
|
DownloadRequest request = getIntent().getParcelableExtra(ARG_DOWNLOAD_REQUEST);
|
||||||
|
boolean sendToDownloadRequester = getIntent().getBooleanExtra(ARG_SEND_TO_DOWNLOAD_REQUESTER_BOOL, false);
|
||||||
|
|
||||||
request = getIntent().getParcelableExtra(ARG_DOWNLOAD_REQUEST);
|
String newDescription = txtvDescription.getText() + ":\n\n" + request.getTitle();
|
||||||
sendToDownloadRequester = getIntent().getBooleanExtra(ARG_SEND_TO_DOWNLOAD_REQUESTER_BOOL, false);
|
txtvDescription.setText(newDescription);
|
||||||
|
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
etxtUsername.setText(savedInstanceState.getString("username"));
|
etxtUsername.setText(savedInstanceState.getString("username"));
|
||||||
etxtPassword.setText(savedInstanceState.getString("password"));
|
etxtPassword.setText(savedInstanceState.getString("password"));
|
||||||
}
|
}
|
||||||
|
|
||||||
txtvDescription.setText(txtvDescription.getText() + ":\n\n" + request.getTitle());
|
|
||||||
|
|
||||||
butCancel.setOnClickListener(v -> {
|
|
||||||
setResult(Activity.RESULT_CANCELED);
|
|
||||||
finish();
|
|
||||||
});
|
|
||||||
|
|
||||||
butConfirm.setOnClickListener(v -> {
|
butConfirm.setOnClickListener(v -> {
|
||||||
String username = etxtUsername.getText().toString();
|
String username = etxtUsername.getText().toString();
|
||||||
String password = etxtPassword.getText().toString();
|
String password = etxtPassword.getText().toString();
|
||||||
@ -87,11 +77,16 @@ public class DownloadAuthenticationActivity extends ActionBarActivity {
|
|||||||
setResult(Activity.RESULT_OK, result);
|
setResult(Activity.RESULT_OK, result);
|
||||||
|
|
||||||
if (sendToDownloadRequester) {
|
if (sendToDownloadRequester) {
|
||||||
if (BuildConfig.DEBUG) Log.d(TAG, "Sending request to DownloadRequester");
|
|
||||||
DownloadRequester.getInstance().download(DownloadAuthenticationActivity.this, request);
|
DownloadRequester.getInstance().download(DownloadAuthenticationActivity.this, request);
|
||||||
}
|
}
|
||||||
finish();
|
finish();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
butCancel.setOnClickListener(v -> {
|
||||||
|
setResult(Activity.RESULT_CANCELED);
|
||||||
|
finish();
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -2,51 +2,37 @@ package de.danoeh.antennapod.activity;
|
|||||||
|
|
||||||
import android.content.ClipData;
|
import android.content.ClipData;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.graphics.LightingColorFilter;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.text.Editable;
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.TextWatcher;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.AdapterView;
|
|
||||||
import android.widget.AdapterView.OnItemSelectedListener;
|
|
||||||
import android.widget.CheckBox;
|
|
||||||
import android.widget.EditText;
|
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.RadioButton;
|
|
||||||
import android.widget.Spinner;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
import com.bumptech.glide.Glide;
|
||||||
import com.joanzapata.iconify.Iconify;
|
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.R;
|
||||||
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
|
|
||||||
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
|
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
|
||||||
import de.danoeh.antennapod.core.feed.Feed;
|
import de.danoeh.antennapod.core.feed.Feed;
|
||||||
import de.danoeh.antennapod.core.feed.FeedFilter;
|
|
||||||
import de.danoeh.antennapod.core.feed.FeedPreferences;
|
|
||||||
import de.danoeh.antennapod.core.glide.ApGlideSettings;
|
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.preferences.UserPreferences;
|
||||||
import de.danoeh.antennapod.core.storage.DBReader;
|
import de.danoeh.antennapod.core.storage.DBReader;
|
||||||
import de.danoeh.antennapod.core.storage.DBWriter;
|
|
||||||
import de.danoeh.antennapod.core.storage.DownloadRequestException;
|
import de.danoeh.antennapod.core.storage.DownloadRequestException;
|
||||||
import de.danoeh.antennapod.core.util.IntentUtils;
|
import de.danoeh.antennapod.core.util.IntentUtils;
|
||||||
import de.danoeh.antennapod.core.util.LangUtils;
|
import de.danoeh.antennapod.core.util.LangUtils;
|
||||||
import de.danoeh.antennapod.core.util.syndication.HtmlToPlainText;
|
import de.danoeh.antennapod.core.util.syndication.HtmlToPlainText;
|
||||||
import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
|
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.Observable;
|
||||||
import rx.Subscription;
|
import rx.Subscription;
|
||||||
import rx.android.schedulers.AndroidSchedulers;
|
import rx.android.schedulers.AndroidSchedulers;
|
||||||
@ -59,7 +45,6 @@ public class FeedInfoActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
public static final String EXTRA_FEED_ID = "de.danoeh.antennapod.extra.feedId";
|
public static final String EXTRA_FEED_ID = "de.danoeh.antennapod.extra.feedId";
|
||||||
private static final String TAG = "FeedInfoActivity";
|
private static final String TAG = "FeedInfoActivity";
|
||||||
private boolean autoDeleteChanged = false;
|
|
||||||
private Feed feed;
|
private Feed feed;
|
||||||
|
|
||||||
private ImageView imgvCover;
|
private ImageView imgvCover;
|
||||||
@ -70,15 +55,6 @@ public class FeedInfoActivity extends AppCompatActivity {
|
|||||||
private TextView lblAuthor;
|
private TextView lblAuthor;
|
||||||
private TextView txtvAuthor;
|
private TextView txtvAuthor;
|
||||||
private TextView txtvUrl;
|
private TextView txtvUrl;
|
||||||
private EditText etxtUsername;
|
|
||||||
private EditText etxtPassword;
|
|
||||||
private EditText etxtFilterText;
|
|
||||||
private RadioButton rdoFilterInclude;
|
|
||||||
private RadioButton rdoFilterExclude;
|
|
||||||
private CheckBox cbxAutoDownload;
|
|
||||||
private CheckBox cbxKeepUpdated;
|
|
||||||
private Spinner spnAutoDelete;
|
|
||||||
private boolean filterInclude = true;
|
|
||||||
|
|
||||||
private Subscription subscription;
|
private Subscription subscription;
|
||||||
|
|
||||||
@ -88,56 +64,16 @@ public class FeedInfoActivity extends AppCompatActivity {
|
|||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
if(feed != null && feed.getDownload_url() != null) {
|
if(feed != null && feed.getDownload_url() != null) {
|
||||||
String url = feed.getDownload_url();
|
String url = feed.getDownload_url();
|
||||||
if (android.os.Build.VERSION.SDK_INT >= 11) {
|
ClipData clipData = ClipData.newPlainText(url, url);
|
||||||
ClipData clipData = ClipData.newPlainText(url, url);
|
android.content.ClipboardManager cm = (android.content.ClipboardManager) FeedInfoActivity.this
|
||||||
android.content.ClipboardManager cm = (android.content.ClipboardManager) FeedInfoActivity.this
|
.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||||
.getSystemService(Context.CLIPBOARD_SERVICE);
|
cm.setPrimaryClip(clipData);
|
||||||
cm.setPrimaryClip(clipData);
|
|
||||||
} else {
|
|
||||||
android.text.ClipboardManager cm = (android.text.ClipboardManager) FeedInfoActivity.this
|
|
||||||
.getSystemService(Context.CLIPBOARD_SERVICE);
|
|
||||||
cm.setText(url);
|
|
||||||
}
|
|
||||||
Toast t = Toast.makeText(FeedInfoActivity.this, R.string.copied_url_msg, Toast.LENGTH_SHORT);
|
Toast t = Toast.makeText(FeedInfoActivity.this, R.string.copied_url_msg, Toast.LENGTH_SHORT);
|
||||||
t.show();
|
t.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private boolean authInfoChanged = false;
|
|
||||||
|
|
||||||
private TextWatcher authTextWatcher = new TextWatcher() {
|
|
||||||
@Override
|
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterTextChanged(Editable s) {
|
|
||||||
authInfoChanged = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private boolean filterTextChanged = false;
|
|
||||||
|
|
||||||
private TextWatcher filterTextWatcher = new TextWatcher() {
|
|
||||||
@Override
|
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterTextChanged(Editable s) {
|
|
||||||
filterTextChanged = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
setTheme(UserPreferences.getTheme());
|
setTheme(UserPreferences.getTheme());
|
||||||
@ -148,28 +84,20 @@ public class FeedInfoActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
imgvCover = (ImageView) findViewById(R.id.imgvCover);
|
imgvCover = (ImageView) findViewById(R.id.imgvCover);
|
||||||
txtvTitle = (TextView) findViewById(R.id.txtvTitle);
|
txtvTitle = (TextView) findViewById(R.id.txtvTitle);
|
||||||
|
TextView txtvAuthorHeader = (TextView) findViewById(R.id.txtvAuthor);
|
||||||
|
ImageView imgvBackground = (ImageView) 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);
|
txtvDescription = (TextView) findViewById(R.id.txtvDescription);
|
||||||
lblLanguage = (TextView) findViewById(R.id.lblLanguage);
|
lblLanguage = (TextView) findViewById(R.id.lblLanguage);
|
||||||
txtvLanguage = (TextView) findViewById(R.id.txtvLanguage);
|
txtvLanguage = (TextView) findViewById(R.id.txtvLanguage);
|
||||||
lblAuthor = (TextView) findViewById(R.id.lblAuthor);
|
lblAuthor = (TextView) findViewById(R.id.lblAuthor);
|
||||||
txtvAuthor = (TextView) findViewById(R.id.txtvAuthor);
|
txtvAuthor = (TextView) findViewById(R.id.txtvDetailsAuthor);
|
||||||
txtvUrl = (TextView) findViewById(R.id.txtvUrl);
|
txtvUrl = (TextView) findViewById(R.id.txtvUrl);
|
||||||
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);
|
|
||||||
rdoFilterInclude.setOnClickListener(v -> {
|
|
||||||
filterInclude = true;
|
|
||||||
filterTextChanged = true;
|
|
||||||
});
|
|
||||||
rdoFilterExclude = (RadioButton) findViewById(R.id.radio_filter_exclude);
|
|
||||||
rdoFilterExclude.setOnClickListener(v -> {
|
|
||||||
filterInclude = false;
|
|
||||||
filterTextChanged = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
txtvUrl.setOnClickListener(copyUrlToClipboard);
|
txtvUrl.setOnClickListener(copyUrlToClipboard);
|
||||||
|
|
||||||
@ -185,7 +113,6 @@ public class FeedInfoActivity extends AppCompatActivity {
|
|||||||
Log.d(TAG, "Language is " + feed.getLanguage());
|
Log.d(TAG, "Language is " + feed.getLanguage());
|
||||||
Log.d(TAG, "Author is " + feed.getAuthor());
|
Log.d(TAG, "Author is " + feed.getAuthor());
|
||||||
Log.d(TAG, "URL is " + feed.getDownload_url());
|
Log.d(TAG, "URL is " + feed.getDownload_url());
|
||||||
FeedPreferences prefs = feed.getPreferences();
|
|
||||||
Glide.with(FeedInfoActivity.this)
|
Glide.with(FeedInfoActivity.this)
|
||||||
.load(feed.getImageLocation())
|
.load(feed.getImageLocation())
|
||||||
.placeholder(R.color.light_gray)
|
.placeholder(R.color.light_gray)
|
||||||
@ -194,6 +121,14 @@ public class FeedInfoActivity extends AppCompatActivity {
|
|||||||
.fitCenter()
|
.fitCenter()
|
||||||
.dontAnimate()
|
.dontAnimate()
|
||||||
.into(imgvCover);
|
.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()
|
||||||
|
.into(imgvBackground);
|
||||||
|
|
||||||
txtvTitle.setText(feed.getTitle());
|
txtvTitle.setText(feed.getTitle());
|
||||||
|
|
||||||
@ -211,6 +146,7 @@ public class FeedInfoActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
if (!TextUtils.isEmpty(feed.getAuthor())) {
|
if (!TextUtils.isEmpty(feed.getAuthor())) {
|
||||||
txtvAuthor.setText(feed.getAuthor());
|
txtvAuthor.setText(feed.getAuthor());
|
||||||
|
txtvAuthorHeader.setText(feed.getAuthor());
|
||||||
} else {
|
} else {
|
||||||
lblAuthor.setVisibility(View.GONE);
|
lblAuthor.setVisibility(View.GONE);
|
||||||
txtvAuthor.setVisibility(View.GONE);
|
txtvAuthor.setVisibility(View.GONE);
|
||||||
@ -224,113 +160,13 @@ public class FeedInfoActivity extends AppCompatActivity {
|
|||||||
txtvUrl.setText(feed.getDownload_url() + " {fa-paperclip}");
|
txtvUrl.setText(feed.getDownload_url() + " {fa-paperclip}");
|
||||||
Iconify.addIcons(txtvUrl);
|
Iconify.addIcons(txtvUrl);
|
||||||
|
|
||||||
cbxAutoDownload.setEnabled(UserPreferences.isEnableAutodownload());
|
|
||||||
cbxAutoDownload.setChecked(prefs.getAutoDownload());
|
|
||||||
cbxAutoDownload.setOnCheckedChangeListener((compoundButton, checked) -> {
|
|
||||||
feed.getPreferences().setAutoDownload(checked);
|
|
||||||
feed.savePreferences();
|
|
||||||
updateAutoDownloadSettings();
|
|
||||||
ApplyToEpisodesDialog dialog = new ApplyToEpisodesDialog(FeedInfoActivity.this,
|
|
||||||
feed, checked);
|
|
||||||
dialog.createNewDialog().show();
|
|
||||||
});
|
|
||||||
cbxKeepUpdated.setChecked(prefs.getKeepUpdated());
|
|
||||||
cbxKeepUpdated.setOnCheckedChangeListener((compoundButton, checked) -> {
|
|
||||||
feed.getPreferences().setKeepUpdated(checked);
|
|
||||||
feed.savePreferences();
|
|
||||||
});
|
|
||||||
spnAutoDelete.setOnItemSelectedListener(new OnItemSelectedListener() {
|
|
||||||
@Override
|
|
||||||
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
|
|
||||||
FeedPreferences.AutoDeleteAction auto_delete_action;
|
|
||||||
switch (parent.getSelectedItemPosition()) {
|
|
||||||
case 0:
|
|
||||||
auto_delete_action = FeedPreferences.AutoDeleteAction.GLOBAL;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
auto_delete_action = FeedPreferences.AutoDeleteAction.YES;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
auto_delete_action = FeedPreferences.AutoDeleteAction.NO;
|
|
||||||
break;
|
|
||||||
default: // TODO - add exceptions here
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
feed.getPreferences().setAutoDeleteAction(auto_delete_action);// p
|
|
||||||
autoDeleteChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNothingSelected(AdapterView<?> parent) {
|
|
||||||
// Another interface callback
|
|
||||||
}
|
|
||||||
});
|
|
||||||
spnAutoDelete.setSelection(prefs.getAutoDeleteAction().ordinal());
|
|
||||||
|
|
||||||
etxtUsername.setText(prefs.getUsername());
|
|
||||||
etxtPassword.setText(prefs.getPassword());
|
|
||||||
|
|
||||||
etxtUsername.addTextChangedListener(authTextWatcher);
|
|
||||||
etxtPassword.addTextChangedListener(authTextWatcher);
|
|
||||||
|
|
||||||
FeedFilter filter = prefs.getFilter();
|
|
||||||
if (filter.includeOnly()) {
|
|
||||||
etxtFilterText.setText(filter.getIncludeFilter());
|
|
||||||
rdoFilterInclude.setChecked(true);
|
|
||||||
rdoFilterExclude.setChecked(false);
|
|
||||||
filterInclude = true;
|
|
||||||
} else if (filter.excludeOnly()) {
|
|
||||||
etxtFilterText.setText(filter.getExcludeFilter());
|
|
||||||
rdoFilterInclude.setChecked(false);
|
|
||||||
rdoFilterExclude.setChecked(true);
|
|
||||||
filterInclude = false;
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "No filter set");
|
|
||||||
rdoFilterInclude.setChecked(false);
|
|
||||||
rdoFilterExclude.setChecked(false);
|
|
||||||
etxtFilterText.setText("");
|
|
||||||
}
|
|
||||||
etxtFilterText.addTextChangedListener(filterTextWatcher);
|
|
||||||
|
|
||||||
supportInvalidateOptionsMenu();
|
supportInvalidateOptionsMenu();
|
||||||
updateAutoDownloadSettings();
|
|
||||||
}, error -> {
|
}, error -> {
|
||||||
Log.d(TAG, Log.getStackTraceString(error));
|
Log.d(TAG, Log.getStackTraceString(error));
|
||||||
finish();
|
finish();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPause() {
|
|
||||||
super.onPause();
|
|
||||||
if (feed != null) {
|
|
||||||
FeedPreferences prefs = feed.getPreferences();
|
|
||||||
if (authInfoChanged) {
|
|
||||||
Log.d(TAG, "Auth info changed, saving credentials");
|
|
||||||
prefs.setUsername(etxtUsername.getText().toString());
|
|
||||||
prefs.setPassword(etxtPassword.getText().toString());
|
|
||||||
}
|
|
||||||
if (filterTextChanged) {
|
|
||||||
Log.d(TAG, "Filter info changed, saving...");
|
|
||||||
String filterText = etxtFilterText.getText().toString();
|
|
||||||
String includeString = "";
|
|
||||||
String excludeString = "";
|
|
||||||
if (filterInclude) {
|
|
||||||
includeString = filterText;
|
|
||||||
} else {
|
|
||||||
excludeString = filterText;
|
|
||||||
}
|
|
||||||
prefs.setFilter(new FeedFilter(includeString, excludeString));
|
|
||||||
}
|
|
||||||
if (authInfoChanged || autoDeleteChanged || filterTextChanged) {
|
|
||||||
DBWriter.setFeedPreferences(prefs);
|
|
||||||
}
|
|
||||||
authInfoChanged = false;
|
|
||||||
autoDeleteChanged = false;
|
|
||||||
filterTextChanged = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
@ -375,34 +211,4 @@ public class FeedInfoActivity extends AppCompatActivity {
|
|||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateAutoDownloadSettings() {
|
|
||||||
if (feed != null && feed.getPreferences() != null) {
|
|
||||||
boolean enabled = feed.getPreferences().getAutoDownload() && UserPreferences.isEnableAutodownload();
|
|
||||||
rdoFilterInclude.setEnabled(enabled);
|
|
||||||
rdoFilterExclude.setEnabled(enabled);
|
|
||||||
etxtFilterText.setEnabled(enabled);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ApplyToEpisodesDialog extends ConfirmationDialog {
|
|
||||||
|
|
||||||
private final Feed feed;
|
|
||||||
private final boolean autoDownload;
|
|
||||||
|
|
||||||
ApplyToEpisodesDialog(Context context, Feed feed, boolean autoDownload) {
|
|
||||||
super(context, R.string.auto_download_apply_to_items_title,
|
|
||||||
R.string.auto_download_apply_to_items_message);
|
|
||||||
this.feed = feed;
|
|
||||||
this.autoDownload = autoDownload;
|
|
||||||
setPositiveText(R.string.yes);
|
|
||||||
setNegativeText(R.string.no);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onConfirmButtonPressed(DialogInterface dialog) {
|
|
||||||
DBWriter.setFeedsItemsAutoDownload(feed, autoDownload);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,370 @@
|
|||||||
|
package de.danoeh.antennapod.activity;
|
||||||
|
|
||||||
|
import android.content.ClipData;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.graphics.LightingColorFilter;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.text.TextWatcher;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.AdapterView.OnItemSelectedListener;
|
||||||
|
import android.widget.CheckBox;
|
||||||
|
import android.widget.EditText;
|
||||||
|
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 de.danoeh.antennapod.R;
|
||||||
|
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
|
||||||
|
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
|
||||||
|
import de.danoeh.antennapod.core.feed.Feed;
|
||||||
|
import de.danoeh.antennapod.core.feed.FeedFilter;
|
||||||
|
import de.danoeh.antennapod.core.feed.FeedPreferences;
|
||||||
|
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.storage.DBReader;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays information about a feed.
|
||||||
|
*/
|
||||||
|
public class FeedSettingsActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
public static final String EXTRA_FEED_ID = "de.danoeh.antennapod.extra.feedId";
|
||||||
|
private static final String TAG = "FeedSettingsActivity";
|
||||||
|
private boolean autoDeleteChanged = false;
|
||||||
|
private Feed feed;
|
||||||
|
|
||||||
|
private ImageView imgvCover;
|
||||||
|
private TextView txtvTitle;
|
||||||
|
private EditText etxtUsername;
|
||||||
|
private EditText etxtPassword;
|
||||||
|
private EditText etxtFilterText;
|
||||||
|
private RadioButton rdoFilterInclude;
|
||||||
|
private RadioButton rdoFilterExclude;
|
||||||
|
private CheckBox cbxAutoDownload;
|
||||||
|
private CheckBox cbxKeepUpdated;
|
||||||
|
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 boolean authInfoChanged = false;
|
||||||
|
|
||||||
|
private final TextWatcher authTextWatcher = new TextWatcher() {
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
authInfoChanged = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private boolean filterTextChanged = false;
|
||||||
|
|
||||||
|
private final TextWatcher filterTextWatcher = new TextWatcher() {
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
filterTextChanged = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
setTheme(UserPreferences.getTheme());
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.feedsettings);
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
rdoFilterInclude.setOnClickListener(v -> {
|
||||||
|
filterInclude = true;
|
||||||
|
filterTextChanged = true;
|
||||||
|
});
|
||||||
|
rdoFilterExclude = (RadioButton) findViewById(R.id.radio_filter_exclude);
|
||||||
|
rdoFilterExclude.setOnClickListener(v -> {
|
||||||
|
filterInclude = false;
|
||||||
|
filterTextChanged = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
subscription = Observable.fromCallable(()-> DBReader.getFeed(feedId))
|
||||||
|
.subscribeOn(Schedulers.newThread())
|
||||||
|
.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()
|
||||||
|
.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()
|
||||||
|
.into(imgvBackground);
|
||||||
|
|
||||||
|
txtvTitle.setText(feed.getTitle());
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(feed.getAuthor())) {
|
||||||
|
txtvAuthorHeader.setText(feed.getAuthor());
|
||||||
|
}
|
||||||
|
|
||||||
|
cbxAutoDownload.setEnabled(UserPreferences.isEnableAutodownload());
|
||||||
|
cbxAutoDownload.setChecked(prefs.getAutoDownload());
|
||||||
|
cbxAutoDownload.setOnCheckedChangeListener((compoundButton, checked) -> {
|
||||||
|
feed.getPreferences().setAutoDownload(checked);
|
||||||
|
feed.savePreferences();
|
||||||
|
updateAutoDownloadSettings();
|
||||||
|
ApplyToEpisodesDialog dialog = new ApplyToEpisodesDialog(FeedSettingsActivity.this,
|
||||||
|
feed, checked);
|
||||||
|
dialog.createNewDialog().show();
|
||||||
|
});
|
||||||
|
cbxKeepUpdated.setChecked(prefs.getKeepUpdated());
|
||||||
|
cbxKeepUpdated.setOnCheckedChangeListener((compoundButton, checked) -> {
|
||||||
|
feed.getPreferences().setKeepUpdated(checked);
|
||||||
|
feed.savePreferences();
|
||||||
|
});
|
||||||
|
spnAutoDelete.setOnItemSelectedListener(new OnItemSelectedListener() {
|
||||||
|
@Override
|
||||||
|
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
|
||||||
|
FeedPreferences.AutoDeleteAction auto_delete_action;
|
||||||
|
switch (parent.getSelectedItemPosition()) {
|
||||||
|
case 0:
|
||||||
|
auto_delete_action = FeedPreferences.AutoDeleteAction.GLOBAL;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
auto_delete_action = FeedPreferences.AutoDeleteAction.YES;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
auto_delete_action = FeedPreferences.AutoDeleteAction.NO;
|
||||||
|
break;
|
||||||
|
default: // TODO - add exceptions here
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
feed.getPreferences().setAutoDeleteAction(auto_delete_action);// p
|
||||||
|
autoDeleteChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNothingSelected(AdapterView<?> parent) {
|
||||||
|
// Another interface callback
|
||||||
|
}
|
||||||
|
});
|
||||||
|
spnAutoDelete.setSelection(prefs.getAutoDeleteAction().ordinal());
|
||||||
|
|
||||||
|
etxtUsername.setText(prefs.getUsername());
|
||||||
|
etxtPassword.setText(prefs.getPassword());
|
||||||
|
|
||||||
|
etxtUsername.addTextChangedListener(authTextWatcher);
|
||||||
|
etxtPassword.addTextChangedListener(authTextWatcher);
|
||||||
|
|
||||||
|
FeedFilter filter = prefs.getFilter();
|
||||||
|
if (filter.includeOnly()) {
|
||||||
|
etxtFilterText.setText(filter.getIncludeFilter());
|
||||||
|
rdoFilterInclude.setChecked(true);
|
||||||
|
rdoFilterExclude.setChecked(false);
|
||||||
|
filterInclude = true;
|
||||||
|
} else if (filter.excludeOnly()) {
|
||||||
|
etxtFilterText.setText(filter.getExcludeFilter());
|
||||||
|
rdoFilterInclude.setChecked(false);
|
||||||
|
rdoFilterExclude.setChecked(true);
|
||||||
|
filterInclude = false;
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "No filter set");
|
||||||
|
rdoFilterInclude.setChecked(false);
|
||||||
|
rdoFilterExclude.setChecked(false);
|
||||||
|
etxtFilterText.setText("");
|
||||||
|
}
|
||||||
|
etxtFilterText.addTextChangedListener(filterTextWatcher);
|
||||||
|
|
||||||
|
supportInvalidateOptionsMenu();
|
||||||
|
updateAutoDownloadSettings();
|
||||||
|
}, error -> {
|
||||||
|
Log.d(TAG, Log.getStackTraceString(error));
|
||||||
|
finish();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
if (feed != null) {
|
||||||
|
FeedPreferences prefs = feed.getPreferences();
|
||||||
|
if (authInfoChanged) {
|
||||||
|
Log.d(TAG, "Auth info changed, saving credentials");
|
||||||
|
prefs.setUsername(etxtUsername.getText().toString());
|
||||||
|
prefs.setPassword(etxtPassword.getText().toString());
|
||||||
|
}
|
||||||
|
if (filterTextChanged) {
|
||||||
|
Log.d(TAG, "Filter info changed, saving...");
|
||||||
|
String filterText = etxtFilterText.getText().toString();
|
||||||
|
String includeString = "";
|
||||||
|
String excludeString = "";
|
||||||
|
if (filterInclude) {
|
||||||
|
includeString = filterText;
|
||||||
|
} else {
|
||||||
|
excludeString = filterText;
|
||||||
|
}
|
||||||
|
prefs.setFilter(new FeedFilter(includeString, excludeString));
|
||||||
|
}
|
||||||
|
if (authInfoChanged || autoDeleteChanged || filterTextChanged) {
|
||||||
|
DBWriter.setFeedPreferences(prefs);
|
||||||
|
}
|
||||||
|
authInfoChanged = false;
|
||||||
|
autoDeleteChanged = false;
|
||||||
|
filterTextChanged = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
if(subscription != null) {
|
||||||
|
subscription.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
super.onCreateOptionsMenu(menu);
|
||||||
|
MenuInflater inflater = getMenuInflater();
|
||||||
|
inflater.inflate(R.menu.feedinfo, menu);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||||
|
super.onPrepareOptionsMenu(menu);
|
||||||
|
menu.findItem(R.id.support_item).setVisible(
|
||||||
|
feed != null && feed.getPaymentLink() != null);
|
||||||
|
menu.findItem(R.id.share_link_item).setVisible(feed != null && feed.getLink() != null);
|
||||||
|
menu.findItem(R.id.visit_website_item).setVisible(feed != null && feed.getLink() != null &&
|
||||||
|
IntentUtils.isCallable(this, new Intent(Intent.ACTION_VIEW, Uri.parse(feed.getLink()))));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case android.R.id.home:
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
try {
|
||||||
|
return FeedMenuHandler.onOptionsItemClicked(this, item, feed);
|
||||||
|
} catch (DownloadRequestException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
DownloadRequestErrorDialogCreator.newRequestErrorDialog(this,
|
||||||
|
e.getMessage());
|
||||||
|
}
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateAutoDownloadSettings() {
|
||||||
|
if (feed != null && feed.getPreferences() != null) {
|
||||||
|
boolean enabled = feed.getPreferences().getAutoDownload() && UserPreferences.isEnableAutodownload();
|
||||||
|
rdoFilterInclude.setEnabled(enabled);
|
||||||
|
rdoFilterExclude.setEnabled(enabled);
|
||||||
|
etxtFilterText.setEnabled(enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ApplyToEpisodesDialog extends ConfirmationDialog {
|
||||||
|
|
||||||
|
private final Feed feed;
|
||||||
|
private final boolean autoDownload;
|
||||||
|
|
||||||
|
ApplyToEpisodesDialog(Context context, Feed feed, boolean autoDownload) {
|
||||||
|
super(context, R.string.auto_download_apply_to_items_title,
|
||||||
|
R.string.auto_download_apply_to_items_message);
|
||||||
|
this.feed = feed;
|
||||||
|
this.autoDownload = autoDownload;
|
||||||
|
setPositiveText(R.string.yes);
|
||||||
|
setNegativeText(R.string.no);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConfirmButtonPressed(DialogInterface dialog) {
|
||||||
|
DBWriter.setFeedsItemsAutoDownload(feed, autoDownload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -4,7 +4,7 @@ package de.danoeh.antennapod.activity;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v7.app.ActionBarActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
@ -18,11 +18,10 @@ import de.danoeh.antennapod.BuildConfig;
|
|||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||||
import de.danoeh.antennapod.core.util.flattr.FlattrUtils;
|
import de.danoeh.antennapod.core.util.flattr.FlattrUtils;
|
||||||
import de.danoeh.antennapod.preferences.PreferenceController;
|
|
||||||
|
|
||||||
/** Guides the user through the authentication process */
|
/** Guides the user through the authentication process */
|
||||||
|
|
||||||
public class FlattrAuthActivity extends ActionBarActivity {
|
public class FlattrAuthActivity extends AppCompatActivity {
|
||||||
private static final String TAG = "FlattrAuthActivity";
|
private static final String TAG = "FlattrAuthActivity";
|
||||||
|
|
||||||
private TextView txtvExplanation;
|
private TextView txtvExplanation;
|
||||||
@ -104,7 +103,7 @@ public class FlattrAuthActivity extends ActionBarActivity {
|
|||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case android.R.id.home:
|
case android.R.id.home:
|
||||||
if (authSuccessful) {
|
if (authSuccessful) {
|
||||||
Intent intent = new Intent(this, PreferenceController.getPreferenceActivity());
|
Intent intent = new Intent(this, PreferenceActivity.class);
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
} else {
|
} else {
|
||||||
|
@ -0,0 +1,188 @@
|
|||||||
|
package de.danoeh.antennapod.activity;
|
||||||
|
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Environment;
|
||||||
|
import android.os.ParcelFileDescriptor;
|
||||||
|
import android.support.design.widget.Snackbar;
|
||||||
|
import android.support.v7.app.ActionBar;
|
||||||
|
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;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays the 'import/export' screen
|
||||||
|
*/
|
||||||
|
public class ImportExportActivity extends AppCompatActivity {
|
||||||
|
private static final int REQUEST_CODE_RESTORE = 43;
|
||||||
|
private static final int REQUEST_CODE_BACKUP_DOCUMENT = 44;
|
||||||
|
private static final String EXPORT_FILENAME = "AntennaPodBackup.db";
|
||||||
|
private static final String TAG = ImportExportActivity.class.getSimpleName();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
setTheme(UserPreferences.getTheme());
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
ActionBar actionBar = getSupportActionBar();
|
||||||
|
if (actionBar != null) {
|
||||||
|
actionBar.setDisplayShowHomeEnabled(true);
|
||||||
|
}
|
||||||
|
setContentView(R.layout.import_export_activity);
|
||||||
|
|
||||||
|
findViewById(R.id.button_export).setOnClickListener(view -> backup());
|
||||||
|
findViewById(R.id.button_import).setOnClickListener(view -> restore());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
if (item.getItemId() == android.R.id.home) {
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void backup() {
|
||||||
|
if (Build.VERSION.SDK_INT >= 19) {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT)
|
||||||
|
.addCategory(Intent.CATEGORY_OPENABLE)
|
||||||
|
.setType("application/x-sqlite3")
|
||||||
|
.putExtra(Intent.EXTRA_TITLE, EXPORT_FILENAME);
|
||||||
|
|
||||||
|
startActivityForResult(intent, REQUEST_CODE_BACKUP_DOCUMENT);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
File sd = Environment.getExternalStorageDirectory();
|
||||||
|
File backupDB = new File(sd, EXPORT_FILENAME);
|
||||||
|
writeBackupTo(new FileOutputStream(backupDB));
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, Log.getStackTraceString(e));
|
||||||
|
Snackbar.make(findViewById(R.id.import_export_layout), e.getLocalizedMessage(), Snackbar.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void restore() {
|
||||||
|
if (Build.VERSION.SDK_INT >= 19) {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
||||||
|
intent.setType("*/*");
|
||||||
|
startActivityForResult(intent, REQUEST_CODE_RESTORE);
|
||||||
|
} else {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||||
|
intent.setType("*/*");
|
||||||
|
startActivityForResult(Intent.createChooser(intent,
|
||||||
|
getString(R.string.import_select_file)), REQUEST_CODE_RESTORE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
|
||||||
|
if (resultCode != RESULT_OK || resultData == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Uri uri = resultData.getData();
|
||||||
|
|
||||||
|
if (requestCode == REQUEST_CODE_RESTORE) {
|
||||||
|
restoreFrom(uri);
|
||||||
|
} else if (requestCode == REQUEST_CODE_BACKUP_DOCUMENT) {
|
||||||
|
backupToDocument(uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void restoreFrom(Uri inputUri) {
|
||||||
|
File currentDB = getDatabasePath(PodDBAdapter.DATABASE_NAME);
|
||||||
|
InputStream inputStream = null;
|
||||||
|
try {
|
||||||
|
inputStream = getContentResolver().openInputStream(inputUri);
|
||||||
|
FileUtils.copyInputStreamToFile(inputStream, currentDB);
|
||||||
|
displayImportSuccessDialog();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, Log.getStackTraceString(e));
|
||||||
|
Snackbar.make(findViewById(R.id.import_export_layout), e.getLocalizedMessage(), Snackbar.LENGTH_SHORT).show();
|
||||||
|
} finally {
|
||||||
|
IOUtils.closeQuietly(inputStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void displayImportSuccessDialog() {
|
||||||
|
AlertDialog.Builder d = new AlertDialog.Builder(ImportExportActivity.this);
|
||||||
|
d.setMessage(R.string.import_ok);
|
||||||
|
d.setCancelable(false);
|
||||||
|
d.setPositiveButton(android.R.string.ok, (dialogInterface, i) -> {
|
||||||
|
Intent intent = new Intent(getApplicationContext(), SplashActivity.class);
|
||||||
|
ComponentName cn = intent.getComponent();
|
||||||
|
Intent mainIntent = Intent.makeRestartActivityTask(cn);
|
||||||
|
startActivity(mainIntent);
|
||||||
|
});
|
||||||
|
d.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void backupToDocument(Uri uri) {
|
||||||
|
ParcelFileDescriptor pfd = null;
|
||||||
|
FileOutputStream fileOutputStream = null;
|
||||||
|
try {
|
||||||
|
pfd = getContentResolver().openFileDescriptor(uri, "w");
|
||||||
|
fileOutputStream = new FileOutputStream(pfd.getFileDescriptor());
|
||||||
|
writeBackupTo(fileOutputStream);
|
||||||
|
|
||||||
|
Snackbar.make(findViewById(R.id.import_export_layout),
|
||||||
|
R.string.export_ok, Snackbar.LENGTH_SHORT).show();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, Log.getStackTraceString(e));
|
||||||
|
Snackbar.make(findViewById(R.id.import_export_layout), e.getLocalizedMessage(), Snackbar.LENGTH_SHORT).show();
|
||||||
|
} finally {
|
||||||
|
IOUtils.closeQuietly(fileOutputStream);
|
||||||
|
|
||||||
|
if (pfd != null) {
|
||||||
|
try {
|
||||||
|
pfd.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.d(TAG, "Unable to close ParcelFileDescriptor");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeBackupTo(FileOutputStream outFileStream) {
|
||||||
|
FileChannel src = null;
|
||||||
|
FileChannel dst = null;
|
||||||
|
try {
|
||||||
|
File currentDB = getDatabasePath(PodDBAdapter.DATABASE_NAME);
|
||||||
|
|
||||||
|
if (currentDB.exists()) {
|
||||||
|
src = new FileInputStream(currentDB).getChannel();
|
||||||
|
dst = outFileStream.getChannel();
|
||||||
|
dst.transferFrom(src, 0, src.size());
|
||||||
|
|
||||||
|
Snackbar.make(findViewById(R.id.import_export_layout),
|
||||||
|
R.string.export_ok, Snackbar.LENGTH_SHORT).show();
|
||||||
|
} else {
|
||||||
|
Snackbar.make(findViewById(R.id.import_export_layout),
|
||||||
|
"Can not access current database", Snackbar.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, Log.getStackTraceString(e));
|
||||||
|
Snackbar.make(findViewById(R.id.import_export_layout), e.getLocalizedMessage(), Snackbar.LENGTH_SHORT).show();
|
||||||
|
} finally {
|
||||||
|
IOUtils.closeQuietly(src);
|
||||||
|
IOUtils.closeQuietly(dst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -30,6 +30,9 @@ import android.widget.ListView;
|
|||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
import com.bumptech.glide.Glide;
|
||||||
|
|
||||||
|
import de.danoeh.antennapod.core.event.ServiceEvent;
|
||||||
|
import de.danoeh.antennapod.core.util.IntentUtils;
|
||||||
|
import de.danoeh.antennapod.core.util.gui.NotificationUtils;
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
|
|
||||||
@ -64,7 +67,6 @@ import de.danoeh.antennapod.fragment.PlaybackHistoryFragment;
|
|||||||
import de.danoeh.antennapod.fragment.QueueFragment;
|
import de.danoeh.antennapod.fragment.QueueFragment;
|
||||||
import de.danoeh.antennapod.fragment.SubscriptionFragment;
|
import de.danoeh.antennapod.fragment.SubscriptionFragment;
|
||||||
import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
|
import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
|
||||||
import de.danoeh.antennapod.preferences.PreferenceController;
|
|
||||||
import de.greenrobot.event.EventBus;
|
import de.greenrobot.event.EventBus;
|
||||||
import rx.Observable;
|
import rx.Observable;
|
||||||
import rx.Subscription;
|
import rx.Subscription;
|
||||||
@ -83,7 +85,7 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
|
|||||||
|
|
||||||
public static final String PREF_NAME = "MainActivityPrefs";
|
public static final String PREF_NAME = "MainActivityPrefs";
|
||||||
public static final String PREF_IS_FIRST_LAUNCH = "prefMainActivityIsFirstLaunch";
|
public static final String PREF_IS_FIRST_LAUNCH = "prefMainActivityIsFirstLaunch";
|
||||||
public static final String PREF_LAST_FRAGMENT_TAG = "prefMainActivityLastFragmentTag";
|
private static final String PREF_LAST_FRAGMENT_TAG = "prefMainActivityLastFragmentTag";
|
||||||
|
|
||||||
public static final String EXTRA_NAV_TYPE = "nav_type";
|
public static final String EXTRA_NAV_TYPE = "nav_type";
|
||||||
public static final String EXTRA_NAV_INDEX = "nav_index";
|
public static final String EXTRA_NAV_INDEX = "nav_index";
|
||||||
@ -91,8 +93,8 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
|
|||||||
public static final String EXTRA_FRAGMENT_ARGS = "fragment_args";
|
public static final String EXTRA_FRAGMENT_ARGS = "fragment_args";
|
||||||
public static final String EXTRA_FEED_ID = "fragment_feed_id";
|
public static final String EXTRA_FEED_ID = "fragment_feed_id";
|
||||||
|
|
||||||
public static final String SAVE_BACKSTACK_COUNT = "backstackCount";
|
private static final String SAVE_BACKSTACK_COUNT = "backstackCount";
|
||||||
public static final String SAVE_TITLE = "title";
|
private static final String SAVE_TITLE = "title";
|
||||||
|
|
||||||
public static final String[] NAV_DRAWER_TAGS = {
|
public static final String[] NAV_DRAWER_TAGS = {
|
||||||
QueueFragment.TAG,
|
QueueFragment.TAG,
|
||||||
@ -173,7 +175,7 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
|
|||||||
|
|
||||||
findViewById(R.id.nav_settings).setOnClickListener(v -> {
|
findViewById(R.id.nav_settings).setOnClickListener(v -> {
|
||||||
drawerLayout.closeDrawer(navDrawer);
|
drawerLayout.closeDrawer(navDrawer);
|
||||||
startActivity(new Intent(MainActivity.this, PreferenceController.getPreferenceActivity()));
|
startActivity(new Intent(MainActivity.this, PreferenceActivity.class));
|
||||||
});
|
});
|
||||||
|
|
||||||
FragmentTransaction transaction = fm.beginTransaction();
|
FragmentTransaction transaction = fm.beginTransaction();
|
||||||
@ -201,6 +203,8 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
|
|||||||
transaction.commit();
|
transaction.commit();
|
||||||
|
|
||||||
checkFirstLaunch();
|
checkFirstLaunch();
|
||||||
|
NotificationUtils.createChannels(this);
|
||||||
|
UserPreferences.restartUpdateAlarm(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveLastNavFragment(String tag) {
|
private void saveLastNavFragment(String tag) {
|
||||||
@ -236,7 +240,7 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showDrawerPreferencesDialog() {
|
private void showDrawerPreferencesDialog() {
|
||||||
final List<String> hiddenDrawerItems = UserPreferences.getHiddenDrawerItems();
|
final List<String> hiddenDrawerItems = UserPreferences.getHiddenDrawerItems();
|
||||||
String[] navLabels = new String[NAV_DRAWER_TAGS.length];
|
String[] navLabels = new String[NAV_DRAWER_TAGS.length];
|
||||||
final boolean[] checked = new boolean[NAV_DRAWER_TAGS.length];
|
final boolean[] checked = new boolean[NAV_DRAWER_TAGS.length];
|
||||||
@ -270,7 +274,7 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
|
|||||||
return (navDrawerData != null) ? navDrawerData.feeds : null;
|
return (navDrawerData != null) ? navDrawerData.feeds : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadFragment(int index, Bundle args) {
|
private void loadFragment(int index, Bundle args) {
|
||||||
Log.d(TAG, "loadFragment(index: " + index + ", args: " + args + ")");
|
Log.d(TAG, "loadFragment(index: " + index + ", args: " + args + ")");
|
||||||
if (index < navAdapter.getSubscriptionOffset()) {
|
if (index < navAdapter.getSubscriptionOffset()) {
|
||||||
String tag = navAdapter.getTags().get(index);
|
String tag = navAdapter.getTags().get(index);
|
||||||
@ -399,7 +403,7 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private AdapterView.OnItemClickListener navListClickListener = new AdapterView.OnItemClickListener() {
|
private final AdapterView.OnItemClickListener navListClickListener = new AdapterView.OnItemClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||||
int viewType = parent.getAdapter().getItemViewType(position);
|
int viewType = parent.getAdapter().getItemViewType(position);
|
||||||
@ -410,7 +414,7 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private AdapterView.OnItemLongClickListener newListLongClickListener = new AdapterView.OnItemLongClickListener() {
|
private final AdapterView.OnItemLongClickListener newListLongClickListener = new AdapterView.OnItemLongClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
|
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
|
||||||
if(position < navAdapter.getTags().size()) {
|
if(position < navAdapter.getTags().size()) {
|
||||||
@ -573,10 +577,29 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
|
|||||||
Feed feed = navDrawerData.feeds.get(position - navAdapter.getSubscriptionOffset());
|
Feed feed = navDrawerData.feeds.get(position - navAdapter.getSubscriptionOffset());
|
||||||
switch(item.getItemId()) {
|
switch(item.getItemId()) {
|
||||||
case R.id.mark_all_seen_item:
|
case R.id.mark_all_seen_item:
|
||||||
DBWriter.markFeedSeen(feed.getId());
|
ConfirmationDialog markAllSeenConfirmationDialog = new ConfirmationDialog(this,
|
||||||
|
R.string.mark_all_seen_label,
|
||||||
|
R.string.mark_all_seen_confirmation_msg) {
|
||||||
|
@Override
|
||||||
|
public void onConfirmButtonPressed(DialogInterface dialog) {
|
||||||
|
dialog.dismiss();
|
||||||
|
DBWriter.markFeedSeen(feed.getId());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
markAllSeenConfirmationDialog.createNewDialog().show();
|
||||||
return true;
|
return true;
|
||||||
case R.id.mark_all_read_item:
|
case R.id.mark_all_read_item:
|
||||||
DBWriter.markFeedRead(feed.getId());
|
ConfirmationDialog markAllReadConfirmationDialog = new ConfirmationDialog(this,
|
||||||
|
R.string.mark_all_read_label,
|
||||||
|
R.string.mark_all_read_confirmation_msg) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConfirmButtonPressed(DialogInterface dialog) {
|
||||||
|
dialog.dismiss();
|
||||||
|
DBWriter.markFeedRead(feed.getId());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
markAllReadConfirmationDialog.createNewDialog().show();
|
||||||
return true;
|
return true;
|
||||||
case R.id.rename_item:
|
case R.id.rename_item:
|
||||||
new RenameFeedDialog(this, feed).show();
|
new RenameFeedDialog(this, feed).show();
|
||||||
@ -605,8 +628,7 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
|
|||||||
remover.skipOnCompletion = true;
|
remover.skipOnCompletion = true;
|
||||||
int playerStatus = PlaybackPreferences.getCurrentPlayerStatus();
|
int playerStatus = PlaybackPreferences.getCurrentPlayerStatus();
|
||||||
if(playerStatus == PlaybackPreferences.PLAYER_STATUS_PLAYING) {
|
if(playerStatus == PlaybackPreferences.PLAYER_STATUS_PLAYING) {
|
||||||
sendBroadcast(new Intent(
|
IntentUtils.sendLocalBroadcast(MainActivity.this, PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE);
|
||||||
PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
remover.executeAsync();
|
remover.executeAsync();
|
||||||
@ -631,7 +653,7 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
|
|||||||
private DBReader.NavDrawerData navDrawerData;
|
private DBReader.NavDrawerData navDrawerData;
|
||||||
private int selectedNavListIndex = 0;
|
private int selectedNavListIndex = 0;
|
||||||
|
|
||||||
private NavListAdapter.ItemAccess itemAccess = new NavListAdapter.ItemAccess() {
|
private final NavListAdapter.ItemAccess itemAccess = new NavListAdapter.ItemAccess() {
|
||||||
@Override
|
@Override
|
||||||
public int getCount() {
|
public int getCount() {
|
||||||
if (navDrawerData != null) {
|
if (navDrawerData != null) {
|
||||||
@ -721,6 +743,15 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
|
|||||||
loadData();
|
loadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onEventMainThread(ServiceEvent event) {
|
||||||
|
Log.d(TAG, "onEvent(" + event + ")");
|
||||||
|
switch(event.action) {
|
||||||
|
case SERVICE_STARTED:
|
||||||
|
externalPlayerFragment.connectToPlaybackService();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void onEventMainThread(ProgressEvent event) {
|
public void onEventMainThread(ProgressEvent event) {
|
||||||
Log.d(TAG, "onEvent(" + event + ")");
|
Log.d(TAG, "onEvent(" + event + ")");
|
||||||
switch(event.action) {
|
switch(event.action) {
|
||||||
@ -744,14 +775,12 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
|
|||||||
View parentLayout = findViewById(R.id.drawer_layout);
|
View parentLayout = findViewById(R.id.drawer_layout);
|
||||||
Snackbar snackbar = Snackbar.make(parentLayout, event.message, Snackbar.LENGTH_SHORT);
|
Snackbar snackbar = Snackbar.make(parentLayout, event.message, Snackbar.LENGTH_SHORT);
|
||||||
if(event.action != null) {
|
if(event.action != null) {
|
||||||
snackbar.setAction(getString(R.string.undo), v -> {
|
snackbar.setAction(getString(R.string.undo), v -> event.action.run());
|
||||||
event.action.run();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
snackbar.show();
|
snackbar.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
|
private final EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(EventDistributor eventDistributor, Integer arg) {
|
public void update(EventDistributor eventDistributor, Integer arg) {
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package de.danoeh.antennapod.activity;
|
package de.danoeh.antennapod.activity;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.PixelFormat;
|
import android.graphics.PixelFormat;
|
||||||
@ -11,6 +13,9 @@ import android.net.Uri;
|
|||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
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.support.v7.app.AlertDialog;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
@ -33,21 +38,28 @@ import com.joanzapata.iconify.fonts.FontAwesomeIcons;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import de.danoeh.antennapod.R;
|
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.FeedItem;
|
||||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
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.preferences.UserPreferences;
|
||||||
import de.danoeh.antennapod.core.service.playback.PlaybackService;
|
import de.danoeh.antennapod.core.service.playback.PlaybackService;
|
||||||
import de.danoeh.antennapod.core.storage.DBReader;
|
import de.danoeh.antennapod.core.storage.DBReader;
|
||||||
import de.danoeh.antennapod.core.storage.DBTasks;
|
import de.danoeh.antennapod.core.storage.DBTasks;
|
||||||
import de.danoeh.antennapod.core.storage.DBWriter;
|
import de.danoeh.antennapod.core.storage.DBWriter;
|
||||||
import de.danoeh.antennapod.core.util.Converter;
|
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.Flavors;
|
||||||
|
import de.danoeh.antennapod.core.util.IntentUtils;
|
||||||
import de.danoeh.antennapod.core.util.ShareUtils;
|
import de.danoeh.antennapod.core.util.ShareUtils;
|
||||||
import de.danoeh.antennapod.core.util.StorageUtils;
|
import de.danoeh.antennapod.core.util.StorageUtils;
|
||||||
import de.danoeh.antennapod.core.util.Supplier;
|
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.MediaPlayerError;
|
||||||
import de.danoeh.antennapod.core.util.playback.Playable;
|
import de.danoeh.antennapod.core.util.playback.Playable;
|
||||||
import de.danoeh.antennapod.core.util.playback.PlaybackController;
|
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.SleepTimerDialog;
|
||||||
import de.danoeh.antennapod.dialog.VariableSpeedDialog;
|
import de.danoeh.antennapod.dialog.VariableSpeedDialog;
|
||||||
import rx.Observable;
|
import rx.Observable;
|
||||||
@ -65,20 +77,21 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
|
|||||||
private static final String TAG = "MediaplayerActivity";
|
private static final String TAG = "MediaplayerActivity";
|
||||||
private static final String PREFS = "MediaPlayerActivityPreferences";
|
private static final String PREFS = "MediaPlayerActivityPreferences";
|
||||||
private static final String PREF_SHOW_TIME_LEFT = "showTimeLeft";
|
private static final String PREF_SHOW_TIME_LEFT = "showTimeLeft";
|
||||||
|
private static final int REQUEST_CODE_STORAGE = 42;
|
||||||
|
|
||||||
protected PlaybackController controller;
|
PlaybackController controller;
|
||||||
|
|
||||||
protected TextView txtvPosition;
|
private TextView txtvPosition;
|
||||||
protected TextView txtvLength;
|
private TextView txtvLength;
|
||||||
protected SeekBar sbPosition;
|
SeekBar sbPosition;
|
||||||
protected ImageButton butRev;
|
private ImageButton butRev;
|
||||||
protected TextView txtvRev;
|
private TextView txtvRev;
|
||||||
protected ImageButton butPlay;
|
private ImageButton butPlay;
|
||||||
protected ImageButton butFF;
|
private ImageButton butFF;
|
||||||
protected TextView txtvFF;
|
private TextView txtvFF;
|
||||||
protected ImageButton butSkip;
|
private ImageButton butSkip;
|
||||||
|
|
||||||
protected boolean showTimeLeft = false;
|
private boolean showTimeLeft = false;
|
||||||
|
|
||||||
private boolean isFavorite = false;
|
private boolean isFavorite = false;
|
||||||
|
|
||||||
@ -183,31 +196,31 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static TextView getTxtvFFFromActivity(MediaplayerActivity activity) {
|
private static TextView getTxtvFFFromActivity(MediaplayerActivity activity) {
|
||||||
return activity.txtvFF;
|
return activity.txtvFF;
|
||||||
}
|
}
|
||||||
protected static TextView getTxtvRevFromActivity(MediaplayerActivity activity) {
|
private static TextView getTxtvRevFromActivity(MediaplayerActivity activity) {
|
||||||
return activity.txtvRev;
|
return activity.txtvRev;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onSetSpeedAbilityChanged() {
|
private void onSetSpeedAbilityChanged() {
|
||||||
Log.d(TAG, "onSetSpeedAbilityChanged()");
|
Log.d(TAG, "onSetSpeedAbilityChanged()");
|
||||||
updatePlaybackSpeedButton();
|
updatePlaybackSpeedButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onPlaybackSpeedChange() {
|
private void onPlaybackSpeedChange() {
|
||||||
updatePlaybackSpeedButtonText();
|
updatePlaybackSpeedButtonText();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onServiceQueried() {
|
private void onServiceQueried() {
|
||||||
supportInvalidateOptionsMenu();
|
supportInvalidateOptionsMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void chooseTheme() {
|
void chooseTheme() {
|
||||||
setTheme(UserPreferences.getTheme());
|
setTheme(UserPreferences.getTheme());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setScreenOn(boolean enable) {
|
void setScreenOn(boolean enable) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -224,9 +237,11 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPause() {
|
protected void onPause() {
|
||||||
if(controller != null) {
|
if (!PictureInPictureUtil.isInPictureInPictureMode(this)) {
|
||||||
controller.reinitServiceIfPaused();
|
if (controller != null) {
|
||||||
controller.pause();
|
controller.reinitServiceIfPaused();
|
||||||
|
controller.pause();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
super.onPause();
|
super.onPause();
|
||||||
}
|
}
|
||||||
@ -248,7 +263,7 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
|
|||||||
*/
|
*/
|
||||||
protected abstract void onBufferEnd();
|
protected abstract void onBufferEnd();
|
||||||
|
|
||||||
protected void onBufferUpdate(float progress) {
|
private void onBufferUpdate(float progress) {
|
||||||
if (sbPosition != null) {
|
if (sbPosition != null) {
|
||||||
sbPosition.setSecondaryProgress((int) progress * sbPosition.getMax());
|
sbPosition.setSecondaryProgress((int) progress * sbPosition.getMax());
|
||||||
}
|
}
|
||||||
@ -257,7 +272,7 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
|
|||||||
/**
|
/**
|
||||||
* Current screen orientation.
|
* Current screen orientation.
|
||||||
*/
|
*/
|
||||||
protected int orientation;
|
private int orientation;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
protected void onStart() {
|
||||||
@ -266,6 +281,9 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
|
|||||||
controller.release();
|
controller.release();
|
||||||
}
|
}
|
||||||
controller = newPlaybackController();
|
controller = newPlaybackController();
|
||||||
|
setupGUI();
|
||||||
|
loadMediaInfo();
|
||||||
|
onPositionObserverUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -316,11 +334,11 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
|
|||||||
((FeedMedia) media).getItem().getFlattrStatus().flattrable()
|
((FeedMedia) media).getItem().getFlattrStatus().flattrable()
|
||||||
);
|
);
|
||||||
|
|
||||||
boolean hasWebsiteLink = media != null && media.getWebsiteLink() != null;
|
boolean hasWebsiteLink = ( getWebsiteLinkWithFallback(media) != null );
|
||||||
menu.findItem(R.id.visit_website_item).setVisible(hasWebsiteLink);
|
menu.findItem(R.id.visit_website_item).setVisible(hasWebsiteLink);
|
||||||
|
|
||||||
boolean isItemAndHasLink = isFeedMedia &&
|
boolean isItemAndHasLink = isFeedMedia &&
|
||||||
((FeedMedia) media).getItem() != null && ((FeedMedia) media).getItem().getLink() != null;
|
ShareUtils.hasLinkToShare(((FeedMedia) media).getItem());
|
||||||
menu.findItem(R.id.share_link_item).setVisible(isItemAndHasLink);
|
menu.findItem(R.id.share_link_item).setVisible(isItemAndHasLink);
|
||||||
menu.findItem(R.id.share_link_with_position_item).setVisible(isItemAndHasLink);
|
menu.findItem(R.id.share_link_with_position_item).setVisible(isItemAndHasLink);
|
||||||
|
|
||||||
@ -368,7 +386,17 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
|
|||||||
MainActivity.class);
|
MainActivity.class);
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
|
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||||
| Intent.FLAG_ACTIVITY_NEW_TASK);
|
| Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
startActivity(intent);
|
|
||||||
|
View cover = findViewById(R.id.imgvCover);
|
||||||
|
if (cover != null && Build.VERSION.SDK_INT >= 16) {
|
||||||
|
ActivityOptionsCompat options = ActivityOptionsCompat.
|
||||||
|
makeSceneTransitionAnimation(MediaplayerActivity.this,
|
||||||
|
cover, "coverTransition");
|
||||||
|
startActivity(intent, options.toBundle());
|
||||||
|
} else {
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
finish();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
if (media != null) {
|
if (media != null) {
|
||||||
@ -546,7 +574,7 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case R.id.visit_website_item:
|
case R.id.visit_website_item:
|
||||||
Uri uri = Uri.parse(media.getWebsiteLink());
|
Uri uri = Uri.parse(getWebsiteLinkWithFallback(media));
|
||||||
startActivity(new Intent(Intent.ACTION_VIEW, uri));
|
startActivity(new Intent(Intent.ACTION_VIEW, uri));
|
||||||
break;
|
break;
|
||||||
case R.id.support_item:
|
case R.id.support_item:
|
||||||
@ -589,16 +617,37 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String getWebsiteLinkWithFallback(Playable media) {
|
||||||
|
if (media == null) {
|
||||||
|
return null;
|
||||||
|
} else if (media.getWebsiteLink() != null) {
|
||||||
|
return media.getWebsiteLink();
|
||||||
|
} else if (media instanceof FeedMedia) {
|
||||||
|
return FeedItemUtil.getLinkWithFallback(((FeedMedia)media).getItem());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
Log.d(TAG, "onResume()");
|
Log.d(TAG, "onResume()");
|
||||||
StorageUtils.checkStorageAvailability(this);
|
StorageUtils.checkStorageAvailability(this);
|
||||||
if(controller != null) {
|
if (controller != null) {
|
||||||
controller.init();
|
controller.init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onEventMainThread(ServiceEvent event) {
|
||||||
|
Log.d(TAG, "onEvent(" + event + ")");
|
||||||
|
if (event.action == ServiceEvent.Action.SERVICE_STARTED) {
|
||||||
|
if (controller != null) {
|
||||||
|
controller.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by 'handleStatus()' when the PlaybackService is waiting for
|
* Called by 'handleStatus()' when the PlaybackService is waiting for
|
||||||
* a video surface.
|
* a video surface.
|
||||||
@ -609,7 +658,7 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
|
|||||||
|
|
||||||
protected abstract void clearStatusMsg();
|
protected abstract void clearStatusMsg();
|
||||||
|
|
||||||
protected void onPositionObserverUpdate() {
|
void onPositionObserverUpdate() {
|
||||||
if (controller == null || txtvPosition == null || txtvLength == null) {
|
if (controller == null || txtvPosition == null || txtvLength == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -645,12 +694,11 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
|
|||||||
* to the PlaybackService to ensure that the activity has the right
|
* to the PlaybackService to ensure that the activity has the right
|
||||||
* FeedMedia object.
|
* FeedMedia object.
|
||||||
*/
|
*/
|
||||||
protected boolean loadMediaInfo() {
|
boolean loadMediaInfo() {
|
||||||
Log.d(TAG, "loadMediaInfo()");
|
Log.d(TAG, "loadMediaInfo()");
|
||||||
if(controller == null || controller.getMedia() == null) {
|
if(controller == null || controller.getMedia() == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Playable media = controller.getMedia();
|
|
||||||
SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE);
|
SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE);
|
||||||
showTimeLeft = prefs.getBoolean(PREF_SHOW_TIME_LEFT, false);
|
showTimeLeft = prefs.getBoolean(PREF_SHOW_TIME_LEFT, false);
|
||||||
onPositionObserverUpdate();
|
onPositionObserverUpdate();
|
||||||
@ -659,18 +707,18 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updatePlaybackSpeedButton() {
|
void updatePlaybackSpeedButton() {
|
||||||
// Only meaningful on AudioplayerActivity, where it is overridden.
|
// Only meaningful on AudioplayerActivity, where it is overridden.
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updatePlaybackSpeedButtonText() {
|
void updatePlaybackSpeedButtonText() {
|
||||||
// Only meaningful on AudioplayerActivity, where it is overridden.
|
// Only meaningful on AudioplayerActivity, where it is overridden.
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract directions to skip forward or back (rewind) and encapsulates behavior to get or set preference (including update of UI on the skip buttons).
|
* Abstract directions to skip forward or back (rewind) and encapsulates behavior to get or set preference (including update of UI on the skip buttons).
|
||||||
*/
|
*/
|
||||||
static public enum SkipDirection {
|
public enum SkipDirection {
|
||||||
SKIP_FORWARD(
|
SKIP_FORWARD(
|
||||||
UserPreferences::getFastForwardSecs,
|
UserPreferences::getFastForwardSecs,
|
||||||
MediaplayerActivity::getTxtvFFFromActivity,
|
MediaplayerActivity::getTxtvFFFromActivity,
|
||||||
@ -753,7 +801,7 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
|
|||||||
builder.create().show();
|
builder.create().show();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setupGUI() {
|
void setupGUI() {
|
||||||
setContentView(getContentViewResourceId());
|
setContentView(getContentViewResourceId());
|
||||||
sbPosition = (SeekBar) findViewById(R.id.sbPosition);
|
sbPosition = (SeekBar) findViewById(R.id.sbPosition);
|
||||||
txtvPosition = (TextView) findViewById(R.id.txtvPosition);
|
txtvPosition = (TextView) findViewById(R.id.txtvPosition);
|
||||||
@ -823,11 +871,12 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (butSkip != null) {
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onRewind() {
|
void onRewind() {
|
||||||
if (controller == null) {
|
if (controller == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -835,14 +884,15 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
|
|||||||
controller.seekTo(curr - UserPreferences.getRewindSecs() * 1000);
|
controller.seekTo(curr - UserPreferences.getRewindSecs() * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onPlayPause() {
|
void onPlayPause() {
|
||||||
if(controller == null) {
|
if(controller == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
controller.init();
|
||||||
controller.playPause();
|
controller.playPause();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onFastForward() {
|
void onFastForward() {
|
||||||
if (controller == null) {
|
if (controller == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -852,7 +902,7 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
|
|||||||
|
|
||||||
protected abstract int getContentViewResourceId();
|
protected abstract int getContentViewResourceId();
|
||||||
|
|
||||||
void handleError(int errorCode) {
|
private void handleError(int errorCode) {
|
||||||
final AlertDialog.Builder errorDialog = new AlertDialog.Builder(this);
|
final AlertDialog.Builder errorDialog = new AlertDialog.Builder(this);
|
||||||
errorDialog.setTitle(R.string.error_label);
|
errorDialog.setTitle(R.string.error_label);
|
||||||
errorDialog.setMessage(MediaPlayerError.getErrorString(this, errorCode));
|
errorDialog.setMessage(MediaPlayerError.getErrorString(this, errorCode));
|
||||||
@ -865,7 +915,7 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
|
|||||||
errorDialog.create().show();
|
errorDialog.create().show();
|
||||||
}
|
}
|
||||||
|
|
||||||
float prog;
|
private float prog;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onProgressChanged (SeekBar seekBar,int progress, boolean fromUser) {
|
public void onProgressChanged (SeekBar seekBar,int progress, boolean fromUser) {
|
||||||
@ -914,4 +964,39 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import android.content.Intent;
|
|||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.design.widget.AppBarLayout;
|
import android.support.design.widget.AppBarLayout;
|
||||||
import android.support.design.widget.Snackbar;
|
import android.support.design.widget.Snackbar;
|
||||||
@ -47,6 +48,7 @@ import de.danoeh.antennapod.core.service.playback.PlayerStatus;
|
|||||||
import de.danoeh.antennapod.core.storage.DBReader;
|
import de.danoeh.antennapod.core.storage.DBReader;
|
||||||
import de.danoeh.antennapod.core.storage.DBTasks;
|
import de.danoeh.antennapod.core.storage.DBTasks;
|
||||||
import de.danoeh.antennapod.core.storage.DBWriter;
|
import de.danoeh.antennapod.core.storage.DBWriter;
|
||||||
|
import de.danoeh.antennapod.core.util.IntentUtils;
|
||||||
import de.danoeh.antennapod.core.util.playback.Playable;
|
import de.danoeh.antennapod.core.util.playback.Playable;
|
||||||
import de.danoeh.antennapod.core.util.playback.PlaybackController;
|
import de.danoeh.antennapod.core.util.playback.PlaybackController;
|
||||||
import de.danoeh.antennapod.dialog.RenameFeedDialog;
|
import de.danoeh.antennapod.dialog.RenameFeedDialog;
|
||||||
@ -60,7 +62,6 @@ import de.danoeh.antennapod.fragment.PlaybackHistoryFragment;
|
|||||||
import de.danoeh.antennapod.fragment.QueueFragment;
|
import de.danoeh.antennapod.fragment.QueueFragment;
|
||||||
import de.danoeh.antennapod.fragment.SubscriptionFragment;
|
import de.danoeh.antennapod.fragment.SubscriptionFragment;
|
||||||
import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
|
import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
|
||||||
import de.danoeh.antennapod.preferences.PreferenceController;
|
|
||||||
import de.greenrobot.event.EventBus;
|
import de.greenrobot.event.EventBus;
|
||||||
import rx.Observable;
|
import rx.Observable;
|
||||||
import rx.Subscription;
|
import rx.Subscription;
|
||||||
@ -72,16 +73,17 @@ import rx.schedulers.Schedulers;
|
|||||||
*/
|
*/
|
||||||
public abstract class MediaplayerInfoActivity extends MediaplayerActivity implements NavDrawerActivity {
|
public abstract class MediaplayerInfoActivity extends MediaplayerActivity implements NavDrawerActivity {
|
||||||
|
|
||||||
|
private static final String TAG = "MediaplayerInfoActivity";
|
||||||
|
|
||||||
private static final int POS_COVER = 0;
|
private static final int POS_COVER = 0;
|
||||||
private static final int POS_DESCR = 1;
|
private static final int POS_DESCR = 1;
|
||||||
private static final int POS_CHAPTERS = 2;
|
private static final int POS_CHAPTERS = 2;
|
||||||
private static final int NUM_CONTENT_FRAGMENTS = 3;
|
private static final int NUM_CONTENT_FRAGMENTS = 3;
|
||||||
|
|
||||||
final String TAG = "MediaplayerInfoActivity";
|
|
||||||
private static final String PREFS = "AudioPlayerActivityPreferences";
|
private static final String PREFS = "AudioPlayerActivityPreferences";
|
||||||
private static final String PREF_KEY_SELECTED_FRAGMENT_POSITION = "selectedFragmentPosition";
|
private static final String PREF_KEY_SELECTED_FRAGMENT_POSITION = "selectedFragmentPosition";
|
||||||
|
|
||||||
public static final String[] NAV_DRAWER_TAGS = {
|
private static final String[] NAV_DRAWER_TAGS = {
|
||||||
QueueFragment.TAG,
|
QueueFragment.TAG,
|
||||||
EpisodesFragment.TAG,
|
EpisodesFragment.TAG,
|
||||||
SubscriptionFragment.TAG,
|
SubscriptionFragment.TAG,
|
||||||
@ -91,8 +93,8 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem
|
|||||||
NavListAdapter.SUBSCRIPTION_LIST_TAG
|
NavListAdapter.SUBSCRIPTION_LIST_TAG
|
||||||
};
|
};
|
||||||
|
|
||||||
protected Button butPlaybackSpeed;
|
Button butPlaybackSpeed;
|
||||||
protected ImageButton butCastDisconnect;
|
ImageButton butCastDisconnect;
|
||||||
private DrawerLayout drawerLayout;
|
private DrawerLayout drawerLayout;
|
||||||
private NavListAdapter navAdapter;
|
private NavListAdapter navAdapter;
|
||||||
private ListView navList;
|
private ListView navList;
|
||||||
@ -112,6 +114,12 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem
|
|||||||
EventBus.getDefault().unregister(this);
|
EventBus.getDefault().unregister(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
supportPostponeEnterTransition();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStop() {
|
protected void onStop() {
|
||||||
super.onStop();
|
super.onStop();
|
||||||
@ -145,7 +153,7 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem
|
|||||||
setTheme(UserPreferences.getNoTitleTheme());
|
setTheme(UserPreferences.getNoTitleTheme());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void saveCurrentFragment() {
|
void saveCurrentFragment() {
|
||||||
if(pager == null) {
|
if(pager == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -153,7 +161,7 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem
|
|||||||
SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE);
|
SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE);
|
||||||
prefs.edit()
|
prefs.edit()
|
||||||
.putInt(PREF_KEY_SELECTED_FRAGMENT_POSITION, pager.getCurrentItem())
|
.putInt(PREF_KEY_SELECTED_FRAGMENT_POSITION, pager.getCurrentItem())
|
||||||
.commit();
|
.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -235,7 +243,7 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem
|
|||||||
|
|
||||||
drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.drawer_open, R.string.drawer_close);
|
drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.drawer_open, R.string.drawer_close);
|
||||||
drawerToggle.setDrawerIndicatorEnabled(false);
|
drawerToggle.setDrawerIndicatorEnabled(false);
|
||||||
drawerLayout.setDrawerListener(drawerToggle);
|
drawerLayout.addDrawerListener(drawerToggle);
|
||||||
|
|
||||||
navAdapter = new NavListAdapter(itemAccess, this);
|
navAdapter = new NavListAdapter(itemAccess, this);
|
||||||
navList.setAdapter(navAdapter);
|
navList.setAdapter(navAdapter);
|
||||||
@ -263,7 +271,7 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem
|
|||||||
|
|
||||||
findViewById(R.id.nav_settings).setOnClickListener(v -> {
|
findViewById(R.id.nav_settings).setOnClickListener(v -> {
|
||||||
drawerLayout.closeDrawer(navDrawer);
|
drawerLayout.closeDrawer(navDrawer);
|
||||||
startActivity(new Intent(MediaplayerInfoActivity.this, PreferenceController.getPreferenceActivity()));
|
startActivity(new Intent(MediaplayerInfoActivity.this, PreferenceActivity.class));
|
||||||
});
|
});
|
||||||
|
|
||||||
butPlaybackSpeed = (Button) findViewById(R.id.butPlaybackSpeed);
|
butPlaybackSpeed = (Button) findViewById(R.id.butPlaybackSpeed);
|
||||||
@ -277,6 +285,8 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem
|
|||||||
pageIndicator.setViewPager(pager);
|
pageIndicator.setViewPager(pager);
|
||||||
loadLastFragment();
|
loadLastFragment();
|
||||||
pager.onSaveInstanceState();
|
pager.onSaveInstanceState();
|
||||||
|
|
||||||
|
navList.post(this::supportStartPostponedEnterTransition);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -297,7 +307,7 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void notifyMediaPositionChanged() {
|
private void notifyMediaPositionChanged() {
|
||||||
if(pagerAdapter == null) {
|
if(pagerAdapter == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -387,12 +397,7 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem
|
|||||||
new RenameFeedDialog(this, feed).show();
|
new RenameFeedDialog(this, feed).show();
|
||||||
return true;
|
return true;
|
||||||
case R.id.remove_item:
|
case R.id.remove_item:
|
||||||
final FeedRemover remover = new FeedRemover(this, feed) {
|
final FeedRemover remover = new FeedRemover(this, feed);
|
||||||
@Override
|
|
||||||
protected void onPostExecute(Void result) {
|
|
||||||
super.onPostExecute(result);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ConfirmationDialog conDialog = new ConfirmationDialog(this,
|
ConfirmationDialog conDialog = new ConfirmationDialog(this,
|
||||||
R.string.remove_feed_label,
|
R.string.remove_feed_label,
|
||||||
getString(R.string.feed_delete_confirmation_msg, feed.getTitle())) {
|
getString(R.string.feed_delete_confirmation_msg, feed.getTitle())) {
|
||||||
@ -404,12 +409,12 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem
|
|||||||
Playable playable = controller.getMedia();
|
Playable playable = controller.getMedia();
|
||||||
if (playable != null && playable instanceof FeedMedia) {
|
if (playable != null && playable instanceof FeedMedia) {
|
||||||
FeedMedia media = (FeedMedia) playable;
|
FeedMedia media = (FeedMedia) playable;
|
||||||
if (media.getItem().getFeed().getId() == feed.getId()) {
|
if (media.getItem() != null && media.getItem().getFeed() != null &&
|
||||||
|
media.getItem().getFeed().getId() == feed.getId()) {
|
||||||
Log.d(TAG, "Currently playing episode is about to be deleted, skipping");
|
Log.d(TAG, "Currently playing episode is about to be deleted, skipping");
|
||||||
remover.skipOnCompletion = true;
|
remover.skipOnCompletion = true;
|
||||||
if(controller.getStatus() == PlayerStatus.PLAYING) {
|
if(controller.getStatus() == PlayerStatus.PLAYING) {
|
||||||
sendBroadcast(new Intent(
|
IntentUtils.sendLocalBroadcast(MediaplayerInfoActivity.this, PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE);
|
||||||
PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -438,7 +443,7 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showDrawerPreferencesDialog() {
|
private void showDrawerPreferencesDialog() {
|
||||||
final List<String> hiddenDrawerItems = UserPreferences.getHiddenDrawerItems();
|
final List<String> hiddenDrawerItems = UserPreferences.getHiddenDrawerItems();
|
||||||
String[] navLabels = new String[NAV_DRAWER_TAGS.length];
|
String[] navLabels = new String[NAV_DRAWER_TAGS.length];
|
||||||
final boolean[] checked = new boolean[NAV_DRAWER_TAGS.length];
|
final boolean[] checked = new boolean[NAV_DRAWER_TAGS.length];
|
||||||
@ -483,14 +488,12 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem
|
|||||||
View parentLayout = findViewById(R.id.drawer_layout);
|
View parentLayout = findViewById(R.id.drawer_layout);
|
||||||
Snackbar snackbar = Snackbar.make(parentLayout, event.message, Snackbar.LENGTH_SHORT);
|
Snackbar snackbar = Snackbar.make(parentLayout, event.message, Snackbar.LENGTH_SHORT);
|
||||||
if (event.action != null) {
|
if (event.action != null) {
|
||||||
snackbar.setAction(getString(R.string.undo), v -> {
|
snackbar.setAction(getString(R.string.undo), v -> event.action.run());
|
||||||
event.action.run();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
snackbar.show();
|
snackbar.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
|
private final EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(EventDistributor eventDistributor, Integer arg) {
|
public void update(EventDistributor eventDistributor, Integer arg) {
|
||||||
|
@ -5,8 +5,9 @@ import android.content.Context;
|
|||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Looper;
|
import android.support.annotation.UiThread;
|
||||||
import android.support.v4.app.NavUtils;
|
import android.support.v4.app.NavUtils;
|
||||||
|
import android.support.v7.app.ActionBar;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
@ -55,7 +56,6 @@ import de.danoeh.antennapod.core.storage.DBReader;
|
|||||||
import de.danoeh.antennapod.core.storage.DownloadRequestException;
|
import de.danoeh.antennapod.core.storage.DownloadRequestException;
|
||||||
import de.danoeh.antennapod.core.storage.DownloadRequester;
|
import de.danoeh.antennapod.core.storage.DownloadRequester;
|
||||||
import de.danoeh.antennapod.core.syndication.handler.FeedHandler;
|
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.syndication.handler.UnsupportedFeedtypeException;
|
||||||
import de.danoeh.antennapod.core.util.DownloadError;
|
import de.danoeh.antennapod.core.util.DownloadError;
|
||||||
import de.danoeh.antennapod.core.util.FileNameGenerator;
|
import de.danoeh.antennapod.core.util.FileNameGenerator;
|
||||||
@ -66,7 +66,6 @@ import de.danoeh.antennapod.core.util.syndication.HtmlToPlainText;
|
|||||||
import de.danoeh.antennapod.dialog.AuthenticationDialog;
|
import de.danoeh.antennapod.dialog.AuthenticationDialog;
|
||||||
import de.greenrobot.event.EventBus;
|
import de.greenrobot.event.EventBus;
|
||||||
import rx.Observable;
|
import rx.Observable;
|
||||||
import rx.Subscriber;
|
|
||||||
import rx.Subscription;
|
import rx.Subscription;
|
||||||
import rx.android.schedulers.AndroidSchedulers;
|
import rx.android.schedulers.AndroidSchedulers;
|
||||||
import rx.schedulers.Schedulers;
|
import rx.schedulers.Schedulers;
|
||||||
@ -84,7 +83,7 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
|
|||||||
public static final String ARG_FEEDURL = "arg.feedurl";
|
public static final String ARG_FEEDURL = "arg.feedurl";
|
||||||
// Optional argument: specify a title for the actionbar.
|
// Optional argument: specify a title for the actionbar.
|
||||||
public static final String ARG_TITLE = "title";
|
public static final String ARG_TITLE = "title";
|
||||||
public static final int RESULT_ERROR = 2;
|
private static final int RESULT_ERROR = 2;
|
||||||
private static final String TAG = "OnlineFeedViewActivity";
|
private static final String TAG = "OnlineFeedViewActivity";
|
||||||
private static final int EVENTS = EventDistributor.FEED_LIST_UPDATE;
|
private static final int EVENTS = EventDistributor.FEED_LIST_UPDATE;
|
||||||
private volatile List<Feed> feeds;
|
private volatile List<Feed> feeds;
|
||||||
@ -101,7 +100,7 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
|
|||||||
private Subscription download;
|
private Subscription download;
|
||||||
private Subscription parser;
|
private Subscription parser;
|
||||||
private Subscription updater;
|
private Subscription updater;
|
||||||
private EventDistributor.EventListener listener = new EventDistributor.EventListener() {
|
private final EventDistributor.EventListener listener = new EventDistributor.EventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void update(EventDistributor eventDistributor, Integer arg) {
|
public void update(EventDistributor eventDistributor, Integer arg) {
|
||||||
if ((arg & EventDistributor.FEED_LIST_UPDATE) != 0) {
|
if ((arg & EventDistributor.FEED_LIST_UPDATE) != 0) {
|
||||||
@ -112,9 +111,7 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
|
|||||||
feeds -> {
|
feeds -> {
|
||||||
OnlineFeedViewActivity.this.feeds = feeds;
|
OnlineFeedViewActivity.this.feeds = feeds;
|
||||||
setSubscribeButtonState(feed);
|
setSubscribeButtonState(feed);
|
||||||
}, error -> {
|
}, error -> Log.e(TAG, Log.getStackTraceString(error))
|
||||||
Log.e(TAG, Log.getStackTraceString(error));
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
} else if ((arg & EVENTS) != 0) {
|
} else if ((arg & EVENTS) != 0) {
|
||||||
setSubscribeButtonState(feed);
|
setSubscribeButtonState(feed);
|
||||||
@ -131,10 +128,13 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
|
|||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
setTheme(UserPreferences.getTheme());
|
setTheme(UserPreferences.getTheme());
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
ActionBar actionBar = getSupportActionBar();
|
||||||
|
if (actionBar != null) {
|
||||||
|
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
if (getIntent() != null && getIntent().hasExtra(ARG_TITLE)) {
|
if (actionBar != null && getIntent() != null && getIntent().hasExtra(ARG_TITLE)) {
|
||||||
getSupportActionBar().setTitle(getIntent().getStringExtra(ARG_TITLE));
|
actionBar.setTitle(getIntent().getStringExtra(ARG_TITLE));
|
||||||
}
|
}
|
||||||
|
|
||||||
StorageUtils.checkStorageAvailability(this);
|
StorageUtils.checkStorageAvailability(this);
|
||||||
@ -146,7 +146,9 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
|
|||||||
|| TextUtils.equals(getIntent().getAction(), Intent.ACTION_VIEW)) {
|
|| 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();
|
? getIntent().getStringExtra(Intent.EXTRA_TEXT) : getIntent().getDataString();
|
||||||
getSupportActionBar().setTitle(R.string.add_feed_label);
|
if (actionBar != null) {
|
||||||
|
actionBar.setTitle(R.string.add_feed_label);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Activity must be started with feedurl argument!");
|
throw new IllegalArgumentException("Activity must be started with feedurl argument!");
|
||||||
}
|
}
|
||||||
@ -265,16 +267,11 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
|
|||||||
feed.getDownload_url(), "OnlineFeed", 0, Feed.FEEDFILETYPE_FEED, username, password,
|
feed.getDownload_url(), "OnlineFeed", 0, Feed.FEEDFILETYPE_FEED, username, password,
|
||||||
true, null);
|
true, null);
|
||||||
|
|
||||||
download = Observable.create(new Observable.OnSubscribe<DownloadStatus>() {
|
download = Observable.fromCallable(() -> {
|
||||||
@Override
|
feeds = DBReader.getFeedList();
|
||||||
public void call(Subscriber<? super DownloadStatus> subscriber) {
|
downloader = new HttpDownloader(request);
|
||||||
feeds = DBReader.getFeedList();
|
downloader.call();
|
||||||
downloader = new HttpDownloader(request);
|
return downloader.getResult();
|
||||||
downloader.call();
|
|
||||||
Log.d(TAG, "Download was completed");
|
|
||||||
subscriber.onNext(downloader.getResult());
|
|
||||||
subscriber.onCompleted();
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.subscribeOn(Schedulers.newThread())
|
.subscribeOn(Schedulers.newThread())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
@ -286,6 +283,7 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
|
|||||||
if (status == null) {
|
if (status == null) {
|
||||||
Log.wtf(TAG, "DownloadStatus returned by Downloader was null");
|
Log.wtf(TAG, "DownloadStatus returned by Downloader was null");
|
||||||
finish();
|
finish();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (status.isCancelled()) {
|
if (status.isCancelled()) {
|
||||||
return;
|
return;
|
||||||
@ -300,7 +298,7 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
String errorMsg = status.getReason().getErrorString(OnlineFeedViewActivity.this);
|
String errorMsg = status.getReason().getErrorString(OnlineFeedViewActivity.this);
|
||||||
if (errorMsg != null && status.getReasonDetailed() != null) {
|
if (status.getReasonDetailed() != null) {
|
||||||
errorMsg += " (" + status.getReasonDetailed() + ")";
|
errorMsg += " (" + status.getReasonDetailed() + ")";
|
||||||
}
|
}
|
||||||
showErrorDialog(errorMsg);
|
showErrorDialog(errorMsg);
|
||||||
@ -313,39 +311,38 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
Log.d(TAG, "Parsing feed");
|
Log.d(TAG, "Parsing feed");
|
||||||
|
|
||||||
parser = Observable.create(new Observable.OnSubscribe<FeedHandlerResult>() {
|
parser = Observable.fromCallable(() -> {
|
||||||
@Override
|
FeedHandler handler = new FeedHandler();
|
||||||
public void call(Subscriber<? super FeedHandlerResult> subscriber) {
|
try {
|
||||||
FeedHandler handler = new FeedHandler();
|
return handler.parseFeed(feed);
|
||||||
try {
|
} catch (UnsupportedFeedtypeException e) {
|
||||||
FeedHandlerResult result = handler.parseFeed(feed);
|
Log.d(TAG, "Unsupported feed type detected");
|
||||||
subscriber.onNext(result);
|
if ("html".equalsIgnoreCase(e.getRootElement())) {
|
||||||
} catch (UnsupportedFeedtypeException e) {
|
showFeedDiscoveryDialog(new File(feed.getFile_url()), feed.getDownload_url());
|
||||||
Log.d(TAG, "Unsupported feed type detected");
|
return null;
|
||||||
if (TextUtils.equals("html", e.getRootElement().toLowerCase())) {
|
} else {
|
||||||
showFeedDiscoveryDialog(new File(feed.getFile_url()), feed.getDownload_url());
|
throw e;
|
||||||
} else {
|
|
||||||
subscriber.onError(e);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, Log.getStackTraceString(e));
|
|
||||||
subscriber.onError(e);
|
|
||||||
} finally {
|
|
||||||
boolean rc = new File(feed.getFile_url()).delete();
|
|
||||||
Log.d(TAG, "Deleted feed source file. Result: " + rc);
|
|
||||||
subscriber.onCompleted();
|
|
||||||
}
|
}
|
||||||
|
} 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())
|
.subscribeOn(Schedulers.newThread())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(result -> {
|
.subscribe(result -> {
|
||||||
beforeShowFeedInformation(result.feed);
|
if(result != null) {
|
||||||
showFeedInformation(result.feed, result.alternateFeedUrls);
|
beforeShowFeedInformation(result.feed);
|
||||||
|
showFeedInformation(result.feed, result.alternateFeedUrls);
|
||||||
|
}
|
||||||
}, error -> {
|
}, error -> {
|
||||||
String errorMsg = DownloadError.ERROR_PARSER_EXCEPTION.getErrorString(
|
String errorMsg = DownloadError.ERROR_PARSER_EXCEPTION.getErrorString(
|
||||||
OnlineFeedViewActivity.this) + " (" + error.getMessage() + ")";
|
OnlineFeedViewActivity.this) + " (" + error.getMessage() + ")";
|
||||||
showErrorDialog(errorMsg);
|
showErrorDialog(errorMsg);
|
||||||
|
Log.d(TAG, "Feed parser exception: " + Log.getStackTraceString(error));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,8 +380,7 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
|
|||||||
this.selectedDownloadUrl = feed.getDownload_url();
|
this.selectedDownloadUrl = feed.getDownload_url();
|
||||||
EventDistributor.getInstance().register(listener);
|
EventDistributor.getInstance().register(listener);
|
||||||
ListView listView = (ListView) findViewById(R.id.listview);
|
ListView listView = (ListView) findViewById(R.id.listview);
|
||||||
LayoutInflater inflater = (LayoutInflater)
|
LayoutInflater inflater = LayoutInflater.from(this);
|
||||||
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
|
||||||
View header = inflater.inflate(R.layout.onlinefeedview_header, listView, false);
|
View header = inflater.inflate(R.layout.onlinefeedview_header, listView, false);
|
||||||
listView.addHeaderView(header);
|
listView.addHeaderView(header);
|
||||||
|
|
||||||
@ -398,9 +394,9 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
subscribeButton = (Button) header.findViewById(R.id.butSubscribe);
|
subscribeButton = (Button) header.findViewById(R.id.butSubscribe);
|
||||||
|
|
||||||
if (feed.getImage() != null && StringUtils.isNotBlank(feed.getImage().getDownload_url())) {
|
if (StringUtils.isNotBlank(feed.getImageUrl())) {
|
||||||
Glide.with(this)
|
Glide.with(this)
|
||||||
.load(feed.getImage().getDownload_url())
|
.load(feed.getImageUrl())
|
||||||
.placeholder(R.color.light_gray)
|
.placeholder(R.color.light_gray)
|
||||||
.error(R.color.light_gray)
|
.error(R.color.light_gray)
|
||||||
.diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
|
.diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
|
||||||
@ -414,7 +410,7 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
|
|||||||
description.setText(feed.getDescription());
|
description.setText(feed.getDescription());
|
||||||
|
|
||||||
subscribeButton.setOnClickListener(v -> {
|
subscribeButton.setOnClickListener(v -> {
|
||||||
if(feed != null && feedInFeedlist(feed)) {
|
if(feedInFeedlist(feed)) {
|
||||||
Intent intent = new Intent(OnlineFeedViewActivity.this, MainActivity.class);
|
Intent intent = new Intent(OnlineFeedViewActivity.this, MainActivity.class);
|
||||||
// feed.getId() is always 0, we have to retrieve the id from the feed list from
|
// feed.getId() is always 0, we have to retrieve the id from the feed list from
|
||||||
// the database
|
// the database
|
||||||
@ -508,8 +504,8 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@UiThread
|
||||||
private void showErrorDialog(String errorMsg) {
|
private void showErrorDialog(String errorMsg) {
|
||||||
assert(Looper.myLooper() == Looper.getMainLooper()); // run on UI thread
|
|
||||||
if (!isFinishing() && !isPaused) {
|
if (!isFinishing() && !isPaused) {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
builder.setTitle(R.string.error_label);
|
builder.setTitle(R.string.error_label);
|
||||||
@ -586,7 +582,7 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
private class FeedViewAuthenticationDialog extends AuthenticationDialog {
|
private class FeedViewAuthenticationDialog extends AuthenticationDialog {
|
||||||
|
|
||||||
private String feedUrl;
|
private final String feedUrl;
|
||||||
|
|
||||||
FeedViewAuthenticationDialog(Context context, int titleRes, String feedUrl) {
|
FeedViewAuthenticationDialog(Context context, int titleRes, String feedUrl) {
|
||||||
super(context, titleRes, true, false, null, null);
|
super(context, titleRes, true, false, null, null);
|
||||||
|
@ -68,7 +68,7 @@ public class OpmlImportBaseActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void importUri(@Nullable Uri uri) {
|
void importUri(@Nullable Uri uri) {
|
||||||
if(uri == null) {
|
if(uri == null) {
|
||||||
new MaterialDialog.Builder(this)
|
new MaterialDialog.Builder(this)
|
||||||
.content(R.string.opml_import_error_no_file)
|
.content(R.string.opml_import_error_no_file)
|
||||||
@ -114,7 +114,7 @@ public class OpmlImportBaseActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Starts the import process. */
|
/** Starts the import process. */
|
||||||
protected void startImport() {
|
private void startImport() {
|
||||||
try {
|
try {
|
||||||
Reader mReader = new InputStreamReader(getContentResolver().openInputStream(uri), LangUtils.UTF_8);
|
Reader mReader = new InputStreamReader(getContentResolver().openInputStream(uri), LangUtils.UTF_8);
|
||||||
importWorker = new OpmlImportWorker(this, mReader) {
|
importWorker = new OpmlImportWorker(this, mReader) {
|
||||||
@ -144,7 +144,7 @@ public class OpmlImportBaseActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean finishWhenCanceled() {
|
boolean finishWhenCanceled() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
package de.danoeh.antennapod.activity;
|
package de.danoeh.antennapod.activity;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.Preference;
|
|
||||||
import android.preference.PreferenceFragment;
|
|
||||||
import android.support.v7.app.ActionBar;
|
import android.support.v7.app.ActionBar;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.support.v7.preference.Preference;
|
||||||
|
import android.support.v7.preference.PreferenceFragmentCompat;
|
||||||
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@ -16,6 +14,9 @@ import android.widget.FrameLayout;
|
|||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
|
import com.bytehamster.lib.preferencesearch.SearchPreference;
|
||||||
|
import com.bytehamster.lib.preferencesearch.SearchPreferenceResult;
|
||||||
|
import com.bytehamster.lib.preferencesearch.SearchPreferenceResultListener;
|
||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||||
import de.danoeh.antennapod.preferences.PreferenceController;
|
import de.danoeh.antennapod.preferences.PreferenceController;
|
||||||
@ -24,25 +25,40 @@ import de.danoeh.antennapod.preferences.PreferenceController;
|
|||||||
* PreferenceActivity for API 11+. In order to change the behavior of the preference UI, see
|
* PreferenceActivity for API 11+. In order to change the behavior of the preference UI, see
|
||||||
* PreferenceController.
|
* PreferenceController.
|
||||||
*/
|
*/
|
||||||
public class PreferenceActivity extends AppCompatActivity {
|
public class PreferenceActivity extends AppCompatActivity implements SearchPreferenceResultListener {
|
||||||
|
|
||||||
|
public static final String PARAM_RESOURCE = "resource";
|
||||||
private static WeakReference<PreferenceActivity> instance;
|
private static WeakReference<PreferenceActivity> instance;
|
||||||
private PreferenceController preferenceController;
|
private PreferenceController preferenceController;
|
||||||
private MainFragment prefFragment;
|
|
||||||
private final PreferenceController.PreferenceUI preferenceUI = new PreferenceController.PreferenceUI() {
|
private final PreferenceController.PreferenceUI preferenceUI = new PreferenceController.PreferenceUI() {
|
||||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
private PreferenceFragmentCompat fragment;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Preference findPreference(CharSequence key) {
|
public void setFragment(PreferenceFragmentCompat fragment) {
|
||||||
return prefFragment.findPreference(key);
|
this.fragment = fragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Activity getActivity() {
|
public PreferenceFragmentCompat getFragment() {
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Preference findPreference(CharSequence key) {
|
||||||
|
return fragment.findPreference(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PreferenceScreen getPreferenceScreen() {
|
||||||
|
return fragment.getPreferenceScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AppCompatActivity getActivity() {
|
||||||
return PreferenceActivity.this;
|
return PreferenceActivity.this;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
// This must be the FIRST thing we do, otherwise other code may not have the
|
// This must be the FIRST thing we do, otherwise other code may not have the
|
||||||
@ -68,8 +84,21 @@ public class PreferenceActivity extends AppCompatActivity {
|
|||||||
// since the MainFragment depends on the preferenceController already being created
|
// since the MainFragment depends on the preferenceController already being created
|
||||||
preferenceController = new PreferenceController(preferenceUI);
|
preferenceController = new PreferenceController(preferenceUI);
|
||||||
|
|
||||||
prefFragment = new MainFragment();
|
showPreferenceScreen(R.xml.preferences, false);
|
||||||
getFragmentManager().beginTransaction().replace(R.id.content, prefFragment).commit();
|
}
|
||||||
|
|
||||||
|
private void showPreferenceScreen(int screen, boolean addHistory) {
|
||||||
|
PreferenceFragmentCompat prefFragment = new MainFragment();
|
||||||
|
preferenceUI.setFragment(prefFragment);
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putInt(PARAM_RESOURCE, screen);
|
||||||
|
prefFragment.setArguments(args);
|
||||||
|
if (addHistory) {
|
||||||
|
getSupportFragmentManager().beginTransaction().replace(R.id.content, prefFragment)
|
||||||
|
.addToBackStack(getString(PreferenceController.getTitleOfPage(screen))).commit();
|
||||||
|
} else {
|
||||||
|
getSupportFragmentManager().beginTransaction().replace(R.id.content, prefFragment).commit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -88,24 +117,40 @@ public class PreferenceActivity extends AppCompatActivity {
|
|||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case android.R.id.home:
|
case android.R.id.home:
|
||||||
finish();
|
if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
|
||||||
|
finish();
|
||||||
|
} else {
|
||||||
|
getSupportFragmentManager().popBackStack();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
@Override
|
||||||
public static class MainFragment extends PreferenceFragment {
|
public void onSearchResultClicked(SearchPreferenceResult result) {
|
||||||
|
showPreferenceScreen(result.getResourceFile(), true);
|
||||||
|
result.highlight(preferenceUI.getFragment());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class MainFragment extends PreferenceFragmentCompat {
|
||||||
|
private int screen;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setRetainInstance(true);
|
setRetainInstance(true);
|
||||||
addPreferencesFromResource(R.xml.preferences);
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||||
|
screen = getArguments().getInt(PARAM_RESOURCE);
|
||||||
|
addPreferencesFromResource(screen);
|
||||||
PreferenceActivity activity = instance.get();
|
PreferenceActivity activity = instance.get();
|
||||||
if(activity != null && activity.preferenceController != null) {
|
if (activity != null && activity.preferenceController != null) {
|
||||||
activity.preferenceController.onCreate();
|
activity.preferenceUI.setFragment(this);
|
||||||
|
activity.preferenceController.onCreate(screen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,15 +159,17 @@ public class PreferenceActivity extends AppCompatActivity {
|
|||||||
super.onResume();
|
super.onResume();
|
||||||
PreferenceActivity activity = instance.get();
|
PreferenceActivity activity = instance.get();
|
||||||
if(activity != null && activity.preferenceController != null) {
|
if(activity != null && activity.preferenceController != null) {
|
||||||
activity.preferenceController.onResume();
|
activity.setTitle(PreferenceController.getTitleOfPage(screen));
|
||||||
|
activity.preferenceUI.setFragment(this);
|
||||||
|
activity.preferenceController.onResume(screen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPause() {
|
public void onPause() {
|
||||||
PreferenceActivity activity = instance.get();
|
PreferenceActivity activity = instance.get();
|
||||||
if(activity != null && activity.preferenceController != null) {
|
if (screen == R.xml.preferences_gpodder) {
|
||||||
activity.preferenceController.onPause();
|
activity.preferenceController.unregisterGpodnet();
|
||||||
}
|
}
|
||||||
super.onPause();
|
super.onPause();
|
||||||
}
|
}
|
||||||
@ -130,8 +177,8 @@ public class PreferenceActivity extends AppCompatActivity {
|
|||||||
@Override
|
@Override
|
||||||
public void onStop() {
|
public void onStop() {
|
||||||
PreferenceActivity activity = instance.get();
|
PreferenceActivity activity = instance.get();
|
||||||
if(activity != null && activity.preferenceController != null) {
|
if (screen == R.xml.preferences_storage) {
|
||||||
activity.preferenceController.onStop();
|
activity.preferenceController.unsubscribeExportSubscription();
|
||||||
}
|
}
|
||||||
super.onStop();
|
super.onStop();
|
||||||
}
|
}
|
||||||
|
@ -1,97 +0,0 @@
|
|||||||
package de.danoeh.antennapod.activity;
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.res.Resources.Theme;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.preference.Preference;
|
|
||||||
import android.preference.PreferenceScreen;
|
|
||||||
|
|
||||||
import de.danoeh.antennapod.R;
|
|
||||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
|
||||||
import de.danoeh.antennapod.preferences.PreferenceController;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PreferenceActivity for API 10. In order to change the behavior of the preference UI, see
|
|
||||||
* PreferenceController.
|
|
||||||
*/
|
|
||||||
public class PreferenceActivityGingerbread extends android.preference.PreferenceActivity {
|
|
||||||
private static final String TAG = "PreferenceActivity";
|
|
||||||
private final PreferenceController.PreferenceUI preferenceUI = new PreferenceController.PreferenceUI() {
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
@Override
|
|
||||||
public Preference findPreference(CharSequence key) {
|
|
||||||
return PreferenceActivityGingerbread.this.findPreference(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Activity getActivity() {
|
|
||||||
return PreferenceActivityGingerbread.this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
private PreferenceController preferenceController;
|
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
setTheme(UserPreferences.getTheme());
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
addPreferencesFromResource(R.xml.preferences);
|
|
||||||
preferenceController = new PreferenceController(preferenceUI);
|
|
||||||
preferenceController.onCreate();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
preferenceController.onResume();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPause() {
|
|
||||||
preferenceController.onPause();
|
|
||||||
super.onPause();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStop() {
|
|
||||||
preferenceController.onStop();
|
|
||||||
super.onStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onApplyThemeResource(Theme theme, int resid, boolean first) {
|
|
||||||
theme.applyStyle(UserPreferences.getTheme(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
|
||||||
preferenceController.onActivityResult(requestCode, resultCode, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
@Override
|
|
||||||
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
|
|
||||||
Preference preference) {
|
|
||||||
super.onPreferenceTreeClick(preferenceScreen, preference);
|
|
||||||
if (preference != null)
|
|
||||||
if (preference instanceof PreferenceScreen)
|
|
||||||
if (((PreferenceScreen) preference).getDialog() != null)
|
|
||||||
((PreferenceScreen) preference)
|
|
||||||
.getDialog()
|
|
||||||
.getWindow()
|
|
||||||
.getDecorView()
|
|
||||||
.setBackgroundDrawable(
|
|
||||||
this.getWindow().getDecorView()
|
|
||||||
.getBackground().getConstantState()
|
|
||||||
.newDrawable()
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,23 +1,50 @@
|
|||||||
package de.danoeh.antennapod.activity;
|
package de.danoeh.antennapod.activity;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.graphics.PorterDuff;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v4.graphics.drawable.DrawableCompat;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
|
import de.danoeh.antennapod.R;
|
||||||
|
import de.danoeh.antennapod.core.storage.PodDBAdapter;
|
||||||
|
import rx.Completable;
|
||||||
|
import rx.android.schedulers.AndroidSchedulers;
|
||||||
|
import rx.schedulers.Schedulers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creator: vbarad
|
* Shows the AntennaPod logo while waiting for the main activity to start
|
||||||
* Date: 2016-12-03
|
|
||||||
* Project: AntennaPod
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class SplashActivity extends AppCompatActivity {
|
public class SplashActivity extends AppCompatActivity {
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.splash);
|
||||||
|
|
||||||
Intent intent = new Intent(this, MainActivity.class);
|
ProgressBar progressBar = findViewById(R.id.progressBar);
|
||||||
startActivity(intent);
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||||
finish();
|
Drawable wrapDrawable = DrawableCompat.wrap(progressBar.getIndeterminateDrawable());
|
||||||
}
|
DrawableCompat.setTint(wrapDrawable, 0xffffffff);
|
||||||
|
progressBar.setIndeterminateDrawable(DrawableCompat.unwrap(wrapDrawable));
|
||||||
|
} else {
|
||||||
|
progressBar.getIndeterminateDrawable().setColorFilter(0xffffffff, PorterDuff.Mode.SRC_IN);
|
||||||
|
}
|
||||||
|
|
||||||
|
Completable.create(subscriber -> {
|
||||||
|
// Trigger schema updates
|
||||||
|
PodDBAdapter.getInstance().open();
|
||||||
|
PodDBAdapter.getInstance().close();
|
||||||
|
subscriber.onCompleted();
|
||||||
|
})
|
||||||
|
.subscribeOn(Schedulers.newThread())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(() -> {
|
||||||
|
Intent intent = new Intent(SplashActivity.this, MainActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
|
finish();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -164,7 +164,7 @@ public class StorageErrorActivity extends AppCompatActivity {
|
|||||||
startActivity(new Intent(this, MainActivity.class));
|
startActivity(new Intent(this, MainActivity.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
private BroadcastReceiver mediaUpdate = new BroadcastReceiver() {
|
private final BroadcastReceiver mediaUpdate = new BroadcastReceiver() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
@ -7,29 +7,34 @@ import android.os.Build;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.support.v4.view.WindowCompat;
|
import android.support.v4.view.WindowCompat;
|
||||||
|
import android.support.v7.app.ActionBar;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.SurfaceHolder;
|
import android.view.SurfaceHolder;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.view.animation.Animation;
|
import android.view.animation.Animation;
|
||||||
import android.view.animation.AnimationUtils;
|
import android.view.animation.AnimationUtils;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.SeekBar;
|
import android.widget.SeekBar;
|
||||||
|
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.Playable;
|
||||||
|
import de.danoeh.antennapod.view.AspectRatioVideoView;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import de.danoeh.antennapod.R;
|
|
||||||
import de.danoeh.antennapod.core.feed.MediaType;
|
|
||||||
import de.danoeh.antennapod.core.service.playback.PlaybackService;
|
|
||||||
import de.danoeh.antennapod.core.service.playback.PlayerStatus;
|
|
||||||
import de.danoeh.antennapod.core.util.playback.ExternalMedia;
|
|
||||||
import de.danoeh.antennapod.core.util.playback.Playable;
|
|
||||||
import de.danoeh.antennapod.view.AspectRatioVideoView;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activity for playing video files.
|
* Activity for playing video files.
|
||||||
*/
|
*/
|
||||||
@ -45,12 +50,13 @@ public class VideoplayerActivity extends MediaplayerActivity {
|
|||||||
|
|
||||||
private VideoControlsHider videoControlsHider = new VideoControlsHider(this);
|
private VideoControlsHider videoControlsHider = new VideoControlsHider(this);
|
||||||
|
|
||||||
private AtomicBoolean isSetup = new AtomicBoolean(false);
|
private final AtomicBoolean isSetup = new AtomicBoolean(false);
|
||||||
|
|
||||||
private LinearLayout controls;
|
private LinearLayout controls;
|
||||||
private LinearLayout videoOverlay;
|
private LinearLayout videoOverlay;
|
||||||
private AspectRatioVideoView videoview;
|
private AspectRatioVideoView videoview;
|
||||||
private ProgressBar progressIndicator;
|
private ProgressBar progressIndicator;
|
||||||
|
private FrameLayout videoframe;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void chooseTheme() {
|
protected void chooseTheme() {
|
||||||
@ -70,20 +76,8 @@ public class VideoplayerActivity extends MediaplayerActivity {
|
|||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
if (getIntent().getAction() != null
|
if (TextUtils.equals(getIntent().getAction(), Intent.ACTION_VIEW)) {
|
||||||
&& getIntent().getAction().equals(Intent.ACTION_VIEW)) {
|
playExternalMedia(getIntent(), MediaType.VIDEO);
|
||||||
Intent intent = getIntent();
|
|
||||||
Log.d(TAG, "Received VIEW intent: " + intent.getData().getPath());
|
|
||||||
ExternalMedia media = new ExternalMedia(intent.getData().getPath(),
|
|
||||||
MediaType.VIDEO);
|
|
||||||
Intent launchIntent = new Intent(this, PlaybackService.class);
|
|
||||||
launchIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, media);
|
|
||||||
launchIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED,
|
|
||||||
true);
|
|
||||||
launchIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM, false);
|
|
||||||
launchIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY,
|
|
||||||
true);
|
|
||||||
startService(launchIntent);
|
|
||||||
} else if (PlaybackService.isCasting()) {
|
} else if (PlaybackService.isCasting()) {
|
||||||
Intent intent = PlaybackService.getPlayerActivityIntent(this);
|
Intent intent = PlaybackService.getPlayerActivityIntent(this);
|
||||||
if (!intent.getComponent().getClassName().equals(VideoplayerActivity.class.getName())) {
|
if (!intent.getComponent().getClassName().equals(VideoplayerActivity.class.getName())) {
|
||||||
@ -94,11 +88,28 @@ public class VideoplayerActivity extends MediaplayerActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
if (!PictureInPictureUtil.isInPictureInPictureMode(this)) {
|
||||||
|
videoControlsHider.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUserLeaveHint () {
|
||||||
|
if (!PictureInPictureUtil.isInPictureInPictureMode(this) && UserPreferences.getVideoBackgroundBehavior()
|
||||||
|
== UserPreferences.VideoBackgroundBehavior.PICTURE_IN_PICTURE) {
|
||||||
|
compatEnterPictureInPicture();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPause() {
|
protected void onPause() {
|
||||||
videoControlsHider.stop();
|
if (!PictureInPictureUtil.isInPictureInPictureMode(this)) {
|
||||||
if (controller != null && controller.getStatus() == PlayerStatus.PLAYING) {
|
if (controller != null && controller.getStatus() == PlayerStatus.PLAYING) {
|
||||||
controller.pause();
|
controller.pause();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
super.onPause();
|
super.onPause();
|
||||||
}
|
}
|
||||||
@ -126,7 +137,7 @@ public class VideoplayerActivity extends MediaplayerActivity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setupGUI() {
|
protected void setupGUI() {
|
||||||
if(isSetup.getAndSet(true)) {
|
if (isSetup.getAndSet(true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
super.setupGUI();
|
super.setupGUI();
|
||||||
@ -134,34 +145,30 @@ public class VideoplayerActivity extends MediaplayerActivity {
|
|||||||
controls = (LinearLayout) findViewById(R.id.controls);
|
controls = (LinearLayout) findViewById(R.id.controls);
|
||||||
videoOverlay = (LinearLayout) findViewById(R.id.overlay);
|
videoOverlay = (LinearLayout) findViewById(R.id.overlay);
|
||||||
videoview = (AspectRatioVideoView) findViewById(R.id.videoview);
|
videoview = (AspectRatioVideoView) findViewById(R.id.videoview);
|
||||||
|
videoframe = (FrameLayout) findViewById(R.id.videoframe);
|
||||||
progressIndicator = (ProgressBar) findViewById(R.id.progressIndicator);
|
progressIndicator = (ProgressBar) findViewById(R.id.progressIndicator);
|
||||||
videoview.getHolder().addCallback(surfaceHolderCallback);
|
videoview.getHolder().addCallback(surfaceHolderCallback);
|
||||||
videoview.setOnTouchListener(onVideoviewTouched);
|
videoframe.setOnTouchListener(onVideoviewTouched);
|
||||||
|
videoOverlay.setOnTouchListener((view, motionEvent) -> true); // To suppress touches directly below the slider
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= 16) {
|
if (Build.VERSION.SDK_INT >= 16) {
|
||||||
videoview.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
|
videoview.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
|
||||||
}
|
}
|
||||||
if (Build.VERSION.SDK_INT >= 14) {
|
videoOverlay.setFitsSystemWindows(true);
|
||||||
videoOverlay.setFitsSystemWindows(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
setupVideoControlsToggler();
|
setupVideoControlsToggler();
|
||||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||||
|
|
||||||
|
videoframe.getViewTreeObserver().addOnGlobalLayoutListener(() ->
|
||||||
|
videoview.setAvailableSize(videoframe.getWidth(), videoframe.getHeight()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onAwaitingVideoSurface() {
|
protected void onAwaitingVideoSurface() {
|
||||||
|
setupVideoAspectRatio();
|
||||||
if (videoSurfaceCreated && controller != null) {
|
if (videoSurfaceCreated && controller != null) {
|
||||||
Log.d(TAG, "Videosurface already created, setting videosurface now");
|
Log.d(TAG, "Videosurface already created, setting videosurface now");
|
||||||
|
|
||||||
Pair<Integer, Integer> videoSize = controller.getVideoSize();
|
|
||||||
if (videoSize != null && videoSize.first > 0 && videoSize.second > 0) {
|
|
||||||
Log.d(TAG, "Width,height of video: " + videoSize.first + ", " + videoSize.second);
|
|
||||||
videoview.setVideoSize(videoSize.first, videoSize.second);
|
|
||||||
} else {
|
|
||||||
Log.e(TAG, "Could not determine video size");
|
|
||||||
}
|
|
||||||
controller.setVideoSurface(videoview.getHolder());
|
controller.setVideoSurface(videoview.getHolder());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -180,8 +187,11 @@ public class VideoplayerActivity extends MediaplayerActivity {
|
|||||||
progressIndicator.setVisibility(View.INVISIBLE);
|
progressIndicator.setVisibility(View.INVISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
View.OnTouchListener onVideoviewTouched = (v, event) -> {
|
private final View.OnTouchListener onVideoviewTouched = (v, event) -> {
|
||||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||||
|
if (PictureInPictureUtil.isInPictureInPictureMode(this)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
videoControlsHider.stop();
|
videoControlsHider.stop();
|
||||||
toggleVideoControlsVisibility();
|
toggleVideoControlsVisibility();
|
||||||
if (videoControlsShowing) {
|
if (videoControlsShowing) {
|
||||||
@ -194,11 +204,23 @@ public class VideoplayerActivity extends MediaplayerActivity {
|
|||||||
};
|
};
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
void setupVideoControlsToggler() {
|
private void setupVideoControlsToggler() {
|
||||||
videoControlsHider.stop();
|
videoControlsHider.stop();
|
||||||
videoControlsHider.start();
|
videoControlsHider.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setupVideoAspectRatio() {
|
||||||
|
if (videoSurfaceCreated && controller != null) {
|
||||||
|
Pair<Integer, Integer> videoSize = controller.getVideoSize();
|
||||||
|
if (videoSize != null && videoSize.first > 0 && videoSize.second > 0) {
|
||||||
|
Log.d(TAG, "Width,height of video: " + videoSize.first + ", " + videoSize.second);
|
||||||
|
videoview.setVideoSize(videoSize.first, videoSize.second);
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "Could not determine video size");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void toggleVideoControlsVisibility() {
|
private void toggleVideoControlsVisibility() {
|
||||||
if (videoControlsShowing) {
|
if (videoControlsShowing) {
|
||||||
getSupportActionBar().hide();
|
getSupportActionBar().hide();
|
||||||
@ -247,14 +269,16 @@ public class VideoplayerActivity extends MediaplayerActivity {
|
|||||||
Log.e(TAG, "Couldn't attach surface to mediaplayer - reference to service was null");
|
Log.e(TAG, "Couldn't attach surface to mediaplayer - reference to service was null");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
setupVideoAspectRatio();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||||
Log.d(TAG, "Videosurface was destroyed");
|
Log.d(TAG, "Videosurface was destroyed");
|
||||||
videoSurfaceCreated = false;
|
videoSurfaceCreated = false;
|
||||||
if (controller != null && !destroyingDueToReload) {
|
if (controller != null && !destroyingDueToReload
|
||||||
|
&& UserPreferences.getVideoBackgroundBehavior()
|
||||||
|
!= UserPreferences.VideoBackgroundBehavior.CONTINUE_PLAYING) {
|
||||||
controller.notifyVideoSurfaceAbandoned();
|
controller.notifyVideoSurfaceAbandoned();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -263,6 +287,13 @@ public class VideoplayerActivity extends MediaplayerActivity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onReloadNotification(int notificationCode) {
|
protected void onReloadNotification(int notificationCode) {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && PictureInPictureUtil.isInPictureInPictureMode(this)) {
|
||||||
|
if (notificationCode == PlaybackService.EXTRA_CODE_AUDIO
|
||||||
|
|| notificationCode == PlaybackService.EXTRA_CODE_CAST) {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (notificationCode == PlaybackService.EXTRA_CODE_AUDIO) {
|
if (notificationCode == PlaybackService.EXTRA_CODE_AUDIO) {
|
||||||
Log.d(TAG, "ReloadNotification received, switching to Audioplayer now");
|
Log.d(TAG, "ReloadNotification received, switching to Audioplayer now");
|
||||||
destroyingDueToReload = true;
|
destroyingDueToReload = true;
|
||||||
@ -307,28 +338,31 @@ public class VideoplayerActivity extends MediaplayerActivity {
|
|||||||
videoOverlay.startAnimation(animation);
|
videoOverlay.startAnimation(animation);
|
||||||
controls.startAnimation(animation);
|
controls.startAnimation(animation);
|
||||||
}
|
}
|
||||||
if (Build.VERSION.SDK_INT >= 14) {
|
videoview.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
|
||||||
videoview.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
private void hideVideoControls() {
|
private void hideVideoControls(boolean showAnimation) {
|
||||||
final Animation animation = AnimationUtils.loadAnimation(this, R.anim.fade_out);
|
if (showAnimation) {
|
||||||
if (animation != null) {
|
final Animation animation = AnimationUtils.loadAnimation(this, R.anim.fade_out);
|
||||||
videoOverlay.startAnimation(animation);
|
if (animation != null) {
|
||||||
controls.startAnimation(animation);
|
videoOverlay.startAnimation(animation);
|
||||||
}
|
controls.startAnimation(animation);
|
||||||
if (Build.VERSION.SDK_INT >= 14) {
|
}
|
||||||
int videoviewFlag = (Build.VERSION.SDK_INT >= 16) ? View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION : 0;
|
|
||||||
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_FLAG_FULLSCREEN
|
|
||||||
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | videoviewFlag);
|
|
||||||
videoOverlay.setFitsSystemWindows(true);
|
|
||||||
}
|
}
|
||||||
|
int videoviewFlag = (Build.VERSION.SDK_INT >= 16) ? View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION : 0;
|
||||||
|
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||||
|
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | videoviewFlag);
|
||||||
|
videoOverlay.setFitsSystemWindows(true);
|
||||||
|
|
||||||
videoOverlay.setVisibility(View.GONE);
|
videoOverlay.setVisibility(View.GONE);
|
||||||
controls.setVisibility(View.GONE);
|
controls.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void hideVideoControls() {
|
||||||
|
hideVideoControls(true);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getContentViewResourceId() {
|
protected int getContentViewResourceId() {
|
||||||
return R.layout.videoplayer_activity;
|
return R.layout.videoplayer_activity;
|
||||||
@ -344,24 +378,53 @@ public class VideoplayerActivity extends MediaplayerActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||||
|
super.onPrepareOptionsMenu(menu);
|
||||||
|
if (PictureInPictureUtil.supportsPictureInPicture(this)) {
|
||||||
|
menu.findItem(R.id.player_go_to_picture_in_picture).setVisible(true);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
if (item.getItemId() == R.id.player_go_to_picture_in_picture) {
|
||||||
|
compatEnterPictureInPicture();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void compatEnterPictureInPicture() {
|
||||||
|
if (PictureInPictureUtil.supportsPictureInPicture(this) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
|
getSupportActionBar().hide();
|
||||||
|
hideVideoControls(false);
|
||||||
|
enterPictureInPictureMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static class VideoControlsHider extends Handler {
|
private static class VideoControlsHider extends Handler {
|
||||||
|
|
||||||
private static final int DELAY = 2500;
|
private static final int DELAY = 2500;
|
||||||
|
|
||||||
private WeakReference<VideoplayerActivity> activity;
|
private WeakReference<VideoplayerActivity> activity;
|
||||||
|
|
||||||
public VideoControlsHider(VideoplayerActivity activity) {
|
VideoControlsHider(VideoplayerActivity activity) {
|
||||||
this.activity = new WeakReference<>(activity);
|
this.activity = new WeakReference<>(activity);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Runnable hideVideoControls = () -> {
|
private final Runnable hideVideoControls = () -> {
|
||||||
VideoplayerActivity vpa = activity.get();
|
VideoplayerActivity vpa = activity != null ? activity.get() : null;
|
||||||
if(vpa == null) {
|
if (vpa == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (vpa.videoControlsShowing) {
|
if (vpa.videoControlsShowing) {
|
||||||
Log.d(TAG, "Hiding video controls");
|
Log.d(TAG, "Hiding video controls");
|
||||||
vpa.getSupportActionBar().hide();
|
ActionBar actionBar = vpa.getSupportActionBar();
|
||||||
|
if (actionBar != null) {
|
||||||
|
actionBar.hide();
|
||||||
|
}
|
||||||
vpa.hideVideoControls();
|
vpa.hideVideoControls();
|
||||||
vpa.videoControlsShowing = false;
|
vpa.videoControlsShowing = false;
|
||||||
}
|
}
|
||||||
@ -371,7 +434,7 @@ public class VideoplayerActivity extends MediaplayerActivity {
|
|||||||
this.postDelayed(hideVideoControls, DELAY);
|
this.postDelayed(hideVideoControls, DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop() {
|
void stop() {
|
||||||
this.removeCallbacks(hideVideoControls);
|
this.removeCallbacks(hideVideoControls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ public class GpodnetAuthenticationActivity extends AppCompatActivity {
|
|||||||
private volatile String password;
|
private volatile String password;
|
||||||
private volatile GpodnetDevice selectedDevice;
|
private volatile GpodnetDevice selectedDevice;
|
||||||
|
|
||||||
View[] views;
|
private View[] views;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@ -171,11 +171,7 @@ public class GpodnetAuthenticationActivity extends AppCompatActivity {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
|
authTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, service);
|
||||||
authTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, service);
|
|
||||||
} else {
|
|
||||||
authTask.execute();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package de.danoeh.antennapod.adapter;
|
|||||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||||
import de.danoeh.antennapod.core.util.LongList;
|
import de.danoeh.antennapod.core.util.LongList;
|
||||||
|
|
||||||
public interface ActionButtonCallback {
|
interface ActionButtonCallback {
|
||||||
/** Is called when the action button of a list item has been pressed. */
|
/** Is called when the action button of a list item has been pressed. */
|
||||||
void onActionButtonPressed(FeedItem item, LongList queueIds);
|
void onActionButtonPressed(FeedItem item, LongList queueIds);
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ import de.danoeh.antennapod.core.storage.DownloadRequester;
|
|||||||
* Utility methods for the action button that is displayed on the right hand side
|
* Utility methods for the action button that is displayed on the right hand side
|
||||||
* of a listitem.
|
* of a listitem.
|
||||||
*/
|
*/
|
||||||
public class ActionButtonUtils {
|
class ActionButtonUtils {
|
||||||
|
|
||||||
private final int[] labels;
|
private final int[] labels;
|
||||||
private final TypedArray drawables;
|
private final TypedArray drawables;
|
||||||
|
@ -21,7 +21,6 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
import com.bumptech.glide.Glide;
|
||||||
import com.joanzapata.iconify.Iconify;
|
import com.joanzapata.iconify.Iconify;
|
||||||
import com.nineoldandroids.view.ViewHelper;
|
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
@ -30,12 +29,12 @@ import de.danoeh.antennapod.activity.MainActivity;
|
|||||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||||
import de.danoeh.antennapod.core.glide.ApGlideSettings;
|
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.storage.DownloadRequester;
|
||||||
import de.danoeh.antennapod.core.util.Converter;
|
import de.danoeh.antennapod.core.util.Converter;
|
||||||
import de.danoeh.antennapod.core.util.DateUtils;
|
import de.danoeh.antennapod.core.util.DateUtils;
|
||||||
import de.danoeh.antennapod.core.util.LongList;
|
import de.danoeh.antennapod.core.util.LongList;
|
||||||
import de.danoeh.antennapod.core.util.NetworkUtils;
|
import de.danoeh.antennapod.core.util.NetworkUtils;
|
||||||
|
import de.danoeh.antennapod.core.util.ThemeUtils;
|
||||||
import de.danoeh.antennapod.fragment.ItemFragment;
|
import de.danoeh.antennapod.fragment.ItemFragment;
|
||||||
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
|
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
|
||||||
|
|
||||||
@ -68,11 +67,7 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
|
|||||||
this.actionButtonCallback = actionButtonCallback;
|
this.actionButtonCallback = actionButtonCallback;
|
||||||
this.showOnlyNewEpisodes = showOnlyNewEpisodes;
|
this.showOnlyNewEpisodes = showOnlyNewEpisodes;
|
||||||
|
|
||||||
if(UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) {
|
playingBackGroundColor = ThemeUtils.getColorFromAttr(mainActivity, R.attr.currently_playing_background);
|
||||||
playingBackGroundColor = ContextCompat.getColor(mainActivity, R.color.highlight_dark);
|
|
||||||
} else {
|
|
||||||
playingBackGroundColor = ContextCompat.getColor(mainActivity, R.color.highlight_light);
|
|
||||||
}
|
|
||||||
normalBackGroundColor = ContextCompat.getColor(mainActivity, android.R.color.transparent);
|
normalBackGroundColor = ContextCompat.getColor(mainActivity, android.R.color.transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,7 +96,6 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
|
|||||||
holder.txtvDuration = (TextView) view.findViewById(R.id.txtvDuration);
|
holder.txtvDuration = (TextView) view.findViewById(R.id.txtvDuration);
|
||||||
holder.item = null;
|
holder.item = null;
|
||||||
holder.mainActivityRef = mainActivityRef;
|
holder.mainActivityRef = mainActivityRef;
|
||||||
holder.position = -1;
|
|
||||||
// so we can grab this later
|
// so we can grab this later
|
||||||
view.setTag(holder);
|
view.setTag(holder);
|
||||||
|
|
||||||
@ -113,11 +107,10 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
|
|||||||
final FeedItem item = itemAccess.getItem(position);
|
final FeedItem item = itemAccess.getItem(position);
|
||||||
if (item == null) return;
|
if (item == null) return;
|
||||||
holder.itemView.setOnLongClickListener(v -> {
|
holder.itemView.setOnLongClickListener(v -> {
|
||||||
this.position = position;
|
this.position = holder.getAdapterPosition();
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
holder.item = item;
|
holder.item = item;
|
||||||
holder.position = position;
|
|
||||||
holder.placeholder.setVisibility(View.VISIBLE);
|
holder.placeholder.setVisibility(View.VISIBLE);
|
||||||
holder.placeholder.setText(item.getFeed().getTitle());
|
holder.placeholder.setText(item.getFeed().getTitle());
|
||||||
holder.title.setText(item.getTitle());
|
holder.title.setText(item.getTitle());
|
||||||
@ -129,9 +122,9 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
|
|||||||
holder.statusUnread.setVisibility(View.VISIBLE);
|
holder.statusUnread.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
if(item.isPlayed()) {
|
if(item.isPlayed()) {
|
||||||
ViewHelper.setAlpha(holder.content, 0.5f);
|
holder.content.setAlpha(0.5f);
|
||||||
} else {
|
} else {
|
||||||
ViewHelper.setAlpha(holder.content, 1.0f);
|
holder.content.setAlpha(1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
FeedMedia media = item.getMedia();
|
FeedMedia media = item.getMedia();
|
||||||
@ -174,7 +167,7 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
|
|||||||
holder.progress.setVisibility(View.VISIBLE);
|
holder.progress.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
holder.progress.setVisibility(View.GONE);
|
holder.progress.setVisibility(View.INVISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(media.isCurrentlyPlaying()) {
|
if(media.isCurrentlyPlaying()) {
|
||||||
@ -183,7 +176,7 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
|
|||||||
holder.container.setBackgroundColor(normalBackGroundColor);
|
holder.container.setBackgroundColor(normalBackGroundColor);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
holder.progress.setVisibility(View.GONE);
|
holder.progress.setVisibility(View.INVISIBLE);
|
||||||
holder.txtvDuration.setVisibility(View.GONE);
|
holder.txtvDuration.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,7 +221,7 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
|
|||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
private View.OnClickListener secondaryActionListener = new View.OnClickListener() {
|
private final View.OnClickListener secondaryActionListener = new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
FeedItem item = (FeedItem) v.getTag();
|
FeedItem item = (FeedItem) v.getTag();
|
||||||
@ -253,7 +246,6 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
|
|||||||
ImageButton butSecondary;
|
ImageButton butSecondary;
|
||||||
FeedItem item;
|
FeedItem item;
|
||||||
WeakReference<MainActivity> mainActivityRef;
|
WeakReference<MainActivity> mainActivityRef;
|
||||||
int position;
|
|
||||||
|
|
||||||
public Holder(View itemView) {
|
public Holder(View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
@ -266,18 +258,18 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
|
|||||||
MainActivity mainActivity = mainActivityRef.get();
|
MainActivity mainActivity = mainActivityRef.get();
|
||||||
if (mainActivity != null) {
|
if (mainActivity != null) {
|
||||||
long[] ids = itemAccess.getItemsIds().toArray();
|
long[] ids = itemAccess.getItemsIds().toArray();
|
||||||
mainActivity.loadChildFragment(ItemFragment.newInstance(ids, position));
|
mainActivity.loadChildFragment(ItemFragment.newInstance(ids, getAdapterPosition()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onItemSelected() {
|
public void onItemSelected() {
|
||||||
ViewHelper.setAlpha(itemView, 0.5f);
|
itemView.setAlpha(0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onItemClear() {
|
public void onItemClear() {
|
||||||
ViewHelper.setAlpha(itemView, 1.0f);
|
itemView.setAlpha(1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FeedItem getFeedItem() { return item; }
|
public FeedItem getFeedItem() { return item; }
|
||||||
@ -303,6 +295,8 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
FeedItemMenuHandler.onPrepareMenu(contextMenuInterface, item, true, null);
|
FeedItemMenuHandler.onPrepareMenu(contextMenuInterface, item, true, null);
|
||||||
|
|
||||||
|
contextMenuInterface.setItemVisibility(R.id.mark_as_seen_item, item.isNew());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ import android.text.Spannable;
|
|||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
import android.text.style.ClickableSpan;
|
import android.text.style.ClickableSpan;
|
||||||
import android.text.util.Linkify;
|
import android.text.util.Linkify;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@ -20,9 +19,9 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
import de.danoeh.antennapod.core.feed.Chapter;
|
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.ChapterUtils;
|
||||||
import de.danoeh.antennapod.core.util.Converter;
|
import de.danoeh.antennapod.core.util.Converter;
|
||||||
|
import de.danoeh.antennapod.core.util.ThemeUtils;
|
||||||
import de.danoeh.antennapod.core.util.playback.Playable;
|
import de.danoeh.antennapod.core.util.playback.Playable;
|
||||||
|
|
||||||
public class ChaptersListAdapter extends ArrayAdapter<Chapter> {
|
public class ChaptersListAdapter extends ArrayAdapter<Chapter> {
|
||||||
@ -144,9 +143,7 @@ public class ChaptersListAdapter extends ArrayAdapter<Chapter> {
|
|||||||
|
|
||||||
Chapter current = ChapterUtils.getCurrentChapter(media);
|
Chapter current = ChapterUtils.getCurrentChapter(media);
|
||||||
if (current == sc) {
|
if (current == sc) {
|
||||||
boolean darkTheme = UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark;
|
int playingBackGroundColor = ThemeUtils.getColorFromAttr(getContext(), R.attr.currently_playing_background);
|
||||||
int highlight = darkTheme ? R.color.highlight_dark : R.color.highlight_light;
|
|
||||||
int playingBackGroundColor = ContextCompat.getColor(getContext(), highlight);
|
|
||||||
holder.view.setBackgroundColor(playingBackGroundColor);
|
holder.view.setBackgroundColor(playingBackGroundColor);
|
||||||
} else {
|
} else {
|
||||||
holder.view.setBackgroundColor(ContextCompat.getColor(getContext(), android.R.color.transparent));
|
holder.view.setBackgroundColor(ContextCompat.getColor(getContext(), android.R.color.transparent));
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package de.danoeh.antennapod.adapter;
|
package de.danoeh.antennapod.adapter;
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.net.Uri;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
@ -6,6 +6,8 @@ import android.widget.Toast;
|
|||||||
|
|
||||||
import com.afollestad.materialdialogs.MaterialDialog;
|
import com.afollestad.materialdialogs.MaterialDialog;
|
||||||
|
|
||||||
|
import de.danoeh.antennapod.core.util.IntentUtils;
|
||||||
|
import de.danoeh.antennapod.core.util.playback.PlaybackServiceStarter;
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
|
|
||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
@ -80,13 +82,19 @@ public class DefaultActionButtonCallback implements ActionButtonCallback {
|
|||||||
Toast.makeText(context, R.string.download_canceled_msg, Toast.LENGTH_LONG).show();
|
Toast.makeText(context, R.string.download_canceled_msg, Toast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
} else { // media is downloaded
|
} else { // media is downloaded
|
||||||
if (item.hasMedia() && item.getMedia().isCurrentlyPlaying()) {
|
if (media.isCurrentlyPlaying()) {
|
||||||
context.sendBroadcast(new Intent(PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE));
|
new PlaybackServiceStarter(context, media)
|
||||||
}
|
.startWhenPrepared(true)
|
||||||
else if (item.hasMedia() && item.getMedia().isCurrentlyPaused()) {
|
.shouldStream(false)
|
||||||
context.sendBroadcast(new Intent(PlaybackService.ACTION_RESUME_PLAY_CURRENT_EPISODE));
|
.start();
|
||||||
}
|
IntentUtils.sendLocalBroadcast(context, PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE);
|
||||||
else {
|
} else if (media.isCurrentlyPaused()) {
|
||||||
|
new PlaybackServiceStarter(context, media)
|
||||||
|
.startWhenPrepared(true)
|
||||||
|
.shouldStream(false)
|
||||||
|
.start();
|
||||||
|
IntentUtils.sendLocalBroadcast(context, PlaybackService.ACTION_RESUME_PLAY_CURRENT_EPISODE);
|
||||||
|
} else {
|
||||||
DBTasks.playMedia(context, media, false, true, false);
|
DBTasks.playMedia(context, media, false, true, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@ import com.joanzapata.iconify.widget.IconTextView;
|
|||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
|
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
|
||||||
import de.danoeh.antennapod.core.feed.Feed;
|
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.feed.FeedMedia;
|
||||||
import de.danoeh.antennapod.core.service.download.DownloadStatus;
|
import de.danoeh.antennapod.core.service.download.DownloadStatus;
|
||||||
import de.danoeh.antennapod.core.storage.DBReader;
|
import de.danoeh.antennapod.core.storage.DBReader;
|
||||||
@ -29,11 +28,11 @@ import de.danoeh.antennapod.core.storage.DownloadRequestException;
|
|||||||
/** Displays a list of DownloadStatus entries. */
|
/** Displays a list of DownloadStatus entries. */
|
||||||
public class DownloadLogAdapter extends BaseAdapter {
|
public class DownloadLogAdapter extends BaseAdapter {
|
||||||
|
|
||||||
private final String TAG = "DownloadLogAdapter";
|
private static final String TAG = "DownloadLogAdapter";
|
||||||
|
|
||||||
private Context context;
|
private final Context context;
|
||||||
|
|
||||||
private ItemAccess itemAccess;
|
private final ItemAccess itemAccess;
|
||||||
|
|
||||||
public DownloadLogAdapter(Context context, ItemAccess itemAccess) {
|
public DownloadLogAdapter(Context context, ItemAccess itemAccess) {
|
||||||
super();
|
super();
|
||||||
@ -67,8 +66,6 @@ public class DownloadLogAdapter extends BaseAdapter {
|
|||||||
holder.type.setText(R.string.download_type_feed);
|
holder.type.setText(R.string.download_type_feed);
|
||||||
} else if (status.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
|
} else if (status.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
|
||||||
holder.type.setText(R.string.download_type_media);
|
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) {
|
if (status.getTitle() != null) {
|
||||||
holder.title.setText(status.getTitle());
|
holder.title.setText(status.getTitle());
|
||||||
@ -94,8 +91,7 @@ public class DownloadLogAdapter extends BaseAdapter {
|
|||||||
}
|
}
|
||||||
holder.reason.setText(reasonText);
|
holder.reason.setText(reasonText);
|
||||||
holder.reason.setVisibility(View.VISIBLE);
|
holder.reason.setVisibility(View.VISIBLE);
|
||||||
if(status.getFeedfileType() != FeedImage.FEEDFILETYPE_FEEDIMAGE &&
|
if(!newerWasSuccessful(position, status.getFeedfileType(), status.getFeedfileId())) {
|
||||||
!newerWasSuccessful(position, status.getFeedfileType(), status.getFeedfileId())) {
|
|
||||||
holder.retry.setVisibility(View.VISIBLE);
|
holder.retry.setVisibility(View.VISIBLE);
|
||||||
holder.retry.setOnClickListener(clickListener);
|
holder.retry.setOnClickListener(clickListener);
|
||||||
ButtonHolder btnHolder;
|
ButtonHolder btnHolder;
|
||||||
|
@ -12,11 +12,11 @@ import android.widget.ImageView;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
import com.bumptech.glide.Glide;
|
||||||
import com.nineoldandroids.view.ViewHelper;
|
|
||||||
|
|
||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||||
import de.danoeh.antennapod.core.glide.ApGlideSettings;
|
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.Converter;
|
||||||
import de.danoeh.antennapod.core.util.DateUtils;
|
import de.danoeh.antennapod.core.util.DateUtils;
|
||||||
|
|
||||||
@ -87,9 +87,9 @@ public class DownloadedEpisodesListAdapter extends BaseAdapter {
|
|||||||
.into(holder.imageView);
|
.into(holder.imageView);
|
||||||
|
|
||||||
if(item.isPlayed()) {
|
if(item.isPlayed()) {
|
||||||
ViewHelper.setAlpha(convertView, 0.5f);
|
convertView.setAlpha(0.5f);
|
||||||
} else {
|
} else {
|
||||||
ViewHelper.setAlpha(convertView, 1.0f);
|
convertView.setAlpha(1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
holder.title.setText(item.getTitle());
|
holder.title.setText(item.getTitle());
|
||||||
@ -99,10 +99,12 @@ public class DownloadedEpisodesListAdapter extends BaseAdapter {
|
|||||||
holder.pubDate.setText(pubDateStr);
|
holder.pubDate.setText(pubDateStr);
|
||||||
|
|
||||||
FeedItem.State state = item.getState();
|
FeedItem.State state = item.getState();
|
||||||
if (state == FeedItem.State.PLAYING) {
|
if (state == FeedItem.State.PLAYING && PlaybackService.isRunning) {
|
||||||
holder.butSecondary.setEnabled(false);
|
holder.butSecondary.setEnabled(false);
|
||||||
|
holder.butSecondary.setAlpha(0.5f);
|
||||||
} else {
|
} else {
|
||||||
holder.butSecondary.setEnabled(true);
|
holder.butSecondary.setEnabled(true);
|
||||||
|
holder.butSecondary.setAlpha(1.0f);
|
||||||
}
|
}
|
||||||
holder.butSecondary.setFocusable(false);
|
holder.butSecondary.setFocusable(false);
|
||||||
holder.butSecondary.setTag(item);
|
holder.butSecondary.setTag(item);
|
||||||
@ -111,7 +113,7 @@ public class DownloadedEpisodesListAdapter extends BaseAdapter {
|
|||||||
return convertView;
|
return convertView;
|
||||||
}
|
}
|
||||||
|
|
||||||
private View.OnClickListener secondaryActionListener = new View.OnClickListener() {
|
private final View.OnClickListener secondaryActionListener = new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
FeedItem item = (FeedItem) v.getTag();
|
FeedItem item = (FeedItem) v.getTag();
|
||||||
|
@ -19,11 +19,11 @@ import de.danoeh.antennapod.core.util.ThemeUtils;
|
|||||||
|
|
||||||
public class DownloadlistAdapter extends BaseAdapter {
|
public class DownloadlistAdapter extends BaseAdapter {
|
||||||
|
|
||||||
public static final int SELECTION_NONE = -1;
|
private static final int SELECTION_NONE = -1;
|
||||||
|
|
||||||
private int selectedItemIndex;
|
private int selectedItemIndex;
|
||||||
private ItemAccess itemAccess;
|
private final ItemAccess itemAccess;
|
||||||
private Context context;
|
private final Context context;
|
||||||
|
|
||||||
public DownloadlistAdapter(Context context,
|
public DownloadlistAdapter(Context context,
|
||||||
ItemAccess itemAccess) {
|
ItemAccess itemAccess) {
|
||||||
@ -105,7 +105,7 @@ public class DownloadlistAdapter extends BaseAdapter {
|
|||||||
return convertView;
|
return convertView;
|
||||||
}
|
}
|
||||||
|
|
||||||
private View.OnClickListener butSecondaryListener = new View.OnClickListener() {
|
private final View.OnClickListener butSecondaryListener = new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
Downloader downloader = (Downloader) v.getTag();
|
Downloader downloader = (Downloader) v.getTag();
|
||||||
@ -121,15 +121,6 @@ public class DownloadlistAdapter extends BaseAdapter {
|
|||||||
ImageButton butSecondary;
|
ImageButton butSecondary;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSelectedItemIndex() {
|
|
||||||
return selectedItemIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSelectedItemIndex(int selectedItemIndex) {
|
|
||||||
this.selectedItemIndex = selectedItemIndex;
|
|
||||||
notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface ItemAccess {
|
public interface ItemAccess {
|
||||||
int getCount();
|
int getCount();
|
||||||
|
|
||||||
|
@ -17,13 +17,10 @@ import android.widget.LinearLayout;
|
|||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.nineoldandroids.view.ViewHelper;
|
|
||||||
|
|
||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||||
import de.danoeh.antennapod.core.feed.MediaType;
|
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.storage.DownloadRequester;
|
||||||
import de.danoeh.antennapod.core.util.DateUtils;
|
import de.danoeh.antennapod.core.util.DateUtils;
|
||||||
import de.danoeh.antennapod.core.util.LongList;
|
import de.danoeh.antennapod.core.util.LongList;
|
||||||
@ -34,16 +31,16 @@ import de.danoeh.antennapod.core.util.ThemeUtils;
|
|||||||
*/
|
*/
|
||||||
public class FeedItemlistAdapter extends BaseAdapter {
|
public class FeedItemlistAdapter extends BaseAdapter {
|
||||||
|
|
||||||
private ActionButtonCallback callback;
|
private final ActionButtonCallback callback;
|
||||||
private final ItemAccess itemAccess;
|
private final ItemAccess itemAccess;
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private boolean showFeedtitle;
|
private final boolean showFeedtitle;
|
||||||
private int selectedItemIndex;
|
private final int selectedItemIndex;
|
||||||
/** true if played items should be made partially transparent */
|
/** true if played items should be made partially transparent */
|
||||||
private boolean makePlayedItemsTransparent;
|
private final boolean makePlayedItemsTransparent;
|
||||||
private final ActionButtonUtils actionButtonUtils;
|
private final ActionButtonUtils actionButtonUtils;
|
||||||
|
|
||||||
public static final int SELECTION_NONE = -1;
|
private static final int SELECTION_NONE = -1;
|
||||||
|
|
||||||
private final int playingBackGroundColor;
|
private final int playingBackGroundColor;
|
||||||
private final int normalBackGroundColor;
|
private final int normalBackGroundColor;
|
||||||
@ -62,11 +59,7 @@ public class FeedItemlistAdapter extends BaseAdapter {
|
|||||||
this.actionButtonUtils = new ActionButtonUtils(context);
|
this.actionButtonUtils = new ActionButtonUtils(context);
|
||||||
this.makePlayedItemsTransparent = makePlayedItemsTransparent;
|
this.makePlayedItemsTransparent = makePlayedItemsTransparent;
|
||||||
|
|
||||||
if(UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) {
|
playingBackGroundColor = ThemeUtils.getColorFromAttr(context, R.attr.currently_playing_background);
|
||||||
playingBackGroundColor = ContextCompat.getColor(context, R.color.highlight_dark);
|
|
||||||
} else {
|
|
||||||
playingBackGroundColor = ContextCompat.getColor(context, R.color.highlight_light);
|
|
||||||
}
|
|
||||||
normalBackGroundColor = ContextCompat.getColor(context, android.R.color.transparent);
|
normalBackGroundColor = ContextCompat.getColor(context, android.R.color.transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,9 +138,9 @@ public class FeedItemlistAdapter extends BaseAdapter {
|
|||||||
holder.statusUnread.setVisibility(View.INVISIBLE);
|
holder.statusUnread.setVisibility(View.INVISIBLE);
|
||||||
}
|
}
|
||||||
if(item.isPlayed() && makePlayedItemsTransparent) {
|
if(item.isPlayed() && makePlayedItemsTransparent) {
|
||||||
ViewHelper.setAlpha(convertView, 0.5f);
|
convertView.setAlpha(0.5f);
|
||||||
} else {
|
} else {
|
||||||
ViewHelper.setAlpha(convertView, 1.0f);
|
convertView.setAlpha(1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
String pubDateStr = DateUtils.formatAbbrev(context, item.getPubDate());
|
String pubDateStr = DateUtils.formatAbbrev(context, item.getPubDate());
|
||||||
@ -157,7 +150,7 @@ public class FeedItemlistAdapter extends BaseAdapter {
|
|||||||
|
|
||||||
FeedMedia media = item.getMedia();
|
FeedMedia media = item.getMedia();
|
||||||
if (media == null) {
|
if (media == null) {
|
||||||
holder.episodeProgress.setVisibility(View.GONE);
|
holder.episodeProgress.setVisibility(View.INVISIBLE);
|
||||||
holder.inPlaylist.setVisibility(View.INVISIBLE);
|
holder.inPlaylist.setVisibility(View.INVISIBLE);
|
||||||
holder.type.setVisibility(View.INVISIBLE);
|
holder.type.setVisibility(View.INVISIBLE);
|
||||||
holder.lenSize.setVisibility(View.INVISIBLE);
|
holder.lenSize.setVisibility(View.INVISIBLE);
|
||||||
@ -176,7 +169,7 @@ public class FeedItemlistAdapter extends BaseAdapter {
|
|||||||
holder.episodeProgress.setProgress(itemAccess.getItemDownloadProgressPercent(item));
|
holder.episodeProgress.setProgress(itemAccess.getItemDownloadProgressPercent(item));
|
||||||
} else {
|
} else {
|
||||||
if(media.getPosition() == 0) {
|
if(media.getPosition() == 0) {
|
||||||
holder.episodeProgress.setVisibility(View.GONE);
|
holder.episodeProgress.setVisibility(View.INVISIBLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,10 +48,10 @@ import de.danoeh.antennapod.fragment.SubscriptionFragment;
|
|||||||
public class NavListAdapter extends BaseAdapter
|
public class NavListAdapter extends BaseAdapter
|
||||||
implements SharedPreferences.OnSharedPreferenceChangeListener {
|
implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
|
|
||||||
public static final int VIEW_TYPE_COUNT = 3;
|
private static final int VIEW_TYPE_COUNT = 3;
|
||||||
public static final int VIEW_TYPE_NAV = 0;
|
public static final int VIEW_TYPE_NAV = 0;
|
||||||
public static final int VIEW_TYPE_SECTION_DIVIDER = 1;
|
public static final int VIEW_TYPE_SECTION_DIVIDER = 1;
|
||||||
public static final int VIEW_TYPE_SUBSCRIPTION = 2;
|
private static final int VIEW_TYPE_SUBSCRIPTION = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* a tag used as a placeholder to indicate if the subscription list should be displayed or not
|
* a tag used as a placeholder to indicate if the subscription list should be displayed or not
|
||||||
@ -62,8 +62,8 @@ public class NavListAdapter extends BaseAdapter
|
|||||||
private static List<String> tags;
|
private static List<String> tags;
|
||||||
private static String[] titles;
|
private static String[] titles;
|
||||||
|
|
||||||
private ItemAccess itemAccess;
|
private final ItemAccess itemAccess;
|
||||||
private WeakReference<Activity> activity;
|
private final WeakReference<Activity> activity;
|
||||||
private boolean showSubscriptionList = true;
|
private boolean showSubscriptionList = true;
|
||||||
|
|
||||||
public NavListAdapter(ItemAccess itemAccess, Activity context) {
|
public NavListAdapter(ItemAccess itemAccess, Activity context) {
|
||||||
@ -86,9 +86,7 @@ public class NavListAdapter extends BaseAdapter
|
|||||||
private void loadItems() {
|
private void loadItems() {
|
||||||
List<String> newTags = new ArrayList<>(Arrays.asList(MainActivity.NAV_DRAWER_TAGS));
|
List<String> newTags = new ArrayList<>(Arrays.asList(MainActivity.NAV_DRAWER_TAGS));
|
||||||
List<String> hiddenFragments = UserPreferences.getHiddenDrawerItems();
|
List<String> hiddenFragments = UserPreferences.getHiddenDrawerItems();
|
||||||
for(String hidden : hiddenFragments) {
|
newTags.removeAll(hiddenFragments);
|
||||||
newTags.remove(hidden);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newTags.contains(SUBSCRIPTION_LIST_TAG)) {
|
if (newTags.contains(SUBSCRIPTION_LIST_TAG)) {
|
||||||
// we never want SUBSCRIPTION_LIST_TAG to be in 'tags'
|
// we never want SUBSCRIPTION_LIST_TAG to be in 'tags'
|
||||||
|
@ -24,8 +24,8 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
import com.bumptech.glide.Glide;
|
||||||
import com.joanzapata.iconify.Iconify;
|
import com.joanzapata.iconify.Iconify;
|
||||||
import com.nineoldandroids.view.ViewHelper;
|
|
||||||
|
|
||||||
|
import de.danoeh.antennapod.core.util.ThemeUtils;
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
@ -51,7 +51,7 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap
|
|||||||
|
|
||||||
private static final String TAG = QueueRecyclerAdapter.class.getSimpleName();
|
private static final String TAG = QueueRecyclerAdapter.class.getSimpleName();
|
||||||
|
|
||||||
private WeakReference<MainActivity> mainActivity;
|
private final WeakReference<MainActivity> mainActivity;
|
||||||
private final ItemAccess itemAccess;
|
private final ItemAccess itemAccess;
|
||||||
private final ActionButtonCallback actionButtonCallback;
|
private final ActionButtonCallback actionButtonCallback;
|
||||||
private final ActionButtonUtils actionButtonUtils;
|
private final ActionButtonUtils actionButtonUtils;
|
||||||
@ -76,11 +76,7 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap
|
|||||||
this.itemTouchHelper = itemTouchHelper;
|
this.itemTouchHelper = itemTouchHelper;
|
||||||
locked = UserPreferences.isQueueLocked();
|
locked = UserPreferences.isQueueLocked();
|
||||||
|
|
||||||
if(UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) {
|
playingBackGroundColor = ThemeUtils.getColorFromAttr(mainActivity, R.attr.currently_playing_background);
|
||||||
playingBackGroundColor = ContextCompat.getColor(mainActivity, R.color.highlight_dark);
|
|
||||||
} else {
|
|
||||||
playingBackGroundColor = ContextCompat.getColor(mainActivity, R.color.highlight_light);
|
|
||||||
}
|
|
||||||
normalBackGroundColor = ContextCompat.getColor(mainActivity, android.R.color.transparent);
|
normalBackGroundColor = ContextCompat.getColor(mainActivity, android.R.color.transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,12 +194,12 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onItemSelected() {
|
public void onItemSelected() {
|
||||||
ViewHelper.setAlpha(itemView, 0.5f);
|
itemView.setAlpha(0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onItemClear() {
|
public void onItemClear() {
|
||||||
ViewHelper.setAlpha(itemView, 1.0f);
|
itemView.setAlpha(1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind(FeedItem item) {
|
public void bind(FeedItem item) {
|
||||||
@ -280,7 +276,7 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap
|
|||||||
progressLeft.setText("");
|
progressLeft.setText("");
|
||||||
}
|
}
|
||||||
progressRight.setText(Converter.getDurationStringLong(media.getDuration()));
|
progressRight.setText(Converter.getDurationStringLong(media.getDuration()));
|
||||||
progressBar.setVisibility(View.GONE);
|
progressBar.setVisibility(View.INVISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(media.isCurrentlyPlaying()) {
|
if(media.isCurrentlyPlaying()) {
|
||||||
@ -305,7 +301,7 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private View.OnClickListener secondaryActionListener = new View.OnClickListener() {
|
private final View.OnClickListener secondaryActionListener = new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
FeedItem item = (FeedItem) v.getTag();
|
FeedItem item = (FeedItem) v.getTag();
|
||||||
|
@ -11,7 +11,6 @@ import android.widget.ImageView;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
import com.bumptech.glide.Glide;
|
||||||
import com.nineoldandroids.view.ViewHelper;
|
|
||||||
|
|
||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
import de.danoeh.antennapod.core.feed.Feed;
|
import de.danoeh.antennapod.core.feed.Feed;
|
||||||
@ -97,7 +96,7 @@ public class SearchlistAdapter extends BaseAdapter {
|
|||||||
holder.subtitle.setText(result.getSubtitle());
|
holder.subtitle.setText(result.getSubtitle());
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewHelper.setAlpha(convertView, item.isPlayed() ? 0.5f : 1.0f);
|
convertView.setAlpha(item.isPlayed() ? 0.5f : 1.0f);
|
||||||
|
|
||||||
Glide.with(context)
|
Glide.with(context)
|
||||||
.load(item.getFeed().getImageLocation())
|
.load(item.getFeed().getImageLocation())
|
||||||
|
@ -23,8 +23,8 @@ import de.danoeh.antennapod.core.util.Converter;
|
|||||||
* Adapter for the statistics list
|
* Adapter for the statistics list
|
||||||
*/
|
*/
|
||||||
public class StatisticsListAdapter extends BaseAdapter {
|
public class StatisticsListAdapter extends BaseAdapter {
|
||||||
private Context context;
|
private final Context context;
|
||||||
List<DBReader.StatisticsItem> feedTime = new ArrayList<>();
|
private List<DBReader.StatisticsItem> feedTime = new ArrayList<>();
|
||||||
private boolean countAll = true;
|
private boolean countAll = true;
|
||||||
|
|
||||||
public StatisticsListAdapter(Context context) {
|
public StatisticsListAdapter(Context context) {
|
||||||
|
@ -50,7 +50,6 @@ public class SubscriptionsAdapter extends BaseAdapter implements AdapterView.OnI
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int getAdjustedPosition(int origPosition) {
|
private int getAdjustedPosition(int origPosition) {
|
||||||
assert(origPosition != getAddTilePosition());
|
|
||||||
return origPosition < getAddTilePosition() ? origPosition : origPosition - 1;
|
return origPosition < getAddTilePosition() ? origPosition : origPosition - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ public class ItunesAdapter extends ArrayAdapter<ItunesAdapter.Podcast> {
|
|||||||
* @param json object holding the podcast information
|
* @param json object holding the podcast information
|
||||||
* @throws JSONException
|
* @throws JSONException
|
||||||
*/
|
*/
|
||||||
public static Podcast fromSearch(JSONObject json) throws JSONException {
|
public static Podcast fromSearch(JSONObject json) {
|
||||||
String title = json.optString("collectionName", "");
|
String title = json.optString("collectionName", "");
|
||||||
String imageUrl = json.optString("artworkUrl100", null);
|
String imageUrl = json.optString("artworkUrl100", null);
|
||||||
String feedUrl = json.optString("feedUrl", null);
|
String feedUrl = json.optString("feedUrl", null);
|
||||||
@ -162,7 +162,7 @@ public class ItunesAdapter extends ArrayAdapter<ItunesAdapter.Podcast> {
|
|||||||
/**
|
/**
|
||||||
* View holder object for the GridView
|
* View holder object for the GridView
|
||||||
*/
|
*/
|
||||||
class PodcastViewHolder {
|
static class PodcastViewHolder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ImageView holding the Podcast image
|
* ImageView holding the Podcast image
|
||||||
|
@ -23,15 +23,15 @@ public class ExportWorker {
|
|||||||
private static final String TAG = "ExportWorker";
|
private static final String TAG = "ExportWorker";
|
||||||
private static final String DEFAULT_OUTPUT_NAME = "antennapod-feeds";
|
private static final String DEFAULT_OUTPUT_NAME = "antennapod-feeds";
|
||||||
|
|
||||||
private ExportWriter exportWriter;
|
private final ExportWriter exportWriter;
|
||||||
private File output;
|
private final File output;
|
||||||
|
|
||||||
public ExportWorker(ExportWriter exportWriter) {
|
public ExportWorker(ExportWriter exportWriter) {
|
||||||
this(exportWriter, new File(UserPreferences.getDataFolder(EXPORT_DIR),
|
this(exportWriter, new File(UserPreferences.getDataFolder(EXPORT_DIR),
|
||||||
DEFAULT_OUTPUT_NAME + "." + exportWriter.fileExtension()));
|
DEFAULT_OUTPUT_NAME + "." + exportWriter.fileExtension()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExportWorker(ExportWriter exportWriter, @NonNull File output) {
|
private ExportWorker(ExportWriter exportWriter, @NonNull File output) {
|
||||||
this.exportWriter = exportWriter;
|
this.exportWriter = exportWriter;
|
||||||
this.output = output;
|
this.output = output;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package de.danoeh.antennapod.asynctask;
|
package de.danoeh.antennapod.asynctask;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
@ -16,9 +15,9 @@ import de.danoeh.antennapod.core.storage.DownloadRequester;
|
|||||||
|
|
||||||
/** Queues items for download in the background. */
|
/** Queues items for download in the background. */
|
||||||
public class OpmlFeedQueuer extends AsyncTask<Void, Void, Void> {
|
public class OpmlFeedQueuer extends AsyncTask<Void, Void, Void> {
|
||||||
private Context context;
|
private final Context context;
|
||||||
private ProgressDialog progDialog;
|
private ProgressDialog progDialog;
|
||||||
private int[] selection;
|
private final int[] selection;
|
||||||
|
|
||||||
public OpmlFeedQueuer(Context context, int[] selection) {
|
public OpmlFeedQueuer(Context context, int[] selection) {
|
||||||
super();
|
super();
|
||||||
@ -56,13 +55,8 @@ public class OpmlFeedQueuer extends AsyncTask<Void, Void, Void> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
|
||||||
public void executeAsync() {
|
public void executeAsync() {
|
||||||
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
|
executeOnExecutor(THREAD_POOL_EXECUTOR);
|
||||||
executeOnExecutor(THREAD_POOL_EXECUTOR);
|
|
||||||
} else {
|
|
||||||
execute();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package de.danoeh.antennapod.asynctask;
|
package de.danoeh.antennapod.asynctask;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
@ -21,12 +20,12 @@ public class OpmlImportWorker extends
|
|||||||
AsyncTask<Void, Void, ArrayList<OpmlElement>> {
|
AsyncTask<Void, Void, ArrayList<OpmlElement>> {
|
||||||
private static final String TAG = "OpmlImportWorker";
|
private static final String TAG = "OpmlImportWorker";
|
||||||
|
|
||||||
private Context context;
|
private final Context context;
|
||||||
private Exception exception;
|
private Exception exception;
|
||||||
|
|
||||||
private ProgressDialog progDialog;
|
private ProgressDialog progDialog;
|
||||||
|
|
||||||
private Reader mReader;
|
private final Reader mReader;
|
||||||
|
|
||||||
public OpmlImportWorker(Context context, Reader reader) {
|
public OpmlImportWorker(Context context, Reader reader) {
|
||||||
super();
|
super();
|
||||||
@ -93,13 +92,8 @@ public class OpmlImportWorker extends
|
|||||||
return exception != null;
|
return exception != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
|
||||||
public void executeAsync() {
|
public void executeAsync() {
|
||||||
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
|
executeOnExecutor(THREAD_POOL_EXECUTOR);
|
||||||
executeOnExecutor(THREAD_POOL_EXECUTOR);
|
|
||||||
} else {
|
|
||||||
execute();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import de.danoeh.antennapod.core.ClientConfig;
|
|||||||
/**
|
/**
|
||||||
* Configures the ClientConfig class of the core package.
|
* Configures the ClientConfig class of the core package.
|
||||||
*/
|
*/
|
||||||
public class ClientConfigurator {
|
class ClientConfigurator {
|
||||||
|
|
||||||
private ClientConfigurator(){}
|
private ClientConfigurator(){}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package de.danoeh.antennapod.config;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
|
||||||
|
import android.os.Build;
|
||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
import de.danoeh.antennapod.activity.AudioplayerActivity;
|
import de.danoeh.antennapod.activity.AudioplayerActivity;
|
||||||
import de.danoeh.antennapod.activity.CastplayerActivity;
|
import de.danoeh.antennapod.activity.CastplayerActivity;
|
||||||
@ -18,7 +19,11 @@ public class PlaybackServiceCallbacksImpl implements PlaybackServiceCallbacks {
|
|||||||
return new Intent(context, CastplayerActivity.class);
|
return new Intent(context, CastplayerActivity.class);
|
||||||
}
|
}
|
||||||
if (mediaType == MediaType.VIDEO) {
|
if (mediaType == MediaType.VIDEO) {
|
||||||
return new Intent(context, VideoplayerActivity.class);
|
Intent i = new Intent(context, VideoplayerActivity.class);
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
i.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
|
||||||
|
}
|
||||||
|
return i;
|
||||||
} else {
|
} else {
|
||||||
return new Intent(context, AudioplayerActivity.class);
|
return new Intent(context, AudioplayerActivity.class);
|
||||||
}
|
}
|
||||||
|
@ -32,14 +32,14 @@ import de.danoeh.antennapod.core.util.LongList;
|
|||||||
|
|
||||||
public class EpisodesApplyActionFragment extends Fragment {
|
public class EpisodesApplyActionFragment extends Fragment {
|
||||||
|
|
||||||
public String TAG = "EpisodeActionFragment";
|
public static final String TAG = "EpisodeActionFragment";
|
||||||
|
|
||||||
public static final int ACTION_QUEUE = 1;
|
public static final int ACTION_QUEUE = 1;
|
||||||
public static final int ACTION_MARK_PLAYED = 2;
|
private static final int ACTION_MARK_PLAYED = 2;
|
||||||
public static final int ACTION_MARK_UNPLAYED = 4;
|
private static final int ACTION_MARK_UNPLAYED = 4;
|
||||||
public static final int ACTION_DOWNLOAD = 8;
|
private static final int ACTION_DOWNLOAD = 8;
|
||||||
public static final int ACTION_REMOVE = 16;
|
public static final int ACTION_REMOVE = 16;
|
||||||
public static final int ACTION_ALL = ACTION_QUEUE | ACTION_MARK_PLAYED | ACTION_MARK_UNPLAYED
|
private static final int ACTION_ALL = ACTION_QUEUE | ACTION_MARK_PLAYED | ACTION_MARK_UNPLAYED
|
||||||
| ACTION_DOWNLOAD | ACTION_REMOVE;
|
| ACTION_DOWNLOAD | ACTION_REMOVE;
|
||||||
|
|
||||||
private ListView mListView;
|
private ListView mListView;
|
||||||
|
@ -8,6 +8,7 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
import de.danoeh.antennapod.core.gpoddernet.GpodnetService;
|
import de.danoeh.antennapod.core.gpoddernet.GpodnetService;
|
||||||
import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
|
import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
|
||||||
|
@ -43,7 +43,7 @@ public class ProxyDialog {
|
|||||||
|
|
||||||
private static final String TAG = "ProxyDialog";
|
private static final String TAG = "ProxyDialog";
|
||||||
|
|
||||||
private Context context;
|
private final Context context;
|
||||||
|
|
||||||
private MaterialDialog dialog;
|
private MaterialDialog dialog;
|
||||||
|
|
||||||
@ -243,47 +243,44 @@ public class ProxyDialog {
|
|||||||
txtvMessage.setTextColor(textColorPrimary);
|
txtvMessage.setTextColor(textColorPrimary);
|
||||||
txtvMessage.setText("{fa-circle-o-notch spin} " + checking);
|
txtvMessage.setText("{fa-circle-o-notch spin} " + checking);
|
||||||
txtvMessage.setVisibility(View.VISIBLE);
|
txtvMessage.setVisibility(View.VISIBLE);
|
||||||
subscription = Observable.create(new Observable.OnSubscribe<Response>() {
|
subscription = Observable.create((Observable.OnSubscribe<Response>) subscriber -> {
|
||||||
@Override
|
String type = (String) spType.getSelectedItem();
|
||||||
public void call(Subscriber<? super Response> subscriber) {
|
String host = etHost.getText().toString();
|
||||||
String type = (String) spType.getSelectedItem();
|
String port = etPort.getText().toString();
|
||||||
String host = etHost.getText().toString();
|
String username = etUsername.getText().toString();
|
||||||
String port = etPort.getText().toString();
|
String password = etPassword.getText().toString();
|
||||||
String username = etUsername.getText().toString();
|
int portValue = 8080;
|
||||||
String password = etPassword.getText().toString();
|
if(!TextUtils.isEmpty(port)) {
|
||||||
int portValue = 8080;
|
portValue = Integer.valueOf(port);
|
||||||
if(!TextUtils.isEmpty(port)) {
|
}
|
||||||
portValue = Integer.valueOf(port);
|
SocketAddress address = InetSocketAddress.createUnresolved(host, portValue);
|
||||||
}
|
Proxy.Type proxyType = Proxy.Type.valueOf(type.toUpperCase());
|
||||||
SocketAddress address = InetSocketAddress.createUnresolved(host, portValue);
|
Proxy proxy = new Proxy(proxyType, address);
|
||||||
Proxy.Type proxyType = Proxy.Type.valueOf(type.toUpperCase());
|
OkHttpClient.Builder builder = AntennapodHttpClient.newBuilder()
|
||||||
Proxy proxy = new Proxy(proxyType, address);
|
.connectTimeout(10, TimeUnit.SECONDS)
|
||||||
OkHttpClient.Builder builder = AntennapodHttpClient.newBuilder()
|
.proxy(proxy);
|
||||||
.connectTimeout(10, TimeUnit.SECONDS)
|
builder.interceptors().clear();
|
||||||
.proxy(proxy);
|
OkHttpClient client = builder.build();
|
||||||
builder.interceptors().clear();
|
if(!TextUtils.isEmpty(username)) {
|
||||||
OkHttpClient client = builder.build();
|
String credentials = Credentials.basic(username, password);
|
||||||
if(!TextUtils.isEmpty(username)) {
|
client.interceptors().add(chain -> {
|
||||||
String credentials = Credentials.basic(username, password);
|
Request request = chain.request().newBuilder()
|
||||||
client.interceptors().add(chain -> {
|
.header("Proxy-Authorization", credentials).build();
|
||||||
Request request = chain.request().newBuilder()
|
return chain.proceed(request);
|
||||||
.header("Proxy-Authorization", credentials).build();
|
});
|
||||||
return chain.proceed(request);
|
}
|
||||||
});
|
Request request = new Request.Builder()
|
||||||
}
|
.url("http://www.google.com")
|
||||||
Request request = new Request.Builder()
|
.head()
|
||||||
.url("http://www.google.com")
|
.build();
|
||||||
.head()
|
try {
|
||||||
.build();
|
Response response = client.newCall(request).execute();
|
||||||
try {
|
subscriber.onNext(response);
|
||||||
Response response = client.newCall(request).execute();
|
} catch(IOException e) {
|
||||||
subscriber.onNext(response);
|
subscriber.onError(e);
|
||||||
} catch(IOException e) {
|
}
|
||||||
subscriber.onError(e);
|
subscriber.onCompleted();
|
||||||
}
|
})
|
||||||
subscriber.onCompleted();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.subscribeOn(Schedulers.newThread())
|
.subscribeOn(Schedulers.newThread())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(
|
.subscribe(
|
||||||
|
@ -56,7 +56,7 @@ public class RatingDialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void rateNow() {
|
private static void rateNow() {
|
||||||
Context context = mContext.get();
|
Context context = mContext.get();
|
||||||
if(context == null) {
|
if(context == null) {
|
||||||
return;
|
return;
|
||||||
@ -69,11 +69,11 @@ public class RatingDialog {
|
|||||||
saveRated();
|
saveRated();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean rated() {
|
private static boolean rated() {
|
||||||
return mPreferences.getBoolean(KEY_RATED, false);
|
return mPreferences.getBoolean(KEY_RATED, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void saveRated() {
|
private static void saveRated() {
|
||||||
mPreferences
|
mPreferences
|
||||||
.edit()
|
.edit()
|
||||||
.putBoolean(KEY_RATED, true)
|
.putBoolean(KEY_RATED, true)
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package de.danoeh.antennapod.dialog;
|
package de.danoeh.antennapod.dialog;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.support.design.widget.Snackbar;
|
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@ -9,7 +8,6 @@ import android.view.View;
|
|||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
import android.widget.CompoundButton;
|
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
@ -26,7 +24,7 @@ public abstract class SleepTimerDialog {
|
|||||||
|
|
||||||
private static final String TAG = SleepTimerDialog.class.getSimpleName();
|
private static final String TAG = SleepTimerDialog.class.getSimpleName();
|
||||||
|
|
||||||
private Context context;
|
private final Context context;
|
||||||
|
|
||||||
private MaterialDialog dialog;
|
private MaterialDialog dialog;
|
||||||
private EditText etxtTime;
|
private EditText etxtTime;
|
||||||
|
@ -52,7 +52,7 @@ public class VariableSpeedDialog {
|
|||||||
builder.neutralText(R.string.close_label);
|
builder.neutralText(R.string.close_label);
|
||||||
builder.onPositive((dialog, which) -> {
|
builder.onPositive((dialog, which) -> {
|
||||||
if (Build.VERSION.SDK_INT >= 16) { // just to be safe
|
if (Build.VERSION.SDK_INT >= 16) { // just to be safe
|
||||||
UserPreferences.enableSonic(true);
|
UserPreferences.enableSonic();
|
||||||
if(showSpeedSelector) {
|
if(showSpeedSelector) {
|
||||||
showSpeedSelectorDialog(context);
|
showSpeedSelectorDialog(context);
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ public class AddFeedFragment extends Fragment {
|
|||||||
/**
|
/**
|
||||||
* Preset value for url text field.
|
* Preset value for url text field.
|
||||||
*/
|
*/
|
||||||
public static final String ARG_FEED_URL = "feedurl";
|
private static final String ARG_FEED_URL = "feedurl";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
@ -66,4 +66,15 @@ public class AddFeedFragment extends Fragment {
|
|||||||
|
|
||||||
return root;
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,8 @@ import android.content.Context;
|
|||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.support.design.widget.Snackbar;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v4.view.MenuItemCompat;
|
import android.support.v4.view.MenuItemCompat;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
@ -36,12 +38,12 @@ import de.danoeh.antennapod.core.feed.EventDistributor;
|
|||||||
import de.danoeh.antennapod.core.feed.Feed;
|
import de.danoeh.antennapod.core.feed.Feed;
|
||||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
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.DownloadService;
|
||||||
import de.danoeh.antennapod.core.service.download.Downloader;
|
import de.danoeh.antennapod.core.service.download.Downloader;
|
||||||
import de.danoeh.antennapod.core.storage.DBReader;
|
import de.danoeh.antennapod.core.storage.DBReader;
|
||||||
import de.danoeh.antennapod.core.storage.DBTasks;
|
import de.danoeh.antennapod.core.storage.DBTasks;
|
||||||
import de.danoeh.antennapod.core.storage.DBWriter;
|
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.storage.DownloadRequester;
|
||||||
import de.danoeh.antennapod.core.util.FeedItemUtil;
|
import de.danoeh.antennapod.core.util.FeedItemUtil;
|
||||||
import de.danoeh.antennapod.core.util.LongList;
|
import de.danoeh.antennapod.core.util.LongList;
|
||||||
@ -69,24 +71,24 @@ public class AllEpisodesFragment extends Fragment {
|
|||||||
private static final String PREF_SCROLL_POSITION = "scroll_position";
|
private static final String PREF_SCROLL_POSITION = "scroll_position";
|
||||||
private static final String PREF_SCROLL_OFFSET = "scroll_offset";
|
private static final String PREF_SCROLL_OFFSET = "scroll_offset";
|
||||||
|
|
||||||
protected RecyclerView recyclerView;
|
RecyclerView recyclerView;
|
||||||
protected AllEpisodesRecycleAdapter listAdapter;
|
AllEpisodesRecycleAdapter listAdapter;
|
||||||
private ProgressBar progLoading;
|
private ProgressBar progLoading;
|
||||||
|
|
||||||
protected List<FeedItem> episodes;
|
List<FeedItem> episodes;
|
||||||
private List<Downloader> downloaderList;
|
private List<Downloader> downloaderList;
|
||||||
|
|
||||||
private boolean itemsLoaded = false;
|
private boolean itemsLoaded = false;
|
||||||
private boolean viewsCreated = false;
|
private boolean viewsCreated = false;
|
||||||
|
|
||||||
private boolean isUpdatingFeeds;
|
private boolean isUpdatingFeeds;
|
||||||
protected boolean isMenuInvalidationAllowed = false;
|
boolean isMenuInvalidationAllowed = false;
|
||||||
|
|
||||||
protected Subscription subscription;
|
Subscription subscription;
|
||||||
private LinearLayoutManager layoutManager;
|
private LinearLayoutManager layoutManager;
|
||||||
|
|
||||||
protected boolean showOnlyNewEpisodes() { return false; }
|
boolean showOnlyNewEpisodes() { return false; }
|
||||||
protected String getPrefName() { return DEFAULT_PREF_NAME; }
|
String getPrefName() { return DEFAULT_PREF_NAME; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
@ -165,7 +167,7 @@ public class AllEpisodesFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void resetViewState() {
|
void resetViewState() {
|
||||||
viewsCreated = false;
|
viewsCreated = false;
|
||||||
listAdapter = null;
|
listAdapter = null;
|
||||||
}
|
}
|
||||||
@ -284,13 +286,17 @@ public class AllEpisodesFragment extends Fragment {
|
|||||||
return super.onContextItemSelected(item);
|
return super.onContextItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
// Mark as seen contains UI logic specific to All/New/FavoriteSegments,
|
||||||
return FeedItemMenuHandler.onMenuItemClicked(getActivity(), item.getItemId(), selectedItem);
|
// e.g., Undo with Snackbar,
|
||||||
} catch (DownloadRequestException e) {
|
// and is handled by this class rather than the generic FeedItemMenuHandler
|
||||||
e.printStackTrace();
|
// Undo is useful for Mark as seen, given there is no UI to undo it otherwise,
|
||||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_LONG).show();
|
// 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 true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return FeedItemMenuHandler.onMenuItemClicked(getActivity(), item.getItemId(), selectedItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -299,10 +305,10 @@ public class AllEpisodesFragment extends Fragment {
|
|||||||
R.layout.all_episodes_fragment);
|
R.layout.all_episodes_fragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected View onCreateViewHelper(LayoutInflater inflater,
|
View onCreateViewHelper(LayoutInflater inflater,
|
||||||
ViewGroup container,
|
ViewGroup container,
|
||||||
Bundle savedInstanceState,
|
Bundle savedInstanceState,
|
||||||
int fragmentResource) {
|
int fragmentResource) {
|
||||||
super.onCreateView(inflater, container, savedInstanceState);
|
super.onCreateView(inflater, container, savedInstanceState);
|
||||||
|
|
||||||
View root = inflater.inflate(fragmentResource, container, false);
|
View root = inflater.inflate(fragmentResource, container, false);
|
||||||
@ -346,7 +352,7 @@ public class AllEpisodesFragment extends Fragment {
|
|||||||
updateShowOnlyEpisodesListViewState();
|
updateShowOnlyEpisodesListViewState();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AllEpisodesRecycleAdapter.ItemAccess itemAccess = new AllEpisodesRecycleAdapter.ItemAccess() {
|
private final AllEpisodesRecycleAdapter.ItemAccess itemAccess = new AllEpisodesRecycleAdapter.ItemAccess() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getCount() {
|
public int getCount() {
|
||||||
@ -444,7 +450,7 @@ public class AllEpisodesFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
|
private final EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void update(EventDistributor eventDistributor, Integer arg) {
|
public void update(EventDistributor eventDistributor, Integer arg) {
|
||||||
if ((arg & EVENTS) != 0) {
|
if ((arg & EVENTS) != 0) {
|
||||||
@ -459,7 +465,7 @@ public class AllEpisodesFragment extends Fragment {
|
|||||||
private void updateShowOnlyEpisodesListViewState() {
|
private void updateShowOnlyEpisodesListViewState() {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void loadItems() {
|
void loadItems() {
|
||||||
if(subscription != null) {
|
if(subscription != null) {
|
||||||
subscription.unsubscribe();
|
subscription.unsubscribe();
|
||||||
}
|
}
|
||||||
@ -483,8 +489,40 @@ public class AllEpisodesFragment extends Fragment {
|
|||||||
}, error -> Log.e(TAG, Log.getStackTraceString(error)));
|
}, error -> Log.e(TAG, Log.getStackTraceString(error)));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<FeedItem> loadData() {
|
List<FeedItem> loadData() {
|
||||||
return DBReader.getRecentlyPublishedEpisodes(RECENT_EPISODES_LIMIT);
|
return DBReader.getRecentlyPublishedEpisodes(RECENT_EPISODES_LIMIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void markItemAsSeenWithUndo(FeedItem item) {
|
||||||
|
if (item == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d(TAG, "markItemAsSeenWithUndo(" + item.getId() + ")");
|
||||||
|
if (subscription != null) {
|
||||||
|
subscription.unsubscribe();
|
||||||
|
}
|
||||||
|
// 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));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -140,18 +140,7 @@ public class CompletedDownloadsFragment extends ListFragment {
|
|||||||
super.onCreateOptionsMenu(menu, inflater);
|
super.onCreateOptionsMenu(menu, inflater);
|
||||||
if(items != null) {
|
if(items != null) {
|
||||||
inflater.inflate(R.menu.downloads_completed, menu);
|
inflater.inflate(R.menu.downloads_completed, menu);
|
||||||
MenuItem episodeActions = menu.findItem(R.id.episode_actions);
|
menu.findItem(R.id.episode_actions).setVisible(items.size() > 0);
|
||||||
if(items.size() > 0) {
|
|
||||||
int[] attrs = {R.attr.action_bar_icon_color};
|
|
||||||
TypedArray ta = getActivity().obtainStyledAttributes(UserPreferences.getTheme(), attrs);
|
|
||||||
int textColor = ta.getColor(0, Color.GRAY);
|
|
||||||
ta.recycle();
|
|
||||||
episodeActions.setIcon(new IconDrawable(getActivity(),
|
|
||||||
FontAwesomeIcons.fa_gears).color(textColor).actionBarSize());
|
|
||||||
episodeActions.setVisible(true);
|
|
||||||
} else {
|
|
||||||
episodeActions.setVisible(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +149,7 @@ public class CompletedDownloadsFragment extends ListFragment {
|
|||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.episode_actions:
|
case R.id.episode_actions:
|
||||||
EpisodesApplyActionFragment fragment = EpisodesApplyActionFragment
|
EpisodesApplyActionFragment fragment = EpisodesApplyActionFragment
|
||||||
.newInstance(items, EpisodesApplyActionFragment.ACTION_REMOVE);
|
.newInstance(items, EpisodesApplyActionFragment.ACTION_REMOVE | EpisodesApplyActionFragment.ACTION_QUEUE);
|
||||||
((MainActivity) getActivity()).loadChildFragment(fragment);
|
((MainActivity) getActivity()).loadChildFragment(fragment);
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
@ -168,7 +157,7 @@ public class CompletedDownloadsFragment extends ListFragment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private DownloadedEpisodesListAdapter.ItemAccess itemAccess = new DownloadedEpisodesListAdapter.ItemAccess() {
|
private final DownloadedEpisodesListAdapter.ItemAccess itemAccess = new DownloadedEpisodesListAdapter.ItemAccess() {
|
||||||
@Override
|
@Override
|
||||||
public int getCount() {
|
public int getCount() {
|
||||||
return (items != null) ? items.size() : 0;
|
return (items != null) ? items.size() : 0;
|
||||||
@ -189,7 +178,7 @@ public class CompletedDownloadsFragment extends ListFragment {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
|
private final EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void update(EventDistributor eventDistributor, Integer arg) {
|
public void update(EventDistributor eventDistributor, Integer arg) {
|
||||||
if ((arg & EVENTS) != 0) {
|
if ((arg & EVENTS) != 0) {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package de.danoeh.antennapod.fragment;
|
package de.danoeh.antennapod.fragment;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.ListFragment;
|
import android.support.v4.app.ListFragment;
|
||||||
@ -13,9 +15,11 @@ import android.widget.ListView;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import android.widget.TextView;
|
||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
import de.danoeh.antennapod.adapter.DownloadLogAdapter;
|
import de.danoeh.antennapod.adapter.DownloadLogAdapter;
|
||||||
import de.danoeh.antennapod.core.feed.EventDistributor;
|
import de.danoeh.antennapod.core.feed.EventDistributor;
|
||||||
|
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||||
import de.danoeh.antennapod.core.service.download.DownloadStatus;
|
import de.danoeh.antennapod.core.service.download.DownloadStatus;
|
||||||
import de.danoeh.antennapod.core.storage.DBReader;
|
import de.danoeh.antennapod.core.storage.DBReader;
|
||||||
import de.danoeh.antennapod.core.storage.DBWriter;
|
import de.danoeh.antennapod.core.storage.DBWriter;
|
||||||
@ -82,7 +86,30 @@ public class DownloadLogFragment extends ListFragment {
|
|||||||
getActivity().supportInvalidateOptionsMenu();
|
getActivity().supportInvalidateOptionsMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
private DownloadLogAdapter.ItemAccess itemAccess = new DownloadLogAdapter.ItemAccess() {
|
@Override
|
||||||
|
public void onListItemClick(ListView l, View v, int position, long id) {
|
||||||
|
super.onListItemClick(l, v, position, id);
|
||||||
|
|
||||||
|
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.isSuccessful()) {
|
||||||
|
message = status.getReasonDetailed();
|
||||||
|
}
|
||||||
|
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
||||||
|
builder.setTitle(R.string.download_error_details);
|
||||||
|
builder.setMessage(getString(R.string.download_error_details_message, message, url));
|
||||||
|
builder.setPositiveButton(android.R.string.ok, null);
|
||||||
|
Dialog dialog = builder.show();
|
||||||
|
((TextView) dialog.findViewById(android.R.id.message)).setTextIsSelectable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final DownloadLogAdapter.ItemAccess itemAccess = new DownloadLogAdapter.ItemAccess() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getCount() {
|
public int getCount() {
|
||||||
@ -99,7 +126,7 @@ public class DownloadLogFragment extends ListFragment {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
|
private final EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(EventDistributor eventDistributor, Integer arg) {
|
public void update(EventDistributor eventDistributor, Integer arg) {
|
||||||
|
@ -25,7 +25,7 @@ public class DownloadsFragment extends Fragment {
|
|||||||
public static final String ARG_SELECTED_TAB = "selected_tab";
|
public static final String ARG_SELECTED_TAB = "selected_tab";
|
||||||
|
|
||||||
public static final int POS_RUNNING = 0;
|
public static final int POS_RUNNING = 0;
|
||||||
public static final int POS_COMPLETED = 1;
|
private static final int POS_COMPLETED = 1;
|
||||||
public static final int POS_LOG = 2;
|
public static final int POS_LOG = 2;
|
||||||
|
|
||||||
private static final String PREF_LAST_TAB_POSITION = "tab_position";
|
private static final String PREF_LAST_TAB_POSITION = "tab_position";
|
||||||
@ -78,9 +78,9 @@ public class DownloadsFragment extends Fragment {
|
|||||||
viewPager.setCurrentItem(lastPosition);
|
viewPager.setCurrentItem(lastPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DownloadsPagerAdapter extends FragmentPagerAdapter {
|
public static class DownloadsPagerAdapter extends FragmentPagerAdapter {
|
||||||
|
|
||||||
Resources resources;
|
final Resources resources;
|
||||||
|
|
||||||
public DownloadsPagerAdapter(FragmentManager fm, Resources resources) {
|
public DownloadsPagerAdapter(FragmentManager fm, Resources resources) {
|
||||||
super(fm);
|
super(fm);
|
||||||
|
@ -21,10 +21,10 @@ public class EpisodesFragment extends Fragment {
|
|||||||
public static final String TAG = "EpisodesFragment";
|
public static final String TAG = "EpisodesFragment";
|
||||||
private static final String PREF_LAST_TAB_POSITION = "tab_position";
|
private static final String PREF_LAST_TAB_POSITION = "tab_position";
|
||||||
|
|
||||||
public static final int POS_NEW_EPISODES = 0;
|
private static final int POS_NEW_EPISODES = 0;
|
||||||
public static final int POS_ALL_EPISODES = 1;
|
private static final int POS_ALL_EPISODES = 1;
|
||||||
public static final int POS_FAV_EPISODES = 2;
|
private static final int POS_FAV_EPISODES = 2;
|
||||||
public static final int TOTAL_COUNT = 3;
|
private static final int TOTAL_COUNT = 3;
|
||||||
|
|
||||||
|
|
||||||
private TabLayout tabLayout;
|
private TabLayout tabLayout;
|
||||||
@ -79,7 +79,7 @@ public class EpisodesFragment extends Fragment {
|
|||||||
public static class EpisodesPagerAdapter extends FragmentPagerAdapter {
|
public static class EpisodesPagerAdapter extends FragmentPagerAdapter {
|
||||||
|
|
||||||
private final Resources resources;
|
private final Resources resources;
|
||||||
private AllEpisodesFragment[] fragments = {
|
private final AllEpisodesFragment[] fragments = {
|
||||||
new NewEpisodesFragment(),
|
new NewEpisodesFragment(),
|
||||||
new AllEpisodesFragment(),
|
new AllEpisodesFragment(),
|
||||||
new FavoriteEpisodesFragment()
|
new FavoriteEpisodesFragment()
|
||||||
@ -106,7 +106,7 @@ public class EpisodesFragment extends Fragment {
|
|||||||
case POS_ALL_EPISODES:
|
case POS_ALL_EPISODES:
|
||||||
return resources.getString(R.string.all_episodes_short_label);
|
return resources.getString(R.string.all_episodes_short_label);
|
||||||
case POS_NEW_EPISODES:
|
case POS_NEW_EPISODES:
|
||||||
return resources.getString(R.string.new_label);
|
return resources.getString(R.string.new_episodes_label);
|
||||||
case POS_FAV_EPISODES:
|
case POS_FAV_EPISODES:
|
||||||
return resources.getString(R.string.favorite_episodes_label);
|
return resources.getString(R.string.favorite_episodes_label);
|
||||||
default:
|
default:
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package de.danoeh.antennapod.fragment;
|
package de.danoeh.antennapod.fragment;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.app.ActivityOptionsCompat;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@ -14,11 +17,15 @@ import android.widget.TextView;
|
|||||||
import com.bumptech.glide.Glide;
|
import com.bumptech.glide.Glide;
|
||||||
|
|
||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
|
import de.danoeh.antennapod.core.feed.MediaType;
|
||||||
import de.danoeh.antennapod.core.glide.ApGlideSettings;
|
import de.danoeh.antennapod.core.glide.ApGlideSettings;
|
||||||
import de.danoeh.antennapod.core.service.playback.PlaybackService;
|
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.Playable;
|
||||||
import de.danoeh.antennapod.core.util.playback.PlaybackController;
|
import de.danoeh.antennapod.core.util.playback.PlaybackController;
|
||||||
|
import rx.Single;
|
||||||
|
import rx.Subscription;
|
||||||
|
import rx.android.schedulers.AndroidSchedulers;
|
||||||
|
import rx.schedulers.Schedulers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fragment which is supposed to be displayed outside of the MediaplayerActivity
|
* Fragment which is supposed to be displayed outside of the MediaplayerActivity
|
||||||
@ -33,8 +40,8 @@ public class ExternalPlayerFragment extends Fragment {
|
|||||||
private ImageButton butPlay;
|
private ImageButton butPlay;
|
||||||
private TextView mFeedName;
|
private TextView mFeedName;
|
||||||
private ProgressBar mProgressBar;
|
private ProgressBar mProgressBar;
|
||||||
|
|
||||||
private PlaybackController controller;
|
private PlaybackController controller;
|
||||||
|
private Subscription subscription;
|
||||||
|
|
||||||
public ExternalPlayerFragment() {
|
public ExternalPlayerFragment() {
|
||||||
super();
|
super();
|
||||||
@ -56,8 +63,15 @@ public class ExternalPlayerFragment extends Fragment {
|
|||||||
Log.d(TAG, "layoutInfo was clicked");
|
Log.d(TAG, "layoutInfo was clicked");
|
||||||
|
|
||||||
if (controller != null && controller.getMedia() != null) {
|
if (controller != null && controller.getMedia() != null) {
|
||||||
startActivity(PlaybackService.getPlayerActivityIntent(
|
Intent intent = PlaybackService.getPlayerActivityIntent(getActivity(), controller.getMedia());
|
||||||
getActivity(), controller.getMedia()));
|
|
||||||
|
if (Build.VERSION.SDK_INT >= 16 && controller.getMedia().getMediaType() == MediaType.AUDIO) {
|
||||||
|
ActivityOptionsCompat options = ActivityOptionsCompat.
|
||||||
|
makeSceneTransitionAnimation(getActivity(), imgvCover, "coverTransition");
|
||||||
|
startActivity(intent, options.toBundle());
|
||||||
|
} else {
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return root;
|
return root;
|
||||||
@ -68,10 +82,15 @@ public class ExternalPlayerFragment extends Fragment {
|
|||||||
super.onActivityCreated(savedInstanceState);
|
super.onActivityCreated(savedInstanceState);
|
||||||
controller = setupPlaybackController();
|
controller = setupPlaybackController();
|
||||||
butPlay.setOnClickListener(v -> {
|
butPlay.setOnClickListener(v -> {
|
||||||
if(controller != null) {
|
if (controller != null) {
|
||||||
controller.playPause();
|
controller.playPause();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
loadMediaInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void connectToPlaybackService() {
|
||||||
|
controller.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
private PlaybackController setupPlaybackController() {
|
private PlaybackController setupPlaybackController() {
|
||||||
@ -112,9 +131,9 @@ public class ExternalPlayerFragment extends Fragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
onPositionObserverUpdate();
|
||||||
|
|
||||||
controller.init();
|
controller.init();
|
||||||
mProgressBar.setProgress((int)
|
|
||||||
((double) controller.getPosition() / controller.getDuration() * 100));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -124,6 +143,9 @@ public class ExternalPlayerFragment extends Fragment {
|
|||||||
if (controller != null) {
|
if (controller != null) {
|
||||||
controller.release();
|
controller.release();
|
||||||
}
|
}
|
||||||
|
if (subscription != null) {
|
||||||
|
subscription.unsubscribe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -144,7 +166,7 @@ public class ExternalPlayerFragment extends Fragment {
|
|||||||
controller = setupPlaybackController();
|
controller = setupPlaybackController();
|
||||||
if (butPlay != null) {
|
if (butPlay != null) {
|
||||||
butPlay.setOnClickListener(v -> {
|
butPlay.setOnClickListener(v -> {
|
||||||
if(controller != null) {
|
if (controller != null) {
|
||||||
controller.playPause();
|
controller.playPause();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -154,50 +176,56 @@ public class ExternalPlayerFragment extends Fragment {
|
|||||||
|
|
||||||
private boolean loadMediaInfo() {
|
private boolean loadMediaInfo() {
|
||||||
Log.d(TAG, "Loading media info");
|
Log.d(TAG, "Loading media info");
|
||||||
if (controller != null && controller.serviceAvailable()) {
|
if (controller == null) {
|
||||||
Playable media = controller.getMedia();
|
Log.w(TAG, "loadMediaInfo was called while PlaybackController was null!");
|
||||||
if (media != null) {
|
|
||||||
txtvTitle.setText(media.getEpisodeTitle());
|
|
||||||
mFeedName.setText(media.getFeedTitle());
|
|
||||||
mProgressBar.setProgress((int)
|
|
||||||
((double) controller.getPosition() / controller.getDuration() * 100));
|
|
||||||
|
|
||||||
Glide.with(getActivity())
|
|
||||||
.load(media.getImageLocation())
|
|
||||||
.placeholder(R.color.light_gray)
|
|
||||||
.error(R.color.light_gray)
|
|
||||||
.diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
|
|
||||||
.fitCenter()
|
|
||||||
.dontAnimate()
|
|
||||||
.into(imgvCover);
|
|
||||||
|
|
||||||
fragmentLayout.setVisibility(View.VISIBLE);
|
|
||||||
if (controller.isPlayingVideoLocally()) {
|
|
||||||
butPlay.setVisibility(View.GONE);
|
|
||||||
} else {
|
|
||||||
butPlay.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "loadMediaInfo was called while the media object of playbackService was null!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "loadMediaInfo was called while playbackService was null!");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (subscription != null) {
|
||||||
|
subscription.unsubscribe();
|
||||||
|
}
|
||||||
|
subscription = Single.create(subscriber -> subscriber.onSuccess(controller.getMedia()))
|
||||||
|
.subscribeOn(Schedulers.newThread())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(media -> updateUi((Playable) media));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getPositionString(int position, int duration) {
|
private void updateUi(Playable media) {
|
||||||
return Converter.getDurationStringLong(position) + " / "
|
if (media != null) {
|
||||||
+ Converter.getDurationStringLong(duration);
|
txtvTitle.setText(media.getEpisodeTitle());
|
||||||
|
mFeedName.setText(media.getFeedTitle());
|
||||||
|
onPositionObserverUpdate();
|
||||||
|
|
||||||
|
Glide.with(getActivity())
|
||||||
|
.load(media.getImageLocation())
|
||||||
|
.placeholder(R.color.light_gray)
|
||||||
|
.error(R.color.light_gray)
|
||||||
|
.diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
|
||||||
|
.fitCenter()
|
||||||
|
.dontAnimate()
|
||||||
|
.into(imgvCover);
|
||||||
|
|
||||||
|
fragmentLayout.setVisibility(View.VISIBLE);
|
||||||
|
if (controller.isPlayingVideoLocally()) {
|
||||||
|
butPlay.setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
butPlay.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.w(TAG, "loadMediaInfo was called while the media object of playbackService was null!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlaybackController getPlaybackControllerTestingOnly() {
|
public PlaybackController getPlaybackControllerTestingOnly() {
|
||||||
return controller;
|
return controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onPositionObserverUpdate() {
|
private void onPositionObserverUpdate() {
|
||||||
|
if (controller.getPosition() == PlaybackService.INVALID_TIME
|
||||||
|
|| controller.getDuration() == PlaybackService.INVALID_TIME) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
mProgressBar.setProgress((int)
|
mProgressBar.setProgress((int)
|
||||||
((double) controller.getPosition() / controller.getDuration() * 100));
|
((double) controller.getPosition() / controller.getDuration() * 100));
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ import de.danoeh.antennapod.core.storage.DBWriter;
|
|||||||
|
|
||||||
public class FavoriteEpisodesFragment extends AllEpisodesFragment {
|
public class FavoriteEpisodesFragment extends AllEpisodesFragment {
|
||||||
|
|
||||||
public static final String TAG = "FavoriteEpisodesFrag";
|
private static final String TAG = "FavoriteEpisodesFrag";
|
||||||
|
|
||||||
private static final String PREF_NAME = "PrefFavoriteEpisodesFragment";
|
private static final String PREF_NAME = "PrefFavoriteEpisodesFragment";
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ public class FyydSearchFragment extends Fragment {
|
|||||||
private Button butRetry;
|
private Button butRetry;
|
||||||
private TextView txtvEmpty;
|
private TextView txtvEmpty;
|
||||||
|
|
||||||
private FyydClient client = new FyydClient(AntennapodHttpClient.getHttpClient());
|
private final FyydClient client = new FyydClient(AntennapodHttpClient.getHttpClient());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of podcasts retreived from the search
|
* List of podcasts retreived from the search
|
||||||
@ -169,7 +169,7 @@ public class FyydSearchFragment extends Fragment {
|
|||||||
progressBar.setVisibility(View.VISIBLE);
|
progressBar.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void processSearchResult(FyydResponse response) {
|
private void processSearchResult(FyydResponse response) {
|
||||||
adapter.clear();
|
adapter.clear();
|
||||||
if (!response.getData().isEmpty()) {
|
if (!response.getData().isEmpty()) {
|
||||||
adapter.clear();
|
adapter.clear();
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user