Wednesday, October 19, 2016

Developing Garmin SmartWatch Apps with ConnectIQ Platform-Part 2

This is part 2 of blog series that covers a tutorial on developing Wearables App for Garmin SmartWatches. In this part of the tutorial we will write the logic to display Meeting Alerts in the watch widget that we created in part-1 of this tutorial.

Lets create a Monkey-C class called MeetingAlert.mc in the CalendarAlerts ConnectIQ Eclipse Project. MeetingAlert class will represent a single MeetingAlert record that we will receive from the Android Device over BLE.

using Toybox.System as Sys;
class MeetingAlert {

  //mTime - meeting time
  //mDate - meeting date
  //mSubject - meeting subject
  //mLocation -meeting location
 hidden var mTime, mDate, mSubject, mLocation;

 
 function getMeetingTime() {
  return mTime;
 }
 
 function getMeetingDate() {
  return mDate;
 }
 
 function getMeetingSubject() {
  return mSubject;
 }
 
 function getMeetingLocation() {
  return mLocation;
 }
 
 
}

We can assume that the calendar event details are received from Android Device whenever the watch synchronizes with phone over bluetooth. As mentioned in part-1 of this blog we will use comma separated string values to exchange data. Hence we are assuming that the Android Device will send us the calendar events in the following CSV format

           mTime, mSubject, mLocation, mDate

Where
    mTime - is the meeting time
    mDate - is the meeting date
    mSubject - is the meeting subject
    mLocation - is the meeting location

When we receive a message containing the above mentioned CSV string we will parse it and create a MeetingAlert Object. So to parse it we will add a method called initialize() in MeetingAlerts which will accept a CSV string of meeting record and populate the mTime, mDate, mSubject and mLoaction variables in the MeetingAlert Class.

function initialize(eventData) {
     var i=eventData.find(",");
        
      mTime = eventData.substring(0, i);
      var leftOver = eventData.substring(i+1, eventData.length());
      i=leftOver.find(",");
      mSubject =leftOver.substring(0, i);
      
      leftOver = leftOver.substring(i+1, leftOver.length());
      i=leftOver.find(",");
      mLocation =leftOver.substring(0, i);
     
      leftOver = leftOver.substring(i+1, leftOver.length());
      mDate =leftOver;
      Sys.println("mTime" + mTime +" mDate "+ mDate + " mSubject "+ mSubject+" mLocation "+mLocation);
   
 }

In the above method we are trying to parse the comma separated calendar event record String (eventData) and assign the comma separated first value to mTime, second value to mSubject, third value to mLocation and fourth value to mDate variable.

Now lets expand the folder named "resources" in our CalendarAlerts project. You can see that it has an "images" folder and a "layouts" folder. The images folder is the place where you keep all your
 the images that you would like to use in your app. and the layouts folder has a file called layout.xml which defines the layout of the UI components that you will use in your app. The project structure at this point would look as in the screenshot on the left.
Now if you open the layouts.xml you can see a bitmap tag which has a file name as shown below.

bitmap filename="../images/monkey.png

This bitmap tag is responsible to render the image of monkey in the center of the default view that you see when the app is launched(check by launching in simulator). Since we don't need it for our app we can remove it. 
Now open the CalendarAlertsApp.mc class. This is our main application class which extends Toybox::Application::AppBase and is the entry point of our application. Notice that ToyBox.Application is aliased as App in the first statement using Toybox.Application as App; This is very similar to import statements that you use to import Classes/Packages in other languages like Java. See class definition below.

using Toybox.Application as App;

class CalendarAlertsApp extends App.AppBase {

    //! onStart() is called on application start up
    function onStart() {
    }

    //! onStop() is called when your application is exiting
    function onStop() {
    }

    //! Return the initial view of your application here
    function getInitialView() {
        return [ new CalendarAlertsView() ];
    }

}

As mentioned in the code comments you can do operation that you want to do on startup of the app in the onStart() method. If you want to perform an operation on exiting the application, that needs to be written in the onStop() method.  The function getInitialView returns the first view to be shown to the app user, in our case it is the CalendarAlertsView.

Now lets create CalendarAlertsView and add something to it. The basic structure of CalendarAlertsView.mc will look like this
using Toybox.WatchUi as Ui;
using Toybox.WatchUi as Ui;
using Toybox.Graphics as Gfx;
using Toybox.System as Sys;
using Toybox.Communications as Comm;
using Toybox.Attention as Attention;
using Toybox.Timer as Timer;
using Toybox.Lang as Lan;
using Toybox.Application as App;
using Toybox.Time as Time;
using Toybox.Time.Gregorian as Calendar;
 
class CalendarAlertsView extends Ui.View {
 
     //a string message to be shown on the screen
       var displayString ="None in next 15 mins";
    
   //! Load your resources here
    function onLayout(dc) {
        setLayout(Rez.Layouts.MainLayout(dc));
    }
 
    //! Called when this View is brought to the foreground. Restore
    //! the state of this View and prepare it to be shown. This includes
    //! loading resources into memory.
    function onShow() {
    }
 
    //! Update the view
    function onUpdate(dc) {
        // Call the parent onUpdate function to redraw the layout
              View.onUpdate(dc);
             
         //Set the foreground and background color of graphics    
              dc.setColor( Gfx.COLOR_WHITE, Gfx.COLOR_TRANSPARENT );
         //Set text that we want to draw at a given top,left location on the screen
  dc.drawText(10, 20,  Gfx.FONT_MEDIUM, "Upcoming Meetings:", Gfx.TEXT_JUSTIFY_LEFT);
dc.drawText(10, 50,  Gfx.FONT_MEDIUM, displayString, Gfx.TEXT_JUSTIFY_LEFT);
       
         //Refresh the UI with changes that we did above
             Ui.requestUpdate();
    }
 
    //! Called when this View is removed from the screen. Save the
    //! state of this View here. This includes freeing resources from
    //! memory.
    function onHide() {
    }
 
}

This should display an output like as shown in the image below.
I am assuming that the comments in the source code are self explanatory. As you can see that in the onUpdate() method we are trying to draw texts on the UI using dc.drawText(). Here the object dc represent the Device Context of the wearable device and is an object of Class: Toybox::Graphics::Dc. This class has few more methods to draw different kind of graphical shapes or text. In the end of this method we requested a UI update by calling UI.requestUpdate() which indirectly request the UI update from the current View by calling onUpdate(). At this point we are left with receiving the calendar data from mobile and displaying it 15 mins prior to the meeting time in our watch. Now lets set up the infrastructure to receive messages from the mobile app and setting up a timer which checks for a meeting occurrence at regular intervals. If you refer to the documentation of Class: Toybox::WatchUi::View there is a method called initialize() which acts as a constructor. Which means we can add a method called initialize in CalendarAlertsView class which can initialize the basic stuff like setting up the communication infrastructure and initializing the timer to scan upcoming meetings. So lets add this initialize() method to CalendarAlertsView.mc.
       var count=0;
       var meetingsArray= new [100] ;
       var timer;
       var app;

   function initialize() {
              // when a message is received over Bluetooth LE it would be received by the onMail method described below
              Comm.setMailboxListener( method(:onMail) );
              Comm.emptyMailbox();
              app=App.getApp();
              
              //this method is described below
              checkForUpcomingMeetings();
              timer = new Timer.Timer();
              //the method checkForUpcomingMeetings will be called at an interval of every 30 seconds
              timer.start( method(:checkForUpcomingMeetings), 1000*30, true );
       }


  function checkForUpcomingMeetings() {
          Sys.println("Checking for meetings");
       }

  function onMail(mailIter)
    {
         var  mail = mailIter.next();
        while( mail != null )
        {
             count++;
            
           //the variable 'mail' would contain a comma separated information about each meeting, create a MeetingAlert object out of it
            var meetingAlert = new MeetingAlert(mail);
            
           // store the meeting alerts for next 3 days stored in an in-memory array of MeetingAlerts
            meetingsArray[count]=meetingAlert;
            mail = mailIter.next();
        }
        Comm.emptyMailbox();
        return true;
    }
   
The method initialize() registers onMail() method as a mail box listener by calling Comm.setMailBoxListener. Mail box is a virtual place where messages sent over Bluetooth LE will arrive and on receipt of the same it invokes the listener method - in our case the onMail() method. Then we create a Timer which executes a method checkForUpcomingMeetings at a regular interval of 30 seconds. The Timer works in a similar way as setInterval method in Javascript or a TimerTask in Java. Right now the method checkForUpcomingMeetings just prints a single statement "Checking for meetings" on the console. However if you try to run this, your app wont start because you need to grant the necessary permission to the app for communicating over Bluetooth LE which can be done by adding following lines in your manifest.xml file.
        
            
        
 
If you run your application now it should show the watch app with a message "Upcoming Meetings - None in next 15 mins" and should print "Checking for upcoming meetings" every 30 seconds.
In next part of this tutorial we will setup our Android app to pass on the meeting information over Bluetooth LE to our watch widget.

Thursday, June 30, 2016

Developing Garmin SmartWatch Apps with ConnectIQ Platform-Part 1

Recently I was involved in developing apps for Gramin Wearables. Being new to the wearables world I found it relatively easier to develop apps for Garmin Wearables then what I had thought earlier. Hence I would like to share my experience via this blog series. I will take you through the step by step process of developing a simple watch widget that synchronizes with an Android phone's Google Calendar to send out meeting alerts and reminders on your Garmin Watch.

Apps for Garmin Wearables are developed using the Garmin ConnectIQ SDK  and are programmed using Monkey C language . You are already familiar with Monkey C if you are familiar with languages like Java or Objective C. Introduction to Monkey C language  highlights the basic difference between other languages and Monkey C. Its a short and precise tutorial, I would suggest to give a quick read in case you are planning to develop apps for Garmin.

The Problem Statement
Lets say you own an Android Phone and you have configured your Google Calendar to show meetings,events or reminders from your Google Account or may be MS Outlook using exchange services. The watch widget that we will develop will be responsible to send out alerts for these calendar events 15 minutes prior the event time, on your Garmin Watch.

The Basics
Before we proceed further, you need to know a few things that are applicable to the Wearables world.

  1. Most of the wearables does not have direct access to internet. Especially those which don't come with a SIM card slot. Same is applicable to Garmin Wearables.
  2. Communication with a web service over internet is only possible if a communication channel is established with a SmartPhone (Android or iOS) over Bluetooth LE protocol.
  3. Garmin comes with Android and iOS Mobile SDK's that helps you communicate with your mobile device easily.  These SDK's can be used to exchange data over Bluetooth Low Energy(BLE) with your phone easily and watch vice-versa.  The Android SDK is just a  JAR file to be included as part of your Android Project, which contains a bunch of Classes that helps you send and receive data over BLE.
  4. If you are capturing activity data using wearables then you need to store it into a temporary store until the user sync's the wearable device with a smartphone that can establish an internet communication to upload data over to web service. The storage space on wearable device is limited so you need to take care that the format of stored data is as precise as possible. Storing in XML is not a preferred way as the format is too verbose. JSON is still okay only if required. I would prefer comma separated string values or enums. 
  5. Same concept applies while transferring data from a Mobile phone to a watch. Bluetooth Low Energy is relatively slower, the amount of time taken to transfer a bigger chunk of data will take long. I would prefer comma separated strings over other formats here as well.
  6. Using Garmin SDK you can create different type of apps viz. a watch widget, a watch face, a data field or a watch app. Watch faces are the ones which are responsible to show time, you can choose to develop a customized watch face which is more graphically attractive however a watch face doesn't have access to communication API's to communicate over BLE or to access sensor data recorded by inbuilt sensors of a watch. A watch widget is like a card that resides on your main watch carousel it has ability to communicate over BLE with your smartphone and process data in background, it also has access to sensor data. Watch Apps are accessed on request basis and have much wider permissions as compared to a watch face and a widget, it can read data from ANT+ sensors. Data fields are basically apps that present captured activity data of a user in a creative way.
 As part of this blog series I am gonna create a watch widget to show calendar alerts which beeps and flashes the meeting/event details 15 minutes prior to the event time.
Setting up the environment
I am using Eclipse IDE with the ConnectIQ Plugin to develop the Garmin Watch App/Widget and Android Studio for developing the corresponding Android App. The ConnectIQ Eclipse plugin can be installed using the Eclipse update site http://developer.garmin.com/downloads/connect-iq/eclipse/. For more details see http://developer.garmin.com/connect-iq/getting-started/.

Jumping Right In
 Assuming that you are done setting up the environment. 
  1. Create a new ConnectIQ Project in Eclipse as shown in the screenshot below and lets name it CalendarAlerts.

  2. Choose the Project type as "Widget" and select appropriate target platforms.
  3. Select the default project template and click next.
  4. Select the supported languages for your app/widget.
  5. Click Finish to see the project created in the project explorer in Eclipse.
  6. To verify, run the project by Right Click->Run As-> Connect IQ App
  7. Choose Appropriate Device to Simulate
  8. You should see a widget displaying image of a monkey in the ConnectIQ Device Simulator.
At this point you should be done setting up everything that is required to start working on the actual app. In the next part of this blog series, we will modify this app that we just created to do what we described in the problem statement above.

Monday, May 2, 2016

Building Secure RESTful Webservices

Recently I delivered a webinar on "Building Secure RESTFul Webservices" on Techgig which received a very good feedback based on the Techgig survey. The webinar column was published on Gizmodo India as well.

Here is a list of key takeaways from the webinar

  • How HTTPS work in detail and how to implement HTTP BASIC Authentication.
  • What is Mutual SSL Authentication and how to implement it.
  • What kind of damage can be done with security attacks like Man in the Middle and Replay Attack. 
  • Authenticating user without passing credentials over the wire
  • Preventing Man in the Middle attacks using Signature verification
  • Preventing Replay Attacks using timestamp and cryptographic nonce
  • What are OAuth 1a and OAuth 2

The code samples (written in Java) related to this webinar can be found at 


I am embedding the webinar recording for quick access below.


Building Secure RESTful Web Services from Techgig on Vimeo.