How to create custom camera plugin?

Yes, the “src” is autogenerated from “ng-src”. And the addition of “unsafe” before “file:” is what causes the image links to be broken.

I think I know what causes this, the “unsafe” has to do with CORS and with the Content-Security-Policy tag in your index.html. In my index.html the tag looks like this:

  <meta http-equiv="Content-Security-Policy"
        content="default-src 'self' * data: gap: filesystem: https://ssl.gstatic.com https://maps.googleapis.com/ https://maps.gstatic.com/ https://mts0.googleapis.com/ 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">

How does yours look? The important thing is that “filesystem:” is present (between “gap:” and “https://ssl.gstatic.com”). I remember that before I added this I also had the problem (but I’m not sure if that was on a device or in the browser).

Try to add this tag and see if that solves the problem.

The meta tag I have in my index.html file is the one below:

I think the meta tag is ok according to your suggestion (filesystem between “gap:” and “https://ssl.gstatic.com”).

I have also added in config.xml file from suggestions that I found when I was looking about the problem the lines below:

access origin=“file:///"/
allow-navigation href="
”/
allow-navigation href=“file:///”/

I don’t know if this makes any difference at all or if it is not of any importance but I mention it anyway just in case it is important.

Did you include the Cordova Whitelist plugin? Please double-check that.

And have a look at this article:

http://sonam93.blogspot.com/2015/11/load-image-using-ng-src-in-android.html

This author uses the following CSP tag:

  <meta http-equiv="Content-Security-Policy" content="default-src *; img-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'">

with the explicit addition of “image source”:

img-src *

Anyway evidently as soon as Angular/Ionic isn’t adding “unsafe” anymore to your “src” attribute then your images will start working. Did you try my suggestion about angular-image-cache?

I have installed the whitelist plugin in my app because I can see that it exists in the plugins folder.

I am going to try and use the Content Security Policy that is suggested in this article.

If this does not work I will try the angular-image-cache. I did not use angular-image-cache yet because I have to check how to put it on work. I have never used this directive before.

Thanks leob

Okay cool.

It always amazes me how people keep saying “creating an app with Ionic or hybrid or whatever is so simple, it took me 3 hours” or “even my grandma could do it”. I think that’s true only for very trivial apps, or if you are very lucky.

My experience is that a realistic app requires tons of patience and knowledge even though yes with hybrid/Ionic it’s less work than with “native” and you can develop for Android and iOS with 1 codebase.

But it’s still a lot of work especially for a solo developer, anyone who’s saying the contrary is talking nonsense. The devil is in the details, and just the constant testing and retesting to check if anything’s broken in your app is already a ton of work, let alone the amount of stuff that breaks when you change or upgrade any of the dependencies (Ionic, Cordova, any plugins, iOS version, Android version and so on).

(yes I know about automated testing but just that is already a ton of work to set up and keep running properly, I think that al the optimistic stories assume that you’ve got a big team of specialists with a ton of money and lots of time on their hands, for a solo dev this is extremely hard work)

Example: right now I’m trying to get the Ionic 2 CLI to work which optimistically should work transparently with Ionic 1 apps, but it’s breaking on some kind of vague conflict with “karma” which I dared to include in my app:

Many people struggling with it, nobody found a solution, go figure …

Other example: recently I started producing iOS apps for the first time, the amount of obscure Apple tooling (Xcode, iTunes Connect and so on) you then need to set up and understand is baffling. And of course I happened to have a requirement for my app which was an edge case (not mainstream) and it required a ton of complicated workarounds to get working properly.

This stuff is so complex “under the hood”, sometimes it amazes me that it works at all.

Totally agree with you. This is the first app I am trying to create and I was thinking that it would take me about 1 to 2 months to finish it and still I am at the start. You have to cope with the UI especially if it is a complex one, various plugins that take lots of time to learn and configure and who knows what else can come up. And when you finish with the code then you have to test your app in various operating systems to check how it responds. Furthermore you have to make your application known to the public if you want to earn some money which requests to do your own ASO and your own marketing in order to make your app popular.

Yes true, I wasn’t even talking about the marketing, just about the development. It’s no rocket science but it requires lots of time and patience to get all the details right, and a huge amount of tweaking/testing/optimization.

Example:

I found out accidentally that my app didn’t do “portrait” on iOS when I rotate the device horizontally.

Also found out that in some pages the keyboard on iOS was obscuring the page making it unusable.

Both are solved by installing a Cordova plugin which in fact you need only on iOS. I could go on for hours with examples like these.

Hi leob

I have 2 questions regarding the angular-image-cache directive because I am not familiar with this component and I did not find any examples demonstrating how to use it in an Ionic app.

  1. In my html code right now I have something like this to show the images:

< img ng-repeat=“image in images” ng-src="{{urlForImage(image)}}" style=“height:200px; padding: 5px 5px 5px 5px;” / >

From the code you can see that in the ng-src I am calling a function urlForImage and passing the variable image that contains a file url like this one : file:///data/data/com.ionicframework.devdacticimages326829/files/WavkM20160605_175407.jpg

So my question is: in order to use the angular-image-cache I just have to install it and then replace ng-source with this: < img ng-repeat=“image in images” img-cache ic-src="{{urlForImage(image)}}" style=“height:200px; padding: 5px 5px 5px 5px;” / > (use only the directive img-cache ic-src)

OR

I should also do the things mentioned in the documentation for example declare it in the Angulars config section, initializing it in the $ionicPlatform.ready() and access the ImgCache service to cache the files and then use the directive img-cache ic-src in the < img > tag ???

  1. In an ionic application where should I place the following script tags:

< script src=“bower_components/angular/angular.js” ></ script >
< script src=“bower_components/imgcache.js/js/imgcache.js” >< /script >
< script src=“bower_components/angular-imgcache.js/angular-imgcache.js” >< /script >

As far as I know they should be placed below the script tag
< script src=“lib/ionic/js/ionic.bundle.js” ></ script > and also there is no need to declare the angular.js file because it is included inside the ionic.bundle.js file. Is this correct?

Note: I am storing the files locally in the data directory of the app and also the filenames are stored in the local storage so in order to get the image I do a concatenation of data directory + filename from local storage and then return that from the urlForImage() function )

Yes in any case you need to change the HTML tag so for instance as you already said:

< img ng-repeat="image in images" img-cache ic-src="{{urlForImage(image)}}" style="height:200px; padding: 5px 5px 5px 5px;" / >

If I were you I would replace only one of your image tags and check if it works then. If it still doesn’t work then you won’t have wasted time with replacing all your image tags. If it works however then of course you proceed to modify all of your other image tags to use ng-img-cache.

In your app.js, you first add “ImgCache” as an Angular module, so for instance:

  angular.module('app', [
    // libraries
    'ionic',
    // angular-imgcache
    'ImgCache',
// ................................. etcetera
  ])

and (also in app.js) you add a config-function like this:

  .config(function (ImgCacheProvider) {

    ImgCacheProvider.setOptions({
      debug: true,    // you can set this to false for a production app
      chromeQuota: 25 * 1024 * 1024,          /* allocated cache space : here 25MB instead of the default 10MB */
      usePersistentCache: true
    });

    // ImgCache library is initialized automatically, but set this option if you are using platform like Ionic -
    // in this case we need init imgcache.js manually after device is ready
    ImgCacheProvider.manualInit = true;
  })

and finally in your “run” function (also in app.js) you add this to your “ionic platform ready” handler:

  .run(function ($ionicPlatform, $log, ImgCache) {

    $ionicPlatform.ready(function () {
      $log.info('IONIC PLATFORM READY');

      ImgCache.$init();
// .......... etcetera

Finally, in your index.hrml you include the 2 necessary JS libraries, BELOW ionic bundle and ABOVE cordova:

  <script src="lib/ionic/js/ionic.bundle.js"></script>

  <script src="lib/imgcache.js/js/imgcache.js"></script>
  <script src="lib/angular-imgcache/angular-imgcache.js"></script>

  <script src="lib/ngCordova/dist/ng-cordova.min.js"></script>
  <script src="cordova.js"></script>

That should be it …

Hi leob

Thanks for your suggestions. I have done all the changes and deploy the app on my device. Now when I open the app I don’t receive any broken image but also I don’t see any image at all. The image seems to be there but does not appear.

I also get the following error when I debug from the chrome://inspect/#devices:

Uncaught ReferenceError: FileTransfer is not defined http://192.168.1.3:8100/cordova.js Line: 312 (index):29

Does this mean that the FileTransfer plugin is missing? I don’t use it in my app anyway. I just use the File and FilePath plugins.

The img tag now includes the following code:

<img ng-repeat="image in images" img-cache ic-src="file:///data/data/com.ionicframework.devdacticimages326829/files/TnC2p20160605_175407.jpg" style="height: 200px; padding: 5px;" class>

Yes, just try to add the file transfer plugin and see if it works then:

ionic plugin add cordova-plugin-file-transfer

If that doesn’t help then we may need to reconsider using angular-image-cache because to be honest it isn’t adding real value in your use case (because your images are already local so caching is redundant).

What we would really need to figure out is how to prevent “unsafe” from getting added before the “file:” protocol in your src attribute. If you want you could send me your source code and I could have a look at it, maybe it’s something simple …

Yes I will try to install the FileTransfer plugin and try again to check if it works.

In case it is not working I will send you the source code.

Thank you.

Hi leob

I have installed the FileTransfer plugin and rebuild the app and when deployed it the images were broken again. Now the < img > tag includes the following information:

< img ng-repeat=“image in images” img-cache="" ic-src=“file:///data/data/com.ionicframework.devdacticimages326829/files/Mf7gl20140530_172056_20140530194755740.jpg” style=“height: 200px; padding: 5px;” class="" src=“cdvfile://localhost/persistent/imgcache/5914b7e8b17444350c5a06581a1569f436d64465.jpg” >

and also I receive the following error:

GET cdvfile://localhost/persistent/imgcache/5914b7e8b17444350c5a06581a1569f436d64465.jpg 404 (Not Found)

I will send you the source code to have a look at it also

Hi leob

I have uploaded the source code in github

https://github.com/akarayiannis/devdactic-images.

Have a look at it if you like

Thank you in advance

Okay I’ll have a look!

P.S. I’ve downloaded your code from Github but haven’t had time yet to check it, it’s almost midnight do I’ll do that tomorrow …

Ok leob there is no problem when ever you can…thanks

Okay I had a look and I have it working on my Android device. To get it working I made only the following 2 changes in www/index.html:

  1. I noticed that the “ion-content” tag wasn’t closed properly, the end tag was coded “” instead of “” ( the “t” was missing).

  2. I went back from angular-image-cache to normal ng-src (without the cache, which is redundant anyway because the files are local).

Both lines were already there with the “ng-src” line commented out. So all I did was uncomment the line that was commented out, and comment out the line that was not commented out, resulting in:

    <img ng-repeat="image in images" ng-src="{{urlForImage(image)}}" style="height:200px; padding: 5px 5px 5px 5px;" />
    <!--<img ng-repeat="image in images" img-cache ic-src="{{urlForImage(image)}}" style="height:200px; padding: 5px 5px 5px 5px;" />-->

And then it just worked, I could take an image with the camera plugin and it displayed fine. No addition of “unsafe” to my “src” attribute.

Hi leob
I also tried the app with the changes that you mentioned and it works. I think that the app worked because of those two changes:

  1. The close of the tag in the ion-content
  2. The addition of the meta tag

considering that the first version of the code included the ng-source attribute and not the img-cache.

I think that what made the big difference was the addition of the meta tag that allows showing images from the filesystem.

Thanks a lot for your help and for your valuable suggestions :slight_smile:
Have a nice day

Cool!

Yes I noticed immediately that the closing tag was incorrect, my editor/IDE flagged it “red”.
And yes, the “Content-Security-Policy” tag (the meta tag) is important, and highly recommended.

So it means that you can remove angular-image-cache from the app again, since it’s not used anymore.