2014-02-12 2 views
15

Я работаю над приложением, и одна из функций, над которыми я работаю, - это загрузка некоторых двоичных файлов. Некоторые из них действительно большие (более нескольких мегабайт). Загрузки заканчиваются нормально, пока размер файла составляет менее 2 ГБ.DownloadManager загружает файлы более 2,1 ГБ

Я застрял в файле размером 3,2 ГБ, чтобы получить обновления для процесса обновления (я собираю DownloadManager для обновлений прогресса), но когда загрузка завершена, файл отсутствует в пути к целевому файлу. Опросив DownloadManager для этого идентификатора загрузки, я получаю STATUS_FAILED и причину ERROR_UNKNOWN - любимые сведения об ошибке, о которых вы когда-либо захотите!

Странно, что это появляется на большинстве устройств, но для некоторых (например, Samsung SG 4 Active OS 4.2.2 и LG Nexus 5 OS 4.4.2) оно не появляется.

Выполнение дополнительного расследования, я узнал, что это похоже на bug in Android DownloadManager implementation. Кажется, реализация Android хранит счетчик загрузки как int, но когда этот счет идет выше Integer.MAX_VALUE, загрузка заканчивается как неудачная.

Я имею в виду, чтобы заменить DownloadManager использование со службой на первом плане, но я бы не отказался от еще ....

ли вы, ребята сталкиваются с этим, и если да, то как это исправить? Есть ли какая-нибудь работа для использования DownloadManager в пред-4.2.2, поэтому я могу загрузить более 2,1 ГБ на файл?

+0

проверить Ion из Koush: https://github.com/koush/ion это довольно здорово, и это может хорошо работать с большими файлами – josebama

+0

@ josebama: это фактическая загрузка, выпущенная из пользовательского интерфейса? Я имею в виду, если пользователь поворачивает устройство, выйдет из приложения и затем снова войдет, будет ли загрузка продолжена и соответствовать всему пользовательскому интерфейсу? – gunar

+0

Не могу подтвердить, но предполагается – josebama

ответ

2

Чтобы скачать такие большие файлы, вам необходимо скачать те на куски. Либо вы можете использовать любую библиотеку, которая поддерживает параметры диапазона HTTP, позволяющие вытаскивать один файл в нескольких частях, поддерживая возобновление и т. Д.

Или вы можете разделить большой файл на своем сервере, а затем добавить текстовый файл с хешем MD5 каждый файл, когда вы сначала начинаете загрузку, затем получите файл MD5 после завершения, затем проверьте, что хеши соответствуют загруженным фрагментам. Если они этого не сделают, удалите эту часть и добавьте ее в очередь элементов для загрузки.

После того, как все куски загружены и MD5, вы можете поместить части обратно вместе в виде одного файла.

Если вы хотите загрузить файл на SD-карту, то FAT32 является файловой системой по умолчанию. В этой файловой системе есть ограничение по 4 ГБ на файл.

+0

Вы обобщили то, что говорили все остальные :) Но я не думаю, что вы предоставили что-то новое. – gunar

+0

Это только вы можете пройти через это, я еще не читал других ответов. Я не думаю, что я их скопировал, просто независимо от того, что бы я ни написал, и я не знаю, почему это казалось вам, я не представил ничего нового. –

+0

Принимая этот ответ, даже если он на самом деле не отвечает на него, потому что нет правдоподобного ответа. В конце я написал свой собственный менеджер загрузок, но этот ответ так же близок, как можно принять. Первоначально я хотел принять ответ от 'ksasq', но я не смог его проверить, так как у меня нет сервера, который знает, как обращаться с содержимым chuncked. Решение «Range» работает для меня, так как сервер поддерживает его. Благодаря! – gunar

0

Вы можете передать эту проблему, разделив файл на более мелкие ZIP-файлы. Следующий шаг - объединить их в цель, я нашел ->this<-, которые могут вам помочь. Если вы не будете сжимать файл (только для разделения), у вас должна быть хорошая производительность. Другая проблема заключается в том, что вам потребуется вдвое больше места для хранения. Вы можете загружать файлы меньшего размера, около 100 МБ, записывать их в объединенный буфер и удалять файловую систему формы, что позволит сэкономить пространство.

+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 content response, чтобы проверить его. – gunar

2

Существует один ясный результат этого:

Вы не можете исправить DownloadManager. Если это ошибка, это будет так. Поэтому, короче говоря, No, вы не можете обойти эту проблему, используя DownloadManager. Однако вы могли бы обойти это, используя подход на стороне сервера, который был добавлен в слова в других ответах.

Итак, я думаю, что вашим самым простым решением было бы заставить минимальный уровень sdk для JB-MR2, потому что @ksasq упомянул, что эта проблема решена.

Если это не правдоподобно или в вашем случае возможно, вы можете найти лучшую библиотеку для загрузки файлов и создать интерфейс, аналогичный DownloadManager для этой библиотеки. Конечно, этот интерфейс должен быть реализован для использования DownloadManager по умолчанию для версий, у которых нет этой ошибки, и использовать специальную библиотеку для тех, у кого была эта ошибка (и для файлов, которые вызывают проблему, если это возможно).

К сожалению, поиск по Google показал yingyixu's android-download-manager последнее обновление в 2012 году

Другой unfortunate note about this topic by CommonsWare просто проверяет, что нет DownloadManager в библиотеках поддержки Google. Хуже всего то, что парень отказался от идеи реализовать свой собственный порт, потому что это было слишком сложно. Вы можете только надеяться, что библиотека yingyixu или другая библиотека, которую вы, надеюсь, найдете, достаточно хороши.

+0

Загрузка - это только одна из особенностей приложения. Я не могу установить минимальный уровень для JB-MR2, потому что я потеряю оставшуюся часть доли на рынке. – gunar

0

Вы также можете воспользоваться фиксированной версией DownloadManager, изменить пакет на свою структуру упаковки и использовать эту версию вместо системной версии. В конце концов вам нужно импортировать некоторые классы из исходного пакета android.app. Затем зарегистрируйте свою реализацию как услугу.

+0

Фактическая загрузка не производится DownloadManager; системное приложение делает это от имени приложения-вызывающего. Чтобы проверить это, начните загрузку с примера приложения, закройте приложение и при открытии приложения Download Manager вы увидите, что загрузка выполняется. – gunar