summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/ISSUE_TEMPLATE/bug_report.md35
-rw-r--r--.github/ISSUE_TEMPLATE/feature_request.md16
-rw-r--r--CHANGELOG.md6
-rw-r--r--CONTRIBUTING.md71
-rw-r--r--app/build.gradle39
-rw-r--r--app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java13
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java30
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/OpmlImportActivity.java11
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java55
-rw-r--r--app/src/main/java/de/danoeh/antennapod/view/viewholder/EpisodeItemViewHolder.java5
-rw-r--r--app/src/main/res/layout/audioplayer_fragment.xml16
-rw-r--r--build.gradle35
-rw-r--r--core/build.gradle26
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java25
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java17
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSRSS20.java13
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/syndication/util/SyndStringUtils.java14
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java4
-rw-r--r--core/src/main/res/values/dimens.xml1
-rw-r--r--createTranslatorsList.py2
21 files changed, 229 insertions, 207 deletions
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index 9f0531c01..cb7c71b63 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -9,30 +9,51 @@ DELETE ME
Use the search function to see if someone else has already submitted the same bug report.
+Try to describe the problem with as much detail as possible.
+
+Some bugs may only occur on certain devices or versions of Android. Please add information about your device and the version of Android that is running on it (you can look these up under `Settings → About Phone`), as well as which version of AntennaPod you are using.
+
+If the bug only seems to occur with a certain podcast, please include the URL of that podcast.
+
+If possible, add instructions on how to reproduce the bug.
+
+If possible, add a logfile to your post. This is especially useful if the bug makes the application crash. AntennaPod has an `export logs` feature for this.
+
+Usually, you can take a screenshot of your smartphone by pressing *Power* + *Volume down* for a few seconds.
+
You don't need to adhere to the template strictly. Feel free to leave out information you feel is not important or does not make sense.
If you are experiencing a crash, including the stacktrace will likely get it fixed sooner.
-->
-**App version**: 1.x (from Google Play/F-Droid/Custom build)
+<!-- READ THIS: The latest version may be different depending on your device. You can find the version in AntennaPod's settings. -->
+**App version**: x.y.z (state whether from Google Play/F-Droid/Custom built APK)
+
+
+**Android version**: 5.x (Please mention if you are using a custom rom!)
-**Android version**: 5.x [Please mention if you are using a custom rom!]
**Device model**:
+
**Expected behaviour**:
+
**Current behaviour**:
-**First occurred**: Version 1.x / about x days/weeks ago
-**Steps to reproduce**:
+**First occurred**: (e.g. about x days/weeks ago)
+
+**Steps to reproduce**:
1. This
-1. Than that
-1. Then
+2. Then that
+3. Then this
+4. Etc.
+
+
+**Environment**: (Settings you have changed (e.g. Auto Download). "Unusual" devices you use (e.g. Bluetooth headphones). Did you select another media player?)
-**Environment**: [Settings you have changed, e.g. Auto Download. "Unusual" devices you use, e.g. Bluetooth headphones. Did you select another media player?]
**Stacktrace/Logcat**:
```
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index 878b857c8..8719120cd 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -7,19 +7,25 @@ about: Request a new feature
<!--
DELETE ME
-Use the search function to see if someone else has already submitted the same feature request. If there already is another request, please upvote the first post instead of commenting something like "I also want this".
+Make sure you are using the latest version of AntennaPod. Perhaps the feature you are looking for has already been implemented.
+
+Use the search function to see if someone else has already submitted the same feature request. If there is another request already, please upvote the first post instead of commenting something like "I also want this".
To make it easier for us to keep track of requests, please only make one feature request per issue.
-Give a brief explanation about the problem that currently exists and why your requested feature solves this problem.
+Give a brief explanation about the problem that may currently exist and how your requested feature solves this problem.
-Try do be as specific as possible. Please not only explain what the feature does, but also how. When your request is about changing or extending the UI, describe what the UI would look like and how the user would interact with it.
+Try to be as specific as possible. Please not only explain what the feature does, but also how. If your request is about (or includes) changing or extending the UI, describe what the UI would look like and how the user would interact with it.
-->
-**App version**: 1.x (from Google Play/F-Droid/Custom build)
+<!-- READ THIS: The latest version may be different depending on your device. You can find the version in AntennaPod's settings. -->
+**App version**: x.y.z (state whether from Google Play/F-Droid/Custom built APK)
+
+
+**Problem you may be having, or feature you want**:
-**Problem you are having**:
**Suggested solution**:
+
**Screenshots / Drawings / Technical details**:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b6357a0de..8fb58a64a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,12 @@
Change Log
==========
+Version 1.8.1
+-------------
+* Enabled picture-in-picture for video podcasts by default (by @ByteHamster)
+* Fixed podcast discovery not showing local trends (by @tonytamsf)
+* Various bug fixes and improvements (by @ByteHamster)
+
Version 1.8.0
-------------
* Added per-feed playback speed setting (by @spacecowboy)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 47a7336cb..7ac62535c 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,63 +1,40 @@
How to report a bug
-------------------
-- Use the search function to see if someone else has already reported the bug. If an issue has already been opened, see if you can add any useful information to it.
-- Otherwise, create a new issue on the "issues" page
-- Describe the problem as detailed as possible.
-- Some bugs only occur on certain devices or versions of Android. Please add information about your device and the version of Android that is running on it (you can look these up under `Settings → About Phone`) as well as which version of AntennaPod you are using.
-- If the bug only seems to occur with a certain podcast, make sure to include the URL of that podcast.
+- Before anything else, please make sure you are on the latest version, the bug you are experiencing may have been fixed already!
+- Use the search function to see if someone else has already submitted the same bug report.
+- Try to describe the problem with as much detail as possible.
+- Some bugs may only occur on certain devices or versions of Android. Please add information about your device and the version of Android that is running on it (you can look these up under `Settings → About Phone`), as well as which version of AntennaPod you are using.
+- If the bug only seems to occur with a certain podcast, please include the URL of that podcast.
- If possible, add instructions on how to reproduce the bug.
-- If possible, add a logfile to your post. This is especially useful if the bug makes the application crash. You can create logfiles with an app like `aLogcat`. Just launch `alogcat`, then start AntennaPod and reproduce the bug. aLogcat should now display information about the bug when you start it.
-- Usually, you can make a screenshot of your smartphone by pressing [Power] + [Volume down] for a few seconds
-- Please use the following **template**:
-
-**App version**: 1.x (from Google Play/F-Store/Custom build)
-
-**Android version**: 5.x [Especially mention custom roms!]
-
-**Device model**:
-
-**Expected behaviour**:
-
-**Current behaviour**:
-
-**First occured**: Version 1.x / about x days/weeks ago
-
-**Steps to reproduce**:
-
-1. Do this
-1. Do that
-
-**Environment**: Settings you have changed, e.g. Auto Download. "Unusual" devices you use, e.g. Bluetooth headphones.
-
-**Stacktrace/Logcat**: [if available]
-```
-...
-```
+- If possible, add a logfile to your post. This is especially useful if the bug makes the application crash. AntennaPod has an `export logs` feature for this.
+- Usually, you can take a screenshot of your smartphone by pressing *Power* + *Volume down* for a few seconds.
+- Please use the following **[template](.github/ISSUE_TEMPLATE/bug_report.md)**.
How to submit a feature request
-------------------------------
- Make sure you are using the latest version of AntennaPod. Perhaps the feature you are looking for has already been implemented.
-- Use the search function to see if someone else has already submitted the same feature request.
-- If an issue has already been opened, see if you can add anything useful to it.
-- Otherwise, create a new issue on the "issues" page
-- To make it easier for us to keep track of requests, please only make one feature request per issue
-- Give a brief explanation about the problem that currently exists and why your requested feature solves this problem.
-- Try do be as specific as possible. Please not only explain *what* the feature does, but also *how*. When your request is about changing or extending the UI, describe what the UI would look like and how the user would interact with it.
+- Use the search function to see if someone else has already submitted the same feature request. If there is another request already, please upvote the first post instead of commenting something like "I also want this".
+- To make it easier for us to keep track of requests, please only make one feature request per issue.
+- Give a brief explanation about the problem that may currently exist and how your requested feature solves this problem.
+- Try to be as specific as possible. Please not only explain what the feature does, but also how. If your request is about (or includes) changing or extending the UI, describe what the UI would look like and how the user would interact with it.
+
Translating AntennaPod
----------------------
-If you would like to translate the app into another language or improve an existing translation, you can visit the [Transifex project page](https://www.transifex.com/projects/p/antennapod/). From there, you can either join a language team if it already exists or create a new language team.
+If you would like to translate the app into another language or improve an existing translation, you can visit the [Transifex project page](https://www.transifex.com/antennapod/antennapod/). From there, you can either join a language team if it already exists or create a new language team.
+
-Submit a pull-request
+Submit a pull request
---------------------
-- If you want to work on a feature that has been requested or fix a bug that has been reported on the "issues" page, add a comment to it so that other people know that you are working on it.
-- Fork the repository
-- Almost all changes of AntennaPod are done on the `develop` branch. If a new version of AntennaPod is released, the `develop` branch is merged into `master`. As a result, the `master` branch probably doesn't contain the latest changes when you are reading this. Please make sure that you are branching from `develop`! Otherwise, there might be a lot of merge-conflicts when merging your changes into `develop` and therefore it might take longer to review your pull-request. Exceptions are changes in files like README.md, CONTRIBUTING.md and other files that are not directly related to the source code.
-- If your pull-request fixes a bug that has been reported or implements a feature that has been requested in another issue, try to mention it so that it can be closed once your pull-request has been merged. If you use special keywords in the [commit comment](https://help.github.com/articles/closing-issues-via-commit-messages/) or [pull request text](https://github.com/blog/1506-closing-issues-via-pull-requests) github will close the issues automatically when the changes lands at the master branch.
-- Although not every part of AntennaPod's source code is fully documented yet, it would be very nice if you could add documentation to your changes if it is a larger pull-request.
-- If possible, add unit tests for your pull-request and make sure that they pass. Information on how to add unit tests and run them can be found here: [TODO]
+- If you want to work on a feature that has been requested or fix a bug that has been reported on the "issues" page, add a comment to it so that other people know that you are working on it.
+- Fork the repository.
+- Almost all changes of AntennaPod are done on the `develop` branch. If a new version of AntennaPod is released, the `develop` branch is merged into `master`. As a result, the `master` branch probably doesn't contain the latest changes when you are reading this. Please make sure that you are branching from `develop`! Otherwise, there might be a lot of merge-conflicts when merging your changes into `develop` and therefore it might take longer to review your pull-request. Exceptions are changes in files like README.md, CONTRIBUTING.md, and other files that are not directly related to the source code.
+- If your pull request fixes a bug that has been reported or implements a feature that has been requested in another issue, try to mention it so that it can be closed once your pull request has been merged. If you use special keywords in the [commit comment](https://help.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue) or [pull request text](https://github.blog/2013-05-14-closing-issues-via-pull-requests/), GitHub will close the issue(s) automatically when the changes land on the master branch.
+- Although not every part of AntennaPod's source code is fully documented yet, it would be very nice if you could add documentation to your changes if it is a larger pull request.
+- If possible, add unit tests for your pull request and make sure that they pass. Information on how to add unit tests and run them can be found here: (TODO)
+
Improving this file
-------------------
-If you think this file needs clarification or additional information on certain topics, feel free to improve it via pull-requests or ask a question on the issues section.
+If you think this file needs clarification or additional information on certain topics, feel free to improve it via pull requests or by opening an issue.
diff --git a/app/build.gradle b/app/build.gradle
index df07b177e..44faefeec 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -10,17 +10,19 @@ android {
defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
- multiDexEnabled false
- vectorDrawables.useSupportLibrary true
// Version code schema:
// "1.2.3-SNAPSHOT" -> 1020300
// "1.2.3-RC4" -> 1020304
// "1.2.3" -> 1020395
versionCode 2000002
versionName "2.0.0-alpha2"
+
+ multiDexEnabled false
+ vectorDrawables.useSupportLibrary true
+ vectorDrawables.generatedDensities = []
+
testApplicationId "de.test.antennapod"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
- vectorDrawables.generatedDensities = []
def commit = "Unknown commit"
try {
@@ -62,16 +64,14 @@ android {
}
buildTypes {
- def STRING = "String"
-
debug {
applicationIdSuffix ".debug"
resValue "string", "provider_authority", "de.danoeh.antennapod.debug.provider"
- // debug build has method count over 64k single-dex threshold.
- // For building debug build to use on Android < 21 (pre-Android 5) devices,
+ // debug build has method count over 64k single-dex threshold.
+ // For building debug build to use on Android < 21 (pre-Android 5) devices,
// you need to manually change class
- // de.danoeh.antennapod.PodcastApp to extend MultiDexApplication .
+ // de.danoeh.antennapod.PodcastApp to extend MultiDexApplication .
// See Issue #2813
multiDexEnabled true
@@ -138,18 +138,17 @@ dependencies {
System.out.println("app: free build hack, skipping some dependencies")
}
- annotationProcessor 'androidx.annotation:annotation:1.1.0'
- implementation 'androidx.appcompat:appcompat:1.1.0'
+ annotationProcessor "androidx.annotation:annotation:$annotationVersion"
+ implementation "androidx.appcompat:appcompat:$appcompatVersion"
implementation 'androidx.coordinatorlayout:coordinatorlayout:1.1.0'
implementation 'androidx.gridlayout:gridlayout:1.0.0'
- implementation 'androidx.media:media:1.1.0'
- implementation 'androidx.preference:preference:1.1.1'
+ implementation "androidx.media:media:$mediaVersion"
+ implementation "androidx.preference:preference:$preferenceVersion"
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'androidx.viewpager2:viewpager2:1.1.0-alpha01'
implementation "androidx.work:work-runtime:$workManagerVersion"
- implementation 'com.google.android.material:material:1.1.0'
+ implementation "com.google.android.material:material:$googleMaterialVersion"
- compileOnly "com.google.android.wearable:wearable:$wearableSupportVersion"
implementation "org.apache.commons:commons-lang3:$commonslangVersion"
implementation "commons-io:commons-io:$commonsioVersion"
implementation "org.jsoup:jsoup:$jsoupVersion"
@@ -165,13 +164,15 @@ dependencies {
implementation "com.joanzapata.iconify:android-iconify-fontawesome:$iconifyVersion"
implementation "com.joanzapata.iconify:android-iconify-material:$iconifyVersion"
- implementation "com.yqritc:recyclerview-flexibledivider:$recyclerviewFlexibledividerVersion"
- implementation "com.github.shts:TriangleLabelView:$triangleLabelViewVersion"
+ implementation 'com.yqritc:recyclerview-flexibledivider:1.4.0'
+ implementation 'com.github.shts:TriangleLabelView:1.1.2'
implementation 'com.leinardi.android:speed-dial:3.1.1'
implementation "com.github.AntennaPod:AntennaPod-AudioPlayer:$audioPlayerVersion"
implementation 'com.github.mfietz:fyydlin:v0.5.0'
implementation 'com.github.ByteHamster:SearchPreference:v2.0.0'
- implementation "com.github.skydoves:balloon:1.1.5"
+ implementation 'com.github.skydoves:balloon:1.1.5'
+
+ compileOnly "com.google.android.wearable:wearable:$wearableSupportVersion"
androidTestImplementation "org.awaitility:awaitility:$awaitilityVersion"
androidTestImplementation 'com.nanohttpd:nanohttpd:2.1.1'
@@ -179,8 +180,8 @@ dependencies {
androidTestImplementation "androidx.test.espresso:espresso-core:$espressoVersion"
androidTestImplementation "androidx.test.espresso:espresso-contrib:$espressoVersion"
androidTestImplementation "androidx.test.espresso:espresso-intents:$espressoVersion"
- androidTestImplementation 'androidx.test:runner:1.2.0'
- androidTestImplementation 'androidx.test:rules:1.2.0'
+ androidTestImplementation "androidx.test:runner:$runnerVersion"
+ androidTestImplementation "androidx.test:rules:$rulesVersion"
}
if (project.hasProperty("antennaPodPlayPublisherCredentials")) {
diff --git a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java
index dbc86a228..fce78ea4f 100644
--- a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java
@@ -5,6 +5,7 @@ import androidx.test.InstrumentationRegistry;
import androidx.test.annotation.UiThreadTest;
import androidx.test.filters.LargeTest;
+import de.danoeh.antennapod.core.preferences.SleepTimerPreferences;
import org.awaitility.Awaitility;
import org.greenrobot.eventbus.EventBus;
import org.junit.After;
@@ -53,6 +54,8 @@ public class PlaybackServiceTaskManagerTest {
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
adapter.close();
+ SleepTimerPreferences.setShakeToReset(false);
+ SleepTimerPreferences.setVibrate(false);
}
@Test
@@ -304,7 +307,7 @@ public class PlaybackServiceTaskManagerTest {
PlaybackServiceTaskManager pstm = new PlaybackServiceTaskManager(c, defaultPSTM);
pstm.startWidgetUpdater();
pstm.startPositionSaver();
- pstm.setSleepTimer(100000, false, false);
+ pstm.setSleepTimer(100000);
pstm.cancelAllTasks();
assertFalse(pstm.isPositionSaverActive());
assertFalse(pstm.isWidgetUpdaterActive());
@@ -353,7 +356,7 @@ public class PlaybackServiceTaskManagerTest {
}
});
- pstm.setSleepTimer(TIME, false, false);
+ pstm.setSleepTimer(TIME);
countDownLatch.await(TIMEOUT, TimeUnit.MILLISECONDS);
pstm.shutdown();
}
@@ -396,7 +399,7 @@ public class PlaybackServiceTaskManagerTest {
}
});
- pstm.setSleepTimer(TIME, false, false);
+ pstm.setSleepTimer(TIME);
pstm.disableSleepTimer();
assertFalse(countDownLatch.await(TIMEOUT, TimeUnit.MILLISECONDS));
pstm.shutdown();
@@ -407,7 +410,7 @@ public class PlaybackServiceTaskManagerTest {
public void testIsSleepTimerActivePositive() {
final Context c = InstrumentationRegistry.getInstrumentation().getTargetContext();
PlaybackServiceTaskManager pstm = new PlaybackServiceTaskManager(c, defaultPSTM);
- pstm.setSleepTimer(10000, false, false);
+ pstm.setSleepTimer(1000);
assertTrue(pstm.isSleepTimerActive());
pstm.shutdown();
}
@@ -417,7 +420,7 @@ public class PlaybackServiceTaskManagerTest {
public void testIsSleepTimerActiveNegative() {
final Context c = InstrumentationRegistry.getInstrumentation().getTargetContext();
PlaybackServiceTaskManager pstm = new PlaybackServiceTaskManager(c, defaultPSTM);
- pstm.setSleepTimer(10000, false, false);
+ pstm.setSleepTimer(10000);
pstm.disableSleepTimer();
assertFalse(pstm.isSleepTimerActive());
pstm.shutdown();
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
index 9e647bcaa..655049b2c 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
@@ -409,13 +409,7 @@ public class MainActivity extends CastEnabledActivity {
public void onEventMainThread(MessageEvent event) {
Log.d(TAG, "onEvent(" + event + ")");
- Snackbar snackbar;
- if (getBottomSheet().getState() == BottomSheetBehavior.STATE_COLLAPSED) {
- snackbar = showSnackbarAbovePlayer(event.message, Snackbar.LENGTH_SHORT);
- } else {
- snackbar = Snackbar.make(findViewById(android.R.id.content), event.message, Snackbar.LENGTH_SHORT);
- snackbar.show();
- }
+ Snackbar snackbar = showSnackbarAbovePlayer(event.message, Snackbar.LENGTH_SHORT);
if (event.action != null) {
snackbar.setAction(getString(R.string.undo), v -> event.action.run());
}
@@ -453,21 +447,21 @@ public class MainActivity extends CastEnabledActivity {
setIntent(intent);
}
- public Snackbar showSnackbarAbovePlayer(int text, int duration) {
- Snackbar s = Snackbar.make(findViewById(R.id.main_view), text, duration);
- if (findViewById(R.id.audioplayerFragment).getVisibility() == View.VISIBLE) {
- s.setAnchorView(findViewById(R.id.audioplayerFragment));
+ public Snackbar showSnackbarAbovePlayer(CharSequence text, int duration) {
+ Snackbar s;
+ if (getBottomSheet().getState() == BottomSheetBehavior.STATE_COLLAPSED) {
+ s = Snackbar.make(findViewById(R.id.main_view), text, duration);
+ if (findViewById(R.id.audioplayerFragment).getVisibility() == View.VISIBLE) {
+ s.setAnchorView(findViewById(R.id.audioplayerFragment));
+ }
+ } else {
+ s = Snackbar.make(findViewById(android.R.id.content), text, duration);
}
s.show();
return s;
}
- public Snackbar showSnackbarAbovePlayer(String text, int duration) {
- Snackbar s = Snackbar.make(findViewById(R.id.main_view), text, duration);
- if (findViewById(R.id.audioplayerFragment).getVisibility() == View.VISIBLE) {
- s.setAnchorView(findViewById(R.id.audioplayerFragment));
- }
- s.show();
- return s;
+ public Snackbar showSnackbarAbovePlayer(int text, int duration) {
+ return showSnackbarAbovePlayer(getResources().getText(text), duration);
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportActivity.java
index f4d312a4f..10292b892 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportActivity.java
@@ -18,8 +18,12 @@ import de.danoeh.antennapod.asynctask.OpmlImportWorker;
import de.danoeh.antennapod.core.export.opml.OpmlElement;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.util.LangUtils;
+import org.apache.commons.io.ByteOrderMark;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.input.BOMInputStream;
import org.apache.commons.lang3.ArrayUtils;
+import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
@@ -130,7 +134,12 @@ public class OpmlImportActivity extends AppCompatActivity {
/** Starts the import process. */
private void startImport() {
try {
- Reader reader = new InputStreamReader(getContentResolver().openInputStream(uri), LangUtils.UTF_8);
+ InputStream opmlFileStream = getContentResolver().openInputStream(uri);
+ BOMInputStream bomInputStream = new BOMInputStream(opmlFileStream);
+ ByteOrderMark bom = bomInputStream.getBOM();
+ String charsetName = (bom == null) ? "UTF-8" : bom.getCharsetName();
+ Reader reader = new InputStreamReader(bomInputStream, charsetName);
+
OpmlImportWorker importWorker = new OpmlImportWorker(this, reader) {
@Override
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java
index fafe888ee..a9c54e879 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java
@@ -2,9 +2,8 @@ package de.danoeh.antennapod.dialog;
import android.app.Dialog;
import android.content.Context;
+import android.content.DialogInterface;
import android.os.Bundle;
-import android.text.Editable;
-import android.text.TextWatcher;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
@@ -14,7 +13,6 @@ import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
-import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
@@ -36,9 +34,6 @@ public class SleepTimerDialog extends DialogFragment {
private EditText etxtTime;
private Spinner spTimeUnit;
- private CheckBox cbShakeToReset;
- private CheckBox cbVibrate;
- private CheckBox chAutoEnable;
private LinearLayout timeSetup;
private LinearLayout timeDisplay;
private TextView time;
@@ -85,33 +80,15 @@ public class SleepTimerDialog extends DialogFragment {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(R.string.sleep_timer_label);
builder.setView(content);
- builder.setPositiveButton(android.R.string.ok, null);
+ builder.setPositiveButton(R.string.close_label, null);
etxtTime = content.findViewById(R.id.etxtTime);
spTimeUnit = content.findViewById(R.id.spTimeUnit);
- cbShakeToReset = content.findViewById(R.id.cbShakeToReset);
- cbVibrate = content.findViewById(R.id.cbVibrate);
- chAutoEnable = content.findViewById(R.id.chAutoEnable);
timeSetup = content.findViewById(R.id.timeSetup);
timeDisplay = content.findViewById(R.id.timeDisplay);
time = content.findViewById(R.id.time);
- AlertDialog dialog = builder.create();
etxtTime.setText(SleepTimerPreferences.lastTimerValue());
- etxtTime.addTextChangedListener(new TextWatcher() {
- @Override
- public void afterTextChanged(Editable s) {
- dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(s.length() > 0);
- }
-
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- }
- });
etxtTime.postDelayed(() -> {
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(etxtTime, InputMethodManager.SHOW_IMPLICIT);
@@ -127,12 +104,21 @@ public class SleepTimerDialog extends DialogFragment {
spTimeUnit.setAdapter(spinnerAdapter);
spTimeUnit.setSelection(SleepTimerPreferences.lastTimerTimeUnit());
+ CheckBox cbShakeToReset = content.findViewById(R.id.cbShakeToReset);
+ CheckBox cbVibrate = content.findViewById(R.id.cbVibrate);
+ CheckBox chAutoEnable = content.findViewById(R.id.chAutoEnable);
+
cbShakeToReset.setChecked(SleepTimerPreferences.shakeToReset());
cbVibrate.setChecked(SleepTimerPreferences.vibrate());
chAutoEnable.setChecked(SleepTimerPreferences.autoEnable());
+ cbShakeToReset.setOnCheckedChangeListener((buttonView, isChecked)
+ -> SleepTimerPreferences.setShakeToReset(isChecked));
+ cbVibrate.setOnCheckedChangeListener((buttonView, isChecked)
+ -> SleepTimerPreferences.setVibrate(isChecked));
chAutoEnable.setOnCheckedChangeListener((compoundButton, isChecked)
- -> SleepTimerPreferences.setAutoEnable(isChecked));
+ -> SleepTimerPreferences.setAutoEnable(isChecked));
+
Button disableButton = content.findViewById(R.id.disableSleeptimerButton);
disableButton.setOnClickListener(v -> {
if (controller != null) {
@@ -143,27 +129,20 @@ public class SleepTimerDialog extends DialogFragment {
setButton.setOnClickListener(v -> {
if (!PlaybackService.isRunning) {
Snackbar.make(content, R.string.no_media_playing_label, Snackbar.LENGTH_LONG).show();
+ return;
}
try {
- savePreferences();
+ SleepTimerPreferences.setLastTimer(etxtTime.getText().toString(), spTimeUnit.getSelectedItemPosition());
long time = SleepTimerPreferences.timerMillis();
if (controller != null) {
- controller.setSleepTimer(time, cbShakeToReset.isChecked(), cbVibrate.isChecked());
+ controller.setSleepTimer(time);
}
} catch (NumberFormatException e) {
e.printStackTrace();
- Toast.makeText(getContext(), R.string.time_dialog_invalid_input, Toast.LENGTH_LONG).show();
+ Snackbar.make(content, R.string.time_dialog_invalid_input, Snackbar.LENGTH_LONG).show();
}
});
- return dialog;
- }
-
- private void savePreferences() {
- SleepTimerPreferences.setLastTimer(etxtTime.getText().toString(),
- spTimeUnit.getSelectedItemPosition());
- SleepTimerPreferences.setShakeToReset(cbShakeToReset.isChecked());
- SleepTimerPreferences.setVibrate(cbVibrate.isChecked());
- SleepTimerPreferences.setAutoEnable(chAutoEnable.isChecked());
+ return builder.create();
}
private void updateTime() {
diff --git a/app/src/main/java/de/danoeh/antennapod/view/viewholder/EpisodeItemViewHolder.java b/app/src/main/java/de/danoeh/antennapod/view/viewholder/EpisodeItemViewHolder.java
index 8584befbc..b7e1728b5 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/viewholder/EpisodeItemViewHolder.java
+++ b/app/src/main/java/de/danoeh/antennapod/view/viewholder/EpisodeItemViewHolder.java
@@ -7,15 +7,11 @@ import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.view.accessibility.AccessibilityEvent;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.cardview.widget.CardView;
-import androidx.core.view.AccessibilityDelegateCompat;
-import androidx.core.view.ViewCompat;
-import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.joanzapata.iconify.Iconify;
@@ -201,6 +197,7 @@ public class EpisodeItemViewHolder extends RecyclerView.ViewHolder {
progressBar.setProgress((int) (100.0 * event.getPosition() / event.getDuration()));
position.setText(Converter.getDurationStringLong(event.getPosition()));
duration.setText(Converter.getDurationStringLong(event.getDuration()));
+ duration.setVisibility(View.VISIBLE); // Even if the duration was previously unknown, it is now known
}
/**
diff --git a/app/src/main/res/layout/audioplayer_fragment.xml b/app/src/main/res/layout/audioplayer_fragment.xml
index 1935ce36c..37c30b4dd 100644
--- a/app/src/main/res/layout/audioplayer_fragment.xml
+++ b/app/src/main/res/layout/audioplayer_fragment.xml
@@ -107,10 +107,10 @@
android:id="@+id/butPlay"
android:layout_width="@dimen/audioplayer_playercontrols_length_big"
android:layout_height="@dimen/audioplayer_playercontrols_length_big"
- android:layout_marginLeft="8dp"
- android:layout_marginStart="8dp"
- android:layout_marginRight="8dp"
- android:layout_marginEnd="8dp"
+ android:layout_marginLeft="@dimen/audioplayer_playercontrols_margin"
+ android:layout_marginStart="@dimen/audioplayer_playercontrols_margin"
+ android:layout_marginRight="@dimen/audioplayer_playercontrols_margin"
+ android:layout_marginEnd="@dimen/audioplayer_playercontrols_margin"
android:padding="8dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
@@ -145,8 +145,8 @@
android:layout_height="@dimen/audioplayer_playercontrols_length"
android:layout_toLeftOf="@id/butPlay"
android:layout_toStartOf="@id/butPlay"
- android:layout_marginLeft="8dp"
- android:layout_marginStart="8dp"
+ android:layout_marginLeft="@dimen/audioplayer_playercontrols_margin"
+ android:layout_marginStart="@dimen/audioplayer_playercontrols_margin"
android:layout_centerVertical="true"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/rewind_label"
@@ -201,8 +201,8 @@
android:layout_height="@dimen/audioplayer_playercontrols_length"
android:layout_toRightOf="@id/butPlay"
android:layout_toEndOf="@id/butPlay"
- android:layout_marginRight="8dp"
- android:layout_marginEnd="8dp"
+ android:layout_marginRight="@dimen/audioplayer_playercontrols_margin"
+ android:layout_marginEnd="@dimen/audioplayer_playercontrols_margin"
android:layout_centerVertical="true"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/fast_forward_label"
diff --git a/build.gradle b/build.gradle
index 82cec73ce..9774fc3c8 100644
--- a/build.gradle
+++ b/build.gradle
@@ -46,31 +46,36 @@ project.ext {
minSdkVersion = 16
targetSdkVersion = 28
+ // AndroidX
+ annotationVersion = "1.1.0"
+ appcompatVersion = "1.1.0"
+ mediaVersion = "1.1.0"
+ preferenceVersion = "1.1.1"
workManagerVersion = "2.3.4"
- espressoVersion = "3.2.0"
- awaitilityVersion = "3.1.6"
- commonsioVersion = "2.5"
+ googleMaterialVersion = "1.1.0"
+
+ // Third-party
commonslangVersion = "3.6"
- eventbusVersion = "3.2.0"
- glideVersion = "4.8.0"
- glideOkhttpIntegrationVersion = "4.8.0"
- iconifyVersion = "2.2.2"
+ commonsioVersion = "2.5"
jsoupVersion = "1.11.2"
+ glideVersion = "4.8.0"
okhttpVersion = "3.12.10"
okioVersion = "1.17.5"
- recyclerviewFlexibledividerVersion = "1.4.0"
- robotiumSoloVersion = "5.6.3"
+ eventbusVersion = "3.2.0"
rxAndroidVersion = "2.1.1"
rxJavaVersion = "2.2.2"
- rxJavaRulesVersion = "1.3.3.0"
- triangleLabelViewVersion = "1.1.2"
-
- exoPlayerVersion = "2.10.8"
+ iconifyVersion = "2.2.2"
audioPlayerVersion = "v1.0.17"
- castCompanionLibVer = "2.9.1"
- playServicesVersion = "8.4.0"
+ // Google Play build
wearableSupportVersion = "2.6.0"
+
+ //Tests
+ awaitilityVersion = "3.1.6"
+ robotiumSoloVersion = "5.6.3"
+ espressoVersion = "3.2.0"
+ runnerVersion = "1.2.0"
+ rulesVersion = "1.2.0"
}
wrapper {
diff --git a/core/build.gradle b/core/build.gradle
index 9189f1d8e..4c7ef5a0a 100644
--- a/core/build.gradle
+++ b/core/build.gradle
@@ -6,9 +6,9 @@ android {
defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
+
multiDexEnabled false
- versionCode 1
- versionName "1.0"
+
testApplicationId "de.danoeh.antennapod.core.tests"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -55,19 +55,19 @@ android {
}
dependencies {
- annotationProcessor 'androidx.annotation:annotation:1.1.0'
- implementation 'androidx.appcompat:appcompat:1.1.0'
- implementation 'androidx.media:media:1.1.0'
- implementation 'androidx.preference:preference:1.1.1'
+ annotationProcessor "androidx.annotation:annotation:$annotationVersion"
+ implementation "androidx.appcompat:appcompat:$appcompatVersion"
+ implementation "androidx.media:media:$mediaVersion"
+ implementation "androidx.preference:preference:$preferenceVersion"
implementation "androidx.work:work-runtime:$workManagerVersion"
- implementation 'com.google.android.material:material:1.1.0'
+ implementation "com.google.android.material:material:$googleMaterialVersion"
implementation "org.apache.commons:commons-lang3:$commonslangVersion"
implementation "commons-io:commons-io:$commonsioVersion"
implementation "org.jsoup:jsoup:$jsoupVersion"
implementation "com.github.bumptech.glide:glide:$glideVersion"
annotationProcessor "com.github.bumptech.glide:compiler:$glideVersion"
- implementation "com.github.bumptech.glide:okhttp3-integration:$glideOkhttpIntegrationVersion@aar"
+ implementation "com.github.bumptech.glide:okhttp3-integration:$glideVersion@aar"
implementation "com.squareup.okhttp3:okhttp:$okhttpVersion"
implementation "com.squareup.okhttp3:okhttp-urlconnection:$okhttpVersion"
implementation "com.squareup.okio:okio:$okioVersion"
@@ -76,15 +76,15 @@ dependencies {
implementation "io.reactivex.rxjava2:rxandroid:$rxAndroidVersion"
implementation "io.reactivex.rxjava2:rxjava:$rxJavaVersion"
- implementation "com.google.android.exoplayer:exoplayer:$exoPlayerVersion"
+ implementation 'com.google.android.exoplayer:exoplayer:2.10.8'
implementation "com.github.AntennaPod:AntennaPod-AudioPlayer:$audioPlayerVersion"
// Add casting features
// free build hack: skip some dependencies
if (!doFreeBuild()) {
- playApi "com.google.android.libraries.cast.companionlibrary:ccl:$castCompanionLibVer"
+ playApi 'com.google.android.libraries.cast.companionlibrary:ccl:2.9.1'
api 'androidx.mediarouter:mediarouter:1.0.0'
- playApi "com.google.android.gms:play-services-cast:$playServicesVersion"
+ playApi 'com.google.android.gms:play-services-cast:8.4.0'
api "com.google.android.support:wearable:$wearableSupportVersion"
compileOnly "com.google.android.wearable:wearable:$wearableSupportVersion"
} else {
@@ -96,8 +96,8 @@ dependencies {
testImplementation 'org.mockito:mockito-core:1.10.19'
androidTestImplementation "com.jayway.android.robotium:robotium-solo:$robotiumSoloVersion"
androidTestImplementation "androidx.test.espresso:espresso-core:$espressoVersion"
- androidTestImplementation 'androidx.test:runner:1.2.0'
- androidTestImplementation 'androidx.test:rules:1.2.0'
+ androidTestImplementation "androidx.test:runner:$runnerVersion"
+ androidTestImplementation "androidx.test:rules:$rulesVersion"
}
tasks.withType(Test) {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java
index a41b04b53..7e1a5fd9b 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java
@@ -224,7 +224,7 @@ public class FeedMedia extends FeedFile implements Playable {
public boolean hasAlmostEnded() {
int smartMarkAsPlayedSecs = UserPreferences.getSmartMarkAsPlayedSecs();
- return this.position >= this.duration - smartMarkAsPlayedSecs * 1000;
+ return this.duration > 0 && this.position >= this.duration - smartMarkAsPlayedSecs * 1000;
}
@Override
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java
index a83e50506..33a2a72ff 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java
@@ -48,6 +48,7 @@ import java.util.concurrent.TimeUnit;
import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.R;
+import de.danoeh.antennapod.core.event.FeedItemEvent;
import de.danoeh.antennapod.core.event.MessageEvent;
import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
import de.danoeh.antennapod.core.event.ServiceEvent;
@@ -523,7 +524,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
Context context = getApplicationContext();
if (skipIntro > 0 && playable.getPosition() < skipIntro * 1000) {
int duration = getDuration();
- if (skipIntro * 1000 < duration) {
+ if (skipIntro * 1000 < duration || duration <= 0) {
Log.d(TAG, "skipIntro " + playable.getEpisodeTitle());
mediaPlayer.seekTo(skipIntro * 1000);
String skipIntroMesg = context.getString(R.string.pref_feed_skip_intro_toast,
@@ -791,8 +792,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
// set sleep timer if auto-enabled
if (newInfo.oldPlayerStatus != null && newInfo.oldPlayerStatus != PlayerStatus.SEEKING
&& SleepTimerPreferences.autoEnable() && !sleepTimerActive()) {
- setSleepTimer(SleepTimerPreferences.timerMillis(), SleepTimerPreferences.shakeToReset(),
- SleepTimerPreferences.vibrate());
+ setSleepTimer(SleepTimerPreferences.timerMillis());
EventBus.getDefault().post(new MessageEvent(getString(R.string.sleep_timer_enabled_label),
PlaybackService.this::disableSleepTimer));
}
@@ -847,6 +847,17 @@ public class PlaybackService extends MediaBrowserServiceCompat {
return true;
case MediaPlayer.MEDIA_INFO_BUFFERING_END:
sendNotificationBroadcast(NOTIFICATION_TYPE_BUFFER_END, 0);
+
+ Playable playable = getPlayable();
+ if (getPlayable() instanceof FeedMedia
+ && playable.getDuration() <= 0 && mediaPlayer.getDuration() > 0) {
+ // Playable is being streamed and does not have a duration specified in the feed
+ playable.setDuration(mediaPlayer.getDuration());
+ DBWriter.setFeedMedia((FeedMedia) playable);
+ updateMediaSessionMetadata(playable);
+ setupNotification(playable);
+ }
+
return true;
default:
return flavorHelper.onMediaPlayerInfo(PlaybackService.this, code, resourceId);
@@ -1055,9 +1066,9 @@ public class PlaybackService extends MediaBrowserServiceCompat {
}
}
- public void setSleepTimer(long waitingTime, boolean shakeToReset, boolean vibrate) {
+ public void setSleepTimer(long waitingTime) {
Log.d(TAG, "Setting sleep timer to " + waitingTime + " milliseconds");
- taskManager.setSleepTimer(waitingTime, shakeToReset, vibrate);
+ taskManager.setSleepTimer(waitingTime);
sendNotificationBroadcast(NOTIFICATION_TYPE_SLEEPTIMER_UPDATE, 0);
}
@@ -1087,7 +1098,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
FeedPreferences preferences = feedMedia.getItem().getFeed().getPreferences();
int skipEnd = preferences.getFeedSkipEnding();
if (skipEnd > 0
- && skipEnd < playable.getDuration()
+ && skipEnd < getDuration()
&& (remainingTime - (skipEnd * 1000) > 0)
&& ((remainingTime - skipEnd * 1000) < (getCurrentPlaybackSpeed() * 1000))) {
Log.d(TAG, "skipEndingIfNecessary: Skipping the remaining " + remainingTime + " " + skipEnd * 1000 + " speed " + getCurrentPlaybackSpeed());
@@ -1720,7 +1731,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
private void addPlayableToQueue(Playable playable) {
if (playable instanceof FeedMedia) {
- long itemId = ((FeedMedia) playable).getId();
+ long itemId = ((FeedMedia) playable).getItem().getId();
DBWriter.addQueueItem(this, false, false, itemId);
}
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java
index 904c1508d..17cd1b24a 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java
@@ -7,6 +7,7 @@ import android.os.Vibrator;
import androidx.annotation.NonNull;
import android.util.Log;
+import de.danoeh.antennapod.core.preferences.SleepTimerPreferences;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
@@ -215,7 +216,7 @@ public class PlaybackServiceTaskManager {
*
* @throws java.lang.IllegalArgumentException if waitingTime <= 0
*/
- public synchronized void setSleepTimer(long waitingTime, boolean shakeToReset, boolean vibrate) {
+ public synchronized void setSleepTimer(long waitingTime) {
if (waitingTime <= 0) {
throw new IllegalArgumentException("Waiting time <= 0");
}
@@ -224,7 +225,7 @@ public class PlaybackServiceTaskManager {
if (isSleepTimerActive()) {
sleepTimerFuture.cancel(true);
}
- sleepTimer = new SleepTimer(waitingTime, shakeToReset, vibrate);
+ sleepTimer = new SleepTimer(waitingTime);
sleepTimerFuture = schedExecutor.schedule(sleepTimer, 0, TimeUnit.MILLISECONDS);
}
@@ -361,17 +362,13 @@ public class PlaybackServiceTaskManager {
private static final long NOTIFICATION_THRESHOLD = 10000;
private final long waitingTime;
private long timeLeft;
- private final boolean shakeToReset;
- private final boolean vibrate;
private ShakeListener shakeListener;
private final Handler handler;
- public SleepTimer(long waitingTime, boolean shakeToReset, boolean vibrate) {
+ public SleepTimer(long waitingTime) {
super();
this.waitingTime = waitingTime;
this.timeLeft = waitingTime;
- this.shakeToReset = shakeToReset;
- this.vibrate = vibrate;
if (UserPreferences.useExoplayer() && Looper.myLooper() == Looper.getMainLooper()) {
// Run callbacks in main thread so they can call ExoPlayer methods themselves
@@ -409,13 +406,13 @@ public class PlaybackServiceTaskManager {
if (timeLeft < NOTIFICATION_THRESHOLD && !notifiedAlmostExpired) {
Log.d(TAG, "Sleep timer is about to expire");
- if (vibrate) {
+ if (SleepTimerPreferences.vibrate()) {
Vibrator v = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
if (v != null) {
v.vibrate(500);
}
}
- if (shakeListener == null && shakeToReset) {
+ if (shakeListener == null && SleepTimerPreferences.shakeToReset()) {
shakeListener = new ShakeListener(context, this);
}
postCallback(callback::onSleepTimerAlmostExpired);
@@ -442,7 +439,7 @@ public class PlaybackServiceTaskManager {
public void restart() {
postCallback(() -> {
- setSleepTimer(waitingTime, shakeToReset, vibrate);
+ setSleepTimer(waitingTime);
callback.onSleepTimerReset();
});
if (shakeListener != null) {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSRSS20.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSRSS20.java
index 3fc0a69d2..45c5d4884 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSRSS20.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSRSS20.java
@@ -3,6 +3,7 @@ package de.danoeh.antennapod.core.syndication.namespace;
import android.text.TextUtils;
import android.util.Log;
+import de.danoeh.antennapod.core.syndication.util.SyndStringUtils;
import org.xml.sax.Attributes;
import de.danoeh.antennapod.core.feed.FeedItem;
@@ -98,7 +99,8 @@ public class NSRSS20 extends Namespace {
}
state.setCurrentItem(null);
} else if (state.getTagstack().size() >= 2 && state.getContentBuf() != null) {
- String content = state.getContentBuf().toString();
+ String contentRaw = state.getContentBuf().toString();
+ String content = SyndStringUtils.trimAllWhitespace(contentRaw);
SyndElement topElement = state.getTagstack().peek();
String top = topElement.getName();
SyndElement secondElement = state.getSecondTag();
@@ -110,15 +112,14 @@ public class NSRSS20 extends Namespace {
if (GUID.equals(top) && ITEM.equals(second)) {
// some feed creators include an empty or non-standard guid-element in their feed,
// which should be ignored
- if (!TextUtils.isEmpty(content) && state.getCurrentItem() != null) {
- state.getCurrentItem().setItemIdentifier(content);
+ if (!TextUtils.isEmpty(contentRaw) && state.getCurrentItem() != null) {
+ state.getCurrentItem().setItemIdentifier(contentRaw);
}
} else if (TITLE.equals(top)) {
- String title = content.trim();
if (ITEM.equals(second) && state.getCurrentItem() != null) {
- state.getCurrentItem().setTitle(title);
+ state.getCurrentItem().setTitle(content);
} else if (CHANNEL.equals(second) && state.getFeed() != null) {
- state.getFeed().setTitle(title);
+ state.getFeed().setTitle(content);
}
} else if (LINK.equals(top)) {
if (CHANNEL.equals(second) && state.getFeed() != null) {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/util/SyndStringUtils.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/util/SyndStringUtils.java
new file mode 100644
index 000000000..addcdd4b7
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/syndication/util/SyndStringUtils.java
@@ -0,0 +1,14 @@
+package de.danoeh.antennapod.core.syndication.util;
+
+public class SyndStringUtils {
+ private SyndStringUtils() {
+
+ }
+
+ /**
+ * Trims all whitespace from beginning and ending of a String. {{@link String#trim()}} only trims spaces.
+ */
+ public static String trimAllWhitespace(String string) {
+ return string.replaceAll("(^\\s*)|(\\s*$)", "");
+ }
+}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java
index 8f7e5dc33..0b849aa1f 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java
@@ -556,9 +556,9 @@ public class PlaybackController {
}
}
- public void setSleepTimer(long time, boolean shakeToReset, boolean vibrate) {
+ public void setSleepTimer(long time) {
if (playbackService != null) {
- playbackService.setSleepTimer(time, shakeToReset, vibrate);
+ playbackService.setSleepTimer(time);
}
}
diff --git a/core/src/main/res/values/dimens.xml b/core/src/main/res/values/dimens.xml
index cfb272ad9..41a24f6fa 100644
--- a/core/src/main/res/values/dimens.xml
+++ b/core/src/main/res/values/dimens.xml
@@ -31,6 +31,7 @@
<dimen name="audioplayer_playercontrols_length">48dp</dimen>
<dimen name="audioplayer_playercontrols_length_big">64dp</dimen>
+ <dimen name="audioplayer_playercontrols_margin">12dp</dimen>
<dimen name="media_router_controller_playback_control_vertical_padding">16dp</dimen>
<dimen name="media_router_controller_playback_control_horizontal_spacing">12dp</dimen>
diff --git a/createTranslatorsList.py b/createTranslatorsList.py
index 16cbe575a..8ada1397d 100644
--- a/createTranslatorsList.py
+++ b/createTranslatorsList.py
@@ -31,7 +31,7 @@ for lang in r.json():
langName = lang['language_code']
print('\033[91mLanguage code not found:' + langCode + '\033[0m')
- joinedTranslators = ', '.join(langContributers).replace(';', '');
+ joinedTranslators = ', '.join(langContributers).replace(';', '')
contributorsFile.write(langName + ": " + joinedTranslators + '\n')
csvFile.write(langName + ';' + joinedTranslators + '\n')
print(langName + ';' + joinedTranslators)