Ionic Framework, Cordova and Yeoman – Loved One Notifier13 min read

My good friend Jayesh came to me asking if we can build an app that sends out a message to a few contacts when the battery goes below a certain level. Kind of like a notification that your battery is about to die. I liked the Idea and wanted to try this out using Cordova. The app sounded very helpful and in the past few days of testing I found the app to be highly useful. So I wanted to share the app as well the process I used to build it.

The final app which we build would look like

You can also download Loved One Notifier from the app store

App Name

In this post, we will be building an Android app using Ionic Framework, Cordova and Yeoman. The app we are going to build is called Loved One Notifier.

We will be using Yeoman Ionic generator to scaffold and develop the app. We will be using Ionic Framework as the UI layer for the app. And finally we will be using the following plugins to interact with the device.

  • battery-status
  • contacts
  • plugin.sms
  • local-notification

You can find the completed code here.

So, let us get started.

App Design

The app is pretty simple. We ask the user to set a battery threshold when the SMS needs to be triggered, a message that needs to be sent along with the SMS and the list of contacts who should receive this message.

Once the above is stored, we keep monitoring the battery status. And when the battery percentage is equal to or less the configured threshold value, we trigger a SMS to all the selected contacts with message provided.

We will be using

We will be using angular-local-storage to manage the config between the app and local storage.

Scaffold App

So far I have been using the Ionic generator provided by the Ionic team. But this time I wanted to try Yeoman’s generator-ionic. I had my eye on it for a while but did not get a chance to use it. So here we go.

First, let us install Yeoman and the generator

npm install -g yo grunt-cli bower generator-ionic

This will take a while.

PS : If you are a mac user and want to run global commands without sudo , follow this.

Once the generator is installed, we will scaffold a new project. Before that create a new folder named myIonicApp. Open a new terminal/prompt and run

yo ionic myIonicApp

You can answer No to the question

Next, select the below plugins from the list

  • org.apache.cordova.console
  • org.apache.cordova.device
  • org.apache.cordova.battery-status
  • org.apache.cordova.contacts

On the next screen, select User Intro template and that is it! Yeoman will setup the project for you. This may take up to 5mins.

The scaffolded app would consist of the following

To quickly test drive the app, you can run

grunt serve

This will launch the app in the browser. The first screen you see is a intro screen, which has  3 slides. Once you complete the 3 slides you would reach the actual application.

We will be using this feature in our app to show a welcome wizard when the user launches the app for the first time. And from next time onward, we will show the main app.

Next, we will install two more Cordova plugins. Run

phonegap local plugin add

for sending SMS and

grunt plugin:add:de.appplant.cordova.plugin.local-notification

for showing a notification to the user.

PS : You need to have Phone gap installed for setting up SMS plugin. More info on setup : PhoneGap 3 CLI Setup on Mac & Windows.

Develop the App

The first thing we would do is setup the config.xml. Open config.xml and update it as below

You can fill in appropriate details in the XML.

When using the Yeoman generator, we will be working in the app directory and the configured grunt tasks will take care of making the contents of www folder production ready.

We want to use a different font (open-sans) for our app. We will download the same and add it to our project using bower. Run

bower install open-sans-fontface angular-local-storage --save

We will also be using angular-local-storage to mange data between the Angular.js app and the local storage.

Next, open app/index.html and update it as below

A standard Angular.js app setup.

Next, we will setup app.js. Open app/scripts/app.js and update it as below

Things to Notice

  • Line 20 and 40 :  Fetch the local storage value for skip .  This value tells if the user has already completed the intro
  • Line 33 and 42 : If the user is going to intro route and s/he has already finished the intro, we will navigate to the home page
  • Line 22, 27 and 30 : We handle the back button scenario for the splash screen and intro screen.
  • Line 55 : We create 4 states. One for loading (splash screen), intro, home and contacts.
  • Line 83 : We add a prefix to all our local storage keys

Next, we will work on the controllers. Open app/scripts/controllers.js and update it as below

Things to notice

  • Line 4 : IntroCtrl. This controller handles the navigation for the introduction slides.
  • Line 7 : When the user clicks on Navigate to App or Skip Intro, we set  skip property to true. This way, we do not show the intro screen next time
  • Line 10, 13 and 17 : Methods to interact with the slider
  • Line 23 : We create a property under $scope where we store the config options.
  • Line 24 – 31 : We set the default values to each of the config options, based on the prior saved value or a default value
  • Line 33 – 36 : We register watch on the config options and ask the  localStorageService to update the local storage when there are changes to these values.
  • Line 60 : We wait for $ionicPlatform.ready() and register a battery change event listener. And when there is a change, $scope.onBatteryStatus()  will be called on line 43.
  • Line 43 : This gets triggered when there is change in battery service. Here we assign the battery level and isPlugged values to scope. lonConfig.lastSentBattery stores the battery status when the last SMS was sent. This way, we do not keep resending the SMS on battery change less than threshold.
  • Line 52 : Before we trigger an SMS, we check if the notifier is enabled, device not plugged in, and the current battery level is less than or equal to threshold
  • Line 62 : We set the  lonConfig.lastSentBattery to the current level, get a list of saved contacts on line 83 and trigger a SMS on line 79.
  • Line 92 : Once the SMS is sent, we show a notification to the end user that a SMS is sent.
  • Line 105 : As soon as we enter the ContactsCtrl, we show a loading dialog that we are fetching contacts
  • Line 147 : We get all the contacts on the phone and trigger the success function on line 115.
  • Line 149 : When the user selects a contact, we push the contacts to the local storage for future reference.

This wraps up the Javascript part. We will create the templates needed for these views.

Create a new file named loading.html inside the templates folder. This will act as a splash screen

Next, update the intro.html

Rename main.html to home.html and update it as below

Create a new file named contacts.html and update it as below

Finally some CSS. Update main.css as

For images, refer here. And you need to run it through an Android asset generator and replace the icons with the one inside /resources/android. Then only the icon reflect in your app.

That is it! Now, let us test the app.

Test the app

We will add Android environment to the app. Run

grunt platform:add:android

Next, you can either emulate the app

grunt emulate:android

Or you can run it on a device

grunt run:android

This will install the app on your device and you can test the features.

If you have any issues, you can plug your Android device via USB and use Chrome’s mobile debugging to analyse it.

Screen Shot 2015-01-25 at 11.58.04

You can find more info here : Remote Debugging on Android with Chrome. Since Hybrid apps are web views, Chrome detects them and allows us to debug it, set breakpoints and run console commands.

Also check out Chrome DevTools for Mobile: Screencast and Emulation post by Paul Irish, which is targeted more at mobile web debugging.

Once you are happy with the app, you can publish it to the app store.

Hope this post gave you an idea on how to work with Ionic Framework and Cordova plugins.

Known Issues

  1. The contacts API is very slow and buggy.
  2. On few phones, the contacts API shows only the networks contacts and not contacts on phone.

Thanks for reading! Do comment.