Fixed problem with automatic feed updates

This commit is contained in:
daniel oeh 2013-10-04 17:23:38 +02:00
parent 44e4924db9
commit 15446f1847
7 changed files with 144 additions and 37 deletions

View File

@ -347,6 +347,20 @@ public class UserPreferences implements
editor.commit();
}
/**
* Sets the update interval value. Should only be used for testing purposes!
* */
public static void setUpdateInterval(Context context, long newValue) {
instanceAvailable();
SharedPreferences.Editor editor = PreferenceManager
.getDefaultSharedPreferences(context.getApplicationContext())
.edit();
editor.putString(PREF_UPDATE_INTERVAL,
String.valueOf(newValue));
editor.commit();
instance.updateInterval = newValue;
}
/**
* Return the folder where the app stores all of its data. This method will
* return the standard data folder if none has been set by the user.

View File

@ -106,7 +106,7 @@ public final class DBReader {
* of the returned list does NOT have its list of FeedItems yet. The FeedItem-list
* can be loaded separately with {@link #getFeedItemList(android.content.Context, de.danoeh.antennapod.feed.Feed)}.
*/
static List<Feed> getExpiredFeedsList(final Context context, final long expirationTime) {
public static List<Feed> getExpiredFeedsList(final Context context, final long expirationTime) {
if (AppConfig.DEBUG)
Log.d(TAG, String.format("getExpiredFeedsList(%d)", expirationTime));

View File

@ -1,27 +1,11 @@
package de.danoeh.antennapod.storage;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.atomic.AtomicBoolean;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.util.Log;
import de.danoeh.antennapod.AppConfig;
import de.danoeh.antennapod.feed.EventDistributor;
import de.danoeh.antennapod.feed.Feed;
import de.danoeh.antennapod.feed.FeedImage;
import de.danoeh.antennapod.feed.FeedItem;
import de.danoeh.antennapod.feed.FeedMedia;
import de.danoeh.antennapod.feed.*;
import de.danoeh.antennapod.preferences.UserPreferences;
import de.danoeh.antennapod.service.GpodnetSyncService;
import de.danoeh.antennapod.service.PlaybackService;
@ -32,6 +16,12 @@ import de.danoeh.antennapod.util.QueueAccess;
import de.danoeh.antennapod.util.comparator.FeedItemPubdateComparator;
import de.danoeh.antennapod.util.exception.MediaFileNotFoundException;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Provides methods for doing common tasks that use DBReader and DBWriter.
*/
@ -43,9 +33,10 @@ public final class DBTasks {
/**
* Removes the feed with the given download url. This method should NOT be executed on the GUI thread.
* @param context Used for accessing the db
*
* @param context Used for accessing the db
* @param downloadUrl URL of the feed.
* */
*/
public static void removeFeedWithDownloadUrl(Context context, String downloadUrl) {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open();
@ -156,6 +147,30 @@ public final class DBTasks {
}
}
/**
* Used by refreshExpiredFeeds to determine which feeds should be refreshed.
* This method will use the value specified in the UserPreferences as the
* expiration time.
* @param context Used for DB access.
* @return A list of expired feeds. An empty list will be returned if there
* are no expired feeds.
*/
public static List<Feed> getExpiredFeeds(final Context context) {
long millis = UserPreferences.getUpdateInterval();
if (millis > 0) {
List<Feed> feedList = DBReader.getExpiredFeedsList(context,
millis);
if (feedList.size() > 0) {
refreshFeeds(context, feedList);
}
return feedList;
} else {
return new ArrayList<Feed>();
}
}
/**
* Refreshes expired Feeds in the list returned by the getExpiredFeedsList(Context, long) method in DBReader.
* The expiration date parameter is determined by the update interval specified in {@link UserPreferences}.
@ -168,19 +183,7 @@ public final class DBTasks {
new Thread() {
public void run() {
long millis = UserPreferences.getUpdateInterval();
if (millis > 0) {
long now = Calendar.getInstance().getTime().getTime();
// Allow a 10 minute window
millis -= 10 * 60 * 1000;
List<Feed> feedList = DBReader.getExpiredFeedsList(context,
now - millis);
if (feedList.size() > 0) {
refreshFeeds(context, feedList);
}
}
refreshFeeds(context, getExpiredFeeds(context));
}
}.start();
}

View File

@ -675,8 +675,8 @@ public class PodDBAdapter {
}
public final Cursor getExpiredFeedsCursor(long expirationTime) {
Cursor c = db.query(TABLE_NAME_FEEDS, null, "?<?", new String[]{
KEY_LASTUPDATE, String.valueOf(System.currentTimeMillis() - expirationTime)}, null, null,
Cursor c = db.query(TABLE_NAME_FEEDS, null, KEY_LASTUPDATE + " < " + String.valueOf(System.currentTimeMillis() - expirationTime),
null, null, null,
null);
return c;
}

View File

@ -12,7 +12,9 @@ public class AntennaPodTestRunner extends InstrumentationTestRunner {
@Override
public TestSuite getAllTests() {
return new TestSuiteBuilder(AntennaPodTestRunner.class).includeAllPackagesUnderHere().build();
//return new TestSuiteBuilder(AntennaPodTestRunner.class).includeAllPackagesUnderHere().excludePackages("instrumentationTest.de.test.antennapod.syndication.handler").build();
return new TestSuiteBuilder(AntennaPodTestRunner.class).includeAllPackagesUnderHere()
// .excludePackages("instrumentationTest.de.test.antennapod.syndication.handler")
// .excludePackages("instrumentationTest.de.test.antennapod.gpodnet")
.build();
}
}

View File

@ -1,11 +1,67 @@
package instrumentationTest.de.test.antennapod.storage;
import android.content.Context;
import android.test.InstrumentationTestCase;
import de.danoeh.antennapod.feed.Feed;
import de.danoeh.antennapod.feed.FeedItem;
import de.danoeh.antennapod.storage.DBReader;
import de.danoeh.antennapod.storage.PodDBAdapter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* Test class for DBReader
*/
public class DBReaderTest extends InstrumentationTestCase {
@Override
protected void tearDown() throws Exception {
super.tearDown();
final Context context = getInstrumentation().getTargetContext();
assertTrue(PodDBAdapter.deleteDatabase(context));
}
@Override
protected void setUp() throws Exception {
super.setUp();
final Context context = getInstrumentation().getTargetContext();
context.deleteDatabase(PodDBAdapter.DATABASE_NAME);
// make sure database is created
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open();
adapter.close();
}
private void expiredFeedListTestHelper(long lastUpdate, long expirationTime, boolean shouldReturn) {
final Context context = getInstrumentation().getTargetContext();
Feed feed = new Feed(0, new Date(lastUpdate), "feed", "link", "descr", null,
null, null, null, "feed", null, null, "url", false);
feed.setItems(new ArrayList<FeedItem>());
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open();
adapter.setCompleteFeed(feed);
adapter.close();
assertTrue(feed.getId() != 0);
List<Feed> expiredFeeds = DBReader.getExpiredFeedsList(context, expirationTime);
assertNotNull(expiredFeeds);
if (shouldReturn) {
assertTrue(expiredFeeds.size() == 1);
assertTrue(expiredFeeds.get(0).getId() == feed.getId());
} else {
assertTrue(expiredFeeds.isEmpty());
}
}
public void testGetExpiredFeedsListShouldReturnFeed() {
final long expirationTime = 1000 * 60 * 60; // 1 hour
expiredFeedListTestHelper(System.currentTimeMillis() - expirationTime - 1, expirationTime, true);
}
public void testGetExpiredFeedsListShouldNotReturnFeed() {
final long expirationTime = 1000 * 60 * 60; // 1 hour
expiredFeedListTestHelper(System.currentTimeMillis() - expirationTime / 2, expirationTime, false);
}
}

View File

@ -249,4 +249,36 @@ public class DBTasksTest extends InstrumentationTestCase {
lastDate = item.getPubDate();
}
}
private void expiredFeedListTestHelper(long lastUpdate, long expirationTime, boolean shouldReturn) {
final Context context = getInstrumentation().getTargetContext();
UserPreferences.setUpdateInterval(context, expirationTime);
Feed feed = new Feed(0, new Date(lastUpdate), "feed", "link", "descr", null,
null, null, null, "feed", null, null, "url", false);
feed.setItems(new ArrayList<FeedItem>());
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open();
adapter.setCompleteFeed(feed);
adapter.close();
assertTrue(feed.getId() != 0);
List<Feed> expiredFeeds = DBTasks.getExpiredFeeds(context);
assertNotNull(expiredFeeds);
if (shouldReturn) {
assertTrue(expiredFeeds.size() == 1);
assertTrue(expiredFeeds.get(0).getId() == feed.getId());
} else {
assertTrue(expiredFeeds.isEmpty());
}
}
public void testGetExpiredFeedsTestShouldReturn() {
final long expirationTime = 1000 * 60 * 60;
expiredFeedListTestHelper(System.currentTimeMillis() - expirationTime - 1, expirationTime, true);
}
public void testGetExpiredFeedsTestShouldNotReturn() {
final long expirationTime = 1000 * 60 * 60;
expiredFeedListTestHelper(System.currentTimeMillis() - expirationTime / 2, expirationTime, false);
}
}