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):
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.
I recently came across this issue and could find no solutions online, so I will provide mine here in the hopes that it helps someone.
The issue at hand is that when the CapturePhotoAsync is called, the camera app is opened and your app is put into the background. This makes it vulnerable to garbage collection and will sometimes cause the app to restart on next launch.
My solution: In order to keep our app alive when taking the photo, we will first start a foreground process before calling CapturePhotoAsync.
1.) Create a service in your Android project, something like this:
[Service]
public class AndroidPhotoService : Service
2.) In the service, override OnStartCommand and create your notification
// Create a notification and set it as a foreground service
var notification = new Notification.Builder(this)
.SetChannelId("yourChannelName")
.SetContentTitle("Whatever")
.SetContentText("Whatever")
.SetSmallIcon(Resource.Drawable.SymDefAppIcon)
.Build();
StartForeground(1, notification);
return StartCommandResult.Sticky;
3.) Make sure override OnDestroy
public override void OnDestroy()
{
StopForeground(true);
base.OnDestroy();
}
4.) In your MainActivity, setup a Messaging subscription to capture the photo and send the results back to your ViewModel
MessagingCenter.Subscribe<AddAttachmentViewModel>(this, "StartPhotoService", async (sender) =>
{
var intent = new Intent(this, typeof(AndroidPhotoService));
StartService(intent);
var photo = await MediaPicker.CapturePhotoAsync();
MessagingCenter.Send("YourMessageID", "PhotoCaptured", photo);
}
5.) Subscribe to this message in your ViewModel and process the photo as required.