apache / cordova-plugin-camera

Apache Cordova Plugin camera
https://cordova.apache.org/
Apache License 2.0
966 stars 1.55k forks source link

Camera plugin crashes app on some android phones when an image is taken #345

Closed hamzatrq closed 4 weeks ago

hamzatrq commented 6 years ago

So the plugin works on most of the devices, it works on IOS perfectly. But on android it works on some devices and on some devices once the picture is taken the user is send back to app, app crashes. Now the only thing that I am doing is storing this image in an array. Now one more thing is that if I take a picture and click on retake and then submit the second image the app does not crashes but if I submit the first image it crashes.

Here is my function:


uploadImage() {
    this.actionCtrl.create({
      title:  'Upload Image',
      buttons: [
        {
          icon: 'camera',
          text: 'Open Camera',
          handler: () => {
            const options: CameraOptions = {
              quality: 100,
              destinationType: this.camera.DestinationType.DATA_URL,
              encodingType: this.camera.EncodingType.JPEG,
              mediaType: this.camera.MediaType.PICTURE,
              sourceType: 1
            }

            this.camera.getPicture(options).then((imageData) => {
              let base64Image = 'data:image/jpeg;base64,' + imageData;
              this.images.push(base64Image);
              console.log(base64Image);
            }, (err) => {
              console.log('Error Uploading File')
            });
          }
        },
        {
          icon: 'image',
          text:  'Open Gallery',
          handler: () => {
            const options: CameraOptions = {
              quality: 100,
              destinationType: this.camera.DestinationType.DATA_URL,
              encodingType: this.camera.EncodingType.JPEG,
              mediaType: this.camera.MediaType.PICTURE,
              sourceType: 0
            }

            this.camera.getPicture(options).then((imageData) => {
              let base64Image = 'data:image/jpeg;base64,' + imageData;
              this.images.push(base64Image);
            }, (err) => {
              console.log('Error Uploading File')
            });
          }
        }
      ]
    }).present();
  }
coderroggie commented 6 years ago

Which version of Android? We are seeing similar issues with an Android 8 device. We are thinking it may be related to the device having an app called Moto Camera installed on it.

bleuscyther commented 6 years ago

Happens on Android 7 Moto C Plus

Saqib92 commented 6 years ago

Happens on Infinix Devices (android 6.0) also.

bleuscyther commented 6 years ago

Using cordova-plugin-background-mode. Enable before camera and then disable after camera is back. It fixed the problem.

peterpeterparker commented 6 years ago

It's probably a memory problem and it's how Android behave

I faced that problem too and built a workaround in my Ionic app using the provided Cordova lifecycle, I documented everything in https://forum.ionicframework.com/t/solved-camera-plugin-restart-app-on-android-8-1 if interested

Mastech10 commented 6 years ago

Happens on Android 6 also (Moto G 3G).

Just sometimes console display URI of the new image and then crush or just crash DevApp (Restart). My code:

takePicture(sourceType: PictureSourceType) { var options: CameraOptions = { quality: 20, sourceType: sourceType, // PHOTOLIBRARY or CAMERA targetWidth: 300, targetHeight: 300, destinationType: this.camera.DestinationType.FILE_URI, };

this.camera.getPicture(options).then(imagePath => {
    //console.log("getPicture done!", imagePath);
    this.profilePic = normalizeURL(imagePath);
    console.log("picture normalized done!", this.profilePic);
});

}

Saqib92 commented 6 years ago

Devices Update fixed this issue for me.

yuankunluo commented 5 years ago

yes. Some problem.

It happened on Android 9, which will kill the IonicApp during photo taking. I have 3 android phones, it works well on android 7.0.1, Android 8. This does not happen always, it is unpredictable.

If the app was killed ,there is no way to get data back from life cycle. Because it is not "resume", it was restarted.

mrHassanRaza commented 5 years ago

Update Camera Plugin and Cordova-android version it will fix this issue

cymxiao commented 5 years ago

yes. Some problem.

It happened on Android 9, which will kill the IonicApp during photo taking. I have 3 android phones, it works well on android 7.0.1, Android 8. This does not happen always, it is unpredictable.

If the app was killed ,there is no way to get data back from life cycle. Because it is not "resume", it was restarted.

Same problem from my IOS device. IOS 12, iphone 6 plus 64G . some time it works fine , some time after take photo, the app crashed.

desmeit commented 5 years ago

@mrHassanRaza I updated to the newest Android Cordova Version 7.1.4 but its the same issue. It crahs the app if I try to get a photo with 8.1.0.

mrHassanRaza commented 5 years ago

@desmeit is your cordova-plugin-camera plugin version is greater then 4.0 ? if not then update it to latest

ikamikaz3 commented 5 years ago

Hi,

I'm encoutering the same issues as @yuankunluo / @desmeit / @cymxiao

Here's my ionic info output

β†’ ionic info                                                                                                [0e15ec6]
βœ” Gathering environment info - done!

Ionic:

   ionic (Ionic CLI)  : 4.2.1
   Ionic Framework    : ionic-angular 3.9.2
   @ionic/app-scripts : 3.2.1

Cordova:

   cordova (Cordova CLI) : 8.1.2 (cordova-lib@8.1.1)
   Cordova Platforms     : android 7.1.4, ios 4.5.5
   Cordova Plugins       : cordova-plugin-ionic-keyboard 2.1.3, cordova-plugin-ionic-webview 2.3.1, (and 13 other plugins)

System:

   Android SDK Tools : 26.1.1 (/home/mikaz3/android-sdk-linux)
   NodeJS            : v8.12.0 (/usr/bin/node)
   npm               : 6.4.1
   OS                : Linux 4.15

cordova-plugin-camera in package.json has version : ^4.0.3

I can also say that taking a picture with the camera works for me but not choosing one from the library (internal storage). i can provide my code aswell if needed.

As pointed by @yuankunluo the lifecycle event doesn't even get fired. The app is set in pause state when opening the photo library, then when choosing the desired picture, the app simply gets put on background as if I had pressed the back button, and when clicking on the app it boots normally. Meaning resume event never gets fired.

I've actually tested all of the above and can provide code for it.

Regards

desmeit commented 5 years ago

It seems Android worked on the issue which made it necessary to implement the background plugin. I deactivated the background plugin for devices older than Android 8 and now it worked. I don't know if there is a generally issue with the Background Plugin and Android 8.

if (device.platform.toLowerCase() == 'android' && parseInt( device.version, 10 ) < 8){
    cordova.plugins.backgroundMode.enable();
}
ikamikaz3 commented 5 years ago

It seems Android worked on the issue which made it necessary to implement the background plugin. I deactivated the background plugin for devices older than Android 8 and now it worked. I don't know if there is a generally issue with the Background Plugin and Android 8.

if (device.platform.toLowerCase() == 'android' && parseInt( device.version, 10 ) < 8){
  cordova.plugins.backgroundMode.enable();
}

Thanks for the input, will try this ASAP !

sithwarrior commented 5 years ago

So whats the verdict on this? Does enabling the background mode before image capture, fix this?

@ikamikaz3 ?

coderroggie commented 5 years ago

@sithwarrior We upgraded to cordova-plugin-camera@4.0.3, cordova-android@7.1.4 and cordova@8.1.2 and it seemed to fix most issues with users and the camera. We had to get rid of the backgroundMode plugin as it was causing problems with ios 12.2 so that fix option was not an issue.

ikamikaz3 commented 5 years ago

@sithwarrior Well, i've managed to get it working with background mode but im not 100% it was caused by this as other users seem to have it working without it,

imho for me it was more a problem on the system ram for the device i was testing on.

My conclusion on this would be to try without it in the first place and make sure you have tons of ram on your android simulator or test on a real device.

sithwarrior commented 5 years ago

@coderroggie @ikamikaz3 Thanks for the response guys. Will try updating the camera plugin.

ynagasundeep commented 5 years ago

I am facing same issue. I am using FILE_URI as destinationType. My phone contains lot of free memory, still app crashes when i try to take pictures.

Does anyone help me to understand the root cause for the crash?

@sithwarrior did you tried with upgrading the plugin, please post your results.

Thanks

ynagasundeep commented 5 years ago

Which version of Android? We are seeing similar issues with an Android 8 device. We are thinking it may be related to the device having an app called Moto Camera installed on it.

i see crashes on samsung and LG phones with high resolution camera not just moto.

thesheikhwasim commented 5 years ago

It's probably a memory problem and it's how Android behave

I faced that problem too and built a workaround in my Ionic app using the provided Cordova lifecycle, I documented everything in https://forum.ionicframework.com/t/solved-camera-plugin-restart-app-on-android-8-1 if interested

Its 404, the link provided. Can you elaborate

weiz18 commented 5 years ago

Hey,

I am also having the similar issue on my Iphone devices where after a photo is taken, the app is restarted. Especially for the devices with high resolution camera. My assumption is that when the camera is opened and the app is placed in background, the IOS terminates the app due to high memory assumption (either coming from the camera or from my app) ? Is there a way to save the state of the app or to prevent the IOS from terminating the app ?

Thanks

yaksneumann commented 5 years ago

It's probably a memory problem and it's how Android behave

I faced that problem too and built a workaround in my Ionic app using the provided Cordova lifecycle, I documented everything in https://forum.ionicframework.com/t/solved-camera-plugin-restart-app-on-android-8-1 if interested

the link is not founded, i have the same issue with a moto g4 plus, i have a feeling that it has to do with the memory. if anyone knows any other solution please share

bleuscyther commented 5 years ago

It's probably a memory problem and it's how Android behave I faced that problem too and built a workaround in my Ionic app using the provided Cordova lifecycle, I documented everything in https://forum.ionicframework.com/t/solved-camera-plugin-restart-app-on-android-8-1 if interested

the link is not founded, i have the same issue with a moto g4 plus, i have a feeling that it has to do with the memory. if anyone knows any other solution please share

@yaksneumann @thesheikhwasim here is the new link: https://forum.ionicframework.com/t/solved-camera-plugin-restart-app-on-android/117828

Arieru commented 5 years ago

It crashes on my tablet which has Android 6.0

tenglandct commented 5 years ago

Hey,

I am also having the similar issue on my Iphone devices where after a photo is taken, the app is restarted. Especially for the devices with high resolution camera. My assumption is that when the camera is opened and the app is placed in background, the IOS terminates the app due to high memory assumption (either coming from the camera or from my app) ? Is there a way to save the state of the app or to prevent the IOS from terminating the app ?

Thanks

Hi @weiz18 , some of our users are having a similar issue and we are finding it nearly impossible to replicate. Did you manage to find a solution, or work out what was happening?

weiz18 commented 5 years ago

@tenglandct we never managed to find a proper solution. IOS will always kill app to save memory. So i doubt there is a good way to prevent the crash beside limiting the memory consumption of your app. To reproduce, i guess you just need to run a lot of background apps, and then take high quality pictures (with Iphone x max). My advice is to do a fail safe check which make sure that app can restore to previous state the app crashed and reloaded

tenglandct commented 5 years ago

@weiz18 thank you very much for responding! That is interesting, I think we may have something slightly different going on as one of our users who has reported it is using an older phone (iPhone 6s Plus) and using quite downscaled photos (using the target height/width) and it has only started happening in the last couple of versions. Thank you very much for responding, it is great to get some more information πŸ˜„

ynagasundeep commented 5 years ago

I still see the same issue, its just because IONIC cannot manage high resolution pictures and app crashes due to low memory issue. So we shifted to React instead of IONIC.. now we don't see this issue :)

On Tue, Jul 9, 2019 at 9:11 PM tenglandct notifications@github.com wrote:

@weiz18 https://github.com/weiz18 thank you very much for responding! That is interesting, I think we may have something slightly different going on as one of our users who has reported it is using an older phone (iPhone 6s Plus) and using quite downscaled photos (using the target height/width) and it has only started happening in the last couple of versions. Thank you very much for responding, it is great to get some more information πŸ˜„

β€” You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/apache/cordova-plugin-camera/issues/345?email_source=notifications&email_token=AFJPJYJ4MYDDT4T7Q7J4JKTP6SWRLA5CNFSM4FVZJL3KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODZQVN3Y#issuecomment-509695727, or mute the thread https://github.com/notifications/unsubscribe-auth/AFJPJYJW5XW75QFUXHDW3WDP6SWRLANCNFSM4FVZJL3A .

-- ​ With Regards,

Naga Sundeep. ​Asst. Professor, Dept of EEE PBR VITS, Kavali 524201 Nellore D.t​ Andhra Pradesh.

veronicatc commented 5 years ago

@weiz18 thank you very much for responding! That is interesting, I think we may have something slightly different going on as one of our users who has reported it is using an older phone (iPhone 6s Plus) and using quite downscaled photos (using the target height/width) and it has only started happening in the last couple of versions. Thank you very much for responding, it is great to get some more information πŸ˜„

We are experiencing this same issue. Did you find a solution? Thanks.

gustavoalmuna commented 5 years ago

I have an app with ultimate plugin and crash the same way, so i hope someone post a solution for this. Thansk for the help.

breautek commented 5 years ago

On modern devices, this can be a problem when using the DATA_URL destination. This is because it needs to encode an already large image binary into a base64 encoded string, which expands the data by about 40%. This can be a problem for devices that have low memory limits.

This is noted in the documentation:

NOTE: Photo resolution on newer devices is quite good. Photos selected from the device's gallery are not downscaled to a lower quality, even if a quality parameter is specified. To avoid common memory problems, set Camera.destinationType to FILE_URI rather than DATA_URL.

Using a FILE_URI will give you a url that can be read into a blob, which is far more efficient for representing binary data. You can also use blobs to create an object url to use in html tags like <img> tags, or send to a remote server using XMLHttpRequest.

I am facing same issue. I am using FILE_URI as destinationType. My phone contains lot of free memory, still app crashes when i try to take pictures.

Many phones imposes a memory quota, so having lots of free money doesn't mean all that memory is available for any individual app. You could also be experiencing another android quirk, also documented below:

Android uses intents to launch the camera activity on the device to capture images, and on phones with low memory, the Cordova activity may be killed. In this scenario, the result from the plugin call will be delivered via the resume event. See the Android Lifecycle guide for more information. The pendingResult.result value will contain the value that would be passed to the callbacks (either the URI/URL or an error message). Check the pendingResult.pluginStatus to determine whether or not the call was successful.

mirko77 commented 5 years ago

We have this issue happening only on a single test device, MI 9se with MIUI 10 (Android 9). It is really random, maybe 1 picture out of 10 restarts the app. No problems on any other android device/versions

satkkd commented 5 years ago

@hamzatrq i am having exactly the same issue in android 9 samsung device. did you manage to resolve this issue?

satkkd commented 5 years ago

We have this issue happening only on a single test device, MI 9se with MIUI 10 (Android 9). It is really random, maybe 1 picture out of 10 restarts the app. No problems on any other android device/versions

it happens only while taking picture from front camera? also when we take a picture and click on retake and then submit the second image the app does not crashes but if I submit the first image it crashes.

is it same for you?

mirko77 commented 5 years ago

We have this issue happening only on a single test device, MI 9se with MIUI 10 (Android 9). It is really random, maybe 1 picture out of 10 restarts the app. No problems on any other android device/versions

it happens only while taking picture from front camera? also when we take a picture and click on retake and then submit the second image the app does not crashes but if I submit the first image it crashes.

is it same for you?

No, it is completely random. It tends to crash when I take the first photo after a new build, that it is stable for a while (10/15 photos) then it crashes again.

mirko77 commented 5 years ago

On modern devices, this can be a problem when using the DATA_URL destination. This is because it needs to encode an already large image binary into a base64 encoded string, which expands the data by about 40%. This can be a problem for devices that have low memory limits.

This is noted in the documentation:

NOTE: Photo resolution on newer devices is quite good. Photos selected from the device's gallery are not downscaled to a lower quality, even if a quality parameter is specified. To avoid common memory problems, set Camera.destinationType to FILE_URI rather than DATA_URL.

Using a FILE_URI will give you a url that can be read into a blob, which is far more efficient for representing binary data. You can also use blobs to create an object url to use in html tags like <img> tags, or send to a remote server using XMLHttpRequest.

I am facing same issue. I am using FILE_URI as destinationType. My phone contains lot of free memory, still app crashes when i try to take pictures.

Many phones imposes a memory quota, so having lots of free money doesn't mean all that memory is available for any individual app. You could also be experiencing another android quirk, also documented below:

Android uses intents to launch the camera activity on the device to capture images, and on phones with low memory, the Cordova activity may be killed. In this scenario, the result from the plugin call will be delivered via the resume event. See the Android Lifecycle guide for more information. The pendingResult.result value will contain the value that would be passed to the callbacks (either the URI/URL or an error message). Check the pendingResult.pluginStatus to determine whether or not the call was successful.

We find weird it crashes on a phone with 6GB of ram (MI 9 SE) while we have no issues on old devices like Nexus 4 or Samsung Galaxy 5.

mirko77 commented 5 years ago

Update Camera Plugin and Cordova-android version it will fix this issue

Nope, the same issue with

cordova 9.0.0 cordova-android 8.0.1 cordova-plugin-camera 4.1.0

1 photo out of 10/15 will restart the app

thesheikhwasim commented 5 years ago

This issue is still in this plugin for some of the devices. It has unusual behaviour of restarting. The only way to avoid this is open image with cropper tool. I fixed my camera to 500x500 size image and resized it which stopped this plugin's extra behaviour (restarting) to take place

breautek commented 5 years ago

We find weird it crashes on a phone with 6GB of ram (MI 9 SE)

The total amount of RAM generally doesn't really matter as most vendors only allow a certain quota to that RAM. In otherwords an app may run out of RAM, even though there is plenty of free RAM available overall. This however varies by device, OS version and manufacturer.

Additionally, the JS engines can only efficiently handle so much data under one string variable before it starts bogging down, regardless of free RAM the app has available.

we have no issues on old devices like Nexus 4 or Samsung Galaxy 5.

Older devices generally capture a much smaller resolution, resulting in a much smaller data url string to work with.

mirko77 commented 5 years ago

@breautek are you saying that going forward this plugin will cause more and more issues since device cameras are getting better?

It does not sound promising :(

breautek commented 5 years ago

It's only an issue if using DATA_URL destination. DATA_URL is useful for representing small binary data, it's not reasonable to use it to represent large binary. And that will only get worse as phones support larger resolutions which will only make the data larger. I can also make an educated guess to say that's why videos never supported DATA_URL destination at all.

Using the FILE_URI destination type will save/stream the data to a temporary location, where you can read a file into a blob, which is the proper way of handling binary data in javascript. Using blobs will also keep the binary data allocated outside of the JS virtual machine (similar to how Buffers work in NodeJS), which helps JS performance by not requiring frequent garbage collections.

satkkd commented 5 years ago

I am using FILE_URI destination type still facing the issue with front camera and when I click on retake and then submit the second image the app does not crash

breautek commented 5 years ago

I am using FILE_URI destination type still facing the issue with front camera and when I click on retake and then submit the second image the app does not crash

If someone can provide a sample reproduction app that produces this issue, it will help move this ticket along.

https://github.com/apache/cordova-contribute/blob/master/create-reproduction.md

mirko77 commented 5 years ago

Using cordova-plugin-background-mode. Enable before camera and then disable after camera is back. It fixed the problem.

Lots of issues on Android 9 with that plugin

mirko77 commented 5 years ago

I am using FILE_URI destination type still facing the issue with front camera and when I click on retake and then submit the second image the app does not crash

If someone can provide a sample reproduction app that produces this issue, it will help move this ticket along.

https://github.com/apache/cordova-contribute/blob/master/create-reproduction.md

That is difficult. We are experiencing the issue only on Xiaomi devices with MIUI on Android 9, which we assume is due to the battery management implementation of those roms. It does not always happen, maybe 1 out of 10 photos

satkkd commented 5 years ago

HI,

My issue resolved after updating Cordova-android version, and creating the new project from the scratch.

now it works with android 9.0 without any issues.

mirko77 commented 4 years ago

HI,

My issue resolved after updating Cordova-android version, and creating the new project from the scratch.

now it works with android 9.0 without any issues.

What Cordova version are you using? We still have the issue on android 7.1.4

williamkoch-ngs commented 4 years ago

I'm curious if anyone else has experimented with artificially throttling the rate at which the app allows the user to capture photos, and seen any positive impact. To prove this idea out, we added a 5 second delay between allowed photo captures, and saw a definite reduction in crashes/UI refreshes. Are we chasing ghosts?