0

I have an ionic (cordova/phonegap) app that includes uploading pictures taken from the device camera or photo library. I'm using cordova plugins via ngCordova including cordova-plugin-camera and cordova-plugin-file.

The android version uses the CrossWalk engine.

I am able to select the image from the library or take a new picture. However my callback isn't called so I'm unable to use the result. N.B: everything works perfectly on iOS.

The callback (which is not called is as follows) The callbacks are in the 'then' methods.

 $scope.getPhoto = function(useLibarary) {
        var options = {
            destinationType: Camera.DestinationType.FILE_URI,
            sourceType: (useLibarary) ? Camera.PictureSourceType.PHOTOLIBRARY : Camera.PictureSourceType.Camera,
            encodingType: Camera.EncodingType.JPEG
        };

       $cordovaCamera.getPicture(options).then(function(imageURI) {
            // success
            //
            $scope.postImageSrc = imageURI;
            console.log(JSON.stringify(imageURI));

            $scope.imageURI = imageURI;

        }, function(err) {
            // error
            console.log("error: " + JSON.stringify(err));
        });

        $cordovaCamera.cleanup().then(
            function() {
                console.log("cleanup done");
            }); // only for FILE_URI
    };

I need help getting getting it to work on Android.

I've tested on emulators and real devices.

Cordova version: 5.4.1

The emulator logcat output is below:

--------- beginning of main
W/BindingManager( 2653): Cannot call determinedVisibility() - never saw a connection for the pid: 2653
--------- beginning of system
I/ActivityManager(  339): START u0 {act=android.intent.action.CHOOSER cmp=android/com.android.internal.app.ChooserActivity (has extras)} from uid 10057 on display 0
W/PluginManager( 2653): THREAD WARNING: exec() call to Camera.takePicture blocked the main thread for 264ms. Plugin should use CordovaInterface.getThreadPool().
D/ResolverActivity( 2562): sinceTime=1448829119611
I/ActivityManager(  339): START u0 {act=android.intent.action.GET_CONTENT cat=[android.intent.category.OPENABLE] typ=image/* flg=0x3000000 cmp=com.android.documentsui/.DocumentsActivity} from uid 10057 on display 0
W/EGL_emulation( 1929): eglSurfaceAttrib not implemented
W/OpenGLRenderer( 1929): Failed to set EGL_SWAP_BEHAVIOR on surface 0xa6742220, error=EGL_SUCCESS
I/Choreographer( 1929): Skipped 85 frames!  The application may be doing too much work on its main thread.
I/UsageStatsService(  339): User[0] Flushing usage stats to disk
I/ActivityManager(  339): Displayed com.android.documentsui/.DocumentsActivity: +5s48ms (total +5s807ms)
I/Choreographer( 1929): Skipped 122 frames!  The application may be doing too much work on its main thread.
W/IInputConnectionWrapper( 2653): showStatusIcon on inactive InputConnection
W/Documents( 1929): Failed to restore stack: java.io.FileNotFoundException: Failed to find matching root for null
D/Documents( 1929): Current stack: 
D/Documents( 1929):  * null
D/Documents( 1929): Before filtering 0, after 0
D/Documents( 1929): Before filtering 1, after 1
D/Documents( 1929): Found 2 of 2 recent queries done
I/art     ( 1929): Background partial concurrent mark sweep GC freed 1027(62KB) AllocSpace objects, 0(0B) LOS objects, 40% free, 1752KB/2MB, paused 3.258ms total 114.968ms
W/AudioTrack(  339): AUDIO_OUTPUT_FLAG_FAST denied by client
D/Documents( 1929): onFinished() [content://com.android.providers.media.documents/document/image%3A25]
D/CordovaInterfaceImpl( 2653): Sending activity result to plugin
W/CordovaPlugin( 2653): Attempted to send a second callback for ID: Camera1798864042
W/CordovaPlugin( 2653): Result was: "content:\/\/com.android.providers.media.documents\/document\/image%3A25"
W/art     ( 2653): Attempt to remove local handle scope entry from IRT, ignoring
W/EGL_emulation( 2653): eglSurfaceAttrib not implemented
W/OpenGLRenderer( 2653): Failed to set EGL_SWAP_BEHAVIOR on surface 0xa00b1e20, error=EGL_SUCCESS
E/chromium( 2653): [ERROR:buffer_manager.cc(340)] [GroupMarkerNotSet(crbug.com/242999)!:7C04DEA1]GL ERROR :GL_INVALID_OPERATION : glBufferData: <- error from previous GL command
I/Choreographer(  339): Skipped 38 frames!  The application may be doing too much work on its main thread.
I/art     ( 1929): Explicit concurrent mark sweep GC freed 3277(230KB) AllocSpace objects, 0(0B) LOS objects, 24% free, 1554KB/2MB, paused 1.064ms total 312.134ms
I/art     ( 1929): Explicit concurrent mark sweep GC freed 701(63KB) AllocSpace objects, 3(68KB) LOS objects, 26% free, 1423KB/1935KB, paused 2.203ms total 296.900ms
I/art     ( 1929): Explicit concurrent mark sweep GC freed 3(96B) AllocSpace objects, 0(0B) LOS objects, 26% free, 1423KB/1935KB, paused 1.873ms total 404.704ms
E/StrictMode( 1929): class com.android.documentsui.DocumentsActivity; instances=2; limit=1
E/StrictMode( 1929): android.os.StrictMode$InstanceCountViolation: class com.android.documentsui.DocumentsActivity; instances=2; limit=1
E/StrictMode( 1929):    at android.os.StrictMode.setClassInstanceLimit(StrictMode.java:1)
I/Choreographer( 1929): Skipped 157 frames!  The application may be doing too much work on its main thread.
Kholofelo
  • 694
  • 9
  • 15
  • A couple question. Why are you not testing (first) with the standard API? Are you aware Android is written in Java, and the iOS is written in Objective-C? Are you using inline Javascript in your `index.html`? Are all your assets (Javascript, CSS, Fonts, etc.) on the device? –  Dec 15 '15 at 04:47
  • Thanks @JesseMonroy650. I'm doing cross-platform dev using cordova, as I don't have the time do native dev using Java/Obj-C/Swift - and either way Cordova has native api wrappers in Javascript. My javascript is included in my `index.html` and loaded using AngularJS. Yes all the assets are on the device. – Kholofelo Dec 17 '15 at 22:53
  • Okay. It appear Java is your weakness. Unfortunately, even though `Java/Obj-C/etc` are not required, it helps when you are reading an error log. The second line says *W/BindingManager( 2653): Cannot call determinedVisibility()*. This means something that should have been resolved - was not. I recommend removing the `cordova-plugin-file` to test your *camera* code. You can also look at my [demo code](http://codesnippets.altervista.org/examples/phonegap/demos/PUBLIC.Apps.html). It uses *Phonegap Build*. However, you may also have a `whitelist` bug. More in next.... –  Dec 18 '15 at 02:40
  • You might inadvertently introduced the need to use the Cordova `whitelist`, but I can't tell without looking at the entire code base. In any case, you need to learn how to debug these issues - and the method I gave you is the one we employ over and over again in all forums. –  Dec 18 '15 at 02:42
  • Thanks again @JesseMonroy650. I have a good knowledge of native java android, however I thought it's better not to change any of the plugin code. I'm having to use `cordova-plugin-file` since I need the `FILE_URI` so I can later upload the file. In the meantime I'm looking at your demo code and seeing what the differences are. – Kholofelo Dec 18 '15 at 08:56
  • I have [Demo code](http://codesnippets.altervista.org/examples/phonegap/demos/PUBLIC.Apps.html). It is using the simplest cases just as POC (Proof of Concept). I have three sets of code for `whitelist`. It is all going into a giant blog post. [cordova-whitelist-example](https://github.com/jessemonroy650/cordova-whitelist-example) general test, [cordova-whitelist-inappbrowser-test](https://github.com/jessemonroy650/cordova-whitelist-inappbrowser-test) test inappbrowser and whitelist. [cordova-inappbrowser-test](https://github.com/jessemonroy650/cordova-inappbrowser-test) no whitelist plugin –  Dec 18 '15 at 10:05
  • The `whitelist` is tricky, until one reads all the silly rules. –  Dec 18 '15 at 10:05
  • FWIW: you DONT need the `cordova-plugin-file` to test the camera. Test the camera code, and test the file code separately, unless you enjoy pain. –  Dec 18 '15 at 10:14

1 Answers1

0

Hi so I've found a solution to my own problem - in case anyone gets the same problem.

Basically the issue with cordova-plugin-camera on Android is that once the camera activity is instantiated, the garbage collector kills the main app, so the callback cannot happen once the app is re-instantiated. The solution is to run the CameraPlugin in foreground without killing the original app.

I didn't code the solution myself: here are some plugins you can use:

Kholofelo
  • 694
  • 9
  • 15