ContentResolver openInputStream загружает файл в фоновом режиме

Итак, я пытаюсь скачать огромный файл. Поэтому, естественно, мой первый шаг - открыть поток

RNFetchBlob.RCTContext.getContentResolver().openInputStream(Uri.parse(fromUri));

Моя проблема в том, что вместо того, чтобы работать быстро и просто открывать поток, он фактически загружает объект в фоновом режиме. Откуда я знаю? Эта команда блокируется примерно на 5 минут, а затем, когда я читаю из потока, это происходит мгновенно.

Могу ли я сделать это действие запретить загрузку в фоновом режиме? Я хочу информировать пользователя о прогрессе, а не просто ждать.

Обновлено: чтобы прояснить, я использую URI content: // для ресурса

Нашли какое-нибудь решение? У меня такая же проблема при импорте файла размером 116 МБ из GDrive - мое приложение «зависает» на openInputStream. Я могу начать обсуждение этого вопроса, но кто знает, завершится ли когда-нибудь этот вызов.

coyer 04.03.2020 10:15
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
1
1 034
2

Ответы 2

Это неправильный метод чтения файла по сети, вам нужно использовать сетевые методы.

HttpURLConnection request = 
    (HttpURLConnection)(new URL(Uri.parse(fromUri)).openConnection());
// Connect to the server, expect a delay and draw a progress bar
request.connect();
// This will read HTTP headers with content length, expect another delay
// Must be called before request.getContentLength()
request.getInputStream();
// Get the size of your file, to draw your progress bar properly
long total = request.getContentLength();
// Now you can finally start reading the data
InputStream input = request.getInputStream();

спасибо, попробую! одна мелочь - мой URI - это вещь content: //, надеюсь, она сработает и для этого :)

Novellizator 15.11.2018 16:09

Это было бы проблемой, HttpURLConnection обрабатывает только URI http:// и https://. Вы не можете сделать это с помощью URI content://, он загружается кодом поставщика контента, а не кодом вашего приложения, и приложение не может контролировать процесс загрузки.

pelya 15.11.2018 16:13

Значит, нет способа узнать прогресс загрузки, и никто в сообществе Android не жаловался на это? (Я довольно много гуглил)

Novellizator 15.11.2018 16:15

Для длительных загрузок HTTP вы можете использовать DownloadManager и показывать прогресс загрузки, например. как в это вопрос Виктор Лаэрт:

    String urlDownload = <YOUR_URL>;
    DownloadManager.Request request = new DownloadManager.Request(Uri.parse(urlDownload));

    request.setDescription("Testando");
    request.setTitle("Download");
    request.allowScanningByMediaScanner();
    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
    request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,"teste.zip");

    final DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);

    final long downloadId = manager.enqueue(request);

    final ProgressBar mProgressBar = (ProgressBar) findViewById(R.id.progressBar1);

    new Thread(new Runnable() {

        @Override
        public void run() {

            boolean downloading = true;

            while (downloading) {

                DownloadManager.Query q = new DownloadManager.Query();
                q.setFilterById(downloadId);

                Cursor cursor = manager.query(q);
                cursor.moveToFirst();
                int bytes_downloaded = cursor.getInt(cursor
                        .getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
                int bytes_total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));

                if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL) {
                    downloading = false;
                }

                final int dl_progress = (int) ((bytes_downloaded * 100l) / bytes_total);

                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {

                        mProgressBar.setProgress((int) dl_progress);

                    }
                });

                Log.d(Constants.MAIN_VIEW_ACTIVITY, statusMessage(cursor));
                cursor.close();
            }

        }
    }).start();

здравствуйте, просто убедитесь, будет ли это работать для адресов content: //?

Novellizator 15.11.2018 16:16

Кажется, DownloadManagercontent: // дружелюбный: Важной вещью, которая способствует этому, является то, что Uri, возвращаемый DownloadManager, на самом деле является content: // ... Uri, который очень удобен для других приложений и позволяет им легко получать доступ к контенту через ContentProvider, предоставляемый DownloadManager..

Andrii Omelchenko 15.11.2018 16:22

@Novellizator Также взгляните на вопросы и ответы это и тот.

Andrii Omelchenko 15.11.2018 16:28

Так что, в конце концов, похоже, что это не так просто. попробовал ваш подход и получил: java.lang.IllegalArgumentException: Can only download HTTP/HTTPS URIs: content://com.google.android.apps.docs.storage/document/acc%‌​3D2%3Bdoc%3D43

Novellizator 15.11.2018 17:14

@Novellizator Какой у вас fromUri?

Andrii Omelchenko 15.11.2018 21:30

извлекается из сборщиков стопки при получении документа Google Диска

Novellizator 16.11.2018 13:52

Другие вопросы по теме