Editor’s note: We found an interesting series of articlesLearn 30 New Technologies in 30 Days, ready for translation, one update a day, year-end gift package. Here’s day 10.


Today is another “30 new skills in 30 days” day. For a long time, I found mobile development scary because most apps don’t have a business model. In fact, writing mobile apps has never been exciting to me. However, given how fast the mobile space is growing and how many more people are accessing the Internet on their phones rather than on the desktop, I decided to give mobile development a try. My mobile development journey will start with PhoneGap.

This article starts with the basics of PhoneGap, and then we develop a mobile application using PhoneGap.

Mobile application

We’re going to develop a mobile reader for “Learn 30 new technologies in 30 days.” Users can install the app on Android, Symbian, WebOS or Windows devices. The mobile application can be downloaded at https://build.phonegap.com/apps/635001/share.

This app does:

Gives a list of all published articles in the series. The user clicks on an item in the list and invokes the browser to open the link.

Readers can use the app to contribute ideas.

What is PhoneGap?

PhoneGap is a free and open source mobile development framework that uses standard web technologies, namely HTML, CSS and JavaScript, for mobile application development.

It encapsulates your application’s Web resources in native apps that can be submitted to the major app stores. More importantly, we can use PhoneGap to develop cross-platform mobile apps. This means that, in an ideal world, you can write a mobile application once and port it to multiple platforms. For example, I wrote this app for Android devices, while using PhoneGap build, I packaged the app for other devices as well. Most of the standard device features, such as photography, geolocation, storage, and so on, are provided by JavaScript APIs. Depending on the target device, PhoneGap provides a different JavaScript API.

Facts about PhoneGap:

  1. In 2009, Nitobi developed the PhoneGap framework.
  2. In October 2011, Adobe bought the company behind Nitobi (PhoneGap).
  3. Adobe is contributing PhoneGap to the Apache Foundation.
  4. The open source project is named Apache Cordova.
  5. PhoneGap is an implementation of Apache Cordova, an open source project completed by Adobe. At its core, PhoneGap uses Apache Cordova.
  6. PhoneGap uses a plug-in based architecture. All device features are provided as plug-ins. In this article, we’ll use a few plug-ins.

Why do I care about PhoneGap?

  1. There is no need to learn a native development environment for each platform. The cross-platform nature of PhoneGap can save developers a lot of time and effort if they intend to target multiple platforms. I know HTML, CSS, and JavaScript and can get into the mobile world very smoothly.

  2. PhoneGap is great for developing CRUD mobile applications based on REST APIs.

  3. It does not force developers to choose a particular CSS library. Developers can use any mobile library they like. I used jQuery Mobile in this application.

PhoneGap Prerequisites

PhoneGap relies on NodeJS and we need to install PhoneGap using NPM. Npm is the package manager for NodeJS, and new versions of NodeJS come with Npm. You can download the latest version of NodeJS from the website.

You need to install the SDK for the target machine as well. For example, if we are creating an Android application, we need to install the Android developer tools on the operating system. PhoneGap uses the SDK to build packages for the target platform.

PhoneGap start

Install PhoneGap with the following command:

sudo npm install -g phonegap

The above command installs the PhoneGap package globally so that it can be used in any directory.

Installing the plug-in requires Cordova to be installed.

Use the following command to install Cordova.

sudo npm install -g cordova

Making the warehouse

The code for today’s demo application is on GitHub.

Create a PhoneGap application

The PhoneGap command line provides commands to create a new PhoneGap project using a template:

phonegap create reader --id io.reader --name Reader30

The above command creates a reader directory.

Reader and Reader30 are optional: Reader provides an anti-domain identifier, and Reader30 provides the display text for the application.

The file structure applied is as follows:

Let’s look at these generated directories:

  1. mergesFolders hold resources that are specific to a particular platform. For example, we might usemergesTo change the font size for Android devices.
  2. platformsThe directory holds the platform build files.
  3. pluginsHouses the plug-ins used by the application. When we install a plug-in, it will be stored in this directory.
  4. wwwDirectories hold application resources, for examplehtml,css,jsandimg. This is the catalog we spend the most time on.config.xmlContains the meta information needed to generate and distribute the application. Meta-information also includes application name, description, author details, application permissions, and so on. inHere,You can see a complete list.

To run the application on Android, run the following commands:

phonegap run android

This is the first build of our Reader app for the Android platform. If you have a real device connected, your app will run on a real device. If no device is present, the Android Virtualizer is launched and the application is deployed to the Virtualizer.

Note: The performance of the Android Virtual Device is pretty lame, so I recommend that you always connect to your real device. Grant Shipley’s blog provides some information on how to speed up the Android virtual.

Developing mobile apps

As mentioned above, our application has two pages. Let’s develop the first one.

Blog list

The initial page shows a list of all published articles. Let’s change index.html to copy CSS and JavaScript resources from my GitHub repository.

<! DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <title>Learn 30 technologies in 30 days</title> <link Rel = "stylesheet" href = "CSS/vendor/jquery mobile - 1.3.1. Min. CSS" > < link rel = "stylesheet" href="css/vendor/jquery.loadmask.css"> </head> <body> <div data-role="page" id="mainPage"> <div data-role="header" data-position="fixed"> <h1>30Technologies30Days</h1> <a href="#feeback" data-icon="edit" data-theme="b" class="feedback ui-btn-right" data-role="button" data-inline="true" data-ajax="false">Feedback</a> <div data-role="navbar"> <ul> <li><a href="#home" class="home ui-btn-active" data-icon="home">Home</a></li> </ul> </div> </div> <div id="main" Data -role="content"> </div> <div data-theme="a" data-role="footer"> <h3> © Shekhar Gulati 2013 </h3> </div> </div> <script type="text/x-mustache-template" id="home-template"> <ul id="blogs" data-role="listview" data-filter="true" data-filter-placeholder="Search blogs..." data-inset="true"> </ul> </script> <script type="text/x-mustache-template" id="blog-template"> <li> <a href="{{url}}" target="_blank"> <h3>{{title}}</h3> <p><strong>{{publishedOn}}</strong></p> </li> </script> <script SRC = "phonegap. Js" > < / script > < script SRC = "js/vendor/jquery - 1.9.1. Min. Js" > < / script > < script SRC = "js/vendor/jquery. Mobile - 1.3.1. Min. Js" > < / script > < script SRC = "js/vendor/jquery UI. Map. Js" > < / script > < script src="js/vendor/jquery.loadmask.min.js"></script> <script src="js/vendor/jquery.timeago.js"></script> <script type="text/javascript" src="js/vendor/mustache.js"></script> <script type="text/javascript" src="js/app.js"></script> </body> </html>

The HTML above imports the required CSS and JavaScript files. It uses jQuery Mobile for native effects. We also defined a Mustache template to render the list.

The application-related JavaScript code is placed in the app.js file:

$(document).ready(function(){ homeView(); $('.home').on('tap', renderHomeView); $('.feedback').on('tap', renderFeedbackFormView); }); function renderHomeView(event){ event.preventDefault(); homeView(); } function homeView(){ $('#main').empty(); $('.home').addClass("ui-btn-active"); $('#main').html(template("home")); var url = 'http://30technologiesin30days-t20.rhcloud.com/api/v1/blogs'; $.mobile.loading( 'show',{}); $.ajax({ url : url, dataType : 'json', success : function(data){ $.mobile.loading( 'hide',{}); $.each(data , function(i , obj){ var template = $("#blog-template").html(); obj.publishedOn = $.timeago(obj.publishedOn); $("#blogs").append(Mustache.to_html(template,obj)); $('#blogs').listview('refresh'); }); }, error : function(XMLHttpRequest,textStatus, errorThrown) { $.mobile.loading( 'hide',{text:"Fetching blogs.." }); alert("Something wrong happended on the server. Try again.." ); } }) $('#main').trigger('create'); } function template(name) { return Mustache.compile($('#'+name+'-template').html()); } function showNotification(message , title){ if (navigator.notification) { navigator.notification.alert(message, null, title, 'OK'); } else { alert(title ? (title + ": " + message) : message); }}

The app.js above does this:

  1. The ready event is bound to the document. Once in place, the initial page is rendered.

  2. The initial page makes a REST call to retrieve all the blogs. We use jQuery to call REST.

  3. After receiving the information, we create a list. Finally refresh.

Allow access to REST services

By default, PhoneGap does not allow applications to access remote resources. This means that the application cannot make REST calls. To allow an application to make REST calls, we need to allow it access. We can use the wildcard * to allow our application access to all resources. See the documentation for more information.

Modify access control information under config.xml:

<access origin="*" />

Installing a plug-in

Applications use plug-ins to access device-specific features.

cordova plugin add org.apache.cordova.geolocation
cordova plugin add org.apache.cordova.dialogs
  1. The first command installs the geolocation plug-in. Geolocation provides information about the location of the device, such as longitude and latitude. We will use this feature later. See the documentation for more information.

  2. The second command installs the dialogs plug-in. The Dialogs plugin provides native visual reminders of the device. See the documentation for more information.

Feedback Submission Form

The second screen allows the user to submit feedback.

We added a feedback form to record user feedback.

<script type="text/x-mustache-template" id="feedback-form-template"> <form action="" id="feedbackForm"> <div data-role="fieldcontain"> <label for="name"> Describe </label> <input type="text" name="name" id="name" placeholder="Full Name eg. Shekhar Gulati "> </div> <div data-role="fieldcontain"> <label for="description"> Describe </label> <textarea name="description" id="description" placeholder="Message for author.." ></textarea> </div> <div id="checkboxes1" data-role="fieldcontain"> <fieldset data-role="controlgroup" data-type="vertical"> <legend> Share my location </legend> <input id="sharemylocation" name="sharemylocation" type="checkbox" value="true"> <label for="sharemylocation"> Share </label> </fieldset> </div> <button id="create-button"  data-inline="true">Feedback</button> </form> </script>

Modify the app.js file and listen for tap events.

$(document).ready(function(){ homeView(); $('.home').on('tap', renderHomeView); $('.feedback').on('tap', renderFeedbackFormView); }); function renderFeedbackFormView(event){ event.preventDefault(); $('#main').empty(); $('#main').html(template("feedback-form")); $('#main').trigger('create'); $('#create-button').bind('tap',shareFeedback); } function shareFeedback(event){ event.preventDefault(); $('#feedbackForm').mask(); var name = $('#name').val(); var description = $('textarea#description').val(); var sharemylocation = $("#sharemylocation:checked").val() === undefined ? "false" : "true"; var data = {name:name , description:description , lngLat :[]}; if(sharemylocation === "true"){ navigator.geolocation.getCurrentPosition(function(position){ var lngLat = [position.coords.longitude , position.coords.latitude]; data.lngLat = lngLat; postFeedback(data); } , function(error){ alert('code: ' + error.code + '\n' + 'message: ' + error.message + '\n'); $('#feedbackForm').unmask(); }); }else{ postFeedback(data); } } function postFeedback(data){ $.ajax({ type : 'POST', url : 'http://30technologiesin30days-t20.rhcloud.com/api/v1/feedback', crossDomain : true, data : JSON.stringify(data), dataType : 'json', contentType: "application/json", success : function(data){ $('#feedbackForm').unmask(); $('#feedbackForm')[0].reset(); showNotification('Received your feedback', 'Info'); homeView(); }, error : function(XMLHttpRequest,textStatus, errorThrown) { $('#feedbackForm').unmask(); alert("Error status :"+textStatus); alert("Error type :"+errorThrown); }}); }

When the feedback form is submitted, we get the data from the form. If the user has checked “Share My Location”, we use the geolocation plug-in to get the user’s location. Finally, we submit the POST request to our REST service. Once a successful submission is made, we display a reminder.

Run the application

Now we are ready to install and run the application on the device. Use the following command:

phonegap run android

That’s all for today. Give back.


Day 10: PhoneGap–Mobile Development for the Dummies