DownloadManager загружает файлы более 2,1 ГБ
Я работаю над приложением, и одна из функций, над которыми я работаю, - это загрузка некоторых двоичных файлов. Некоторые из них действительно большие (более нескольких мегабайт). Загрузки заканчиваются нормально, пока размер файла меньше 2 ГБ.
Я застрял в файле размером 3,2 ГБ, чтобы получить обновления для процесса обновления (я собираю DownloadManager для обновлений прогресса), но когда загрузка завершена, файл отсутствует в пути к целевому файлу. Опросив DownloadManager
для этого идентификатора загрузки, я получаю STATUS_FAILED
и причину ERROR_UNKNOWN
- список любимых ошибок, которые вы когда-либо пожелаете!
Что странно, так это то, что это появляется на большинстве устройств, но для некоторых (например, Samsung SG 4 Active OS 4.2.2 и LG Nexus 5 OS 4.4.2) оно не появляется.
Проведя дополнительное исследование, я узнал, что это выглядит как ошибка в реализации Android DownloadManager
. Кажется, реализация Android хранит счетчик скачиваний как int, но когда этот счет идет выше Integer.MAX_VALUE
, загрузка заканчивается как неудачная.
Я собираюсь заменить использование DownloadManager
на службу переднего плана, но я бы не сдался...
Вы, ребята, смотрели на это, и если да, то как вы это исправили?
Есть ли необходимость использовать DownloadManager
в пред-4.2.2, чтобы я мог загрузить более 2,1 ГБ на файл?
Ответы
Ответ 1
Чтобы загрузить такие большие файлы, вам нужно загрузить их в куски. Либо вы можете использовать любую библиотеку, которая поддерживает параметры диапазона HTTP, позволяющие вытаскивать один файл в нескольких частях, поддерживая возобновление и т.д.
Или вы можете разделить свой большой файл на своем сервере, а затем иметь текстовый файл с хешем MD5 каждого файла, когда вы сначала начнете загружаться, затем получите файл MD5 после завершения, затем проверьте, что хеши соответствуют загруженным фрагментам. Если они этого не сделают, удалите эту часть и добавьте ее в очередь загружаемых элементов.
Как только все куски загружены и MD5, вы можете поместить части обратно вместе как один файл.
Если вы хотите загрузить файл на SD-карту, тогда FAT32 является файловой системой по умолчанию. В этой файловой системе есть ограничение по 4 ГБ на файл.
Ответ 2
От взгляда на исходный код Android, похоже, эта проблема была решена в JB-MR2.
Кажется, что единственный способ обойти это на более старых версиях платформы - это изменить сервер таким образом, чтобы для этих больших ресурсов использовалась кодированная передача кодирования [1]. В этом случае Менеджер загрузки игнорирует и не пытается проанализировать заголовок Content-Length.
[1] http://en.wikipedia.org/wiki/Chunked_transfer_encoding
Ответ 3
Есть один явный результат:
Вы не можете исправить DownloadManager
. Если это ошибка в нем, это будет так. Поэтому, короче говоря, No, вы не можете обойти эту проблему, используя DownloadManager
. Однако вы могли бы обойти это, используя подход на стороне сервера, который был добавлен в слова в других ответах.
Итак, я думаю, что вашим самым простым решением было бы заставить минимальный уровень sdk для JB-MR2, потому что @ksasq упомянул, что эта проблема решена.
Если это не правдоподобно и в вашем случае возможно, вы можете найти лучшую библиотеку загрузки файлов и создать интерфейс, аналогичный DownloadManager для этой библиотеки. Конечно, этот интерфейс должен быть реализован для использования стандартного DownloadManager для версий, которые не имеют этой ошибки, и используют специальную библиотеку для тех, у кого была эта ошибка (и для файлов, которые могут вызвать проблему, если это возможно).
К сожалению, поиск в google показал yingyixu android-download-manager, последний раз обновленный в 2012 году.
Еще одна неудачная заметка об этой теме от CommonsWare просто проверяет, нет ли DownloadManager в библиотеках поддержки google. Хуже всего то, что парень отказался от идеи реализовать свой собственный порт, потому что это было слишком сложно. Вы можете только надеяться, что библиотека yingyixu или какая-то другая библиотека, которую вы, надеюсь, найдете, достаточно хороша.
Ответ 4
Вы можете передать эту проблему, разделив файл на более мелкие zip файлы. Следующий шаг - объединить их в цель, я нашел - > this < -, который может вам помочь. Если вы не будете сжимать файл (только для разделения), у вас должна быть хорошая производительность. Другая проблема заключается в том, что вам потребуется вдвое больше места для хранения. Вы можете загружать файлы меньшего размера, около 100 МБ, записывать их в объединенный буфер и удалять файловую систему формы, что позволит сэкономить пространство.
Ответ 5
Вы также можете взять фиксированную версию DownloadManager, изменить пакет на свою структуру пакета и использовать эту версию вместо версии системы, В конце концов вам нужно импортировать некоторые классы из исходного пакета android.app
. Затем зарегистрируйте свою реализацию как службу.