Saving an image after getting folder from Storage Access Framework UI

三世轮回 提交于 2019-12-23 03:42:07

问题


I set a preference for users to select save folder for my app using Storage Access Framework. After getting uri onActivityResult I save it to SharedPreferences as String and save image when it's to be saved.

I'm using this method to save image successfully.

public void saveImageWithDocumentFile(String uriString, String mimeType, String name) {
    isImageSaved = false;
    try {
        Uri uri = Uri.parse(uriString);
        DocumentFile pickedDir = DocumentFile.fromTreeUri(this, uri);
        DocumentFile file = pickedDir.createFile(mimeType, name);
        OutputStream out = getContentResolver().openOutputStream(file.getUri());
        isImageSaved = mBitmap.compress(CompressFormat.JPEG, 100, out);
        out.close();

    } catch (IOException e) {
        throw new RuntimeException("Something went wrong : " + e.getMessage(), e);
    }
    Toast.makeText(MainActivity.this, "Image saved  " + isImageSaved, Toast.LENGTH_SHORT).show();
}

If user deletes the folder selected using SAF, iget null DocumentFile file and app crashes. My first question is how can i check if folder exist without opening SAF ui again.

I also want to use ParcelFileDescriptor to save same image with this method

public void saveImageWithParcelFileDescriptor(String folder, String name) {
    if (mBitmap == null) {
        Toast.makeText(MainActivity.this, "", Toast.LENGTH_SHORT).show();
        return;
    }
    String image = folder + File.separator + name + ".jpg";
    Toast.makeText(MainActivity.this, "image " + image, Toast.LENGTH_LONG).show();

    Uri uri = Uri.parse(image);
    ParcelFileDescriptor pfd = null;
    FileOutputStream fileOutputStream = null;
    try {
        pfd = getContentResolver().openFileDescriptor(uri, "w");
        fileOutputStream = new FileOutputStream(pfd.getFileDescriptor());
        mBitmap.compress(CompressFormat.JPEG, 100, fileOutputStream);

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } finally {
        if (pfd != null) {
            try {
                pfd.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        if (fileOutputStream != null) {
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    Toast.makeText(MainActivity.this, "Image saved  " + isImageSaved, Toast.LENGTH_SHORT).show();

}

i get java.lang.IllegalArgumentException: Invalid URI: content://com.android.externalstorage.documents/tree/612E-B7BF%3Aname/imagePFD.jpg on linepfd = getContentResolver().openFileDescriptor(uri, "w");

This is how I call this method, currentFolder is the folder I get using intent and same folder on first method.

saveImageWithParcelFileDescriptor(currentFolder, "imagePFD");

How can I fix this, and which method is more preferable and why?


回答1:


how can i check if folder exist

DocumentFile has an exists() method. In theory, pickedDir.exists() should tell you if it exists. In practice, it is up to the storage provider.

I also want to use ParcelFileDescriptor to save same image with this method

That code has bugs:

  • You cannot grant yourself permissions using grantUriPermission()

  • You cannot invent arbitrary Uri values via concatenation, particularly for a provider that is not yours

How can I fix this

Delete it.

which method is more preferable

The first one.

and why?

The first one will work, perhaps with minor adjustment. The second one has no chance of working.



来源:https://stackoverflow.com/questions/45924864/saving-an-image-after-getting-folder-from-storage-access-framework-ui

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!