Essentials: [Bug] 1.6.0-pre5 MediaPicker throws System.UnauthorizedAccessException on videos and images

Created on 6 Dec 2020  路  3Comments  路  Source: xamarin/Essentials

I just tried to update from 1.6.0-pre4 to 1.6.0-pre5 on a currently working xamarin project. Using Visual Studio 2019. Testing the resulting App on Android 10, from Pixel Experience.

On 1.6.0-pre5:

Using the MediaPicker to choose photos (or videos, same problem), it shows the picker interface, but when selecting a media file I get (i.e.):

System.UnauthorizedAccessException: 'Access to the path "/storage/emulated/0/Pictures/Reddit/30b195b.png" is denied.'

Then I proceed to Uninsntall 1.6.0-pre5, reinstall 1.6.0-pre4, same photo (or video) and it works flawlessly: Picker is shown, media is selected just fine.

Tried several times. Same result.

bug

Most helpful comment

Thanks for the feedback. I managed to figure it out. I was testing on a whole matrix here, but it seems that Android 10+ has a slightly different file permissions model.

On devices before 10, the picker returns a URI to an image, and you can resolve it to get the physical image file. If you have permissions to read the file, which we do, then all is good.
However, on 10+, the OS actually restricts the access to that file since you don't own it. In the earlier previews of Essentials, we actually requested read access but then leaked it. In the latest preview, I did not account for the updated permissions and still returned the physical path to the file.

I'll open a PR and correctly return a valid path that will work.

All 3 comments

Just checking if you have the permissions to read the external storage?

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

I'll do some tests and see what needs to happen, but that _should_ allow you access.

Yes, I have, on my AssembyInfo.cs:

[assembly: UsesPermission(Android.Manifest.Permission.ReadExternalStorage)]
[assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)]
[assembly: UsesPermission(Android.Manifest.Permission.Camera)]

Everything works fine under 1.6.0-pre4.

Thanks for your work and concern!

Thanks for the feedback. I managed to figure it out. I was testing on a whole matrix here, but it seems that Android 10+ has a slightly different file permissions model.

On devices before 10, the picker returns a URI to an image, and you can resolve it to get the physical image file. If you have permissions to read the file, which we do, then all is good.
However, on 10+, the OS actually restricts the access to that file since you don't own it. In the earlier previews of Essentials, we actually requested read access but then leaked it. In the latest preview, I did not account for the updated permissions and still returned the physical path to the file.

I'll open a PR and correctly return a valid path that will work.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

RogerSchmidlin picture RogerSchmidlin  路  4Comments

charlespetzold picture charlespetzold  路  4Comments

nbsoftware picture nbsoftware  路  5Comments

Agredo picture Agredo  路  3Comments

gabry90 picture gabry90  路  3Comments