ContentResolver 在创建文件后立即查询中不包含刚刚创建的图像

ContentResolver doesn't contain just created image in an immediate query after creation of file

我正在使用此代码通过 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何时注册了新创建的图像?

对不起,我发错代码了

当您将文件添加到 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/

你可以使用 this 或者这就是我如何实现一个监听器(观察器)到 ContentResolver 变化,使用 ContentObserver 来知道什么时候是 运行 从 ContentResolver.

获取新创建图像的查询

首先创建ContentObserverClass:

这个 class 正如它的名字告诉我们的那样,观察我们想要的 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 设置为特定 Uri 上的 ContentResolver

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

并且不要忘记注销您的观察者,否则您将面临内存泄漏。我更愿意在我的 AsyncTask (onPostExecute) 结束时执行此操作。

getContentResolver().unregisterContentObserver(myObserver);

您可以选择在整个应用程序生命周期中为所需的 Uri 添加一个 ContentObserver,以便在媒体从您的应用程序外部或内部更改、删除或插入时收到通知。

对于这种方法,您可以在 onResume() 生命周期方法中注册您的观察者,并在 onPause() 方法中注销它。