创建文件后,ContentResolver在立即查询中不包含刚刚创建的图像 [英] ContentResolver doesn't contain just created image in an immediate query after creation of file

本文介绍了创建文件后,ContentResolver在立即查询中不包含刚刚创建的图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用此代码使用documentFile.createFile()

I'm using this code to copy an image using 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的方式,以立即刷新我的图像库,其中包含应该包含新创建图像信息的查询结果.

And this is how I query ContentResolver after creating image, to immediately refresh my image gallery with the result of query which should contain info of newly created image.

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

但是立即查询找不到新创建的图像. 如果过一会儿再次运行查询,结果中将出现新创建的图像.

But immediate query couldn't find newly created image. And if I run query again after a moment, newly created image is there in the result.

为新创建的图像提供信息似乎需要花费ContentResolver的时间(如果由ContentResolver负责),因为在我运行即时查询时它将在后台运行.

It seems providing information for newly created image takes time for ContentResolver(if ContentResolver is in charge for it) as it would be running in background while I run immediate query.

是否有任何方法或侦听器知道ContentResolver何时注册了新创建的图像?

Is there any method or listener to know when the newly created image is registered by ContentResolver?

推荐答案

您可以使用或这就是我对ContentResolver更改实施侦听器(观察者)的方法,使用ContentObserver知道什么时候才是运行查询以从中获取新创建的图像的适当时间ContentResolver.

You could use this or this is how I've implemented a listener(observer) to ContentResolver changes, using ContentObserver to know when is the appropriate time to run a query for getting newly created image from ContentResolver.

首先创建ContentObserver类:

此类的名称告诉我们,它会在我们所需的Uri中观察任何内容更改.

This class as its name tells us, observes any content changes in our desired 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();
    }
}

,在复制方法的最后,您可以在特定的Uri上将ContentObserver设置为ContentResolver.

and at the end of your copy method, you could set ContentObserver to your ContentResolver on specific Uri.

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

并且不要忘记注销观察者的注册,否则您将面临内存泄漏.我希望在AsyncTask(onPostExecute)的末尾执行该操作.

and don't forget to unregister your observer otherwise you will face memory leak. I would prefer to do it at the end of my AsyncTask (onPostExecute).

getContentResolver().unregisterContentObserver(myObserver);

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

You could choose to have a ContentObserver on your desired Uri through your entire app lifecycle to get notified whenever a media got changed, deleted or inserted from outside or within your app.

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

For this approach, you could register your observer in the onResume() lifecycle method and unregister it in the onPause() method.

这篇关于创建文件后,ContentResolver在立即查询中不包含刚刚创建的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆