DownloadManager似乎是在不稳定的移动互联网连接上进行大量后台下载的应用程序的正确选择。
使用在网络上找到的教程代码,该应用程序能够请求从系统的DM下载,如下所示:
// in onCreate()
dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
// in requestData()
Uri u = Uri.parse("http://server:8000/feed/data");
Request dreq = new Request(u);
dreq.setNotificationVisibility(Request.VISIBILITY_HIDDEN);
downloadID = dm.enqueue(dreq);
该代码中的 URL 是本地计算机上的测试服务器。URL有效,Android模拟器中的浏览器可以检索页面,当我的应用程序通过DownloadManager和上面引用的代码请求该页面时,服务器会返回HTTP代码200。
这是 ACTION_DOWNLOAD_COMPLETE BroadcastReceiver 中的相关代码,当 DM 检索文件时会调用该代码。
Query q = new Query();
q.setFilterById(downloadID);
Log.i("handleData()", "Handling data");
Cursor c = dm.query(q);
if (c.moveToFirst()) {
Log.i("handleData()", "Download ID: " + downloadID + " / " + c.getInt(c.getColumnIndex(DownloadManager.COLUMN_ID)));
Log.i("handleData()", "Download Status: " + c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS)));
if (c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL) {
String uriString = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
Log.i("handleData()", "Download URI: " + uriString);
} else if (c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_FAILED) {
Log.i("handleData()", "Reason: " + c.getString(c.getColumnIndex(DownloadManager.COLUMN_REASON)));
}
}
奇怪的结果是这样的:
DOWNLOAD_STATUS是 16(或 STATUS_FAILED),但原因是"占位符"。
为什么?为什么服务器返回 200 状态代码时会失败?为什么下载管理器没有给出理由?
在这里回答我自己。
问题是:COLUMN_REASON不是字符串,而是数字值。
Log.i("handleData()", "Reason: " + c.getInt(c.getColumnIndex(DownloadManager.COLUMN_REASON)));
将返回可以使用的实际错误代码。