【问题标题】:DownloadManager.ACTION_DOWNLOAD_COMPLETE broadcast receiver receiving same download id more than once with different download statuses in AndroidDownloadManager.ACTION_DOWNLOAD_COMPLETE 广播接收器在 Android 中多次接收相同的下载 ID,但下载状态不同
【发布时间】:2012-02-14 19:21:15
【问题描述】:

我正在使用 Android DownloadManger System Service 通过以下方式下载一些文件

dwnId = mgr.enqueue(new DownloadManager.Request(serveruri)
        .setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI |
                DownloadManager.Request.NETWORK_MOBILE)
                .setAllowedOverRoaming(false)
                .setTitle(getAlbumName())
                .setDescription(getTrackName())
                .setDestinationUri(deviceUri)
                .setShowRunningNotification(true));

mgr 是下载管理器实例,dwnId 是返回的唯一 ID。我也在注册ACTION_DOWNLOAD_COMPLETE

registerReceiver(onDownloadComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));

在 onDownloadComplete BroadcastReceiver 的 onReceive() 方法中,我得到了类似的下载 ID

Long dwnId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);

之后我正在向下载管理器查询下载状态

Cursor c = downloadManager.query(new DownloadManager.Query().setFilterById(dwnId)); c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));

对于 DownloadManager.STATUS_* 常量。

问题是我两次收到相同的 downId(意味着 onReceive 方法被调用了两次),一次使用 DownloadManager.STATUS_SUCCESSFUL 状态,一次使用相同 dwnId 的 DownloadManager.STATUS_FAILED 状态。我正在发出一次下载大约 10 个文件的请求,但在设备下载管理器上,它在通知栏左上角的意思中显示下载计数为 12 或 13。我认为下载管理器在下载文件时出现问题并恢复或自动重新启动以再次下载相同的文件。这就是为什么我请求下载的文件数量与下载队列中的实际数量之间存在差异的原因。因此,只有我两次获得相同的 DownloadId 完成操作。如果这是真的,如何限制它。我错了可能是我要求实际下载的计数差异的原因吗?为什么广播接收器两次收到相同的下载 ID。有人可以告诉我吗?

提前致谢……

【问题讨论】:

  • 在我的情况下有点不同 - onReceive 方法调用了两次,因为我不止一次注册接收器:一个通过清单,一个在 onCreate() 中通过 registerReceiver() 方法。

标签: android download broadcastreceiver broadcast download-manager


【解决方案1】:

这是一个报告的错误,请参阅:http://code.google.com/p/android/issues/detail?id=18462

我发现的方法是验证下载是否成功,如果没有则放弃意图或重新排队文件如果从未下载过...

花了几个小时才弄清楚那个:(

** 编辑:添加代码示例 **

/**
 * Check if download was valid, see issue
 * http://code.google.com/p/android/issues/detail?id=18462
 * @param long1
 * @return
 */
private boolean validDownload(long downloadId) {

    Log.d(TAG,"Checking download status for id: " + downloadId);

    //Verify if download is a success
    Cursor c= dMgr.query(new DownloadManager.Query().setFilterById(downloadId));

    if(c.moveToFirst()){            
        int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));

        if(status == DownloadManager.STATUS_SUCCESSFUL){
            return true; //Download is valid, celebrate
        }else{
            int reason = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_REASON));
            Log.d(TAG, "Download not correct, status [" + status + "] reason [" + reason + "]");            
            return false;
        }   
    }               
    return false;                                   
}

完整代码见:https://github.com/flegare/JAV387_LaboWidget/blob/master/src/com/mobidroid/widgetfact/service/FactService.java

【讨论】:

  • @flegare 如果我想开始多个并行下载,那么我如何确定哪个下载已完成,如果我想取消特定下载,那么如何存储特定下载的 downloadId。如果可能的话,请告诉我怎么做。
  • 我想知道:这仍然是一个问题吗?我在装有 Android 5.0.1 的 Nexus 7 (2012) 上看到过类似的情况,但它只是偶尔发生,我无法确定。它实际上不再是一个问题还是我只是看到鬼魂? :O
【解决方案2】:

下载文件的简单方法,在通知栏中查看下载进度,甚至在完成下载后只需在通知栏中单击即可打开文件。

只需调用此方法并传递您的文件名和下载网址

 public void downloadFile(String name, String url){ 
        //download link
        downloadUri = Uri.parse(url);

        DownloadManager.Request request = new DownloadManager.Request(downloadUri);

        //allow download to take place over wifi, mobile network and roaming
        request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE ).setAllowedOverRoaming(true);
        request.setAllowedOverRoaming(false);

        //name to show while downloading
        request.setTitle(name);

        //description to show while downloading
        request.setDescription("Downloading " + name);

        //show on navigation
        request.setVisibleInDownloadsUi(true);

        //download path
        request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS.toString(), "/" + name);

        //file open when item on navigation is clicked
        request.allowScanningByMediaScanner();
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
       long downloadId = downloadManager.enqueue(request);

    }

输出

您可以了解更多here

【讨论】:

    【解决方案3】:

    您还可以在Broadcast Receiver下添加布尔或数字,条件来完成每个下载任务后完成的特定工作。

    喜欢

    private BroadcastReceiver onDownloadComplete = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            //Fetching the download id received with the broadcast
            long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
            //Checking if the received broadcast is for our enqueued download by matching download id
            if (downloadID == id) {
                //firstDownload is a boolean variable and assign each downloadManager as true or false
    
                if (firstDownload) {
                    //First task downlaoded
                } else {
                    //Second task downloaded
    
    
                }
            }
    
    
        };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-03
      • 2015-07-12
      • 1970-01-01
      相关资源
      最近更新 更多