repeated use of Xamarin.Essentials.MediaPicker.CapturePhotoAsync restarts my app on Android 11

Viewed 1112

I need to take more photos, but the app restarts on Android 11 devices. Android 10 or lower is OK. It behaves enigmatic. Sometimes it happens after third capturing, sometimes maybe after seventh capturing.

Simulation of the problem (restart after second capturing):

  1. Click Button for take a picture
  2. Take a picture
  3. Click OK
  4. App returns to the screen with button
  5. Steps 1-3
  6. App restarts and displays the home screen

If I place a breakpoint on var photo = await MediaPicker.CapturePhotoAsync(); and go to next step, nothing gets done and app crashes.

This also happens in App-Essentials Sample App.

Edit: My code:

var file = await MediaPicker.CapturePhotoAsync();

while (LS.IsIntermediateActivity())

{ await Task.Delay(10); }

Normal behaviour: capture photo, click OK, next step - while (LS.IsIntermediateActivity()) and then in MainActivity OnRestart and OnResume. (LS is DependencyService)

Incorrect behaviour: capture photo, click OK, no next step - app crash or restart and show MainPage. No Exception, no warning.

3 Answers

I remember one of my colleagues ran into a very similar issue and this note on Media picker that actually fixed their issue

All methods must be called on the UI thread because permission checks and requests are automatically handled by Xamarin.Essentials.

This is weird because their own example is not doing that :/

Anyway try this and see if this solves your issue:

var fileResult= await Device.InvokeOnMainThreadAsync(async () => await MediaPicker.CapturePhotoAsync());

Goodluck

Feel free to get back if you have queries.

I looked into this very problem. Basically, when opening the camera with Media Picker from within you app, your app gets put in the background by Android since the camera app is now being used. Some RAM optimizations takes place and the OS may restart your app. In testing we had no problems with a device with 3Gb RAM, but run into this issue with a 2Gb RAM device. Very likely because of not enough RAM.

A solution would be to save your application state when leaving your app and reuse that after coming back from taking a photo, in case your app gets restarted. We haven't found a simple solution for that, ideas are very welcome...

I tried another solution:

public async Task<string> TakePhotoAsync()
    {
        waitForResult = new AsyncAutoResetEvent();
        var context = Android.App.Application.Context;
        var activity = Xamarin.Essentials.Platform.CurrentActivity as MainActivity;
        using (var intent = new Intent(MediaStore.ActionImageCapture))
        {
            string timestamp = System.DateTime.Now.ToString("yyyyMMdd_HHmmss");
            var file = new File(GetPictureDirPath(), "EMAphoto_" + timestamp + ".jpg");
            var uri = FileProvider.GetUriForFile(context, context.ApplicationContext.PackageName + ".fileprovider", file);
            intent.PutExtra(MediaStore.ExtraOutput, uri);
            activity.StartActivityForResult(intent, CAMERA_REQUEST_CODE);
            await waitForResult.WaitAsync().ConfigureAwait(true);
            return file.Path;
        }

    }

and it crashes too... Is stupid Android 11 or me?

Related