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

标签 android android-contentprovider android-contentresolver storage-access-framework documentfile

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

最佳答案

您可以使用this或者这就是我如何实现 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 设置为特定 Uri 上的 ContentResolver

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

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

getContentResolver().unregisterContentObserver(myObserver);

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

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

关于android - ContentResolver 在创建文件后立即查询中不包含刚刚创建的图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38554843/

相关文章:

Android - 找不到 google-play-services_lib.apk!错误

Android + Sync Adapter + Content provider更新操作失败

android - 修复 Content Provider Android 上的 SQL 注入(inject)漏洞

android - getcontentresolver() 在服务中返回 null

Android:不处理带有选择 WHERE 子句的 SQLite 查询

java - 如何在 "query"方法中传递选择参数

android - 如何使用 onClick() 方法在 Recyclerview 中设置 ImageResource()?

android - 如何解决 'Null Pointer Exception'

java - Android onClickListener 和 Button 仅触发一次

android - 无法使用 ContentProvoider 更新联系人