1.监听下载任务状态
为了监听自身创建的下载任务,可以通过创建 ContentObserver 来 监听DownloadProvider
mContext.getContentResolver().registerContentObserver(
Downloads.Impl.CONTENT_URI, true, mDownloadManagerObserver);
其中
public static final Uri CONTENT_URI =
Uri.parse("content://downloads/my_downloads");
使用这个可以监听到当前应用创建的下载任务。另外还有ALL_DOWNLOADS_CONTENT_URI可以监听到所有的下载任务,不过也需要相应的ACCESS_ALL_DOWNLOADS权限才行。
第二个参数,表示是否监听派生的URL。false的时候,则精确匹配URL,才会通知。true的话,类似content://downloads/my_downloads/3 这种url时也会通知
第三个参数则是自己继承实现的 ContentObserver ,需要Handler作为参数
private class DownloadManagerObserver extends ContentObserver {
public DownloadManagerObserver(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange) {
updateDownloadState();
}
}
2.下载任务状态
可以监听下载任务后,需要根据对应的下载状态,来进行不同操作或提示。
状态情况如下,如字面意思:
STATUS_PENDING
STATUS_RUNNING
STATUS_PAUSED
STATUS_SUCCESSFUL
STATUS_FAILED
关于状态获取,有两种方法:
一种就是标准的,通过DownloadManager提供的方法来查询:
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(id);
Cursor cursor = mDownloadManager.query(query);
try {
if (cursor != null && cursor.moveToFirst()) {
ret[0] = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
ret[1] = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_REASON));
ret2[0] = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
ret2[1] = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (cursor != null) {
cursor.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
提供ID,可以查询该任务的详细状态,如Status,失败时的Reason,已下载大小COLUMN_BYTES_DOWNLOADED_SO_FAR,总大小COLUMN_TOTAL_SIZE_BYTES
该方法可以返回DownloadManager经过处理,允许暴露的一些属性
不过如果直接把DownloadProvider从手机中导出来查看的话,可以发现其中还有很多还未查到的属性。比如存了任务失败详细信息的ErrorMsg字段
这时候需要用到第二种方法,直接去查询DownloadProvider:
Uri uri = ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, id);
Cursor cursor = mContext.getContentResolver().query(uri,
new String[] {Downloads.Impl.COLUMN_ERROR_MSG},
null, null, null);
if (cursor != null) {
try {
if (cursor.getCount() > 0) {
cursor.moveToFirst();
result[1] = cursor.getString(cursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_ERROR_MSG));
result[0] = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_SERVER_IP));
}
} catch (IllegalArgumentException e) {
Log.e(TAG, "column does not exist: ");
} finally {
cursor.close();
}
}
主要是query的参数不太一样,除了第一个uri外,第二个参数为projection,表示需要查询返回的列,如果为null的话,则会返回所有列(其实只会返回部分,下载管理之外的程序访问时,只会返回部分,比如想获取的ErrorMsg就不给。但是如果你在projection直接声明需要返回的列,则可以返回,而且效率更高),第三个selection第四个参数selectionArgs为常见的查询参数,第五个sortOrder为是否需要排序。
通过该方法,我们可以获得更详细的一些属性。