DownloadManager - 收到ACTION_DOWNLOAD_COMPLETE,但状态为STATUS_RUNNING

时间:2015-10-08 07:43:28

标签: android android-download-manager

我在ACTION_DOWNLOAD_COMPLETE广播的清单中注册了BroadcastReceiver。

当我收到此广播时,我提取下载ID:

public class DownloadCompleteBroadcastReceiver
    extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

        if (intent != null) {

            String action = intent.getAction();

            if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
                handleDownloadCompleteReceiver(context, intent);
            }
        }
    }

    private void handleDownloadCompleteReceiver(Context context, Intent intent) {

        long enqueueId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);

        if (enqueueId != -1) {

            Intent startServiceIntent = new Intent(context, HandleAPKDownloadCompleteIntentService.class);

            startServiceIntent.putExtra(HandleAPKDownloadCompleteIntentService.EXTRA_ENQUEUE_ID, enqueueId);

            context.startService(startServiceIntent);
        }
    }
}

我获得了enqueueId的有效值,并开始IntentService来处理已下载的文件:

@Override
protected void onHandleIntent(Intent intent) {

    long enqueueId = intent.getLongExtra(EXTRA_ENQUEUE_ID, -1);

    if (enqueueId == -1) {

        return;
    }

    DownloadManager dm = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);

    DownloadManager.Query query = new DownloadManager.Query();

    query.setFilterById(enqueueId);

    Cursor c = dm.query(query);

    if (c != null) {

        if (c.moveToFirst()) {

            int statusColumnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS);
            int downloadManagerDownloadStatus = c.getInt(statusColumnIndex);

            if (DownloadManager.STATUS_SUCCESSFUL == downloadManagerDownloadStatus) {
                ...
                ...
            }
            else if (DownloadManager.STATUS_FAILED == downloadManagerDownloadStatus) {
                ...
                ...
            }
            else {
                reportToGoogleAnalyticsUnexpectedStatus(downloadManagerDownloadStatus);
            }

        }

        c.close();
    }
}

此时downloadManagerDownloadStatus = 2,根据documentation STATUS_RUNNING

它没有任何意义,因为广播ACTION_DOWNLOAD_COMPLETE已被调用,因此下载不应该正在运行。

我在Google分析中发现这种情况很多次,但无法重现。

  • 知道为什么会这样吗?

  • 任何想法如何重现?

  • 我应该将此状态视为下载成功还是失败?

我真的不明白是否认为这样的下载成功与否,因为从一方面 - 下载完整广播被解雇,但另一方面状态正在运行。

值得一提的一点:我正在密切使用下载管理器:在应用程序的特定流程中触发启动10-15次下载,

提前致谢。

4 个答案:

答案 0 :(得分:2)

您提到您正在开始多次下载。

  

值得一提的是:我正在密集使用下载管理器:   一次启动10-15次下载,触发特定流量   应用程序,

现在清楚地解释onHandleIntent中发生了什么。

取自android docs

  

protected abstract void onHandleIntent(Intent intent)

     

在具有请求的工作线程上调用此方法   处理。一次只处理一个Intent,但处理   发生在独立于其他线程的工作线程上   应用逻辑。因此,如果此代码需要很长时间,它将保持不变   对同一个IntentService的其他请求,但它不会阻止   还要别的吗。当所有请求都已处理完毕后   IntentService会自行停止,因此您不应该调用stopSelf()。

您很可能在DownloadManager.ACTION_DOWNLOAD_COMPLETE跳过一次或多次成功下载,然后该线程处于STATUS_RUNNING状态,其中有多个原因导致下载未完成。

正如另一个答案所提到的,你可能已经没有内存了。我建议您在每个阶段记录您的应用,并确切了解正在下载的内容以及它被卡住的位置。然后调查它停止的原因。

答案 1 :(得分:2)

行为似乎很奇怪。你可以尝试以下方法来获得你感兴趣的两个案例(除setFilterById()之外):

query.setFilterByStatus(DownloadManager.STATUS_SUCCESSFUL | DownloadManager.STATUS_FAILED);

但这并不能说明你为什么得到你所得到的东西。我建议你添加以下日志来查看该光标中的内容,这将为您提供更好的建议。

DatabaseUtils.dumpCursorToString(cursor)

更新:值得一试:DownloadManager.ACTION_DOWNLOAD_COMPLETE broadcast receiver receiving same download id more than once with different download statuses in Android

答案 2 :(得分:1)

我之前使用的是DownloadManager。我想你可以关注这些要点:

1。DownloadManager似乎与DownloadProvider.apk有关系,当此应用程序被杀死时,DownloadManager可能会出现问题。

2.当您没有足够的存储空间时,您将拥有:

Downloads.Impl.STATUS_INSUFFICIENT_SPACE_ERROR

这种情况可能会告诉你状态是Downloads.Impl.STATUS_RUNNING

答案 3 :(得分:1)

我一直在使用这几次类似的问题。务必仔细检查以下所有内容:

  • android.permission.INTERNET对
  • query.setFilterByStatus(DownloadManager.STATUS_PAUSED | DownloadManager.STATUS_PENDING | DownloadManager.STATUS_RUNNING | DownloadManager.STATUS_SUCCESSFUL);
  • 检查此商品DownloadManager tutorial

我希望这会有所帮助。