facebook / fresco

An Android library for managing images and the memory they use.
https://frescolib.org/
MIT License
17.07k stars 3.75k forks source link

targetSdk 29 (scoped storage) support? #2455

Open raymondctc opened 4 years ago

raymondctc commented 4 years ago

Description

Fresco failed to load images from EXTERNAL_CONTENT_URI e.g. content://media/external/images/media/8039, FileNotFoundException was seen from the logs

Reproduction

Loading images with EXTERNAL_CONTENT_URI content://media/external/images/media/8039

Solution

I found that inside com.facebook.imagepipeline.producers.LocalContentUriFetchProducer, given the above content uri, it will fall to the call getCameraImage and which in turn getting the absolute file path of the image. However, due to scoped storage in targetSdk 29, that wouldn't be allowed. Probably getting input stream like

ParcelFileDescriptor pfd = mContentResolver.openFileDescriptor(contentUri, "r");
FileInputStream fis = FileInputStream(pfd.getFileDescriptor());

Additional Information

TangoHanks commented 4 years ago

Has it fixed by v2.1.0 ? Anybody knows ?

stale[bot] commented 4 years ago

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as "bug" or "enhancement" and I will leave it open. Thank you for your contributions.

husseinrasti commented 4 years ago
<manifest >
  <application 
        android:requestLegacyExternalStorage="true"
        tools:targetApi="q">
  </application>
</manifest>

use this solution as a temporary one

vokilam commented 4 years ago

I think this is also the reason why video thumbs are not loaded on Android Q. See https://github.com/facebook/fresco/issues/2390

paulmasters commented 4 years ago

I’m seeing something similar. The content URI of a photo is being converted to a file URI which cannot be accessed in Android10 (targetSDK29)

Loading URI : “content://media/external/images/media/34”
 gives error {“error": "/storage/emulated/0/Download/portrait5.jpg: open failed: EACCES (Permission denied)"}

paulmasters commented 4 years ago

I'll take a look at fixing this

esafirm commented 4 years ago

Hi @paulmasters do you still working on the fix? I would be happy to create one if you haven't

esafirm commented 4 years ago

After checking the issue, i think this already being handled. You have to request READ_EXTERNAL_STORAGE permission first though. cc: @oprisnik

paulmasters commented 4 years ago

Ha @esafirm, I started looking at it, but got diverted to a higher priority, sorry! I think a fix requiring READ_EXTERNAL_STORAGE must be a temporary one since any direct access of file URLs will stop working, as I understand it.

My initial investigation suggested that removing the code here will fix the problem. https://github.com/facebook/fresco/blob/master/imagepipeline/src/main/java/com/facebook/imagepipeline/producers/LocalContentUriFetchProducer.java#L71-L76 That code tests for external storage URIs ( not really camera URI), then tries to make file URLs, which will not work in the future.

If we remove this and simply let the next line use the contentURL directly to open a stream that should work fine, but I did not get time to make a nice test case.

paulmasters commented 4 years ago

For reference, this MediaStore.Images.ImageColumns.DATA is deprecated https://github.com/facebook/fresco/blob/b2049dcc2f2b5d8541e03682e3919d1b4c18eda8/imagepipeline/src/main/java/com/facebook/imagepipeline/producers/LocalContentUriFetchProducer.java#L35

https://developer.android.com/reference/android/provider/MediaStore.MediaColumns#DATA

paulmasters commented 4 years ago

@esafirm I've made this PR to show where I got to, if you could test that it works for you that would be great

TaeHyungK commented 4 years ago

I'm still experiencing this problem. Has it fixed ? In which version did this work? Does anyone know?

wafer-li commented 4 years ago

It is now October 2020

Since Android 11 become official, and it allow direct file access of Media Files again.

It is safe to say we could just simply use android:requestLegacyExternalStorage="true" when targetApi=29.

And when targetApi=30, even though the Android 11 force you to use Scoped Storage, Fresco could still use its old way to successfully display the image.

s4cha commented 3 years ago

Loading the same image uri with Native ImageView, using Glide or Coil works, but not Fresco's SimpleDraweeView.

raymondctc commented 3 years ago

Is there any roadmap on this? As it's approaching the deadline for new updates must set targetSdk to 30 soon (In November)

https://developer.android.com/distribute/best-practices/develop/target-sdk