Taking a picture using the ionic-native camera plugin sometime makes the app restart

VERSIONS:
Ionic CLI (ionic -v): 6.12.1
cordova (cordova -v): 9.0.0

@ionic/angular: 5.2.3
@ionic-native/camera: 5.27.0
cordova-android: 8.1.0

Problem
I have an Ionic app which uses the ionic-native camera plugin. 99% of the time I take a picture with that plugin, everything works as intended and I get an bas64 string back from the camera. However, sometimes when confirming the photo in the camera app (when it should return to my app), it restarts my app.

I’ve tried using the cordova-plugin-background-mode plugin to enable the backgroundMode just before starting the camera, but this doesn’t change the outcome (this makes it “worse” because now the app doesn’t restart, but is just killed).

I’ve checked if it’s a memory issue, but it also happens on devices that have more than enough memory (8gb, more than 3gb free)

Code example

// Camera options
this.defaultCameraOptions = {
    quality: 80,
    destinationType: DestinationType.DATA_URL,
    encodingType: EncodingType.JPEG,
    mediaType: MediaType.PICTURE,
    targetHeight: 1000,
    targetWidth: 1000,
    correctOrientation: true,
    saveToPhotoAlbum: false,
    cameraDirection: 0,
    sourceType: PictureSourceType.CAMERA
};

const cameraResult: string = await this.camera.getPicture(this.defaultCameraOptions);

let resultBase64: string = '';
if (cameraResult) {
    resultBase64 = 'data:image/jpeg;base64,' + cameraResult;
}

console.log(resultBase64);

Debug logs:
Using logcat I got the following logs:

PluginManager: THREAD WARNING: exec() call to Camera.takePicture blocked the main thread for 40ms. Plugin should use CordovaInterface.getThreadPool().
CordovaActivity: Paused the activity.
CordovaActivity: Stopped the activity.

Process : Sending signal. PID: 29900 SIG: 9
Zygote  : Process 29900 exited due to signal 9 (Killed)
ActivityManager: Process <package.id> (pid 29900) has died: fore TOP 
libprocessgroup: Successfully killed process cgroup uid 10175 pid 29900 in 0ms

I think this is pretty common with cordova-android and their camera API. They way it works is by pausing the App, starting the built-in camera app, and then returning the photo data from that. As unfortunate as it sounds, this is to be expected from Cordova-android.

Capacitor thought shouldn’t have this problem.

1 Like

Is it possible to use capacitor plugins in our current cordova app (which is pretty huge, with quite a lot cordova plugins)? Or do we need to ‘rebuild’ the app from scratch to include Capacitor?

Also can you explain why the Capacitor camera plugin doesn’t have this issue?

I’ve migrated our project to use capacitor (luckily almost all our cordova plugins where supported by capacitor) using the guide provided by Ionic at: Capacitor - build cross platform apps with the web

I also am now using the capacitor plugin for the camera. But I still get the same result. The app still restarts sometimes after taking a picture.

Logs from logcat:

08-31 13:42:55.601 28975 29181 V Capacitor/Plugin: To native (Capacitor plugin): callbackId: 111841455, pluginId: Camera, methodName: getPhoto
08-31 13:42:55.602 28975 29181 V Capacitor: callback: 111841455, pluginId: Camera, methodName: getPhoto, methodData: {"quality":80,"resultType":"dataUrl","width":1000,"height":1000,"correctOrientation":true,"saveToGallery":false,"direction":"REAR","source":"CAMERA"}
08-31 13:42:55.665 28975 28975 D Capacitor: App paused
08-31 13:42:56.454 28975 28975 D Capacitor/AppPlugin: Firing change: false
08-31 13:42:56.454 28975 28975 V Capacitor/AppPlugin: Notifying listeners for event appStateChange
08-31 13:42:56.454 28975 28975 D Capacitor/AppPlugin: No listeners found for event appStateChange
08-31 13:42:56.457 28975 28975 D Capacitor: App stopped
08-31 13:42:56.468 28975 28975 D Capacitor: Saving instance state!
08-31 13:43:00.672  1534  6349 I ActivityManager: Process <package.id> (pid 28975) has died: prev LAST
08-31 13:43:00.678   994   994 I Zygote  : Process 28975 exited due to signal 9 (Killed)
08-31 13:43:00.695  1534  1589 W ActivityManager: setHasOverlayUi called on unknown pid: 28975
08-31 13:43:00.717  1534  1598 I libprocessgroup: Successfully killed process cgroup uid 10177 pid 28975 in 44ms

Correction to what mhartington said.

This is a common problem in Capacitor apps too, and even in native apps.
When you launch an Intent to another app (such as the camera), there are always possibilities that the OS kills your app while the other app was open and your app gets restarted once the other app finish doing their business (taking the picture).

1 Like

call this.backgroundMode.enable() just before this.camera.getPicture method
and disable it before resolving.

Make sure to add BackgroundMode in Providers array and import it in your component.