Added 'title' and 'reasonDetailed' attributes to DownloadStatus

This commit is contained in:
daniel oeh 2012-09-20 19:03:21 +02:00
parent f78bb0be13
commit 82db128a66
10 changed files with 153 additions and 87 deletions

View File

@ -16,43 +16,57 @@ public class DownloadStatus {
return completionDate;
}
// ----------------------------------- ATTRIBUTES STORED IN DB
/** Unique id for storing the object in database. */
protected long id;
/**
* A human-readable string which is shown to the user so that he can
* identify the download. Should be the title of the item/feed/media or the
* URL if the download has no other title.
*/
protected String title;
protected int reason;
/**
* A message which can be presented to the user to give more information.
* Should be null if Download was successful.
*/
protected String reasonDetailed;
protected boolean successful;
protected Date completionDate;
/** Used by DownloadService to check if the status has been updated. */
protected volatile boolean updateAvailable;
// ------------------------------------ NOT STORED IN DB
protected FeedFile feedfile;
protected int progressPercent;
protected long soFar;
protected long size;
protected int statusMsg;
protected int reason;
protected boolean successful;
protected boolean done;
protected Date completionDate;
public DownloadStatus(FeedFile feedfile) {
this.feedfile = feedfile;
}
/** Constructor for restoring Download status entries from DB. */
public DownloadStatus(long id, FeedFile feedfile, boolean successful,
int reason, Date completionDate) {
this.id = id;
this.feedfile = feedfile;
public DownloadStatus(long id, String title, FeedFile feedfile,
boolean successful, int reason, Date completionDate,
String reasonDetailed) {
progressPercent = 100;
soFar = 0;
size = 0;
this.id = id;
this.title = title;
this.done = true;
this.feedfile = feedfile;
this.reason = reason;
this.successful = successful;
this.done = true;
this.completionDate = completionDate;
}
/** Constructor for creating new completed downloads. */
public DownloadStatus(FeedFile feedfile, int reason, boolean successful) {
this(0, feedfile, successful, reason, new Date());
public DownloadStatus(FeedFile feedfile, String title, int reason,
boolean successful, String reasonDetailed) {
this(0, title, feedfile, successful, reason, new Date(), reasonDetailed);
}
public FeedFile getFeedFile() {
@ -131,12 +145,20 @@ public class DownloadStatus {
this.completionDate = completionDate;
}
public boolean isUpdateAvailable() {
return updateAvailable;
public String getReasonDetailed() {
return reasonDetailed;
}
public void setUpdateAvailable(boolean updateAvailable) {
this.updateAvailable = updateAvailable;
public void setReasonDetailed(String reasonDetailed) {
this.reasonDetailed = reasonDetailed;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}

View File

@ -134,6 +134,15 @@ public class Feed extends FeedFile {
}
}
@Override
public String getHumanReadableIdentifier() {
if (title != null) {
return title;
} else {
return download_url;
}
}
public String getTitle() {
return title;
}

View File

@ -17,6 +17,12 @@ public abstract class FeedFile extends FeedComponent {
this(null, null, false);
}
/**
* Should return a non-null, human-readable String so that the item can be
* identified by the user. Can be title, download-url, etc.
*/
public abstract String getHumanReadableIdentifier();
public String getFile_url() {
return file_url;
}

View File

@ -17,6 +17,15 @@ public class FeedImage extends FeedFile {
this.title = title;
}
@Override
public String getHumanReadableIdentifier() {
if (feed != null && feed.getTitle() != null) {
return feed.getTitle();
} else {
return download_url;
}
}
public FeedImage() {
super();
}

View File

@ -950,32 +950,34 @@ public class FeedManager {
if (logCursor.moveToFirst()) {
do {
long id = logCursor.getLong(PodDBAdapter.KEY_ID_INDEX);
FeedFile feedfile = null;
long feedfileId = logCursor
.getLong(PodDBAdapter.KEY_FEEDFILE_INDEX);
int feedfileType = logCursor
.getInt(PodDBAdapter.KEY_FEEDFILETYPE_INDEX);
FeedFile feedfile = null;
switch (feedfileType) {
case PodDBAdapter.FEEDFILETYPE_FEED:
feedfile = getFeed(feedfileId);
break;
case PodDBAdapter.FEEDFILETYPE_FEEDIMAGE:
feedfile = getFeedImage(feedfileId);
break;
case PodDBAdapter.FEEDFILETYPE_FEEDMEDIA:
feedfile = getFeedMedia(feedfileId);
}
if (feedfile != null) { // otherwise ignore status
boolean successful = logCursor
.getInt(PodDBAdapter.KEY_SUCCESSFUL_INDEX) > 0;
int reason = logCursor
.getInt(PodDBAdapter.KEY_REASON_INDEX);
Date completionDate = new Date(
logCursor
.getLong(PodDBAdapter.KEY_COMPLETION_DATE_INDEX));
downloadLog.add(new DownloadStatus(id, feedfile,
successful, reason, completionDate));
if (feedfileId != 0) {
int feedfileType = logCursor
.getInt(PodDBAdapter.KEY_FEEDFILETYPE_INDEX);
switch (feedfileType) {
case PodDBAdapter.FEEDFILETYPE_FEED:
feedfile = getFeed(feedfileId);
break;
case PodDBAdapter.FEEDFILETYPE_FEEDIMAGE:
feedfile = getFeedImage(feedfileId);
break;
case PodDBAdapter.FEEDFILETYPE_FEEDMEDIA:
feedfile = getFeedMedia(feedfileId);
}
}
boolean successful = logCursor
.getInt(PodDBAdapter.KEY_SUCCESSFUL_INDEX) > 0;
int reason = logCursor.getInt(PodDBAdapter.KEY_REASON_INDEX);
String reasonDetailed = logCursor.getString(PodDBAdapter.KEY_REASON_DETAILED_INDEX);
String title = logCursor.getString(PodDBAdapter.KEY_DOWNLOADSTATUS_TITLE_INDEX);
Date completionDate = new Date(
logCursor
.getLong(PodDBAdapter.KEY_COMPLETION_DATE_INDEX));
downloadLog.add(new DownloadStatus(id, title, feedfile, successful,
reason, completionDate, reasonDetailed));
} while (logCursor.moveToNext());
}

View File

@ -1,21 +1,23 @@
package de.danoeh.antennapod.feed;
public class FeedMedia extends FeedFile{
public class FeedMedia extends FeedFile {
private int duration;
private int position; // Current position in file
private long size; // File size in Byte
private int position; // Current position in file
private long size; // File size in Byte
private String mime_type;
private FeedItem item;
public FeedMedia(FeedItem i, String download_url, long size, String mime_type) {
public FeedMedia(FeedItem i, String download_url, long size,
String mime_type) {
super(null, download_url, false);
this.item = i;
this.size = size;
this.mime_type = mime_type;
}
public FeedMedia(long id, FeedItem item, int duration, int position, long size, String mime_type,
String file_url, String download_url, boolean downloaded) {
public FeedMedia(long id, FeedItem item, int duration, int position,
long size, String mime_type, String file_url, String download_url,
boolean downloaded) {
super(file_url, download_url, downloaded);
this.id = id;
this.item = item;
@ -24,15 +26,22 @@ public class FeedMedia extends FeedFile{
this.size = size;
this.mime_type = mime_type;
}
public FeedMedia(long id,FeedItem item) {
public FeedMedia(long id, FeedItem item) {
super();
this.id = id;
this.item = item;
}
@Override
public String getHumanReadableIdentifier() {
if (item != null && item.getTitle() != null) {
return item.getTitle();
} else {
return download_url;
}
}
public int getDuration() {
return duration;
}
@ -72,10 +81,5 @@ public class FeedMedia extends FeedFile{
public void setItem(FeedItem item) {
this.item = item;
}
}

View File

@ -101,7 +101,6 @@ public class DownloadService extends Service {
private NotificationCompat.Builder notificationBuilder;
private int NOTIFICATION_ID = 2;
private int REPORT_ID = 3;
private List<Downloader> downloads;
@ -543,6 +542,7 @@ public class DownloadService extends Service {
public void run() {
Feed savedFeed = null;
reason = 0;
String reasonDetailed = null;
successful = true;
FeedManager manager = FeedManager.getInstance();
FeedHandler handler = new FeedHandler();
@ -571,22 +571,27 @@ public class DownloadService extends Service {
successful = false;
e.printStackTrace();
reason = DownloadError.ERROR_PARSER_EXCEPTION;
reasonDetailed = e.getMessage();
} catch (IOException e) {
successful = false;
e.printStackTrace();
reason = DownloadError.ERROR_PARSER_EXCEPTION;
reasonDetailed = e.getMessage();
} catch (ParserConfigurationException e) {
successful = false;
e.printStackTrace();
reason = DownloadError.ERROR_PARSER_EXCEPTION;
reasonDetailed = e.getMessage();
} catch (UnsupportedFeedtypeException e) {
e.printStackTrace();
successful = false;
reason = DownloadError.ERROR_UNSUPPORTED_TYPE;
reasonDetailed = e.getMessage();
} catch (InvalidFeedException e) {
e.printStackTrace();
successful = false;
reason = DownloadError.ERROR_PARSER_EXCEPTION;
reasonDetailed = e.getMessage();
}
// cleanup();
@ -594,7 +599,9 @@ public class DownloadService extends Service {
savedFeed = feed;
}
saveDownloadStatus(new DownloadStatus(savedFeed, reason, successful));
saveDownloadStatus(new DownloadStatus(savedFeed,
savedFeed.getHumanReadableIdentifier(), reason, successful,
reasonDetailed));
sendDownloadHandledIntent(DOWNLOAD_TYPE_FEED);
downloadsBeingHandled -= 1;
queryDownloads();
@ -684,7 +691,7 @@ public class DownloadService extends Service {
} finally {
mediaplayer.release();
}
saveDownloadStatus(status);
sendDownloadHandledIntent(DOWNLOAD_TYPE_MEDIA);
manager.setFeedMedia(DownloadService.this, media);

View File

@ -43,10 +43,6 @@ public abstract class Downloader extends Thread {
}
}
protected void publishProgress() {
status.setUpdateAvailable(true);
}
protected abstract void download();
@Override

View File

@ -35,7 +35,6 @@ public class HttpDownloader extends Downloader {
OutputStream out = null;
try {
status.setStatusMsg(R.string.download_pending);
publishProgress();
URL url = new URL(status.getFeedFile().getDownload_url());
connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(CONNECTION_TIMEOUT);
@ -66,7 +65,6 @@ public class HttpDownloader extends Downloader {
Log.d(TAG, "Free space is " + freeSpace);
if (status.getSize() == DownloadStatus.SIZE_UNKNOWN
|| status.getSize() <= freeSpace) {
publishProgress();
if (AppConfig.DEBUG)
Log.d(TAG, "Starting download");
while (!cancelled && (count = in.read(buffer)) != -1) {
@ -81,23 +79,23 @@ public class HttpDownloader extends Downloader {
onSuccess();
}
} else {
onFail(DownloadError.ERROR_NOT_ENOUGH_SPACE);
onFail(DownloadError.ERROR_NOT_ENOUGH_SPACE, null);
}
} else {
onFail(DownloadError.ERROR_FILE_EXISTS);
onFail(DownloadError.ERROR_FILE_EXISTS, null);
}
} else {
onFail(DownloadError.ERROR_DEVICE_NOT_FOUND);
onFail(DownloadError.ERROR_DEVICE_NOT_FOUND, null);
}
} catch (MalformedURLException e) {
e.printStackTrace();
onFail(DownloadError.ERROR_MALFORMED_URL);
onFail(DownloadError.ERROR_MALFORMED_URL, e.getMessage());
} catch (SocketTimeoutException e) {
e.printStackTrace();
onFail(DownloadError.ERROR_CONNECTION_ERROR);
onFail(DownloadError.ERROR_CONNECTION_ERROR, e.getMessage());
} catch (IOException e) {
e.printStackTrace();
onFail(DownloadError.ERROR_IO_ERROR);
onFail(DownloadError.ERROR_IO_ERROR, e.getMessage());
} finally {
if (connection != null) {
connection.disconnect();
@ -119,11 +117,12 @@ public class HttpDownloader extends Downloader {
status.setDone(true);
}
private void onFail(int reason) {
private void onFail(int reason, String reasonDetailed) {
if (AppConfig.DEBUG) {
Log.d(TAG, "Download failed");
}
status.setReason(reason);
status.setReasonDetailed(reasonDetailed);
status.setDone(true);
status.setSuccessful(false);
}

View File

@ -25,7 +25,7 @@ import de.danoeh.antennapod.feed.SimpleChapter;
* */
public class PodDBAdapter {
private static final String TAG = "PodDBAdapter";
private static final int DATABASE_VERSION = 5;
private static final int DATABASE_VERSION = 6;
private static final String DATABASE_NAME = "Antennapod.db";
/** Maximum number of arguments for IN-operator. */
@ -67,6 +67,8 @@ public class PodDBAdapter {
public static final int KEY_REASON_INDEX = 3;
public static final int KEY_SUCCESSFUL_INDEX = 4;
public static final int KEY_COMPLETION_DATE_INDEX = 5;
public static final int KEY_REASON_DETAILED_INDEX = 6;
public static final int KEY_DOWNLOADSTATUS_TITLE_INDEX = 7;
// --------- Queue indices
public static final int KEY_FEEDITEM_INDEX = 1;
public static final int KEY_QUEUE_FEED_INDEX = 2;
@ -109,6 +111,8 @@ public class PodDBAdapter {
public static final String KEY_TYPE = "type";
public static final String KEY_ITEM_IDENTIFIER = "item_identifier";
public static final String KEY_FEED_IDENTIFIER = "feed_identifier";
public static final String KEY_REASON_DETAILED = "reason_detailed";
public static final String KEY_DOWNLOADSTATUS_TITLE = "title";
// Table names
public static final String TABLE_NAME_FEEDS = "Feeds";
@ -156,7 +160,8 @@ public class PodDBAdapter {
+ TABLE_NAME_DOWNLOAD_LOG + " (" + TABLE_PRIMARY_KEY + KEY_FEEDFILE
+ " INTEGER," + KEY_FEEDFILETYPE + " INTEGER," + KEY_REASON
+ " INTEGER," + KEY_SUCCESSFUL + " INTEGER," + KEY_COMPLETION_DATE
+ " INTEGER)";
+ " INTEGER," + KEY_REASON_DETAILED + " TEXT,"
+ KEY_DOWNLOADSTATUS_TITLE + " TEXT)";
private static final String CREATE_TABLE_QUEUE = "CREATE TABLE "
+ TABLE_NAME_QUEUE + "(" + KEY_ID + " INTEGER PRIMARY KEY,"
@ -368,9 +373,8 @@ public class PodDBAdapter {
* Inserts or updates a download status.
* */
public long setDownloadStatus(DownloadStatus status) {
// Don't save failed downloads
ContentValues values = new ContentValues();
if (status.getFeedFile() != null) {
ContentValues values = new ContentValues();
values.put(KEY_FEEDFILE, status.getFeedFile().getId());
if (status.getFeedFile().getClass() == Feed.class) {
values.put(KEY_FEEDFILETYPE, FEEDFILETYPE_FEED);
@ -379,18 +383,19 @@ public class PodDBAdapter {
} else if (status.getFeedFile().getClass() == FeedMedia.class) {
values.put(KEY_FEEDFILETYPE, FEEDFILETYPE_FEEDMEDIA);
}
values.put(KEY_REASON, status.getReason());
values.put(KEY_SUCCESSFUL, status.isSuccessful());
values.put(KEY_COMPLETION_DATE, status.getCompletionDate()
.getTime());
if (status.getId() == 0) {
status.setId(db.insert(TABLE_NAME_DOWNLOAD_LOG, null, values));
} else {
db.update(TABLE_NAME_DOWNLOAD_LOG, values, KEY_ID + "=?",
new String[] { String.valueOf(status.getId()) });
}
}
values.put(KEY_REASON, status.getReason());
values.put(KEY_SUCCESSFUL, status.isSuccessful());
values.put(KEY_COMPLETION_DATE, status.getCompletionDate().getTime());
values.put(KEY_REASON_DETAILED, status.getReasonDetailed());
values.put(KEY_DOWNLOADSTATUS_TITLE, status.getTitle());
if (status.getId() == 0) {
status.setId(db.insert(TABLE_NAME_DOWNLOAD_LOG, null, values));
} else {
db.update(TABLE_NAME_DOWNLOAD_LOG, values, KEY_ID + "=?",
new String[] { String.valueOf(status.getId()) });
}
return status.getId();
}
@ -570,7 +575,8 @@ public class PodDBAdapter {
} else {
neededLength = elementsLeft;
parts = Arrays.copyOfRange(mediaIds, i
* IN_OPERATOR_MAXIMUM, (i * IN_OPERATOR_MAXIMUM) + neededLength);
* IN_OPERATOR_MAXIMUM, (i * IN_OPERATOR_MAXIMUM)
+ neededLength);
}
cursors[i] = db.rawQuery("SELECT * FROM "
@ -666,6 +672,12 @@ public class PodDBAdapter {
db.execSQL("ALTER TABLE " + TABLE_NAME_FEEDS + " ADD COLUMN "
+ KEY_FEED_IDENTIFIER + " TEXT");
}
if (oldVersion <= 5) {
db.execSQL("ALTER TABLE " + TABLE_NAME_DOWNLOAD_LOG
+ " ADD COLUMN " + KEY_REASON_DETAILED + " TEXT");
db.execSQL("ALTER TABLE " + TABLE_NAME_DOWNLOAD_LOG
+ " ADD COLUMN " + KEY_DOWNLOADSTATUS_TITLE + " TEXT");
}
}
}