summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/src/androidTest/java/de/test/antennapod/handler/FeedHandlerTest.java2
-rw-r--r--app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java2
-rw-r--r--app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java2
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBCleanupTests.java8
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBNullCleanupAlgorithmTest.java2
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBQueueCleanupAlgorithmTest.java2
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java8
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java15
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java2
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java57
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java1
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java2
-rw-r--r--app/src/main/AndroidManifest.xml4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/PodcastApp.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/UpdateManager.java9
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java85
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java27
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java5
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/OpmlImportBaseActivity.java98
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromIntentActivity.java22
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromPathActivity.java28
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java5
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java16
-rw-r--r--app/src/main/java/de/danoeh/antennapod/asynctask/OpmlFeedQueuer.java3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java13
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java30
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java10
-rw-r--r--app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java9
-rw-r--r--app/src/main/java/de/danoeh/antennapod/receiver/SPAReceiver.java3
-rw-r--r--app/src/main/res/layout/feedinfo.xml11
-rw-r--r--app/src/main/res/layout/itemdescription_listitem.xml49
33 files changed, 334 insertions, 208 deletions
diff --git a/app/src/androidTest/java/de/test/antennapod/handler/FeedHandlerTest.java b/app/src/androidTest/java/de/test/antennapod/handler/FeedHandlerTest.java
index 5836bb699..ee454ce8a 100644
--- a/app/src/androidTest/java/de/test/antennapod/handler/FeedHandlerTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/handler/FeedHandlerTest.java
@@ -162,7 +162,7 @@ public class FeedHandlerTest extends InstrumentationTestCase {
if (withImage) {
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/feed", true);
feed.setItems(new ArrayList<FeedItem>());
diff --git a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java
index d7a170c17..7862e986d 100644
--- a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java
@@ -115,7 +115,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
private Playable writeTestPlayable(String downloadUrl, String fileUrl) {
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);
f.setPreferences(prefs);
f.setItems(new ArrayList<>());
diff --git a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java
index f06d2f2a6..5c3d32960 100644
--- a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java
@@ -48,7 +48,7 @@ public class PlaybackServiceTaskManagerTest extends InstrumentationTestCase {
private List<FeedItem> writeTestQueue(String pref) {
final Context c = getInstrumentation().getTargetContext();
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<>());
for (int i = 0; i < NUM_ITEMS; i++) {
f.getItems().add(new FeedItem(0, pref + i, pref + i, "link", new Date(), FeedItem.PLAYED, f));
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBCleanupTests.java b/app/src/androidTest/java/de/test/antennapod/storage/DBCleanupTests.java
index afdaeead0..7300df395 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBCleanupTests.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBCleanupTests.java
@@ -87,7 +87,7 @@ public class DBCleanupTests extends InstrumentationTestCase {
public void testPerformAutoCleanupShouldDelete() throws IOException {
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<>();
feed.setItems(items);
List<File> files = new ArrayList<>();
@@ -143,7 +143,7 @@ public class DBCleanupTests extends InstrumentationTestCase {
public void testPerformAutoCleanupHandleUnplayed() throws IOException {
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>();
feed.setItems(items);
List<File> files = new ArrayList<File>();
@@ -159,7 +159,7 @@ public class DBCleanupTests extends InstrumentationTestCase {
public void testPerformAutoCleanupShouldNotDeleteBecauseInQueue() throws IOException {
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<>();
feed.setItems(items);
List<File> files = new ArrayList<>();
@@ -198,7 +198,7 @@ public class DBCleanupTests extends InstrumentationTestCase {
public void testPerformAutoCleanupShouldNotDeleteBecauseFavorite() throws IOException {
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<>();
feed.setItems(items);
List<File> files = new ArrayList<>();
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBNullCleanupAlgorithmTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBNullCleanupAlgorithmTest.java
index 18a8d63d1..7205b42c4 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBNullCleanupAlgorithmTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBNullCleanupAlgorithmTest.java
@@ -82,7 +82,7 @@ public class DBNullCleanupAlgorithmTest extends InstrumentationTestCase {
public void testPerformAutoCleanupShouldNotDelete() throws IOException {
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<>();
feed.setItems(items);
List<File> files = new ArrayList<>();
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBQueueCleanupAlgorithmTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBQueueCleanupAlgorithmTest.java
index 890897f43..3bd508eaf 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBQueueCleanupAlgorithmTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBQueueCleanupAlgorithmTest.java
@@ -32,7 +32,7 @@ public class DBQueueCleanupAlgorithmTest extends DBCleanupTests {
public void testPerformAutoCleanupHandleUnplayed() throws IOException {
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<>();
feed.setItems(items);
List<File> files = new ArrayList<>();
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java
index 3988669ce..0fc3b1892 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java
@@ -54,10 +54,10 @@ public class DBReaderTest extends InstrumentationTestCase {
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
- Feed feed1 = new Feed(0, new Date(), "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 feed3 = new Feed(0, new Date(), "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 feed1 = new Feed(0, null, "A", "link", "d", null, null, null, "rss", "A", null, "", "", true);
+ Feed feed2 = new Feed(0, null, "b", "link", "d", null, null, null, "rss", "b", null, "", "", true);
+ Feed feed3 = new Feed(0, null, "C", "link", "d", null, null, null, "rss", "C", null, "", "", true);
+ Feed feed4 = new Feed(0, null, "d", "link", "d", null, null, null, "rss", "d", null, "", "", true);
adapter.setCompleteFeed(feed1);
adapter.setCompleteFeed(feed2);
adapter.setCompleteFeed(feed3);
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java
index 1894d6585..5b2393d45 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java
@@ -1,13 +1,9 @@
package de.test.antennapod.storage;
import android.content.Context;
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
import android.test.FlakyTest;
import android.test.InstrumentationTestCase;
-import java.io.File;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
@@ -15,14 +11,11 @@ import java.util.List;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedItem;
-import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
-import static de.test.antennapod.storage.DBTestUtils.saveFeedlist;
-
/**
* Test class for DBTasks
*/
@@ -57,7 +50,7 @@ public class DBTasksTest extends InstrumentationTestCase {
public void testUpdateFeedNewFeed() {
final int NUM_ITEMS = 10;
- Feed feed = new Feed("url", new Date(), "title");
+ Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>());
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));
@@ -75,8 +68,8 @@ public class DBTasksTest extends InstrumentationTestCase {
/** Two feeds with the same title, but different download URLs should be treated as different feeds. */
public void testUpdateFeedSameTitle() {
- Feed feed1 = new Feed("url1", new Date(), "title");
- Feed feed2 = new Feed("url2", new Date(), "title");
+ Feed feed1 = new Feed("url1", null, "title");
+ Feed feed2 = new Feed("url2", null, "title");
feed1.setItems(new ArrayList<>());
feed2.setItems(new ArrayList<>());
@@ -91,7 +84,7 @@ public class DBTasksTest extends InstrumentationTestCase {
final int NUM_ITEMS_OLD = 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<>());
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));
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java b/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java
index 0af8afa83..78b807710 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java
@@ -44,7 +44,7 @@ public class DBTestUtils {
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
for (int i = 0; i < numFeeds; i++) {
- Feed f = new Feed(0, 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);
f.setItems(new ArrayList<>());
for (int j = 0; j < numItems; j++) {
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java
index eaae9323c..0e1d19f7b 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java
@@ -59,13 +59,14 @@ public class DBWriterTest extends InstrumentationTestCase {
adapter.close();
}
- public void testSetFeedMediaPlaybackInformation() throws IOException, ExecutionException, InterruptedException {
+ public void testSetFeedMediaPlaybackInformation()
+ throws IOException, ExecutionException, InterruptedException, TimeoutException {
final int POSITION = 50;
final long LAST_PLAYED_TIME = 1000;
final int PLAYED_DURATION = 60;
final int DURATION = 100;
- Feed feed = new Feed("url", new Date(), "title");
+ Feed feed = new Feed("url", null, "title");
List<FeedItem> items = new ArrayList<>();
feed.setItems(items);
FeedItem item = new FeedItem(0, "Item", "Item", "url", new Date(), FeedItem.PLAYED, feed);
@@ -73,13 +74,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);
item.setMedia(media);
- DBWriter.setFeedItem(item).get();
+ DBWriter.setFeedItem(item).get(TIMEOUT, TimeUnit.SECONDS);
media.setPosition(POSITION);
media.setLastPlayedTime(LAST_PLAYED_TIME);
media.setPlayedDuration(PLAYED_DURATION);
- DBWriter.setFeedMediaPlaybackInformation(item.getMedia()).get();
+ DBWriter.setFeedMediaPlaybackInformation(item.getMedia()).get(TIMEOUT, TimeUnit.SECONDS);
FeedItem itemFromDb = DBReader.getFeedItem(item.getId());
FeedMedia mediaFromDb = itemFromDb.getMedia();
@@ -90,12 +91,13 @@ public class DBWriterTest extends InstrumentationTestCase {
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");
assertTrue(dest.createNewFile());
- Feed feed = new Feed("url", new Date(), "title");
+ Feed feed = new Feed("url", null, "title");
List<FeedItem> items = new ArrayList<>();
feed.setItems(items);
FeedItem item = new FeedItem(0, "Item", "Item", "url", new Date(), FeedItem.PLAYED, feed);
@@ -112,7 +114,8 @@ public class DBWriterTest extends InstrumentationTestCase {
assertTrue(media.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());
assertNotNull(media);
assertFalse(dest.exists());
@@ -124,7 +127,7 @@ public class DBWriterTest extends InstrumentationTestCase {
File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
assertNotNull(destFolder);
- Feed feed = new Feed("url", new Date(), "title");
+ Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>());
// create Feed image
@@ -197,7 +200,7 @@ public class DBWriterTest extends InstrumentationTestCase {
File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
assertNotNull(destFolder);
- Feed feed = new Feed("url", new Date(), "title");
+ Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>());
feed.setImage(null);
@@ -253,7 +256,7 @@ public class DBWriterTest extends InstrumentationTestCase {
File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
assertNotNull(destFolder);
- Feed feed = new Feed("url", new Date(), "title");
+ Feed feed = new Feed("url", null, "title");
feed.setItems(null);
// create Feed image
@@ -290,7 +293,7 @@ public class DBWriterTest extends InstrumentationTestCase {
File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
assertNotNull(destFolder);
- Feed feed = new Feed("url", new Date(), "title");
+ Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>());
// create Feed image
@@ -342,7 +345,7 @@ public class DBWriterTest extends InstrumentationTestCase {
File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
assertNotNull(destFolder);
- Feed feed = new Feed("url", new Date(), "title");
+ Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>());
// create Feed image
@@ -400,7 +403,7 @@ public class DBWriterTest extends InstrumentationTestCase {
File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
assertNotNull(destFolder);
- Feed feed = new Feed("url", new Date(), "title");
+ Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>());
// create Feed image
@@ -472,7 +475,7 @@ public class DBWriterTest extends InstrumentationTestCase {
File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
assertNotNull(destFolder);
- Feed feed = new Feed("url", new Date(), "title");
+ Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<FeedItem>());
// create Feed image
@@ -528,7 +531,7 @@ public class DBWriterTest extends InstrumentationTestCase {
private FeedMedia playbackHistorySetup(Date playbackCompletionDate) {
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>());
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);
@@ -542,9 +545,10 @@ public class DBWriterTest extends InstrumentationTestCase {
return media;
}
- public void testAddItemToPlaybackHistoryNotPlayedYet() throws ExecutionException, InterruptedException {
+ public void testAddItemToPlaybackHistoryNotPlayedYet()
+ throws ExecutionException, InterruptedException, TimeoutException {
FeedMedia media = playbackHistorySetup(null);
- DBWriter.addItemToPlaybackHistory(media).get();
+ DBWriter.addItemToPlaybackHistory(media).get(TIMEOUT, TimeUnit.SECONDS);
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
media = DBReader.getFeedMedia(media.getId());
@@ -554,11 +558,12 @@ public class DBWriterTest extends InstrumentationTestCase {
assertNotNull(media.getPlaybackCompletionDate());
}
- public void testAddItemToPlaybackHistoryAlreadyPlayed() throws ExecutionException, InterruptedException {
+ public void testAddItemToPlaybackHistoryAlreadyPlayed()
+ throws ExecutionException, InterruptedException, TimeoutException {
final long OLD_DATE = 0;
FeedMedia media = playbackHistorySetup(new Date(OLD_DATE));
- DBWriter.addItemToPlaybackHistory(media).get();
+ DBWriter.addItemToPlaybackHistory(media).get(TIMEOUT, TimeUnit.SECONDS);
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
media = DBReader.getFeedMedia(media.getId());
@@ -571,7 +576,7 @@ public class DBWriterTest extends InstrumentationTestCase {
private Feed queueTestSetupMultipleItems(final int NUM_ITEMS) throws InterruptedException, ExecutionException, TimeoutException {
final Context context = getInstrumentation().getTargetContext();
- Feed feed = new Feed("url", new Date(), "title");
+ Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>());
for (int i = 0; i < NUM_ITEMS; i++) {
FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.PLAYED, feed);
@@ -598,7 +603,7 @@ public class DBWriterTest extends InstrumentationTestCase {
public void testAddQueueItemSingleItem() throws InterruptedException, ExecutionException, TimeoutException {
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 item = new FeedItem(0, "title", "id", "link", new Date(), FeedItem.PLAYED, feed);
feed.getItems().add(item);
@@ -622,7 +627,7 @@ public class DBWriterTest extends InstrumentationTestCase {
public void testAddQueueItemSingleItemAlreadyInQueue() throws InterruptedException, ExecutionException, TimeoutException {
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 item = new FeedItem(0, "title", "id", "link", new Date(), FeedItem.PLAYED, feed);
feed.getItems().add(item);
@@ -688,7 +693,7 @@ public class DBWriterTest extends InstrumentationTestCase {
public void testRemoveQueueItem() throws InterruptedException, ExecutionException, TimeoutException {
final int NUM_ITEMS = 10;
final Context context = getInstrumentation().getTargetContext();
- Feed feed = new Feed("url", new Date(), "title");
+ Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>());
for (int i = 0; i < NUM_ITEMS; i++) {
FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.PLAYED, feed);
@@ -733,7 +738,7 @@ public class DBWriterTest extends InstrumentationTestCase {
public void testMoveQueueItem() throws InterruptedException, ExecutionException, TimeoutException {
final int NUM_ITEMS = 10;
- Feed feed = new Feed("url", new Date(), "title");
+ Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>());
for (int i = 0; i < NUM_ITEMS; i++) {
FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.PLAYED, feed);
@@ -779,7 +784,7 @@ public class DBWriterTest extends InstrumentationTestCase {
public void testMarkFeedRead() throws InterruptedException, ExecutionException, TimeoutException {
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>());
for (int i = 0; i < NUM_ITEMS; i++) {
FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.UNPLAYED, feed);
@@ -805,7 +810,7 @@ public class DBWriterTest extends InstrumentationTestCase {
public void testMarkAllItemsReadSameFeed() throws InterruptedException, ExecutionException, TimeoutException {
final int NUM_ITEMS = 10;
- Feed feed = new Feed("url", new Date(), "title");
+ Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>());
for (int i = 0; i < NUM_ITEMS; i++) {
FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.UNPLAYED, feed);
diff --git a/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java b/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java
index e456f3891..4e214cf81 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java
@@ -142,6 +142,7 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
return ((MainActivity) solo.getCurrentActivity()).getSupportActionBar().getTitle().toString();
}
+ @SuppressWarnings("unchecked")
@FlakyTest(tolerance = 3)
public void testGoToPreferences() {
openNavDrawer();
diff --git a/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java b/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java
index 13abbb1cc..432d4a4e6 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java
@@ -143,7 +143,7 @@ public class UITestUtils {
for (int i = 0; i < NUM_FEEDS; i++) {
File bitmapFile = newBitmapFile("image" + i);
FeedImage image = new FeedImage(0, "image " + i, null, hostFile(bitmapFile), false);
- Feed feed = new Feed(0, 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/feed/src/" + i, false);
image.setOwner(feed);
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 287c17978..9d7bbee67 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.danoeh.antennapod"
- android:versionCode="1050002"
- android:versionName="1.5.0.2">
+ android:versionCode="1050004"
+ android:versionName="1.5.0.4">
<!--
Version code schema:
"1.2.3-SNAPSHOT" -> 1020300
diff --git a/app/src/main/java/de/danoeh/antennapod/PodcastApp.java b/app/src/main/java/de/danoeh/antennapod/PodcastApp.java
index c1d4bc4fd..829a49a15 100644
--- a/app/src/main/java/de/danoeh/antennapod/PodcastApp.java
+++ b/app/src/main/java/de/danoeh/antennapod/PodcastApp.java
@@ -57,8 +57,8 @@ public class PodcastApp extends Application {
singleton = this;
PodDBAdapter.init(this);
- UpdateManager.init(this);
UserPreferences.init(this);
+ UpdateManager.init(this);
PlaybackPreferences.init(this);
NetworkUtils.init(this);
EventDistributor.getInstance();
diff --git a/app/src/main/java/de/danoeh/antennapod/UpdateManager.java b/app/src/main/java/de/danoeh/antennapod/UpdateManager.java
index b1d7fffc8..0b3c43381 100644
--- a/app/src/main/java/de/danoeh/antennapod/UpdateManager.java
+++ b/app/src/main/java/de/danoeh/antennapod/UpdateManager.java
@@ -5,14 +5,18 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.os.Build;
import android.util.Log;
+import org.antennapod.audio.MediaPlayer;
+
import java.io.File;
import java.util.List;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedImage;
import de.danoeh.antennapod.core.feed.FeedItem;
+import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
@@ -83,6 +87,11 @@ public class UpdateManager {
}
}.start();
}
+ if(oldVersionCode < 1050004) {
+ if(MediaPlayer.isPrestoLibraryInstalled(context) && Build.VERSION.SDK_INT >= 16) {
+ UserPreferences.enableSonic(true);
+ }
+ }
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java
index 50d557735..12bae2f51 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java
@@ -6,11 +6,11 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Build;
+import android.support.annotation.Nullable;
import android.support.design.widget.AppBarLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
-import android.support.v4.app.ListFragment;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
@@ -28,6 +28,7 @@ import android.widget.ListView;
import com.viewpagerindicator.CirclePageIndicator;
import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.adapter.ChaptersListAdapter;
@@ -83,6 +84,8 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe
AddFeedFragment.TAG
};
+ private AtomicBoolean isSetup = new AtomicBoolean(false);
+
private DrawerLayout drawerLayout;
private NavListAdapter navAdapter;
private ListView navList;
@@ -108,6 +111,16 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe
}
@Override
+ public void onDestroy() {
+ super.onDestroy();
+ // don't risk creating memory leaks
+ navAdapter = null;
+ drawerToggle = null;
+ mPager = null;
+ mPagerAdapter = null;
+ }
+
+ @Override
protected void chooseTheme() {
setTheme(UserPreferences.getNoTitleTheme());
}
@@ -116,7 +129,6 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe
if(mPager == null) {
return;
}
-
Log.d(TAG, "Saving preferences");
SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE);
prefs.edit()
@@ -156,10 +168,9 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe
}
if(mPagerAdapter != null && controller != null && controller.getMedia() != media) {
media = controller.getMedia();
- mPagerAdapter.notifyDataSetChanged();
+ mPagerAdapter.onMediaChanged(media);
}
-
EventDistributor.getInstance().register(contentUpdate);
loadData();
}
@@ -193,6 +204,9 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe
@Override
protected void setupGUI() {
+ if(isSetup.getAndSet(true)) {
+ return;
+ }
super.setupGUI();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
@@ -242,13 +256,11 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe
});
mPager = (ViewPager) findViewById(R.id.pager);
- if(mPager.getAdapter() == null) {
- mPagerAdapter = new AudioplayerPagerAdapter(getSupportFragmentManager());
- mPager.setAdapter(mPagerAdapter);
- CirclePageIndicator pageIndicator = (CirclePageIndicator) findViewById(R.id.page_indicator);
- pageIndicator.setViewPager(mPager);
- loadLastFragment();
- }
+ mPagerAdapter = new AudioplayerPagerAdapter(getSupportFragmentManager());
+ mPager.setAdapter(mPagerAdapter);
+ CirclePageIndicator pageIndicator = (CirclePageIndicator) findViewById(R.id.page_indicator);
+ pageIndicator.setViewPager(mPager);
+ loadLastFragment();
mPager.onSaveInstanceState();
}
@@ -265,16 +277,18 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe
}
if(controller.getMedia() != media) {
media = controller.getMedia();
- mPagerAdapter.notifyDataSetChanged();
+ mPagerAdapter.onMediaChanged(media);
}
return true;
}
public void notifyMediaPositionChanged() {
- ListFragment chapterFragment = (ListFragment) mPagerAdapter.getItem(POS_CHAPTERS);
- ChaptersListAdapter adapter = (ChaptersListAdapter) chapterFragment.getListAdapter();
- if(adapter != null) {
- adapter.notifyDataSetChanged();
+ ChaptersFragment chaptersFragment = mPagerAdapter.getChaptersFragment();
+ if(chaptersFragment != null) {
+ ChaptersListAdapter adapter = (ChaptersListAdapter) chaptersFragment.getListAdapter();
+ if (adapter != null) {
+ adapter.notifyDataSetChanged();
+ }
}
}
@@ -510,7 +524,7 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe
};
public interface AudioplayerContentFragment {
- void onDataSetChanged(Playable media);
+ void onMediaChanged(Playable media);
}
private class AudioplayerPagerAdapter extends FragmentStatePagerAdapter {
@@ -519,22 +533,51 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe
super(fm);
}
+ private CoverFragment coverFragment;
+ private ItemDescriptionFragment itemDescriptionFragment;
+ private ChaptersFragment chaptersFragment;
+
+ public void onMediaChanged(Playable media) {
+ if(coverFragment != null) {
+ coverFragment.onMediaChanged(media);
+ }
+ if(itemDescriptionFragment != null) {
+ itemDescriptionFragment.onMediaChanged(media);
+ }
+ if(chaptersFragment != null) {
+ chaptersFragment.onMediaChanged(media);
+ }
+ }
+
+ @Nullable
+ public ChaptersFragment getChaptersFragment() {
+ return chaptersFragment;
+ }
+
@Override
public Fragment getItem(int position) {
Log.d(TAG, "getItem(" + position + ")");
switch (position) {
case POS_COVER:
- return CoverFragment.newInstance(media);
+ if(coverFragment == null) {
+ coverFragment = CoverFragment.newInstance(media);
+ }
+ return coverFragment;
case POS_DESCR:
- return ItemDescriptionFragment.newInstance(media, true, true);
+ if(itemDescriptionFragment == null) {
+ itemDescriptionFragment = ItemDescriptionFragment.newInstance(media, true, true);
+ }
+ return itemDescriptionFragment;
case POS_CHAPTERS:
- return ChaptersFragment.newInstance(media, controller);
+ if(chaptersFragment == null) {
+ chaptersFragment = ChaptersFragment.newInstance(media, controller);
+ }
+ return chaptersFragment;
default:
return null;
}
}
-
@Override
public int getCount() {
return NUM_CONTENT_FRAGMENTS;
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java
index dedc3d9fd..9116decb0 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java
@@ -18,7 +18,6 @@ import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.CheckBox;
-import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RadioButton;
@@ -67,6 +66,7 @@ public class FeedInfoActivity extends ActionBarActivity {
private RadioButton rdoFilterInclude;
private RadioButton rdoFilterExclude;
private CheckBox cbxAutoDownload;
+ private CheckBox cbxKeepUpdated;
private Spinner spnAutoDelete;
private boolean filterInclude = true;
@@ -106,6 +106,7 @@ public class FeedInfoActivity extends ActionBarActivity {
txtvAuthor = (TextView) findViewById(R.id.txtvAuthor);
txtvUrl = (TextView) findViewById(R.id.txtvUrl);
cbxAutoDownload = (CheckBox) findViewById(R.id.cbxAutoDownload);
+ cbxKeepUpdated = (CheckBox) findViewById(R.id.cbxKeepUpdated);
spnAutoDelete = (Spinner) findViewById(R.id.spnAutoDelete);
etxtUsername = (EditText) findViewById(R.id.etxtUsername);
etxtPassword = (EditText) findViewById(R.id.etxtPassword);
@@ -168,16 +169,18 @@ public class FeedInfoActivity extends ActionBarActivity {
cbxAutoDownload.setEnabled(UserPreferences.isEnableAutodownload());
cbxAutoDownload.setChecked(prefs.getAutoDownload());
- cbxAutoDownload.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
- feed.getPreferences().setAutoDownload(checked);
- feed.savePreferences(FeedInfoActivity.this);
- updateAutoDownloadSettings();
- ApplyToEpisodesDialog dialog = new ApplyToEpisodesDialog(FeedInfoActivity.this,
- feed, checked);
- dialog.createNewDialog().show();
- }
+ cbxAutoDownload.setOnCheckedChangeListener((compoundButton, checked) -> {
+ feed.getPreferences().setAutoDownload(checked);
+ feed.savePreferences(FeedInfoActivity.this);
+ updateAutoDownloadSettings();
+ ApplyToEpisodesDialog dialog = new ApplyToEpisodesDialog(FeedInfoActivity.this,
+ feed, checked);
+ dialog.createNewDialog().show();
+ });
+ cbxKeepUpdated.setChecked(prefs.getKeepUpdated());
+ cbxKeepUpdated.setOnCheckedChangeListener((compoundButton, checked) -> {
+ feed.getPreferences().setKeepUpdated(checked);
+ feed.savePreferences(FeedInfoActivity.this);
});
spnAutoDelete.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
@@ -221,10 +224,12 @@ public class FeedInfoActivity extends ActionBarActivity {
etxtFilterText.setText(filter.getIncludeFilter());
rdoFilterInclude.setChecked(true);
rdoFilterExclude.setChecked(false);
+ filterInclude = true;
} else if (filter.excludeOnly()) {
etxtFilterText.setText(filter.getExcludeFilter());
rdoFilterInclude.setChecked(false);
rdoFilterExclude.setChecked(true);
+ filterInclude = false;
} else {
Log.d(TAG, "No filter set");
rdoFilterInclude.setChecked(false);
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
index 8c2b7f838..c7426c006 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
@@ -35,7 +35,6 @@ import org.jsoup.nodes.Document;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -258,7 +257,7 @@ public class OnlineFeedViewActivity extends ActionBarActivity {
private void startFeedDownload(String url, String username, String password) {
Log.d(TAG, "Starting feed download");
url = URLChecker.prepareURL(url);
- feed = new Feed(url, new Date(0));
+ feed = new Feed(url, null);
if (username != null && password != null) {
feed.setPreferences(new FeedPreferences(0, false, FeedPreferences.AutoDeleteAction.GLOBAL, username, password));
}
@@ -410,7 +409,7 @@ public class OnlineFeedViewActivity extends ActionBarActivity {
subscribeButton.setOnClickListener(v -> {
try {
- Feed f = new Feed(selectedDownloadUrl, new Date(0), feed.getTitle());
+ Feed f = new Feed(selectedDownloadUrl, null, feed.getTitle());
f.setPreferences(feed.getPreferences());
this.feed = f;
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportBaseActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportBaseActivity.java
index d974e0e1b..46dabec12 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportBaseActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportBaseActivity.java
@@ -1,16 +1,27 @@
package de.danoeh.antennapod.activity;
import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Environment;
+import android.support.v4.app.ActivityCompat;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
-import de.danoeh.antennapod.BuildConfig;
-import de.danoeh.antennapod.asynctask.OpmlFeedQueuer;
-import de.danoeh.antennapod.asynctask.OpmlImportWorker;
-import de.danoeh.antennapod.core.opml.OpmlElement;
+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.OpmlImportWorker;
+import de.danoeh.antennapod.core.opml.OpmlElement;
+import de.danoeh.antennapod.core.util.LangUtils;
+
/**
* Base activity for Opml Import - e.g. with code what to do afterwards
* */
@@ -19,22 +30,23 @@ public class OpmlImportBaseActivity extends ActionBarActivity {
private static final String TAG = "OpmlImportBaseActivity";
private OpmlImportWorker importWorker;
- /**
+ private static final int PERMISSION_REQUEST_READ_EXTERNAL_STORAGE = 5;
+ private Uri uri;
+
+ /**
* Handles the choices made by the user in the OpmlFeedChooserActivity and
* starts the OpmlFeedQueuer if necessary.
*/
@Override
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 (BuildConfig.DEBUG)
- Log.d(TAG, "Activity was cancelled");
- if (finishWhenCanceled())
- finish();
+ Log.d(TAG, "Activity was cancelled");
+ if (finishWhenCanceled()) {
+ finish();
+ }
} else {
- int[] selected = data
- .getIntArrayExtra(OpmlFeedChooserActivity.EXTRA_SELECTED_ITEMS);
+ int[] selected = data.getIntArrayExtra(OpmlFeedChooserActivity.EXTRA_SELECTED_ITEMS);
if (selected != null && selected.length > 0) {
OpmlFeedQueuer queuer = new OpmlFeedQueuer(this, selected) {
@@ -50,35 +62,75 @@ public class OpmlImportBaseActivity extends ActionBarActivity {
};
queuer.executeAsync();
} else {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "No items were selected");
+ Log.d(TAG, "No items were selected");
}
}
}
- /** Starts the import process. */
- protected void startImport(Reader reader) {
+ protected void importUri(Uri uri) {
+ 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();
+ }
+
+ private void requestPermission() {
+ String[] permissions = { android.Manifest.permission.READ_EXTERNAL_STORAGE };
+ ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST_READ_EXTERNAL_STORAGE);
+ }
- if (reader != null) {
- importWorker = new OpmlImportWorker(this, reader) {
+ @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
protected void onPostExecute(ArrayList<OpmlElement> result) {
super.onPostExecute(result);
if (result != null) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Parsing was successful");
+ Log.d(TAG, "Parsing was successful");
OpmlImportHolder.setReadElements(result);
startActivityForResult(new Intent(
OpmlImportBaseActivity.this,
OpmlFeedChooserActivity.class), 0);
} else {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Parser error occurred");
+ Log.d(TAG, "Parser error occurred");
}
}
};
importWorker.executeAsync();
+ } catch (Exception e) {
+ Log.d(TAG, Log.getStackTraceString(e));
+ new MaterialDialog.Builder(this)
+ .content("Cannot open OPML file: " + e.getMessage())
+ .positiveText(android.R.string.ok)
+ .show();
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromIntentActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromIntentActivity.java
index 46e5f0e8e..ab4b0d0ee 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromIntentActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromIntentActivity.java
@@ -2,25 +2,14 @@ package de.danoeh.antennapod.activity;
import android.net.Uri;
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.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. */
public class OpmlImportFromIntentActivity extends OpmlImportBaseActivity {
private static final String TAG = "OpmlImportFromIntentAct";
-
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(UserPreferences.getTheme());
@@ -28,15 +17,8 @@ public class OpmlImportFromIntentActivity extends OpmlImportBaseActivity {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
- try {
- Uri uri = getIntent().getData();
-
- 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();
- }
-
+ Uri uri = getIntent().getData();
+ importUri(uri);
}
@Override
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromPathActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromPathActivity.java
index 6e3991739..15d97cc2c 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromPathActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromPathActivity.java
@@ -11,16 +11,9 @@ import android.view.View;
import android.widget.Button;
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.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.util.IntentUtils;
-import de.danoeh.antennapod.core.util.LangUtils;
import de.danoeh.antennapod.core.util.StorageUtils;
/**
@@ -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
* the user choose a specific OPML-file to import from.
@@ -155,13 +135,7 @@ public class OpmlImportFromPathActivity extends OpmlImportBaseActivity {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == CHOOSE_OPML_FILE) {
Uri uri = data.getData();
-
- try {
- Reader mReader = new InputStreamReader(getContentResolver().openInputStream(uri), LangUtils.UTF_8);
- startImport(mReader);
- } catch (FileNotFoundException e) {
- Log.d(TAG, "File not found");
- }
+ importUri(uri);
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java
index fbea102eb..ee459dbc6 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java
@@ -20,6 +20,7 @@ import android.widget.ProgressBar;
import android.widget.SeekBar;
import java.lang.ref.WeakReference;
+import java.util.concurrent.atomic.AtomicBoolean;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.MediaType;
@@ -43,6 +44,8 @@ public class VideoplayerActivity extends MediaplayerActivity {
private VideoControlsHider videoControlsHider = new VideoControlsHider(this);
+ private AtomicBoolean isSetup = new AtomicBoolean(false);
+
private LinearLayout controls;
private LinearLayout videoOverlay;
private AspectRatioVideoView videoview;
@@ -115,6 +118,9 @@ public class VideoplayerActivity extends MediaplayerActivity {
@Override
protected void setupGUI() {
+ if(isSetup.getAndSet(true)) {
+ return;
+ }
super.setupGUI();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
controls = (LinearLayout) findViewById(R.id.controls);
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java
index 582538fb8..893c92907 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java
@@ -13,8 +13,6 @@ import android.widget.Toast;
import com.joanzapata.iconify.Iconify;
import com.joanzapata.iconify.widget.IconButton;
-import java.util.Date;
-
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
import de.danoeh.antennapod.core.feed.Feed;
@@ -123,9 +121,8 @@ public class DownloadLogAdapter extends BaseAdapter {
if(holder.typeId == Feed.FEEDFILETYPE_FEED) {
Feed feed = DBReader.getFeed(holder.id);
if (feed != null) {
- feed.setLastUpdate(new Date(0)); // force refresh
try {
- DBTasks.refreshFeed(context, feed);
+ DBTasks.forceRefreshFeed(context, feed);
} catch (DownloadRequestException e) {
e.printStackTrace();
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java
index 9011c8b02..5b205e91f 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java
@@ -6,11 +6,13 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
-import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.feed.FeedItem;
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.
*/
@@ -33,6 +35,7 @@ public class FeedItemlistDescriptionAdapter extends ArrayAdapter<FeedItem> {
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.itemdescription_listitem, parent, false);
holder.title = (TextView) convertView.findViewById(R.id.txtvTitle);
+ holder.pubDate = (TextView) convertView.findViewById(R.id.txtvPubDate);
holder.description = (TextView) convertView.findViewById(R.id.txtvDescription);
convertView.setTag(holder);
@@ -41,15 +44,20 @@ public class FeedItemlistDescriptionAdapter extends ArrayAdapter<FeedItem> {
}
holder.title.setText(item.getTitle());
+ holder.pubDate.setText(DateUtils.formatAbbrev(getContext(), item.getPubDate()));
if (item.getDescription() != null) {
- holder.description.setText(item.getDescription());
+ String description = item.getDescription()
+ .replaceAll("\n", " ")
+ .replaceAll("\\s+", " ")
+ .trim();
+ holder.description.setText(description);
}
-
return convertView;
}
static class Holder {
TextView title;
+ TextView pubDate;
TextView description;
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlFeedQueuer.java b/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlFeedQueuer.java
index 00327bce0..cc27b6c9d 100644
--- a/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlFeedQueuer.java
+++ b/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlFeedQueuer.java
@@ -6,7 +6,6 @@ import android.content.Context;
import android.os.AsyncTask;
import java.util.Arrays;
-import java.util.Date;
import de.danoeh.antennapod.activity.OpmlImportHolder;
import de.danoeh.antennapod.core.R;
@@ -47,7 +46,7 @@ public class OpmlFeedQueuer extends AsyncTask<Void, Void, Void> {
for (int idx = 0; idx < selection.length; idx++) {
OpmlElement element = OpmlImportHolder.getReadElements().get(
selection[idx]);
- Feed feed = new Feed(element.getXmlUrl(), new Date(0),
+ Feed feed = new Feed(element.getXmlUrl(), null,
element.getText());
try {
requester.downloadFeed(context.getApplicationContext(), feed);
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java
index abc9f3d22..96abdd835 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java
@@ -55,11 +55,20 @@ public class ChaptersFragment extends ListFragment implements AudioplayerContent
}
}
+ public void onDestroy() {
+ super.onDestroy();
+ adapter = null;
+ }
+
@Override
- public void onDataSetChanged(Playable media) {
+ public void onMediaChanged(Playable media) {
+ if(this.media == media || adapter == null) {
+ return;
+ }
+ this.media = media;
adapter.setMedia(media);
adapter.notifyDataSetChanged();
- if(media.getChapters() == null) {
+ if(media == null || media.getChapters() == null || media.getChapters().size() == 0) {
setEmptyText(getString(R.string.no_items_label));
} else {
setEmptyText(null);
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java
index a3e9723ea..931d14924 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java
@@ -19,8 +19,8 @@ import de.danoeh.antennapod.core.util.playback.Playable;
/**
* Displays the cover and the title of a FeedItem.
*/
-public class CoverFragment extends Fragment implements
- AudioplayerContentFragment {
+public class CoverFragment extends Fragment implements AudioplayerContentFragment {
+
private static final String TAG = "CoverFragment";
private static final String ARG_PLAYABLE = "arg.playable";
@@ -71,14 +71,12 @@ public class CoverFragment extends Fragment implements
Log.d(TAG, "episode title: " + media.getEpisodeTitle());
txtvPodcastTitle.setText(media.getFeedTitle());
txtvEpisodeTitle.setText(media.getEpisodeTitle());
- imgvCover.post(() -> {
- Glide.with(this)
- .load(media.getImageUri())
- .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
- .dontAnimate()
- .fitCenter()
- .into(imgvCover);
- });
+ Glide.with(this)
+ .load(media.getImageUri())
+ .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
+ .dontAnimate()
+ .fitCenter()
+ .into(imgvCover);
} else {
Log.w(TAG, "loadMediaInfo was called while media was null");
}
@@ -97,7 +95,17 @@ public class CoverFragment extends Fragment implements
}
@Override
- public void onDataSetChanged(Playable media) {
+ public void onDestroy() {
+ super.onDestroy();
+ // prevent memory leaks
+ root = null;
+ }
+
+ @Override
+ public void onMediaChanged(Playable media) {
+ if(this.media == media) {
+ return;
+ }
this.media = media;
loadMediaInfo();
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
index 9790e66b3..4c723e5ff 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
@@ -21,7 +21,7 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
-import android.webkit.WebSettings.LayoutAlgorithm;
+import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
@@ -67,7 +67,6 @@ public class ItemDescriptionFragment extends Fragment implements AudioplayerCont
private ShownotesProvider shownotesProvider;
private Playable media;
-
private Subscription webViewLoader;
/**
@@ -124,7 +123,7 @@ public class ItemDescriptionFragment extends Fragment implements AudioplayerCont
ta.recycle();
webvDescription.setBackgroundColor(backgroundColor);
webvDescription.getSettings().setUseWideViewPort(false);
- webvDescription.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
+ webvDescription.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
webvDescription.getSettings().setLoadWithOverviewMode(true);
webvDescription.setOnLongClickListener(webViewLongClickListener);
webvDescription.setWebViewClient(new WebViewClient() {
@@ -384,7 +383,10 @@ public class ItemDescriptionFragment extends Fragment implements AudioplayerCont
}
@Override
- public void onDataSetChanged(Playable media) {
+ public void onMediaChanged(Playable media) {
+ if(this.media == media) {
+ return;
+ }
this.media = media;
this.shownotesProvider = media;
load();
diff --git a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java
index 830e9d419..38030f4ea 100644
--- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java
+++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java
@@ -63,10 +63,10 @@ public class FeedMenuHandler {
final Feed selectedFeed) throws DownloadRequestException {
switch (item.getItemId()) {
case R.id.refresh_item:
- DBTasks.refreshFeed(context, selectedFeed);
+ DBTasks.forceRefreshFeed(context, selectedFeed);
break;
case R.id.refresh_complete_item:
- DBTasks.refreshCompleteFeed(context, selectedFeed);
+ DBTasks.forceRefreshCompleteFeed(context, selectedFeed);
break;
case R.id.filter_items:
showFilterDialog(context, selectedFeed);
diff --git a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java
index 083ac5202..785944768 100644
--- a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java
+++ b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java
@@ -397,12 +397,11 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
ui.findPreference("prefSendCrashReport").setOnPreferenceClickListener(preference -> {
Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setType("text/plain");
- String to[] = { "Martin.Fietz@gmail.com" };
- emailIntent .putExtra(Intent.EXTRA_EMAIL, to);
+ emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{"Martin.Fietz@gmail.com"});
+ emailIntent.putExtra(Intent.EXTRA_SUBJECT, "AntennaPod Crash Report");
+ emailIntent.putExtra(Intent.EXTRA_TEXT, "Please describe what you were doing when the app crashed");
// the attachment
- emailIntent .putExtra(Intent.EXTRA_STREAM, Uri.fromFile(CrashReportWriter.getFile()));
- // the mail subject
- emailIntent .putExtra(Intent.EXTRA_SUBJECT, "AntennaPod Crash Report");
+ emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(CrashReportWriter.getFile()));
String intentTitle = ui.getActivity().getString(R.string.send_email);
ui.getActivity().startActivity(Intent.createChooser(emailIntent, intentTitle));
return true;
diff --git a/app/src/main/java/de/danoeh/antennapod/receiver/SPAReceiver.java b/app/src/main/java/de/danoeh/antennapod/receiver/SPAReceiver.java
index ef6330f82..8201fe3e2 100644
--- a/app/src/main/java/de/danoeh/antennapod/receiver/SPAReceiver.java
+++ b/app/src/main/java/de/danoeh/antennapod/receiver/SPAReceiver.java
@@ -8,7 +8,6 @@ import android.util.Log;
import android.widget.Toast;
import java.util.Arrays;
-import java.util.Date;
import de.danoeh.antennapod.BuildConfig;
import de.danoeh.antennapod.R;
@@ -35,7 +34,7 @@ public class SPAReceiver extends BroadcastReceiver{
if (feedUrls != null) {
if (BuildConfig.DEBUG) Log.d(TAG, "Received feeds list: " + Arrays.toString(feedUrls));
for (String url : feedUrls) {
- Feed f = new Feed(url, new Date(0));
+ Feed f = new Feed(url, null);
try {
DownloadRequester.getInstance().downloadFeed(context, f);
} catch (DownloadRequestException e) {
diff --git a/app/src/main/res/layout/feedinfo.xml b/app/src/main/res/layout/feedinfo.xml
index efc367c8b..4b545e3cc 100644
--- a/app/src/main/res/layout/feedinfo.xml
+++ b/app/src/main/res/layout/feedinfo.xml
@@ -181,6 +181,17 @@
android:clickable="true" />
</android.support.v7.widget.GridLayout>
+ <CheckBox
+ android:id="@+id/cbxKeepUpdated"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dp"
+ android:text="@string/keep_updated"
+ android:enabled="true"
+ android:textColor="?android:attr/textColorPrimary"
+ tools:background="@android:color/holo_red_light"
+ android:checked="true" />
+
<TextView
android:id="@+id/txtvAuthentication"
android:layout_width="match_parent"
diff --git a/app/src/main/res/layout/itemdescription_listitem.xml b/app/src/main/res/layout/itemdescription_listitem.xml
index ca8f974bf..51bc9a5eb 100644
--- a/app/src/main/res/layout/itemdescription_listitem.xml
+++ b/app/src/main/res/layout/itemdescription_listitem.xml
@@ -1,30 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
+ android:layout_height="wrap_content"
+ android:paddingTop="8dp"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp"
+ android:paddingBottom="8dp"
tools:background="@android:color/holo_orange_light">
<TextView
+ android:id="@+id/txtvPubDate"
+ style="@android:style/TextAppearance.Small"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:layout_alignParentTop="true"
+ android:layout_marginLeft="8dp"
+ android:textSize="14sp"
+ android:textColor="?android:textColorSecondary"
+ android:ellipsize="end"
+ android:lines="1"
+ tools:text="22 Jan 2016"
+ tools:background="@android:color/holo_green_dark" />
+
+ <TextView
android:id="@+id/txtvTitle"
- style="@style/AntennaPod.TextView.ListItemPrimaryTitle"
- android:layout_width="match_parent"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_margin="16dp"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentTop="true"
+ android:layout_toLeftOf="@id/txtvPubDate"
+ android:textSize="16sp"
+ android:textColor="?android:attr/textColorPrimary"
+ android:ellipsize="end"
+ android:maxLines="2"
tools:text="Feed item title"
tools:background="@android:color/holo_green_dark" />
<TextView
android:id="@+id/txtvDescription"
- style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginBottom="16dp"
- android:layout_marginLeft="16dp"
- android:layout_marginRight="16dp"
- android:lines="3"
+ android:layout_below="@id/txtvTitle"
+ android:textSize="14sp"
+ android:textColor="?android:attr/textColorSecondary"
+ android:ellipsize="end"
+ android:maxLines="3"
tools:text="Feed item description"
tools:background="@android:color/holo_green_dark" />
-</LinearLayout>
+
+</RelativeLayout>