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

时间:2016-07-24 17:35:35

标签: 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何时注册新创建的图像?

2 个答案:

答案 0 :(得分:1)

您可以使用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()方法中取消注册。

答案 1 :(得分: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/