question

JRE-6783 avatar image
0 Votes"
JRE-6783 asked RobCaplan edited

Cannot use CapturePhotoAsync() if camera causes app to background and restore?

I understand that during the lifecycle of the app, an activity may be put into the background, and essentially be 'put to sleep'. I have code during a normal activity restore, that will recover the data etc.

When I use a method like:

 private async void TakePhoto()
     {
         // Photo requested
    
         var photo = await MediaPicker.CapturePhotoAsync();
    
        // Photo taken
    
     }

If when calling TakePhoto(), the Android device does not fully background the app, the method successfully hits "Photo taken". If the app is fully backgrounded (as soon as the camera app loads in front it decides to free up resources), once the photo is taken, the activity restores itself, but the original method is no longer executing, so I am unable to continue to get the photo response, thus "Photo taken" is never hit.

So my question is, how am I implementing this wrong, given how the Android activity lifecycle works?


dotnet-xamarin
· 3
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

but the original method is no longer executing, so I am unable to continue to get the photo response, thus "Photo taken" is never hit.

Hi, JRE-6783. Sorry, I am a little confused about this question. What does the 'original method' mean? And what is the 'photo response'? Could you please post more details about the problem? When launching the camera app from an Activity, the OnPause and OnStop method will be triggered.

I create a basic demo to the function, the photo is successfully captured. And it's able to get the file info of taking photo, everything works as expected.

0 Votes 0 ·

Hi @JarvanZhang-MSFT

The original method = 'TakePhoto()'

'Photo response' = var Photo

It works for me as too, as long as OnCreate() is never fired after OnStop() instead of OnResume(). If I have a device where Android decides to free up the resource, as the camera is launched, my app process may suddenly be killed, this is a problem. Android is free to do this by design as it doesn't know the user doesn't want to use my app anymore, but is despirate for resource, so kills the process (as per https://developer.android.com/guide/components/activities/activity-lifecycle "Apps with higher priority need memory"). The app is not destroyed, but will require the process to be recreated automatically when it resumes. It has to go via OnCreate() first though.

So in the above, I take the photo, but as soon as my app resumes, OnCreate() and OnResume() fires, but OnPhoto() never picks up where it left off. So the line "var photo = await MediaPicker.CapturePhotoAsync();" never completes.

The only way to recreate is to force your app to need to call OnCreate() and OnResume() once your app returns, by having it put your app to be despirate for resources. I find going to the homescreen and launching as many resource hungry apps as possible, speeds this up. If your app stays alive the whole time, it won't be a problem, and is not recreatable.

0 Votes 0 ·

Please tell me I am making sense? I know this is not a problem with Essentials or Android; both work fine. It is just i don't understand how it is possible to rely on getting a result/response from one activity (in this case camera) directly, just because you can't be sure the activity will be in the same lifecycle state when it returns. When i coded taking a photo without using a third party lib, I would call the camera with StartActivityForResult(). This way of doing it means, you don't need to worry about the app not returning back to the same method. OnActivityResult() fires even if OnResume() fires, and you grab the photo data from there. With this inline way of calling the camera, and waiting for a response, the lifecycles of Android seem to be getting in the way...

Again, please tell me I am making sense?

0 Votes 0 ·

1 Answer

JarvanZhang-MSFT avatar image
0 Votes"
JarvanZhang-MSFT answered JarvanZhang-MSFT edited

Hello,​

Welcome to our Microsoft Q&A platform!

If I have a device where Android decides to free up the resource, as the camera is launched, and my app is now suddenly put into the background, this is a problem...

Do you face the issue or just want to avoid this problem? When the MediaPicker.CapturePhotoAsync is called, it will start the system internal camera api/function instead of starting the camera application. You could click the 'progress' button to check the progress of the application of the device after calling the command. You'll see that there is only one progress, the capture function runs in your application's progess. So when your application is killed by the system or manaually, the capture function will also be killed.

Best Regards,

Jarvan Zhang


If the response is helpful, please click "Accept Answer" and upvote it.

Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

@JarvanZhang-MSFT

I face the issue. The fact remains, unfortunately as soon as the camera launches (I don't care what is actually happening behind the scenes to make that happen), my app gets killed, but the camera (internal API camera) is still running. Just to be clear, I know via logging, that OnCreate() gets called, when the camera has done its thing (the camera stayed alive, to let me click capture and then click save). I also know via logging, the whole app process is killed, and recovered, as per https://developer.android.com/guide/components/activities/activity-lifecycle, as other static classes are also recreated at this point, which is logged. This is just fact. Are you able to reproduce this lifecycle scenario in Xamarin.Android, and confirm you are still able to load the photo (i.e. get the response from MediaPicker.CapturePhotoAsync())?

0 Votes 0 ·

Hi, JRE-6783. Please see this running record: https://imgur.com/Lm5d15O The camera api/function is running in the test App, the application is not be killed. And the OnCreate method is not being calling after taking the photo. Please add breakpoints to the lifecycle method for test.

0 Votes 0 ·