Ionic Native is a set of wrappers for various Cordova plugins that make them easier to work with in Ionic 2 applications. These wrappers cover the core plugins (Camera, File, etc) but also a subset of other popular plugins. One of the cool things I found while going through the docs was that they supported plugins I had never even heard of. (And you should keep that in mind - even if you have no plans on using Ionic 2 or heck, even Ionic, these plugins that Ionic Native wrap are available for any Cordova application.)
One of the more interesting ones I discovered recently was the Diagnostic plugin. Initially I assumed this was some weird testing framework for hardware or something that worked with various internal settings. Instead it works with device settings and permissions and can be incredibly useful for providing information about what your app can do on the device. So for example, this plugin can:
- Tell you if GPS, Wifi, a camera, or bluetooth is available on the device
- Switch to device settings, so for example, to help a user enable GPS, Wifi, etc
- Enable or disable Wifi and Bluetooth
- Check to see if the app has permissions for various things, and even ask for permission explicitly. These settings are more than just hardware items like the camera, but also things like contacts and the device calendar
Basically - this plugin can help your app figure out exactly what it is allowed to do and even automate the request for having more access. It is incredibly cool, and frankly, I just wish it had a different name. Maybe something like "AwesomeAppPermissionCheckerUtilityOfAwesomeness." I think I'll fire a PR right now for that name change!
For my demo of this plugin, I decided to build something relatively simple. For a long time now I've been building Camera demos. I've done this for Flex Mobile, PhoneGap, jQuery Mobile, Ionic, and NativeScript. It's simple and fun and demos well.
One issue I run into though is that when using the iOS simulator, there's no camera available. (Which is pretty silly if you ask me. Android simply 'fakes' the camera which is what iOS should do as well.) This isn't a big deal as I just use the "select existing photo" option in the Camera plugin, but I've always wished that the Camera plugin itself would have an option to check for the existence of a camera. It's rather trivial Objective-C code (and NativeScript makes it easy to call, see my post on it from a few weeks ago), but we've never had a nice way of doing it in Cordova. Turns out we can do this quickly with the Diagnostics plugin.
The plugin supports working with the camera in three different methods:
isCameraEnabled
checks if the device has a camera, and on iOS also sees if the application has permission.isCameraPresent
checks to see if the device has a camera.isCameraAuthorized
checks if the application has permission to use the camera.
I created a super simple Ionic V2 application to work with the camera and photo gallery. I began with a simple view consisting of two buttons and a space for the image.
<ion-header>
<ion-navbar>
<ion-title>
Camera/Diagnostics
</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<img src="{{img}}" *ngIf="img !== ''">
<button block primary (click)="getPic('take')">Take Picture</button>
<button block primary (click)="getPic('select')">Select Picture</button>
</ion-content>
On the back end, I've got a simple method that makes use of Ionic Native wrapper for Camera:
import {Component} from '@angular/core';
import {NavController} from 'ionic-angular';
import {Camera} from 'ionic-native';
import {CameraOptions} from 'ionic-native';
@Component({
templateUrl: 'build/pages/home/home.html'
})
export class HomePage {
public img:String;
constructor(private navCtrl: NavController) {
this.img = "";
}
getPic(type:String) {
let options:CameraOptions = {
targetWidth:400,
targetHeight:400
}
if(type === 'select') {
options.sourceType = Camera.PictureSourceType.PHOTOLIBRARY;
} else {
options.sourceType = Camera.PictureSourceType.CAMERA;
}
Camera.getPicture(options).then((url) => {
this.img = url;
});
}
}
I've said this before but I'll say it again. I love working with Ionic 2 (and Angular 2). I'm still fumbling my way through stuff, but the code just feels better. Ok, back on topic, Ray. So in this version, the user can click either button and either take a new picture or select an existing one. I won't share a screen shot of this as it just plain works as expected. You can find the source code for this version here: https://github.com/cfjedimaster/Cordova-Examples/tree/master/cameradiagnostics/app_v1
Alright - so now let's modify it to hide the button that uses the camera when it isn't present. Don't forget to actually add the Diagnostics plugin (ionic plugin add cordova.plugins.diagnostic
). Every single time I've used Ionic Native I've forgotten to add the plugin. I'm kinda slow sometimes.
The first thing I did was modify the button itself:
<button block primary (click)="getPic('take')" *ngIf="cameraSupported">Take Picture</button>
And here is the updated code:
import {Component} from '@angular/core';
import {NavController,Platform} from 'ionic-angular';
import {Camera} from 'ionic-native';
import {CameraOptions} from 'ionic-native';
import {Diagnostic} from 'ionic-native';
@Component({
templateUrl: 'build/pages/home/home.html'
})
export class HomePage {
public img:string;
public cameraSupported:boolean;
constructor(private navCtrl: NavController, platform:Platform) {
this.img = '';
platform.ready().then(() => {
Diagnostic.isCameraPresent().then((res) => {
console.log('diagnostic result', res);
this.cameraSupported = res;
}).catch((err) => {
console.log('got an error using diagnostic');
console.dir(err);
});
});
}
getPic(type:string) {
let options:CameraOptions = {
targetWidth:400,
targetHeight:400
}
if(type === 'select') {
options.sourceType = Camera.PictureSourceType.PHOTOLIBRARY;
} else {
options.sourceType = Camera.PictureSourceType.CAMERA;
}
Camera.getPicture(options).then((url) => {
this.img = url;
});
}
}
The changes include:
- Importing Diagnostic from the Ionic Native library. The docs do not tell you to do this (but they do for other plugins) and I've filed a bug report to get this added. It's pretty easy to guess of course, but the docs should be consistent.
- Then I simply use
Diagnostic.isCameraPresent()
to check the hardware. I can then simply use the result boolean to show/hide the button.
So here's the code running in the iOS Simulator:

And here it is running on the device:

Not terribly exciting in a visual sense, but as a developer, I think this is incredibly cool, and I wish I had known about this plugin earlier. (Note to self - maybe consider a weekly series where I find a random plugin and just build a cool demo of it.)
The complete source code (including the release + initial version) may be found here: https://github.com/cfjedimaster/Cordova-Examples/tree/master/cameradiagnostics/app_v1
Archived Comments
This is nice to have, and indeed the name "diagnostic" may not be that appropriate. Reading the title of your post, I thought it were about debugging performance issues!
The info on whether push notifications are enabled or not is nice, but iOS only.
Sorry Raymond but the plugin does not open the settings.
We get a error in typescript saying: Property 'switchToSettings' does not exist on type 'typeof Diagnostic'.
Two things - either the Ionic Native plugin is broken in it's "wrapping" of the Diagnostics plugin, or the Diagnostics plugin itself is broken. Dig a bit deeper, find which it is, and then report the bug.
I've already check the ts file and the file is very short, no trace of the switchTosettings function..
Then it appears to be a bug in Ionic Native, so file a bug in their repo please.
I did it..
https://github.com/driftyco...
Good job. :)
Hello Raymond
I'd like to use custom plugin ionic native plugin doesn't have.
e.g.
https://www.npmjs.com/packa...
Is there any helpful tip for this?
Thanks
Ionic Native basically provides a 'nice way' to use these plugins. It is *not* required. You can still add the plugin to your code and reference the plugin in your JS.
Hey Raymond can you please do that for asking GPS location??
I'm not really doing a lot of Ionic demos right now - sorry.