Fresco: Can't handle MediaStore URI if no Storage Permission.

Created on 8 Feb 2017  路  10Comments  路  Source: facebook/fresco

If Storage Permission is not granted, fetchDecodedImage in ImagePipeline fails when passed an ImageRequest with a MediaStore URI (e.g. content://media/external/images/media/917).

Error is /storage/emulated/0/DCIM/Camera/20161128_142252.jpg: open failed: EACCES (Permission denied)

My workaround was to convert the MediaStore Uri into a File Uri that is saved in the cache directory. The File Uri is then passed to Fresco.

if (UriUtil.isLocalCameraUri(uri)) {
   uri = copyMediaStoreUriToCacheDir(uri, filename);
}

    Uri copyMediaStoreUriToCacheDir(Uri uri, String filename) {

        String destinationFilename = App.getAppContext().getCacheDir().getAbsolutePath() + "/" + filename;

        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;

        try {
            bis = new BufferedInputStream(App.getAppContext().getContentResolver().openInputStream(uri));
            bos = new BufferedOutputStream(new FileOutputStream(destinationFilename, false));
            byte[] buf = new byte[1024];
            bis.read(buf);
            do {
                bos.write(buf);
            } while (bis.read(buf) != -1);

            return Uri.fromFile(new File(destinationFilename));
        } catch (IOException e) {
            //
        } finally {
            try {
                if (bis != null) {
                    bis.close();
                }
                if (bos != null) {
                    bos.close();
                }
            } catch (IOException e) {
                //
            }
        }

        return null;
    }
bug

All 10 comments

Thanks for the report @dannyroa, we'll take a look!

What exactly is the issue here? I've tried using an ACTION_PICK intent to get a content://media/external/... URI and without the EXTERNAL_STORAGE permission it doesn't work. However, using a simple ImageView or using your copyMediaStoreUriToCacheDir to change the URI did not change this either. Images don't show up unless the permission is granted. Isn't that the expected behavior?

@oprisnik: I'm using ACTION_GET_CONTENT intent.

ACTION_PICK is considered deprecated according to Diane Hackborn.

http://stackoverflow.com/questions/6486716/using-intent-action-pick-for-specific-path/6486827#6486827

Thanks, I only tested ACTION_OPEN_DOCUMENT and ACTION_PICK (sample will be available soon). I'll test with ACTION_GET_CONTENT.

It seems that the ACTION_GET_CONTENT example is working for me, even without permissions. I've added the sample in 35090465864103f65246546f170216ffddbee8ff. The Showcase sample app is here.

I always get content://com.android.externalstorage.documents/... URIs when I use ACTION_GET_CONTENT.

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, REQUEST_CODE_PICK_MEDIA);

screenshot_1486735873

Can you reproduce the issue in the sample app? You can just clone the repo, go to samples/showcase and install the app with Gradle.

@oprisnik: Sorry. Another thing I left out is it only happens in certain devices like LG G4 and Samsung Galaxy S6 - 6.0.1.

screen shot 2017-02-10 at 7 54 04 am

Same code in my Google Pixel works fine.

@oprisnik: Anything else you need?

As I've mentioned above: Can you reproduce the issue in the sample app? You can just clone the repo, go to samples/showcase and install the app with Gradle.

Happens on android 7.1.2, ACTION_GET_CONTENT does not work ACTION_OPEN_DOCUMENT works without permission

Closing as the reported issue is not reproducible in the sample app. Might be a device specific bug.

Was this page helpful?
0 / 5 - 0 ratings