1

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();
        }
    }

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.

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.

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

4

2 回答 2

1

您可以使用,或者这就是我实现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的特定 Uri。

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

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

getContentResolver().unregisterContentObserver(myObserver);

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

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

于 2016-07-25T13:25:39.050 回答
0

对不起,我发布了错误的代码

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

于 2016-07-24T18:43:39.277 回答