ContentResolver не содержит только что созданное изображение в немедленном запросе после создания файла

Я использую этот код для копирования изображения с помощью documentFile.createFile()

private void newcopyFile(File fileInput, String outputParentPath,
                            String mimeType, String newFileName) {

        DocumentFile documentFileGoal = DocumentFile.fromTreeUri(this, treeUri);

        String[] parts = outputParentPath.split("\\/");
        for (int i = 3; i < parts.length; i++) {
            if (documentFileGoal != null) {
                documentFileGoal = documentFileGoal.findFile(parts[i]);
            }
        }
        if (documentFileGoal == null) {
            Toast.makeText(MainActivity.this, "Directory not found", Toast.LENGTH_SHORT).show();
            return;
        }

        DocumentFile documentFileNewFile = documentFileGoal.createFile(mimeType, newFileName);

        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {
            outputStream = getContentResolver().openOutputStream(documentFileNewFile.getUri());
            inputStream = new FileInputStream(fileInput);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        try {
            if (outputStream != null) {
                byte[] buffer = new byte[1024];
                int read;
                if (inputStream != null) {
                    while ((read = inputStream.read(buffer)) != -1) {
                        outputStream.write(buffer, 0, read);
                    }
                }
                if (inputStream != null) {
                    inputStream.close();
                }
                inputStream = null;
                outputStream.flush();
                outputStream.close();
                outputStream = null;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

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

cursorPhotos = MainActivity.this.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                    projectionsImages,
                    null,
                    null,
                    MediaStore.Images.Media.DATE_TAKEN + " DESC"
            );

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

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

Есть ли способ или слушатель, чтобы знать, когда вновь созданное изображение зарегистрировано ContentResolver?

2 ответа

Решение

Вы можете использовать это или так я реализовал слушателя (наблюдателя) для ContentResolver изменения, используя ContentObserver знать, когда подходящее время для запуска запроса на получение вновь созданного изображения из ContentResolver,

Сначала создать ContentObserver Учебный класс:

Этот класс, как говорит его название, наблюдает за любыми изменениями содержимого в нашем желаемом Uri.

class MyObserver extends ContentObserver {
    public MyObserver(android.os.Handler handler) {
        super(handler);
    }

    @Override
    public void onChange(boolean selfChange) {
        this.onChange(selfChange, null);
    }

    @Override
    public void onChange(boolean selfChange, Uri uri) {
        //(SDK>=16)
        // do s.th.
        // depending on the handler you might be on the UI
        // thread, so be cautious!

        // This is my AsyncTask that queries ContentResolver which now
        // is aware of newly created media file.
        // You implement your own query here in whatever way you like
        // This query will contain info for newly created image
        asyncTaskGetPhotosVideos = new AsyncTaskGetPhotosVideos();
        asyncTaskGetPhotosVideos.execute();
    }
}

и в конце вашего метода копирования вы можете установить ContentObserver на ваш ContentResolver на конкретном ури.

 getContentResolver().registerContentObserver(
         MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
         true,
         myObserver);

и не забудьте отменить регистрацию вашего наблюдателя, иначе вы столкнетесь с утечкой памяти. Я бы предпочел это в конце моей AsyncTask (onPostExecute).

getContentResolver().unregisterContentObserver(myObserver);

Вы можете выбрать ContentObserver на желаемом Uri в течение всего жизненного цикла приложения, чтобы получать уведомления об изменении, удалении или вставке носителей извне или внутри вашего приложения.

Для этого подхода вы можете зарегистрировать своего наблюдателя в onResume() метод жизненного цикла и отменить его регистрацию в onPause() метод.

Извините, я отправил неправильный код

Когда вы добавляете файлы в файловую систему Android, эти файлы не выбираются программой MedaScanner автоматически. Но часто они должны быть.

Таким образом, чтобы добавить файл в контент-провайдера вручную

Так что используйте этот код:-

Intent intent =
      new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(Uri.fromFile(file));
sendBroadcast(intent);

Для большего количества методов сделать это и для справки посетите этот сайт:-

http://www.grokkingandroid.com/adding-files-to-androids-media-library-using-the-mediascanner/