Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Capacitor Camera restarts apps on certain Android 13 devices #1736

Open
klaurtar opened this issue Aug 15, 2023 · 27 comments
Open

Capacitor Camera restarts apps on certain Android 13 devices #1736

klaurtar opened this issue Aug 15, 2023 · 27 comments

Comments

@klaurtar
Copy link

Bug Report

Plugin(s)

@capacitor/camera v5.X.X

Capacitor Version

💊   Capacitor Doctor  💊 

Latest Dependencies:

  @capacitor/cli: 5.2.3
  @capacitor/core: 5.2.3
  @capacitor/android: 5.2.3
  @capacitor/ios: 5.2.3

Installed Dependencies:

  @capacitor/cli: 5.0.3
  @capacitor/core: 5.2.2
  @capacitor/android: 5.0.3
  @capacitor/ios: 5.0.3

[success] iOS looking great! 👌
[error] Missing <manifest package=""> attribute in app/src/main

Platform(s)

Certain Android devices running Android 13 with SDK version 33
Reports of this happening have come from:

  • Samsung SM-A426U
  • Samsung Galaxy S21FE
  • Samsung Galaxy S21 5G

Current Behavior

When Camera.getPhoto() is called the system allows the user to choose a photo or take a photo. When take a photo is clicked, the system's camera UI is displayed. A user is then allowed to take a photo. When the photo is taken, it will then ask the user if they would like to retry the photo or if it is ok. When the ok option is selected, the app restarts as if the user had just opened the app. No debugging occurs as the console is wiped everytime this happens.

Screen_Recording_20230814_223820_bad_camera_android.mp4

app crashes

Expected Behavior

Camera.getPhoto() should allow Android 13 users to take a photo, and then approve the photo. This should not restart the app.

Record_2023-08-14-22-40-15.mp4

Code Reproduction

Here is a working recreation of the bug

Run the Android app on a physical Samsung Android 13 device like I listed above. Click the + icon on the placeholder image to take a photo. Then quickly click the ok or checkmark button. This should cause the app to restart. I had to take a photo 3 times before the bug started occurring. If it is not occuring, kill the app and restart it and repeat the process.

Other Technical Details

Additional Context

I found this related Ionic forum post about this issue

I also noticed from testing that if a user with an effected device takes a photo, then waits for about 10 seconds before pressing ok or the checkmark on the system UI, it will work as it should. However, if a user quickly takes a photo and accepts it, the app restarts.

I unfortunately need a fix for this asap. My business relies on this feature. Thanks!

@klaurtar
Copy link
Author

Can anyone from the Capacitor team at least let me know they've seen this report? My Android app is getting review bombed due to this bug

@dallastjames
Copy link
Collaborator

Hey @klaurtar!
We took a good look at this yesterday and were not able to reproduce it across our suite of devices. I believe that the issue you're running into is actually a fairly common issue with Android. When the camera is launched, it's a new "activity" and that puts your application in the background. The behavior of the Android OS is that if it needs more memory, it'll kill things that are in the background, and that can include your application. All symptoms in your report seem to point to that being what's going on: no crash report, app is restarting, occurs when you finish the flow with the camera app and it's trying to return to your application.

There are two pieces you need to handle this in your application. When you go to open something over the top of your application, in this case camera, but it could apply to other things too, you should save enough information about the state of your application that you can restore it if the OS kills your application. That might include things like what page the user was on, any form data, etc. This would allow you to restore your app state on init again if needed. Then, whenever you return from this other "something" that you're doing, you would clear that data from memory, so you don't restore to this state later when it doesn't make sense. That's the first half.

The second half is "how do I get the data from the camera if the webview was restarted?" Obviously, you'll have no more promise to await, however, the camera data will still be made available through the appRestoredResult. This is our way of providing your app with any data sent to your application if it had been closed due to the Android OS killing your app in the background (same as described in the SO link above).

Put those two pieces together, and you can smoothly handle your app restarting due to Android low memory behavior!
Hope this helps!

@klaurtar
Copy link
Author

Thank you for the detailed reply. I will see if this helps.

@LeonardoRT96
Copy link

I had the same problem, my solution was to change CameraResultType.Uri to CameraResultType.Base64. But I need an effective solution that allows me to use CameraResultType.Uri.

@michael-arboleda
Copy link

I am still getting this issue. Not only on Android but iOS as well. I added Crashlytics log around Camera.getPhoto since this is where the app restarts. According to Crashlytics, the device does have a good amount of RAM and Disk memory free.

Here are the device details of an Android device restarting:
Device
Brand: Samsung
Model: Galaxy S20 FE 5G
RAM free: 1.68 GB
Disk free: 71.4 GB

Operating System
Version: Android 13
Orientation: Portrait
Rooted: No

@klaurtar
Copy link
Author

klaurtar commented Sep 6, 2023

@michael-arboleda Yeah that is my thoughts as well. The phones have plenty of memory left when this happens. I have started working on adding the fix the Capacitor team recommended above. It is a bit of a hacky workaround having to access the pre-crash state and then get the user back to where they were. Were you able to recreate the issue on the sample application I provided?

@klaurtar
Copy link
Author

klaurtar commented Sep 8, 2023

@dallastjames Anyway to get a second look at this? @michael-arboleda brings up a good point with his above comment. I still think Capacitor could have a bug

@klaurtar
Copy link
Author

klaurtar commented Sep 9, 2023

UPDATE: When the application is in the camera UI from calling the Camera.getPhoto method, the bug almost NEVER occurs when the flash is turned on.

@dallastjames
Copy link
Collaborator

@klaurtar I'm happy to look at this issue again, but I do still believe that this is most likely the Android OS just killing the app in the background. We've looked at the sample provided and tested across our devices and have not been able to replicate this issue, so at the moment, there really isn't anything we can do about without additional information. If the application is crashing, there should be crash logs from that, and I believe you can typically get those from your play store console to help debug crashes in production. Any chance you could provide those here?

The most likely case here is just the Android OS killing your app in the background. According to the Android Activity lifecycle docs the state of having the camera in the foreground puts your application in the higher category for the OS killing your application. The method I described above, while it might feel hacky, is the recommended approach given by Android and is just abstracted away into the Capacitor appRestoredResult handler. Unfortunately, just looking at the amount of RAM available when the app was killed isn't a way to judge if the app was terminated by the OS or not. The example provided above, assuming the lower-end S20 FE 5G (6 gb ram) still puts ram usage at ~75% (and ~80% for the 8gb model) at the time the app was killed. There's no information available from Android that details limits and thresholds, but it seems plausible that it might happen in the case.

Anyways, if you do have crash logs I'd love to see them and we can take a look to see if there's something telling within the logs that can help us track down if there is a bug in Capacitor. If there is, we'll happily take a look and see what we can do!

@dallastjames
Copy link
Collaborator

One other resource one of the other team members brought up. It hasn't been updated super recently, but we haven't seen anything indicating that anything has changed since Android 11 anyways. https://dontkillmyapp.com/samsung Samsung is notoriously quick to kill background apps, so it's not surprising that all the reported devices here as Samsung devices as well.

@klaurtar
Copy link
Author

@dallastjames Thanks for the update. I've implemented the above fix you mentioned and it's working. I'll continue to do some digging and see if I can gain any insights on the issue, and report back. I'm glad Capacitor has an answer for this out of the box. Thank you!

@ZioCain
Copy link

ZioCain commented Sep 13, 2023

I have a very lowend Android and as time goes by, it kills more and more apps while taking pictures.
My user solution was to reduce the quality of the images taken by the camera so that it would take less computing effort and has to kill fewer apps.

It's not a good solution, but it might help to lower the overall quality from the camera settings (at least for testing purposes)

@PYTHAVA
Copy link

PYTHAVA commented Sep 26, 2023

i also get the similer problem while i am taking image using camera.getPhoto it's take the image but i submit the click or just click on right button it's crash my app and restart the application

@abcRede
Copy link

abcRede commented Dec 5, 2023

I'm having this exact same issue with some high-end devices!

@raphjutras
Copy link

I also received two bug reports from separate clients using our app running Capacitor.
The bug is exactly as described in this issue.
Also, they both have a Samsung S21 running Android 13.

@JLoveI
Copy link

JLoveI commented Jan 2, 2024

I'm looking for the solution

@c00
Copy link

c00 commented Jan 18, 2024

@dallastjames Thank you for the ton of details you've provided about this!

Do you know of any way to simulate this situation? To effectively force Android to close the app while the camera is open, so I can test the fixes to it?

@klaurtar
Copy link
Author

@dallastjames Thank you for the ton of details you've provided about this!

Do you know of any way to simulate this situation? To effectively force Android to close the app while the camera is open, so I can test the fixes to it?

In developer settings on your android phone you want to turn on the setting "Don't Keep Activities"

Screenshot_2024-01-18-00-16-50-44_fc704e6b13c4fb26bf5e411f75da84f2.jpg

@Hambat
Copy link

Hambat commented Jan 23, 2024

@dallastjames hello, I'm having this exact same
you can replicate this issue in browserstack, Xiaomi > Redmi Note 9 (10)

@qliqdev
Copy link

qliqdev commented Feb 2, 2024

I think @capcitor/camera should migrate to Camera X

to solve this problem. Any contributors here who can do this?

@pbergner
Copy link

pbergner commented Feb 8, 2024

@klaurtar was the suggested fix you implemented to store and restore the app state if it crashes?

@dtrigo
Copy link

dtrigo commented Apr 19, 2024

  • Updated project to capacitor v6.
  • As sugested by @klaurtar I enabled "Don't keep activities" option to 'simultate' the situation.

-> No appRestoredResult is produced as far as I can tell.

Am I missing something? Do I have to modify AndroidManifest or MainActivity in any way? thanks in advance

@dtrigo
Copy link

dtrigo commented May 3, 2024

Apparently I had and old version of MainActivity.java (I mean, generated by an old capacitor version), so after I removed the following "outState.clear();", it worked as expected:

@Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // outState.clear(); }

@miguelvillaparedes
Copy link

@klaurtar ayudame no se que codigo debo hacer para hacer una solucion , me esta pasando en android 13 y no he podido solucionar , ayudaa
@klaurtar help me, I don't know what code I should do to make a solution, it's happening to me on Android 13 and I haven't been able to solve it, help

@rsh-am
Copy link

rsh-am commented Jun 25, 2024

Hello,

We are observing the same issue with a device in particular :
Samsung Galaxy Tab Active4 Pro 5G 64Go Entreprise Edition.
(Exact model: SM-T636B, storage: 64 Go, memory: 4 Go).

It is running on Android 14.
We are using Ionic 15 and Capacitor Camera plugin "@capacitor/camera": "^6.0.0".

We call the function like this:

Camera.getPhoto({
resultType: CameraResultType.Base64,
source: CameraSource.Camera,
quality: 80,
width: 600
})

If it may help, we observed that the issue occurs more frequently when the "Automatic HDR" option is enabled in the settings when taking a photo. It probably always occurs when HDR mode is effectively applied. But it sometimes occurs even when Automatic HDR is disabled.

We tried to reproduce it with the same application on other devices (Samsung galaxy S24 for example with Android 14 as well, and on older devices), but without success.

When analyzing in debug with android studio, we don't see a memory peak, it's just as if the webview was restarted.

Let us know if we can help to solve this issue.

@jonathan-chin
Copy link

@dallastjames hello, I'm having this exact same you can replicate this issue in browserstack, Xiaomi > Redmi Note 9 (10)

a client of mine is reporting this exact issue with this exact phone, running Android 13.0.3

I've tried reducing the image quality (100 to 50) and disabling image editing but he is still reporting the same issue.

I can try the state restore solution but it seems like that would take a bit of work. any other possible solutions that would be quick to try?

@MaddHatters
Copy link

MaddHatters commented Sep 11, 2024

@dallastjames I think these logs/findings will help confirm your thoughts here.

I've been seeing this issue on a Samsung S7 FE SM-T733. On the device it shows I have 1.1 GB of ram available out of 4.

If I set the battery optimization for my app to unrestricted it seems to help but did not fully stop the issue from occurring. If I set it to restricted, that seems to make the problem more apparent as expected.

I'm not sure why this occurs on some devices and not others. They must have different settings. We have older devices running Android 13/14 with the same or less ram and they work fine.

I believe it is the lmkd driver that is causing this. See logs below.
https://source.android.com/docs/core/perf/lmkd

Notice

  1. when the camera is open cameramode_killboost is set to true
  2. My app is reclaimed after taking a picture Reclaim 'base64.baseline.com.myapp.mobile'
  3. The reclaim message is only shown before my app is restarted so I'm pretty confident this is the cause.
2024-09-11 10:36:23.027   653-653   lmkd   lmkd   I  check CAMERA CLOSE, set cameramode_killboost false
2024-09-11 10:36:39.926   653-653   lmkd   lmkd   I  check CAMERA OPEN, set cameramode_killboost true
.....log truncated
2024-09-11 10:36:42.587   653-653   lmkd   lmkd   I  cached 0, sandbox(not0) 0
2024-09-11 10:36:42.587   653-653   lmkd   lmkd   D  No processes to kill with adj score >= 850
2024-09-11 10:36:42.589   653-653   lmkd   lmkd   I  cached 0, sandbox(not0) 0
2024-09-11 10:36:42.594   653-653   lmkd   lmkd   I  Reclaim 'android:drmService' (15089), uid 1000, oom_score_adj 500, state 10 to free 31936kB rss, 40320kB swap; reason: low watermark is breached and swap is low (2093644kB < 912256kB)
2024-09-11 10:36:42.602   653-653   lmkd   lmkd   I  cached 0, sandbox(not0) 0

2024-09-11 10:36:42.608   653-653   lmkd   lmkd   I  Reclaim 'base64.baseline.com.myapp.mobile' (15137), uid 10315, oom_score_adj 350, state 150 to free 153144kB rss, 40940kB swap; reason: low watermark is breached and swap is low (2094576kB < 912256kB)

2024-09-11 10:36:42.683   653-653   lmkd   lmkd   I  cached 0, sandbox(not0) 0
2024-09-11 10:36:42.684   653-653   lmkd   lmkd   D  No processes to kill with adj score >= 201
2024-09-11 10:36:42.694   653-653   lmkd   lmkd   I  cached 0, sandbox(not0) 0
2024-09-11 10:36:42.694   653-653   lmkd   lmkd   D  No processes to kill with adj score >= 201
2024-09-11 10:36:42.707   653-653   lmkd   lmkd   I  cached 0, sandbox(not0) 0
2024-09-11 10:36:42.707   653-653   lmkd   lmkd   D  No processes to kill with adj score >= 201
2024-09-11 10:36:45.641   653-653   lmkd   lmkd   I  check CAMERA CLOSE, set cameramode_killboost false

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests