Android 下载管理器。状态始终未决

Android Download Manager. status is always pending

我尝试使用 Download Manager 从特定 URL 下载一些文件, 但下载请求从未完成。

所以我记录了一些信息,看看出了什么问题,结果请求一直处于待处理状态,COLUMN_REASON0,我在上找不到相应的描述文档。

COLUMN_STATUS: 1
COLUMN_REASON: 0
COLUMN_TOTAL_SIZE_BYTES: -1
COLUMN_BYTES_DOWNLOADED_SO_FAR: 0

这是开始下载的方法。

val req = DownloadManager.Request(uri).apply {
    addRequestHeader("Cookie", cookie)
    allowScanningByMediaScanner()
    setTitle(fullname)
    setDescription(/* description text */)
    setDestinationInExternalFilesDir(context, Environment.DIRECTORY_DOWNLOADS, fullname)
}
val downloadId = downloadManager.enqueue(req)

以及用于调试的日志信息。

        val filterQuery = DownloadManager.Query().setFilterById(downloadId)
        val cursor = downloadManager.query(filterQuery)
        if (cursor.moveToFirst()) {
            val total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES))
            val current = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR))
            val status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))
            val reason = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_REASON))

            Log.d("App", "status: " + status.toString())
            Log.d("App", "reason: " + reason.toString())
            Log.d("App", "total: " + total.toString())
            Log.d("App", "current: " +  current.toString())
        }

那么请求状态一直处于待定状态的可能原因是什么?我该如何调试它?

我们将不胜感激。

就我而言,设置 VPN 似乎可以解决这个问题。看起来 google 服务在我的网络中被阻止了,在我设置系统全局 VPN 后问题就消失了。

DownloadManager 将其日志输出到 logcat 但不在您的应用程序 ID 下,因此您需要显示所有应用程序的日志。那里应该有下载失败的线索。例如,这是我的几个失败案例。

D/DownloadManager: [1988] Starting
W/DownloadManager: [1988] Stop requested with status 500: Internal Server Error
D/DownloadManager: [1988] Finished with status WAITING_TO_RETRY

W/DownloadManager: [1988] Stop requested with status 403: Unhandled HTTP response: 403 Forbidden

您必须等待(延迟)才能检查状态或在定时器中每次设置下载ID。 enqueue 好像return 下载ID 来不及了。 我的代码运行良好:

private void startDownload(View v)
{
    Uri uri=Uri.parse("http://example.com/app/name.apk");
    DownloadManager mgr = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
    DownloadManager.Request req = new DownloadManager.Request(uri)
            .setTitle(title)
            .setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI
                    |DownloadManager.Request.NETWORK_MOBILE)
            .setDescription("downloading")
            .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,"name.apk");
    downloadId = mgr.enqueue(req);
 

    getDownloadStatus();
}

查看状态方法

 private void getDownloadStatus()
    {
        DownloadManager.Query query = new DownloadManager.Query();
        query.setFilterById(downloadId);
        Cursor cursor = ((DownloadManager)context.getSystemService(Context.DOWNLOAD_SERVICE))
                .query(query);
        if (cursor.moveToFirst())
        {
            final Timer timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    query.setFilterById(downloadId);
                    Cursor cursor = ((DownloadManager)context.getSystemService(Context.DOWNLOAD_SERVICE))
                            .query(query);
                    cursor.moveToFirst();
                    int status=cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));

                    if (status == DownloadManager.STATUS_RUNNING) {
                        Log.i("DM_STATUS","status is "+" running");
                    }else if (status == DownloadManager.STATUS_SUCCESSFUL) {
                        Log.i("DM_STATUS","status is "+" success");
                        timer.cancel();
                    }
                }
            }, 100,1);
        }
    }