Cordova, the Camera plugin, AngularJS, and Ninja Cats.

This post is more than 2 years old.

Just a random tip for folks who may run into this in the future. I'm working on a mobile app for a client and I'm using both Cordova and AngularJS. The application allows people to select a photo from their gallery or take a new picture. It then renders a thumbnail to the web page. It supports any number of selections so my view simply loops over an array.

<img ng-repeat="pic in groupPics[group.part]" ng-src="{{pic}}" ng-click="removePicture(group.part,pic)" class="img-thumbnail" style="width:120px; height: 120px">

Pretty simple, right? In my testing I always used the simulator as it doesn't have a real camera, and I typically tested on iOS only since they were testing Android. Also, the camera is pretty simple to use so it just plain works most of the time.

But then the client reported something odd. Whenever he selected a picture from the gallery, the image thumbnail would show up broken. I quickly ran it (and since I said quickly you know I used Genymotion and not the Android emulator) and confirmed it failed. Like any other good hybrid developer I fired up my dev tools and checked the console. This is what I saw.

GET unsafe:content://com.android.providers.media.documents/document/image%3A21

Some Googling turned up this Stackoverflow post. Long story short - it is an Angular security measure. I've run into Angular security stuff before (trying to inject HTML into the DOM) so this isn't the first time I've had an issue like this, but it threw me for a loop since it worked in iOS. If you look at the file URI returned by Camera/Gallery selections though it makes a bit more sense. Here is an example of a file URI returned from iOS (spaces added so it will wrap):

file:///Users/ray/Library/Developer/CoreSimulator/Devices/ C8202B3B-300B-4819-8CD3-4C4AA690CE7C/ data/Applications/D82BF64E-6DD1-4645-B637-BCF65001FD29/tmp/cdv_photo_003.jpg

The exact same code on Android returns a file URI like so:

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

Angular sees this as something weird and says, "No Way Man!". Luckily the fix is simple. In my application's configure block, I added this:

$compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|mailto|content):/);

So, keep it in mind if you are using the camera in a Cordova/AngularJS application.

Ninja cat provided for no good reason.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Adam Tuttle posted on 10/10/2014 at 7:46 PM
Comment 2 by Raymond Camden posted on 10/10/2014 at 7:49 PM

Weird - my Android VM is 4.4.2 and it worked fine once I fixed the Angular issue.

Comment 3 by Raymond Camden posted on 10/11/2014 at 5:13 PM

As an FYI, you also need to add file to the list of approved schemes if you are using the camera on an Android device. Pictures selected from the camera will use file, not content.

Comment 4 by Ankit Shandilya posted on 10/16/2014 at 2:13 PM

Hi,

I've used the Google Analytics Plugin from GitHub (
https://github.com/phonegap... to get Google Analytics to
work for PhoneGap. As far as I know, I installed and configured everything
correctly. However, I don't see any data in Google Analytics.

This is what I've done:

- created a 'HelloPhoneGap' project in Eclipse
- downloaded the GAPlugin and installed in 'manually' (I did not use
plugman): I copied GAPlugin.js, GAPlygin.java, libGoogleAnalyticsV2.jar,
index.html from the downloaded GAPlugin into my HelloPhoneGap project. I
also added the GAPlugin in the config.xml
- copied my own GA Account (UA-12345678-1) into the index.html
- run the project in an emulator. Results:
- in onDeviceReady it executes gaPlugin = window.plugins.gaPlugin
- in onDeviceReady itgives a notification asking for permission
- in LogCat: Need to call intilize() and be in fallback mode to start
diuspatch
- in LogCat: Thread[]: Service unavailable (code=1), will retry.
- in LogCat: Thread[]: No campaign data found
- when I click Track Event, it executes gaPlugin.trackEvent and the
logging from the success callback appears in LogCat: trackEvent - category
= Button; etc
- I checked Google Analytics: nothing ;- (

Did I made a mistake somewhere? Or is this plugin only suitable for
PhoneGap Build?

Regards, Ankit

PS. I'm using PhoneGap 2.5, on Eclipse, on Windows 7.

Comment 5 by Raymond Camden posted on 10/16/2014 at 2:41 PM

@Ankit: This comment has absolutely nothing to do with this blog post. For general questions, I suggest you use the PhoneGap Google group, or Stack Overflow. You can email me these types of things too, but I'd hit the Google group at least first.

Comment 6 by willy posted on 10/17/2014 at 1:21 PM

hey guys, i also use cordova, angularjs and the camera plugin.
and when i choose a picture over camera i use the base64 data with bloburl of the file to display the image inline.
one think of the new android filesystem what kitkat bring on is very annoying.
why i can't get the real filename of choosen file?
my coworker found out that the file plugin makes a blob of choosen file and lost the filename,
and in the fileapi every file you choose is called content.
has anyone a solution therefor?
cheers dutscher