This commit is contained in:
Tom Hennen 2016-03-25 10:50:41 -04:00
parent 5cc6f12acb
commit 4cd58a9b37
738 changed files with 7859 additions and 3328 deletions

View File

@ -4,21 +4,33 @@ host = https://www.transifex.com
[antennapod.english] [antennapod.english]
source_file = core/src/main/res/values/strings.xml source_file = core/src/main/res/values/strings.xml
source_lang = en source_lang = en
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.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.cs_CZ = core/src/main/res/values-cs-rCZ/strings.xml trans.cs_CZ = core/src/main/res/values-cs-rCZ/strings.xml
trans.da = core/src/main/res/values-da/strings.xml trans.da = core/src/main/res/values-da/strings.xml
trans.de = core/src/main/res/values-de/strings.xml trans.de = core/src/main/res/values-de/strings.xml
trans.el = core/src/main/res/values-el/strings.xml
trans.es = core/src/main/res/values-es/strings.xml trans.es = core/src/main/res/values-es/strings.xml
trans.es_ES = core/src/main/res/values-es-rES/strings.xml trans.es_ES = core/src/main/res/values-es-rES/strings.xml
trans.fi = core/src/main/res/values-fi/strings.xml
trans.fr = core/src/main/res/values-fr/strings.xml trans.fr = core/src/main/res/values-fr/strings.xml
trans.he_IL = core/src/main/res/values-iw-rIL/strings.xml trans.he_IL = core/src/main/res/values-iw-rIL/strings.xml
trans.hi_IN = core/src/main/res/values-hi-rIN/strings.xml trans.hi_IN = core/src/main/res/values-hi-rIN/strings.xml
trans.hu = core/src/main/res/values-hu/strings.xml
trans.id = core/src/main/res/values-id/strings.xml
trans.it = core/src/main/res/values-it/strings.xml
trans.it_IT = core/src/main/res/values-it-rIT/strings.xml trans.it_IT = core/src/main/res/values-it-rIT/strings.xml
trans.ja = core/src/main/res/values-ja/strings.xml trans.ja = core/src/main/res/values-ja/strings.xml
trans.kn_IN = core/src/main/res/values-kn-rIN/strings.xml
trans.ko = core/src/main/res/values-ko/strings.xml trans.ko = core/src/main/res/values-ko/strings.xml
trans.ko_KR = core/src/main/res/values-ko-rKR/strings.xml
trans.nb = core/src/main/res/values-nb/strings.xml
trans.no = core/src/main/res/values-no/strings.xml
trans.nl = core/src/main/res/values-nl/strings.xml trans.nl = core/src/main/res/values-nl/strings.xml
trans.nb_NO = core/src/main/res/values-nb/strings.xml trans.nb_NO = core/src/main/res/values-no-rNB/strings.xml
trans.pl = core/src/main/res/values-pl/strings.xml
trans.pl_PL = core/src/main/res/values-pl-rPL/strings.xml trans.pl_PL = core/src/main/res/values-pl-rPL/strings.xml
trans.pt = core/src/main/res/values-pt/strings.xml trans.pt = core/src/main/res/values-pt/strings.xml
trans.pt_BR = core/src/main/res/values-pt-rBR/strings.xml trans.pt_BR = core/src/main/res/values-pt-rBR/strings.xml
@ -30,6 +42,8 @@ trans.uk_UA = core/src/main/res/values-uk-rUA/strings.xml
trans.zh_CN = core/src/main/res/values-zh-rCN/strings.xml trans.zh_CN = core/src/main/res/values-zh-rCN/strings.xml
trans.sv_SE = core/src/main/res/values-sv-rSE/strings.xml trans.sv_SE = core/src/main/res/values-sv-rSE/strings.xml
trans.tr = core/src/main/res/values-tr/strings.xml trans.tr = core/src/main/res/values-tr/strings.xml
trans.vi = core/src/main/res/values-vi/strings.xml
trans.vi_VN = core/src/main/res/values-vi-rVN/strings.xml
[antennapod.description] [antennapod.description]
file_filter = description/<lang>.txt file_filter = description/<lang>.txt

View File

@ -1,5 +1,13 @@
Change Log Change Log
========== ==========
Version 1.5.0
-------------
* Exclude episodes from auto download by keyword
* Configure feeds to prevent them from refreshing automatically
* Improved audio player
* Improved UI
* Bug fixes
Version 1.4.1 Version 1.4.1
------------- -------------
* Performance improvements * Performance improvements

33
ISSUE_TEMPLATE.md Normal file
View File

@ -0,0 +1,33 @@
---
DELETE ME<br/>
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 submitting a feature request, please read [this](https://github.com/AntennaPod/AntennaPod/blob/develop/CONTRIBUTING.md#how-to-submit-a-feature-request).
In particular, please not only tell us that you want something (*what*), but also make suggestions *how* it should be implemented.
---
**App version:** 1.x (from Google Play/F-Store/Custom build)
**Android version**: 5.x [Please mention if you are using a custom rom!]
**Devide model**:
**Expected behaviour**:
**Current behaviour**:
**First occured**: Version 1.x / about x days/weeks ago
**Steps to reproduce**:
1. This
1. Than that
1. Then
**Environment**: [Settings you have changed, e.g. Auto Download. "Unusual" devices you use, e.g. Bluetooth headphones. Do you still use Prestissimo?]
**Stacktrace/Logcat**:
```
[if available]
```

View File

@ -70,6 +70,7 @@ android {
versionName "${getMyVersionName()}" versionName "${getMyVersionName()}"
testApplicationId "de.test.antennapod" testApplicationId "de.test.antennapod"
testInstrumentationRunner "de.test.antennapod.AntennaPodTestRunner" testInstrumentationRunner "de.test.antennapod.AntennaPodTestRunner"
generatedDensities = []
} }
signingConfigs { signingConfigs {
@ -131,6 +132,10 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8
} }
aaptOptions {
additionalParameters "--no-version-vectors"
}
} }
// about.html is templatized so that we can automatically insert // about.html is templatized so that we can automatically insert

View File

@ -162,7 +162,7 @@ public class FeedHandlerTest extends InstrumentationTestCase {
if (withImage) { if (withImage) {
image = new FeedImage(0, "image", null, "http://example.com/picture", false); image = new FeedImage(0, "image", null, "http://example.com/picture", false);
} }
Feed feed = new Feed(0, new Date(), "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", image, file.getAbsolutePath(),
"http://example.com/feed", true); "http://example.com/feed", true);
feed.setItems(new ArrayList<FeedItem>()); feed.setItems(new ArrayList<FeedItem>());

View File

@ -53,7 +53,10 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
super.setUp(); super.setUp();
assertionError = null; assertionError = null;
final Context context = getInstrumentation().getTargetContext();
// create new database // create new database
PodDBAdapter.init(context);
PodDBAdapter.deleteDatabase(); PodDBAdapter.deleteDatabase();
PodDBAdapter adapter = PodDBAdapter.getInstance(); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
@ -62,7 +65,6 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
httpServer = new HTTPBin(); httpServer = new HTTPBin();
httpServer.start(); httpServer.start();
final Context context = getInstrumentation().getTargetContext();
File cacheDir = context.getExternalFilesDir("testFiles"); File cacheDir = context.getExternalFilesDir("testFiles");
if (cacheDir == null) if (cacheDir == null)
cacheDir = context.getExternalFilesDir("testFiles"); cacheDir = context.getExternalFilesDir("testFiles");
@ -115,7 +117,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
private Playable writeTestPlayable(String downloadUrl, String fileUrl) { private Playable writeTestPlayable(String downloadUrl, String fileUrl) {
final Context c = getInstrumentation().getTargetContext(); final Context c = getInstrumentation().getTargetContext();
Feed f = new Feed(0, new Date(), "f", "l", "d", null, null, null, null, "i", null, null, "l", false); Feed f = new Feed(0, null, "f", "l", "d", null, null, null, null, "i", null, null, "l", false);
FeedPreferences prefs = new FeedPreferences(f.getId(), false, FeedPreferences.AutoDeleteAction.NO, null, null); FeedPreferences prefs = new FeedPreferences(f.getId(), false, FeedPreferences.AutoDeleteAction.NO, null, null);
f.setPreferences(prefs); f.setPreferences(prefs);
f.setItems(new ArrayList<>()); f.setItems(new ArrayList<>());
@ -167,6 +169,11 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
} }
@Override
public void setSpeedAbilityChanged() {
}
@Override @Override
public void onBufferingUpdate(int percent) { public void onBufferingUpdate(int percent) {
@ -236,6 +243,11 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
} }
@Override
public void setSpeedAbilityChanged() {
}
@Override @Override
public void onBufferingUpdate(int percent) { public void onBufferingUpdate(int percent) {
@ -308,6 +320,11 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
} }
@Override
public void setSpeedAbilityChanged() {
}
@Override @Override
public void onBufferingUpdate(int percent) { public void onBufferingUpdate(int percent) {
@ -381,6 +398,11 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
} }
@Override
public void setSpeedAbilityChanged() {
}
@Override @Override
public void onBufferingUpdate(int percent) { public void onBufferingUpdate(int percent) {
@ -448,6 +470,11 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
} }
@Override
public void setSpeedAbilityChanged() {
}
@Override @Override
public void onBufferingUpdate(int percent) { public void onBufferingUpdate(int percent) {
@ -516,6 +543,11 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
} }
@Override
public void setSpeedAbilityChanged() {
}
@Override @Override
public void onBufferingUpdate(int percent) { public void onBufferingUpdate(int percent) {
@ -586,6 +618,11 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
} }
@Override
public void setSpeedAbilityChanged() {
}
@Override @Override
public void onBufferingUpdate(int percent) { public void onBufferingUpdate(int percent) {
@ -659,6 +696,11 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
} }
@Override
public void setSpeedAbilityChanged() {
}
@Override @Override
public void onBufferingUpdate(int percent) { public void onBufferingUpdate(int percent) {
@ -707,6 +749,11 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
} }
@Override
public void setSpeedAbilityChanged() {
}
@Override @Override
public void onBufferingUpdate(int percent) { public void onBufferingUpdate(int percent) {
@ -775,6 +822,11 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
} }
@Override
public void setSpeedAbilityChanged() {
}
@Override @Override
public void onBufferingUpdate(int percent) { public void onBufferingUpdate(int percent) {
@ -880,6 +932,11 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
} }
@Override
public void setSpeedAbilityChanged() {
}
@Override @Override
public void onBufferingUpdate(int percent) { public void onBufferingUpdate(int percent) {
@ -962,6 +1019,11 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
} }
@Override
public void setSpeedAbilityChanged() {
}
@Override @Override
public void onBufferingUpdate(int percent) { public void onBufferingUpdate(int percent) {
@ -1056,6 +1118,11 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
} }
@Override
public void setSpeedAbilityChanged() {
}
@Override @Override
public void onBufferingUpdate(int percent) { public void onBufferingUpdate(int percent) {

View File

@ -34,6 +34,7 @@ public class PlaybackServiceTaskManagerTest extends InstrumentationTestCase {
super.setUp(); super.setUp();
// create new database // create new database
PodDBAdapter.init(getInstrumentation().getTargetContext());
PodDBAdapter.deleteDatabase(); PodDBAdapter.deleteDatabase();
PodDBAdapter adapter = PodDBAdapter.getInstance(); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
@ -48,7 +49,7 @@ public class PlaybackServiceTaskManagerTest extends InstrumentationTestCase {
private List<FeedItem> writeTestQueue(String pref) { private List<FeedItem> writeTestQueue(String pref) {
final Context c = getInstrumentation().getTargetContext(); final Context c = getInstrumentation().getTargetContext();
final int NUM_ITEMS = 10; final int NUM_ITEMS = 10;
Feed f = new Feed(0, new Date(), "title", "link", "d", null, null, null, null, "id", null, "null", "url", false); Feed f = new Feed(0, null, "title", "link", "d", null, null, null, null, "id", null, "null", "url", false);
f.setItems(new ArrayList<>()); f.setItems(new ArrayList<>());
for (int i = 0; i < NUM_ITEMS; i++) { for (int i = 0; i < NUM_ITEMS; i++) {
f.getItems().add(new FeedItem(0, pref + i, pref + i, "link", new Date(), FeedItem.PLAYED, f)); f.getItems().add(new FeedItem(0, pref + i, pref + i, "link", new Date(), FeedItem.PLAYED, f));

View File

@ -70,6 +70,7 @@ public class DBCleanupTests extends InstrumentationTestCase {
assertTrue(destFolder.canWrite()); assertTrue(destFolder.canWrite());
// create new database // create new database
PodDBAdapter.init(context);
PodDBAdapter.deleteDatabase(); PodDBAdapter.deleteDatabase();
PodDBAdapter adapter = PodDBAdapter.getInstance(); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
@ -87,7 +88,7 @@ public class DBCleanupTests extends InstrumentationTestCase {
public void testPerformAutoCleanupShouldDelete() throws IOException { public void testPerformAutoCleanupShouldDelete() throws IOException {
final int NUM_ITEMS = EPISODE_CACHE_SIZE * 2; final int NUM_ITEMS = EPISODE_CACHE_SIZE * 2;
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", null, "title");
List<FeedItem> items = new ArrayList<>(); List<FeedItem> items = new ArrayList<>();
feed.setItems(items); feed.setItems(items);
List<File> files = new ArrayList<>(); List<File> files = new ArrayList<>();
@ -143,7 +144,7 @@ public class DBCleanupTests extends InstrumentationTestCase {
public void testPerformAutoCleanupHandleUnplayed() throws IOException { public void testPerformAutoCleanupHandleUnplayed() throws IOException {
final int NUM_ITEMS = EPISODE_CACHE_SIZE * 2; final int NUM_ITEMS = EPISODE_CACHE_SIZE * 2;
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", null, "title");
List<FeedItem> items = new ArrayList<FeedItem>(); List<FeedItem> items = new ArrayList<FeedItem>();
feed.setItems(items); feed.setItems(items);
List<File> files = new ArrayList<File>(); List<File> files = new ArrayList<File>();
@ -159,7 +160,7 @@ public class DBCleanupTests extends InstrumentationTestCase {
public void testPerformAutoCleanupShouldNotDeleteBecauseInQueue() throws IOException { public void testPerformAutoCleanupShouldNotDeleteBecauseInQueue() throws IOException {
final int NUM_ITEMS = EPISODE_CACHE_SIZE * 2; final int NUM_ITEMS = EPISODE_CACHE_SIZE * 2;
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", null, "title");
List<FeedItem> items = new ArrayList<>(); List<FeedItem> items = new ArrayList<>();
feed.setItems(items); feed.setItems(items);
List<File> files = new ArrayList<>(); List<File> files = new ArrayList<>();
@ -198,7 +199,7 @@ public class DBCleanupTests extends InstrumentationTestCase {
public void testPerformAutoCleanupShouldNotDeleteBecauseFavorite() throws IOException { public void testPerformAutoCleanupShouldNotDeleteBecauseFavorite() throws IOException {
final int NUM_ITEMS = EPISODE_CACHE_SIZE * 2; final int NUM_ITEMS = EPISODE_CACHE_SIZE * 2;
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", null, "title");
List<FeedItem> items = new ArrayList<>(); List<FeedItem> items = new ArrayList<>();
feed.setItems(items); feed.setItems(items);
List<File> files = new ArrayList<>(); List<File> files = new ArrayList<>();

View File

@ -19,8 +19,6 @@ import de.danoeh.antennapod.core.preferences.UserPreferences;
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 de.test.antennapod.storage.DBTestUtils.saveFeedlist;
/** /**
* Tests that the APNullCleanupAlgorithm is working correctly. * Tests that the APNullCleanupAlgorithm is working correctly.
*/ */
@ -60,6 +58,7 @@ public class DBNullCleanupAlgorithmTest extends InstrumentationTestCase {
assertTrue(destFolder.canWrite()); assertTrue(destFolder.canWrite());
// create new database // create new database
PodDBAdapter.init(context);
PodDBAdapter.deleteDatabase(); PodDBAdapter.deleteDatabase();
PodDBAdapter adapter = PodDBAdapter.getInstance(); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
@ -82,7 +81,7 @@ public class DBNullCleanupAlgorithmTest extends InstrumentationTestCase {
public void testPerformAutoCleanupShouldNotDelete() throws IOException { public void testPerformAutoCleanupShouldNotDelete() throws IOException {
final int NUM_ITEMS = EPISODE_CACHE_SIZE * 2; final int NUM_ITEMS = EPISODE_CACHE_SIZE * 2;
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", null, "title");
List<FeedItem> items = new ArrayList<>(); List<FeedItem> items = new ArrayList<>();
feed.setItems(items); feed.setItems(items);
List<File> files = new ArrayList<>(); List<File> files = new ArrayList<>();

View File

@ -32,7 +32,7 @@ public class DBQueueCleanupAlgorithmTest extends DBCleanupTests {
public void testPerformAutoCleanupHandleUnplayed() throws IOException { public void testPerformAutoCleanupHandleUnplayed() throws IOException {
final int NUM_ITEMS = EPISODE_CACHE_SIZE * 2; final int NUM_ITEMS = EPISODE_CACHE_SIZE * 2;
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", null, "title");
List<FeedItem> items = new ArrayList<>(); List<FeedItem> items = new ArrayList<>();
feed.setItems(items); feed.setItems(items);
List<File> files = new ArrayList<>(); List<File> files = new ArrayList<>();

View File

@ -34,6 +34,7 @@ public class DBReaderTest extends InstrumentationTestCase {
super.setUp(); super.setUp();
// create new database // create new database
PodDBAdapter.init(getInstrumentation().getTargetContext());
PodDBAdapter.deleteDatabase(); PodDBAdapter.deleteDatabase();
PodDBAdapter adapter = PodDBAdapter.getInstance(); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
@ -54,10 +55,10 @@ public class DBReaderTest extends InstrumentationTestCase {
PodDBAdapter adapter = PodDBAdapter.getInstance(); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
Feed feed1 = new Feed(0, new Date(), "A", "link", "d", null, null, null, "rss", "A", null, "", "", true); Feed feed1 = new Feed(0, null, "A", "link", "d", null, null, null, "rss", "A", null, "", "", true);
Feed feed2 = new Feed(0, new Date(), "b", "link", "d", null, null, null, "rss", "b", null, "", "", true); Feed feed2 = new Feed(0, null, "b", "link", "d", null, null, null, "rss", "b", null, "", "", true);
Feed feed3 = new Feed(0, new Date(), "C", "link", "d", null, null, null, "rss", "C", null, "", "", true); Feed feed3 = new Feed(0, null, "C", "link", "d", null, null, null, "rss", "C", null, "", "", true);
Feed feed4 = new Feed(0, new Date(), "d", "link", "d", null, null, null, "rss", "d", null, "", "", true); Feed feed4 = new Feed(0, null, "d", "link", "d", null, null, null, "rss", "d", null, "", "", true);
adapter.setCompleteFeed(feed1); adapter.setCompleteFeed(feed1);
adapter.setCompleteFeed(feed2); adapter.setCompleteFeed(feed2);
adapter.setCompleteFeed(feed3); adapter.setCompleteFeed(feed3);

View File

@ -1,14 +1,11 @@
package de.test.antennapod.storage; package de.test.antennapod.storage;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.test.FlakyTest; import android.test.FlakyTest;
import android.test.InstrumentationTestCase; import android.test.InstrumentationTestCase;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@ -21,8 +18,6 @@ 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 de.test.antennapod.storage.DBTestUtils.saveFeedlist;
/** /**
* Test class for DBTasks * Test class for DBTasks
*/ */
@ -35,7 +30,6 @@ public class DBTasksTest extends InstrumentationTestCase {
@Override @Override
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
super.tearDown(); super.tearDown();
assertTrue(PodDBAdapter.deleteDatabase()); assertTrue(PodDBAdapter.deleteDatabase());
} }
@ -45,6 +39,7 @@ public class DBTasksTest extends InstrumentationTestCase {
context = getInstrumentation().getTargetContext(); context = getInstrumentation().getTargetContext();
// create new database // create new database
PodDBAdapter.init(context);
PodDBAdapter.deleteDatabase(); PodDBAdapter.deleteDatabase();
PodDBAdapter adapter = PodDBAdapter.getInstance(); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
@ -57,7 +52,7 @@ public class DBTasksTest extends InstrumentationTestCase {
public void testUpdateFeedNewFeed() { public void testUpdateFeedNewFeed() {
final int NUM_ITEMS = 10; final int NUM_ITEMS = 10;
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>()); feed.setItems(new ArrayList<>());
for (int i = 0; i < NUM_ITEMS; i++) { for (int i = 0; i < NUM_ITEMS; i++) {
feed.getItems().add(new FeedItem(0, "item " + i, "id " + i, "link " + i, new Date(), FeedItem.UNPLAYED, feed)); feed.getItems().add(new FeedItem(0, "item " + i, "id " + i, "link " + i, new Date(), FeedItem.UNPLAYED, feed));
@ -75,8 +70,8 @@ public class DBTasksTest extends InstrumentationTestCase {
/** Two feeds with the same title, but different download URLs should be treated as different feeds. */ /** Two feeds with the same title, but different download URLs should be treated as different feeds. */
public void testUpdateFeedSameTitle() { public void testUpdateFeedSameTitle() {
Feed feed1 = new Feed("url1", new Date(), "title"); Feed feed1 = new Feed("url1", null, "title");
Feed feed2 = new Feed("url2", new Date(), "title"); Feed feed2 = new Feed("url2", null, "title");
feed1.setItems(new ArrayList<>()); feed1.setItems(new ArrayList<>());
feed2.setItems(new ArrayList<>()); feed2.setItems(new ArrayList<>());
@ -91,7 +86,7 @@ public class DBTasksTest extends InstrumentationTestCase {
final int NUM_ITEMS_OLD = 10; final int NUM_ITEMS_OLD = 10;
final int NUM_ITEMS_NEW = 10; final int NUM_ITEMS_NEW = 10;
final Feed feed = new Feed("url", new Date(), "title"); final Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>()); feed.setItems(new ArrayList<>());
for (int i = 0; i < NUM_ITEMS_OLD; i++) { for (int i = 0; i < NUM_ITEMS_OLD; i++) {
feed.getItems().add(new FeedItem(0, "item " + i, "id " + i, "link " + i, new Date(i), FeedItem.PLAYED, feed)); feed.getItems().add(new FeedItem(0, "item " + i, "id " + i, "link " + i, new Date(i), FeedItem.PLAYED, feed));
@ -127,6 +122,32 @@ public class DBTasksTest extends InstrumentationTestCase {
updatedFeedTest(feedFromDB, feedID, itemIDs, NUM_ITEMS_OLD, NUM_ITEMS_NEW); updatedFeedTest(feedFromDB, feedID, itemIDs, NUM_ITEMS_OLD, NUM_ITEMS_NEW);
} }
public void testUpdateFeedMediaUrlResetState() {
final Feed feed = new Feed("url", null, "title");
FeedItem item = new FeedItem(0, "item", "id", "link", new Date(), FeedItem.PLAYED, feed);
feed.setItems(Arrays.asList(item));
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
adapter.setCompleteFeed(feed);
adapter.close();
// ensure that objects have been saved in db, then reset
assertTrue(feed.getId() != 0);
assertTrue(item.getId() != 0);
FeedMedia media = new FeedMedia(item, "url", 1024, "mime/type");
item.setMedia(media);
feed.setItems(Arrays.asList(item));
final Feed newFeed = DBTasks.updateFeed(context, feed)[0];
assertTrue(feed != newFeed);
final Feed feedFromDB = DBReader.getFeed(newFeed.getId());
final FeedItem feedItemFromDB = feedFromDB.getItems().get(0);
assertTrue("state: " + feedItemFromDB.getState(), feedItemFromDB.isNew());
}
private void updatedFeedTest(final Feed newFeed, long feedID, List<Long> itemIDs, final int NUM_ITEMS_OLD, final int NUM_ITEMS_NEW) { private void updatedFeedTest(final Feed newFeed, long feedID, List<Long> itemIDs, final int NUM_ITEMS_OLD, final int NUM_ITEMS_NEW) {
assertTrue(newFeed.getId() == feedID); assertTrue(newFeed.getId() == feedID);
assertTrue(newFeed.getItems().size() == NUM_ITEMS_NEW + NUM_ITEMS_OLD); assertTrue(newFeed.getItems().size() == NUM_ITEMS_NEW + NUM_ITEMS_OLD);

View File

@ -44,7 +44,7 @@ public class DBTestUtils {
PodDBAdapter adapter = PodDBAdapter.getInstance(); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
for (int i = 0; i < numFeeds; i++) { for (int i = 0; i < numFeeds; i++) {
Feed f = new Feed(0, new Date(), "feed " + i, "link" + i, "descr", null, null, Feed f = new Feed(0, null, "feed " + i, "link" + i, "descr", null, null,
null, null, "id" + i, null, null, "url" + i, false, new FlattrStatus(), false, null, null, false); null, null, "id" + i, null, null, "url" + i, false, new FlattrStatus(), false, null, null, false);
f.setItems(new ArrayList<>()); f.setItems(new ArrayList<>());
for (int j = 0; j < numItems; j++) { for (int j = 0; j < numItems; j++) {

View File

@ -53,19 +53,21 @@ public class DBWriterTest extends InstrumentationTestCase {
super.setUp(); super.setUp();
// create new database // create new database
PodDBAdapter.init(getInstrumentation().getTargetContext());
PodDBAdapter.deleteDatabase(); PodDBAdapter.deleteDatabase();
PodDBAdapter adapter = PodDBAdapter.getInstance(); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.close(); adapter.close();
} }
public void testSetFeedMediaPlaybackInformation() throws IOException, ExecutionException, InterruptedException { public void testSetFeedMediaPlaybackInformation()
throws IOException, ExecutionException, InterruptedException, TimeoutException {
final int POSITION = 50; final int POSITION = 50;
final long LAST_PLAYED_TIME = 1000; final long LAST_PLAYED_TIME = 1000;
final int PLAYED_DURATION = 60; final int PLAYED_DURATION = 60;
final int DURATION = 100; final int DURATION = 100;
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", null, "title");
List<FeedItem> items = new ArrayList<>(); List<FeedItem> items = new ArrayList<>();
feed.setItems(items); feed.setItems(items);
FeedItem item = new FeedItem(0, "Item", "Item", "url", new Date(), FeedItem.PLAYED, feed); FeedItem item = new FeedItem(0, "Item", "Item", "url", new Date(), FeedItem.PLAYED, feed);
@ -73,13 +75,13 @@ public class DBWriterTest extends InstrumentationTestCase {
FeedMedia media = new FeedMedia(0, item, DURATION, 1, 1, "mime_type", "dummy path", "download_url", true, null, 0, 0); FeedMedia media = new FeedMedia(0, item, DURATION, 1, 1, "mime_type", "dummy path", "download_url", true, null, 0, 0);
item.setMedia(media); item.setMedia(media);
DBWriter.setFeedItem(item).get(); DBWriter.setFeedItem(item).get(TIMEOUT, TimeUnit.SECONDS);
media.setPosition(POSITION); media.setPosition(POSITION);
media.setLastPlayedTime(LAST_PLAYED_TIME); media.setLastPlayedTime(LAST_PLAYED_TIME);
media.setPlayedDuration(PLAYED_DURATION); media.setPlayedDuration(PLAYED_DURATION);
DBWriter.setFeedMediaPlaybackInformation(item.getMedia()).get(); DBWriter.setFeedMediaPlaybackInformation(item.getMedia()).get(TIMEOUT, TimeUnit.SECONDS);
FeedItem itemFromDb = DBReader.getFeedItem(item.getId()); FeedItem itemFromDb = DBReader.getFeedItem(item.getId());
FeedMedia mediaFromDb = itemFromDb.getMedia(); FeedMedia mediaFromDb = itemFromDb.getMedia();
@ -90,12 +92,13 @@ public class DBWriterTest extends InstrumentationTestCase {
assertEquals(DURATION, mediaFromDb.getDuration()); assertEquals(DURATION, mediaFromDb.getDuration());
} }
public void testDeleteFeedMediaOfItemFileExists() throws IOException, ExecutionException, InterruptedException { public void testDeleteFeedMediaOfItemFileExists()
throws IOException, ExecutionException, InterruptedException, TimeoutException {
File dest = new File(getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER), "testFile"); File dest = new File(getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER), "testFile");
assertTrue(dest.createNewFile()); assertTrue(dest.createNewFile());
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", null, "title");
List<FeedItem> items = new ArrayList<>(); List<FeedItem> items = new ArrayList<>();
feed.setItems(items); feed.setItems(items);
FeedItem item = new FeedItem(0, "Item", "Item", "url", new Date(), FeedItem.PLAYED, feed); FeedItem item = new FeedItem(0, "Item", "Item", "url", new Date(), FeedItem.PLAYED, feed);
@ -112,7 +115,8 @@ public class DBWriterTest extends InstrumentationTestCase {
assertTrue(media.getId() != 0); assertTrue(media.getId() != 0);
assertTrue(item.getId() != 0); assertTrue(item.getId() != 0);
DBWriter.deleteFeedMediaOfItem(getInstrumentation().getTargetContext(), media.getId()).get(); DBWriter.deleteFeedMediaOfItem(getInstrumentation().getTargetContext(), media.getId())
.get(TIMEOUT, TimeUnit.SECONDS);
media = DBReader.getFeedMedia(media.getId()); media = DBReader.getFeedMedia(media.getId());
assertNotNull(media); assertNotNull(media);
assertFalse(dest.exists()); assertFalse(dest.exists());
@ -124,7 +128,7 @@ public class DBWriterTest extends InstrumentationTestCase {
File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER); File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
assertNotNull(destFolder); assertNotNull(destFolder);
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>()); feed.setItems(new ArrayList<>());
// create Feed image // create Feed image
@ -191,13 +195,14 @@ public class DBWriterTest extends InstrumentationTestCase {
assertEquals(0, c.getCount()); assertEquals(0, c.getCount());
c.close(); c.close();
} }
adapter.close();
} }
public void testDeleteFeedNoImage() throws ExecutionException, InterruptedException, IOException, TimeoutException { public void testDeleteFeedNoImage() 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", new Date(), "title"); Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>()); feed.setItems(new ArrayList<>());
feed.setImage(null); feed.setImage(null);
@ -247,13 +252,14 @@ public class DBWriterTest extends InstrumentationTestCase {
assertTrue(c.getCount() == 0); assertTrue(c.getCount() == 0);
c.close(); c.close();
} }
adapter.close();
} }
public void testDeleteFeedNoItems() throws IOException, ExecutionException, InterruptedException, TimeoutException { public void testDeleteFeedNoItems() throws IOException, ExecutionException, InterruptedException, TimeoutException {
File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER); File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
assertNotNull(destFolder); assertNotNull(destFolder);
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", null, "title");
feed.setItems(null); feed.setItems(null);
// create Feed image // create Feed image
@ -284,13 +290,14 @@ public class DBWriterTest extends InstrumentationTestCase {
c = adapter.getImageCursor(String.valueOf(image.getId())); c = adapter.getImageCursor(String.valueOf(image.getId()));
assertTrue(c.getCount() == 0); assertTrue(c.getCount() == 0);
c.close(); c.close();
adapter.close();
} }
public void testDeleteFeedNoFeedMedia() throws IOException, ExecutionException, InterruptedException, TimeoutException { public void testDeleteFeedNoFeedMedia() throws IOException, ExecutionException, InterruptedException, TimeoutException {
File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER); File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
assertNotNull(destFolder); assertNotNull(destFolder);
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>()); feed.setItems(new ArrayList<>());
// create Feed image // create Feed image
@ -336,13 +343,14 @@ public class DBWriterTest extends InstrumentationTestCase {
assertTrue(c.getCount() == 0); assertTrue(c.getCount() == 0);
c.close(); c.close();
} }
adapter.close();
} }
public void testDeleteFeedWithItemImages() throws InterruptedException, ExecutionException, TimeoutException, IOException { public void testDeleteFeedWithItemImages() throws InterruptedException, ExecutionException, TimeoutException, IOException {
File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER); File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
assertNotNull(destFolder); assertNotNull(destFolder);
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>()); feed.setItems(new ArrayList<>());
// create Feed image // create Feed image
@ -394,13 +402,14 @@ public class DBWriterTest extends InstrumentationTestCase {
assertEquals(0, c.getCount()); assertEquals(0, c.getCount());
c.close(); 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);
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>()); feed.setItems(new ArrayList<>());
// create Feed image // create Feed image
@ -472,7 +481,7 @@ public class DBWriterTest extends InstrumentationTestCase {
File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER); File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
assertNotNull(destFolder); assertNotNull(destFolder);
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<FeedItem>()); feed.setItems(new ArrayList<FeedItem>());
// create Feed image // create Feed image
@ -524,11 +533,12 @@ public class DBWriterTest extends InstrumentationTestCase {
assertTrue(c.getCount() == 0); assertTrue(c.getCount() == 0);
c.close(); c.close();
} }
adapter.close();
} }
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", new Date(), "title"); Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<FeedItem>()); feed.setItems(new ArrayList<FeedItem>());
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);
@ -542,9 +552,10 @@ public class DBWriterTest extends InstrumentationTestCase {
return media; return media;
} }
public void testAddItemToPlaybackHistoryNotPlayedYet() throws ExecutionException, InterruptedException { public void testAddItemToPlaybackHistoryNotPlayedYet()
throws ExecutionException, InterruptedException, TimeoutException {
FeedMedia media = playbackHistorySetup(null); FeedMedia media = playbackHistorySetup(null);
DBWriter.addItemToPlaybackHistory(media).get(); DBWriter.addItemToPlaybackHistory(media).get(TIMEOUT, TimeUnit.SECONDS);
PodDBAdapter adapter = PodDBAdapter.getInstance(); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
media = DBReader.getFeedMedia(media.getId()); media = DBReader.getFeedMedia(media.getId());
@ -554,11 +565,12 @@ public class DBWriterTest extends InstrumentationTestCase {
assertNotNull(media.getPlaybackCompletionDate()); assertNotNull(media.getPlaybackCompletionDate());
} }
public void testAddItemToPlaybackHistoryAlreadyPlayed() throws ExecutionException, InterruptedException { public void testAddItemToPlaybackHistoryAlreadyPlayed()
throws ExecutionException, InterruptedException, TimeoutException {
final long OLD_DATE = 0; final long OLD_DATE = 0;
FeedMedia media = playbackHistorySetup(new Date(OLD_DATE)); FeedMedia media = playbackHistorySetup(new Date(OLD_DATE));
DBWriter.addItemToPlaybackHistory(media).get(); DBWriter.addItemToPlaybackHistory(media).get(TIMEOUT, TimeUnit.SECONDS);
PodDBAdapter adapter = PodDBAdapter.getInstance(); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
media = DBReader.getFeedMedia(media.getId()); media = DBReader.getFeedMedia(media.getId());
@ -571,7 +583,7 @@ public class DBWriterTest extends InstrumentationTestCase {
private Feed queueTestSetupMultipleItems(final int NUM_ITEMS) throws InterruptedException, ExecutionException, TimeoutException { private Feed queueTestSetupMultipleItems(final int NUM_ITEMS) throws InterruptedException, ExecutionException, TimeoutException {
final Context context = getInstrumentation().getTargetContext(); final Context context = getInstrumentation().getTargetContext();
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>()); 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.PLAYED, feed); FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.PLAYED, feed);
@ -598,7 +610,7 @@ public class DBWriterTest extends InstrumentationTestCase {
public void testAddQueueItemSingleItem() throws InterruptedException, ExecutionException, TimeoutException { public void testAddQueueItemSingleItem() throws InterruptedException, ExecutionException, TimeoutException {
final Context context = getInstrumentation().getTargetContext(); final Context context = getInstrumentation().getTargetContext();
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>()); 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);
feed.getItems().add(item); feed.getItems().add(item);
@ -622,7 +634,7 @@ public class DBWriterTest extends InstrumentationTestCase {
public void testAddQueueItemSingleItemAlreadyInQueue() throws InterruptedException, ExecutionException, TimeoutException { public void testAddQueueItemSingleItemAlreadyInQueue() throws InterruptedException, ExecutionException, TimeoutException {
final Context context = getInstrumentation().getTargetContext(); final Context context = getInstrumentation().getTargetContext();
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>()); 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);
feed.getItems().add(item); feed.getItems().add(item);
@ -688,7 +700,7 @@ public class DBWriterTest extends InstrumentationTestCase {
public void testRemoveQueueItem() throws InterruptedException, ExecutionException, TimeoutException { public void testRemoveQueueItem() throws InterruptedException, ExecutionException, TimeoutException {
final int NUM_ITEMS = 10; final int NUM_ITEMS = 10;
final Context context = getInstrumentation().getTargetContext(); final Context context = getInstrumentation().getTargetContext();
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>()); 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.PLAYED, feed); FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.PLAYED, feed);
@ -725,7 +737,6 @@ public class DBWriterTest extends InstrumentationTestCase {
} }
assertTrue(idFound); assertTrue(idFound);
} }
queue.close(); queue.close();
adapter.close(); adapter.close();
} }
@ -733,7 +744,7 @@ public class DBWriterTest extends InstrumentationTestCase {
public void testMoveQueueItem() throws InterruptedException, ExecutionException, TimeoutException { public void testMoveQueueItem() throws InterruptedException, ExecutionException, TimeoutException {
final int NUM_ITEMS = 10; final int NUM_ITEMS = 10;
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>()); 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.PLAYED, feed); FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.PLAYED, feed);
@ -779,7 +790,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", new Date(), "title"); Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<FeedItem>()); feed.setItems(new ArrayList<FeedItem>());
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);
@ -805,7 +816,7 @@ public class DBWriterTest extends InstrumentationTestCase {
public void testMarkAllItemsReadSameFeed() throws InterruptedException, ExecutionException, TimeoutException { public void testMarkAllItemsReadSameFeed() throws InterruptedException, ExecutionException, TimeoutException {
final int NUM_ITEMS = 10; final int NUM_ITEMS = 10;
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>()); 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);

View File

@ -41,10 +41,12 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
@Override @Override
protected void setUp() throws Exception { protected void setUp() throws Exception {
super.setUp(); super.setUp();
uiTestUtils = new UITestUtils(getInstrumentation().getTargetContext()); Context context = getInstrumentation().getTargetContext();
uiTestUtils = new UITestUtils(context);
uiTestUtils.setup(); uiTestUtils.setup();
// create new database // create new database
PodDBAdapter.init(context);
PodDBAdapter.deleteDatabase(); PodDBAdapter.deleteDatabase();
PodDBAdapter adapter = PodDBAdapter.getInstance(); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
@ -142,6 +144,7 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
return ((MainActivity) solo.getCurrentActivity()).getSupportActionBar().getTitle().toString(); return ((MainActivity) solo.getCurrentActivity()).getSupportActionBar().getTitle().toString();
} }
@SuppressWarnings("unchecked")
@FlakyTest(tolerance = 3) @FlakyTest(tolerance = 3)
public void testGoToPreferences() { public void testGoToPreferences() {
openNavDrawer(); openNavDrawer();

View File

@ -143,7 +143,7 @@ public class UITestUtils {
for (int i = 0; i < NUM_FEEDS; i++) { for (int i = 0; i < NUM_FEEDS; i++) {
File bitmapFile = newBitmapFile("image" + i); File bitmapFile = newBitmapFile("image" + i);
FeedImage image = new FeedImage(0, "image " + i, null, hostFile(bitmapFile), false); FeedImage image = new FeedImage(0, "image " + i, null, hostFile(bitmapFile), false);
Feed feed = new Feed(0, new Date(), "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, image, null,
"http://example.com/feed/src/" + i, false); "http://example.com/feed/src/" + i, false);
image.setOwner(feed); image.setOwner(feed);

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-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:versionCode="1050003" android:versionCode="1050200"
android:versionName="1.5.0.3"> android:versionName="1.5.2.0">
<!-- <!--
Version code schema: Version code schema:
"1.2.3-SNAPSHOT" -> 1020300 "1.2.3-SNAPSHOT" -> 1020300
@ -144,6 +144,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.StatisticsActivity"
android:label="@string/statistics_label">
<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" android:configChanges="keyboardHidden|orientation"
@ -179,7 +186,7 @@
<activity <activity
android:name=".activity.VideoplayerActivity" android:name=".activity.VideoplayerActivity"
android:configChanges="keyboardHidden|orientation" android:configChanges="keyboardHidden|orientation"
android:screenOrientation="landscape"> android:screenOrientation="sensorLandscape">
<meta-data <meta-data
android:name="android.support.PARENT_ACTIVITY" android:name="android.support.PARENT_ACTIVITY"
android:value="de.danoeh.antennapod.activity.MainActivity"/> android:value="de.danoeh.antennapod.activity.MainActivity"/>
@ -201,10 +208,6 @@
android:value="de.danoeh.antennapod.activity.PreferenceActivity"/> android:value="de.danoeh.antennapod.activity.PreferenceActivity"/>
</activity> </activity>
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="de.danoeh.antennapod.activity.PreferenceActivity"/>
<activity <activity
android:name=".activity.OnlineFeedViewActivity" android:name=".activity.OnlineFeedViewActivity"
android:configChanges="orientation" android:configChanges="orientation"

Binary file not shown.

View File

@ -8,11 +8,8 @@ import com.joanzapata.iconify.Iconify;
import com.joanzapata.iconify.fonts.FontAwesomeModule; import com.joanzapata.iconify.fonts.FontAwesomeModule;
import com.joanzapata.iconify.fonts.MaterialModule; import com.joanzapata.iconify.fonts.MaterialModule;
import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.feed.EventDistributor; import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.danoeh.antennapod.core.util.NetworkUtils;
import de.danoeh.antennapod.spa.SPAUtil; import de.danoeh.antennapod.spa.SPAUtil;
/** Main application class. */ /** Main application class. */
@ -56,11 +53,8 @@ public class PodcastApp extends Application {
singleton = this; singleton = this;
PodDBAdapter.init(this); ClientConfig.initialize(this);
UpdateManager.init(this);
UserPreferences.init(this);
PlaybackPreferences.init(this);
NetworkUtils.init(this);
EventDistributor.getInstance(); EventDistributor.getInstance();
Iconify.with(new FontAwesomeModule()); Iconify.with(new FontAwesomeModule());
Iconify.with(new MaterialModule()); Iconify.with(new MaterialModule());

View File

@ -4,7 +4,7 @@ import android.content.res.TypedArray;
import android.graphics.Color; import android.graphics.Color;
import android.os.Build; import android.os.Build;
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.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
@ -30,7 +30,7 @@ import rx.schedulers.Schedulers;
/** /**
* Displays the 'about' screen * Displays the 'about' screen
*/ */
public class AboutActivity extends ActionBarActivity { public class AboutActivity extends AppCompatActivity {
private static final String TAG = AboutActivity.class.getSimpleName(); private static final String TAG = AboutActivity.class.getSimpleName();
@ -87,7 +87,7 @@ public class AboutActivity extends ActionBarActivity {
res.recycle(); res.recycle();
input = getAssets().open(filename); input = getAssets().open(filename);
String webViewData = IOUtils.toString(input, Charset.defaultCharset()); String webViewData = IOUtils.toString(input, Charset.defaultCharset());
if(false == webViewData.startsWith("<!DOCTYPE html>")) { if(!webViewData.startsWith("<!DOCTYPE html>")) {
//webViewData = webViewData.replace("\n\n", "</p><p>"); //webViewData = webViewData.replace("\n\n", "</p><p>");
webViewData = webViewData.replace("%", "&#37;"); webViewData = webViewData.replace("%", "&#37;");
webViewData = webViewData =

View File

@ -94,8 +94,8 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe
private int mPosition = -1; private int mPosition = -1;
private Playable media; private Playable media;
private ViewPager mPager; private ViewPager pager;
private AudioplayerPagerAdapter mPagerAdapter; private AudioplayerPagerAdapter pagerAdapter;
private Subscription subscription; private Subscription subscription;
@ -103,6 +103,7 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe
protected void onStop() { protected void onStop() {
super.onStop(); super.onStop();
Log.d(TAG, "onStop()"); Log.d(TAG, "onStop()");
pagerAdapter.setController(null);
if(subscription != null) { if(subscription != null) {
subscription.unsubscribe(); subscription.unsubscribe();
} }
@ -112,12 +113,16 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe
@Override @Override
public void onDestroy() { public void onDestroy() {
Log.d(TAG, "onDestroy()");
super.onDestroy(); super.onDestroy();
// don't risk creating memory leaks // don't risk creating memory leaks
drawerLayout = null;
navAdapter = null; navAdapter = null;
navList = null;
navDrawer = null;
drawerToggle = null; drawerToggle = null;
mPager = null; pager = null;
mPagerAdapter = null; pagerAdapter = null;
} }
@Override @Override
@ -126,27 +131,29 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe
} }
private void saveCurrentFragment() { private void saveCurrentFragment() {
if(mPager == null) { if(pager == null) {
return; return;
} }
Log.d(TAG, "Saving preferences"); Log.d(TAG, "Saving preferences");
SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE); SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE);
prefs.edit() prefs.edit()
.putInt(PREF_KEY_SELECTED_FRAGMENT_POSITION, mPager.getCurrentItem()) .putInt(PREF_KEY_SELECTED_FRAGMENT_POSITION, pager.getCurrentItem())
.commit(); .commit();
} }
@Override @Override
public void onConfigurationChanged(Configuration newConfig) { public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig); super.onConfigurationChanged(newConfig);
if(drawerToggle != null) {
drawerToggle.onConfigurationChanged(newConfig); drawerToggle.onConfigurationChanged(newConfig);
} }
}
private void loadLastFragment() { private void loadLastFragment() {
Log.d(TAG, "Restoring instance state"); Log.d(TAG, "Restoring instance state");
SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE); SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE);
int lastPosition = prefs.getInt(PREF_KEY_SELECTED_FRAGMENT_POSITION, -1); int lastPosition = prefs.getInt(PREF_KEY_SELECTED_FRAGMENT_POSITION, -1);
mPager.setCurrentItem(lastPosition); pager.setCurrentItem(lastPosition);
} }
@Override @Override
@ -166,9 +173,10 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe
true); true);
startService(launchIntent); startService(launchIntent);
} }
if(mPagerAdapter != null && controller != null && controller.getMedia() != media) { if(pagerAdapter != null && controller != null && controller.getMedia() != media) {
media = controller.getMedia(); media = controller.getMedia();
mPagerAdapter.onMediaChanged(media); pagerAdapter.onMediaChanged(media);
pagerAdapter.setController(controller);
} }
EventDistributor.getInstance().register(contentUpdate); EventDistributor.getInstance().register(contentUpdate);
@ -255,13 +263,14 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe
startActivity(new Intent(AudioplayerActivity.this, PreferenceController.getPreferenceActivity())); startActivity(new Intent(AudioplayerActivity.this, PreferenceController.getPreferenceActivity()));
}); });
mPager = (ViewPager) findViewById(R.id.pager); pager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new AudioplayerPagerAdapter(getSupportFragmentManager()); pagerAdapter = new AudioplayerPagerAdapter(getSupportFragmentManager(), media);
mPager.setAdapter(mPagerAdapter); pagerAdapter.setController(controller);
pager.setAdapter(pagerAdapter);
CirclePageIndicator pageIndicator = (CirclePageIndicator) findViewById(R.id.page_indicator); CirclePageIndicator pageIndicator = (CirclePageIndicator) findViewById(R.id.page_indicator);
pageIndicator.setViewPager(mPager); pageIndicator.setViewPager(pager);
loadLastFragment(); loadLastFragment();
mPager.onSaveInstanceState(); pager.onSaveInstanceState();
} }
@Override @Override
@ -277,13 +286,16 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe
} }
if(controller.getMedia() != media) { if(controller.getMedia() != media) {
media = controller.getMedia(); media = controller.getMedia();
mPagerAdapter.onMediaChanged(media); pagerAdapter.onMediaChanged(media);
} }
return true; return true;
} }
public void notifyMediaPositionChanged() { public void notifyMediaPositionChanged() {
ChaptersFragment chaptersFragment = mPagerAdapter.getChaptersFragment(); if(pagerAdapter == null) {
return;
}
ChaptersFragment chaptersFragment = pagerAdapter.getChaptersFragment();
if(chaptersFragment != null) { if(chaptersFragment != null) {
ChaptersListAdapter adapter = (ChaptersListAdapter) chaptersFragment.getListAdapter(); ChaptersListAdapter adapter = (ChaptersListAdapter) chaptersFragment.getListAdapter();
if (adapter != null) { if (adapter != null) {
@ -329,11 +341,7 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
if (drawerToggle != null && drawerToggle.onOptionsItemSelected(item)) { return drawerToggle != null && drawerToggle.onOptionsItemSelected(item) || super.onOptionsItemSelected(item);
return true;
} else {
return super.onOptionsItemSelected(item);
}
} }
@Override @Override
@ -411,13 +419,13 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe
public void onBackPressed() { public void onBackPressed() {
if(isDrawerOpen()) { if(isDrawerOpen()) {
drawerLayout.closeDrawer(navDrawer); drawerLayout.closeDrawer(navDrawer);
} else if (mPager.getCurrentItem() == 0) { } else if (pager == null || pager.getCurrentItem() == 0) {
// If the user is currently looking at the first step, allow the system to handle the // If the user is currently looking at the first step, allow the system to handle the
// Back button. This calls finish() on this activity and pops the back stack. // Back button. This calls finish() on this activity and pops the back stack.
super.onBackPressed(); super.onBackPressed();
} else { } else {
// Otherwise, select the previous step. // Otherwise, select the previous step.
mPager.setCurrentItem(mPager.getCurrentItem() - 1); pager.setCurrentItem(pager.getCurrentItem() - 1);
} }
} }
@ -452,7 +460,7 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe
private DBReader.NavDrawerData navDrawerData; private DBReader.NavDrawerData navDrawerData;
private void loadData() { private void loadData() {
subscription = Observable.fromCallable(() -> DBReader.getNavDrawerData()) subscription = Observable.fromCallable(DBReader::getNavDrawerData)
.subscribeOn(Schedulers.newThread()) .subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> { .subscribe(result -> {
@ -517,6 +525,11 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe
return (navDrawerData != null) ? navDrawerData.numDownloadedItems : 0; return (navDrawerData != null) ? navDrawerData.numDownloadedItems : 0;
} }
@Override
public int getReclaimableItems() {
return (navDrawerData != null) ? navDrawerData.reclaimableSpace : 0;
}
@Override @Override
public int getFeedCounter(long feedId) { public int getFeedCounter(long feedId) {
return navDrawerData != null ? navDrawerData.feedCounters.get(feedId) : 0; return navDrawerData != null ? navDrawerData.feedCounters.get(feedId) : 0;
@ -527,10 +540,16 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe
void onMediaChanged(Playable media); void onMediaChanged(Playable media);
} }
private class AudioplayerPagerAdapter extends FragmentStatePagerAdapter { private static class AudioplayerPagerAdapter extends FragmentStatePagerAdapter {
public AudioplayerPagerAdapter(FragmentManager fm) { private static final String TAG = "AudioplayerPagerAdapter";
private Playable media;
private PlaybackController controller;
public AudioplayerPagerAdapter(FragmentManager fm, Playable media) {
super(fm); super(fm);
this.media = media;
} }
private CoverFragment coverFragment; private CoverFragment coverFragment;
@ -538,6 +557,7 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe
private ChaptersFragment chaptersFragment; private ChaptersFragment chaptersFragment;
public void onMediaChanged(Playable media) { public void onMediaChanged(Playable media) {
this.media = media;
if(coverFragment != null) { if(coverFragment != null) {
coverFragment.onMediaChanged(media); coverFragment.onMediaChanged(media);
} }
@ -549,6 +569,13 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe
} }
} }
public void setController(PlaybackController controller) {
this.controller = controller;
if(chaptersFragment != null) {
chaptersFragment.setController(controller);
}
}
@Nullable @Nullable
public ChaptersFragment getChaptersFragment() { public ChaptersFragment getChaptersFragment() {
return chaptersFragment; return chaptersFragment;
@ -570,7 +597,8 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe
return itemDescriptionFragment; return itemDescriptionFragment;
case POS_CHAPTERS: case POS_CHAPTERS:
if(chaptersFragment == null) { if(chaptersFragment == null) {
chaptersFragment = ChaptersFragment.newInstance(media, controller); chaptersFragment = ChaptersFragment.newInstance(media);
chaptersFragment.setController(controller);
} }
return chaptersFragment; return chaptersFragment;
default: default:

View File

@ -6,8 +6,8 @@ import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
import android.os.FileObserver; import android.os.FileObserver;
import android.support.v4.app.NavUtils; import android.support.v4.app.NavUtils;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
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.MenuInflater; import android.view.MenuInflater;
@ -34,7 +34,8 @@ import de.danoeh.antennapod.core.preferences.UserPreferences;
* Let's the user choose a directory on the storage device. The selected folder * Let's the user choose a directory on the storage device. The selected folder
* will be sent back to the starting activity as an activity result. * will be sent back to the starting activity as an activity result.
*/ */
public class DirectoryChooserActivity extends ActionBarActivity { public class DirectoryChooserActivity extends AppCompatActivity {
private static final String TAG = "DirectoryChooserActivit"; private static final String TAG = "DirectoryChooserActivit";
private static final String CREATE_DIRECTORY_NAME = "AntennaPod"; private static final String CREATE_DIRECTORY_NAME = "AntennaPod";
@ -242,7 +243,7 @@ public class DirectoryChooserActivity extends ActionBarActivity {
@Override @Override
public void onEvent(int event, String path) { public void onEvent(int event, String path) {
Log.d(TAG, "FileObserver received event " + event); Log.d(TAG, "FileObserver received event " + event);
runOnUiThread(() -> refreshDirectory()); runOnUiThread(DirectoryChooserActivity.this::refreshDirectory);
} }
}; };
} }
@ -250,8 +251,7 @@ public class DirectoryChooserActivity extends ActionBarActivity {
@Override @Override
public boolean onPrepareOptionsMenu(Menu menu) { public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu); super.onPrepareOptionsMenu(menu);
menu.findItem(R.id.new_folder_item) menu.findItem(R.id.new_folder_item).setVisible(isValidFile(selectedDir));
.setVisible(isValidFile(selectedDir));
return true; return true;
} }
@ -333,4 +333,5 @@ public class DirectoryChooserActivity extends ActionBarActivity {
private boolean isValidFile(File file) { private boolean isValidFile(File file) {
return file != null && file.isDirectory() && file.canRead() && file.canWrite(); return file != null && file.isDirectory() && file.canRead() && file.canWrite();
} }
} }

View File

@ -5,7 +5,6 @@ import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.app.ActionBarActivity; import android.support.v7.app.ActionBarActivity;
import android.util.Log; import android.util.Log;
import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView; import android.widget.TextView;
@ -73,17 +72,12 @@ public class DownloadAuthenticationActivity extends ActionBarActivity {
txtvDescription.setText(txtvDescription.getText() + ":\n\n" + request.getTitle()); txtvDescription.setText(txtvDescription.getText() + ":\n\n" + request.getTitle());
butCancel.setOnClickListener(new View.OnClickListener() { butCancel.setOnClickListener(v -> {
@Override
public void onClick(View v) {
setResult(Activity.RESULT_CANCELED); setResult(Activity.RESULT_CANCELED);
finish(); finish();
}
}); });
butConfirm.setOnClickListener(new View.OnClickListener() { butConfirm.setOnClickListener(v -> {
@Override
public void onClick(View v) {
String username = etxtUsername.getText().toString(); String username = etxtUsername.getText().toString();
String password = etxtPassword.getText().toString(); String password = etxtPassword.getText().toString();
request.setUsername(username); request.setUsername(username);
@ -97,7 +91,6 @@ public class DownloadAuthenticationActivity extends ActionBarActivity {
DownloadRequester.getInstance().download(DownloadAuthenticationActivity.this, request); DownloadRequester.getInstance().download(DownloadAuthenticationActivity.this, request);
} }
finish(); finish();
}
}); });
} }

View File

@ -139,20 +139,14 @@ public class FeedInfoActivity extends ActionBarActivity {
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(); FeedPreferences prefs = feed.getPreferences();
imgvCover.post(new Runnable() { imgvCover.post(() -> Glide.with(FeedInfoActivity.this)
@Override
public void run() {
Glide.with(FeedInfoActivity.this)
.load(feed.getImageUri()) .load(feed.getImageUri())
.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)
.fitCenter() .fitCenter()
.dontAnimate() .dontAnimate()
.into(imgvCover); .into(imgvCover));
}
});
txtvTitle.setText(feed.getTitle()); txtvTitle.setText(feed.getTitle());
String description = feed.getDescription(); String description = feed.getDescription();
@ -224,10 +218,12 @@ public class FeedInfoActivity extends ActionBarActivity {
etxtFilterText.setText(filter.getIncludeFilter()); etxtFilterText.setText(filter.getIncludeFilter());
rdoFilterInclude.setChecked(true); rdoFilterInclude.setChecked(true);
rdoFilterExclude.setChecked(false); rdoFilterExclude.setChecked(false);
filterInclude = true;
} else if (filter.excludeOnly()) { } else if (filter.excludeOnly()) {
etxtFilterText.setText(filter.getExcludeFilter()); etxtFilterText.setText(filter.getExcludeFilter());
rdoFilterInclude.setChecked(false); rdoFilterInclude.setChecked(false);
rdoFilterExclude.setChecked(true); rdoFilterExclude.setChecked(true);
filterInclude = false;
} else { } else {
Log.d(TAG, "No filter set"); Log.d(TAG, "No filter set");
rdoFilterInclude.setChecked(false); rdoFilterInclude.setChecked(false);

View File

@ -9,17 +9,17 @@ import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button; import android.widget.Button;
import android.widget.TextView; import android.widget.TextView;
import org.shredzone.flattr4j.exception.FlattrException;
import de.danoeh.antennapod.BuildConfig; 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; import de.danoeh.antennapod.preferences.PreferenceController;
import org.shredzone.flattr4j.exception.FlattrException;
/** Guides the user through the authentication process */ /** Guides the user through the authentication process */
public class FlattrAuthActivity extends ActionBarActivity { public class FlattrAuthActivity extends ActionBarActivity {
@ -46,24 +46,18 @@ public class FlattrAuthActivity extends ActionBarActivity {
butAuthenticate = (Button) findViewById(R.id.but_authenticate); butAuthenticate = (Button) findViewById(R.id.but_authenticate);
butReturn = (Button) findViewById(R.id.but_return_home); butReturn = (Button) findViewById(R.id.but_return_home);
butReturn.setOnClickListener(new OnClickListener() { butReturn.setOnClickListener(v -> {
@Override
public void onClick(View v) {
Intent intent = new Intent(FlattrAuthActivity.this, MainActivity.class); Intent intent = new Intent(FlattrAuthActivity.this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent); startActivity(intent);
}
}); });
butAuthenticate.setOnClickListener(new OnClickListener() { butAuthenticate.setOnClickListener(v -> {
@Override
public void onClick(View v) {
try { try {
FlattrUtils.startAuthProcess(FlattrAuthActivity.this); FlattrUtils.startAuthProcess(FlattrAuthActivity.this);
} catch (FlattrException e) { } catch (FlattrException e) {
e.printStackTrace(); e.printStackTrace();
} }
}
}); });
} }

View File

@ -44,11 +44,13 @@ 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.FeedMedia; import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
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.service.playback.PlayerStatus; 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.DBWriter; import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.util.FeedItemUtil;
import de.danoeh.antennapod.core.util.StorageUtils; import de.danoeh.antennapod.core.util.StorageUtils;
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;
@ -87,6 +89,7 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity
public static final String EXTRA_NAV_INDEX = "nav_index"; public static final String EXTRA_NAV_INDEX = "nav_index";
public static final String EXTRA_FRAGMENT_TAG = "fragment_tag"; public static final String EXTRA_FRAGMENT_TAG = "fragment_tag";
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 SAVE_BACKSTACK_COUNT = "backstackCount"; public static final String SAVE_BACKSTACK_COUNT = "backstackCount";
public static final String SAVE_TITLE = "title"; public static final String SAVE_TITLE = "title";
@ -186,7 +189,7 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity
loadFragment(lastFragment, null); loadFragment(lastFragment, null);
} else { } else {
try { try {
loadFeedFragmentById(Integer.valueOf(lastFragment), null); loadFeedFragmentById(Integer.parseInt(lastFragment), null);
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
// it's not a number, this happens if we removed // it's not a number, this happens if we removed
// a label from the NAV_DRAWER_TAGS // a label from the NAV_DRAWER_TAGS
@ -322,7 +325,6 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity
loadFragment(fragment); loadFragment(fragment);
} }
private void loadFeedFragmentByPosition(int relPos, Bundle args) { private void loadFeedFragmentByPosition(int relPos, Bundle args) {
if(relPos < 0) { if(relPos < 0) {
return; return;
@ -339,15 +341,7 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity
saveLastNavFragment(String.valueOf(feedId)); saveLastNavFragment(String.valueOf(feedId));
currentTitle = ""; currentTitle = "";
getSupportActionBar().setTitle(currentTitle); getSupportActionBar().setTitle(currentTitle);
loadChildFragment(fragment); loadFragment(fragment);
}
private void loadFeedFragment(Feed feed) {
long feedId = feed.getId();
Fragment fragment = ItemlistFragment.newInstance(feedId);
currentTitle = "";
getSupportActionBar().setTitle(currentTitle);
loadChildFragment(fragment);
} }
private void loadFragment(Fragment fragment) { private void loadFragment(Fragment fragment) {
@ -480,8 +474,9 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity
StorageUtils.checkStorageAvailability(this); StorageUtils.checkStorageAvailability(this);
Intent intent = getIntent(); Intent intent = getIntent();
if (navDrawerData != null && intent.hasExtra(EXTRA_NAV_TYPE) && if (intent.hasExtra(EXTRA_FEED_ID) ||
(intent.hasExtra(EXTRA_NAV_INDEX) || intent.hasExtra(EXTRA_FRAGMENT_TAG))) { (navDrawerData != null && intent.hasExtra(EXTRA_NAV_TYPE) &&
(intent.hasExtra(EXTRA_NAV_INDEX) || intent.hasExtra(EXTRA_FRAGMENT_TAG)))) {
handleNavIntent(); handleNavIntent();
} }
loadData(); loadData();
@ -581,23 +576,17 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity
public void onConfirmButtonPressed( public void onConfirmButtonPressed(
DialogInterface dialog) { DialogInterface dialog) {
dialog.dismiss(); dialog.dismiss();
if (externalPlayerFragment != null) { long mediaId = PlaybackPreferences.getCurrentlyPlayingFeedMediaId();
PlaybackController controller = externalPlayerFragment.getPlaybackControllerTestingOnly(); if (mediaId > 0 &&
if (controller != null) { FeedItemUtil.indexOfItemWithMediaId(feed.getItems(), mediaId) >= 0) {
Playable playable = controller.getMedia();
if (playable != null && playable instanceof FeedMedia) {
FeedMedia media = (FeedMedia) playable;
if (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) { int playerStatus = PlaybackPreferences.getCurrentPlayerStatus();
if(playerStatus == PlaybackPreferences.PLAYER_STATUS_PLAYING) {
sendBroadcast(new Intent( sendBroadcast(new Intent(
PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE)); PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE));
} }
} }
}
}
}
remover.executeAsync(); remover.executeAsync();
} }
}; };
@ -659,6 +648,11 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity
return (navDrawerData != null) ? navDrawerData.numDownloadedItems : 0; return (navDrawerData != null) ? navDrawerData.numDownloadedItems : 0;
} }
@Override
public int getReclaimableItems() {
return (navDrawerData != null) ? navDrawerData.reclaimableSpace : 0;
}
@Override @Override
public int getFeedCounter(long feedId) { public int getFeedCounter(long feedId) {
return navDrawerData != null ? navDrawerData.feedCounters.get(feedId) : 0; return navDrawerData != null ? navDrawerData.feedCounters.get(feedId) : 0;
@ -667,7 +661,7 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity
}; };
private void loadData() { private void loadData() {
subscription = Observable.fromCallable(() -> DBReader.getNavDrawerData()) subscription = Observable.fromCallable(DBReader::getNavDrawerData)
.subscribeOn(Schedulers.newThread()) .subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> { .subscribe(result -> {
@ -690,7 +684,7 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity
} }
public void onEvent(SubscriptionFragment.SubscriptionEvent event) { public void onEvent(SubscriptionFragment.SubscriptionEvent event) {
loadFeedFragment(event.feed); loadFeedFragmentById(event.feed.getId(), null);
} }
public void onEventMainThread(ProgressEvent event) { public void onEventMainThread(ProgressEvent event) {
@ -725,15 +719,19 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity
private void handleNavIntent() { private void handleNavIntent() {
Log.d(TAG, "handleNavIntent()"); Log.d(TAG, "handleNavIntent()");
Intent intent = getIntent(); Intent intent = getIntent();
if (intent.hasExtra(EXTRA_NAV_TYPE) && if (intent.hasExtra(EXTRA_FEED_ID) ||
intent.hasExtra(EXTRA_NAV_INDEX) || intent.hasExtra(EXTRA_FRAGMENT_TAG)) { (intent.hasExtra(EXTRA_NAV_TYPE) &&
(intent.hasExtra(EXTRA_NAV_INDEX) || intent.hasExtra(EXTRA_FRAGMENT_TAG)))) {
int index = intent.getIntExtra(EXTRA_NAV_INDEX, -1); int index = intent.getIntExtra(EXTRA_NAV_INDEX, -1);
String tag = intent.getStringExtra(EXTRA_FRAGMENT_TAG); String tag = intent.getStringExtra(EXTRA_FRAGMENT_TAG);
Bundle args = intent.getBundleExtra(EXTRA_FRAGMENT_ARGS); Bundle args = intent.getBundleExtra(EXTRA_FRAGMENT_ARGS);
long feedId = intent.getLongExtra(EXTRA_FEED_ID, 0);
if (index >= 0) { if (index >= 0) {
loadFragment(index, args); loadFragment(index, args);
} else if (tag != null) { } else if (tag != null) {
loadFragment(tag, args); loadFragment(tag, args);
} else if(feedId > 0) {
loadFeedFragmentById(feedId, args);
} }
} }
setIntent(new Intent(MainActivity.this, MainActivity.class)); // to avoid handling the intent twice when the configuration changes setIntent(new Intent(MainActivity.this, MainActivity.class)); // to avoid handling the intent twice when the configuration changes

View File

@ -31,6 +31,8 @@ import com.bumptech.glide.Glide;
import com.joanzapata.iconify.IconDrawable; import com.joanzapata.iconify.IconDrawable;
import com.joanzapata.iconify.fonts.FontAwesomeIcons; import com.joanzapata.iconify.fonts.FontAwesomeIcons;
import java.util.Locale;
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;
@ -171,12 +173,21 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O
super.setScreenOn(enable); super.setScreenOn(enable);
MediaplayerActivity.this.setScreenOn(enable); MediaplayerActivity.this.setScreenOn(enable);
} }
};
@Override
public void onSetSpeedAbilityChanged() {
MediaplayerActivity.this.onSetSpeedAbilityChanged();
}
};
}
protected void onSetSpeedAbilityChanged() {
Log.d(TAG, "onSetSpeedAbilityChanged()");
updatePlaybackSpeedButton();
} }
protected void onPlaybackSpeedChange() { protected void onPlaybackSpeedChange() {
updateButPlaybackSpeed(); updatePlaybackSpeedButtonText();
} }
protected void onServiceQueried() { protected void onServiceQueried() {
@ -206,9 +217,11 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O
@Override @Override
protected void onPause() { protected void onPause() {
super.onPause(); super.onPause();
if(controller != null) {
controller.reinitServiceIfPaused(); controller.reinitServiceIfPaused();
controller.pause(); controller.pause();
} }
}
/** /**
* Should be used to switch to another player activity if the mime type is * Should be used to switch to another player activity if the mime type is
@ -229,8 +242,7 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O
protected void onBufferUpdate(float progress) { protected void onBufferUpdate(float progress) {
if (sbPosition != null) { if (sbPosition != null) {
sbPosition.setSecondaryProgress((int) progress sbPosition.setSecondaryProgress((int) progress * sbPosition.getMax());
* sbPosition.getMax());
} }
} }
@ -254,6 +266,7 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O
Log.d(TAG, "onStop()"); Log.d(TAG, "onStop()");
if (controller != null) { if (controller != null) {
controller.release(); controller.release();
controller = null; // prevent leak
} }
} }
@ -383,18 +396,11 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O
.getSleepTimerTimeLeft())); .getSleepTimerTimeLeft()));
stDialog.positiveText(R.string.disable_sleeptimer_label); stDialog.positiveText(R.string.disable_sleeptimer_label);
stDialog.negativeText(R.string.cancel_label); stDialog.negativeText(R.string.cancel_label);
stDialog.callback(new MaterialDialog.ButtonCallback() { stDialog.onPositive((dialog, which) -> {
@Override
public void onPositive(MaterialDialog dialog) {
dialog.dismiss(); dialog.dismiss();
controller.disableSleepTimer(); controller.disableSleepTimer();
}
@Override
public void onNegative(MaterialDialog dialog) {
dialog.dismiss();
}
}); });
stDialog.onNegative((dialog, which) -> dialog.dismiss());
stDialog.build().show(); stDialog.build().show();
} }
break; break;
@ -412,7 +418,7 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O
case R.id.audio_controls: case R.id.audio_controls:
MaterialDialog dialog = new MaterialDialog.Builder(this) MaterialDialog dialog = new MaterialDialog.Builder(this)
.title(R.string.audio_controls) .title(R.string.audio_controls)
.customView(R.layout.audio_controls, false) .customView(R.layout.audio_controls, true)
.neutralText(R.string.close_label) .neutralText(R.string.close_label)
.onNeutral((dialog1, which) -> { .onNeutral((dialog1, which) -> {
final SeekBar left = (SeekBar) dialog1.findViewById(R.id.volume_left); final SeekBar left = (SeekBar) dialog1.findViewById(R.id.volume_left);
@ -454,14 +460,13 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O
if(controller != null && controller.canSetPlaybackSpeed()) { if(controller != null && controller.canSetPlaybackSpeed()) {
float playbackSpeed = (progress + 10) / 20.0f; float playbackSpeed = (progress + 10) / 20.0f;
controller.setPlaybackSpeed(playbackSpeed); controller.setPlaybackSpeed(playbackSpeed);
String speed = String.format("%.2f", playbackSpeed); String speedPref = String.format(Locale.US, "%.2f", playbackSpeed);
UserPreferences.setPlaybackSpeed(speed); UserPreferences.setPlaybackSpeed(speedPref);
txtvPlaybackSpeed.setText(speed + "x"); String speedStr = String.format("%.2fx", playbackSpeed);
txtvPlaybackSpeed.setText(speedStr);
} else if(fromUser) { } else if(fromUser) {
float speed = Float.valueOf(UserPreferences.getPlaybackSpeed()); float speed = Float.valueOf(UserPreferences.getPlaybackSpeed());
barPlaybackSpeed.post(() -> { barPlaybackSpeed.post(() -> barPlaybackSpeed.setProgress((int) (20 * speed) - 10));
barPlaybackSpeed.setProgress((int) (20 * speed) - 10);
});
} }
} }
@ -479,9 +484,9 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O
barPlaybackSpeed.setProgress((int) (20 * currentSpeed) - 10); barPlaybackSpeed.setProgress((int) (20 * currentSpeed) - 10);
final SeekBar barLeftVolume = (SeekBar) dialog.findViewById(R.id.volume_left); final SeekBar barLeftVolume = (SeekBar) dialog.findViewById(R.id.volume_left);
barLeftVolume.setProgress(100); barLeftVolume.setProgress(UserPreferences.getLeftVolumePercentage());
final SeekBar barRightVolume = (SeekBar) dialog.findViewById(R.id.volume_right); final SeekBar barRightVolume = (SeekBar) dialog.findViewById(R.id.volume_right);
barRightVolume.setProgress(100); barRightVolume.setProgress(UserPreferences.getRightVolumePercentage());
final CheckBox stereoToMono = (CheckBox) dialog.findViewById(R.id.stereo_to_mono); final CheckBox stereoToMono = (CheckBox) dialog.findViewById(R.id.stereo_to_mono);
stereoToMono.setChecked(UserPreferences.stereoToMono()); stereoToMono.setChecked(UserPreferences.stereoToMono());
if (controller != null && !controller.canDownmix()) { if (controller != null && !controller.canDownmix()) {
@ -493,14 +498,9 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O
barLeftVolume.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { barLeftVolume.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override @Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
float leftVolume = 1.0f, rightVolume = 1.0f; controller.setVolume(
if (progress < 100) { Converter.getVolumeFromPercentage(progress),
leftVolume = progress / 100.0f; Converter.getVolumeFromPercentage(barRightVolume.getProgress()));
}
if (barRightVolume.getProgress() < 100) {
rightVolume = barRightVolume.getProgress() / 100.0f;
}
controller.setVolume(leftVolume, rightVolume);
} }
@Override @Override
@ -514,14 +514,9 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O
barRightVolume.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { barRightVolume.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override @Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
float leftVolume = 1.0f, rightVolume = 1.0f; controller.setVolume(
if (progress < 100) { Converter.getVolumeFromPercentage(barLeftVolume.getProgress()),
rightVolume = progress / 100.0f; Converter.getVolumeFromPercentage(progress));
}
if (barLeftVolume.getProgress() < 100) {
leftVolume = barLeftVolume.getProgress() / 100.0f;
}
controller.setVolume(leftVolume, rightVolume);
} }
@Override @Override
@ -583,8 +578,10 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O
super.onResume(); super.onResume();
Log.d(TAG, "onResume()"); Log.d(TAG, "onResume()");
StorageUtils.checkStorageAvailability(this); StorageUtils.checkStorageAvailability(this);
if(controller != null) {
controller.init(); controller.init();
} }
}
/** /**
* Called by 'handleStatus()' when the PlaybackService is waiting for * Called by 'handleStatus()' when the PlaybackService is waiting for
@ -597,32 +594,31 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O
protected abstract void clearStatusMsg(); protected abstract void clearStatusMsg();
protected void onPositionObserverUpdate() { protected void onPositionObserverUpdate() {
if (controller != null) { if (controller == null || txtvPosition == null || txtvLength == null) {
return;
}
int currentPosition = controller.getPosition(); int currentPosition = controller.getPosition();
int duration = controller.getDuration(); int duration = controller.getDuration();
Log.d(TAG, "currentPosition " + Converter Log.d(TAG, "currentPosition " + Converter.getDurationStringLong(currentPosition));
.getDurationStringLong(currentPosition)); if (currentPosition == PlaybackService.INVALID_TIME ||
if (currentPosition != PlaybackService.INVALID_TIME duration == PlaybackService.INVALID_TIME) {
&& duration != PlaybackService.INVALID_TIME Log.w(TAG, "Could not react to position observer update because of invalid time");
&& controller.getMedia() != null) { return;
txtvPosition.setText(Converter }
.getDurationStringLong(currentPosition)); txtvPosition.setText(Converter.getDurationStringLong(currentPosition));
if (showTimeLeft) { if (showTimeLeft) {
txtvLength.setText("-" + Converter txtvLength.setText("-" + Converter.getDurationStringLong(duration - currentPosition));
.getDurationStringLong(duration - currentPosition));
} else { } else {
txtvLength.setText(Converter txtvLength.setText(Converter.getDurationStringLong(duration));
.getDurationStringLong(duration));
} }
updateProgressbarPosition(currentPosition, duration); updateProgressbarPosition(currentPosition, duration);
} else {
Log.w(TAG, "Could not react to position observer update because of invalid time");
}
}
} }
private void updateProgressbarPosition(int position, int duration) { private void updateProgressbarPosition(int position, int duration) {
Log.d(TAG, "updateProgressbarPosition(" + position + ", " + duration + ")"); Log.d(TAG, "updateProgressbarPosition(" + position + ", " + duration + ")");
if(sbPosition == null) {
return;
}
float progress = ((float) position) / duration; float progress = ((float) position) / duration;
sbPosition.setProgress((int) (progress * sbPosition.getMax())); sbPosition.setProgress((int) (progress * sbPosition.getMax()));
} }
@ -639,37 +635,52 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O
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);
if (media != null) { if (media != null) {
txtvPosition.setText(Converter.getDurationStringLong((media.getPosition()))); onPositionObserverUpdate();
if (media.getDuration() != 0) {
txtvLength.setText(Converter.getDurationStringLong(media.getDuration()));
float progress = ((float) media.getPosition()) / media.getDuration();
sbPosition.setProgress((int) (progress * sbPosition.getMax()));
if (showTimeLeft) {
int timeLeft = media.getDuration() - media.getPosition();
txtvLength.setText("-" + Converter.getDurationStringLong(timeLeft));
}
}
checkFavorite(); checkFavorite();
if(butPlaybackSpeed != null) { updatePlaybackSpeedButton();
if (controller == null) {
butPlaybackSpeed.setVisibility(View.GONE);
} else {
butPlaybackSpeed.setVisibility(View.VISIBLE);
if (controller.canSetPlaybackSpeed()) {
ViewCompat.setAlpha(butPlaybackSpeed, 1.0f);
} else {
ViewCompat.setAlpha(butPlaybackSpeed, 0.5f);
}
}
updateButPlaybackSpeed();
}
return true; return true;
} else { } else {
return false; return false;
} }
} }
private void updatePlaybackSpeedButton() {
if(butPlaybackSpeed == null) {
return;
}
if (controller == null) {
butPlaybackSpeed.setVisibility(View.GONE);
return;
}
updatePlaybackSpeedButtonText();
ViewCompat.setAlpha(butPlaybackSpeed, controller.canSetPlaybackSpeed() ? 1.0f : 0.5f);
butPlaybackSpeed.setVisibility(View.VISIBLE);
}
private void updatePlaybackSpeedButtonText() {
if(butPlaybackSpeed == null) {
return;
}
if (controller == null) {
butPlaybackSpeed.setVisibility(View.GONE);
return;
}
float speed = 1.0f;
if(controller.canSetPlaybackSpeed()) {
try {
// we can only retrieve the playback speed from the controller/playback service
// once mediaplayer has been initialized
speed = Float.parseFloat(UserPreferences.getPlaybackSpeed());
} catch (NumberFormatException e) {
Log.e(TAG, Log.getStackTraceString(e));
UserPreferences.setPlaybackSpeed(String.valueOf(speed));
}
}
String speedStr = String.format("%.2fx", speed);
butPlaybackSpeed.setText(speedStr);
}
protected void setupGUI() { protected void setupGUI() {
setContentView(getContentViewResourceId()); setContentView(getContentViewResourceId());
sbPosition = (SeekBar) findViewById(R.id.sbPosition); sbPosition = (SeekBar) findViewById(R.id.sbPosition);
@ -762,10 +773,7 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O
} }
if (butRev != null) { if (butRev != null) {
butRev.setOnClickListener(v -> { butRev.setOnClickListener(v -> onRewind());
int curr = controller.getPosition();
controller.seekTo(curr - UserPreferences.getRewindSecs() * 1000);
});
butRev.setOnLongClickListener(new View.OnLongClickListener() { butRev.setOnLongClickListener(new View.OnLongClickListener() {
int choice; int choice;
@ -792,7 +800,9 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O
builder.setNegativeButton(R.string.cancel_label, null); builder.setNegativeButton(R.string.cancel_label, null);
builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> { builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> {
UserPreferences.setPrefRewindSecs(choice); UserPreferences.setPrefRewindSecs(choice);
if(txtvRev != null){
txtvRev.setText(String.valueOf(choice)); txtvRev.setText(String.valueOf(choice));
}
}); });
builder.create().show(); builder.create().show();
return true; return true;
@ -800,13 +810,10 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O
}); });
} }
butPlay.setOnClickListener(controller.newOnPlayButtonClickListener()); butPlay.setOnClickListener(v -> onPlayPause());
if (butFF != null) { if (butFF != null) {
butFF.setOnClickListener(v -> { butFF.setOnClickListener(v -> onFastForward());
int curr = controller.getPosition();
controller.seekTo(curr + UserPreferences.getFastFowardSecs() * 1000);
});
butFF.setOnLongClickListener(new View.OnLongClickListener() { butFF.setOnLongClickListener(new View.OnLongClickListener() {
int choice; int choice;
@ -833,7 +840,9 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O
builder.setNegativeButton(R.string.cancel_label, null); builder.setNegativeButton(R.string.cancel_label, null);
builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> { builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> {
UserPreferences.setPrefFastForwardSecs(choice); UserPreferences.setPrefFastForwardSecs(choice);
if(txtvFF != null) {
txtvFF.setText(String.valueOf(choice)); txtvFF.setText(String.valueOf(choice));
}
}); });
builder.create().show(); builder.create().show();
return true; return true;
@ -842,19 +851,39 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O
} }
if (butSkip != null) { if (butSkip != null) {
butSkip.setOnClickListener(v -> { butSkip.setOnClickListener(v -> sendBroadcast(new Intent(PlaybackService.ACTION_SKIP_CURRENT_EPISODE)));
sendBroadcast(new Intent(PlaybackService.ACTION_SKIP_CURRENT_EPISODE));
});
} }
} }
protected void onRewind() {
if (controller == null) {
return;
}
int curr = controller.getPosition();
controller.seekTo(curr - UserPreferences.getRewindSecs() * 1000);
}
protected void onPlayPause() {
if(controller == null) {
return;
}
controller.playPause();
}
protected void onFastForward() {
if (controller == null) {
return;
}
int curr = controller.getPosition();
controller.seekTo(curr + UserPreferences.getFastFowardSecs() * 1000);
}
protected abstract int getContentViewResourceId(); protected abstract int getContentViewResourceId();
void handleError(int errorCode) { 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 errorDialog.setMessage(MediaPlayerError.getErrorString(this, errorCode));
.setMessage(MediaPlayerError.getErrorString(this, errorCode));
errorDialog.setNeutralButton("OK", errorDialog.setNeutralButton("OK",
(dialog, which) -> { (dialog, which) -> {
dialog.dismiss(); dialog.dismiss();
@ -868,7 +897,9 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O
@Override @Override
public void onProgressChanged (SeekBar seekBar,int progress, boolean fromUser) { public void onProgressChanged (SeekBar seekBar,int progress, boolean fromUser) {
if (controller != null) { if (controller == null || txtvLength == null) {
return;
}
prog = controller.onSeekBarProgressChanged(seekBar, progress, fromUser, txtvPosition); prog = controller.onSeekBarProgressChanged(seekBar, progress, fromUser, txtvPosition);
if (showTimeLeft && prog != 0) { if (showTimeLeft && prog != 0) {
int duration = controller.getDuration(); int duration = controller.getDuration();
@ -876,13 +907,6 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O
txtvLength.setText(length); txtvLength.setText(length);
} }
} }
}
private void updateButPlaybackSpeed() {
if (controller != null && butPlaybackSpeed != null) {
butPlaybackSpeed.setText(UserPreferences.getPlaybackSpeed() + "x");
}
}
@Override @Override
public void onStartTrackingTouch(SeekBar seekBar) { public void onStartTrackingTouch(SeekBar seekBar) {
@ -906,13 +930,17 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O
Observable.fromCallable(() -> DBReader.getFeedItem(feedItem.getId())) Observable.fromCallable(() -> DBReader.getFeedItem(feedItem.getId()))
.subscribeOn(Schedulers.newThread()) .subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(item -> { .subscribe(
item -> {
boolean isFav = item.isTagged(FeedItem.TAG_FAVORITE); boolean isFav = item.isTagged(FeedItem.TAG_FAVORITE);
if (isFavorite != isFav) { if (isFavorite != isFav) {
isFavorite = isFav; isFavorite = isFav;
invalidateOptionsMenu(); invalidateOptionsMenu();
} }
}); }, error -> {
Log.e(TAG, Log.getStackTraceString(error));
}
);
} }
} }
} }

View File

@ -7,8 +7,8 @@ import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.Looper; import android.os.Looper;
import android.support.v4.app.NavUtils; import android.support.v4.app.NavUtils;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -35,7 +35,6 @@ import org.jsoup.nodes.Document;
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 java.util.Map; import java.util.Map;
@ -80,7 +79,7 @@ import rx.schedulers.Schedulers;
* If the feed cannot be downloaded or parsed, an error dialog will be displayed * If the feed cannot be downloaded or parsed, an error dialog will be displayed
* and the activity will finish as soon as the error dialog is closed. * and the activity will finish as soon as the error dialog is closed.
*/ */
public class OnlineFeedViewActivity extends ActionBarActivity { public class OnlineFeedViewActivity extends AppCompatActivity {
private static final String TAG = "OnlineFeedViewActivity"; private static final String TAG = "OnlineFeedViewActivity";
@ -258,7 +257,7 @@ public class OnlineFeedViewActivity extends ActionBarActivity {
private void startFeedDownload(String url, String username, String password) { private void startFeedDownload(String url, String username, String password) {
Log.d(TAG, "Starting feed download"); Log.d(TAG, "Starting feed download");
url = URLChecker.prepareURL(url); url = URLChecker.prepareURL(url);
feed = new Feed(url, new Date(0)); feed = new Feed(url, null);
if (username != null && password != null) { if (username != null && password != null) {
feed.setPreferences(new FeedPreferences(0, false, FeedPreferences.AutoDeleteAction.GLOBAL, username, password)); feed.setPreferences(new FeedPreferences(0, false, FeedPreferences.AutoDeleteAction.GLOBAL, username, password));
} }
@ -329,6 +328,7 @@ public class OnlineFeedViewActivity extends ActionBarActivity {
subscriber.onError(e); subscriber.onError(e);
} }
} catch (Exception e) { } catch (Exception e) {
Log.e(TAG, Log.getStackTraceString(e));
subscriber.onError(e); subscriber.onError(e);
} finally { } finally {
boolean rc = new File(feed.getFile_url()).delete(); boolean rc = new File(feed.getFile_url()).delete();
@ -409,18 +409,25 @@ public class OnlineFeedViewActivity extends ActionBarActivity {
description.setText(feed.getDescription()); description.setText(feed.getDescription());
subscribeButton.setOnClickListener(v -> { subscribeButton.setOnClickListener(v -> {
try { if(feed != null && feedInFeedlist(feed)) {
Feed f = new Feed(selectedDownloadUrl, new Date(0), feed.getTitle()); Intent intent = new Intent(OnlineFeedViewActivity.this, MainActivity.class);
// feed.getId() is always 0, we have to retrieve the id from the feed list from
// the database
intent.putExtra(MainActivity.EXTRA_FEED_ID, getFeedId(feed));
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
} else {
Feed f = new Feed(selectedDownloadUrl, null, feed.getTitle());
f.setPreferences(feed.getPreferences()); f.setPreferences(feed.getPreferences());
this.feed = f; this.feed = f;
try {
DownloadRequester.getInstance().downloadFeed(this, f); DownloadRequester.getInstance().downloadFeed(this, f);
} catch (DownloadRequestException e) { } catch (DownloadRequestException e) {
e.printStackTrace(); Log.e(TAG, Log.getStackTraceString(e));
DownloadRequestErrorDialogCreator.newRequestErrorDialog(OnlineFeedViewActivity.this, DownloadRequestErrorDialogCreator.newRequestErrorDialog(this, e.getMessage());
e.getMessage());
} }
setSubscribeButtonState(feed); setSubscribeButtonState(feed);
}
}); });
if (alternateFeedUrls.isEmpty()) { if (alternateFeedUrls.isEmpty()) {
@ -463,8 +470,8 @@ public class OnlineFeedViewActivity extends ActionBarActivity {
subscribeButton.setEnabled(false); subscribeButton.setEnabled(false);
subscribeButton.setText(R.string.downloading_label); subscribeButton.setText(R.string.downloading_label);
} else if (feedInFeedlist(feed)) { } else if (feedInFeedlist(feed)) {
subscribeButton.setEnabled(false); subscribeButton.setEnabled(true);
subscribeButton.setText(R.string.subscribed_label); subscribeButton.setText(R.string.open_podcast);
} else { } else {
subscribeButton.setEnabled(true); subscribeButton.setEnabled(true);
subscribeButton.setText(R.string.subscribe_label); subscribeButton.setText(R.string.subscribe_label);
@ -484,6 +491,18 @@ public class OnlineFeedViewActivity extends ActionBarActivity {
return false; return false;
} }
private long getFeedId(Feed feed) {
if (feeds == null || feed == null) {
return 0;
}
for (Feed f : feeds) {
if (f.getIdentifyingValue().equals(feed.getIdentifyingValue())) {
return f.getId();
}
}
return 0;
}
private void showErrorDialog(String errorMsg) { private void showErrorDialog(String errorMsg) {
assert(Looper.myLooper() == Looper.getMainLooper()); // run on UI thread assert(Looper.myLooper() == Looper.getMainLooper()); // run on UI thread
if (!isFinishing() && !isPaused) { if (!isFinishing() && !isPaused) {

View File

@ -2,28 +2,27 @@ package de.danoeh.antennapod.activity;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.view.MenuItemCompat; import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.ActionBarActivity;
import android.util.SparseBooleanArray; import android.util.SparseBooleanArray;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
import android.widget.ListView; import android.widget.ListView;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.opml.OpmlElement;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.opml.OpmlElement;
import de.danoeh.antennapod.core.preferences.UserPreferences;
/** /**
* Displays the feeds that the OPML-Importer has read and lets the user choose * Displays the feeds that the OPML-Importer has read and lets the user choose
* which feeds he wants to import. * which feeds he wants to import.
*/ */
public class OpmlFeedChooserActivity extends ActionBarActivity { public class OpmlFeedChooserActivity extends AppCompatActivity {
private static final String TAG = "OpmlFeedChooserActivity"; private static final String TAG = "OpmlFeedChooserActivity";
public static final String EXTRA_SELECTED_ITEMS = "de.danoeh.antennapod.selectedItems"; public static final String EXTRA_SELECTED_ITEMS = "de.danoeh.antennapod.selectedItems";
@ -33,6 +32,9 @@ public class OpmlFeedChooserActivity extends ActionBarActivity {
private ListView feedlist; private ListView feedlist;
private ArrayAdapter<String> listAdapter; private ArrayAdapter<String> listAdapter;
private MenuItem selectAll;
private MenuItem deselectAll;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
setTheme(UserPreferences.getTheme()); setTheme(UserPreferences.getTheme());
@ -44,24 +46,34 @@ public class OpmlFeedChooserActivity extends ActionBarActivity {
feedlist = (ListView) findViewById(R.id.feedlist); feedlist = (ListView) findViewById(R.id.feedlist);
feedlist.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); feedlist.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listAdapter = new ArrayAdapter<String>(this, listAdapter = new ArrayAdapter<>(this,
android.R.layout.simple_list_item_multiple_choice, android.R.layout.simple_list_item_multiple_choice,
getTitleList()); getTitleList());
feedlist.setAdapter(listAdapter); feedlist.setAdapter(listAdapter);
feedlist.setOnItemClickListener((parent, view, position, id) -> {
butCancel.setOnClickListener(new OnClickListener() { SparseBooleanArray checked = feedlist.getCheckedItemPositions();
@Override int checkedCount = 0;
public void onClick(View v) { for (int i = 0; i < checked.size(); i++) {
setResult(RESULT_CANCELED); if (checked.valueAt(i)) {
finish(); checkedCount++;
}
}
if(checkedCount == listAdapter.getCount()) {
selectAll.setVisible(false);
deselectAll.setVisible(true);
} else {
deselectAll.setVisible(false);
selectAll.setVisible(true);
} }
}); });
butConfirm.setOnClickListener(new OnClickListener() { butCancel.setOnClickListener(v -> {
setResult(RESULT_CANCELED);
finish();
});
@Override butConfirm.setOnClickListener(v -> {
public void onClick(View v) {
Intent intent = new Intent(); Intent intent = new Intent();
SparseBooleanArray checked = feedlist.getCheckedItemPositions(); SparseBooleanArray checked = feedlist.getCheckedItemPositions();
@ -82,7 +94,6 @@ public class OpmlFeedChooserActivity extends ActionBarActivity {
intent.putExtra(EXTRA_SELECTED_ITEMS, selection); intent.putExtra(EXTRA_SELECTED_ITEMS, selection);
setResult(RESULT_OK, intent); setResult(RESULT_OK, intent);
finish(); finish();
}
}); });
} }
@ -93,7 +104,6 @@ public class OpmlFeedChooserActivity extends ActionBarActivity {
for (OpmlElement element : OpmlImportHolder.getReadElements()) { for (OpmlElement element : OpmlImportHolder.getReadElements()) {
result.add(element.getText()); result.add(element.getText());
} }
} }
return result; return result;
} }
@ -101,13 +111,11 @@ public class OpmlFeedChooserActivity extends ActionBarActivity {
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu); super.onCreateOptionsMenu(menu);
MenuItemCompat.setShowAsAction(menu.add(Menu.NONE, R.id.select_all_item, Menu.NONE, MenuInflater inflater = getMenuInflater();
R.string.select_all_label), inflater.inflate(R.menu.opml_selection_options, menu);
MenuItemCompat.SHOW_AS_ACTION_IF_ROOM); selectAll = menu.findItem(R.id.select_all_item);
deselectAll = menu.findItem(R.id.deselect_all_item);
MenuItemCompat.setShowAsAction(menu.add(Menu.NONE, R.id.deselect_all_item, Menu.NONE, deselectAll.setVisible(false);
R.string.deselect_all_label),
MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
return true; return true;
} }
@ -115,10 +123,14 @@ public class OpmlFeedChooserActivity extends ActionBarActivity {
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.select_all_item: case R.id.select_all_item:
selectAll.setVisible(false);
selectAllItems(true); selectAllItems(true);
deselectAll.setVisible(true);
return true; return true;
case R.id.deselect_all_item: case R.id.deselect_all_item:
deselectAll.setVisible(false);
selectAllItems(false); selectAllItems(false);
selectAll.setVisible(true);
return true; return true;
default: default:
return false; return false;

View File

@ -1,40 +1,53 @@
package de.danoeh.antennapod.activity; package de.danoeh.antennapod.activity;
import android.content.Intent; import android.content.Intent;
import android.support.v7.app.ActionBarActivity; import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Environment;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log; import android.util.Log;
import de.danoeh.antennapod.BuildConfig;
import com.afollestad.materialdialogs.MaterialDialog;
import org.apache.commons.lang3.ArrayUtils;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.asynctask.OpmlFeedQueuer; import de.danoeh.antennapod.asynctask.OpmlFeedQueuer;
import de.danoeh.antennapod.asynctask.OpmlImportWorker; import de.danoeh.antennapod.asynctask.OpmlImportWorker;
import de.danoeh.antennapod.core.opml.OpmlElement; import de.danoeh.antennapod.core.opml.OpmlElement;
import de.danoeh.antennapod.core.util.LangUtils;
import java.io.Reader;
import java.util.ArrayList;
/** /**
* Base activity for Opml Import - e.g. with code what to do afterwards * Base activity for Opml Import - e.g. with code what to do afterwards
* */ * */
public class OpmlImportBaseActivity extends ActionBarActivity { public class OpmlImportBaseActivity extends AppCompatActivity {
private static final String TAG = "OpmlImportBaseActivity"; private static final String TAG = "OpmlImportBaseActivity";
private OpmlImportWorker importWorker; private OpmlImportWorker importWorker;
private static final int PERMISSION_REQUEST_READ_EXTERNAL_STORAGE = 5;
@Nullable private Uri uri;
/** /**
* Handles the choices made by the user in the OpmlFeedChooserActivity and * Handles the choices made by the user in the OpmlFeedChooserActivity and
* starts the OpmlFeedQueuer if necessary. * starts the OpmlFeedQueuer if necessary.
*/ */
@Override @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (BuildConfig.DEBUG)
Log.d(TAG, "Received result"); Log.d(TAG, "Received result");
if (resultCode == RESULT_CANCELED) { if (resultCode == RESULT_CANCELED) {
if (BuildConfig.DEBUG)
Log.d(TAG, "Activity was cancelled"); Log.d(TAG, "Activity was cancelled");
if (finishWhenCanceled()) if (finishWhenCanceled()) {
finish(); finish();
}
} else { } else {
int[] selected = data int[] selected = data.getIntArrayExtra(OpmlFeedChooserActivity.EXTRA_SELECTED_ITEMS);
.getIntArrayExtra(OpmlFeedChooserActivity.EXTRA_SELECTED_ITEMS);
if (selected != null && selected.length > 0) { if (selected != null && selected.length > 0) {
OpmlFeedQueuer queuer = new OpmlFeedQueuer(this, selected) { OpmlFeedQueuer queuer = new OpmlFeedQueuer(this, selected) {
@ -50,35 +63,83 @@ public class OpmlImportBaseActivity extends ActionBarActivity {
}; };
queuer.executeAsync(); queuer.executeAsync();
} else { } else {
if (BuildConfig.DEBUG)
Log.d(TAG, "No items were selected"); Log.d(TAG, "No items were selected");
} }
} }
} }
/** Starts the import process. */ protected void importUri(@Nullable Uri uri) {
protected void startImport(Reader reader) { if(uri == null) {
new MaterialDialog.Builder(this)
.content(R.string.opml_import_error_no_file)
.positiveText(android.R.string.ok)
.show();
return;
}
this.uri = uri;
if(uri.toString().contains(Environment.getExternalStorageDirectory().toString())) {
int permission = ActivityCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
requestPermission();
return;
}
}
startImport();
}
if (reader != null) { private void requestPermission() {
importWorker = new OpmlImportWorker(this, reader) { String[] permissions = { android.Manifest.permission.READ_EXTERNAL_STORAGE };
ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST_READ_EXTERNAL_STORAGE);
}
@Override
public void onRequestPermissionsResult(int requestCode,
String[] permissions,
int[] grantResults) {
if (requestCode != PERMISSION_REQUEST_READ_EXTERNAL_STORAGE) {
return;
}
if (grantResults.length > 0 && ArrayUtils.contains(grantResults, PackageManager.PERMISSION_GRANTED)) {
startImport();
} else {
new MaterialDialog.Builder(this)
.content(R.string.opml_import_ask_read_permission)
.positiveText(android.R.string.ok)
.negativeText(R.string.cancel_label)
.onPositive((dialog, which) -> requestPermission())
.onNegative((dialog, which) -> finish())
.show();
}
}
/** Starts the import process. */
protected void startImport() {
try {
Reader mReader = new InputStreamReader(getContentResolver().openInputStream(uri), LangUtils.UTF_8);
importWorker = new OpmlImportWorker(this, mReader) {
@Override @Override
protected void onPostExecute(ArrayList<OpmlElement> result) { protected void onPostExecute(ArrayList<OpmlElement> result) {
super.onPostExecute(result); super.onPostExecute(result);
if (result != null) { if (result != null) {
if (BuildConfig.DEBUG)
Log.d(TAG, "Parsing was successful"); Log.d(TAG, "Parsing was successful");
OpmlImportHolder.setReadElements(result); OpmlImportHolder.setReadElements(result);
startActivityForResult(new Intent( startActivityForResult(new Intent(
OpmlImportBaseActivity.this, OpmlImportBaseActivity.this,
OpmlFeedChooserActivity.class), 0); OpmlFeedChooserActivity.class), 0);
} else { } else {
if (BuildConfig.DEBUG)
Log.d(TAG, "Parser error occurred"); Log.d(TAG, "Parser error occurred");
} }
} }
}; };
importWorker.executeAsync(); importWorker.executeAsync();
} catch (Exception e) {
Log.d(TAG, Log.getStackTraceString(e));
String message = getString(R.string.opml_reader_error);
new MaterialDialog.Builder(this)
.content(message + " " + e.getMessage())
.positiveText(android.R.string.ok)
.show();
} }
} }

View File

@ -2,25 +2,14 @@ package de.danoeh.antennapod.activity;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.util.LangUtils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
/** Lets the user start the OPML-import process. */ /** Lets the user start the OPML-import process. */
public class OpmlImportFromIntentActivity extends OpmlImportBaseActivity { public class OpmlImportFromIntentActivity extends OpmlImportBaseActivity {
private static final String TAG = "OpmlImportFromIntentAct"; private static final String TAG = "OpmlImportFromIntentAct";
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
setTheme(UserPreferences.getTheme()); setTheme(UserPreferences.getTheme());
@ -28,15 +17,8 @@ public class OpmlImportFromIntentActivity extends OpmlImportBaseActivity {
getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true);
try {
Uri uri = getIntent().getData(); Uri uri = getIntent().getData();
importUri(uri);
Reader mReader = new InputStreamReader(getContentResolver().openInputStream(uri), LangUtils.UTF_8);
startImport(mReader);
} catch (Exception e) {
new AlertDialog.Builder(this).setMessage("Cannot open XML - Reason: " + e.getMessage()).show();
}
} }
@Override @Override

View File

@ -11,16 +11,9 @@ import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.TextView; import android.widget.TextView;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.io.Reader;
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.IntentUtils; import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.core.util.LangUtils;
import de.danoeh.antennapod.core.util.StorageUtils; import de.danoeh.antennapod.core.util.StorageUtils;
/** /**
@ -60,7 +53,7 @@ public class OpmlImportFromPathActivity extends OpmlImportBaseActivity {
intentPickAction = new Intent(Intent.ACTION_PICK); intentPickAction = new Intent(Intent.ACTION_PICK);
intentPickAction.setData(Uri.parse("file://")); intentPickAction.setData(Uri.parse("file://"));
if(false == IntentUtils.isCallable(getApplicationContext(), intentPickAction)) { if(!IntentUtils.isCallable(getApplicationContext(), intentPickAction)) {
intentPickAction.setData(null); intentPickAction.setData(null);
if(false == IntentUtils.isCallable(getApplicationContext(), intentPickAction)) { if(false == IntentUtils.isCallable(getApplicationContext(), intentPickAction)) {
txtvHeaderExplanation1.setVisibility(View.GONE); txtvHeaderExplanation1.setVisibility(View.GONE);
@ -77,7 +70,7 @@ public class OpmlImportFromPathActivity extends OpmlImportBaseActivity {
intentGetContentAction = new Intent(Intent.ACTION_GET_CONTENT); intentGetContentAction = new Intent(Intent.ACTION_GET_CONTENT);
intentGetContentAction.addCategory(Intent.CATEGORY_OPENABLE); intentGetContentAction.addCategory(Intent.CATEGORY_OPENABLE);
intentGetContentAction.setType("*/*"); intentGetContentAction.setType("*/*");
if(false == IntentUtils.isCallable(getApplicationContext(), intentGetContentAction)) { if(!IntentUtils.isCallable(getApplicationContext(), intentGetContentAction)) {
txtvHeaderExplanation2.setVisibility(View.GONE); txtvHeaderExplanation2.setVisibility(View.GONE);
txtvExplanation2.setVisibility(View.GONE); txtvExplanation2.setVisibility(View.GONE);
findViewById(R.id.divider2).setVisibility(View.GONE); findViewById(R.id.divider2).setVisibility(View.GONE);
@ -114,19 +107,6 @@ public class OpmlImportFromPathActivity extends OpmlImportBaseActivity {
} }
} }
private void startImport(File file) {
Reader mReader = null;
try {
mReader = new InputStreamReader(new FileInputStream(file),
LangUtils.UTF_8);
Log.d(TAG, "Parsing " + file.toString());
startImport(mReader);
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found which really should be there");
// this should never happen as it is a file we have just chosen
}
}
/* /*
* Creates an implicit intent to launch a file manager which lets * Creates an implicit intent to launch a file manager which lets
* the user choose a specific OPML-file to import from. * the user choose a specific OPML-file to import from.
@ -155,13 +135,7 @@ public class OpmlImportFromPathActivity extends OpmlImportBaseActivity {
super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == CHOOSE_OPML_FILE) { if (resultCode == RESULT_OK && requestCode == CHOOSE_OPML_FILE) {
Uri uri = data.getData(); Uri uri = data.getData();
importUri(uri);
try {
Reader mReader = new InputStreamReader(getContentResolver().openInputStream(uri), LangUtils.UTF_8);
startImport(mReader);
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found");
}
} }
} }

View File

@ -8,7 +8,7 @@ import android.os.Bundle;
import android.preference.Preference; import android.preference.Preference;
import android.preference.PreferenceFragment; import android.preference.PreferenceFragment;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity; import android.support.v7.app.AppCompatActivity;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -24,7 +24,7 @@ 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 ActionBarActivity { public class PreferenceActivity extends AppCompatActivity {
private PreferenceController preferenceController; private PreferenceController preferenceController;
private MainFragment prefFragment; private MainFragment prefFragment;
@ -49,7 +49,7 @@ public class PreferenceActivity extends ActionBarActivity {
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
// reference it needs // reference it needs
instance = new WeakReference<PreferenceActivity>(this); instance = new WeakReference<>(this);
setTheme(UserPreferences.getTheme()); setTheme(UserPreferences.getTheme());
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);

View File

@ -0,0 +1,107 @@
package de.danoeh.antennapod.activity;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.adapter.StatisticsListAdapter;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.util.Converter;
import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
/**
* Displays the 'statistics' screen
*/
public class StatisticsActivity extends AppCompatActivity
implements AdapterView.OnItemClickListener {
private static final String TAG = StatisticsActivity.class.getSimpleName();
private Subscription subscription;
private TextView totalTimeTextView;
private ListView feedStatisticsList;
private ProgressBar progressBar;
private StatisticsListAdapter listAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(UserPreferences.getTheme());
super.onCreate(savedInstanceState);
getSupportActionBar().setDisplayShowHomeEnabled(true);
setContentView(R.layout.statistics_activity);
totalTimeTextView = (TextView) findViewById(R.id.total_time);
feedStatisticsList = (ListView) findViewById(R.id.statistics_list);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
listAdapter = new StatisticsListAdapter(this);
feedStatisticsList.setAdapter(listAdapter);
feedStatisticsList.setOnItemClickListener(this);
}
@Override
public void onResume() {
super.onResume();
progressBar.setVisibility(View.VISIBLE);
totalTimeTextView.setVisibility(View.GONE);
feedStatisticsList.setVisibility(View.GONE);
loadStats();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
private void loadStats() {
if(subscription != null) {
subscription.unsubscribe();
}
subscription = Observable.fromCallable(() -> DBReader.getStatistics())
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
if (result != null) {
totalTimeTextView.setText(Converter
.shortLocalizedDuration(this, result.totalTime));
listAdapter.update(result.feedTime);
progressBar.setVisibility(View.GONE);
totalTimeTextView.setVisibility(View.VISIBLE);
feedStatisticsList.setVisibility(View.VISIBLE);
}
}, error -> {
Log.e(TAG, Log.getStackTraceString(error));
});
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
DBReader.StatisticsItem stats = listAdapter.getItem(position);
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle(stats.feed.getTitle());
dialog.setMessage(getString(R.string.statistics_details_dialog,
stats.episodesStarted,
stats.episodes,
Converter.shortLocalizedDuration(this, stats.timePlayed),
Converter.shortLocalizedDuration(this, stats.time)));
dialog.setPositiveButton(android.R.string.ok, null);
dialog.show();
}
}

View File

@ -1,38 +1,97 @@
package de.danoeh.antennapod.activity; package de.danoeh.antennapod.activity;
import android.Manifest;
import android.app.Activity;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.app.ActionBarActivity; import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.text.Html;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.widget.Button;
import com.afollestad.materialdialogs.MaterialDialog;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
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.Converter;
import de.danoeh.antennapod.core.util.StorageUtils; import de.danoeh.antennapod.core.util.StorageUtils;
/** Is show if there is now external storage available. */ /** Is show if there is now external storage available. */
public class StorageErrorActivity extends ActionBarActivity { public class StorageErrorActivity extends AppCompatActivity {
private static final String TAG = "StorageErrorActivity"; private static final String TAG = "StorageErrorActivity";
private static final String[] EXTERNAL_STORAGE_PERMISSIONS = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE };
private static final int PERMISSION_REQUEST_EXTERNAL_STORAGE = 42;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
setTheme(UserPreferences.getTheme()); setTheme(UserPreferences.getTheme());
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.storage_error); setContentView(R.layout.storage_error);
Button btnChooseDataFolder = (Button) findViewById(R.id.btnChooseDataFolder);
btnChooseDataFolder.setOnClickListener(v -> {
if (Build.VERSION_CODES.KITKAT <= Build.VERSION.SDK_INT &&
Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) {
showChooseDataFolderDialog();
} else {
openDirectoryChooser();
}
});
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M) {
int readPermission = ActivityCompat.checkSelfPermission(this,
Manifest.permission.READ_EXTERNAL_STORAGE);
int writePermission = ActivityCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (readPermission != PackageManager.PERMISSION_GRANTED ||
writePermission != PackageManager.PERMISSION_GRANTED) {
requestPermission();
}
}
}
private void requestPermission() {
ActivityCompat.requestPermissions(this, EXTERNAL_STORAGE_PERMISSIONS,
PERMISSION_REQUEST_EXTERNAL_STORAGE);
}
private void openDirectoryChooser() {
Intent intent = new Intent(this, DirectoryChooserActivity.class);
startActivityForResult(intent, DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED);
} }
@Override @Override
protected void onPause() { public void onRequestPermissionsResult(int requestCode,
super.onPause(); String[] permissions,
try { int[] grantResults) {
unregisterReceiver(mediaUpdate); if (requestCode != PERMISSION_REQUEST_EXTERNAL_STORAGE || grantResults.length != 2) {
} catch (IllegalArgumentException e) { return;
}
if (grantResults[0] != PackageManager.PERMISSION_GRANTED ||
grantResults[1] != PackageManager.PERMISSION_GRANTED) {
new MaterialDialog.Builder(this)
.content(R.string.choose_data_directory_permission_rationale)
.positiveText(android.R.string.ok)
.onPositive((dialog, which) -> requestPermission())
.onNegative((dialog, which) -> finish())
.show();
} }
} }
@ -42,8 +101,112 @@ public class StorageErrorActivity extends ActionBarActivity {
if (StorageUtils.storageAvailable()) { if (StorageUtils.storageAvailable()) {
leaveErrorState(); leaveErrorState();
} else { } else {
registerReceiver(mediaUpdate, new IntentFilter( registerReceiver(mediaUpdate, new IntentFilter(Intent.ACTION_MEDIA_MOUNTED));
Intent.ACTION_MEDIA_MOUNTED)); }
}
@Override
protected void onPause() {
super.onPause();
try {
unregisterReceiver(mediaUpdate);
} catch (IllegalArgumentException e) {
Log.e(TAG, Log.getStackTraceString(e));
}
}
// see PreferenceController.showChooseDataFolderDialog()
private void showChooseDataFolderDialog() {
File dataFolder = UserPreferences.getDataFolder(null);
if(dataFolder == null) {
new MaterialDialog.Builder(this)
.title(R.string.error_label)
.content(R.string.external_storage_error_msg)
.neutralText(android.R.string.ok)
.show();
return;
}
String dataFolderPath = dataFolder.getAbsolutePath();
int selectedIndex = -1;
File[] mediaDirs = ContextCompat.getExternalFilesDirs(this, null);
List<String> folders = new ArrayList<>(mediaDirs.length);
List<CharSequence> choices = new ArrayList<>(mediaDirs.length);
for(int i=0; i < mediaDirs.length; i++) {
if(mediaDirs[i] == null) {
continue;
}
String path = mediaDirs[i].getAbsolutePath();
folders.add(path);
if(dataFolderPath.equals(path)) {
selectedIndex = i;
}
int index = path.indexOf("Android");
String choice;
if(index >= 0) {
choice = path.substring(0, index);
} else {
choice = path;
}
long bytes = StorageUtils.getFreeSpaceAvailable(path);
String freeSpace = String.format(getString(R.string.free_space_label),
Converter.byteToString(bytes));
choices.add(Html.fromHtml("<html><small>" + choice + " [" + freeSpace + "]"
+ "</small></html>"));
}
if(choices.size() == 0) {
new MaterialDialog.Builder(this)
.title(R.string.error_label)
.content(R.string.external_storage_error_msg)
.neutralText(android.R.string.ok)
.show();
return;
}
MaterialDialog dialog = new MaterialDialog.Builder(this)
.title(R.string.choose_data_directory)
.content(R.string.choose_data_directory_message)
.items(choices.toArray(new CharSequence[choices.size()]))
.itemsCallbackSingleChoice(selectedIndex, (dialog1, itemView, which, text) -> {
String folder = folders.get(which);
UserPreferences.setDataFolder(folder);
leaveErrorState();
return true;
})
.negativeText(R.string.cancel_label)
.cancelable(true)
.build();
dialog.show();
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK &&
requestCode == DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED) {
String dir = data.getStringExtra(DirectoryChooserActivity.RESULT_SELECTED_DIR);
File path;
if (dir != null) {
path = new File(dir);
} else {
path = getExternalFilesDir(null);
}
String message = null;
if(!path.exists()) {
message = String.format(getString(R.string.folder_does_not_exist_error), dir);
} else if(!path.canRead()) {
message = String.format(getString(R.string.folder_not_readable_error), dir);
} else if(!path.canWrite()) {
message = String.format(getString(R.string.folder_not_writable_error), dir);
}
if(message == null) {
Log.d(TAG, "Setting data folder: " + dir);
UserPreferences.setDataFolder(dir);
leaveErrorState();
} else {
AlertDialog.Builder ab = new AlertDialog.Builder(this);
ab.setMessage(message);
ab.setPositiveButton(android.R.string.ok, null);
ab.show();
}
} }
} }
@ -58,13 +221,10 @@ public class StorageErrorActivity extends ActionBarActivity {
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
if (TextUtils.equals(intent.getAction(), Intent.ACTION_MEDIA_MOUNTED)) { if (TextUtils.equals(intent.getAction(), Intent.ACTION_MEDIA_MOUNTED)) {
if (intent.getBooleanExtra("read-only", true)) { if (intent.getBooleanExtra("read-only", true)) {
if (BuildConfig.DEBUG)
Log.d(TAG, "Media was mounted; Finishing activity"); Log.d(TAG, "Media was mounted; Finishing activity");
leaveErrorState(); leaveErrorState();
} else { } else {
if (BuildConfig.DEBUG) Log.d(TAG, "Media seemed to have been mounted read only");
Log.d(TAG,
"Media seemed to have been mounted read only");
} }
} }
} }

View File

@ -202,6 +202,24 @@ public class VideoplayerActivity extends MediaplayerActivity {
videoControlsShowing = !videoControlsShowing; videoControlsShowing = !videoControlsShowing;
} }
@Override
protected void onRewind() {
super.onRewind();
setupVideoControlsToggler();
}
@Override
protected void onPlayPause() {
super.onPlayPause();
setupVideoControlsToggler();
}
@Override
protected void onFastForward() {
super.onFastForward();
setupVideoControlsToggler();
}
private final SurfaceHolder.Callback surfaceHolderCallback = new SurfaceHolder.Callback() { private final SurfaceHolder.Callback surfaceHolderCallback = new SurfaceHolder.Callback() {
@Override @Override
@ -312,7 +330,7 @@ public class VideoplayerActivity extends MediaplayerActivity {
private static class VideoControlsHider extends Handler { private static class VideoControlsHider extends Handler {
private static final int DELAY = 5000; private static final int DELAY = 2500;
private WeakReference<VideoplayerActivity> activity; private WeakReference<VideoplayerActivity> activity;

View File

@ -5,7 +5,6 @@ import android.content.Intent;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.NavUtils;
import android.support.v7.app.ActionBarActivity; import android.support.v7.app.ActionBarActivity;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -42,7 +41,7 @@ import de.danoeh.antennapod.core.service.GpodnetSyncService;
* Step 3: Choose from a list of actions * Step 3: Choose from a list of actions
*/ */
public class GpodnetAuthenticationActivity extends ActionBarActivity { public class GpodnetAuthenticationActivity extends ActionBarActivity {
private static final String TAG = "GpodnetAuthenticationActivity"; private static final String TAG = "GpodnetAuthActivity";
private static final String CURRENT_STEP = "current_step"; private static final String CURRENT_STEP = "current_step";
@ -177,7 +176,7 @@ public class GpodnetAuthenticationActivity extends ActionBarActivity {
// load device list // load device list
final AtomicReference<List<GpodnetDevice>> devices = new AtomicReference<List<GpodnetDevice>>(); final AtomicReference<List<GpodnetDevice>> devices = new AtomicReference<>();
new AsyncTask<GpodnetService, Void, List<GpodnetDevice>>() { new AsyncTask<GpodnetService, Void, List<GpodnetDevice>>() {
private volatile Exception exception; private volatile Exception exception;
@ -194,11 +193,11 @@ public class GpodnetAuthenticationActivity extends ActionBarActivity {
protected void onPostExecute(List<GpodnetDevice> gpodnetDevices) { protected void onPostExecute(List<GpodnetDevice> gpodnetDevices) {
super.onPostExecute(gpodnetDevices); super.onPostExecute(gpodnetDevices);
if (gpodnetDevices != null) { if (gpodnetDevices != null) {
List<String> deviceNames = new ArrayList<String>(); List<String> deviceNames = new ArrayList<>();
for (GpodnetDevice device : gpodnetDevices) { for (GpodnetDevice device : gpodnetDevices) {
deviceNames.add(device.getCaption()); deviceNames.add(device.getCaption());
} }
spinnerDevices.setAdapter(new ArrayAdapter<String>(GpodnetAuthenticationActivity.this, spinnerDevices.setAdapter(new ArrayAdapter<>(GpodnetAuthenticationActivity.this,
android.R.layout.simple_spinner_dropdown_item, deviceNames)); android.R.layout.simple_spinner_dropdown_item, deviceNames));
spinnerDevices.setEnabled(true); spinnerDevices.setEnabled(true);
if (!deviceNames.isEmpty()) { if (!deviceNames.isEmpty()) {
@ -274,15 +273,12 @@ public class GpodnetAuthenticationActivity extends ActionBarActivity {
}); });
deviceID.setText(generateDeviceID()); deviceID.setText(generateDeviceID());
chooseDevice.setOnClickListener(new View.OnClickListener() { chooseDevice.setOnClickListener(v -> {
@Override
public void onClick(View v) {
final int position = spinnerDevices.getSelectedItemPosition(); final int position = spinnerDevices.getSelectedItemPosition();
if (position != AdapterView.INVALID_POSITION) { if (position != AdapterView.INVALID_POSITION) {
selectedDevice = devices.get().get(position); selectedDevice = devices.get().get(position);
advance(); advance();
} }
}
}); });
} }
@ -325,20 +321,14 @@ public class GpodnetAuthenticationActivity extends ActionBarActivity {
final Button sync = (Button) view.findViewById(R.id.butSyncNow); final Button sync = (Button) view.findViewById(R.id.butSyncNow);
final Button back = (Button) view.findViewById(R.id.butGoMainscreen); final Button back = (Button) view.findViewById(R.id.butGoMainscreen);
sync.setOnClickListener(new View.OnClickListener() { sync.setOnClickListener(v -> {
@Override
public void onClick(View v) {
GpodnetSyncService.sendSyncIntent(GpodnetAuthenticationActivity.this); GpodnetSyncService.sendSyncIntent(GpodnetAuthenticationActivity.this);
finish(); finish();
}
}); });
back.setOnClickListener(new View.OnClickListener() { back.setOnClickListener(v -> {
@Override
public void onClick(View v) {
Intent intent = new Intent(GpodnetAuthenticationActivity.this, MainActivity.class); Intent intent = new Intent(GpodnetAuthenticationActivity.this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent); startActivity(intent);
}
}); });
} }

View File

@ -4,5 +4,5 @@ import de.danoeh.antennapod.core.feed.FeedItem;
public interface ActionButtonCallback { public 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. */
abstract void onActionButtonPressed(FeedItem item); void onActionButtonPressed(FeedItem item);
} }

View File

@ -47,9 +47,10 @@ public class AdapterUtils {
- media.getPosition())); - media.getPosition()));
} }
} else if (!media.isDownloaded()) { } else if (!media.isDownloaded()) {
Log.d(TAG, "size: " + media.getSize());
if (media.getSize() > 0) { if (media.getSize() > 0) {
txtvPos.setText(Converter.byteToString(media.getSize())); txtvPos.setText(Converter.byteToString(media.getSize()));
} else if(false == media.checkedOnSizeButUnknown()) { } else if(NetworkUtils.isDownloadAllowed() && !media.checkedOnSizeButUnknown()) {
txtvPos.setText("{fa-spinner}"); txtvPos.setText("{fa-spinner}");
Iconify.addIcons(txtvPos); Iconify.addIcons(txtvPos);
NetworkUtils.getFeedMediaSizeObservable(media) NetworkUtils.getFeedMediaSizeObservable(media)

View File

@ -2,6 +2,7 @@ package de.danoeh.antennapod.adapter;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper; import android.support.v7.widget.helper.ItemTouchHelper;
import android.util.Log; import android.util.Log;
@ -70,11 +71,11 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
this.showOnlyNewEpisodes = showOnlyNewEpisodes; this.showOnlyNewEpisodes = showOnlyNewEpisodes;
if(UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) { if(UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) {
playingBackGroundColor = mainActivity.getResources().getColor(R.color.highlight_dark); playingBackGroundColor = ContextCompat.getColor(mainActivity, R.color.highlight_dark);
} else { } else {
playingBackGroundColor = mainActivity.getResources().getColor(R.color.highlight_light); playingBackGroundColor = ContextCompat.getColor(mainActivity, R.color.highlight_light);
} }
normalBackGroundColor = mainActivity.getResources().getColor(android.R.color.transparent); normalBackGroundColor = ContextCompat.getColor(mainActivity, android.R.color.transparent);
} }
@Override @Override
@ -120,7 +121,7 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
holder.title.setText(item.getTitle()); holder.title.setText(item.getTitle());
String pubDateStr = DateUtils.formatAbbrev(mainActivityRef.get(), item.getPubDate()); String pubDateStr = DateUtils.formatAbbrev(mainActivityRef.get(), item.getPubDate());
holder.pubDate.setText(pubDateStr); holder.pubDate.setText(pubDateStr);
if (showOnlyNewEpisodes || false == item.isNew()) { if (showOnlyNewEpisodes || !item.isNew()) {
holder.statusUnread.setVisibility(View.INVISIBLE); holder.statusUnread.setVisibility(View.INVISIBLE);
} else { } else {
holder.statusUnread.setVisibility(View.VISIBLE); holder.statusUnread.setVisibility(View.VISIBLE);
@ -134,7 +135,7 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
holder.txtvDuration.setText(Converter.getDurationStringLong(media.getDuration())); holder.txtvDuration.setText(Converter.getDurationStringLong(media.getDuration()));
} else if (media.getSize() > 0) { } else if (media.getSize() > 0) {
holder.txtvDuration.setText(Converter.byteToString(media.getSize())); holder.txtvDuration.setText(Converter.byteToString(media.getSize()));
} else if(false == media.checkedOnSizeButUnknown()) { } else if(NetworkUtils.isDownloadAllowed() && !media.checkedOnSizeButUnknown()) {
holder.txtvDuration.setText("{fa-spinner}"); holder.txtvDuration.setText("{fa-spinner}");
Iconify.addIcons(holder.txtvDuration); Iconify.addIcons(holder.txtvDuration);
NetworkUtils.getFeedMediaSizeObservable(media) NetworkUtils.getFeedMediaSizeObservable(media)
@ -201,7 +202,8 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
@Override @Override
public long getItemId(int position) { public long getItemId(int position) {
return position; FeedItem item = itemAccess.getItem(position);
return item != null ? item.getId() : RecyclerView.NO_POSITION;
} }
@Override @Override

View File

@ -1,6 +1,7 @@
package de.danoeh.antennapod.adapter; package de.danoeh.antennapod.adapter;
import android.content.Context; import android.content.Context;
import android.support.v4.content.ContextCompat;
import android.text.Layout; import android.text.Layout;
import android.text.Selection; import android.text.Selection;
import android.text.Spannable; import android.text.Spannable;
@ -132,13 +133,13 @@ public class ChaptersListAdapter extends ArrayAdapter<Chapter> {
if (current == sc) { if (current == sc) {
int playingBackGroundColor; int playingBackGroundColor;
if(UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) { if(UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) {
playingBackGroundColor = getContext().getResources().getColor(R.color.highlight_dark); playingBackGroundColor = ContextCompat.getColor(getContext(), R.color.highlight_dark);
} else { } else {
playingBackGroundColor = getContext().getResources().getColor(R.color.highlight_light); playingBackGroundColor = ContextCompat.getColor(getContext(), R.color.highlight_light);
} }
holder.view.setBackgroundColor(playingBackGroundColor); holder.view.setBackgroundColor(playingBackGroundColor);
} else { } else {
holder.view.setBackgroundColor(getContext().getResources().getColor(android.R.color.transparent)); holder.view.setBackgroundColor(ContextCompat.getColor(getContext(), android.R.color.transparent));
holder.title.setTextColor(defaultTextColor); holder.title.setTextColor(defaultTextColor);
holder.start.setTextColor(defaultTextColor); holder.start.setTextColor(defaultTextColor);
} }

View File

@ -1,9 +1,7 @@
package de.danoeh.antennapod.adapter; package de.danoeh.antennapod.adapter;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.support.v7.app.AlertDialog;
import android.widget.Toast; import android.widget.Toast;
import com.afollestad.materialdialogs.MaterialDialog; import com.afollestad.materialdialogs.MaterialDialog;

View File

@ -1,6 +1,7 @@
package de.danoeh.antennapod.adapter; package de.danoeh.antennapod.adapter;
import android.content.Context; import android.content.Context;
import android.support.v4.content.ContextCompat;
import android.text.format.DateUtils; import android.text.format.DateUtils;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -10,10 +11,8 @@ import android.widget.BaseAdapter;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.joanzapata.iconify.Iconify;
import com.joanzapata.iconify.widget.IconButton; import com.joanzapata.iconify.widget.IconButton;
import com.joanzapata.iconify.widget.IconTextView;
import java.util.Date;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator; import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
@ -49,7 +48,7 @@ public class DownloadLogAdapter extends BaseAdapter {
LayoutInflater inflater = (LayoutInflater) context LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE); .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.downloadlog_item, parent, false); convertView = inflater.inflate(R.layout.downloadlog_item, parent, false);
holder.icon = (TextView) convertView.findViewById(R.id.txtvIcon); holder.icon = (IconTextView) convertView.findViewById(R.id.txtvIcon);
holder.retry = (IconButton) convertView.findViewById(R.id.btnRetry); holder.retry = (IconButton) convertView.findViewById(R.id.btnRetry);
holder.date = (TextView) convertView.findViewById(R.id.txtvDate); holder.date = (TextView) convertView.findViewById(R.id.txtvDate);
holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); holder.title = (TextView) convertView.findViewById(R.id.txtvTitle);
@ -76,17 +75,15 @@ public class DownloadLogAdapter extends BaseAdapter {
status.getCompletionDate().getTime(), status.getCompletionDate().getTime(),
System.currentTimeMillis(), 0, 0)); System.currentTimeMillis(), 0, 0));
if (status.isSuccessful()) { if (status.isSuccessful()) {
holder.icon.setTextColor(convertView.getResources().getColor( holder.icon.setTextColor(ContextCompat.getColor(convertView.getContext(),
R.color.download_success_green)); R.color.download_success_green));
holder.icon.setText("{fa-check-circle}"); holder.icon.setText("{fa-check-circle}");
Iconify.addIcons(holder.icon);
holder.retry.setVisibility(View.GONE); holder.retry.setVisibility(View.GONE);
holder.reason.setVisibility(View.GONE); holder.reason.setVisibility(View.GONE);
} else { } else {
holder.icon.setTextColor(convertView.getResources().getColor( holder.icon.setTextColor(ContextCompat.getColor(convertView.getContext(),
R.color.download_failed_red)); R.color.download_failed_red));
holder.icon.setText("{fa-times-circle}"); holder.icon.setText("{fa-times-circle}");
Iconify.addIcons(holder.icon);
String reasonText = status.getReason().getErrorString(context); String reasonText = status.getReason().getErrorString(context);
if (status.getReasonDetailed() != null) { if (status.getReasonDetailed() != null) {
reasonText += ": " + status.getReasonDetailed(); reasonText += ": " + status.getReasonDetailed();
@ -123,9 +120,8 @@ public class DownloadLogAdapter extends BaseAdapter {
if(holder.typeId == Feed.FEEDFILETYPE_FEED) { if(holder.typeId == Feed.FEEDFILETYPE_FEED) {
Feed feed = DBReader.getFeed(holder.id); Feed feed = DBReader.getFeed(holder.id);
if (feed != null) { if (feed != null) {
feed.setLastUpdate(new Date(0)); // force refresh
try { try {
DBTasks.refreshFeed(context, feed); DBTasks.forceRefreshFeed(context, feed);
} catch (DownloadRequestException e) { } catch (DownloadRequestException e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -162,7 +158,7 @@ public class DownloadLogAdapter extends BaseAdapter {
} }
static class Holder { static class Holder {
TextView icon; IconTextView icon;
IconButton retry; IconButton retry;
TextView title; TextView title;
TextView type; TextView type;

View File

@ -25,13 +25,10 @@ public class DownloadedEpisodesListAdapter extends BaseAdapter {
private final Context context; private final Context context;
private final ItemAccess itemAccess; private final ItemAccess itemAccess;
private final int imageSize;
public DownloadedEpisodesListAdapter(Context context, ItemAccess itemAccess) { public DownloadedEpisodesListAdapter(Context context, ItemAccess itemAccess) {
super(); super();
this.context = context; this.context = context;
this.itemAccess = itemAccess; this.itemAccess = itemAccess;
this.imageSize = (int) context.getResources().getDimension(R.dimen.thumbnail_length_downloaded_item);
} }
@Override @Override
@ -52,7 +49,7 @@ public class DownloadedEpisodesListAdapter extends BaseAdapter {
@Override @Override
public View getView(int position, View convertView, ViewGroup parent) { public View getView(int position, View convertView, ViewGroup parent) {
Holder holder; Holder holder;
final FeedItem item = (FeedItem) getItem(position); final FeedItem item = getItem(position);
if (item == null) return null; if (item == null) return null;
if (convertView == null) { if (convertView == null) {
@ -61,35 +58,19 @@ public class DownloadedEpisodesListAdapter extends BaseAdapter {
.getSystemService(Context.LAYOUT_INFLATER_SERVICE); .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.downloaded_episodeslist_item, convertView = inflater.inflate(R.layout.downloaded_episodeslist_item,
parent, false); parent, false);
holder.imageView = (ImageView) convertView.findViewById(R.id.imgvImage);
holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); holder.title = (TextView) convertView.findViewById(R.id.txtvTitle);
holder.txtvSize = (TextView) convertView.findViewById(R.id.txtvSize);
holder.queueStatus = (ImageView) convertView.findViewById(R.id.imgvInPlaylist);
holder.pubDate = (TextView) convertView holder.pubDate = (TextView) convertView
.findViewById(R.id.txtvPublished); .findViewById(R.id.txtvPublished);
holder.butSecondary = (ImageButton) convertView holder.butSecondary = (ImageButton) convertView
.findViewById(R.id.butSecondaryAction); .findViewById(R.id.butSecondaryAction);
holder.imageView = (ImageView) convertView.findViewById(R.id.imgvImage);
holder.txtvSize = (TextView) convertView.findViewById(R.id.txtvSize);
convertView.setTag(holder); convertView.setTag(holder);
} else { } else {
holder = (Holder) convertView.getTag(); holder = (Holder) convertView.getTag();
} }
holder.title.setText(item.getTitle());
String pubDateStr = DateUtils.formatAbbrev(context, item.getPubDate());
holder.pubDate.setText(pubDateStr);
holder.txtvSize.setText(Converter.byteToString(item.getMedia().getSize()));
FeedItem.State state = item.getState();
if (state == FeedItem.State.PLAYING) {
holder.butSecondary.setEnabled(false);
} else {
holder.butSecondary.setEnabled(true);
}
holder.butSecondary.setFocusable(false);
holder.butSecondary.setTag(item);
holder.butSecondary.setOnClickListener(secondaryActionListener);
Glide.with(context) Glide.with(context)
.load(item.getImageUri()) .load(item.getImageUri())
.placeholder(R.color.light_gray) .placeholder(R.color.light_gray)
@ -99,6 +80,22 @@ public class DownloadedEpisodesListAdapter extends BaseAdapter {
.dontAnimate() .dontAnimate()
.into(holder.imageView); .into(holder.imageView);
holder.title.setText(item.getTitle());
holder.txtvSize.setText(Converter.byteToString(item.getMedia().getSize()));
holder.queueStatus.setVisibility(item.isTagged(FeedItem.TAG_QUEUE) ? View.VISIBLE : View.GONE);
String pubDateStr = DateUtils.formatAbbrev(context, item.getPubDate());
holder.pubDate.setText(pubDateStr);
FeedItem.State state = item.getState();
if (state == FeedItem.State.PLAYING) {
holder.butSecondary.setEnabled(false);
} else {
holder.butSecondary.setEnabled(true);
}
holder.butSecondary.setFocusable(false);
holder.butSecondary.setTag(item);
holder.butSecondary.setOnClickListener(secondaryActionListener);
return convertView; return convertView;
} }
@ -112,10 +109,11 @@ public class DownloadedEpisodesListAdapter extends BaseAdapter {
static class Holder { static class Holder {
TextView title;
TextView pubDate;
ImageView imageView; ImageView imageView;
TextView title;
TextView txtvSize; TextView txtvSize;
ImageView queueStatus;
TextView pubDate;
ImageButton butSecondary; ImageButton butSecondary;
} }

View File

@ -1,6 +1,7 @@
package de.danoeh.antennapod.adapter; package de.danoeh.antennapod.adapter;
import android.content.Context; import android.content.Context;
import android.support.v4.content.ContextCompat;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -74,7 +75,7 @@ public class DownloadlistAdapter extends BaseAdapter {
} }
if (position == selectedItemIndex) { if (position == selectedItemIndex) {
convertView.setBackgroundColor(convertView.getResources().getColor( convertView.setBackgroundColor(ContextCompat.getColor(convertView.getContext(),
ThemeUtils.getSelectionBackgroundColor())); ThemeUtils.getSelectionBackgroundColor()));
} else { } else {
convertView.setBackgroundResource(0); convertView.setBackgroundResource(0);
@ -130,11 +131,11 @@ public class DownloadlistAdapter extends BaseAdapter {
} }
public interface ItemAccess { public interface ItemAccess {
public int getCount(); int getCount();
public Downloader getItem(int position); Downloader getItem(int position);
public void onSecondaryActionClick(Downloader downloader); void onSecondaryActionClick(Downloader downloader);
} }
} }

View File

@ -2,6 +2,7 @@ package de.danoeh.antennapod.adapter;
import android.content.Context; import android.content.Context;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.support.v4.content.ContextCompat;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
@ -59,11 +60,11 @@ public class FeedItemlistAdapter extends BaseAdapter {
this.makePlayedItemsTransparent = makePlayedItemsTransparent; this.makePlayedItemsTransparent = makePlayedItemsTransparent;
if(UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) { if(UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) {
playingBackGroundColor = context.getResources().getColor(R.color.highlight_dark); playingBackGroundColor = ContextCompat.getColor(context, R.color.highlight_dark);
} else { } else {
playingBackGroundColor = context.getResources().getColor(R.color.highlight_light); playingBackGroundColor = ContextCompat.getColor(context, R.color.highlight_light);
} }
normalBackGroundColor = context.getResources().getColor(android.R.color.transparent); normalBackGroundColor = ContextCompat.getColor(context, android.R.color.transparent);
} }
@Override @Override
@ -118,8 +119,8 @@ public class FeedItemlistAdapter extends BaseAdapter {
if (!(getItemViewType(position) == Adapter.IGNORE_ITEM_VIEW_TYPE)) { if (!(getItemViewType(position) == Adapter.IGNORE_ITEM_VIEW_TYPE)) {
convertView.setVisibility(View.VISIBLE); convertView.setVisibility(View.VISIBLE);
if (position == selectedItemIndex) { if (position == selectedItemIndex) {
convertView.setBackgroundColor(convertView.getResources() convertView.setBackgroundColor(ContextCompat.getColor(convertView.getContext(),
.getColor(ThemeUtils.getSelectionBackgroundColor())); ThemeUtils.getSelectionBackgroundColor()));
} else { } else {
convertView.setBackgroundResource(0); convertView.setBackgroundResource(0);
} }
@ -188,15 +189,14 @@ public class FeedItemlistAdapter extends BaseAdapter {
holder.type.setImageBitmap(null); holder.type.setImageBitmap(null);
holder.type.setVisibility(View.GONE); holder.type.setVisibility(View.GONE);
} }
typeDrawables.recycle();
if(media.isCurrentlyPlaying()) {
if(media.isCurrentlyPlaying()) { if(media.isCurrentlyPlaying()) {
holder.container.setBackgroundColor(playingBackGroundColor); holder.container.setBackgroundColor(playingBackGroundColor);
} else { } else {
holder.container.setBackgroundColor(normalBackGroundColor); holder.container.setBackgroundColor(normalBackGroundColor);
} }
} }
}
boolean isInQueue = itemAccess.isInQueue(item); boolean isInQueue = itemAccess.isInQueue(item);
actionButtonUtils.configureActionButton(holder.butAction, item, isInQueue); actionButtonUtils.configureActionButton(holder.butAction, item, isInQueue);

View File

@ -6,11 +6,13 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.TextView; import android.widget.TextView;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.FeedItem;
import java.util.List; import java.util.List;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.util.DateUtils;
/** /**
* List adapter for showing a list of FeedItems with their title and description. * List adapter for showing a list of FeedItems with their title and description.
*/ */
@ -33,6 +35,7 @@ public class FeedItemlistDescriptionAdapter extends ArrayAdapter<FeedItem> {
.getSystemService(Context.LAYOUT_INFLATER_SERVICE); .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.itemdescription_listitem, parent, false); convertView = inflater.inflate(R.layout.itemdescription_listitem, parent, false);
holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); holder.title = (TextView) convertView.findViewById(R.id.txtvTitle);
holder.pubDate = (TextView) convertView.findViewById(R.id.txtvPubDate);
holder.description = (TextView) convertView.findViewById(R.id.txtvDescription); holder.description = (TextView) convertView.findViewById(R.id.txtvDescription);
convertView.setTag(holder); convertView.setTag(holder);
@ -41,15 +44,20 @@ public class FeedItemlistDescriptionAdapter extends ArrayAdapter<FeedItem> {
} }
holder.title.setText(item.getTitle()); holder.title.setText(item.getTitle());
holder.pubDate.setText(DateUtils.formatAbbrev(getContext(), item.getPubDate()));
if (item.getDescription() != null) { if (item.getDescription() != null) {
holder.description.setText(item.getDescription()); String description = item.getDescription()
.replaceAll("\n", " ")
.replaceAll("\\s+", " ")
.trim();
holder.description.setText(description);
} }
return convertView; return convertView;
} }
static class Holder { static class Holder {
TextView title; TextView title;
TextView pubDate;
TextView description; TextView description;
} }
} }

View File

@ -74,7 +74,7 @@ public class NavListAdapter extends BaseAdapter
} }
private void loadItems() { private void loadItems() {
List<String> newTags = new ArrayList<String>(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) { for(String hidden : hiddenFragments) {
newTags.remove(hidden); newTags.remove(hidden);
@ -131,7 +131,11 @@ public class NavListAdapter extends BaseAdapter
@Override @Override
public int getCount() { public int getCount() {
return getSubscriptionOffset() ;//+ itemAccess.getCount(); //Avoid feed int baseCount = getSubscriptionOffset();
if (UserPreferences.showSubscriptionsInDrawer()) {
baseCount += itemAccess.getCount();
}
return baseCount;
} }
@Override @Override
@ -181,7 +185,7 @@ public class NavListAdapter extends BaseAdapter
} else if (viewType == VIEW_TYPE_SECTION_DIVIDER) { } else if (viewType == VIEW_TYPE_SECTION_DIVIDER) {
v = getSectionDividerView(convertView, parent); v = getSectionDividerView(convertView, parent);
} else { } else {
v = getFeedView(position - getSubscriptionOffset(), convertView, parent); v = getFeedView(position, convertView, parent);
} }
if (v != null && viewType != VIEW_TYPE_SECTION_DIVIDER) { if (v != null && viewType != VIEW_TYPE_SECTION_DIVIDER) {
TextView txtvTitle = (TextView) v.findViewById(R.id.txtvTitle); TextView txtvTitle = (TextView) v.findViewById(R.id.txtvTitle);
@ -232,17 +236,21 @@ public class NavListAdapter extends BaseAdapter
} }
} else if(tag.equals(DownloadsFragment.TAG) && UserPreferences.isEnableAutodownload()) { } else if(tag.equals(DownloadsFragment.TAG) && UserPreferences.isEnableAutodownload()) {
int epCacheSize = UserPreferences.getEpisodeCacheSize(); int epCacheSize = UserPreferences.getEpisodeCacheSize();
if(itemAccess.getNumberOfDownloadedItems() >= epCacheSize) { // don't count episodes that can be reclaimed
int spaceUsed = itemAccess.getNumberOfDownloadedItems() -
itemAccess.getReclaimableItems();
if (epCacheSize > 0 && spaceUsed >= epCacheSize) {
holder.count.setText("{md-disc-full 150%}"); holder.count.setText("{md-disc-full 150%}");
Iconify.addIcons(holder.count); Iconify.addIcons(holder.count);
holder.count.setVisibility(View.VISIBLE); holder.count.setVisibility(View.VISIBLE);
holder.count.setOnClickListener(v -> { holder.count.setOnClickListener(v ->
new AlertDialog.Builder(context) new AlertDialog.Builder(context)
.setTitle(R.string.episode_cache_full_title) .setTitle(R.string.episode_cache_full_title)
.setMessage(R.string.episode_cache_full_message) .setMessage(R.string.episode_cache_full_message)
.setPositiveButton(android.R.string.ok, (dialog, which) -> {}) .setPositiveButton(android.R.string.ok, (dialog, which) -> {})
.show(); .show()
}); );
} else { } else {
holder.count.setVisibility(View.GONE); holder.count.setVisibility(View.GONE);
} }
@ -267,10 +275,11 @@ public class NavListAdapter extends BaseAdapter
return convertView; return convertView;
} }
private View getFeedView(int feedPos, View convertView, ViewGroup parent) { private View getFeedView(int position, View convertView, ViewGroup parent) {
FeedHolder holder; int feedPos = position - getSubscriptionOffset();
Feed feed = itemAccess.getItem(feedPos); Feed feed = itemAccess.getItem(feedPos);
FeedHolder holder;
if (convertView == null) { if (convertView == null) {
holder = new FeedHolder(); holder = new FeedHolder();
LayoutInflater inflater = (LayoutInflater) context LayoutInflater inflater = (LayoutInflater) context
@ -298,7 +307,6 @@ public class NavListAdapter extends BaseAdapter
holder.title.setText(feed.getTitle()); holder.title.setText(feed.getTitle());
if(feed.hasLastUpdateFailed()) { if(feed.hasLastUpdateFailed()) {
RelativeLayout.LayoutParams p = (RelativeLayout.LayoutParams) holder.title.getLayoutParams(); RelativeLayout.LayoutParams p = (RelativeLayout.LayoutParams) holder.title.getLayoutParams();
p.addRule(RelativeLayout.LEFT_OF, R.id.itxtvFailure); p.addRule(RelativeLayout.LEFT_OF, R.id.itxtvFailure);
@ -312,7 +320,11 @@ public class NavListAdapter extends BaseAdapter
if(counter > 0) { if(counter > 0) {
holder.count.setVisibility(View.VISIBLE); holder.count.setVisibility(View.VISIBLE);
holder.count.setText(String.valueOf(counter)); holder.count.setText(String.valueOf(counter));
holder.count.setTypeface(holder.title.getTypeface()); if (itemAccess.getSelectedItemIndex() == position) {
holder.count.setTypeface(null, Typeface.BOLD);
} else {
holder.count.setTypeface(null, Typeface.NORMAL);
}
} else { } else {
holder.count.setVisibility(View.GONE); holder.count.setVisibility(View.GONE);
} }
@ -339,6 +351,7 @@ public class NavListAdapter extends BaseAdapter
int getQueueSize(); int getQueueSize();
int getNumberOfNewItems(); int getNumberOfNewItems();
int getNumberOfDownloadedItems(); int getNumberOfDownloadedItems();
int getReclaimableItems();
int getFeedCounter(long feedId); int getFeedCounter(long feedId);
} }

View File

@ -3,9 +3,11 @@ package de.danoeh.antennapod.adapter;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.MotionEventCompat; import android.support.v4.view.MotionEventCompat;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper; import android.support.v7.widget.helper.ItemTouchHelper;
import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.view.ContextMenu; import android.view.ContextMenu;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -27,8 +29,6 @@ import com.bumptech.glide.request.target.GlideDrawableImageViewTarget;
import com.joanzapata.iconify.Iconify; import com.joanzapata.iconify.Iconify;
import com.nineoldandroids.view.ViewHelper; import com.nineoldandroids.view.ViewHelper;
import org.apache.commons.lang3.StringUtils;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
@ -78,11 +78,11 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap
locked = UserPreferences.isQueueLocked(); locked = UserPreferences.isQueueLocked();
if(UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) { if(UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) {
playingBackGroundColor = mainActivity.getResources().getColor(R.color.highlight_dark); playingBackGroundColor = ContextCompat.getColor(mainActivity, R.color.highlight_dark);
} else { } else {
playingBackGroundColor = mainActivity.getResources().getColor(R.color.highlight_light); playingBackGroundColor = ContextCompat.getColor(mainActivity, R.color.highlight_light);
} }
normalBackGroundColor = mainActivity.getResources().getColor(android.R.color.transparent); normalBackGroundColor = ContextCompat.getColor(mainActivity, android.R.color.transparent);
} }
public void setLocked(boolean locked) { public void setLocked(boolean locked) {
@ -109,6 +109,12 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap
return selectedItem; return selectedItem;
} }
@Override
public long getItemId(int position) {
FeedItem item = itemAccess.getItem(position);
return item != null ? item.getId() : RecyclerView.NO_POSITION;
}
public int getItemCount() { public int getItemCount() {
return itemAccess.getCount(); return itemAccess.getCount();
} }
@ -213,13 +219,13 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap
title.setText(item.getTitle()); title.setText(item.getTitle());
String pubDateStr = DateUtils.formatAbbrev(mainActivity.get(), item.getPubDate()); String pubDateStr = DateUtils.formatAbbrev(mainActivity.get(), item.getPubDate());
int index = 0; int index = 0;
if(StringUtils.countMatches(pubDateStr, ' ') == 1 || StringUtils.countMatches(pubDateStr, ' ') == 2) { if(countMatches(pubDateStr, ' ') == 1 || countMatches(pubDateStr, ' ') == 2) {
index = pubDateStr.lastIndexOf(' '); index = pubDateStr.lastIndexOf(' ');
} else if(StringUtils.countMatches(pubDateStr, '.') == 2) { } else if(countMatches(pubDateStr, '.') == 2) {
index = pubDateStr.lastIndexOf('.'); index = pubDateStr.lastIndexOf('.');
} else if(StringUtils.countMatches(pubDateStr, '-') == 2) { } else if(countMatches(pubDateStr, '-') == 2) {
index = pubDateStr.lastIndexOf('-'); index = pubDateStr.lastIndexOf('-');
} else if(StringUtils.countMatches(pubDateStr, '/') == 2) { } else if(countMatches(pubDateStr, '/') == 2) {
index = pubDateStr.lastIndexOf('/'); index = pubDateStr.lastIndexOf('/');
} }
if(index > 0) { if(index > 0) {
@ -252,7 +258,7 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap
} else { } else {
if(media.getSize() > 0) { if(media.getSize() > 0) {
progressLeft.setText(Converter.byteToString(media.getSize())); progressLeft.setText(Converter.byteToString(media.getSize()));
} else if(false == media.checkedOnSizeButUnknown()) { } else if(NetworkUtils.isDownloadAllowed() && !media.checkedOnSizeButUnknown()) {
progressLeft.setText("{fa-spinner}"); progressLeft.setText("{fa-spinner}");
Iconify.addIcons(progressLeft); Iconify.addIcons(progressLeft);
NetworkUtils.getFeedMediaSizeObservable(media) NetworkUtils.getFeedMediaSizeObservable(media)
@ -375,4 +381,18 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap
*/ */
void onItemClear(); void onItemClear();
} }
// Oh Xiaomi, I hate you so much. How did you manage to fuck this up?
private static int countMatches(final CharSequence str, final char ch) {
if (TextUtils.isEmpty(str)) {
return 0;
}
int count = 0;
for (int i = 0; i < str.length(); i++) {
if (ch == str.charAt(i)) {
count++;
}
}
return count;
}
} }

View File

@ -9,7 +9,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.bumptech.glide.load.engine.DiskCacheStrategy;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.Feed;
@ -112,7 +111,7 @@ public class SearchlistAdapter extends BaseAdapter {
TextView subtitle; TextView subtitle;
} }
public static interface ItemAccess { public interface ItemAccess {
int getCount(); int getCount();
SearchResult getItem(int position); SearchResult getItem(int position);

View File

@ -0,0 +1,97 @@
package de.danoeh.antennapod.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.joanzapata.iconify.widget.IconTextView;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.util.Converter;
/**
* Adapter for the statistics list
*/
public class StatisticsListAdapter extends BaseAdapter {
private Context context;
List<DBReader.StatisticsItem> feedTime = new ArrayList<>();
public StatisticsListAdapter(Context context) {
this.context = context;
}
@Override
public int getCount() {
return feedTime.size();
}
@Override
public DBReader.StatisticsItem getItem(int position) {
return feedTime.get(position);
}
@Override
public long getItemId(int position) {
return feedTime.get(position).feed.getId();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
StatisticsHolder holder;
Feed feed = feedTime.get(position).feed;
if (convertView == null) {
holder = new StatisticsHolder();
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.statistics_listitem, parent, false);
holder.image = (ImageView) convertView.findViewById(R.id.imgvCover);
holder.title = (TextView) convertView.findViewById(R.id.txtvTitle);
holder.time = (TextView) convertView.findViewById(R.id.txtvTime);
convertView.setTag(holder);
} else {
holder = (StatisticsHolder) convertView.getTag();
}
Glide.with(context)
.load(feed.getImageUri())
.placeholder(R.color.light_gray)
.error(R.color.light_gray)
.diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
.fitCenter()
.dontAnimate()
.into(holder.image);
holder.title.setText(feed.getTitle());
holder.time.setText(Converter.shortLocalizedDuration(context,
feedTime.get(position).timePlayed));
return convertView;
}
public void update(List<DBReader.StatisticsItem> feedTime) {
this.feedTime = feedTime;
notifyDataSetChanged();
}
static class StatisticsHolder {
ImageView image;
TextView title;
TextView time;
}
}

View File

@ -40,7 +40,7 @@ public class SubscriptionsAdapter extends BaseAdapter {
@Override @Override
public long getItemId(int position) { public long getItemId(int position) {
return 0; return mItemAccess.getItem(position).getId();
} }
@Override @Override

View File

@ -9,7 +9,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.bumptech.glide.load.engine.DiskCacheStrategy;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;

View File

@ -167,7 +167,7 @@ public class ItunesAdapter extends ArrayAdapter<ItunesAdapter.Podcast> {
for(int i=0; imageUrl == null && i < images.length(); i++) { for(int i=0; imageUrl == null && i < images.length(); i++) {
JSONObject image = images.getJSONObject(i); JSONObject image = images.getJSONObject(i);
String height = image.getJSONObject("attributes").getString("height"); String height = image.getJSONObject("attributes").getString("height");
if(Integer.valueOf(height) >= 100) { if(Integer.parseInt(height) >= 100) {
imageUrl = image.getString("label"); imageUrl = image.getString("label");
} }
} }

View File

@ -3,7 +3,6 @@ package de.danoeh.antennapod.asynctask;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
@ -80,14 +79,7 @@ public class OpmlExportWorker extends AsyncTask<Void, Void, Void> {
progDialog.dismiss(); progDialog.dismiss();
AlertDialog.Builder alert = new AlertDialog.Builder(context) AlertDialog.Builder alert = new AlertDialog.Builder(context)
.setNeutralButton(android.R.string.ok, .setNeutralButton(android.R.string.ok,
new DialogInterface.OnClickListener() { (dialog, which) -> dialog.dismiss());
@Override
public void onClick(DialogInterface dialog,
int which) {
dialog.dismiss();
}
});
if (exception != null) { if (exception != null) {
alert.setTitle(R.string.export_error_label); alert.setTitle(R.string.export_error_label);
alert.setMessage(exception.getMessage()); alert.setMessage(exception.getMessage());

View File

@ -6,7 +6,6 @@ import android.content.Context;
import android.os.AsyncTask; import android.os.AsyncTask;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date;
import de.danoeh.antennapod.activity.OpmlImportHolder; import de.danoeh.antennapod.activity.OpmlImportHolder;
import de.danoeh.antennapod.core.R; import de.danoeh.antennapod.core.R;
@ -44,10 +43,9 @@ public class OpmlFeedQueuer extends AsyncTask<Void, Void, Void> {
@Override @Override
protected Void doInBackground(Void... params) { protected Void doInBackground(Void... params) {
DownloadRequester requester = DownloadRequester.getInstance(); DownloadRequester requester = DownloadRequester.getInstance();
for (int idx = 0; idx < selection.length; idx++) { for (int selected : selection) {
OpmlElement element = OpmlImportHolder.getReadElements().get( OpmlElement element = OpmlImportHolder.getReadElements().get(selected);
selection[idx]); Feed feed = new Feed(element.getXmlUrl(), null,
Feed feed = new Feed(element.getXmlUrl(), new Date(0),
element.getText()); element.getText());
try { try {
requester.downloadFeed(context.getApplicationContext(), feed); requester.downloadFeed(context.getApplicationContext(), feed);

View File

@ -3,21 +3,20 @@ package de.danoeh.antennapod.asynctask;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.util.Log; import android.util.Log;
import de.danoeh.antennapod.core.BuildConfig;
import de.danoeh.antennapod.core.R;
import de.danoeh.antennapod.core.opml.OpmlElement;
import de.danoeh.antennapod.core.opml.OpmlReader;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException; import java.io.IOException;
import java.io.Reader; import java.io.Reader;
import java.util.ArrayList; import java.util.ArrayList;
import de.danoeh.antennapod.core.R;
import de.danoeh.antennapod.core.opml.OpmlElement;
import de.danoeh.antennapod.core.opml.OpmlReader;
public class OpmlImportWorker extends 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";

View File

@ -2,7 +2,6 @@ package de.danoeh.antennapod.config;
import de.danoeh.antennapod.core.DBTasksCallbacks; import de.danoeh.antennapod.core.DBTasksCallbacks;
import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.APCleanupAlgorithm;
import de.danoeh.antennapod.core.storage.APDownloadAlgorithm; import de.danoeh.antennapod.core.storage.APDownloadAlgorithm;
import de.danoeh.antennapod.core.storage.AutomaticDownloadAlgorithm; import de.danoeh.antennapod.core.storage.AutomaticDownloadAlgorithm;
import de.danoeh.antennapod.core.storage.EpisodeCleanupAlgorithm; import de.danoeh.antennapod.core.storage.EpisodeCleanupAlgorithm;

View File

@ -2,13 +2,13 @@ package de.danoeh.antennapod.dialog;
import android.app.Dialog; import android.app.Dialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.view.View;
import android.view.Window; import android.view.Window;
import android.widget.Button; import android.widget.Button;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.EditText; import android.widget.EditText;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
/** /**
@ -58,26 +58,13 @@ public abstract class AuthenticationDialog extends Dialog {
if (passwordInitialValue != null) { if (passwordInitialValue != null) {
etxtPassword.setText(passwordInitialValue); etxtPassword.setText(passwordInitialValue);
} }
setOnCancelListener(new OnCancelListener() { setOnCancelListener(dialog -> onCancelled());
@Override butCancel.setOnClickListener(v -> cancel());
public void onCancel(DialogInterface dialog) { butConfirm.setOnClickListener(v -> {
onCancelled();
}
});
butCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
cancel();
}
});
butConfirm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onConfirmed(etxtUsername.getText().toString(), onConfirmed(etxtUsername.getText().toString(),
etxtPassword.getText().toString(), etxtPassword.getText().toString(),
showSaveCredentialsCheckbox && saveUsernamePassword.isChecked()); showSaveCredentialsCheckbox && saveUsernamePassword.isChecked());
dismiss(); dismiss();
}
}); });
} }

View File

@ -3,7 +3,6 @@ package de.danoeh.antennapod.dialog;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.view.View; import android.view.View;
import android.widget.CheckBox; import android.widget.CheckBox;
@ -42,12 +41,9 @@ public class AutoFlattrPreferenceDialog {
setStatusMsgText(activity, txtvStatus, initialValue); setStatusMsgText(activity, txtvStatus, initialValue);
skbPercent.setProgress(initialValue); skbPercent.setProgress(initialValue);
chkAutoFlattr.setOnClickListener(new View.OnClickListener() { chkAutoFlattr.setOnClickListener(v -> {
@Override
public void onClick(View v) {
skbPercent.setEnabled(chkAutoFlattr.isChecked()); skbPercent.setEnabled(chkAutoFlattr.isChecked());
txtvStatus.setEnabled(chkAutoFlattr.isChecked()); txtvStatus.setEnabled(chkAutoFlattr.isChecked());
}
}); });
skbPercent.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { skbPercent.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@ -69,20 +65,14 @@ public class AutoFlattrPreferenceDialog {
builder.setTitle(R.string.pref_auto_flattr_title) builder.setTitle(R.string.pref_auto_flattr_title)
.setView(view) .setView(view)
.setPositiveButton(R.string.confirm_label, new DialogInterface.OnClickListener() { .setPositiveButton(R.string.confirm_label, (dialog, which) -> {
@Override
public void onClick(DialogInterface dialog, int which) {
float progDouble = ((float) skbPercent.getProgress()) / 100.0f; float progDouble = ((float) skbPercent.getProgress()) / 100.0f;
callback.onConfirmed(chkAutoFlattr.isChecked(), progDouble); callback.onConfirmed(chkAutoFlattr.isChecked(), progDouble);
dialog.dismiss(); dialog.dismiss();
}
}) })
.setNegativeButton(R.string.cancel_label, new DialogInterface.OnClickListener() { .setNegativeButton(R.string.cancel_label, (dialog, which) -> {
@Override
public void onClick(DialogInterface dialog, int which) {
callback.onCancelled(); callback.onCancelled();
dialog.dismiss(); dialog.dismiss();
}
}) })
.setCancelable(false).show(); .setCancelable(false).show();
} }
@ -97,10 +87,10 @@ public class AutoFlattrPreferenceDialog {
} }
} }
public static interface AutoFlattrPreferenceDialogInterface { public interface AutoFlattrPreferenceDialogInterface {
public void onCancelled(); void onCancelled();
public void onConfirmed(boolean autoFlattrEnabled, float autoFlattrValue); void onConfirmed(boolean autoFlattrEnabled, float autoFlattrValue);
} }

View File

@ -1,7 +1,6 @@
package de.danoeh.antennapod.dialog; package de.danoeh.antennapod.dialog;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityCompat;
@ -18,10 +17,6 @@ import android.widget.Button;
import android.widget.ListView; import android.widget.ListView;
import android.widget.Toast; import android.widget.Toast;
import com.joanzapata.iconify.Icon;
import com.joanzapata.iconify.IconDrawable;
import com.joanzapata.iconify.fonts.FontAwesomeIcons;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -39,6 +34,14 @@ public class EpisodesApplyActionFragment extends Fragment {
public String TAG = "EpisodeActionFragment"; public String TAG = "EpisodeActionFragment";
public static final int ACTION_QUEUE = 1;
public static final int ACTION_MARK_PLAYED = 2;
public static final int ACTION_MARK_UNPLAYED = 4;
public static final int ACTION_DOWNLOAD = 8;
public static final int ACTION_REMOVE = 16;
public static final int ACTION_ALL = ACTION_QUEUE | ACTION_MARK_PLAYED | ACTION_MARK_UNPLAYED
| ACTION_DOWNLOAD | ACTION_REMOVE;
private ListView mListView; private ListView mListView;
private ArrayAdapter<String> mAdapter; private ArrayAdapter<String> mAdapter;
@ -48,27 +51,26 @@ public class EpisodesApplyActionFragment extends Fragment {
private Button btnDownload; private Button btnDownload;
private Button btnDelete; private Button btnDelete;
private final Map<Long,FeedItem> idMap; private final Map<Long,FeedItem> idMap = new ArrayMap<>();
private final List<FeedItem> episodes; private final List<FeedItem> episodes = new ArrayList<>();
private final List<String> titles = new ArrayList(); private int actions;
private final List<String> titles = new ArrayList<>();
private final LongList checkedIds = new LongList(); private final LongList checkedIds = new LongList();
private MenuItem mSelectToggle; private MenuItem mSelectToggle;
private int textColor; public static EpisodesApplyActionFragment newInstance(List<FeedItem> items) {
return newInstance(items, ACTION_ALL);
public EpisodesApplyActionFragment() {
this.episodes = new ArrayList<>();
this.idMap = new ArrayMap<>();
} }
public void setEpisodes(List<FeedItem> episodes) { public static EpisodesApplyActionFragment newInstance(List<FeedItem> items, int actions) {
this.episodes.clear(); EpisodesApplyActionFragment f = new EpisodesApplyActionFragment();
this.episodes.addAll(episodes); f.episodes.addAll(items);
this.idMap.clear(); for(FeedItem episode : items) {
for(FeedItem episode : episodes) { f.idMap.put(episode.getId(), episode);
this.idMap.put(episode.getId(), episode);
} }
f.actions = actions;
return f;
} }
@Override @Override
@ -103,16 +105,48 @@ public class EpisodesApplyActionFragment extends Fragment {
mListView.setAdapter(mAdapter); mListView.setAdapter(mAdapter);
checkAll(); checkAll();
int lastVisibleDiv = 0;
btnAddToQueue = (Button) view.findViewById(R.id.btnAddToQueue); btnAddToQueue = (Button) view.findViewById(R.id.btnAddToQueue);
if((actions & ACTION_QUEUE) != 0) {
btnAddToQueue.setOnClickListener(v -> queueChecked()); btnAddToQueue.setOnClickListener(v -> queueChecked());
lastVisibleDiv = R.id.divider1;
} else {
btnAddToQueue.setVisibility(View.GONE);
view.findViewById(R.id.divider1).setVisibility(View.GONE);
}
btnMarkAsPlayed = (Button) view.findViewById(R.id.btnMarkAsPlayed); btnMarkAsPlayed = (Button) view.findViewById(R.id.btnMarkAsPlayed);
if((actions & ACTION_MARK_PLAYED) != 0) {
btnMarkAsPlayed.setOnClickListener(v -> markedCheckedPlayed()); btnMarkAsPlayed.setOnClickListener(v -> markedCheckedPlayed());
lastVisibleDiv = R.id.divider2;
} else {
btnMarkAsPlayed.setVisibility(View.GONE);
view.findViewById(R.id.divider2).setVisibility(View.GONE);
}
btnMarkAsUnplayed = (Button) view.findViewById(R.id.btnMarkAsUnplayed); btnMarkAsUnplayed = (Button) view.findViewById(R.id.btnMarkAsUnplayed);
if((actions & ACTION_MARK_UNPLAYED) != 0) {
btnMarkAsUnplayed.setOnClickListener(v -> markedCheckedUnplayed()); btnMarkAsUnplayed.setOnClickListener(v -> markedCheckedUnplayed());
lastVisibleDiv = R.id.divider3;
} else {
btnMarkAsUnplayed.setVisibility(View.GONE);
view.findViewById(R.id.divider3).setVisibility(View.GONE);
}
btnDownload = (Button) view.findViewById(R.id.btnDownload); btnDownload = (Button) view.findViewById(R.id.btnDownload);
if((actions & ACTION_DOWNLOAD) != 0) {
btnDownload.setOnClickListener(v -> downloadChecked()); btnDownload.setOnClickListener(v -> downloadChecked());
lastVisibleDiv = R.id.divider4;
} else {
btnDownload.setVisibility(View.GONE);
view.findViewById(R.id.divider4).setVisibility(View.GONE);
}
btnDelete = (Button) view.findViewById(R.id.btnDelete); btnDelete = (Button) view.findViewById(R.id.btnDelete);
if((actions & ACTION_REMOVE) != 0) {
btnDelete.setOnClickListener(v -> deleteChecked()); btnDelete.setOnClickListener(v -> deleteChecked());
} else {
btnDelete.setVisibility(View.GONE);
if(lastVisibleDiv > 0) {
view.findViewById(lastVisibleDiv).setVisibility(View.GONE);
}
}
return view; return view;
} }
@ -122,11 +156,6 @@ public class EpisodesApplyActionFragment extends Fragment {
super.onCreateOptionsMenu(menu, inflater); super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.episodes_apply_action_options, menu); inflater.inflate(R.menu.episodes_apply_action_options, menu);
int[] attrs = { android.R.attr.textColor };
TypedArray ta = getActivity().obtainStyledAttributes(attrs);
textColor = ta.getColor(0, Color.GRAY);
ta.recycle();
mSelectToggle = menu.findItem(R.id.select_toggle); mSelectToggle = menu.findItem(R.id.select_toggle);
mSelectToggle.setOnMenuItemClickListener(item -> { mSelectToggle.setOnMenuItemClickListener(item -> {
if (checkedIds.size() == episodes.size()) { if (checkedIds.size() == episodes.size()) {
@ -140,22 +169,21 @@ public class EpisodesApplyActionFragment extends Fragment {
@Override @Override
public void onPrepareOptionsMenu (Menu menu) { public void onPrepareOptionsMenu (Menu menu) {
/* // Prepare icon for select toggle button
* Prepare icon for select toggle button
*/
// Find icon attribute
int[] icon = new int[1]; int[] icon = new int[1];
if(checkedIds.size() == episodes.size()) icon[0] = R.attr.ic_check_box; if (checkedIds.size() == episodes.size()) {
else if(checkedIds.size() == 0) icon[0] = R.attr.ic_check_box_outline; icon[0] = R.attr.ic_check_box;
else icon[0] = R.attr.ic_indeterminate_check_box; } else if (checkedIds.size() == 0) {
icon[0] = R.attr.ic_check_box_outline;
} else {
icon[0] = R.attr.ic_indeterminate_check_box;
}
// Get Drawable from attribute
TypedArray a = getActivity().obtainStyledAttributes(icon); TypedArray a = getActivity().obtainStyledAttributes(icon);
Drawable iconDrawable = a.getDrawable(0); Drawable iconDrawable = a.getDrawable(0);
a.recycle(); a.recycle();
// Set icon
mSelectToggle.setIcon(iconDrawable); mSelectToggle.setIcon(iconDrawable);
} }
@ -189,6 +217,14 @@ public class EpisodesApplyActionFragment extends Fragment {
checkDownloaded(false); checkDownloaded(false);
resId = R.string.selected_not_downloaded_label; resId = R.string.selected_not_downloaded_label;
break; break;
case R.id.check_queued:
checkQueued(true);
resId = R.string.selected_queued_label;
break;
case R.id.check_not_queued:
checkQueued(false);
resId = R.string.selected_not_queued_label;
break;
case R.id.sort_title_a_z: case R.id.sort_title_a_z:
sortByTitle(false); sortByTitle(false);
return true; return true;
@ -249,9 +285,9 @@ public class EpisodesApplyActionFragment extends Fragment {
private void sortByDuration(final boolean reverse) { private void sortByDuration(final boolean reverse) {
Collections.sort(episodes, (lhs, rhs) -> { Collections.sort(episodes, (lhs, rhs) -> {
int ordering; int ordering;
if (false == lhs.hasMedia()) { if (!lhs.hasMedia()) {
ordering = 1; ordering = 1;
} else if (false == rhs.hasMedia()) { } else if (!rhs.hasMedia()) {
ordering = -1; ordering = -1;
} else { } else {
ordering = lhs.getMedia().getDuration() - rhs.getMedia().getDuration(); ordering = lhs.getMedia().getDuration() - rhs.getMedia().getDuration();
@ -268,7 +304,7 @@ public class EpisodesApplyActionFragment extends Fragment {
private void checkAll() { private void checkAll() {
for (FeedItem episode : episodes) { for (FeedItem episode : episodes) {
if(false == checkedIds.contains(episode.getId())) { if(!checkedIds.contains(episode.getId())) {
checkedIds.add(episode.getId()); checkedIds.add(episode.getId());
} }
} }
@ -310,6 +346,17 @@ public class EpisodesApplyActionFragment extends Fragment {
refreshCheckboxes(); refreshCheckboxes();
} }
private void checkQueued(boolean isQueued) {
for (FeedItem episode : episodes) {
if(episode.isTagged(FeedItem.TAG_QUEUE) == isQueued) {
checkedIds.add(episode.getId());
} else {
checkedIds.remove(episode.getId());
}
}
refreshCheckboxes();
}
private void refreshTitles() { private void refreshTitles() {
titles.clear(); titles.clear();
for(FeedItem episode : episodes) { for(FeedItem episode : episodes) {
@ -344,14 +391,14 @@ public class EpisodesApplyActionFragment extends Fragment {
private void downloadChecked() { private void downloadChecked() {
// download the check episodes in the same order as they are currently displayed // download the check episodes in the same order as they are currently displayed
List<FeedItem> toDownload = new ArrayList<FeedItem>(checkedIds.size()); List<FeedItem> toDownload = new ArrayList<>(checkedIds.size());
for(FeedItem episode : episodes) { for(FeedItem episode : episodes) {
if(checkedIds.contains(episode.getId())) { if(checkedIds.contains(episode.getId())) {
toDownload.add(episode); toDownload.add(episode);
} }
} }
try { try {
DBTasks.downloadFeedItems(getActivity(), toDownload.toArray(new FeedItem[0])); DBTasks.downloadFeedItems(getActivity(), toDownload.toArray(new FeedItem[toDownload.size()]));
} catch (DownloadRequestException e) { } catch (DownloadRequestException e) {
e.printStackTrace(); e.printStackTrace();
DownloadRequestErrorDialogCreator.newRequestErrorDialog(getActivity(), e.getMessage()); DownloadRequestErrorDialogCreator.newRequestErrorDialog(getActivity(), e.getMessage());

View File

@ -1,7 +1,6 @@
package de.danoeh.antennapod.dialog; package de.danoeh.antennapod.dialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.text.Editable; import android.text.Editable;
import android.text.InputType; import android.text.InputType;

View File

@ -0,0 +1,320 @@
package de.danoeh.antennapod.dialog;
import android.app.Dialog;
import android.content.Context;
import android.content.res.TypedArray;
import android.support.v4.content.ContextCompat;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Patterns;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.afollestad.materialdialogs.internal.MDButton;
import com.squareup.okhttp.Credentials;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.SocketAddress;
import java.util.concurrent.TimeUnit;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.download.AntennapodHttpClient;
import de.danoeh.antennapod.core.service.download.ProxyConfig;
import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
public class ProxyDialog {
private static final String TAG = "ProxyDialog";
private Context context;
private MaterialDialog dialog;
private Spinner spType;
private EditText etHost;
private EditText etPort;
private EditText etUsername;
private EditText etPassword;
private boolean testSuccessful = false;
private TextView txtvMessage;
private Subscription subscription;
public ProxyDialog(Context context) {
this.context = context;
}
public Dialog createDialog() {
dialog = new MaterialDialog.Builder(context)
.title(R.string.pref_proxy_title)
.customView(R.layout.proxy_settings, true)
.positiveText(R.string.proxy_test_label)
.negativeText(R.string.cancel_label)
.onPositive((dialog1, which) -> {
if(!testSuccessful) {
dialog.getActionButton(DialogAction.POSITIVE).setEnabled(false);
test();
return;
}
String type = (String) ((Spinner) dialog1.findViewById(R.id.spType)).getSelectedItem();
ProxyConfig proxy;
if(Proxy.Type.valueOf(type) == Proxy.Type.DIRECT) {
proxy = ProxyConfig.direct();
} else {
String host = etHost.getText().toString();
String port = etPort.getText().toString();
String username = etUsername.getText().toString();
if(TextUtils.isEmpty(username)) {
username = null;
}
String password = etPassword.getText().toString();
if(TextUtils.isEmpty(password)) {
password = null;
}
int portValue = 0;
if(!TextUtils.isEmpty(port)) {
portValue = Integer.valueOf(port);
}
proxy = ProxyConfig.http(host, portValue, username, password);
}
UserPreferences.setProxyConfig(proxy);
AntennapodHttpClient.reinit();
dialog.dismiss();
})
.onNegative((dialog1, which) -> dialog1.dismiss())
.autoDismiss(false)
.build();
View view = dialog.getCustomView();
spType = (Spinner) view.findViewById(R.id.spType);
String[] types = { Proxy.Type.DIRECT.name(), Proxy.Type.HTTP.name() };
ArrayAdapter<String> adapter = new ArrayAdapter<>(context,
android.R.layout.simple_spinner_item, types);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spType.setAdapter(adapter);
ProxyConfig proxyConfig = UserPreferences.getProxyConfig();
spType.setSelection(adapter.getPosition(proxyConfig.type.name()));
etHost = (EditText) view.findViewById(R.id.etHost);
if(!TextUtils.isEmpty(proxyConfig.host)) {
etHost.setText(proxyConfig.host);
}
etHost.addTextChangedListener(requireTestOnChange);
etPort = (EditText) view.findViewById(R.id.etPort);
if(proxyConfig.port > 0) {
etPort.setText(String.valueOf(proxyConfig.port));
}
etPort.addTextChangedListener(requireTestOnChange);
etUsername = (EditText) view.findViewById(R.id.etUsername);
if(!TextUtils.isEmpty(proxyConfig.username)) {
etUsername.setText(proxyConfig.username);
}
etUsername.addTextChangedListener(requireTestOnChange);
etPassword = (EditText) view.findViewById(R.id.etPassword);
if(!TextUtils.isEmpty(proxyConfig.password)) {
etPassword.setText(proxyConfig.username);
}
etPassword.addTextChangedListener(requireTestOnChange);
if(proxyConfig.type == Proxy.Type.DIRECT) {
enableSettings(false);
setTestRequired(false);
}
spType.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
enableSettings(position > 0);
setTestRequired(position > 0);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
enableSettings(false);
}
});
txtvMessage = (TextView) view.findViewById(R.id.txtvMessage);
checkValidity();
return dialog;
}
private final TextWatcher requireTestOnChange = 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) {
setTestRequired(true);
}
};
private void enableSettings(boolean enable) {
etHost.setEnabled(enable);
etPort.setEnabled(enable);
etUsername.setEnabled(enable);
etPassword.setEnabled(enable);
}
private boolean checkValidity() {
boolean valid = true;
if(spType.getSelectedItemPosition() > 0) {
valid &= checkHost();
}
valid &= checkPort();
return valid;
}
private boolean checkHost() {
String host = etHost.getText().toString();
if(host.length() == 0) {
etHost.setError(context.getString(R.string.proxy_host_empty_error));
return false;
}
if(!"localhost".equals(host) && !Patterns.DOMAIN_NAME.matcher(host).matches()) {
etHost.setError(context.getString(R.string.proxy_host_invalid_error));
return false;
}
return true;
}
private boolean checkPort() {
int port = getPort();
if(port < 0 && port > 65535) {
etPort.setError(context.getString(R.string.proxy_port_invalid_error));
return false;
}
return true;
}
private int getPort() {
String port = etPort.getText().toString();
if(port.length() > 0) {
try {
return Integer.parseInt(port);
} catch(NumberFormatException e) {
// ignore
}
}
return 0;
}
private void setTestRequired(boolean required) {
if(required) {
testSuccessful = false;
MDButton button = dialog.getActionButton(DialogAction.POSITIVE);
button.setText(context.getText(R.string.proxy_test_label));
button.setEnabled(true);
} else {
testSuccessful = true;
MDButton button = dialog.getActionButton(DialogAction.POSITIVE);
button.setText(context.getText(android.R.string.ok));
button.setEnabled(true);
}
}
private void test() {
if(subscription != null) {
subscription.unsubscribe();
}
if(!checkValidity()) {
setTestRequired(true);
return;
}
TypedArray res = context.getTheme().obtainStyledAttributes(new int[] { android.R.attr.textColorPrimary });
int textColorPrimary = res.getColor(0, 0);
res.recycle();
String checking = context.getString(R.string.proxy_checking);
txtvMessage.setTextColor(textColorPrimary);
txtvMessage.setText("{fa-circle-o-notch spin} " + checking);
txtvMessage.setVisibility(View.VISIBLE);
subscription = Observable.create(new Observable.OnSubscribe<Response>() {
@Override
public void call(Subscriber<? super Response> subscriber) {
String type = (String) spType.getSelectedItem();
String host = etHost.getText().toString();
String port = etPort.getText().toString();
String username = etUsername.getText().toString();
String password = etPassword.getText().toString();
int portValue = 8080;
if(!TextUtils.isEmpty(port)) {
portValue = Integer.valueOf(port);
}
SocketAddress address = InetSocketAddress.createUnresolved(host, portValue);
Proxy.Type proxyType = Proxy.Type.valueOf(type.toUpperCase());
Proxy proxy = new Proxy(proxyType, address);
OkHttpClient client = AntennapodHttpClient.newHttpClient();
client.setConnectTimeout(10, TimeUnit.SECONDS);
client.setProxy(proxy);
client.interceptors().clear();
if(!TextUtils.isEmpty(username)) {
String credentials = Credentials.basic(username, password);
client.interceptors().add(chain -> {
Request request = chain.request().newBuilder()
.header("Proxy-Authorization", credentials).build();
return chain.proceed(request);
});
}
Request request = new Request.Builder()
.url("http://www.google.com")
.head()
.build();
try {
Response response = client.newCall(request).execute();
subscriber.onNext(response);
} catch(IOException e) {
subscriber.onError(e);
}
subscriber.onCompleted();
}
})
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
response -> {
int colorId;
String icon;
String result;
if(response.isSuccessful()) {
colorId = R.color.download_success_green;
icon = "{fa-check}";
result = context.getString(R.string.proxy_test_successful);
} else {
colorId = R.color.download_failed_red;
icon = "{fa-close}";
result = context.getString(R.string.proxy_test_failed);
}
int color = ContextCompat.getColor(context, colorId);
txtvMessage.setTextColor(color);
String message = String.format("%s %s: %s", icon, result, response.message());
txtvMessage.setText(message);
setTestRequired(!response.isSuccessful());
},
error -> {
String icon = "{fa-close}";
String result = context.getString(R.string.proxy_test_failed);
int color = ContextCompat.getColor(context, R.color.download_failed_red);
txtvMessage.setTextColor(color);
String message = String.format("%s %s: %s", icon, result, error.getMessage());
txtvMessage.setText(message);
setTestRequired(true);
}
);
}
}

View File

@ -94,11 +94,7 @@ public class RatingDialog {
long firstDate = mPreferences.getLong(KEY_FIRST_START_DATE, now); long firstDate = mPreferences.getLong(KEY_FIRST_START_DATE, now);
long diff = now - firstDate; long diff = now - firstDate;
long diffDays = TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS); long diffDays = TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS);
if (diffDays >= AFTER_DAYS) { return diffDays >= AFTER_DAYS;
return true;
} else {
return false;
}
} }
@Nullable @Nullable
@ -107,30 +103,16 @@ public class RatingDialog {
if(context == null) { if(context == null) {
return null; return null;
} }
MaterialDialog dialog = new MaterialDialog.Builder(context) return new MaterialDialog.Builder(context)
.title(R.string.rating_title) .title(R.string.rating_title)
.content(R.string.rating_message) .content(R.string.rating_message)
.positiveText(R.string.rating_now_label) .positiveText(R.string.rating_now_label)
.negativeText(R.string.rating_never_label) .negativeText(R.string.rating_never_label)
.neutralText(R.string.rating_later_label) .neutralText(R.string.rating_later_label)
.callback(new MaterialDialog.ButtonCallback() { .onPositive((dialog, which) -> rateNow())
@Override .onNegative((dialog, which) -> saveRated())
public void onPositive(MaterialDialog dialog) { .onNeutral((dialog, which) -> resetStartDate())
rateNow();
}
@Override
public void onNegative(MaterialDialog dialog) {
saveRated();
}
@Override
public void onNeutral(MaterialDialog dialog) {
resetStartDate();
}
})
.cancelListener(dialog1 -> resetStartDate()) .cancelListener(dialog1 -> resetStartDate())
.build(); .build();
return dialog;
} }
} }

View File

@ -1,17 +1,13 @@
package de.danoeh.antennapod.dialog; package de.danoeh.antennapod.dialog;
import android.app.Dialog;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.Editable; import android.text.Editable;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.Window;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.EditText; import android.widget.EditText;
import android.widget.Spinner; import android.widget.Spinner;
@ -58,14 +54,8 @@ public abstract class SleepTimerDialog {
builder.customView(R.layout.time_dialog, false); builder.customView(R.layout.time_dialog, false);
builder.positiveText(R.string.set_sleeptimer_label); builder.positiveText(R.string.set_sleeptimer_label);
builder.negativeText(R.string.cancel_label); builder.negativeText(R.string.cancel_label);
builder.callback(new MaterialDialog.ButtonCallback() { builder.onNegative((dialog, which) -> dialog.dismiss());
@Override builder.onPositive((dialog, which) -> {
public void onNegative(MaterialDialog dialog) {
dialog.dismiss();
}
@Override
public void onPositive(MaterialDialog dialog) {
try { try {
savePreferences(); savePreferences();
long input = readTimeMillis(); long input = readTimeMillis();
@ -77,7 +67,6 @@ public abstract class SleepTimerDialog {
Toast.LENGTH_LONG); Toast.LENGTH_LONG);
toast.show(); toast.show();
} }
}
}); });
dialog = builder.build(); dialog = builder.build();
@ -138,7 +127,7 @@ public abstract class SleepTimerDialog {
private long readTimeMillis() { private long readTimeMillis() {
TimeUnit selectedUnit = units[spTimeUnit.getSelectedItemPosition()]; TimeUnit selectedUnit = units[spTimeUnit.getSelectedItemPosition()];
long value = Long.valueOf(etxtTime.getText().toString()); long value = Long.parseLong(etxtTime.getText().toString());
return selectedUnit.toMillis(value); return selectedUnit.toMillis(value);
} }

View File

@ -102,8 +102,8 @@ public class VariableSpeedDialog {
builder.setPositiveButton(android.R.string.ok, builder.setPositiveButton(android.R.string.ok,
(dialog, which) -> { (dialog, which) -> {
int choiceCount = 0; int choiceCount = 0;
for (int i = 0; i < speedChecked.length; i++) { for (boolean checked : speedChecked) {
if (speedChecked[i]) { if (checked) {
choiceCount++; choiceCount++;
} }
} }

View File

@ -47,36 +47,18 @@ public class AddFeedFragment extends Fragment {
final MainActivity activity = (MainActivity) getActivity(); final MainActivity activity = (MainActivity) getActivity();
activity.getSupportActionBar().setTitle(R.string.add_feed_label); activity.getSupportActionBar().setTitle(R.string.add_feed_label);
butSearchITunes.setOnClickListener(new View.OnClickListener() { butSearchITunes.setOnClickListener(v -> activity.loadChildFragment(new ItunesSearchFragment()));
@Override
public void onClick(View v) {
activity.loadChildFragment(new ItunesSearchFragment());
}
});
butBrowserGpoddernet.setOnClickListener(new View.OnClickListener() { butBrowserGpoddernet.setOnClickListener(v -> activity.loadChildFragment(new GpodnetMainFragment()));
@Override
public void onClick(View v) {
activity.loadChildFragment(new GpodnetMainFragment());
}
});
butOpmlImport.setOnClickListener(new View.OnClickListener() { butOpmlImport.setOnClickListener(v -> startActivity(new Intent(getActivity(),
@Override OpmlImportFromPathActivity.class)));
public void onClick(View v) {
startActivity(new Intent(getActivity(),
OpmlImportFromPathActivity.class));
}
});
butConfirm.setOnClickListener(new View.OnClickListener() { butConfirm.setOnClickListener(v -> {
@Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), OnlineFeedViewActivity.class); Intent intent = new Intent(getActivity(), OnlineFeedViewActivity.class);
intent.putExtra(OnlineFeedViewActivity.ARG_FEEDURL, etxtFeedurl.getText().toString()); intent.putExtra(OnlineFeedViewActivity.ARG_FEEDURL, etxtFeedurl.getText().toString());
intent.putExtra(OnlineFeedViewActivity.ARG_TITLE, getString(R.string.add_feed_label)); intent.putExtra(OnlineFeedViewActivity.ARG_TITLE, getString(R.string.add_feed_label));
startActivity(intent); startActivity(intent);
}
}); });
return root; return root;

View File

@ -1,6 +1,5 @@
package de.danoeh.antennapod.fragment; package de.danoeh.antennapod.fragment;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.SharedPreferences; import android.content.SharedPreferences;
@ -24,7 +23,6 @@ import android.widget.Toast;
import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration; import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.activity.MainActivity;
@ -81,8 +79,6 @@ public class AllEpisodesFragment extends Fragment {
private boolean itemsLoaded = false; private boolean itemsLoaded = false;
private boolean viewsCreated = false; private boolean viewsCreated = false;
private AtomicReference<MainActivity> activity = new AtomicReference<MainActivity>();
private boolean isUpdatingFeeds; private boolean isUpdatingFeeds;
protected Subscription subscription; protected Subscription subscription;
@ -101,7 +97,6 @@ public class AllEpisodesFragment extends Fragment {
public void onStart() { public void onStart() {
super.onStart(); super.onStart();
EventDistributor.getInstance().register(contentUpdate); EventDistributor.getInstance().register(contentUpdate);
this.activity.set((MainActivity) getActivity());
if (viewsCreated && itemsLoaded) { if (viewsCreated && itemsLoaded) {
onFragmentLoaded(); onFragmentLoaded();
} }
@ -132,12 +127,6 @@ public class AllEpisodesFragment extends Fragment {
} }
} }
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
this.activity.set((MainActivity) getActivity());
}
@Override @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
@ -176,18 +165,13 @@ public class AllEpisodesFragment extends Fragment {
} }
protected void resetViewState() { protected void resetViewState() {
listAdapter = null;
activity.set(null);
viewsCreated = false; viewsCreated = false;
listAdapter = null;
} }
private final MenuItemUtils.UpdateRefreshMenuItemChecker updateRefreshMenuItemChecker = new MenuItemUtils.UpdateRefreshMenuItemChecker() { private final MenuItemUtils.UpdateRefreshMenuItemChecker updateRefreshMenuItemChecker =
@Override () -> DownloadService.isRunning && DownloadRequester.getInstance().isDownloadingFeeds();
public boolean isRefreshing() {
return DownloadService.isRunning && DownloadRequester.getInstance().isDownloadingFeeds();
}
};
@Override @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
@ -325,7 +309,7 @@ public class AllEpisodesFragment extends Fragment {
viewsCreated = true; viewsCreated = true;
if (itemsLoaded && activity.get() != null) { if (itemsLoaded) {
onFragmentLoaded(); onFragmentLoaded();
} }
@ -334,9 +318,10 @@ public class AllEpisodesFragment extends Fragment {
private void onFragmentLoaded() { private void onFragmentLoaded() {
if (listAdapter == null) { if (listAdapter == null) {
MainActivity mainActivity = activity.get(); MainActivity mainActivity = (MainActivity) getActivity();
listAdapter = new AllEpisodesRecycleAdapter(mainActivity, itemAccess, listAdapter = new AllEpisodesRecycleAdapter(mainActivity, itemAccess,
new DefaultActionButtonCallback(mainActivity), showOnlyNewEpisodes()); new DefaultActionButtonCallback(mainActivity), showOnlyNewEpisodes());
listAdapter.setHasStableIds(true);
recyclerView.setAdapter(listAdapter); recyclerView.setAdapter(listAdapter);
} }
listAdapter.notifyDataSetChanged(); listAdapter.notifyDataSetChanged();
@ -378,10 +363,7 @@ public class AllEpisodesFragment extends Fragment {
@Override @Override
public boolean isInQueue(FeedItem item) { public boolean isInQueue(FeedItem item) {
if (item != null) { return item != null && item.isTagged(FeedItem.TAG_QUEUE);
return item.isTagged(FeedItem.TAG_QUEUE);
}
return false;
} }
@Override @Override
@ -470,7 +452,7 @@ public class AllEpisodesFragment extends Fragment {
recyclerView.setVisibility(View.GONE); recyclerView.setVisibility(View.GONE);
progLoading.setVisibility(View.VISIBLE); progLoading.setVisibility(View.VISIBLE);
} }
subscription = Observable.fromCallable(() -> loadData()) subscription = Observable.fromCallable(this::loadData)
.subscribeOn(Schedulers.newThread()) .subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(data -> { .subscribe(data -> {
@ -479,7 +461,7 @@ public class AllEpisodesFragment extends Fragment {
if (data != null) { if (data != null) {
episodes = data; episodes = data;
itemsLoaded = true; itemsLoaded = true;
if (viewsCreated && activity.get() != null) { if (viewsCreated) {
onFragmentLoaded(); onFragmentLoaded();
} }
} }

View File

@ -2,6 +2,7 @@ package de.danoeh.antennapod.fragment;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.ListFragment; import android.support.v4.app.ListFragment;
import android.util.Log;
import android.view.View; import android.view.View;
import android.widget.ListView; import android.widget.ListView;
@ -15,15 +16,16 @@ import de.danoeh.antennapod.core.util.playback.PlaybackController;
public class ChaptersFragment extends ListFragment implements AudioplayerContentFragment { public class ChaptersFragment extends ListFragment implements AudioplayerContentFragment {
private static final String TAG = "ChaptersFragment";
private Playable media; private Playable media;
private PlaybackController controller; private PlaybackController controller;
private ChaptersListAdapter adapter; private ChaptersListAdapter adapter;
public static ChaptersFragment newInstance(Playable media, PlaybackController controller) { public static ChaptersFragment newInstance(Playable media) {
ChaptersFragment f = new ChaptersFragment(); ChaptersFragment f = new ChaptersFragment();
f.media = media; f.media = media;
f.controller = controller;
return f; return f;
} }
@ -37,6 +39,10 @@ public class ChaptersFragment extends ListFragment implements AudioplayerContent
lv.setPadding(0, vertPadding, 0, vertPadding); lv.setPadding(0, vertPadding, 0, vertPadding);
adapter = new ChaptersListAdapter(getActivity(), 0, pos -> { adapter = new ChaptersListAdapter(getActivity(), 0, pos -> {
if(controller == null) {
Log.d(TAG, "controller is null");
return;
}
Chapter chapter = (Chapter) getListAdapter().getItem(pos); Chapter chapter = (Chapter) getListAdapter().getItem(pos);
controller.seekToChapter(chapter); controller.seekToChapter(chapter);
}); });
@ -58,6 +64,7 @@ public class ChaptersFragment extends ListFragment implements AudioplayerContent
public void onDestroy() { public void onDestroy() {
super.onDestroy(); super.onDestroy();
adapter = null; adapter = null;
controller = null;
} }
@Override @Override
@ -68,10 +75,15 @@ public class ChaptersFragment extends ListFragment implements AudioplayerContent
this.media = media; this.media = media;
adapter.setMedia(media); adapter.setMedia(media);
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
if(media.getChapters() == null) { if(media == null || media.getChapters() == null || media.getChapters().size() == 0) {
setEmptyText(getString(R.string.no_items_label)); setEmptyText(getString(R.string.no_items_label));
} else { } else {
setEmptyText(null); setEmptyText(null);
} }
} }
public void setController(PlaybackController controller) {
this.controller = controller;
}
} }

View File

@ -1,12 +1,20 @@
package de.danoeh.antennapod.fragment; package de.danoeh.antennapod.fragment;
import android.app.Activity; import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.ListFragment; import android.support.v4.app.ListFragment;
import android.util.Log; import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.ListView; import android.widget.ListView;
import com.joanzapata.iconify.IconDrawable;
import com.joanzapata.iconify.fonts.FontAwesomeIcons;
import java.util.List; import java.util.List;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
@ -14,8 +22,10 @@ import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.adapter.DownloadedEpisodesListAdapter; import de.danoeh.antennapod.adapter.DownloadedEpisodesListAdapter;
import de.danoeh.antennapod.core.feed.EventDistributor; import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.dialog.EpisodesApplyActionFragment;
import rx.Observable; import rx.Observable;
import rx.Subscription; import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers; import rx.android.schedulers.AndroidSchedulers;
@ -28,8 +38,7 @@ public class CompletedDownloadsFragment extends ListFragment {
private static final String TAG = CompletedDownloadsFragment.class.getSimpleName(); private static final String TAG = CompletedDownloadsFragment.class.getSimpleName();
private static final int EVENTS = private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED |
EventDistributor.DOWNLOAD_HANDLED |
EventDistributor.DOWNLOADLOG_UPDATE | EventDistributor.DOWNLOADLOG_UPDATE |
EventDistributor.UNREAD_ITEMS_UPDATE; EventDistributor.UNREAD_ITEMS_UPDATE;
@ -37,13 +46,13 @@ public class CompletedDownloadsFragment extends ListFragment {
private DownloadedEpisodesListAdapter listAdapter; private DownloadedEpisodesListAdapter listAdapter;
private boolean viewCreated = false; private boolean viewCreated = false;
private boolean itemsLoaded = false;
private Subscription subscription; private Subscription subscription;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
loadItems(); loadItems();
} }
@ -81,9 +90,9 @@ public class CompletedDownloadsFragment extends ListFragment {
} }
@Override @Override
public void onAttach(Activity activity) { public void onAttach(Context context) {
super.onAttach(activity); super.onAttach(context);
if (viewCreated && itemsLoaded) { if (viewCreated && items != null) {
onFragmentLoaded(); onFragmentLoaded();
} }
} }
@ -99,7 +108,7 @@ public class CompletedDownloadsFragment extends ListFragment {
lv.setPadding(0, vertPadding, 0, vertPadding); lv.setPadding(0, vertPadding, 0, vertPadding);
viewCreated = true; viewCreated = true;
if (itemsLoaded && getActivity() != null) { if (items != null && getActivity() != null) {
onFragmentLoaded(); onFragmentLoaded();
} }
} }
@ -111,7 +120,6 @@ public class CompletedDownloadsFragment extends ListFragment {
if (item != null) { if (item != null) {
((MainActivity) getActivity()).loadChildFragment(ItemFragment.newInstance(item.getId())); ((MainActivity) getActivity()).loadChildFragment(ItemFragment.newInstance(item.getId()));
} }
} }
private void onFragmentLoaded() { private void onFragmentLoaded() {
@ -121,6 +129,43 @@ public class CompletedDownloadsFragment extends ListFragment {
} }
setListShown(true); setListShown(true);
listAdapter.notifyDataSetChanged(); listAdapter.notifyDataSetChanged();
getActivity().supportInvalidateOptionsMenu();
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
if(!isAdded()) {
return;
}
super.onCreateOptionsMenu(menu, inflater);
if(items != null) {
inflater.inflate(R.menu.downloads_completed, menu);
MenuItem episodeActions = menu.findItem(R.id.episode_actions);
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);
}
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.episode_actions:
EpisodesApplyActionFragment fragment = EpisodesApplyActionFragment
.newInstance(items, EpisodesApplyActionFragment.ACTION_REMOVE);
((MainActivity) getActivity()).loadChildFragment(fragment);
return true;
default:
return false;
}
} }
private DownloadedEpisodesListAdapter.ItemAccess itemAccess = new DownloadedEpisodesListAdapter.ItemAccess() { private DownloadedEpisodesListAdapter.ItemAccess itemAccess = new DownloadedEpisodesListAdapter.ItemAccess() {
@ -157,16 +202,15 @@ public class CompletedDownloadsFragment extends ListFragment {
if(subscription != null) { if(subscription != null) {
subscription.unsubscribe(); subscription.unsubscribe();
} }
if (!itemsLoaded && viewCreated) { if (items == null && viewCreated) {
setListShown(false); setListShown(false);
} }
subscription = Observable.fromCallable(() -> DBReader.getDownloadedItems()) subscription = Observable.fromCallable(DBReader::getDownloadedItems)
.subscribeOn(Schedulers.newThread()) .subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> { .subscribe(result -> {
if (result != null) { if (result != null) {
items = result; items = result;
itemsLoaded = true;
if (viewCreated && getActivity() != null) { if (viewCreated && getActivity() != null) {
onFragmentLoaded(); onFragmentLoaded();
} }

View File

@ -63,12 +63,7 @@ public class CoverFragment extends Fragment implements AudioplayerContentFragmen
} }
private void loadMediaInfo() { private void loadMediaInfo() {
if(imgvCover == null) {
return;
}
if (media != null) { if (media != null) {
Log.d(TAG, "feed title: " + media.getFeedTitle());
Log.d(TAG, "episode title: " + media.getEpisodeTitle());
txtvPodcastTitle.setText(media.getFeedTitle()); txtvPodcastTitle.setText(media.getFeedTitle());
txtvEpisodeTitle.setText(media.getEpisodeTitle()); txtvEpisodeTitle.setText(media.getEpisodeTitle());
Glide.with(this) Glide.with(this)
@ -103,7 +98,7 @@ public class CoverFragment extends Fragment implements AudioplayerContentFragmen
@Override @Override
public void onMediaChanged(Playable media) { public void onMediaChanged(Playable media) {
if(this.media == media) { if(!isAdded() || this.media == media) {
return; return;
} }
this.media = media; this.media = media;

View File

@ -154,7 +154,7 @@ public class DownloadLogFragment extends ListFragment {
if(subscription != null) { if(subscription != null) {
subscription.unsubscribe(); subscription.unsubscribe();
} }
subscription = Observable.fromCallable(() -> DBReader.getDownloadLog()) subscription = Observable.fromCallable(DBReader::getDownloadLog)
.subscribeOn(Schedulers.newThread()) .subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> { .subscribe(result -> {

View File

@ -5,7 +5,6 @@ import android.support.v4.app.Fragment;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
@ -53,17 +52,13 @@ public class ExternalPlayerFragment extends Fragment {
mFeedName = (TextView) root.findViewById(R.id.txtvAuthor); mFeedName = (TextView) root.findViewById(R.id.txtvAuthor);
mProgressBar = (ProgressBar) root.findViewById(R.id.episodeProgress); mProgressBar = (ProgressBar) root.findViewById(R.id.episodeProgress);
fragmentLayout.setOnClickListener(new OnClickListener() { fragmentLayout.setOnClickListener(v -> {
@Override
public void onClick(View v) {
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( startActivity(PlaybackService.getPlayerActivityIntent(
getActivity(), controller.getMedia())); getActivity(), controller.getMedia()));
} }
}
}); });
return root; return root;
} }
@ -72,7 +67,11 @@ public class ExternalPlayerFragment extends Fragment {
public void onActivityCreated(Bundle savedInstanceState) { public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState); super.onActivityCreated(savedInstanceState);
controller = setupPlaybackController(); controller = setupPlaybackController();
butPlay.setOnClickListener(controller.newOnPlayButtonClickListener()); butPlay.setOnClickListener(v -> {
if(controller != null) {
controller.playPause();
}
});
} }
private PlaybackController setupPlaybackController() { private PlaybackController setupPlaybackController() {
@ -88,7 +87,6 @@ public class ExternalPlayerFragment extends Fragment {
return butPlay; return butPlay;
} }
@Override @Override
public boolean loadMediaInfo() { public boolean loadMediaInfo() {
ExternalPlayerFragment fragment = ExternalPlayerFragment.this; ExternalPlayerFragment fragment = ExternalPlayerFragment.this;
@ -145,8 +143,11 @@ public class ExternalPlayerFragment extends Fragment {
} }
controller = setupPlaybackController(); controller = setupPlaybackController();
if (butPlay != null) { if (butPlay != null) {
butPlay.setOnClickListener(controller butPlay.setOnClickListener(v -> {
.newOnPlayButtonClickListener()); if(controller != null) {
controller.playPause();
}
});
} }
controller.init(); controller.init();
} }

View File

@ -62,7 +62,6 @@ public class ItemDescriptionFragment extends Fragment implements AudioplayerCont
private static final String ARG_HIGHLIGHT_TIMECODES = "arg.highlightTimecodes"; private static final String ARG_HIGHLIGHT_TIMECODES = "arg.highlightTimecodes";
private WebView webvDescription; private WebView webvDescription;
private String webvData;
private ShownotesProvider shownotesProvider; private ShownotesProvider shownotesProvider;
private Playable media; private Playable media;
@ -112,7 +111,7 @@ public class ItemDescriptionFragment extends Fragment implements AudioplayerCont
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
Log.d(TAG, "Creating view"); Log.d(TAG, "Creating view");
webvDescription = new WebView(getActivity()); webvDescription = new WebView(getActivity().getApplicationContext());
if (Build.VERSION.SDK_INT >= 11) { if (Build.VERSION.SDK_INT >= 11) {
webvDescription.setLayerType(View.LAYER_TYPE_SOFTWARE, null); webvDescription.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
} }
@ -149,7 +148,7 @@ public class ItemDescriptionFragment extends Fragment implements AudioplayerCont
super.onPageFinished(view, url); super.onPageFinished(view, url);
Log.d(TAG, "Page finished"); Log.d(TAG, "Page finished");
// Restoring the scroll position might not always work // Restoring the scroll position might not always work
view.postDelayed(() -> restoreFromPreference(), 50); view.postDelayed(ItemDescriptionFragment.this::restoreFromPreference, 50);
} }
}); });
@ -309,7 +308,6 @@ public class ItemDescriptionFragment extends Fragment implements AudioplayerCont
.subscribeOn(Schedulers.newThread()) .subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(data -> { .subscribe(data -> {
webvData = data;
webvDescription.loadDataWithBaseURL(null, data, "text/html", webvDescription.loadDataWithBaseURL(null, data, "text/html",
"utf-8", "about:blank"); "utf-8", "about:blank");
Log.d(TAG, "Webview loaded"); Log.d(TAG, "Webview loaded");
@ -320,8 +318,7 @@ public class ItemDescriptionFragment extends Fragment implements AudioplayerCont
private String loadData() { private String loadData() {
Timeline timeline = new Timeline(getActivity(), shownotesProvider); Timeline timeline = new Timeline(getActivity(), shownotesProvider);
String data = timeline.processShownotes(highlightTimecodes); return timeline.processShownotes(highlightTimecodes);
return data;
} }
@Override @Override
@ -384,7 +381,7 @@ public class ItemDescriptionFragment extends Fragment implements AudioplayerCont
@Override @Override
public void onMediaChanged(Playable media) { public void onMediaChanged(Playable media) {
if(this.media == media) { if(this.media == media || webvDescription == null) {
return; return;
} }
this.media = media; this.media = media;

View File

@ -9,6 +9,7 @@ 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.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.view.ContextMenu; import android.view.ContextMenu;
@ -101,6 +102,7 @@ public class ItemFragment extends Fragment {
private ViewGroup root; private ViewGroup root;
private WebView webvDescription; private WebView webvDescription;
private TextView txtvPodcast;
private TextView txtvTitle; private TextView txtvTitle;
private TextView txtvDuration; private TextView txtvDuration;
private TextView txtvPublished; private TextView txtvPublished;
@ -134,6 +136,7 @@ public class ItemFragment extends Fragment {
View layout = inflater.inflate(R.layout.feeditem_fragment, container, false); View layout = inflater.inflate(R.layout.feeditem_fragment, container, false);
root = (ViewGroup) layout.findViewById(R.id.content_root); root = (ViewGroup) layout.findViewById(R.id.content_root);
txtvPodcast = (TextView) layout.findViewById(R.id.txtvPodcast);
txtvTitle = (TextView) layout.findViewById(R.id.txtvTitle); txtvTitle = (TextView) layout.findViewById(R.id.txtvTitle);
txtvDuration = (TextView) layout.findViewById(R.id.txtvDuration); txtvDuration = (TextView) layout.findViewById(R.id.txtvDuration);
txtvPublished = (TextView) layout.findViewById(R.id.txtvPublished); txtvPublished = (TextView) layout.findViewById(R.id.txtvPublished);
@ -146,8 +149,7 @@ public class ItemFragment extends Fragment {
&& Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { && Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
webvDescription.setLayerType(View.LAYER_TYPE_SOFTWARE, null); webvDescription.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
} }
webvDescription.setBackgroundColor(getResources().getColor( webvDescription.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.black));
R.color.black));
} }
webvDescription.getSettings().setUseWideViewPort(false); webvDescription.getSettings().setUseWideViewPort(false);
webvDescription.getSettings().setLayoutAlgorithm( webvDescription.getSettings().setLayoutAlgorithm(
@ -219,6 +221,7 @@ public class ItemFragment extends Fragment {
EventDistributor.getInstance().register(contentUpdate); EventDistributor.getInstance().register(contentUpdate);
EventBus.getDefault().registerSticky(this); EventBus.getDefault().registerSticky(this);
if(itemsLoaded) { if(itemsLoaded) {
progbarLoading.setVisibility(View.GONE);
updateAppearance(); updateAppearance();
} }
} }
@ -295,6 +298,7 @@ public class ItemFragment extends Fragment {
return; return;
} }
getActivity().supportInvalidateOptionsMenu(); getActivity().supportInvalidateOptionsMenu();
txtvPodcast.setText(item.getFeed().getTitle());
txtvTitle.setText(item.getTitle()); txtvTitle.setText(item.getTitle());
if (item.getPubDate() != null) { if (item.getPubDate() != null) {
@ -503,7 +507,7 @@ public class ItemFragment extends Fragment {
if(subscription != null) { if(subscription != null) {
subscription.unsubscribe(); subscription.unsubscribe();
} }
subscription = Observable.fromCallable(() -> loadInBackground()) subscription = Observable.fromCallable(this::loadInBackground)
.subscribeOn(Schedulers.newThread()) .subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> { .subscribe(result -> {

View File

@ -185,11 +185,7 @@ public class ItemlistFragment extends ListFragment {
private final MenuItemUtils.UpdateRefreshMenuItemChecker updateRefreshMenuItemChecker = new MenuItemUtils.UpdateRefreshMenuItemChecker() { private final MenuItemUtils.UpdateRefreshMenuItemChecker updateRefreshMenuItemChecker = new MenuItemUtils.UpdateRefreshMenuItemChecker() {
@Override @Override
public boolean isRefreshing() { public boolean isRefreshing() {
if (feed != null && DownloadService.isRunning && DownloadRequester.getInstance().isDownloadingFile(feed)) { return feed != null && DownloadService.isRunning && DownloadRequester.getInstance().isDownloadingFile(feed);
return true;
} else {
return false;
}
} }
}; };
@ -252,8 +248,8 @@ public class ItemlistFragment extends ListFragment {
if (!FeedMenuHandler.onOptionsItemClicked(getActivity(), item, feed)) { if (!FeedMenuHandler.onOptionsItemClicked(getActivity(), item, feed)) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.episode_actions: case R.id.episode_actions:
EpisodesApplyActionFragment fragment = new EpisodesApplyActionFragment(); EpisodesApplyActionFragment fragment = EpisodesApplyActionFragment
fragment.setEpisodes(feed.getItems()); .newInstance(feed.getItems());
((MainActivity)getActivity()).loadChildFragment(fragment); ((MainActivity)getActivity()).loadChildFragment(fragment);
return true; return true;
case R.id.remove_item: case R.id.remove_item:
@ -405,7 +401,6 @@ public class ItemlistFragment extends ListFragment {
public void onEventMainThread(FeedItemEvent event) { public void onEventMainThread(FeedItemEvent event) {
Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]"); Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
boolean queueChanged = false;
if(feed == null || feed.getItems() == null || adapter == null) { if(feed == null || feed.getItems() == null || adapter == null) {
return; return;
} }
@ -628,7 +623,7 @@ public class ItemlistFragment extends ListFragment {
if(subscription != null) { if(subscription != null) {
subscription.unsubscribe(); subscription.unsubscribe();
} }
subscription = Observable.fromCallable(() -> loadData()) subscription = Observable.fromCallable(this::loadData)
.subscribeOn(Schedulers.newThread()) .subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> { .subscribe(result -> {

View File

@ -124,7 +124,7 @@ public class ItunesSearchFragment extends Fragment {
} else { } else {
gridView.setVisibility(View.GONE); gridView.setVisibility(View.GONE);
progressBar.setVisibility(View.VISIBLE); progressBar.setVisibility(View.VISIBLE);
rx.Observable.create((Observable.OnSubscribe<String>) subscriber -> { subscription = Observable.create((Observable.OnSubscribe<String>) subscriber -> {
OkHttpClient client = AntennapodHttpClient.getHttpClient(); OkHttpClient client = AntennapodHttpClient.getHttpClient();
Request.Builder httpReq = new Request.Builder() Request.Builder httpReq = new Request.Builder()
.url(podcast.feedUrl) .url(podcast.feedUrl)
@ -233,7 +233,7 @@ public class ItunesSearchFragment extends Fragment {
butRetry.setVisibility(View.GONE); butRetry.setVisibility(View.GONE);
txtvEmpty.setVisibility(View.GONE); txtvEmpty.setVisibility(View.GONE);
progressBar.setVisibility(View.VISIBLE); progressBar.setVisibility(View.VISIBLE);
subscription = rx.Observable.create((Observable.OnSubscribe<List<Podcast>>) subscriber -> { subscription = Observable.create((Observable.OnSubscribe<List<Podcast>>) subscriber -> {
String lang = Locale.getDefault().getLanguage(); String lang = Locale.getDefault().getLanguage();
String url = "https://itunes.apple.com/" + lang + "/rss/toppodcasts/limit=25/explicit=true/json"; String url = "https://itunes.apple.com/" + lang + "/rss/toppodcasts/limit=25/explicit=true/json";
OkHttpClient client = AntennapodHttpClient.getHttpClient(); OkHttpClient client = AntennapodHttpClient.getHttpClient();

View File

@ -220,7 +220,7 @@ public class PlaybackHistoryFragment extends ListFragment {
private FeedItemlistAdapter.ItemAccess itemAccess = new FeedItemlistAdapter.ItemAccess() { private FeedItemlistAdapter.ItemAccess itemAccess = new FeedItemlistAdapter.ItemAccess() {
@Override @Override
public boolean isInQueue(FeedItem item) { public boolean isInQueue(FeedItem item) {
return (queue != null) ? queue.contains(item.getId()) : false; return (queue != null) && queue.contains(item.getId());
} }
@Override @Override
@ -255,7 +255,7 @@ public class PlaybackHistoryFragment extends ListFragment {
if(subscription != null) { if(subscription != null) {
subscription.unsubscribe(); subscription.unsubscribe();
} }
subscription = Observable.fromCallable(() -> loadData()) subscription = Observable.fromCallable(this::loadData)
.subscribeOn(Schedulers.newThread()) .subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> { .subscribe(result -> {

View File

@ -230,9 +230,8 @@ public class QueueFragment extends Fragment {
resetViewState(); resetViewState();
} }
private final MenuItemUtils.UpdateRefreshMenuItemChecker updateRefreshMenuItemChecker = () -> { private final MenuItemUtils.UpdateRefreshMenuItemChecker updateRefreshMenuItemChecker =
return DownloadService.isRunning && DownloadRequester.getInstance().isDownloadingFeeds(); () -> DownloadService.isRunning && DownloadRequester.getInstance().isDownloadingFeeds();
};
@Override @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
@ -415,7 +414,7 @@ public class QueueFragment extends Fragment {
Snackbar snackbar = Snackbar.make(root, getString(R.string.marked_as_read_label), Snackbar.LENGTH_LONG); Snackbar snackbar = Snackbar.make(root, getString(R.string.marked_as_read_label), Snackbar.LENGTH_LONG);
snackbar.setAction(getString(R.string.undo), v -> { snackbar.setAction(getString(R.string.undo), v -> {
DBWriter.addQueueItemAt(getActivity(), item.getId(), position, false); DBWriter.addQueueItemAt(getActivity(), item.getId(), position, false);
if(false == isRead) { if(!isRead) {
DBWriter.markItemPlayed(FeedItem.UNPLAYED, item.getId()); DBWriter.markItemPlayed(FeedItem.UNPLAYED, item.getId());
} }
}); });
@ -424,12 +423,12 @@ public class QueueFragment extends Fragment {
@Override @Override
public boolean isLongPressDragEnabled() { public boolean isLongPressDragEnabled() {
return false == UserPreferences.isQueueLocked(); return !UserPreferences.isQueueLocked();
} }
@Override @Override
public boolean isItemViewSwipeEnabled() { public boolean isItemViewSwipeEnabled() {
return false == UserPreferences.isQueueLocked(); return !UserPreferences.isQueueLocked();
} }
@Override @Override
@ -474,6 +473,7 @@ public class QueueFragment extends Fragment {
MainActivity activity = (MainActivity) getActivity(); MainActivity activity = (MainActivity) getActivity();
recyclerAdapter = new QueueRecyclerAdapter(activity, itemAccess, recyclerAdapter = new QueueRecyclerAdapter(activity, itemAccess,
new DefaultActionButtonCallback(activity), itemTouchHelper); new DefaultActionButtonCallback(activity), itemTouchHelper);
recyclerAdapter.setHasStableIds(true);
recyclerView.setAdapter(recyclerAdapter); recyclerView.setAdapter(recyclerAdapter);
} }
if(queue == null || queue.size() == 0) { if(queue == null || queue.size() == 0) {
@ -607,7 +607,7 @@ public class QueueFragment extends Fragment {
txtvEmpty.setVisibility(View.GONE); txtvEmpty.setVisibility(View.GONE);
progLoading.setVisibility(View.VISIBLE); progLoading.setVisibility(View.VISIBLE);
} }
subscription = Observable.fromCallable(() -> DBReader.getQueue()) subscription = Observable.fromCallable(DBReader::getQueue)
.subscribeOn(Schedulers.newThread()) .subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(items -> { .subscribe(items -> {

View File

@ -208,7 +208,7 @@ public class SearchFragment extends ListFragment {
if (viewCreated && !itemsLoaded) { if (viewCreated && !itemsLoaded) {
setListShown(false); setListShown(false);
} }
subscription = Observable.fromCallable(() -> performSearch()) subscription = Observable.fromCallable(this::performSearch)
.subscribeOn(Schedulers.newThread()) .subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> { .subscribe(result -> {

View File

@ -14,7 +14,6 @@ import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button; import android.widget.Button;
import android.widget.GridView; import android.widget.GridView;
import android.widget.ProgressBar; import android.widget.ProgressBar;
@ -84,18 +83,9 @@ public abstract class PodcastListFragment extends Fragment {
txtvError = (TextView) root.findViewById(R.id.txtvError); txtvError = (TextView) root.findViewById(R.id.txtvError);
butRetry = (Button) root.findViewById(R.id.butRetry); butRetry = (Button) root.findViewById(R.id.butRetry);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() { gridView.setOnItemClickListener((parent, view, position, id) ->
@Override onPodcastSelected((GpodnetPodcast) gridView.getAdapter().getItem(position)));
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { butRetry.setOnClickListener(v -> loadData());
onPodcastSelected((GpodnetPodcast) gridView.getAdapter().getItem(position));
}
});
butRetry.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
loadData();
}
});
loadData(); loadData();
return root; return root;

View File

@ -1,13 +1,13 @@
package de.danoeh.antennapod.fragment.gpodnet; package de.danoeh.antennapod.fragment.gpodnet;
import java.util.Collections;
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.GpodnetPodcast; import de.danoeh.antennapod.core.gpoddernet.model.GpodnetPodcast;
import de.danoeh.antennapod.core.preferences.GpodnetPreferences; import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
import java.util.ArrayList;
import java.util.List;
/** /**
* Displays suggestions from gpodder.net * Displays suggestions from gpodder.net
*/ */
@ -20,7 +20,7 @@ public class SuggestionListFragment extends PodcastListFragment {
service.authenticate(GpodnetPreferences.getUsername(), GpodnetPreferences.getPassword()); service.authenticate(GpodnetPreferences.getUsername(), GpodnetPreferences.getPassword());
return service.getSuggestions(SUGGESTIONS_COUNT); return service.getSuggestions(SUGGESTIONS_COUNT);
} else { } else {
return new ArrayList<GpodnetPodcast>(); return Collections.emptyList();
} }
} }
} }

View File

@ -11,7 +11,6 @@ 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.TextView; import android.widget.TextView;
import java.util.List; import java.util.List;
@ -65,13 +64,10 @@ public class TagListFragment extends ListFragment {
public void onViewCreated(View view, Bundle savedInstanceState) { public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() { getListView().setOnItemClickListener((parent, view1, position, id) -> {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
GpodnetTag tag = (GpodnetTag) getListAdapter().getItem(position); GpodnetTag tag = (GpodnetTag) getListAdapter().getItem(position);
MainActivity activity = (MainActivity) getActivity(); MainActivity activity = (MainActivity) getActivity();
activity.loadChildFragment(TagFragment.newInstance(tag)); activity.loadChildFragment(TagFragment.newInstance(tag));
}
}); });
startLoadTask(); startLoadTask();

View File

@ -41,7 +41,7 @@ public class FeedItemMenuHandler {
* menu-object and call setVisibility(visibility) on the returned * menu-object and call setVisibility(visibility) on the returned
* MenuItem object. * MenuItem object.
*/ */
abstract void setItemVisibility(int id, boolean visible); void setItemVisibility(int id, boolean visible);
} }
/** /**
@ -98,7 +98,7 @@ public class FeedItemMenuHandler {
mi.setItemVisibility(R.id.share_download_url_item, false); mi.setItemVisibility(R.id.share_download_url_item, false);
mi.setItemVisibility(R.id.share_download_url_with_position_item, false); mi.setItemVisibility(R.id.share_download_url_with_position_item, false);
} }
if(false == hasMedia || selectedItem.getMedia().getPosition() <= 0) { if(!hasMedia || selectedItem.getMedia().getPosition() <= 0) {
mi.setItemVisibility(R.id.share_link_with_position_item, false); mi.setItemVisibility(R.id.share_link_with_position_item, false);
mi.setItemVisibility(R.id.share_download_url_with_position_item, false); mi.setItemVisibility(R.id.share_download_url_with_position_item, false);
} }
@ -113,7 +113,7 @@ public class FeedItemMenuHandler {
mi.setItemVisibility(R.id.reset_position, false); mi.setItemVisibility(R.id.reset_position, false);
} }
if(false == UserPreferences.isEnableAutodownload()) { if(!UserPreferences.isEnableAutodownload()) {
mi.setItemVisibility(R.id.activate_auto_download, false); mi.setItemVisibility(R.id.activate_auto_download, false);
mi.setItemVisibility(R.id.deactivate_auto_download, false); mi.setItemVisibility(R.id.deactivate_auto_download, false);
} else if(selectedItem.getAutoDownload()) { } else if(selectedItem.getAutoDownload()) {
@ -224,7 +224,7 @@ public class FeedItemMenuHandler {
context.startActivity(intent); context.startActivity(intent);
} else { } else {
Toast.makeText(context, context.getString(R.string.download_error_malformed_url), Toast.makeText(context, context.getString(R.string.download_error_malformed_url),
Toast.LENGTH_SHORT); Toast.LENGTH_SHORT).show();
} }
break; break;
case R.id.support_item: case R.id.support_item:

View File

@ -63,10 +63,10 @@ public class FeedMenuHandler {
final Feed selectedFeed) throws DownloadRequestException { final Feed selectedFeed) throws DownloadRequestException {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.refresh_item: case R.id.refresh_item:
DBTasks.refreshFeed(context, selectedFeed); DBTasks.forceRefreshFeed(context, selectedFeed);
break; break;
case R.id.refresh_complete_item: case R.id.refresh_complete_item:
DBTasks.refreshCompleteFeed(context, selectedFeed); DBTasks.forceRefreshCompleteFeed(context, selectedFeed);
break; break;
case R.id.filter_items: case R.id.filter_items:
showFilterDialog(context, selectedFeed); showFilterDialog(context, selectedFeed);
@ -92,7 +92,7 @@ public class FeedMenuHandler {
context.startActivity(intent); context.startActivity(intent);
} else { } else {
Toast.makeText(context, context.getString(R.string.download_error_malformed_url), Toast.makeText(context, context.getString(R.string.download_error_malformed_url),
Toast.LENGTH_SHORT); Toast.LENGTH_SHORT).show();
} }
break; break;
case R.id.support_item: case R.id.support_item:

View File

@ -39,6 +39,7 @@ public class MenuItemUtils extends de.danoeh.antennapod.core.menuhandler.MenuIte
queueLock.setTitle(de.danoeh.antennapod.R.string.lock_queue); queueLock.setTitle(de.danoeh.antennapod.R.string.lock_queue);
queueLock.setIcon(ta.getDrawable(1)); queueLock.setIcon(ta.getDrawable(1));
} }
ta.recycle();
} }
} }

View File

@ -5,5 +5,5 @@ package de.danoeh.antennapod.menuhandler;
*/ */
public interface NavDrawerActivity { public interface NavDrawerActivity {
public boolean isDrawerOpen(); boolean isDrawerOpen();
} }

View File

@ -1,12 +1,14 @@
package de.danoeh.antennapod.preferences; package de.danoeh.antennapod.preferences;
import android.Manifest;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
import android.app.TimePickerDialog; import android.app.TimePickerDialog;
import android.content.ActivityNotFoundException;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
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.Resources; import android.content.res.Resources;
import android.net.Uri; import android.net.Uri;
import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiConfiguration;
@ -18,6 +20,7 @@ import android.preference.ListPreference;
import android.preference.Preference; import android.preference.Preference;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.preference.PreferenceScreen; import android.preference.PreferenceScreen;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.text.Editable; import android.text.Editable;
@ -47,15 +50,18 @@ import de.danoeh.antennapod.activity.DirectoryChooserActivity;
import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.activity.PreferenceActivity; import de.danoeh.antennapod.activity.PreferenceActivity;
import de.danoeh.antennapod.activity.PreferenceActivityGingerbread; import de.danoeh.antennapod.activity.PreferenceActivityGingerbread;
import de.danoeh.antennapod.activity.StatisticsActivity;
import de.danoeh.antennapod.asynctask.OpmlExportWorker; import de.danoeh.antennapod.asynctask.OpmlExportWorker;
import de.danoeh.antennapod.core.preferences.GpodnetPreferences; import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.GpodnetSyncService;
import de.danoeh.antennapod.core.util.Converter; import de.danoeh.antennapod.core.util.Converter;
import de.danoeh.antennapod.core.util.StorageUtils; import de.danoeh.antennapod.core.util.StorageUtils;
import de.danoeh.antennapod.core.util.flattr.FlattrUtils; import de.danoeh.antennapod.core.util.flattr.FlattrUtils;
import de.danoeh.antennapod.dialog.AuthenticationDialog; import de.danoeh.antennapod.dialog.AuthenticationDialog;
import de.danoeh.antennapod.dialog.AutoFlattrPreferenceDialog; import de.danoeh.antennapod.dialog.AutoFlattrPreferenceDialog;
import de.danoeh.antennapod.dialog.GpodnetSetHostnameDialog; import de.danoeh.antennapod.dialog.GpodnetSetHostnameDialog;
import de.danoeh.antennapod.dialog.ProxyDialog;
import de.danoeh.antennapod.dialog.VariableSpeedDialog; import de.danoeh.antennapod.dialog.VariableSpeedDialog;
/** /**
@ -71,20 +77,31 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
public static final String PREF_FLATTR_REVOKE = "prefRevokeAccess"; public static final String PREF_FLATTR_REVOKE = "prefRevokeAccess";
public static final String PREF_AUTO_FLATTR_PREFS = "prefAutoFlattrPrefs"; public static final String PREF_AUTO_FLATTR_PREFS = "prefAutoFlattrPrefs";
public static final String PREF_OPML_EXPORT = "prefOpmlExport"; public static final String PREF_OPML_EXPORT = "prefOpmlExport";
public static final String STATISTICS = "statistics";
public static final String PREF_ABOUT = "prefAbout"; public static final String PREF_ABOUT = "prefAbout";
public static final String PREF_CHOOSE_DATA_DIR = "prefChooseDataDir"; public static final String PREF_CHOOSE_DATA_DIR = "prefChooseDataDir";
public static final String AUTO_DL_PREF_SCREEN = "prefAutoDownloadSettings"; public static final String AUTO_DL_PREF_SCREEN = "prefAutoDownloadSettings";
public static final String PREF_PLAYBACK_SPEED_LAUNCHER = "prefPlaybackSpeedLauncher"; public static final String PREF_PLAYBACK_SPEED_LAUNCHER = "prefPlaybackSpeedLauncher";
public static final String PREF_GPODNET_LOGIN = "pref_gpodnet_authenticate"; public static final String PREF_GPODNET_LOGIN = "pref_gpodnet_authenticate";
public static final String PREF_GPODNET_SETLOGIN_INFORMATION = "pref_gpodnet_setlogin_information"; public static final String PREF_GPODNET_SETLOGIN_INFORMATION = "pref_gpodnet_setlogin_information";
public static final String PREF_GPODNET_SYNC = "pref_gpodnet_sync";
public static final String PREF_GPODNET_LOGOUT = "pref_gpodnet_logout"; public static final String PREF_GPODNET_LOGOUT = "pref_gpodnet_logout";
public static final String PREF_GPODNET_HOSTNAME = "pref_gpodnet_hostname"; public static final String PREF_GPODNET_HOSTNAME = "pref_gpodnet_hostname";
public static final String PREF_EXPANDED_NOTIFICATION = "prefExpandNotify"; public static final String PREF_EXPANDED_NOTIFICATION = "prefExpandNotify";
public static final String PREF_PROXY = "prefProxy";
public static final String PREF_KNOWN_ISSUES = "prefKnownIssues";
public static final String PREF_FAQ = "prefFaq";
public static final String PREF_SEND_CRASH_REPORT = "prefSendCrashReport";
private final PreferenceUI ui; private final PreferenceUI ui;
private CheckBoxPreference[] selectedNetworks; private CheckBoxPreference[] selectedNetworks;
private static final String[] EXTERNAL_STORAGE_PERMISSIONS = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE };
private static final int PERMISSION_REQUEST_EXTERNAL_STORAGE = 41;
public PreferenceController(PreferenceUI ui) { public PreferenceController(PreferenceUI ui) {
this.ui = ui; this.ui = ui;
PreferenceManager.getDefaultSharedPreferences(ui.getActivity().getApplicationContext()) PreferenceManager.getDefaultSharedPreferences(ui.getActivity().getApplicationContext())
@ -121,61 +138,62 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
// disable expanded notification option on unsupported android versions // disable expanded notification option on unsupported android versions
ui.findPreference(PreferenceController.PREF_EXPANDED_NOTIFICATION).setEnabled(false); ui.findPreference(PreferenceController.PREF_EXPANDED_NOTIFICATION).setEnabled(false);
ui.findPreference(PreferenceController.PREF_EXPANDED_NOTIFICATION).setOnPreferenceClickListener( ui.findPreference(PreferenceController.PREF_EXPANDED_NOTIFICATION).setOnPreferenceClickListener(
new Preference.OnPreferenceClickListener() { preference -> {
Toast toast = Toast.makeText(activity,
@Override R.string.pref_expand_notify_unsupport_toast, Toast.LENGTH_SHORT);
public boolean onPreferenceClick(Preference preference) {
Toast toast = Toast.makeText(activity, R.string.pref_expand_notify_unsupport_toast, Toast.LENGTH_SHORT);
toast.show(); toast.show();
return true; return true;
} }
}
); );
} }
ui.findPreference(PreferenceController.PREF_FLATTR_REVOKE).setOnPreferenceClickListener( ui.findPreference(PreferenceController.PREF_FLATTR_REVOKE).setOnPreferenceClickListener(
new Preference.OnPreferenceClickListener() { preference -> {
@Override
public boolean onPreferenceClick(Preference preference) {
FlattrUtils.revokeAccessToken(activity); FlattrUtils.revokeAccessToken(activity);
checkItemVisibility(); checkItemVisibility();
return true; return true;
} }
}
); );
ui.findPreference(PreferenceController.PREF_ABOUT).setOnPreferenceClickListener( ui.findPreference(PreferenceController.PREF_ABOUT).setOnPreferenceClickListener(
new Preference.OnPreferenceClickListener() { preference -> {
activity.startActivity(new Intent(activity, AboutActivity.class));
@Override
public boolean onPreferenceClick(Preference preference) {
activity.startActivity(new Intent(
activity, AboutActivity.class));
return true; return true;
} }
}
); );
ui.findPreference(PreferenceController.STATISTICS).setOnPreferenceClickListener(
ui.findPreference(PreferenceController.PREF_OPML_EXPORT).setOnPreferenceClickListener( preference -> {
new Preference.OnPreferenceClickListener() { activity.startActivity(new Intent(activity, StatisticsActivity.class));
@Override
public boolean onPreferenceClick(Preference preference) {
new OpmlExportWorker(activity)
.executeAsync();
return true; return true;
} }
);
ui.findPreference(PreferenceController.PREF_OPML_EXPORT).setOnPreferenceClickListener(
preference -> {
new OpmlExportWorker(activity).executeAsync();
return true;
}
);
ui.findPreference(PreferenceController.PREF_CHOOSE_DATA_DIR).setOnPreferenceClickListener(
preference -> {
if (Build.VERSION_CODES.KITKAT <= Build.VERSION.SDK_INT &&
Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) {
showChooseDataFolderDialog();
} else {
int readPermission = ActivityCompat.checkSelfPermission(
activity, Manifest.permission.READ_EXTERNAL_STORAGE);
int writePermission = ActivityCompat.checkSelfPermission(
activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (readPermission == PackageManager.PERMISSION_GRANTED &&
writePermission == PackageManager.PERMISSION_GRANTED) {
openDirectoryChooser();
} else {
requestPermission();
}
}
return true;
} }
); );
ui.findPreference(PreferenceController.PREF_CHOOSE_DATA_DIR) ui.findPreference(PreferenceController.PREF_CHOOSE_DATA_DIR)
.setOnPreferenceClickListener( .setOnPreferenceClickListener(
new Preference.OnPreferenceClickListener() { preference -> {
@Override
public boolean onPreferenceClick(Preference preference) {
if (Build.VERSION.SDK_INT >= 19) { if (Build.VERSION.SDK_INT >= 19) {
showChooseDataFolderDialog(); showChooseDataFolderDialog();
} else { } else {
@ -185,15 +203,10 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
} }
return true; return true;
} }
}
); );
ui.findPreference(UserPreferences.PREF_THEME) ui.findPreference(UserPreferences.PREF_THEME)
.setOnPreferenceChangeListener( .setOnPreferenceChangeListener(
new Preference.OnPreferenceChangeListener() { (preference, newValue) -> {
@Override
public boolean onPreferenceChange(
Preference preference, Object newValue) {
Intent i = new Intent(activity, MainActivity.class); Intent i = new Intent(activity, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK
| Intent.FLAG_ACTIVITY_NEW_TASK); | Intent.FLAG_ACTIVITY_NEW_TASK);
@ -201,24 +214,17 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
activity.startActivity(i); activity.startActivity(i);
return true; return true;
} }
}
); );
ui.findPreference(UserPreferences.PREF_HIDDEN_DRAWER_ITEMS) ui.findPreference(UserPreferences.PREF_HIDDEN_DRAWER_ITEMS)
.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { .setOnPreferenceClickListener(preference -> {
@Override
public boolean onPreferenceClick(Preference preference) {
showDrawerPreferencesDialog(); showDrawerPreferencesDialog();
return true; return true;
}
}); });
ui.findPreference(UserPreferences.PREF_UPDATE_INTERVAL) ui.findPreference(UserPreferences.PREF_UPDATE_INTERVAL)
.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { .setOnPreferenceClickListener(preference -> {
@Override
public boolean onPreferenceClick(Preference preference) {
showUpdateIntervalTimePreferencesDialog(); showUpdateIntervalTimePreferencesDialog();
return true; return true;
}
}); });
ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL).setOnPreferenceChangeListener( ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL).setOnPreferenceChangeListener(
@ -234,11 +240,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
}); });
ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL_WIFI_FILTER) ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL_WIFI_FILTER)
.setOnPreferenceChangeListener( .setOnPreferenceChangeListener(
new Preference.OnPreferenceChangeListener() { (preference, newValue) -> {
@Override
public boolean onPreferenceChange(
Preference preference, Object newValue) {
if (newValue instanceof Boolean) { if (newValue instanceof Boolean) {
setSelectedNetworksEnabled((Boolean) newValue); setSelectedNetworksEnabled((Boolean) newValue);
return true; return true;
@ -246,16 +248,13 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
return false; return false;
} }
} }
}
); );
ui.findPreference(UserPreferences.PREF_PARALLEL_DOWNLOADS) ui.findPreference(UserPreferences.PREF_PARALLEL_DOWNLOADS)
.setOnPreferenceChangeListener( .setOnPreferenceChangeListener(
new Preference.OnPreferenceChangeListener() { (preference, o) -> {
@Override
public boolean onPreferenceChange(Preference preference, Object o) {
if (o instanceof String) { if (o instanceof String) {
try { try {
int value = Integer.valueOf((String) o); int value = Integer.parseInt((String) o);
if (1 <= value && value <= 50) { if (1 <= value && value <= 50) {
setParallelDownloadsText(value); setParallelDownloadsText(value);
return true; return true;
@ -266,7 +265,6 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
} }
return false; return false;
} }
}
); );
// validate and set correct value: number of downloads between 1 and 50 (inclusive) // validate and set correct value: number of downloads between 1 and 50 (inclusive)
final EditText ev = ((EditTextPreference) ui.findPreference(UserPreferences.PREF_PARALLEL_DOWNLOADS)).getEditText(); final EditText ev = ((EditTextPreference) ui.findPreference(UserPreferences.PREF_PARALLEL_DOWNLOADS)).getEditText();
@ -283,7 +281,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
public void afterTextChanged(Editable s) { public void afterTextChanged(Editable s) {
if (s.length() > 0) { if (s.length() > 0) {
try { try {
int value = Integer.valueOf(s.toString()); int value = Integer.parseInt(s.toString());
if (value <= 0) { if (value <= 0) {
ev.setText("1"); ev.setText("1");
} else if (value > 50) { } else if (value > 50) {
@ -298,27 +296,20 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
}); });
ui.findPreference(UserPreferences.PREF_EPISODE_CACHE_SIZE) ui.findPreference(UserPreferences.PREF_EPISODE_CACHE_SIZE)
.setOnPreferenceChangeListener( .setOnPreferenceChangeListener(
new Preference.OnPreferenceChangeListener() { (preference, o) -> {
@Override
public boolean onPreferenceChange(Preference preference, Object o) {
if (o instanceof String) { if (o instanceof String) {
setEpisodeCacheSizeText(UserPreferences.readEpisodeCacheSize((String) o)); setEpisodeCacheSizeText(UserPreferences.readEpisodeCacheSize((String) o));
} }
return true; return true;
} }
}
); );
ui.findPreference(PreferenceController.PREF_PLAYBACK_SPEED_LAUNCHER) ui.findPreference(PreferenceController.PREF_PLAYBACK_SPEED_LAUNCHER)
.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { .setOnPreferenceClickListener(preference -> {
@Override
public boolean onPreferenceClick(Preference preference) {
VariableSpeedDialog.showDialog(activity); VariableSpeedDialog.showDialog(activity);
return true; return true;
}
}); });
ui.findPreference(PreferenceController.PREF_GPODNET_SETLOGIN_INFORMATION).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { ui.findPreference(PreferenceController.PREF_GPODNET_SETLOGIN_INFORMATION)
@Override .setOnPreferenceClickListener(preference -> {
public boolean onPreferenceClick(Preference preference) {
AuthenticationDialog dialog = new AuthenticationDialog(activity, AuthenticationDialog dialog = new AuthenticationDialog(activity,
R.string.pref_gpodnet_setlogin_information_title, false, false, GpodnetPreferences.getUsername(), R.string.pref_gpodnet_setlogin_information_title, false, false, GpodnetPreferences.getUsername(),
null) { null) {
@ -330,34 +321,31 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
}; };
dialog.show(); dialog.show();
return true; return true;
}
}); });
ui.findPreference(PreferenceController.PREF_GPODNET_LOGOUT).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { ui.findPreference(PreferenceController.PREF_GPODNET_SYNC).
@Override setOnPreferenceClickListener(preference -> {
public boolean onPreferenceClick(Preference preference) { GpodnetSyncService.sendSyncIntent(ui.getActivity().getApplicationContext());
Toast toast = Toast.makeText(ui.getActivity(), R.string.pref_gpodnet_sync_started,
Toast.LENGTH_SHORT);
toast.show();
return true;
});
ui.findPreference(PreferenceController.PREF_GPODNET_LOGOUT).setOnPreferenceClickListener(
preference -> {
GpodnetPreferences.logout(); GpodnetPreferences.logout();
Toast toast = Toast.makeText(activity, R.string.pref_gpodnet_logout_toast, Toast.LENGTH_SHORT); Toast toast = Toast.makeText(activity, R.string.pref_gpodnet_logout_toast, Toast.LENGTH_SHORT);
toast.show(); toast.show();
updateGpodnetPreferenceScreen(); updateGpodnetPreferenceScreen();
return true; return true;
}
});
ui.findPreference(PreferenceController.PREF_GPODNET_HOSTNAME).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
GpodnetSetHostnameDialog.createDialog(activity).setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
updateGpodnetPreferenceScreen();
}
}); });
ui.findPreference(PreferenceController.PREF_GPODNET_HOSTNAME).setOnPreferenceClickListener(
preference -> {
GpodnetSetHostnameDialog.createDialog(activity).setOnDismissListener(dialog -> updateGpodnetPreferenceScreen());
return true; return true;
}
}); });
ui.findPreference(PreferenceController.PREF_AUTO_FLATTR_PREFS).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { ui.findPreference(PreferenceController.PREF_AUTO_FLATTR_PREFS)
@Override .setOnPreferenceClickListener(preference -> {
public boolean onPreferenceClick(Preference preference) {
AutoFlattrPreferenceDialog.newAutoFlattrPreferenceDialog(activity, AutoFlattrPreferenceDialog.newAutoFlattrPreferenceDialog(activity,
new AutoFlattrPreferenceDialog.AutoFlattrPreferenceDialogInterface() { new AutoFlattrPreferenceDialog.AutoFlattrPreferenceDialogInterface() {
@Override @Override
@ -372,15 +360,11 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
} }
}); });
return true; return true;
}
}); });
ui.findPreference(UserPreferences.PREF_IMAGE_CACHE_SIZE) ui.findPreference(UserPreferences.PREF_IMAGE_CACHE_SIZE).setOnPreferenceChangeListener(
.setOnPreferenceChangeListener( (preference, o) -> {
new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object o) {
if (o instanceof String) { if (o instanceof String) {
int newValue = Integer.valueOf((String) o) * 1024 * 1024; int newValue = Integer.parseInt((String) o) * 1024 * 1024;
if (newValue != UserPreferences.getImageCacheSize()) { if (newValue != UserPreferences.getImageCacheSize()) {
AlertDialog.Builder dialog = new AlertDialog.Builder(ui.getActivity()); AlertDialog.Builder dialog = new AlertDialog.Builder(ui.getActivity());
dialog.setTitle(android.R.string.dialog_alert_title); dialog.setTitle(android.R.string.dialog_alert_title);
@ -392,9 +376,21 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
} }
return false; return false;
} }
}
); );
ui.findPreference("prefSendCrashReport").setOnPreferenceClickListener(preference -> { ui.findPreference(PREF_PROXY).setOnPreferenceClickListener(preference -> {
ProxyDialog dialog = new ProxyDialog(ui.getActivity());
dialog.createDialog().show();
return true;
});
ui.findPreference(PREF_KNOWN_ISSUES).setOnPreferenceClickListener(preference -> {
openInBrowser("https://github.com/AntennaPod/AntennaPod/labels/bug");
return true;
});
ui.findPreference(PREF_FAQ).setOnPreferenceClickListener(preference -> {
openInBrowser("http://antennapod.org/faq.html");
return true;
});
ui.findPreference(PREF_SEND_CRASH_REPORT).setOnPreferenceClickListener(preference -> {
Intent emailIntent = new Intent(Intent.ACTION_SEND); Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setType("text/plain"); emailIntent.setType("text/plain");
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{"Martin.Fietz@gmail.com"}); emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{"Martin.Fietz@gmail.com"});
@ -412,6 +408,16 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
setSelectedNetworksEnabled(UserPreferences.isEnableAutodownloadWifiFilter()); setSelectedNetworksEnabled(UserPreferences.isEnableAutodownloadWifiFilter());
} }
private void openInBrowser(String url) {
try {
Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
ui.getActivity().startActivity(myIntent);
} catch (ActivityNotFoundException e) {
Toast.makeText(ui.getActivity(), R.string.pref_no_browser_found, Toast.LENGTH_LONG).show();
Log.e(TAG, Log.getStackTraceString(e));
}
}
public void onResume() { public void onResume() {
checkItemVisibility(); checkItemVisibility();
setUpdateIntervalText(); setUpdateIntervalText();
@ -427,7 +433,12 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
requestCode == DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED) { requestCode == DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED) {
String dir = data.getStringExtra(DirectoryChooserActivity.RESULT_SELECTED_DIR); String dir = data.getStringExtra(DirectoryChooserActivity.RESULT_SELECTED_DIR);
File path = new File(dir); File path;
if(dir != null) {
path = new File(dir);
} else {
path = ui.getActivity().getExternalFilesDir(null);
}
String message = null; String message = null;
final Context context= ui.getActivity().getApplicationContext(); final Context context= ui.getActivity().getApplicationContext();
if(!path.exists()) { if(!path.exists()) {
@ -456,7 +467,16 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
final boolean loggedIn = GpodnetPreferences.loggedIn(); final boolean loggedIn = GpodnetPreferences.loggedIn();
ui.findPreference(PreferenceController.PREF_GPODNET_LOGIN).setEnabled(!loggedIn); ui.findPreference(PreferenceController.PREF_GPODNET_LOGIN).setEnabled(!loggedIn);
ui.findPreference(PreferenceController.PREF_GPODNET_SETLOGIN_INFORMATION).setEnabled(loggedIn); ui.findPreference(PreferenceController.PREF_GPODNET_SETLOGIN_INFORMATION).setEnabled(loggedIn);
ui.findPreference(PreferenceController.PREF_GPODNET_SYNC).setEnabled(loggedIn);
ui.findPreference(PreferenceController.PREF_GPODNET_LOGOUT).setEnabled(loggedIn); ui.findPreference(PreferenceController.PREF_GPODNET_LOGOUT).setEnabled(loggedIn);
if(loggedIn) {
String format = ui.getActivity().getString(R.string.pref_gpodnet_login_status);
String summary = String.format(format, GpodnetPreferences.getUsername(),
GpodnetPreferences.getDeviceID());
ui.findPreference(PreferenceController.PREF_GPODNET_LOGOUT).setSummary(Html.fromHtml(summary));
} else {
ui.findPreference(PreferenceController.PREF_GPODNET_LOGOUT).setSummary(null);
}
ui.findPreference(PreferenceController.PREF_GPODNET_HOSTNAME).setSummary(GpodnetPreferences.getHostname()); ui.findPreference(PreferenceController.PREF_GPODNET_HOSTNAME).setSummary(GpodnetPreferences.getHostname());
} }
@ -547,7 +567,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL_WIFI_FILTER).setEnabled(autoDownload); ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL_WIFI_FILTER).setEnabled(autoDownload);
setSelectedNetworksEnabled(autoDownload && UserPreferences.isEnableAutodownloadWifiFilter()); setSelectedNetworksEnabled(autoDownload && UserPreferences.isEnableAutodownloadWifiFilter());
ui.findPreference("prefSendCrashReport").setEnabled(CrashReportWriter.getFile().exists()); ui.findPreference(PREF_SEND_CRASH_REPORT).setEnabled(CrashReportWriter.getFile().exists());
if (Build.VERSION.SDK_INT >= 16) { if (Build.VERSION.SDK_INT >= 16) {
ui.findPreference(UserPreferences.PREF_SONIC).setEnabled(true); ui.findPreference(UserPreferences.PREF_SONIC).setEnabled(true);
@ -628,13 +648,10 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
List<String> prefValues = Arrays.asList(UserPreferences List<String> prefValues = Arrays.asList(UserPreferences
.getAutodownloadSelectedNetworks()); .getAutodownloadSelectedNetworks());
PreferenceScreen prefScreen = (PreferenceScreen) ui.findPreference(PreferenceController.AUTO_DL_PREF_SCREEN); PreferenceScreen prefScreen = (PreferenceScreen) ui.findPreference(PreferenceController.AUTO_DL_PREF_SCREEN);
Preference.OnPreferenceClickListener clickListener = new Preference.OnPreferenceClickListener() { Preference.OnPreferenceClickListener clickListener = preference -> {
@Override
public boolean onPreferenceClick(Preference preference) {
if (preference instanceof CheckBoxPreference) { if (preference instanceof CheckBoxPreference) {
String key = preference.getKey(); String key = preference.getKey();
ArrayList<String> prefValuesList = new ArrayList<String>( List<String> prefValuesList = new ArrayList<>(
Arrays.asList(UserPreferences Arrays.asList(UserPreferences
.getAutodownloadSelectedNetworks()) .getAutodownloadSelectedNetworks())
); );
@ -643,10 +660,10 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
Log.d(TAG, "Selected network " + key + ". New state: " + newValue); Log.d(TAG, "Selected network " + key + ". New state: " + newValue);
int index = prefValuesList.indexOf(key); int index = prefValuesList.indexOf(key);
if (index >= 0 && newValue == false) { if (index >= 0 && !newValue) {
// remove network // remove network
prefValuesList.remove(index); prefValuesList.remove(index);
} else if (index < 0 && newValue == true) { } else if (index < 0 && newValue) {
prefValuesList.add(key); prefValuesList.add(key);
} }
@ -657,7 +674,6 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
} else { } else {
return false; return false;
} }
}
}; };
// create preference for each known network. attach listener and set // create preference for each known network. attach listener and set
// value // value
@ -683,9 +699,9 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
if (selectedNetworks != null) { if (selectedNetworks != null) {
PreferenceScreen prefScreen = (PreferenceScreen) ui.findPreference(PreferenceController.AUTO_DL_PREF_SCREEN); PreferenceScreen prefScreen = (PreferenceScreen) ui.findPreference(PreferenceController.AUTO_DL_PREF_SCREEN);
for (int i = 0; i < selectedNetworks.length; i++) { for (CheckBoxPreference network : selectedNetworks) {
if (selectedNetworks[i] != null) { if (network != null) {
prefScreen.removePreference(selectedNetworks[i]); prefScreen.removePreference(network);
} }
} }
} }
@ -703,7 +719,6 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
checked[i] = true; checked[i] = true;
} }
} }
AlertDialog.Builder builder = new AlertDialog.Builder(context); AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.drawer_preferences); builder.setTitle(R.string.drawer_preferences);
builder.setMultiChoiceItems(navTitles, checked, (dialog, which, isChecked) -> { builder.setMultiChoiceItems(navTitles, checked, (dialog, which, isChecked) -> {
@ -713,16 +728,26 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
hiddenDrawerItems.add(NAV_DRAWER_TAGS[which]); hiddenDrawerItems.add(NAV_DRAWER_TAGS[which]);
} }
}); });
builder.setPositiveButton(R.string.confirm_label, new DialogInterface.OnClickListener() { builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> {
@Override
public void onClick(DialogInterface dialog, int which) {
UserPreferences.setHiddenDrawerItems(hiddenDrawerItems); UserPreferences.setHiddenDrawerItems(hiddenDrawerItems);
}
}); });
builder.setNegativeButton(R.string.cancel_label, null); builder.setNegativeButton(R.string.cancel_label, null);
builder.create().show(); builder.create().show();
} }
// CHOOSE DATA FOLDER
private void requestPermission() {
ActivityCompat.requestPermissions(ui.getActivity(), EXTERNAL_STORAGE_PERMISSIONS,
PERMISSION_REQUEST_EXTERNAL_STORAGE);
}
private void openDirectoryChooser() {
Activity activity = ui.getActivity();
Intent intent = new Intent(activity, DirectoryChooserActivity.class);
activity.startActivityForResult(intent, DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED);
}
private void showChooseDataFolderDialog() { private void showChooseDataFolderDialog() {
Context context = ui.getActivity(); Context context = ui.getActivity();
File dataFolder = UserPreferences.getDataFolder(null); File dataFolder = UserPreferences.getDataFolder(null);
@ -786,6 +811,8 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
dialog.show(); dialog.show();
} }
// UPDATE TIME/INTERVAL DIALOG
private void showUpdateIntervalTimePreferencesDialog() { private void showUpdateIntervalTimePreferencesDialog() {
final Context context = ui.getActivity(); final Context context = ui.getActivity();
@ -795,11 +822,9 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
builder.positiveText(R.string.pref_autoUpdateIntervallOrTime_Interval); builder.positiveText(R.string.pref_autoUpdateIntervallOrTime_Interval);
builder.negativeText(R.string.pref_autoUpdateIntervallOrTime_TimeOfDay); builder.negativeText(R.string.pref_autoUpdateIntervallOrTime_TimeOfDay);
builder.neutralText(R.string.pref_autoUpdateIntervallOrTime_Disable); builder.neutralText(R.string.pref_autoUpdateIntervallOrTime_Disable);
builder.callback(new MaterialDialog.ButtonCallback() { builder.onPositive((dialog, which) -> {
@Override AlertDialog.Builder builder1 = new AlertDialog.Builder(context);
public void onPositive(MaterialDialog dialog) { builder1.setTitle(context.getString(R.string.pref_autoUpdateIntervallOrTime_Interval));
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(context.getString(R.string.pref_autoUpdateIntervallOrTime_Interval));
final String[] values = context.getResources().getStringArray(R.array.update_intervall_values); final String[] values = context.getResources().getStringArray(R.array.update_intervall_values);
final String[] entries = getUpdateIntervalEntries(values); final String[] entries = getUpdateIntervalEntries(values);
long currInterval = UserPreferences.getUpdateInterval(); long currInterval = UserPreferences.getUpdateInterval();
@ -808,18 +833,16 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
String currIntervalStr = String.valueOf(TimeUnit.MILLISECONDS.toHours(currInterval)); String currIntervalStr = String.valueOf(TimeUnit.MILLISECONDS.toHours(currInterval));
checkedItem = ArrayUtils.indexOf(values, currIntervalStr); checkedItem = ArrayUtils.indexOf(values, currIntervalStr);
} }
builder.setSingleChoiceItems(entries, checkedItem, (dialog1, which) -> { builder1.setSingleChoiceItems(entries, checkedItem, (dialog1, which1) -> {
int hours = Integer.valueOf(values[which]); int hours = Integer.parseInt(values[which1]);
UserPreferences.setUpdateInterval(hours); UserPreferences.setUpdateInterval(hours);
dialog1.dismiss(); dialog1.dismiss();
setUpdateIntervalText(); setUpdateIntervalText();
}); });
builder.setNegativeButton(context.getString(R.string.cancel_label), null); builder1.setNegativeButton(context.getString(R.string.cancel_label), null);
builder.show(); builder1.show();
} });
builder.onNegative((dialog, which) -> {
@Override
public void onNegative(MaterialDialog dialog) {
int hourOfDay = 7, minute = 0; int hourOfDay = 7, minute = 0;
int[] updateTime = UserPreferences.getUpdateTimeOfDay(); int[] updateTime = UserPreferences.getUpdateTimeOfDay();
if (updateTime.length == 2) { if (updateTime.length == 2) {
@ -836,15 +859,11 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
}, hourOfDay, minute, DateFormat.is24HourFormat(context)); }, hourOfDay, minute, DateFormat.is24HourFormat(context));
timePickerDialog.setTitle(context.getString(R.string.pref_autoUpdateIntervallOrTime_TimeOfDay)); timePickerDialog.setTitle(context.getString(R.string.pref_autoUpdateIntervallOrTime_TimeOfDay));
timePickerDialog.show(); timePickerDialog.show();
} });
builder.onNeutral((dialog, which) -> {
@Override
public void onNeutral(MaterialDialog dialog) {
UserPreferences.setUpdateInterval(0); UserPreferences.setUpdateInterval(0);
setUpdateIntervalText(); setUpdateIntervalText();
}
}); });
builder.forceStacking(true);
builder.show(); builder.show();
} }

View File

@ -8,6 +8,7 @@ import android.net.NetworkInfo;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.DownloadRequester; import de.danoeh.antennapod.core.storage.DownloadRequester;
import de.danoeh.antennapod.core.util.NetworkUtils; import de.danoeh.antennapod.core.util.NetworkUtils;
@ -20,6 +21,7 @@ public class ConnectivityActionReceiver extends BroadcastReceiver {
if (TextUtils.equals(intent.getAction(), ConnectivityManager.CONNECTIVITY_ACTION)) { if (TextUtils.equals(intent.getAction(), ConnectivityManager.CONNECTIVITY_ACTION)) {
Log.d(TAG, "Received intent"); Log.d(TAG, "Received intent");
ClientConfig.initialize(context);
if (NetworkUtils.autodownloadNetworkAvailable()) { if (NetworkUtils.autodownloadNetworkAvailable()) {
Log.d(TAG, "auto-dl network available, starting auto-download"); Log.d(TAG, "auto-dl network available, starting auto-download");
DBTasks.autodownloadUndownloadedItems(context); DBTasks.autodownloadUndownloadedItems(context);

View File

@ -1,5 +1,7 @@
package de.danoeh.antennapod.receiver; package de.danoeh.antennapod.receiver;
import java.util.Arrays;
import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider; import android.appwidget.AppWidgetProvider;
import android.content.Context; import android.content.Context;
@ -44,14 +46,14 @@ public class PlayerWidget extends AppWidgetProvider {
@Override @Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) { int[] appWidgetIds) {
Log.d(TAG, "onUpdate() called with: " + "context = [" + context + "], appWidgetManager = [" + appWidgetManager + "], appWidgetIds = [" + appWidgetIds + "]"); Log.d(TAG, "onUpdate() called with: " + "context = [" + context + "], appWidgetManager = [" + appWidgetManager + "], appWidgetIds = [" + Arrays.toString(appWidgetIds) + "]");
startUpdate(context); startUpdate(context);
} }
@Override @Override
public void onDisabled(Context context) { public void onDisabled(Context context) {
super.onDisabled(context); super.onDisabled(context);
Log.d(TAG, "Widet disabled"); Log.d(TAG, "Widget disabled");
setEnabled(context, false); setEnabled(context, false);
stopUpdate(context); stopUpdate(context);
} }

View File

@ -3,10 +3,9 @@ package de.danoeh.antennapod.receiver;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.BatteryManager;
import android.util.Log; import android.util.Log;
import de.danoeh.antennapod.core.BuildConfig; import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.DownloadRequester; import de.danoeh.antennapod.core.storage.DownloadRequester;
@ -25,6 +24,7 @@ public class PowerConnectionReceiver extends BroadcastReceiver {
Log.d(TAG, "charging intent: " + action); Log.d(TAG, "charging intent: " + action);
ClientConfig.initialize(context);
if (Intent.ACTION_POWER_CONNECTED.equals(action)) { if (Intent.ACTION_POWER_CONNECTED.equals(action)) {
Log.d(TAG, "charging, starting auto-download"); Log.d(TAG, "charging, starting auto-download");
// we're plugged in, this is a great time to auto-download if everything else is // we're plugged in, this is a great time to auto-download if everything else is

View File

@ -8,10 +8,9 @@ import android.util.Log;
import android.widget.Toast; import android.widget.Toast;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date;
import de.danoeh.antennapod.BuildConfig;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.Feed;
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;
@ -28,14 +27,23 @@ public class SPAReceiver extends BroadcastReceiver{
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
if (TextUtils.equals(intent.getAction(), ACTION_SP_APPS_QUERY_FEEDS_REPSONSE)) { if (!TextUtils.equals(intent.getAction(), ACTION_SP_APPS_QUERY_FEEDS_REPSONSE)) {
if (BuildConfig.DEBUG) Log.d(TAG, "Received SP_APPS_QUERY_RESPONSE"); return;
if (intent.hasExtra(ACTION_SP_APPS_QUERY_FEEDS_REPSONSE_FEEDS_EXTRA)) { }
Log.d(TAG, "Received SP_APPS_QUERY_RESPONSE");
if (!intent.hasExtra(ACTION_SP_APPS_QUERY_FEEDS_REPSONSE_FEEDS_EXTRA)) {
Log.e(TAG, "Received invalid SP_APPS_QUERY_RESPONSE: Contains no extra");
return;
}
String[] feedUrls = intent.getStringArrayExtra(ACTION_SP_APPS_QUERY_FEEDS_REPSONSE_FEEDS_EXTRA); String[] feedUrls = intent.getStringArrayExtra(ACTION_SP_APPS_QUERY_FEEDS_REPSONSE_FEEDS_EXTRA);
if (feedUrls != null) { if (feedUrls == null) {
if (BuildConfig.DEBUG) Log.d(TAG, "Received feeds list: " + Arrays.toString(feedUrls)); Log.e(TAG, "Received invalid SP_APPS_QUERY_REPSONSE: extra was null");
return;
}
Log.d(TAG, "Received feeds list: " + Arrays.toString(feedUrls));
ClientConfig.initialize(context);
for (String url : feedUrls) { for (String url : feedUrls) {
Feed f = new Feed(url, new Date(0)); Feed f = new Feed(url, null);
try { try {
DownloadRequester.getInstance().downloadFeed(context, f); DownloadRequester.getInstance().downloadFeed(context, f);
} catch (DownloadRequestException e) { } catch (DownloadRequestException e) {
@ -44,13 +52,5 @@ public class SPAReceiver extends BroadcastReceiver{
} }
} }
Toast.makeText(context, R.string.sp_apps_importing_feeds_msg, Toast.LENGTH_LONG).show(); Toast.makeText(context, R.string.sp_apps_importing_feeds_msg, Toast.LENGTH_LONG).show();
} else {
Log.e(TAG, "Received invalid SP_APPS_QUERY_REPSONSE: extra was null");
}
} else {
Log.e(TAG, "Received invalid SP_APPS_QUERY_RESPONSE: Contains no extra");
}
}
} }
} }

View File

@ -1,64 +0,0 @@
package de.danoeh.antennapod.utils;
import android.content.Context;
import java.util.Date;
import de.danoeh.antennapod.R;
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//http://stackoverflow.com/questions/13018550/time-since-ago-library-for-android-java
public class TimeUtils {
private static final int SECOND_MILLIS = 1000;
private static final int MINUTE_MILLIS = 60 * SECOND_MILLIS;
private static final int HOUR_MILLIS = 60 * MINUTE_MILLIS;
private static final int DAY_MILLIS = 24 * HOUR_MILLIS;
public static String getTimeAgo(long time, Context ctx) {
if (time < 1000000000000L) {
// if timestamp given in seconds, convert to millis
time *= 1000;
}
long now = new Date().getTime();
if (time > now || time <= 0) {
return null;
}
final long diff = now - time;
if (diff < MINUTE_MILLIS) {
return ctx.getString(R.string.time_just_now);
} else if (diff < 2 * MINUTE_MILLIS) {
return ctx.getString(R.string.time_a_min_ago);
} else if (diff < 50 * MINUTE_MILLIS) {
return diff / MINUTE_MILLIS + ctx.getString(R.string.time_min_ago);
} else if (diff < 90 * MINUTE_MILLIS) {
return ctx.getString(R.string.time_an_hour_ago);
} else if (diff < 24 * HOUR_MILLIS) {
return diff / HOUR_MILLIS + ctx.getString(R.string.time_hours_ago);
} else if (diff < 48 * HOUR_MILLIS) {
return ctx.getString(R.string.time_yesterday);
} else {
return diff / DAY_MILLIS + ctx.getString(R.string.time_days_ago);
}
}
}

View File

@ -24,7 +24,6 @@ public class SubscriptionViewItem extends RelativeLayout {
private ImageView mImageView; private ImageView mImageView;
private TextView mTextTime; private TextView mTextTime;
private TextView mUnreadCountText;
private TextView mFeedTitle; private TextView mFeedTitle;
private Context mContext; private Context mContext;
@ -56,7 +55,6 @@ public class SubscriptionViewItem extends RelativeLayout {
mTextTime = (TextView) view.findViewById(R.id.txtvTime); mTextTime = (TextView) view.findViewById(R.id.txtvTime);
mFeedTitle = (TextView) view.findViewById(R.id.txtvTitle); mFeedTitle = (TextView) view.findViewById(R.id.txtvTitle);
mImageView = (ImageView) view.findViewById(R.id.imgvCover); mImageView = (ImageView) view.findViewById(R.id.imgvCover);
mUnreadCountText = (TextView) view.findViewById(R.id.unread_count_text);
} }
public void setFeed(Feed feed) { public void setFeed(Feed feed) {
@ -78,12 +76,8 @@ public class SubscriptionViewItem extends RelativeLayout {
}) })
.centerCrop() .centerCrop()
.into(mImageView); .into(mImageView);
// Removing the updated time. It could be the latest podcast updated time in the future.
//mTextTime.setText(TimeUtils.getTimeAgo(feed.getLastUpdate().getTime(), mContext));
mTextTime.setVisibility(GONE); mTextTime.setVisibility(GONE);
// Could be the count of unread/ not played feed items
//mUnreadCountText.setText(String.valueOf(feed.getNumOfItems()));
} }
} }

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:type="linear"
android:centerX="69%"
android:startColor="#00000000"
android:centerColor="#59000000"
android:endColor="#FF242424"
android:angle="270"/>
</shape>

View File

@ -7,9 +7,7 @@
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content">
android:layout_marginTop="12dp"
android:layout_marginLeft="24dp">
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -30,9 +28,7 @@
<RelativeLayout <RelativeLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="-12dp" android:layout_marginTop="-12dp">
android:layout_marginLeft="24dp"
android:layout_marginRight="24dp">
<Button <Button
android:id="@+id/butDecSpeed" android:id="@+id/butDecSpeed"
@ -74,7 +70,6 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="4dp" android:layout_marginTop="4dp"
android:layout_marginLeft="24dp"
style="@style/AntennaPod.TextView.ListItemPrimaryTitle" style="@style/AntennaPod.TextView.ListItemPrimaryTitle"
android:text="@string/volume" android:text="@string/volume"
android:textStyle="bold"/> android:textStyle="bold"/>
@ -83,8 +78,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="-12dp" android:layout_marginTop="-12dp"
android:layout_marginLeft="24dp" android:layout_marginLeft="8dp"
android:layout_marginRight="24dp"
android:orientation="horizontal" android:orientation="horizontal"
android:gravity="center"> android:gravity="center">
@ -106,8 +100,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginLeft="24dp" android:layout_marginLeft="8dp"
android:layout_marginRight="24dp"
android:orientation="horizontal" android:orientation="horizontal"
android:gravity="center"> android:gravity="center">
@ -129,7 +122,6 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="12dp" android:layout_marginTop="12dp"
android:layout_marginLeft="24dp"
style="@style/AntennaPod.TextView.ListItemPrimaryTitle" style="@style/AntennaPod.TextView.ListItemPrimaryTitle"
android:text="@string/audio_effects" android:text="@string/audio_effects"
android:textStyle="bold"/> android:textStyle="bold"/>
@ -139,8 +131,6 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="-12dp" android:layout_marginTop="-12dp"
android:layout_marginLeft="24dp"
android:layout_marginRight="24dp"
android:text="@string/stereo_to_mono" /> android:text="@string/stereo_to_mono" />
</LinearLayout> </LinearLayout>

View File

@ -22,7 +22,7 @@
<RelativeLayout <RelativeLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="match_parent" android:layout_height="@dimen/thumbnail_length_downloaded_item"
android:layout_marginLeft="@dimen/listitem_threeline_textleftpadding" android:layout_marginLeft="@dimen/listitem_threeline_textleftpadding"
android:layout_marginRight="@dimen/listitem_threeline_textrightpadding" android:layout_marginRight="@dimen/listitem_threeline_textrightpadding"
android:layout_marginTop="@dimen/listitem_threeline_verticalpadding" android:layout_marginTop="@dimen/listitem_threeline_verticalpadding"
@ -48,7 +48,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_below="@id/txtvTitle" android:layout_alignParentBottom="true"
tools:text="23 MB" tools:text="23 MB"
tools:background="@android:color/holo_green_dark" /> tools:background="@android:color/holo_green_dark" />
@ -58,10 +58,23 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_below="@id/txtvTitle" android:layout_alignParentBottom="true"
android:layout_marginLeft="8dp"
tools:text="Jan 23" tools:text="Jan 23"
tools:background="@android:color/holo_green_dark" /> tools:background="@android:color/holo_green_dark" />
<ImageView
android:id="@+id/imgvInPlaylist"
android:layout_width="@dimen/enc_icons_size"
android:layout_height="@dimen/enc_icons_size"
android:layout_toLeftOf="@id/txtvPublished"
android:layout_alignParentBottom="true"
android:contentDescription="@string/in_queue_label"
android:src="?attr/stat_playlist"
android:visibility="visible"
tools:src="@drawable/ic_list_white_24dp"
tools:background="@android:color/holo_red_light" />
</RelativeLayout> </RelativeLayout>
<include layout="@layout/vertical_list_divider"/> <include layout="@layout/vertical_list_divider"/>

View File

@ -10,14 +10,13 @@
android:paddingBottom="8dp" android:paddingBottom="8dp"
tools:background="@android:color/darker_gray"> tools:background="@android:color/darker_gray">
<TextView <com.joanzapata.iconify.widget.IconTextView
android:id="@+id/txtvIcon" android:id="@+id/txtvIcon"
android:layout_width="48dp" android:layout_width="48dp"
android:layout_height="48dp" android:layout_height="48dp"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:textSize="48sp" android:textSize="48sp"
tools:text="[Icon]"
android:gravity="center" /> android:gravity="center" />
<com.joanzapata.iconify.widget.IconButton <com.joanzapata.iconify.widget.IconButton

View File

@ -1,16 +1,16 @@
<RelativeLayout <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<LinearLayout <LinearLayout
android:id="@+id/bottomBar" android:id="@+id/bottomBar"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="68dp" android:layout_height="68dp"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:orientation="horizontal"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="4dp"> android:padding="4dp">
<Button <Button
@ -18,13 +18,13 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:background="@android:color/transparent"
android:drawableTop="?attr/content_new" android:drawableTop="?attr/content_new"
android:text="@string/add_to_queue_label" android:text="@string/add_to_queue_label"
android:textSize="10sp" android:textSize="10sp" />
android:background="@android:color/transparent"/>
<View xmlns:android="http://schemas.android.com/apk/res/android" <View
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/divider1"
android:layout_width="1dp" android:layout_width="1dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_margin="4dp" android:layout_margin="4dp"
@ -36,13 +36,13 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:background="@android:color/transparent"
android:drawableTop="?attr/navigation_accept" android:drawableTop="?attr/navigation_accept"
android:text="@string/mark_read_label" android:text="@string/mark_read_label"
android:textSize="10sp" android:textSize="10sp" />
android:background="@android:color/transparent"/>
<View xmlns:android="http://schemas.android.com/apk/res/android" <View
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/divider2"
android:layout_width="1dp" android:layout_width="1dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_margin="4dp" android:layout_margin="4dp"
@ -54,13 +54,13 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:background="@android:color/transparent"
android:drawableTop="?attr/navigation_cancel" android:drawableTop="?attr/navigation_cancel"
android:text="@string/mark_unread_label" android:text="@string/mark_unread_label"
android:textSize="10sp" android:textSize="10sp" />
android:background="@android:color/transparent"/>
<View xmlns:android="http://schemas.android.com/apk/res/android" <View
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/divider3"
android:layout_width="1dp" android:layout_width="1dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_margin="4dp" android:layout_margin="4dp"
@ -72,13 +72,13 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:background="@android:color/transparent"
android:drawableTop="?attr/av_download" android:drawableTop="?attr/av_download"
android:text="@string/download_label" android:text="@string/download_label"
android:textSize="10sp" android:textSize="10sp" />
android:background="@android:color/transparent"/>
<View xmlns:android="http://schemas.android.com/apk/res/android" <View
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/divider4"
android:layout_width="1dp" android:layout_width="1dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_margin="4dp" android:layout_margin="4dp"
@ -90,31 +90,26 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:background="@android:color/transparent"
android:drawableTop="?attr/content_discard" android:drawableTop="?attr/content_discard"
android:text="@string/remove_episode_lable" android:text="@string/remove_episode_lable"
android:textSize="10sp" android:textSize="10sp" />
android:background="@android:color/transparent"/>
</LinearLayout> </LinearLayout>
<View <View
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/divider" android:id="@+id/divider"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="1dp"
android:layout_above="@id/bottomBar"
android:background="?android:attr/listDivider" android:background="?android:attr/listDivider"
android:paddingBottom="4dp" android:paddingBottom="4dp"
android:layout_above="@id/bottomBar"
tools:background="@android:color/holo_red_dark" /> tools:background="@android:color/holo_red_dark" />
<ListView <ListView
android:id="@android:id/list" android:id="@android:id/list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_above="@id/divider"> android:layout_above="@id/divider"/>
</ListView>
</RelativeLayout> </RelativeLayout>

View File

@ -19,7 +19,7 @@
android:layout_height="@dimen/external_player_height" android:layout_height="@dimen/external_player_height"
android:adjustViewBounds="true" android:adjustViewBounds="true"
android:cropToPadding="true" android:cropToPadding="true"
android:scaleType="fitXY" android:scaleType="centerCrop"
tools:src="@drawable/ic_drag_vertical_white_48dp" tools:src="@drawable/ic_drag_vertical_white_48dp"
tools:background="@android:color/holo_green_dark" tools:background="@android:color/holo_green_dark"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"

Some files were not shown because too many files have changed in this diff Show More