Select images from photo gallery in a Cordova (Phonegap) App on Android

A week after release we realised that Android phones sometimes duplicated the photos uploaded to the server from our app. Turned out to be a bit tricky to find the solution. 

The problem only appeared on Androids. And only when adding more than one image. And only with images from the photo gallery (not from the camera).

In Phonegap I used code like this to get the photo from the gallery:

 function getPhotoWithSize(source) { 
 // Retrieve image file location from specified source
 navigator.camera.getPicture(onPhotoURISuccess, onFail, { quality: 50, 
 targetWidth: 960,
 targetHeight: 960,
 destinationType: destinationType.FILE_URI,
 sourceType: source });
 }

Which gave me a result URI like this on Android devices:

file:///storage/emulated/0/Android/data/com.telerik.CameraTests/cache/resize.jpg?1397645214730

And that kind of path works perfect in the app webview for an img src. But the resize.jpg is only a temporary file, and when the user selects the next one the file is overwritten with a new one.

That does not affect the actual webview – so everything looks fine. But when the user uploads the images later, the uploader uploads the latest file repeatedly.

I found out that it’s only for resized images cordova handles the images this way. When getting picture without height and with settings I get the path to the original file:

content://media/external/images/media/152

For that reason I need to use un-resized images here. However – for users with phones with high resolution cameras this will be a problem, especially if they add lots of pictures. So I need to handle some resizing on my own.

But – what is worse is that in the newest version of Android, the content path is changed like this:

content://com.android.providers.media.documents/document/image%3A153

Which neither the web viewer, nor the uploader likes. Apparently this has been fixed in the Cordova 3.5. https://issues.apache.org/jira/browse/CB-5398

But it takes a while for Telerik to add new Cordova releases to AppBuilder – I don’t expect 3.5 to show up until in a few weeks. Too late for our app. So – I needed a workaround.

It took me too many hours to find a good workaround, and I only succeeded after I got a nice debug setup for my Android development:

1) Genymotion to be able to test my application on emulators for any Android version. I use Telerik AppBuilder to build and publish my app, and AppBuilder automatically recognizes running Genymotion emulators, which means I can deploy directly from AppBuilder to the running emulator. Also small updates (js / html) are pushed instantly from AB to the emulator.

genymotion

2) It’s a PITA to try find errors in code without a console. Weinre is a great solution for that. Just by running Weinre server on my PC and hooking up to the .js on that server from my app I get a console on the running app. http://blogs.telerik.com/appbuilder/posts/13-09-24/remote-debugging-icenium-apps-with-weinre

With these tools I soon found that I did not only have to deal with the path problem.

I found out by looking at the HTML that AngularJs caused problems for me here – prefixing the src path with “unsecure:”. Turns out I needed to add “content” to the img src whitelist to make it work. http://stackoverflow.com/questions/15606751/angular-changes-urls-to-unsafe-in-extension-page

With “content” whitelisted a simple string replacer fixed the problem with the new path for me:

if (imageURI.substring(0,21)=="content://com.android") {
  photo_split=imageURI.split("%3A");
  imageURI="content://media/external/images/media/"+photo_split[1];
}

http://stackoverflow.com/questions/20638932/unable-to-load-image-when-selected-from-the-gallery-on-android-4-4-kitkat-usin

 

Advertisements