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

App crashes randomly after taking a picture with the camera #665

Closed
3 tasks done
keo9ren opened this issue Sep 25, 2020 · 44 comments · Fixed by #700
Closed
3 tasks done

App crashes randomly after taking a picture with the camera #665

keo9ren opened this issue Sep 25, 2020 · 44 comments · Fixed by #700

Comments

@keo9ren
Copy link

keo9ren commented Sep 25, 2020

Bug Report

Problem

After taking a picture, pushing the OK Button (marked below) of camera-plugin crashes the app randomly.
image

What is expected to happen?

The picture should be available in the app for further action.

What does actually happen?

The app crashes.

Information

2020-09-25 16:42:08.277 19807-19807/com.domain.app D/AndroidRuntime: Shutting down VM
2020-09-25 16:42:08.281 19807-19807/com.domain.app E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.domain.app, PID: 19807
    java.lang.RuntimeException: Unable to resume activity {com.domain.app/com.domain.app.MainActivity}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=34, result=-1, data=null} to activity {com.domain.app/com.domain.app.MainActivity}: java.lang.NullPointerException: filename cannot be null
        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4626)
        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4659)
        at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52)
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2261)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:237)
        at android.app.ActivityThread.main(ActivityThread.java:8107)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
     Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=34, result=-1, data=null} to activity {com.domain.app/com.domain.app.MainActivity}: java.lang.NullPointerException: filename cannot be null
        at android.app.ActivityThread.deliverResults(ActivityThread.java:5324)
        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4613)
        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4659) 
        at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52) 
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2261) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        at android.os.Looper.loop(Looper.java:237) 
        at android.app.ActivityThread.main(ActivityThread.java:8107) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100) 
     Caused by: java.lang.NullPointerException: filename cannot be null
        at android.media.ExifInterface.<init>(ExifInterface.java:1390)
        at org.apache.cordova.camera.ExifHelper.createInFile(ExifHelper.java:56)
        at org.apache.cordova.camera.CameraLauncher.processResultFromCamera(CameraLauncher.java:481)
        at org.apache.cordova.camera.CameraLauncher.onActivityResult(CameraLauncher.java:808)
        at org.apache.cordova.CordovaInterfaceImpl.onActivityResult(CordovaInterfaceImpl.java:159)
        at org.apache.cordova.CordovaActivity.onActivityResult(CordovaActivity.java:361)
        at android.app.Activity.dispatchActivityResult(Activity.java:8294)
        at android.app.ActivityThread.deliverResults(ActivityThread.java:5317)
        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4613) 
        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4659) 
        at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52) 
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2261) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        at android.os.Looper.loop(Looper.java:237) 
        at android.app.ActivityThread.main(ActivityThread.java:8107) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(Runti

Command or Code

Environment, Platform, Device

Chrashes have first appeared on Samsung Galaxy Tab A (SM-T515) after Android 10 update.
Same device running android 9 seams to work fine.

Version information

Cordova Packages:

cli: 10.0.0
    common: 4.0.2
    create: 3.0.0
    lib: 10.0.0
        common: 4.0.2
        fetch: 3.0.0
        serve: 4.0.0

Project Installed Platforms:

android: 9.0.0

Project Installed Plugins:

com-darryncampbell-cordova-plugin-intent: 1.3.0
com.mirasense.scanditsdk.plugin: 5.14.4
cordova-plugin-app-version: 0.1.9
cordova-plugin-camera: 5.0.0 (bug appears on older versions too)
cordova-plugin-device: 2.0.3
cordova-plugin-file: 6.0.2
cordova-plugin-network-information: 2.0.2
cordova-plugin-whitelist: 1.3.4
cordova-plugin-x-toast: 2.7.2
phonegap-plugin-barcodescanner: 8.1.0

Environment:

OS: Microsoft Windows 10 Pro 10.0.18362 (18362) (win32 10.0.18362) x64
Node: v13.12.0
npm: 6.14.4

Checklist

  • I searched for existing GitHub issues
  • I updated all Cordova tooling to most recent version
  • I included all the necessary information above
@PieterVanPoyer
Copy link
Contributor

PieterVanPoyer commented Sep 27, 2020

Hey

What are the camerasettings/options in your code?

Kind regards
Pieter

@keo9ren
Copy link
Author

keo9ren commented Sep 28, 2020

Hi Pieter,
camera settings are as follows:

quality: 100,
destinationType: navigator.camera.DestinationType.FILE_URI,
sourceType: navigator.camera.PictureSourceType.CAMERA,
targetWidth: 1024,
targetHeight: 768,
correctOrientation: true

Kind regards

Oliver

@ochakov
Copy link
Contributor

ochakov commented Nov 26, 2020

Happens to me as well, Pixel 4 Android 11
Temp fix by settings allowEdit: true

@ochakov
Copy link
Contributor

ochakov commented Nov 29, 2020

Updated Android SDK and build tools and the problem has gone.

@keo9ren
Copy link
Author

keo9ren commented Nov 30, 2020

Doesn't help much in our Case. Sometimes we are able to record really long series of pictures (50 - 70) before the app breaks.

@ita33
Copy link

ita33 commented Nov 30, 2020

Same here. This did not help with our issue. This might be related to issue #678 for iOS 14... We crash after 150 - 195 photos on Android 11.0. Have not had a chance to test Android 10.0. If helpful, please see attached for the devices and versions tested. 4th column is how many photos it takes to crash. Our users take about 1,500 photos per day. We used to get well over 1,000 photos on Android 9.0 and older. Environments tested here:

Camera plugin 4.1.0 and 5.0.1
Cordova iOS 5.1.1 and 6.1.1

Android and iOS Photo Crash Tests

@ryandsjoquist
Copy link

ryandsjoquist commented Dec 2, 2020

So far from what I can dig up, Is that it might be related to an older bug with Capacitor regarding removing event listeners while events are still being triggered. ionic-team/capacitor#1943
Still digging into stack traces on this, but that's seeming to be in the general direction I'm headed due to the exact same error.

*** Collection <__NSArrayM: 0x283ccadf0> was mutated while being enumerated.
(
0 CoreFoundation 0x00000001966b088c AF3F8E01-C130-3464-AD40-C5532D273483 + 1202316
1 libobjc.A.dylib 0x00000001aac06c50 objc_exception_throw + 60
2 CoreFoundation 0x00000001966b017c AF3F8E01-C130-3464-AD40-C5532D273483 + 1200508
3 CameraUI 0x00000001bfe0c764 33C8166A-6796-36EE-B25A-0A82725559D6 + 976740
4 CameraUI 0x00000001bfe0caa8 33C8166A-6796-36EE-B25A-0A82725559D6 + 977576
5 CameraUI 0x00000001bfdce6f0 33C8166A-6796-36EE-B25A-0A82725559D6 + 722672
6 CameraUI 0x00000001bff1b6e4 33C8166A-6796-36EE-B25A-0A82725559D6 + 2086628
7 libobjc.A.dylib 0x00000001aac05b10 282FD01C-1437-349B-AE1A-2EFF32859670 + 23312
8 libobjc.A.dylib 0x00000001aac1c840 objc_destructInstance + 80
9 libobjc.A.dylib 0x00000001aac2380c _objc_rootDealloc + 80
10 UIKitCore 0x0000000199094928 05147936-B875-3EF3-94DB-9C8869BB0E34 + 12572968
11 UIKitCore 0x0000000198936894 05147936-B875-3EF3-94DB-9C8869BB0E34 + 4847764
12 CameraUI 0x00000001bff128d0 33C8166A-6796-36EE-B25A-0A82725559D6 + 2050256
13 UIKitCore 0x00000001988596d0 05147936-B875-3EF3-94DB-9C8869BB0E34 + 3942096
14 UIKitCore 0x000000019893fb28 05147936-B875-3EF3-94DB-9C8869BB0E34 + 4885288
15 UIKitCore 0x0000000198940918 05147936-B875-3EF3-94DB-9C8869BB0E34 + 4888856
16 UIKitCore 0x0000000198940a30 05147936-B875-3EF3-94DB-9C8869BB0E34 + 4889136
17 UIKitCore 0x000000019881becc 05147936-B875-3EF3-94DB-9C8869BB0E34 + 3690188
18 UIKitCore 0x000000019881bc0c 05147936-B875-3EF3-94DB-9C8869BB0E34 + 3689484
19 UIKitCore 0x00000001988263e4 05147936-B875-3EF3-94DB-9C8869BB0E34 + 3732452
20 UIKitCore 0x0000000198820410 05147936-B875-3EF3-94DB-9C8869BB0E34 + 3707920
21 UIKitCore 0x00000001989649cc 05147936-B875-3EF3-94DB-9C8869BB0E34 + 5036492
22 UIKitCore 0x0000000199567c3c 05147936-B875-3EF3-94DB-9C8869BB0E34 + 17632316
23 UIKitCore 0x00000001995678e8 05147936-B875-3EF3-94DB-9C8869BB0E34 + 17631464
24 UIKitCore 0x000000019959f7b8 05147936-B875-3EF3-94DB-9C8869BB0E34 + 17860536
25 UIKitCore 0x0000000199571b1c 05147936-B875-3EF3-94DB-9C8869BB0E34 + 17672988
26 UIKitCore 0x0000000199572084 05147936-B875-3EF3-94DB-9C8869BB0E34 + 17674372
27 UIKitCore 0x00000001995721e8 05147936-B875-3EF3-94DB-9C8869BB0E34 + 17674728
28 QuartzCore 0x0000000199ad7160 DC2644E7-E5E4-3D83-9110-A5AE7E2C8B1F + 1524064
29 libdispatch.dylib 0x0000000105aa56c0 _dispatch_client_callout + 20
30 libdispatch.dylib 0x0000000105ab4f34 _dispatch_main_queue_callback_4CF + 1000
31 CoreFoundation 0x000000019662c11c AF3F8E01-C130-3464-AD40-C5532D273483 + 659740
32 CoreFoundation 0x0000000196626120 AF3F8E01-C130-3464-AD40-C5532D273483 + 635168
33 CoreFoundation 0x000000019662521c CFRunLoopRunSpecific + 600
34 GraphicsServices 0x00000001ad6a4784 GSEventRunModal + 164
35 UIKitCore 0x000000019905e200 05147936-B875-3EF3-94DB-9C8869BB0E34 + 12349952
36 UIKitCore 0x0000000199063a74 UIApplicationMain + 168
37 AppName 0x0000000104f7a194 main + 64
38 libdyld.dylib 0x00000001962e56c0 BA60CB9E-95C5-3646-BEED-D313E15586CF + 5824
)

(Copied from other bug issue)

@pszmagaj
Copy link

@keo9ren Hi. Have you found a workaround? We are experiencing the same problem and I wondered if you found something that might help to fix it.

@keo9ren
Copy link
Author

keo9ren commented Dec 17, 2020

The only workaround so far is that the tablets won't be upgraded.

@dimitriscsd
Copy link

Hello. I have seen this issue in our app as well. Could you guys try without

destinationType: navigator.camera.DestinationType.FILE_URI

Removing this option has improved the situation a lot. However I have a feeling that some devices behave better with this and some without it.

@tenglandct
Copy link

We pushed an update to the Play Store having upgraded to Cordova Android 9 and 5.0.1 of the camera plugin and immediately started running into this issue with Android 10 devices.

@PieterVanPoyer
Copy link
Contributor

Maybe we should just focus on Android on this issue.
I think the issue is related to the activity being destroyed when the camera opens. (So it is probably also related to #696 ).

My first guess is:
In the onSaveInstanceState the imageFilePath is saved to the Bundle (with the IMAGE_URI key).
But in the onRestoreStateForActivityResult the IMAGE_URI value is set on imageUri. (So there is a switch).
When the activity has been destroyed the imageFilePath is normally set to null.

onSaveInstanceState 

if (this.imageUri != null) {
    state.putString(IMAGE_URI_KEY, this.imageFilePath);
}

and

onRestoreStateForActivityResult 

if (state.containsKey(IMAGE_URI_KEY)) {
    //I have no idea what type of URI is being passed in
    this.imageUri = Uri.parse(state.getString(IMAGE_URI_KEY));
}

When processing the result, the plugin uses the null imageFilePath.

image

So maybe just storing and restoring imageUri and imageFilePath seperatly in the onSaveInstance and onRestore methods is enough.

This is the stacktrace from my testing app https://github.com/PieterVanPoyer/cordova-camera-plugin-testing-app when the activity in the emulator is configured to be always destroyed when the camera opens.

2020-12-30 22:42:41.774 11147-11147/com.pvpoyer.cameraplugintesting E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.pvpoyer.cameraplugintesting, PID: 11147
    java.lang.RuntimeException: Unable to resume activity {com.pvpoyer.cameraplugintesting/com.pvpoyer.cameraplugintesting.MainActivity}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=34, result=-1, data=Intent {  }} to activity {com.pvpoyer.cameraplugintesting/com.pvpoyer.cameraplugintesting.MainActivity}: java.lang.NullPointerException: filename cannot be null
        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4444)
        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4476)
        at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52)
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
     Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=34, result=-1, data=Intent {  }} to activity {com.pvpoyer.cameraplugintesting/com.pvpoyer.cameraplugintesting.MainActivity}: java.lang.NullPointerException: filename cannot be null
        at android.app.ActivityThread.deliverResults(ActivityThread.java:5015)
        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4431)
        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4476) 
        at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52) 
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:223) 
        at android.app.ActivityThread.main(ActivityThread.java:7656) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 
     Caused by: java.lang.NullPointerException: filename cannot be null
        at android.media.ExifInterface.<init>(ExifInterface.java:1498)
        at org.apache.cordova.camera.ExifHelper.createInFile(ExifHelper.java:56)
        at org.apache.cordova.camera.CameraLauncher.processResultFromCamera(CameraLauncher.java:481)
        at org.apache.cordova.camera.CameraLauncher.onActivityResult(CameraLauncher.java:828)
        at org.apache.cordova.CordovaInterfaceImpl.onActivityResult(CordovaInterfaceImpl.java:159)
        at org.apache.cordova.CordovaActivity.onActivityResult(CordovaActivity.java:361)
        at android.app.Activity.dispatchActivityResult(Activity.java:8310)
        at android.app.ActivityThread.deliverResults(ActivityThread.java:5008)
        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4431) 
        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4476) 
        at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52) 
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:223) 
        at android.app.ActivityThread.main(ActivityThread.java:7656) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 

PieterVanPoyer added a commit to PieterVanPoyer/cordova-plugin-camera that referenced this issue Dec 31, 2020
@PieterVanPoyer PieterVanPoyer mentioned this issue Dec 31, 2020
5 tasks
@PieterVanPoyer
Copy link
Contributor

PieterVanPoyer commented Jan 2, 2021

Hi @keo9ren @tenglandct

There is indeed a scenario that results in a NullPointerException and crashes the Android plugin.
I did make a change to plugin code, you can test it with next commands.
I did only corrected the Android failure.

You can install and test the plugin (on Android) with next command.

npx cordova plugin remove cordova-plugin-camera
npx cordova plugin add https://github.com/PieterVanPoyer/cordova-plugin-camera/#bugfix/issue-665-save-instance-restore-bug

You could test it with next reproduction repo:
https://github.com/PieterVanPoyer/cordova-camera-plugin-testing-app

Kind regards Pieter

@maochong513
Copy link

Hi @keo9ren @tenglandct

There is indeed a scenario that results in a NullPointerException and crashes the Android plugin.
I did make a change to plugin code, you can test it with next commands.
I did only corrected the Android failure.

You can install and test the plugin (on Android) with next command.

npx cordova plugin remove cordova-plugin-camera
npx cordova plugin add https://github.com/PieterVanPoyer/cordova-plugin-camera/#bugfix/issue-665-save-instance-restore-bug

You could test it with next reproduction repo:
https://github.com/PieterVanPoyer/cordova-camera-plugin-testing-app

Kind regards Pieter

Test the https://github.com/PieterVanPoyer/cordova-camera-plugin-testing-app
It's still gonna crash
Equipment information
Galaxy Tab A(SM-T515)
One UI 2.1
Android 10

@PieterVanPoyer
Copy link
Contributor

@maochong513

  • can you add a stacktrace of the crash?
  • Did you make the activity destroy when paused in your development settings?

@PieterVanPoyer
Copy link
Contributor

Hi @keo9ren @tenglandct
Is anyone able to test.

@tenglandct
Copy link

Hi @keo9ren @tenglandct
Is anyone able to test.

I'm on leave this week but planning to test next week when I'm back working

@maochong513
Copy link

@PieterVanPoyer
No error message was caught in Android Studio Locat;
However, the Event. PendingResult in the onResume function is not empty
crash-

The Event.PendingResult is not empty only when the app is reloaded

@PieterVanPoyer
Copy link
Contributor

@maochong513 it seems like the desired behaviour. Before my fix the plugin crashes before sending the PendingResult event. I really do not understand your original comment about a crash.

PieterVanPoyer added a commit to PieterVanPoyer/cordova-plugin-camera that referenced this issue Jan 8, 2021
@PieterVanPoyer
Copy link
Contributor

@maochong513 some commits from master were not yet on may branche. So it could lead to crashes. Now it is fixed. The branches are even. My MR is 2 commits ahead of master.

@maochong513
Copy link

Hi @PieterVanPoyer

test step:
1

cordova plugin remove cordova-plugin-camera
cordova plugin add https://github.com/apache/cordova-plugin-camera.git
cordova plugin ls

2

cordova-plugin-camera 5.0.2-dev "Camera"
cordova-plugin-whitelist 1.3.4 "Whitelist"

### The problem appeared after four or five pictures had been taken

Information

2021-01-11 14:33:52.224 12169-12169/com.pvpoyer.cameraplugintesting E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.pvpoyer.cameraplugintesting, PID: 12169
    java.lang.RuntimeException: Unable to resume activity {com.pvpoyer.cameraplugintesting/com.pvpoyer.cameraplugintesting.MainActivity}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=34, result=-1, data=null} to activity {com.pvpoyer.cameraplugintesting/com.pvpoyer.cameraplugintesting.MainActivity}: java.lang.NullPointerException: filename cannot be null
        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4626)
        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4659)
        at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52)
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2261)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:237)
        at android.app.ActivityThread.main(ActivityThread.java:8107)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
     Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=34, result=-1, data=null} to activity {com.pvpoyer.cameraplugintesting/com.pvpoyer.cameraplugintesting.MainActivity}: java.lang.NullPointerException: filename cannot be null
        at android.app.ActivityThread.deliverResults(ActivityThread.java:5324)
        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4613)
        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4659) 
        at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52) 
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2261) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        at android.os.Looper.loop(Looper.java:237) 
        at android.app.ActivityThread.main(ActivityThread.java:8107) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100) 
     Caused by: java.lang.NullPointerException: filename cannot be null
        at android.media.ExifInterface.<init>(ExifInterface.java:1390)
        at org.apache.cordova.camera.ExifHelper.createInFile(ExifHelper.java:56)
        at org.apache.cordova.camera.CameraLauncher.processResultFromCamera(CameraLauncher.java:481)
        at org.apache.cordova.camera.CameraLauncher.onActivityResult(CameraLauncher.java:828)
        at org.apache.cordova.CordovaInterfaceImpl.onActivityResult(CordovaInterfaceImpl.java:159)
        at org.apache.cordova.CordovaActivity.onActivityResult(CordovaActivity.java:361)
        at android.app.Activity.dispatchActivityResult(Activity.java:8294)
        at android.app.ActivityThread.deliverResults(ActivityThread.java:5317)
        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4613) 
        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4659) 
        at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52) 
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2261) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        at android.os.Looper.loop(Looper.java:237) 
        at android.app.ActivityThread.main(ActivityThread.java:8107) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)

@PieterVanPoyer
Copy link
Contributor

PieterVanPoyer commented Jan 11, 2021

@maochong513 thanks for your testing, but your installation test steps are wrong.
My fix is not yet on the master of this repo.
You must install the fork, not the dev branche.

npx cordova plugin remove cordova-plugin-camera
npx cordova plugin add https://github.com/PieterVanPoyer/cordova-plugin-camera/#bugfix/issue-665-save-instance-restore-bug

Kind regards
Pieter

@maochong513
Copy link

@maochong513 thanks for your testing, but your installation test steps are wrong.
My fix is not yet on the master of this repo.
You must install the fork, not the dev branche.

npx cordova plugin remove cordova-plugin-camera
npx cordova plugin add https://github.com/PieterVanPoyer/cordova-plugin-camera/#bugfix/issue-665-save-instance-restore-bug

Kind regards
Pieter

Hi Pieter @PieterVanPoyer
I retested the procedure and still had problems taking photos. After taking another 4 or 5 photos, the app was restarted

@PieterVanPoyer
Copy link
Contributor

PieterVanPoyer commented Jan 11, 2021

@maochong513 restarting of the app is normal. That is Android Lifecycle related stuff. Your app must be able to handle restarting the apps when camera is opened without data loss. see: https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-camera/#android-quirks en https://cordova.apache.org/docs/en/dev/guide/platforms/android/index.html#lifecycle-guide
When the app is restarted, the result must be in the pendingResult.

Before my fix, the app crashed when being restarted when the camera was being processed.

@keo9ren
Copy link
Author

keo9ren commented Jan 11, 2021

@PieterVanPoyer will try to test early this week. Have been on Christmas Holidays till today. Appreciate your effort!

@ypriyasd
Copy link

hi guys, am facing the same problem. if you guys have fixed, kindly share the dets. thanks in advance

@keo9ren
Copy link
Author

keo9ren commented Jan 25, 2021

Hi, I also did not know that the restart of the app is basically by design. Maybe it's caused by low memory, we have only 400 MB available if our app is running, of the specific device. Our App can't handle restarts and we are in the lucky situation that we're able to switch to other devices.

breautek pushed a commit that referenced this issue Feb 2, 2021
* GH-665 - store the imageFilePath when the app is paused (onSaveInstance) and restore it back.

* Update src/android/CameraLauncher.java whitespace layout

Co-authored-by: Tim Brust <github@timbrust.de>

Co-authored-by: Tim Brust <github@timbrust.de>
@guillermohaad
Copy link

hi @keo9ren Can you share the solution to your problem, I have not been able to solve it
thank

@keo9ren
Copy link
Author

keo9ren commented May 3, 2021

As mentioned here we have no real solution either. The restarts are by design on android (links and explanation are in the discussion above ). We just switched to devices with more RAM, that fixed it for us.

@chayed
Copy link

chayed commented May 4, 2021

i have the same issue.app crashes soon after image was captured.

cordova cli
10.0.0
android
9.1.0
camera plugin
5.0.1

Testing on Nokia 7.2 with Android 10 Mobile device

@guillermohaad
Copy link

am working on Cordova 9 platform . and use cordova -plugin-camera@5.0.0
Everything work fine , But the problem occur when am enable the saveToPhotoAlbum option , On Android 10 its not work , throw Camera error . & also some cellphone after capture photo the app automatically shutdown

Thank you

@PieterVanPoyer
Copy link
Contributor

@guillermohaad can you update the plugin-camera to v5.0.1? Then the saveToPhotoAlbum option can be enabled.
There is indeed a bug in the saveToPhotoAlbum flow in v5.0.0.

@guillermohaad
Copy link

guillermohaad commented May 5, 2021

hi @PieterVanPoyer
Am alos use tha latest plugin 5.0.1 also .but the same problems occur on Android 10 .The plugin 5.0.1 . Forcefully close the application once we capture photo . This happen on some specific devices .

thank you

@satheeshkumartitan
Copy link

satheeshkumartitan commented May 27, 2021

I've also updated the latest plugin 5.0.2, but the same problems occur on Android 10 (device - redmi note 7pro). The plugin 5.0.2. Forcefully close the application once we capture a photo. This happens on some specific devices. Please update the new version I'm waiting for the new version
Node -v ----14.16.0
ionic -v ---- 6.13.1
cordova -v----10.0.0
ionic cordova platform add android@9.1.0
npm i @ionic-native/camera@5.33.0
tested and both same crash.

I'm waiting for your response, thanks

@Pedrohf360
Copy link

Same here! The problem is ocurring only in Android 10 devices. When the photo is taken, the window of confirmation appears and I click in "Ok" option, app crash and restart :(

I'm using:
"cordova-plugin-camera": "^5.0.1"
"@ionic-native/camera": "^5.24.0"

@jay34fr
Copy link

jay34fr commented Jun 9, 2021

Hi all,
Same issue here.
I updated to 5.0.2 but the app is still restarting after taking and validating a photo.

Cordova 9.0.0
Cordova Android 9.0.0

@tronious
Copy link

tronious commented Jul 9, 2021

For ME there is a bug in the camera plugin. I fixed it for MY situation. This may or may not apply to yours.

Scenario:

  1. Using a tablet where the NATIVE CAMERA APP rotates to Landscape when it launches.
  2. My app is running in portrait. Because of this it needs to saveInstance var's and reload them.

What I found and what I fixed:

First look at ProcessResultFromCamera function -> these lines:

        String sourcePath = (this.allowEdit && this.croppedUri != null) ?
                this.croppedFilePath :
                this.imageFilePath;

It's using imageUri but saving imageFilePath? Maybe this is intended maybe not.

I added a quick debug helper class to push out Toasts. I added Toasts all throughout CameraLauncher.java.

I looked at onSaveInstanceState and noticed a couple things:

  1. imageFilePath is not being stored anywhere in onSaveInstanceState so when the Activity recreates itself...the imageFilePath that was initially created is now null. This imageFilePath is what's passed into ExifInterface. If you note ABOVE...sourcePath is assigned to imageFilePath.

This would explain why we get the "filename cannot be null" as that specific exception is thrown in ExifInterface.java I believe.

                **_exif.createInFile(sourcePath);_**  <<---- sourcePath is null
                exif.readExifData();
                rotate = exif.getOrientation();

        if (this.**imageUri** != null) {
            state.putString(IMAGE_URI_KEY, this.**imageFilePath**);
        }

The Fix??

Update imageUri in onSaveInstanceState. Add imageFileName to onSaveInstanceState.

Add imageFileName to onRestore

here's the actual code to update/add in onSaveInstanceState:

        if (this.imageUri != null) {
            state.putString(IMAGE_URI_KEY, String.valueOf(this.imageUri));
        }

        if (this.imageFilePath != null) {
            state.putString(IMAGE_FILE_PATH_KEY, this.imageFilePath);
        }

here's the code to ADD in onRestoreStateForActivityResult:

        if (state.containsKey(IMAGE_FILE_PATH_KEY)) {
            this.imageFilePath = state.getString(IMAGE_FILE_PATH_KEY);
        }

@Aarbel
Copy link

Aarbel commented Jul 28, 2021

@breautek still have the problem, can you re-open this issue ?

@Aarbel
Copy link

Aarbel commented Jul 28, 2021

That's not normal that the app crashes with this plugin, even if you manage all the details when the app reboots

@breautek
Copy link
Contributor

That's not normal that the app crashes with this plugin, even if you manage all the details when the app reboots

If the app is "rebooting", then you're not experiencing a crash. A native crash will generally cause the app to completely close and a dialog will appear with a message <App name> has stopped working. What this sounds like to me is that you're experiencing android OS killing the app activity (e.g. the UI process) to save on limited resources. While annoying, this is a completely normal lifecycle flow on android apps and it usually occurs on budget phones with limited RAM. It could also happen on higher end devices if the user have chosen an ultra high resolution images.

If this is what you're experiencing, there isn't anything Cordova can do. That is how Android works and this is something that all android developers needs to keep in mind, including native developers. Particularly when working with android intents that consumes a lot of resources. Cordova does expose a way to handle this situation, which sounds like you're already aware of.

@breautek still have the problem, can you re-open this issue ?

If I misinterpreted and you actually do have a crash, I'd suggest opening a new issue with the issue form filled out. Do not simply create a ticket that references this ticket, that's pointless and doesn't actually tell us anything new. Linking to this ticket for context is helpful. Best to run the app using android studio so that we can have access to the native logs and capture the stack traces. We need to be able to confirm if the issue you're experiencing is in fact the same issue described in this ticket, and only then proceed further to figure out the "why". If you're unsure how to use android studio to capture stack traces, I'd suggest asking our Slack community for assistance.

@tronious
Copy link

tronious commented Jul 29, 2021

If you look at my post two or three up it details exactly what the problem is. It's a crash in the plugin. The app doesn't crash...but it never received the success or error callback so it just lingers.

It is an activity life cycle event in the plugin. onSaveInstanceState isn't saving imageFileName properly and it never reloads it.

And yes the Android OS is killing the app. That's causing imageFileName to be billed out because it's not being save properly and reloaded.

Because of this ExifHelper.js throws an exception

Look at my post a few up.

@Aarbel
Copy link

Aarbel commented Jul 29, 2021

@breautek thanks a lot for this synthesis.

If the app is "rebooting", then you're not experiencing a crash

The problem with rebooting is that it's really close to a crash, we loose the route and all the data filled by the user, so quite hard to provide a compelling user experience.

While annoying, this is a completely normal lifecycle flow on android apps and it usually occurs on budget phones with limited RAM. It could also happen on higher end devices if the user have chosen an ultra high resolution images.

I can confirm that, it crashes on Samsung Tab1 (old tablets) and Lenovo TAB P11 Pro (really recent, 6G RAM, pictures of 40Mo).
For our customers care, Is there any way / setting on an Android device to reduce camera images resolutions ?

Best to run the app using android studio so that we can have access to the native logs and capture the stack traces

Mains challenge is that it's hard to reproduce, because hardware Camera api can't be tested in simulator at the moment. Do you know a way ? Is there also a way to force images resolution in the simulator for Camera capture ?
Found this but maybe more solutions: https://thedroidguy.com/s10-camera-problems-after-android-10-update-1116110, https://www.dummies.com/consumer-electronics/tablets/android-tablets/how-to-change-the-resolution-on-your-android-tablets-camera/

If this is what you're experiencing, there isn't anything Cordova can do

=> There's really absolutely no way to prevent the reboot with Java native Android API or Java Android plugins ? Like maybe storing image in the hard memory and not using RAM, trying to prepare the device RAM for taking a picture, allow more RAM space for pictures capture, killing camera process before camera capture, etc... ?

Because if it's really the case, that should really be a major Android issue for all their developers / users. I mean, when you have 6G RAM, and you can't take a picture of 40Mo without an app reboot, that's really surprising.

=> There's no issue about it in the Android community ?

=> How do the native Java Camera Api works ? Looks like only hybrids apps with this plugin face the problem, otherwise any app in the world should often see their apps reboot since Android 10 on many devices, which would be a major problem for Android users.

Thanks a lot for your explanations ;)

Other usefull links

https://developer.android.com/guide/topics/media/camera

@Aarbel
Copy link

Aarbel commented Jul 29, 2021

If you look at my post two or three up it details exactly what the problem is. It's a crash in the plugin. The app doesn't crash...but it never received the success or error callback so it just lingers.

@tronious a fix has been merged for that full crash problem in the 5.0.2 version, see mobiliarmad#2, but it doesn't solve the reboot bug

@breautek
Copy link
Contributor

This is getting off-topic and not really the place to discuss this, so I'll make some final points and then I'll be locking this thread.

The problem with rebooting is that it's really close to a crash, we loose the route and all the data filled by the user, so quite hard to provide a compelling user experience.

Again, that is the android lifecycle. It is easier to manage working completely in native, it is much harder to "restore" the webview state, but it is up to the android developer to handle serialize their state and reconstruct it later in the case that the OS decides it needs to kill the app activity. This is an app developer problem because this is simply something that cannot be solved generically.

I can confirm that, it crashes on Samsung Tab1 (old tablets) and Lenovo TAB P11 Pro (really recent, 6G RAM, pictures of 40Mo).
For our customers care, Is there any way / setting on an Android device to reduce camera images resolutions ?

No, this plugin relies on intents (that is, to delegate camera responsibility to an existing camera app that has camera permissions). This means it uses whatever settings the user has set in their chosen camera app. More on this later, to another question, with potentially a path forward for your case specifically.

Like maybe storing image in the hard memory and not using RAM, trying to prepare the device RAM for taking a picture, allow more RAM space for pictures capture, killing camera process before camera capture, etc...

The camera app already does this, but it obviously still needs the RAM to render the camera and snapping the photo before it it can save to the hard drive. In fact, the android application receives a file uri from the camera intent, not the photo binary itself.

How do the native Java Camera Api works ? Looks like only hybrids apps with this plugin face the problem, otherwise any app in the world should often see their apps reboot since Android 10 on many devices, which would be a major problem for Android users.

This plugin doesn't use the Camera API directly. We use Camera intents. For those who aren't native developers, Intents is a way to delegate responsibilities to another app. So when you use the camera plugin, android actually puts your app into the background, and launches a completely different app to handle the camera action, then passes the results back to the app that made the request.

Why do we do this? Well first it's the recommended approach by Android. It's recommended because the most apps do not have a reason to have direct access to the camera APIs. They are considered dangerous (in the privacy sense) and if your app simply just wants to snap a photo, it does not have justification to depend on those APIs. Using the camera permissions without necessary justification can be a grounds for the app to be rejected from the Google Play Store. Therefore this camera plugin uses the intent way, to delegate camera responsibilities to an already existing app (which most devices have).

If a plugin DID declare the camera permissions, and used the camera APIs directly, you do have more control. You can pro-grammatically snap a photo without user action, you can work with image data in real time, and I assume you can also control the resolution as well. More importantly, you're app won't ever leave the foreground and therefore the OS won't decide to kill your activity (unless you literally run out of memory).

Using camera APIs directly is not something Apache Cordova tries to solve, but there may be an existing plugin (or you can create your own) that uses the camera APIs directly, if you can convince Google that your app requires the dangerous camera permission.

@apache apache locked as off-topic and limited conversation to collaborators Jul 29, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.