The native functionality provides various facilities including an increase in performance and enhanced UX.

Hybrid web development in Ionic 2 allows you to write applications for all the supported platforms (i.e., Android, iOS, Windows, etc.) with a single code-base. Though you may already understood the power of hybrid apps, there is however a major drawback as well. Basically, Ionic 2 itself doesn’t provide direct access to native functionalities of the hardware, for example, camera, contacts, etc. So does that mean you need to write native code for them?

Well, actually no! In Ionic 1, you had to use Cordova, which is a native wrapper around native functionalities. Basically, it is the engine that powers PhoneGap. Cordova simply loads the web pages that are built on HTML/CSS/JavaScript to a web viewer. Ionic 1 uses the ngCordvoa plugins that allow you to access the native feature of the hardware, such as Contacts List or Camera. Ionic 2 by default uses Cordova for accessing Native UI, so you don’t have to worry about anything if it’s a matter of UI, but what about other functionalities?

Thankfully, Ionic 2 comes with Ionic Native, which is basically an updated version of ngCordova. First of all, it’s using AngularJS2/TypeScript, meaning you can simply download the required plugin, add it to your project and use it as if it is your typical component! This dramatically reduced the development time of native functionalities. In fact, you don’t even need to download Ionic Native separately, as it comes with Ionic 2 built-in.

In this article, I am going to show you how to add the Cordova plugins through Ionic Native to achieve whatever functionality you want. Let’s get started!

Adding Cordova Plugins in Ionic 2 Applications Through Ionic Native

In pure native apps, there is no extra layer of abstraction (i.e., WebView, DOM, etc.), so you write code in native Java (which is officially supported by Android for example) and build the application. But, in semi-native apps (which are created through Ionic 2, ReactNative and NativeScript), there is an extra layer in-between…. the WebView!

So, what’s its relevance here? Well, if your contents are first rendered on WebView, then it implies that they need to be passed to the native container of your application, so there must be some kind of transporter for it! Thankfully, Ionic 2 already comes with Ionic Native, which is a set of wrappers around Cordova plugins, so you can access native or hardware specific functionalities through JavaScript/TypeScript alone!

By the way, I spoke in my last article about Ionic Deploy which allows you to update the HTML, JS, CSS, etc. files quickly without having to wait for the app stores to approve your update, allowing the users to quickly update their applications, so we will be using this feature for updating our application.

I will add some native functionalities to the application, including Camera, Geolocation, Brightness, etc. so you can see that your application is accessing the hardware features of your device.

Creating a project

Before starting, I like to mention that if you run the following command, then you can see the results in both supported platforms, Android and iOS, in a kind of emulator way:

$ ionic serve --lab

So, let’s create our project:

$ ionic start ionic-cordova blank --v2

This will create a blank template, which simply shows a plain page with some useless text. So, let’s add some pages:

$ ionic generate page camera $ ionic generate page geolocation $ ionic generate page brightness

If you do “ionic serve” right now, you won’t see any page button nor the pages, why? Because you haven’t added them to your main app component/module, plus menu button needs to be added in HTML pages, so let’s add all this stuff. In the HTML of all these pages, add the following after <ion-navbar>:

<button ion-button menuToggle> <ion-icon name="menu"></ion-icon> </button>

This will give you the menu toggle button on the top-left side!

Let’s see our camera page. In order to use the camera functionality, you need to first add the ionic native plugin which is a matter of running the following command:

$ ionic plugin add cordova-plugin-camera

Yes, it’s that easy! Once the plugin is installed, you need to import the library in your “camera.ts” file:

import { Camera } from 'ionic-native';

But, it won’t do much, so let’s modify our component! Following is the complete content of “camera.ts”:

camera.ts

import { Component } from '@angular/core'; import { NavController, NavParams } from 'ionic-angular'; import {Camera} from 'ionic-native'; @Component({ selector: 'page-camera', templateUrl: 'camera.html' }) export class CameraPage { // jpeg/image data will be stored on base64 public base64Image: string; constructor(public navCtrl: NavController, public navParams: NavParams) {} ionViewDidLoad() { console.log('ionViewDidLoad CameraPage'); } takePicture(){ Camera.getPicture({ destinationType: Camera.DestinationType.DATA_URL, // set the width and height of picture targetWidth: 1000, targetHeight: 1000 }).then((imageData) => { // imageData is a base64 encoded string this.base64Image = "data:image/jpeg;base64," + imageData; }, (err) => { console.log(err); }); } }

Here, we have first declared the base64Image variable for storing our image. Camera.getPicture() method is used for taking the picture, therein we have also set the width and height of the image.

Now, you need to make changes in its corresponding HTML as well. Following is the complete content of “camera.html”:

camera.html

<ion-header> <ion-navbar> <button ion-button menuToggle> <ion-icon name="menu"></ion-icon> </button> <ion-title>Camera</ion-title> </ion-navbar> </ion-header> <ion-content padding> <ion-card> <ion-card-content>

You can take the picture easily by clicking on

<button (click)="takePicture()">Take a Picture</button> Your Latest Picture: <img [src]="base64Image" *ngIf="base64Image" /> </ion-card-content> </ion-card> </ion-content>

Here, the <ion-card> is used for creating Cards component that are used for highlighting important stuff. This can also include header, content, lists or images. It provides a nice shadowy background, giving a friendly feel to the users!

The rest of the code here should be self-explanatory. Basically, we have added the button for taking pictures, and then the image is loaded in our base64Image variable.

This app can run only on the device properly, otherwise it will give you the Cordova plugin error if you check the “Console” tab on your browser. Just open the app, and click on “Take a Picture” and it will open the camera and show the picture that was taken!

You can either build through “ionic build platform android” and see the results on your device or upload it to the Ionic View by “ionic upload” (make sure to synchronize with the latest changes in your app).

So, let’s see the our geolocation page. Geolocation tells you about the location of your mobile in the form of latitude and longitude which you can put on Google Maps to get the address of your location! Install the plugin first:

$ ionic plugin add cordova-plugin-geolocation

You need to modify the content of “geolocation.ts”, so copy the following to the file:

geolocation.ts

import { Component } from '@angular/core'; import { NavController, NavParams } from 'ionic-angular'; import {Geolocation} from 'ionic-native'; @Component({ selector: 'page-geolocation', templateUrl: 'geolocation.html' }) export class GeolocationPage { latitude: any; longitude: any; constructor(public navCtrl: NavController, public navParams: NavParams) {} ionViewDidLoad() { console.log('ionViewDidLoad GeolocationPage'); } getLocation() { Geolocation.getCurrentPosition().then(pos => { this.latitude = pos.coords.latitude; this.longitude = pos.coords.longitude; console.log('lat: ' + pos.coords.latitude + ', lon: ' + pos.coords.longitude); }); let watch = Geolocation.watchPosition().subscribe(pos => { console.log('lat: ' + pos.coords.latitude + ', lon: ' + pos.coords.longitude); }); // to stop watching watch.unsubscribe(); } getLatitude() { return "Latitude: " + this.latitude; } getLongitude() { return "Longitude: " + this.longitude; } }

Here, we have first imported the Geolocation from ‘ionic-native’, then we defined our latitude and longitude variables. You can see that I have defined the respective methods for returning the current values. We will use it in our HTML side. Geolocation.getCurrentPosition() does what it says: gets the current position! Geolocation.watchPosition() tracks the changes, so if you move your mobile (or body!), then it will show the changes on the console!

So, let’s change our HTML as well. Following is the complete content of “geolocation.html”:

geolocation.html

<ion-header> <ion-navbar> <button ion-button menuToggle> <ion-icon name="menu"></ion-icon> </button> <ion-title>Geolocation</ion-title> </ion-navbar> </ion-header> <ion-content padding> <ion-card> <ion-card-content> You can get your location easily by clicking on <button (click)="getLocation()">Get Location</button> </ion-card-content> </ion-card> {{getLatitude()}} {{getLongitude()}} </ion-content>

This should be easy to understand. You can see that I am using the template expressions for our methods. You can experiment by adding other methods for tracking new location changes and then highlighting them through the expressions in HTML.

Now, let’s see the Brightness page. Brightness plugin allow you to access the brightness feature of your hardware, so you can modify or change the values of brightness. Install the plugin first:

$ ionic plugin add cordova-plugin-brightness

So, let’s modify our “brightness.ts”. Following is the content of “brightness.ts”:

brightness.ts

import { Component } from '@angular/core'; import { NavController, NavParams } from 'ionic-angular'; import { Brightness } from 'ionic-native'; @Component({ selector: 'page-brightness', templateUrl: 'brightness.html' }) export class BrightnessPage { constructor(public navCtrl: NavController, public navParams: NavParams) {} ionViewDidLoad() { console.log('ionViewDidLoad BrightnessPage'); } changeBrightness() { let brightnessValue: number = 0.7; Brightness.setBrightness(brightnessValue); } }

Similar to our previous plugins, this should be easy to understand. You can change the value to something else and it will still work. Perhaps you may want to create additional methods for different brightness levels? You can experiment as much as you want!

So, now it’s time to modify the HTML. Following is the complete content of “brightness.html”:

brightness.html

<ion-header> <ion-navbar> <button ion-button menuToggle> <ion-icon name="menu"></ion-icon> </button> <ion-title>Brightness</ion-title> </ion-navbar> </ion-header> <ion-content padding> <ion-card> <ion-card-content>

You can change the brightness easily by clicking on

<button (click)="changeBrightness()">Change Brightness</button> </ion-card-content> </ion-card> </ion-content>

This should be easy to understand, so let’s skip the explanation!

Make sure to add all these pages in your “app.module.ts” and “app.component.ts”:

app.module.ts

import { NgModule, ErrorHandler } from '@angular/core'; import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular'; import { MyApp } from './app.component'; import { CameraPage } from '../pages/camera/camera'; import { GeolocationPage } from '../pages/geolocation/geolocation'; import { BrightnessPage } from '../pages/brightness/brightness'; @NgModule({ declarations: [ MyApp, CameraPage, GeolocationPage, BrightnessPage ], imports: [ IonicModule.forRoot(MyApp, { tabsPlacement: 'bottom', platforms: { android: { tabsPlacement: 'top' }, ios: { tabsPlacement: 'top' }, windows: { tabsPlacement: 'top' } } }) ], bootstrap: [IonicApp], entryComponents: [ MyApp, CameraPage, GeolocationPage, BrightnessPage ], providers: [{provide: ErrorHandler, useClass: IonicErrorHandler}] }) export class AppModule {} app.component.ts import { Component, ViewChild } from '@angular/core'; import { Nav, Platform } from 'ionic-angular'; import { StatusBar, Splashscreen } from 'ionic-native'; import { CameraPage } from '../pages/camera/camera'; import { GeolocationPage } from '../pages/geolocation/geolocation'; import { BrightnessPage } from '../pages/brightness/brightness'; @Component({ templateUrl: 'app.html' }) export class MyApp { @ViewChild(Nav) nav: Nav; rootPage: any = CameraPage; pages: Array<{title: string, component: any}>; constructor(public platform: Platform) { this.initializeApp(); // used for an example of ngFor and navigation this.pages = [ { title: 'Camera', component: CameraPage }, { title: 'Geolocation', component: GeolocationPage }, { title: 'Maps', component: BrightnessPage } ]; } initializeApp() { this.platform.ready().then(() => { // Okay, so the platform is ready and our plugins are available. // Here you can do any higher level native things you might need. StatusBar.styleDefault(); Splashscreen.hide(); }); } openPage(page) { // Reset the content nav to have just this page // we wouldn't want the back button to show in this scenario this.nav.setRoot(page.component); } }

This is what the application looks like now:

Basically, adding new native functionality is a matter of adding the plugin by selecting the plugin page from here (https://ionicframework.com/docs/v2/native/). Then just import the plugin from ‘ionic-native’, read the instructions of specific plugins and then use it on your pages/components! Make sure that you check if the device is ready before calling the plugin, otherwise it may give promises errors.

Also keep an eye on the “Console” tab when running apps through “ionic serve”. It will show Cordova plugin errors.

Just for the sake of proving how easy it is to add new native functionalities, let’s add two new pages:

$ ionic generate page callnumber $ ionic generate page vibration

We will look at callnumber page first. Install the required plugin:

$ ionic plugin add call-number

Now let’s modify the content of the page. Following is the content of “callnumber.ts”:

callnumber.ts

import { Component } from '@angular/core'; import { NavController, NavParams } from 'ionic-angular'; import {CallNumber} from 'ionic-native'; @Component({ selector: 'page-callnumber', templateUrl: 'callnumber.html' }) export class CallnumberPage { constructor(public navCtrl: NavController, public navParams: NavParams) {} ionViewDidLoad() { console.log('ionViewDidLoad CallnumberPage'); } callNumber() { CallNumber.callNumber("12001010201", true) .then(() => console.log('Dialer is launched!')) .catch(() => console.log('Error launching dialer')); } }

Again, it should be easy to understand. You can change the number in CallNumber.callNumber() method.

Following is the content of “callnumber.html”:

callnumber.html

<ion-header> <ion-navbar> <button ion-button menuToggle> <ion-icon name="menu"></ion-icon> </button> <ion-title>Call Number</ion-title> </ion-navbar> </ion-header> <ion-content padding> <ion-card> <ion-card-content>

You can call to number easily by clicking on

<button (click)="callNumber()">Call Number</button> </ion-card-content> </ion-card> </ion-content>

Now, let’s see our vibration page. First add the Vibration plugin:

$ ionic plugin add cordova-plugin-vibration

Then we need to modify the contents of our page. Following is the content of “vibration.ts”:

vibration.ts

import { Component } from '@angular/core'; import { NavController, NavParams } from 'ionic-angular'; import { Vibration } from 'ionic-native'; @Component({ selector: 'page-vibration', templateUrl: 'vibration.html' }) export class VibrationPage { constructor(public navCtrl: NavController, public navParams: NavParams) {} ionViewDidLoad() { console.log('ionViewDidLoad VibrationPage'); } createVibration() { // Vibrate for 2 seconds Vibration.vibrate(2000); // Vibrate 2 seconds // Pause for 1 second // Vibrate for 2 seconds // Patterns work on Android and Windows only Vibration.vibrate([2000,1000,2000]); // Stops the vibration now Vibration.vibrate(0); } }

Following is the content of “vibration.html”:

vibration.html

<ion-header> <ion-navbar> <button ion-button menuToggle> <ion-icon name="menu"></ion-icon> </button> <ion-title>Vibration</ion-title> </ion-navbar> </ion-header> <ion-content padding> <ion-card> <ion-card-content>

You can create vibration easily by clicking on

<button (click)="createVibration()">Create Vibration</button> </ion-card-content> </ion-card> </ion-content>

Make sure to add callnumber and vibration pages to “app.component.ts” and “app.module.ts”.

You can now run the application through “ionic serve”, but for seeing the plugins in action, either build the android .apk or upload to Ionic View.

If you have trouble following the code, then you can see the repository here (https://github.com/danyalzia/Ionic2-cordova-plugins-play).

Before we wrap things up, I’d like to point out that unfortunately, many native plugins don’t work properly. I’ve selected from the ones that are working just fine however. Ionic Native is still in development stage, so there is a hope that future versions will have functioning plugins.

Conclusion

You have finally witnessed the amazing power of Ionic 2! With the help of Ionic Native, any native functionality can be accessed from your application, pretty much deprecating the need for native mobile development.

If you have anything you’d like to ask, then please ask in the comment section below!