2014-02-12 243 views
15

我正在开发一个应用程序,我正在开发的功能之一就是下载一些二进制文件。其中一些非常大(超过几兆字节)。只要文件大小小于2 GB,下载工作就会顺利完成。DownloadManager下载超过2.1 GB的文件

我被困在3.2GB的文件中,因为我得到了进度更新(我在为进度更新汇集DownloadManager),但是当下载完成时,文件不存在于目标文件路径中。询问该DownloadManager该下载ID,我得到STATUS_FAILED和原因ERROR_UNKNOWN - 人们会希望的最喜欢的错误细节!

奇怪的是,这出现在大多数设备上,但对于一些(如三星SG 4活动OS 4.2.2和LG Nexus 5 OS 4.4.2),它不会出现。

做了一些额外的调查,我发现这似乎是一个bug in Android DownloadManager implementation。看起来Android实现将下载计数存储为int,但是当该计数超过Integer.MAX_VALUE时,下载将以失败结束。

我想更换DownloadManager使用与前台服务,但我不会轻言放弃....

难道你们面对这个如果是这样,你怎么解决? 4.2.2之前是否有任何解决方法可以使用DownloadManager,因此我可以下载每个文件超过2.1 GB的内容?

+0

检查出Koush的Ion:https://github.com/koush/ion它非常好,它可能适用于大型文件 – josebama

+0

@josebama:是从UI中释放的实际下载?我的意思是,如果用户旋转设备,退出应用程序,然后重新进入,下载是否继续并与整个UI保持一致? – gunar

+0

我无法确认,但它应该是 – josebama

回答

2

要下载这么大的文件,你需要下载那些块。您可以使用任何支持HTTP范围选项的库来允许将多个文件分割为多个文件,支持简历等。

或者您可以在服务器上拆分大文件,然后使用带有MD5散列的文本文件每个文件,当你第一次开始下载时,一旦完成后获取MD5文件,然后检查哈希匹配下载的部分。如果他们没有删除那件作品并将其添加到要下载的项目队列中。

一旦所有的作品下载和MD5的作品,你可以把作品单一文件重新组合。

如果您正在考虑将文件下载到SD卡中,那么FAT32是默认的文件系统。此文件系统的每个文件限制为4 GB。

+0

你总结了迄今为止所有其他人所说的话:)但我认为你没有提供新的东西。 – gunar

+0

这只是你可以通过它的方式,迄今为止我还没有阅读其他答案。我不认为我复制了它们,只是简单地写了这些内容,我不知道为什么你看起来我没有提供新的东西。 –

+0

接受这个答案,即使它没有真正回答它,因为没有合理的答案。最后我写了自己的下载管理器,但这个答案尽可能接近我们的接受。最初我想接受来自'ksasq'的答案,但是我无法验证它,因为我没有一个知道处理chuncked内容的服务器。 'Range'解决方案适用于我,因为服务器支持它。谢谢! – gunar

0

您可以通过将文件拆分为更小的zip文件来传递此问题。下一步是加入他们的目标,我发现->this<-可能会帮助你。如果你不会压缩文件(仅分割选项),你应该有很好的性能。其他问题是你需要两倍的存储空间。您可以下载较小的文件(大约100MB),将其写入已加入的缓冲区并删除表单文件系统,这将保留空间浪费。

+0

感谢您回答(+1),但这不是服务器端的选项。 – gunar

4

从查看Android源代码看来,这个问题在JB-MR2中得到了解决。

似乎在较旧的平台版本上解决此问题的唯一方法是修改服务器,使其对这些大型资源使用分块传输编码[1]。在这种情况下,下载管理器将忽略并且不尝试解析Content-Length报头。

[1] http://en.wikipedia.org/wiki/Chunked_transfer_encoding

+0

感谢您回答(+1),但正如所说的,不幸的是,这不是服务器端的选项。无论如何,我不知道是否有人尝试过这种方法,并确认它是否正常工作 – gunar

+0

目前为止,此答案有5个upvotes,并且没有确认这实际上起作用。我无法访问支持chuncked内容响应的服务器以检查它。 – gunar

2

有这样一个明确的结果:

你不能修复DownloadManager。如果它是一个错误,它会是如此。 因此,简而言之,没有,您无法使用DownloadManager解决此问题。但是,您可以使用服务器端方法解决该问题,这种方法已在其他答案中加入了文字。

所以,我认为你最简单的解决方案是强制JB-MR2的最低sdk级别,因为@ksasq提到这个问题已经解决。

如果这不合情理,或者您的情况可能,您可以找到最好的文件下载库,并为此库创建类似于DownloadManager的界面。当然,这个接口应该被实现为使用默认的DownloadManager来处理没有这个错误的版本,并且使用那些有这个错误的自定义库(以及如果可能的话导致问题的文件)。

不幸的是,在谷歌搜索结果显示yingyixu's android-download-manager在2012年

另一个unfortunate note about this topic by CommonsWare只是为了验证有谷歌的支持库没有下载管理器最后更新。更糟糕的是,这家伙放弃了实施自己的港口的想法,因为它太复杂了。你只能希望yingyixu的图书馆或你希望找到的其他图书馆足够好。

+0

下载只是应用程序的功能之一。我无法将最低等级设置为JB-MR2,因为我将失去剩余的市场份额。 – gunar

0

您也可以采用固定版本DownloadManager,将软件包更改为您的软件包结构并使用此版本而不是系统版本。最终你需要从原包android.app中导入一些类。然后将您的实施注册为服务。

+0

实际下载不是由DownloadManager完成的;系统应用程序代表调用者应用程序执行此操作。要测试这一点,请从示例应用程序开始下载,强制关闭应用程序,打开下载管理器应用程序时,您将看到正在下载。 – gunar

相关问题