Merge pull request #777 from mfietz/feature/download-log-retry
Retry failed downloads in the download log
This commit is contained in:
commit
252f80de78
|
@ -2,20 +2,34 @@ package de.danoeh.antennapod.adapter;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.text.format.DateUtils;
|
import android.text.format.DateUtils;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.BaseAdapter;
|
import android.widget.BaseAdapter;
|
||||||
|
import android.widget.Button;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.joanzapata.android.iconify.Iconify;
|
||||||
|
|
||||||
|
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.feed.Feed;
|
import de.danoeh.antennapod.core.feed.Feed;
|
||||||
import de.danoeh.antennapod.core.feed.FeedImage;
|
import de.danoeh.antennapod.core.feed.FeedImage;
|
||||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||||
import de.danoeh.antennapod.core.service.download.DownloadStatus;
|
import de.danoeh.antennapod.core.service.download.DownloadStatus;
|
||||||
|
import de.danoeh.antennapod.core.storage.DBReader;
|
||||||
|
import de.danoeh.antennapod.core.storage.DBTasks;
|
||||||
|
import de.danoeh.antennapod.core.storage.DownloadRequestException;
|
||||||
|
|
||||||
/** Displays a list of DownloadStatus entries. */
|
/** Displays a list of DownloadStatus entries. */
|
||||||
public class DownloadLogAdapter extends BaseAdapter {
|
public class DownloadLogAdapter extends BaseAdapter {
|
||||||
|
|
||||||
|
private final String TAG = "DownloadLogAdapter";
|
||||||
|
|
||||||
private Context context;
|
private Context context;
|
||||||
|
|
||||||
private ItemAccess itemAccess;
|
private ItemAccess itemAccess;
|
||||||
|
@ -35,11 +49,11 @@ 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.retry = (Button) convertView.findViewById(R.id.btnRetry);
|
||||||
|
holder.date = (TextView) convertView.findViewById(R.id.txtvDate);
|
||||||
holder.title = (TextView) convertView.findViewById(R.id.txtvTitle);
|
holder.title = (TextView) convertView.findViewById(R.id.txtvTitle);
|
||||||
holder.type = (TextView) convertView.findViewById(R.id.txtvType);
|
holder.type = (TextView) convertView.findViewById(R.id.txtvType);
|
||||||
holder.date = (TextView) convertView.findViewById(R.id.txtvDate);
|
|
||||||
holder.successful = (TextView) convertView
|
|
||||||
.findViewById(R.id.txtvStatus);
|
|
||||||
holder.reason = (TextView) convertView
|
holder.reason = (TextView) convertView
|
||||||
.findViewById(R.id.txtvReason);
|
.findViewById(R.id.txtvReason);
|
||||||
convertView.setTag(holder);
|
convertView.setTag(holder);
|
||||||
|
@ -62,33 +76,99 @@ 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.successful.setTextColor(convertView.getResources().getColor(
|
holder.icon.setTextColor(convertView.getResources().getColor(
|
||||||
R.color.download_success_green));
|
R.color.download_success_green));
|
||||||
holder.successful.setText(R.string.download_successful);
|
holder.icon.setText("{fa-check-circle}");
|
||||||
|
Iconify.addIcons(holder.icon);
|
||||||
|
holder.retry.setVisibility(View.GONE);
|
||||||
holder.reason.setVisibility(View.GONE);
|
holder.reason.setVisibility(View.GONE);
|
||||||
} else {
|
} else {
|
||||||
holder.successful.setTextColor(convertView.getResources().getColor(
|
holder.icon.setTextColor(convertView.getResources().getColor(
|
||||||
R.color.download_failed_red));
|
R.color.download_failed_red));
|
||||||
holder.successful.setText(R.string.download_failed);
|
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();
|
||||||
}
|
}
|
||||||
holder.reason.setText(reasonText);
|
holder.reason.setText(reasonText);
|
||||||
holder.reason.setVisibility(View.VISIBLE);
|
holder.reason.setVisibility(View.VISIBLE);
|
||||||
|
if(status.getFeedfileType() != FeedImage.FEEDFILETYPE_FEEDIMAGE &&
|
||||||
|
!newerWasSuccessful(position, status.getFeedfileType(), status.getFeedfileId())) {
|
||||||
|
holder.retry.setVisibility(View.VISIBLE);
|
||||||
|
holder.retry.setText("{fa-repeat}");
|
||||||
|
Iconify.addIcons(holder.retry);
|
||||||
|
holder.retry.setOnClickListener(clickListener);
|
||||||
|
ButtonHolder btnHolder;
|
||||||
|
if(holder.retry.getTag() != null) {
|
||||||
|
btnHolder = (ButtonHolder) holder.retry.getTag();
|
||||||
|
} else {
|
||||||
|
btnHolder = new ButtonHolder();
|
||||||
|
}
|
||||||
|
btnHolder.typeId = status.getFeedfileType();
|
||||||
|
btnHolder.id = status.getFeedfileId();
|
||||||
|
holder.retry.setTag(btnHolder);
|
||||||
|
} else {
|
||||||
|
holder.retry.setVisibility(View.GONE);
|
||||||
|
holder.retry.setOnClickListener(null);
|
||||||
|
holder.retry.setTag(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return convertView;
|
return convertView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final View.OnClickListener clickListener = new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
ButtonHolder holder = (ButtonHolder) v.getTag();
|
||||||
|
if(holder.typeId == Feed.FEEDFILETYPE_FEED) {
|
||||||
|
Feed feed = DBReader.getFeed(context, holder.id);
|
||||||
|
feed.setLastUpdate(new Date(0)); // force refresh
|
||||||
|
try {
|
||||||
|
DBTasks.refreshFeed(context, feed);
|
||||||
|
} catch (DownloadRequestException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} else if(holder.typeId == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
|
||||||
|
FeedMedia media = DBReader.getFeedMedia(context, holder.id);
|
||||||
|
try {
|
||||||
|
DBTasks.downloadFeedItems(context, media.getItem());
|
||||||
|
Toast.makeText(context, R.string.status_downloading_label, Toast.LENGTH_SHORT).show();
|
||||||
|
} catch (DownloadRequestException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
DownloadRequestErrorDialogCreator.newRequestErrorDialog(context, e.getMessage());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.wtf(TAG, "Unexpected type id: " + holder.typeId);
|
||||||
|
}
|
||||||
|
v.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private boolean newerWasSuccessful(int position, int feedTypeId, long id) {
|
||||||
|
for (int i = 0; i < position; i++) {
|
||||||
|
DownloadStatus status = getItem(i);
|
||||||
|
if (status.getFeedfileType() == feedTypeId && status.getFeedfileId() == id &&
|
||||||
|
status.isSuccessful()) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static class Holder {
|
static class Holder {
|
||||||
|
TextView icon;
|
||||||
|
Button retry;
|
||||||
TextView title;
|
TextView title;
|
||||||
TextView type;
|
TextView type;
|
||||||
TextView date;
|
TextView date;
|
||||||
TextView successful;
|
|
||||||
TextView reason;
|
TextView reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class ButtonHolder {
|
||||||
|
int typeId;
|
||||||
|
long id;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getCount() {
|
public int getCount() {
|
||||||
return itemAccess.getCount();
|
return itemAccess.getCount();
|
||||||
|
@ -104,9 +184,9 @@ public class DownloadLogAdapter extends BaseAdapter {
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static interface ItemAccess {
|
public interface ItemAccess {
|
||||||
public int getCount();
|
int getCount();
|
||||||
public DownloadStatus getItem(int position);
|
DownloadStatus getItem(int position);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,78 +1,84 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?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"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:paddingTop="8dp"
|
||||||
|
android:paddingLeft="16dp"
|
||||||
|
android:paddingRight="16dp"
|
||||||
|
android:paddingBottom="8dp"
|
||||||
tools:background="@android:color/darker_gray">
|
tools:background="@android:color/darker_gray">
|
||||||
|
|
||||||
<RelativeLayout
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/txtvIcon"
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:textSize="48sp"
|
||||||
|
tools:text="[Icon]"
|
||||||
|
android:gravity="center" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnRetry"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding"
|
android:layout_below="@id/txtvIcon"
|
||||||
android:layout_marginRight="@dimen/listitem_threeline_horizontalpadding"
|
android:layout_alignLeft="@id/txtvIcon"
|
||||||
android:layout_marginTop="@dimen/listitem_threeline_verticalpadding">
|
android:layout_alignRight="@id/txtvIcon"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
tools:text="↻" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/txtvType"
|
android:id="@+id/txtvType"
|
||||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:layout_marginLeft="@dimen/listitem_threeline_textleftpadding"
|
|
||||||
tools:text="Media file"
|
|
||||||
tools:background="@android:color/holo_green_dark" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/txtvTitle"
|
|
||||||
style="@style/AntennaPod.TextView.ListItemPrimaryTitle"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentLeft="true"
|
|
||||||
android:layout_alignParentTop="true"
|
|
||||||
android:layout_toLeftOf="@id/txtvType"
|
|
||||||
tools:text="Download item title"
|
|
||||||
tools:background="@android:color/holo_blue_light" />
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding"
|
android:layout_alignParentTop="true"
|
||||||
android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding"
|
android:layout_alignParentRight="true"
|
||||||
android:layout_marginRight="@dimen/listitem_threeline_horizontalpadding">
|
android:layout_marginLeft="8dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
tools:text="Media file"
|
||||||
|
tools:background="@android:color/holo_green_dark" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/txtvDate"
|
android:id="@+id/txtvTitle"
|
||||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
style="@style/AntennaPod.TextView.ListItemPrimaryTitle"
|
||||||
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_alignParentTop="true"
|
||||||
android:layout_marginRight="8dp"
|
android:layout_toRightOf="@id/txtvIcon"
|
||||||
tools:text="January 23"
|
android:layout_toLeftOf="@id/txtvType"
|
||||||
tools:background="@android:color/holo_green_dark" />
|
android:layout_marginLeft="8dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:minLines="1"
|
||||||
|
android:maxLines="2"
|
||||||
|
tools:text="Download item title"
|
||||||
|
tools:background="@android:color/holo_blue_light" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/txtvStatus"
|
android:id="@+id/txtvDate"
|
||||||
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
|
||||||
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_toRightOf="@id/txtvIcon"
|
||||||
tools:text="successful"
|
android:layout_below="@id/txtvTitle"
|
||||||
tools:background="@android:color/holo_green_dark" />
|
android:layout_marginLeft="8dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
</RelativeLayout>
|
tools:text="January 23"
|
||||||
|
tools:background="@android:color/holo_green_dark" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/txtvReason"
|
android:id="@+id/txtvReason"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding"
|
android:layout_below="@id/txtvDate"
|
||||||
android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding"
|
android:layout_toRightOf="@id/txtvIcon"
|
||||||
android:layout_marginRight="@dimen/listitem_threeline_horizontalpadding"
|
android:layout_marginLeft="8dp"
|
||||||
android:textColor="?android:attr/textColorTertiary"
|
android:textColor="?android:attr/textColorTertiary"
|
||||||
android:textSize="@dimen/text_size_micro"
|
android:textSize="@dimen/text_size_micro"
|
||||||
tools:text="@string/design_time_downloaded_log_failure_reason"
|
tools:text="@string/design_time_downloaded_log_failure_reason"
|
||||||
tools:background="@android:color/holo_green_dark" />
|
tools:background="@android:color/holo_green_dark" />
|
||||||
|
|
||||||
</LinearLayout>
|
</RelativeLayout>
|
|
@ -939,6 +939,13 @@ public class DownloadService extends Service {
|
||||||
|
|
||||||
|
|
||||||
if (successful) {
|
if (successful) {
|
||||||
|
// we create a 'successful' download log if the feed's last refresh failed
|
||||||
|
List<DownloadStatus> log = DBReader.getFeedDownloadLog(DownloadService.this, feed);
|
||||||
|
if(log.size() > 0 && log.get(0).isSuccessful() == false) {
|
||||||
|
saveDownloadStatus(new DownloadStatus(feed,
|
||||||
|
feed.getHumanReadableIdentifier(), DownloadError.SUCCESS, successful,
|
||||||
|
reasonDetailed));
|
||||||
|
}
|
||||||
return Pair.create(request, result);
|
return Pair.create(request, result);
|
||||||
} else {
|
} else {
|
||||||
numberOfDownloads.decrementAndGet();
|
numberOfDownloads.decrementAndGet();
|
||||||
|
|
|
@ -327,6 +327,21 @@ public final class DBReader {
|
||||||
return feed;
|
return feed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static DownloadStatus extractDownloadStatusFromCursorRow(final Cursor cursor) {
|
||||||
|
long id = cursor.getLong(PodDBAdapter.KEY_ID_INDEX);
|
||||||
|
long feedfileId = cursor.getLong(PodDBAdapter.KEY_FEEDFILE_INDEX);
|
||||||
|
int feedfileType = cursor.getInt(PodDBAdapter.KEY_FEEDFILETYPE_INDEX);
|
||||||
|
boolean successful = cursor.getInt(PodDBAdapter.KEY_SUCCESSFUL_INDEX) > 0;
|
||||||
|
int reason = cursor.getInt(PodDBAdapter.KEY_REASON_INDEX);
|
||||||
|
String reasonDetailed = cursor.getString(PodDBAdapter.KEY_REASON_DETAILED_INDEX);
|
||||||
|
String title = cursor.getString(PodDBAdapter.KEY_DOWNLOADSTATUS_TITLE_INDEX);
|
||||||
|
Date completionDate = new Date(cursor.getLong(PodDBAdapter.KEY_COMPLETION_DATE_INDEX));
|
||||||
|
|
||||||
|
return new DownloadStatus(id, title, feedfileId,
|
||||||
|
feedfileType, successful, DownloadError.fromCode(reason), completionDate,
|
||||||
|
reasonDetailed);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static FeedItem getMatchingItemForMedia(long itemId,
|
private static FeedItem getMatchingItemForMedia(long itemId,
|
||||||
List<FeedItem> items) {
|
List<FeedItem> items) {
|
||||||
|
@ -565,27 +580,7 @@ public final class DBReader {
|
||||||
|
|
||||||
if (logCursor.moveToFirst()) {
|
if (logCursor.moveToFirst()) {
|
||||||
do {
|
do {
|
||||||
long id = logCursor.getLong(PodDBAdapter.KEY_ID_INDEX);
|
downloadLog.add(extractDownloadStatusFromCursorRow(logCursor));
|
||||||
|
|
||||||
long feedfileId = logCursor
|
|
||||||
.getLong(PodDBAdapter.KEY_FEEDFILE_INDEX);
|
|
||||||
int feedfileType = logCursor
|
|
||||||
.getInt(PodDBAdapter.KEY_FEEDFILETYPE_INDEX);
|
|
||||||
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, feedfileId,
|
|
||||||
feedfileType, successful, DownloadError.fromCode(reason), completionDate,
|
|
||||||
reasonDetailed));
|
|
||||||
|
|
||||||
} while (logCursor.moveToNext());
|
} while (logCursor.moveToNext());
|
||||||
}
|
}
|
||||||
logCursor.close();
|
logCursor.close();
|
||||||
|
@ -593,6 +588,60 @@ public final class DBReader {
|
||||||
return downloadLog;
|
return downloadLog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the download log for a particular feed from the database.
|
||||||
|
*
|
||||||
|
* @param context A context that is used for opening a database connection.
|
||||||
|
* @param feed Feed for which the download log is loaded
|
||||||
|
* @return A list with DownloadStatus objects that represent the feed's download log,
|
||||||
|
* newest events first.
|
||||||
|
*/
|
||||||
|
public static List<DownloadStatus> getFeedDownloadLog(Context context, Feed feed) {
|
||||||
|
Log.d(TAG, "getFeedDownloadLog(CONTEXT, " + feed.toString() + ")");
|
||||||
|
|
||||||
|
PodDBAdapter adapter = new PodDBAdapter(context);
|
||||||
|
adapter.open();
|
||||||
|
Cursor cursor = adapter.getDownloadLog(Feed.FEEDFILETYPE_FEED, feed.getId());
|
||||||
|
List<DownloadStatus> downloadLog = new ArrayList<DownloadStatus>(
|
||||||
|
cursor.getCount());
|
||||||
|
|
||||||
|
if (cursor.moveToFirst()) {
|
||||||
|
do {
|
||||||
|
downloadLog.add(extractDownloadStatusFromCursorRow(cursor));
|
||||||
|
} while (cursor.moveToNext());
|
||||||
|
}
|
||||||
|
cursor.close();
|
||||||
|
Collections.sort(downloadLog, new DownloadStatusComparator());
|
||||||
|
return downloadLog;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the download log for a particular feed media from the database.
|
||||||
|
*
|
||||||
|
* @param context A context that is used for opening a database connection.
|
||||||
|
* @param media Feed media for which the download log is loaded
|
||||||
|
* @return A list with DownloadStatus objects that represent the feed media's download log,
|
||||||
|
* newest events first.
|
||||||
|
*/
|
||||||
|
public static List<DownloadStatus> getFeedMediaDownloadLog(Context context, FeedMedia media) {
|
||||||
|
Log.d(TAG, "getFeedDownloadLog(CONTEXT, " + media.toString() + ")");
|
||||||
|
|
||||||
|
PodDBAdapter adapter = new PodDBAdapter(context);
|
||||||
|
adapter.open();
|
||||||
|
Cursor cursor = adapter.getDownloadLog(FeedMedia.FEEDFILETYPE_FEEDMEDIA, media.getId());
|
||||||
|
List<DownloadStatus> downloadLog = new ArrayList<DownloadStatus>(
|
||||||
|
cursor.getCount());
|
||||||
|
|
||||||
|
if (cursor.moveToFirst()) {
|
||||||
|
do {
|
||||||
|
downloadLog.add(extractDownloadStatusFromCursorRow(cursor));
|
||||||
|
} while (cursor.moveToNext());
|
||||||
|
}
|
||||||
|
cursor.close();
|
||||||
|
Collections.sort(downloadLog, new DownloadStatusComparator());
|
||||||
|
return downloadLog;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the FeedItemStatistics objects of all Feeds in the database. This method should be preferred over
|
* Loads the FeedItemStatistics objects of all Feeds in the database. This method should be preferred over
|
||||||
* {@link #getFeedItemList(android.content.Context, de.danoeh.antennapod.core.feed.Feed)} if only metadata about
|
* {@link #getFeedItemList(android.content.Context, de.danoeh.antennapod.core.feed.Feed)} if only metadata about
|
||||||
|
|
|
@ -977,6 +977,14 @@ public class PodDBAdapter {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final Cursor getDownloadLog(final int feedFileType, final long feedFileId) {
|
||||||
|
final String query = "SELECT * FROM " + TABLE_NAME_DOWNLOAD_LOG +
|
||||||
|
" WHERE " + KEY_FEEDFILE + "=" + feedFileId + " AND " + KEY_FEEDFILETYPE + "=" + feedFileType
|
||||||
|
+ " ORDER BY " + KEY_ID + " DESC";
|
||||||
|
Cursor c = db.rawQuery(query, null);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
public final Cursor getDownloadLogCursor(final int limit) {
|
public final Cursor getDownloadLogCursor(final int limit) {
|
||||||
Cursor c = db.query(TABLE_NAME_DOWNLOAD_LOG, null, null, null, null,
|
Cursor c = db.query(TABLE_NAME_DOWNLOAD_LOG, null, null, null, null,
|
||||||
null, KEY_COMPLETION_DATE + " DESC LIMIT " + limit);
|
null, KEY_COMPLETION_DATE + " DESC LIMIT " + limit);
|
||||||
|
|
Loading…
Reference in New Issue