Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xamarin.Android MediaPicker.CapturePhotoAsync does not work in Android 13

I am using the Xamarin.Essentials MediaPicker for capturing images in my app. https://learn.microsoft.com/de-de/xamarin/essentials/media-picker?tabs=android

just like var photo = await MediaPicker.CapturePhotoAsync();

For Android < 13 I am asking for permissions:

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

and everything works fine.

Since those permission do not work for Android 13, I am asking for

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

(see Android 13 - How to request WRITE_EXTERNAL_STORAGE)

the problem is, that the Xamarin.Essentials.MediaPicker still misses the StorageWritePermission when trying to take a photo. But I can't ask for those in Android 13.

enter image description here

Any ideas how to make it work for Android 13?

Info:

  • Uploading an image works fine (MediaPicker.PickPhotoAsync)
  • Device tested: Samsung Galaxy Tab 7 FE Android 13
  • Device tested: Google Pixle 7 Android 13
  • Bug thread https://github.com/xamarin/Essentials/issues/2041

Update:

  • Pull request https://github.com/xamarin/Essentials/pull/2065 which could fix this problem
like image 428
Aiko West Avatar asked Oct 27 '25 03:10

Aiko West


1 Answers

Update

In Android 13, the method MediaPicker.CapturePhotoAsync() can not be used due to the permission. You can check the issue thread Storage permissions Android 13 api 33 for more information.

The code below works for versions prior to Android 13

I created a demo on my side and it worked well, you can refer to this. I am using the permissions below.

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

 <queries>
    <intent>
        <action android:name="android.media.action.IMAGE_CAPTURE" />
    </intent>
</queries>

Here is the code in .cs file.

 public partial class MainPage : ContentPage
        {
            public string PhotoPath { get; set; } = null;
            public MainPage()
            {
                InitializeComponent();
            }
    
            private async void Button_Clicked(object sender, EventArgs e)
            {
                var file = await MediaPicker.CapturePhotoAsync();
                await LoadPhotoAsync(file);
                if (file == null)
                    return;
                async Task LoadPhotoAsync(FileResult photo)
                {
                    // canceled
                    if (photo == null)
                    {
                        PhotoPath = null;
                        return;
                    }
                    // save the file into local storage
                    var newFile = Path.Combine(FileSystem.CacheDirectory, photo.FileName);
                    using (var stream = await photo.OpenReadAsync())
                    using (var newStream = File.OpenWrite(newFile))
                        await stream.CopyToAsync(newStream);
                    PhotoPath = newFile;
                    img.Source = PhotoPath;//Show on the front page
                }
            }
        }

Here is the code in xaml

<StackLayout>
    <Button Text="button" Clicked="Button_Clicked"></Button>
    <Image x:Name="img" ></Image>
</StackLayout>
like image 77
Guangyu Bai - MSFT Avatar answered Oct 30 '25 13:10

Guangyu Bai - MSFT



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!