title: Custom cordova plugin creation for ionic2 project
body: <p>Many of us would have gone through similar issues, but even after going through following most relevant links <a href="http://www.mat-d.com/site/tutorial-creating-a-cordova-phonegap-plugin-for-android-app/" rel="nofollow noreferrer">reference link1</a> and <a href="https://cordova.apache.org/docs/en/latest/guide/hybrid/plugins/" rel="nofollow noreferrer">reference link2</a> , I am not able to resolve.</p>
  
  <p><strong>Issue:</strong></p>
  
  <blockquote>
    <p>Create a custom plugin (Cordova) in-order to use this in ionic2
    project.</p>
  </blockquote>
  
  <p><strong>Expectation</strong>: This plugin will be able to interact with native features of IOS and Android. To be precise I am trying to access features of a native SDK (Aruba Internal Positioning SDK) using cordova into Ionic project.</p>
  
  <p><strong>Step 1</strong> Initially created plugin as per <a href="http://www.mat-d.com/site/tutorial-creating-a-cordova-phonegap-plugin-for-android-app/" rel="nofollow noreferrer">reference link 1</a> </p>
  
  <p><strong>Step 2</strong> Created Ionic 2 project( created with <a href="http://ionicframework.com/docs/v2/setup/installation/" rel="nofollow noreferrer">this</a> basic steps )</p>
  
  <p><strong>Step 3</strong> JavaScript file in plugin was not able to refer and access in Ionic2 .</p>
  
  <p>After googling , I found <a href="https://forum.ionicframework.com/t/how-to-use-custom-plugin/53798/25" rel="nofollow noreferrer">this discussion</a> , where it is told to create interface in plugin itself because of the following reason.</p>
  
  <blockquote>
    <p>import {myPluginName} from '../../../plugins/xxx/*.js'</p>
    
    <p>Will not work because the plugin is not part of the ionic native bundle.</p>
    
    <p>If you have a custom plugin, you can do a few things.</p>
    
    <p>1) Make a PR to add it to ionic-native proper </p>
    
    <p>2) Use the raw plugin API.
    You can use the raw plugin API without having it be part of Ionic Native.
    The plugin is on the window object, so you would target the api normally</p>
    
    <p>window.plugin.myPlugin.myMethod()</p>
  </blockquote>
  
  <p>According to the <a href="https://github.com/stirumala76/zpl-printer-poc" rel="nofollow noreferrer">GITHUB Example </a> project this way the interface should be implemented</p>
  
  <pre><code>interface CordovaPlugins {
    ZPLPrinter: ZPLPrinter;
  }
  
  interface ZPLPrinter {
  
    print(
      ipaddress: string,
      bclabels: any,
      printSuccess: (ip: string, labels: string[]) =&gt; void,
      printError: (message: string) =&gt; void): void;
  
  }
  </code></pre>
  
  <p>Now I created a similar interface in my plugin which is the following in plugin's www folder</p>
  
  <pre><code>interface CordovaPlugins {
    Communicator: Communicator;
  }
  
  interface Communicator {
  
    getInfo(successCallback: any, errorCallback: any);
  
  }
  </code></pre>
  
  <p>This interface would ideally target this method in JS file </p>
  
  <pre><code>Device.prototype.getInfo = function(successCallback, errorCallback) {
      console.log("device.js: getInfo function called");
      argscheck.checkArgs('fF', 'Device.getInfo', arguments);
      exec(successCallback, errorCallback, "Device", "getDeviceInfo", []);
  };
  </code></pre>
  
  <p>Now I am stuck , as my Ionic project is not having <strong>typings</strong> folder itself.</p>
  
  <p>In the sample <a href="https://github.com/stirumala76/zpl-printer-poc" rel="nofollow noreferrer">Github Project</a>, cordova packages are referred using <strong>typings</strong> folder . <a href="https://github.com/stirumala76/zpl-printer-poc/blob/master/MyIonic2Project/app/pages/hello-ionic/hello-ionic.ts" rel="nofollow noreferrer">TypeScript File in project</a> is referring <code>Cordova</code> using <a href="https://github.com/stirumala76/zpl-printer-poc/blob/master/MyIonic2Project/typings/globals/cordova/index.d.ts" rel="nofollow noreferrer">index.t.js</a></p>
  
  <p>Import used to refer should go like </p>
  
  <pre><code>declare var cordova: Cordova;
  </code></pre>
  
  <p><strong>Doubts:</strong></p>
  
  <ol>
  <li>Am I in the wright direction of the process</li>
  <li>Is this the way to create <code>Cordova</code> plugin and use in ionic </li>
  <li>Why I am not able to get <code>typings</code> folder in Ionic2</li>
  </ol>
  
  <hr>
  
  <p>EDIT 1:</p>
  
  <p>After just adding the plugin without even referring in Ionic project, I tried to run in Android device. But it gave me the following error.</p>
  
  <p>Main error is this</p>
  
  <pre><code>java.lang.RuntimeException: Unable to start activity ComponentInfo{com.ionicframework.cutepuppypics234138/com.ionicframework.cutepuppypics234138.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void org.apache.cordova.CordovaPlugin.privateInitialize(java.lang.String, org.apache.cordova.CordovaInterface, org.apache.cordova.CordovaWebView, org.apache.cordova.CordovaPreferences)' on a null object reference
  </code></pre>
  
  <p>Why would this error be causing? Detailed logs have given below</p>
  
  <pre><code>12-08 16:10:49.079 20555-20555/? E/ApkAssets: Error while loading asset assets/natives_blob_64.bin: java.io.FileNotFoundException: assets/natives_blob_64.bin
  12-08 16:10:49.079 20555-20555/? E/ApkAssets: Error while loading asset assets/snapshot_blob_64.bin: java.io.FileNotFoundException: assets/snapshot_blob_64.bin
  12-08 16:10:49.682 20555-20555/? E/AndroidRuntime: FATAL EXCEPTION: main
  Process: com.ionicframework.cutepuppypics234138, PID: 20555
  java.lang.RuntimeException: Unable to start activity ComponentInfo{com.ionicframework.cutepuppypics234138/com.ionicframework.cutepuppypics234138.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void org.apache.cordova.CordovaPlugin.privateInitialize(java.lang.String, org.apache.cordova.CordovaInterface, org.apache.cordova.CordovaWebView, org.apache.cordova.CordovaPreferences)' on a null object reference
     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2339)
     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2413)
     at android.app.ActivityThread.access$800(ActivityThread.java:155)
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1317)
     at android.os.Handler.dispatchMessage(Handler.java:102)
     at android.os.Looper.loop(Looper.java:135)
     at android.app.ActivityThread.main(ActivityThread.java:5343)
     at java.lang.reflect.Method.invoke(Native Method)
     at java.lang.reflect.Method.invoke(Method.java:372)
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)
  Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void org.apache.cordova.CordovaPlugin.privateInitialize(java.lang.String, org.apache.cordova.CordovaInterface, org.apache.cordova.CordovaWebView, org.apache.cordova.CordovaPreferences)' on a null object reference
     at org.apache.cordova.PluginManager.getPlugin(PluginManager.java:171)
     at org.apache.cordova.PluginManager.startupPlugins(PluginManager.java:97)
     at org.apache.cordova.PluginManager.init(PluginManager.java:86)
     at org.apache.cordova.CordovaWebViewImpl.init(CordovaWebViewImpl.java:115)
     at org.apache.cordova.CordovaActivity.init(CordovaActivity.java:149)
     at org.apache.cordova.CordovaActivity.loadUrl(CordovaActivity.java:224)
     at com.ionicframework.cutepuppypics234138.MainActivity.onCreate(MainActivity.java:39)
     at android.app.Activity.performCreate(Activity.java:6010)
     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1129)
     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2292)
     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2413) 
     at android.app.ActivityThread.access$800(ActivityThread.java:155) 
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1317) 
     at android.os.Handler.dispatchMessage(Handler.java:102) 
     at android.os.Looper.loop(Looper.java:135) 
     at android.app.ActivityThread.main(ActivityThread.java:5343) 
     at java.lang.reflect.Method.invoke(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:372) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700) 
  12-08 16:10:49.879 20656-20656/? E/SubDex: SubDex Config : .dex 2
  12-08 16:10:50.285 20656-20656/? E/project: extsdcard==/storage/emulated/0/Android/data/com.cleanmaster.mguard/files
  12-08 16:10:50.303 20656-20656/? E/project: extsdcard==/storage/emulated/0/Android/data/com.cleanmaster.mguard/files
  </code></pre>