community icon indicating copy to clipboard operation
community copied to clipboard

Camera crash on Android (presumably by pausing app for a while)

Open Cheaterman opened this issue 3 years ago • 3 comments

Software Versions

  • Python: 3.8.1
  • OS: Android
  • Kivy: 2.0.0rc1 git-e972f0e
  • Kivy installation method: Buildozer

Describe the bug Android camera crashes on start() presumably after pausing app for a while - needs to have used start() once before.

To Reproduce Basically, have an app with a ToggleButton that can start/stop the Camera. You should then start the camera, stop it, pause the app (by pressing your phone power button or otherwise), wait 5 minutes or so, then resume the app and try to start the camera again.

EDIT: No need to start the camera the first time. Start your app, pause it, resume it a while later, then start the camera, and it should crash.

Code and Logs and screenshots It should fail with:

10-20 14:54:21.870 13201 13240 I python  :    File "/data/data/com.unity514.chill/files/app/screens/ticket.kv", line 7, in <module>
10-20 14:54:21.871 13201 13240 I python  :      on_pre_enter: if self.camera: self.camera.start()
10-20 14:54:21.871 13201 13240 I python  :    File "/home/cheaterman/Dev/Unity514/Chill/app/.buildozer/android/app/libs/garden/garden.zbarcam/zbarcam/zbarcam.py", line 110, in start
10-20 14:54:21.871 13201 13240 I python  :    File "kivy/weakproxy.pyx", line 35, in kivy.weakproxy.WeakProxy.__setattr__
10-20 14:54:21.872 13201 13240 I python  :    File "kivy/properties.pyx", line 497, in kivy.properties.Property.__set__
10-20 14:54:21.872 13201 13240 I python  :    File "kivy/properties.pyx", line 544, in kivy.properties.Property.set
10-20 14:54:21.872 13201 13240 I python  :    File "kivy/properties.pyx", line 599, in kivy.properties.Property.dispatch
10-20 14:54:21.873 13201 13240 I python  :    File "kivy/_event.pyx", line 1248, in kivy._event.EventObservers.dispatch
10-20 14:54:21.873 13201 13240 I python  :    File "kivy/_event.pyx", line 1154, in kivy._event.EventObservers._dispatch
10-20 14:54:21.874 13201 13240 I python  :    File "/home/cheaterman/Dev/Unity514/Chill/app/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/chill/kivy/uix/camera.py", line 117, in on_play
10-20 14:54:21.874 13201 13240 I python  :    File "/home/cheaterman/Dev/Unity514/Chill/app/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/chill/kivy/core/camera/camera_android.py", line 133, in start
10-20 14:54:21.874 13201 13240 I python  :    File "jnius/jnius_export_class.pxi", line 769, in jnius.jnius.JavaMethod.__call__
10-20 14:54:21.874 13201 13240 I python  :    File "jnius/jnius_export_class.pxi", line 863, in jnius.jnius.JavaMethod.call_method
10-20 14:54:21.875 13201 13240 I python  :    File "jnius/jnius_utils.pxi", line 91, in jnius.jnius.check_exception
10-20 14:54:21.875 13201 13240 I python  :  jnius.jnius.JavaException: JVM exception occurred: startPreview failed

Or something along those lines.

Additional context Seems like we're not alone: https://github.com/react-native-camera/react-native-camera/issues/2083#issuecomment-550439851

At the very least I have somewhat of a suspicion that we should call .release() in .stop(), which we currently don't. Maybe that would help?

EDIT: We kinda do... But it's as good as if we didn't: https://github.com/kivy/kivy/blob/master/kivy/core/camera/camera_android.py#L44

AIUI __del__() basically offers zero guarantees to ever be called. Maybe we should call _release_camera() in .stop()?

EDIT2: In general I suppose we have zero guarantee that the android.hardware.Camera will still be alive and well after a pause? Maybe kivy.core.CameraAndroid needs to bind to App.on_pause and App.on_resume to revive the camera object if needed?

EDIT3: Extra information: if I stay on the screen that displays the camera (and the camera is supposed to be playing), leave my phone for a few minutes, and go back into the app, the camera appears frozen. If I then call .stop() then .start() again on the camera, the app crashes with the logs above.

Cheaterman avatar Oct 20 '20 13:10 Cheaterman

I concur, pause/resume does not work reliably. I use garden.xcamera the behavior is similar to what @Cheaterman reports. The issue is I think in the use of kivy.graphics.shader , during on_pause() a dict element is not removed by _release_camera() then on_resume() init_camera() fails trying to insert the same shader into the dict.

See https://github.com/kivy/kivy/issues/6919#issuecomment-707447281

I like the "zero guarantee" phrasing, but I think it is worse than that. If an app tries so handle pause/resume it is guaranteed to fail, if an app does not try to handle pause/resume it is guaranteed to fail if another app uses the camera during the first app's pause.

And in case you want to try opencv camera on Android instead, that no longer works at all.

RobertFlatt avatar Oct 21 '20 03:10 RobertFlatt

I have the same problem as @Cheaterman reports. When I open & close (camera.play = True & camera.play = False) , the kivy android app crashed.

The error log is "jnius.jnius.JavaException: JVM exception occurred: startPreview failed"

cloud1980 avatar Apr 03 '22 13:04 cloud1980

I gave up with Kivy Camera on Android, the design predates mobile device cameras, and it uses an obsolete Android api.

So I wrote this https://github.com/Android-for-Python/Camera4Kivy works on https://github.com/Android-for-Python/Camera4Kivy#tested-examples-and-platforms

RobertFlatt avatar Apr 03 '22 16:04 RobertFlatt