Android Download Manager - не может знать размер загрузки

У меня проблемы с загрузкой файлов с сервера в приложении на основе WebView. Этот код на самом деле работает на Galaxy S4 с Android 4.4.2, но не работает на Nexus 5 с той же версией Android.

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {

        if (url.toLowerCase().contains("video") || url.toLowerCase().contains("mp4")) {
            String cookie = CookieManager.getInstance().getCookie(url);

            DownloadManager mdDownloadManager = (DownloadManager) MainActivity.this
                    .getSystemService(Context.DOWNLOAD_SERVICE);

            DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));

            request.addRequestHeader("Cookie", cookie);
            request.setDescription(getString(R.string.download_video));
            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
            request.setTitle(getString(R.string.app_name));
            Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).mkdirs();

            request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,  getFileName(url));
            request.setMimeType("video/mp4");
            mdDownloadManager.enqueue(request);
        }
        webViewPreviousState = PAGE_REDIRECTED;
        view.loadUrl(appendAndroidClientIdentification(url));

        return true;
    }

Проверка журналов обнаружила это при попытке загрузить файл через устройство Nexus 5:

 I/DownloadManager﹕ Download 1755 starting
 W/DownloadManager﹕ Aborting request for download 1755: can't know size of download, giving up
 I/DownloadManager﹕ Download 1755 finished with status CANNOT_RESUME

Ответ:

Проблема была на стороне сервера. Я использовал метод send_data из рельсов. Этот метод не отправляет ContentLength в заголовках, и это является причиной ошибки на некоторых устройствах.

Чтобы исправить это, просто добавьте в файл application.rb:

config.middleware.use Rack::ContentLength

person rodeleon    schedule 13.04.2014    source источник
comment
Помимо файла cookie, есть ли что-нибудь необычное в HTTP-запросе и ответе? Глядя на исходный код, код загрузки не получил заголовок Content-Length и не получил заголовок Transfer-Encoding: chunked, поэтому он не знает, насколько велика загрузка.   -  person CommonsWare    schedule 14.04.2014
comment
Я тестирую это в своей локальной сети, и видеофайлы обслуживаются приложением rails с использованием метода send_data. Теперь я пытаюсь загрузить файл с помощью браузера Chrome (это мобильное приложение jquery), и он не работает, и в журналах появляется та же ошибка. Таким образом, код Android из вопроса может не быть проблемой ... Что касается вашего вопроса, URL-адрес, по которому приложение rails получает видеофайл, является https. Если это проблема, я не уверен, почему она отлично работает на S4, но не на Nexus 5...   -  person rodeleon    schedule 14.04.2014
comment
Просто обновите ответ. Спасибо за вашу помощь!   -  person rodeleon    schedule 14.04.2014


Ответы (1)


Проблема была на стороне сервера. Я использовал метод send_data из рельсов. Этот метод не отправляет ContentLength в заголовках, и это является причиной ошибки на некоторых устройствах.

Чтобы исправить это, просто добавьте к application.rb :

config.middleware.use Rack::ContentLength
person rodeleon    schedule 14.04.2014