Home

Development with cordova / phonegap

Updated:
Created:

Getting started with cordova / phonegap

tl;dr

I am impressed with the ease and speed of mobile app develpment using cordova. My choice is using cordova 3.3, and I debug using weinre and 'cordova browser 3'.

What's what?

When I started, my first question was: whats the difference between phonegap and cordova? The answer is: cordova is the core technology, the toolset and everything. This is what I need for my app development. Phonegap is a layer on top. Phonegap is (nowadays) a wrapper around cordova, that also allows using adobe's cloud service for compiling apps.

Historically phonegap was the name for the whole project, but that has changed. Lots of documentation can be googled using the name phonegap though.

In the end I started using cordova alone, because I don't need the whole phonegap overhead.

Oh, there are also two different versions: 2.x and 3.x. 3.x seems to be the way forward, but lots of documentation on the webs is still for 2.x. It was recommended to me to use 3.x though. No support for 2.x anymore.

Documentation

Official documentation is on http://docs.phonegap.com

Initial setup

First install the java and the android skd on your system. Next, get nodejs. Once that is running, cordova can be installed to it. I do a local installation, so that I can have seperate node versions for testing.:

mkdir -d ~/projects/phonegap
cd ~/projects/phonegap
wget http://nodejs.org/dist/v0.10.26/node-v0.10.26.tar.gz
tar xf node-v0.10.26.tar.gz
cd node-v0.10.26
./configure --prefix=~/projects/phonegap/node
make
make install
cd ..
./node/bin/npm install -g cordova

And thats it. You now have a cordova command available. I would recommend putting the node/bin directory somehow on your path. I have used the script 'activate', which is usually used in python virtualenvs for that. Please set the path on line 42 correctly. Call it with source activate. Now you can type cordova everywhere. To get rid of the path setting (and the prompt) just type deactivate.

I assume that cordova is on your path from now on.

Development

Setup

First thing is to create a new project:

cordova create directoryname your.domain.project ProperName

This will create a project in directoryname. The app will have 'your.domain.project' as its internal name. Its reversed domain order, e.g. 'de.baach.project'. This shouldn't change over time. 'ProperName' is the full name of the project.

Once you have that, 'normal' html development can start. You will want to edit the stuff in the www directory (within the project directory). Have a look at index.html - this is the file thats shown in your app. All the html belongs in there. Please notice the inclusion of the 'cordova.js' file in there. Without that the nice cordova features won't be available!

You need to seperately add deployment platforms to the project:

cordova platform add android

This will add e.g. android. The only platform that I use atm.

In phonegap 3.x you need to seperately add the apis you want to use to your project. You find the apis listed on the offical documentation. Within the root of your project you call e.g.:

cordova plugin add org.apache.cordova.media

to have the 'Media' api available in your project.

This will do all kind of things under the cover, e.g. modify some content in the platforms directory. For android you might want to check that the necessary permission entries are added to platforms/android/AndroidManifest.xml

Building

Darn easy. In the root of the project type:

cordova build

This will regenerate the platform specific stuff (e.g. platforms/android/assets/www) will be regenerated. The whole thing will be compiled, and the apk ends up in 'platforms/android/bin'. The debug apk can then be transferred to your phone.

It might be that the apk gets automatically signed with some form of developer key. Need to check this. If in doubt, sign it like described below.

Releasing

To create a release version (e.g. for google play) one needs to first set to modify the AndroidManifest.xml in platforms/android. Set:

android:debuggable="false"

Next step is to build and compile a release version. In the root of your project:

cordova build --release

After this, you will need to sign the apk with your key. If you don't have a key, create a keystore like this:

keytool -genkey -v -keystore my.keystore -alias keyname -keyalg RSA -keysize 2048 -validity 10000

'my.keystore' is the name of the storage files for the keys. 'keyname' should be set to a name for the key you want to use. Please make sure you keep the keystore (and the password). Only this key can sign subsequent versions of your apk. Without that key, no direct updates of the app are possible. (I think the id of an app is calculated from 'your.domain.project' and the public key id).

After that the apk needs to be signed, and the signature can be verified:

jarsigner -keystore /path/to/my.keystore -digestalg SHA1 -sigalg MD5withRSA Projectname-released-unsiged.apk keyname
jarsigner -verify  Projectname-released-unsiged.apk

After this some bits need to be aligned (no idea what this is, sound like polishing bits to me):

zipalign -v 4 Projectname-released-unsiged.apk Projectname.apk

'Projectname.apk' can now be uploaded to the play store or distributed directly.

Debugging

For me the biggest issue was to find out how to best debug the applications while developing. I am very much used to a 'write some lines, reload, check, repeat' work cycle. Everything else feels very annoying to me. So going through the whole process of building, signing and installing on a physical phone seems a bit hard to me.

Android Emulator

The first idea is to use googles android emulator, that comes with the sdk. Very short version: forget it. Longer version: its way too slow. As in: takes minutes to start. Horrible. (might be accurate though).

Ganymotion Emulator

One thing the google android emulator is good for is for leanring to appreciate the spped of ganymotion (http://www.genymotion.com/). Wow, is this fast. A phonegap application can be installed there. For me the graphics seemed to be borked, but just clicking into the 'phone display' solved the problem for me. Supposedly one can use the android adb tool to directly build an app and send it to the emulator. While ganymotion is fast, the whole compiling and reinstalling on the emulated phone still sounded to slow for me. Hence I haven't tried the adb linkup yet.

Ripple Emulator

The ripple emulator is an addon for chrome of sorts. You can install it using node:

npm install -g ripple-emulator

This will allow you to run (from the root of your project):

ripple emulate

This will open a url in chrome (if its in firefox, copy it to chrome). You will see an 'emulated' device, and you can hit reload to get updates from your project/www directory. Pretty much like normal web development. Three downsides though. First, there are some tiny quirks, e.g. chromium/chrome won't play certain mp3s that the phone will play. This can be ackward. Second, there doesn't seem to be a proper console for directly accessing the javascript objects within your running phonegap app. Third, it manipulates url calls you make in your app. Uses some form of proxy, and this sometimes breaks the app for me. And you can't use weinre with it, it seems.

Weinre

Weinre (http://people.apache.org/~pmuellr/weinre/docs/latest/) is a remote javascript debugger. It allows debugging of your running app on another machine. Doesn't seem to matter too much where you have the app running. It seems that your app, e.g. on the phone or just some normal js in a browser, will connect to a little weinre server, and you then use chrome to connect to said server.

To install the server, run:

npm install -g weinre

The server can then be called:

weinre --boundHost -all-

This will make it listen to all ips. Next, make sure you have the following js line at the top of your app/index.html:

<script src="http://a.b.c:8080/target/target-script-min.js"></script>

Now connect with your browser to it, e.g http://localhost:8080/. Go to the first link to the 'debug client user interface'. Voila.

I find this a fantastic utility, and it even works with apps that you have running on a physical phone. For me this is the way to go. In combination with the cordova browser.

Cordova Browser

Evan Shapiro created a little phonegap app to run on android. This is effectively a minimalistic browser that allows to call remote webpages, and give them full access to the phonegap/cordova api. You can then press 'menu' and refresh the page, to basically reload the page. This means you can use a physical device as the development browser. Full speed development on a real device. Hurray!

I've upgraded his application (https://play.google.com/store/apps/details?id=com.eas.cordova.browser) to use the current cordove 3.3 version. You can find my current version on https://play.google.com/store/apps/details?id=de.baach.cordovabrowser3 .

In order to serve your app, you can either serve, with the webserver of choice, the files in platforms/android/assets/www. You might need to update the files in this assets/www directory after you have done changes to the main project/www directory. You update with:

cordova prepare

Or you use cordova to serve the files:

cordova serve

Then you can add e.g. http://your.machines.ip.address:8000 to the cordova browser, and off you go. It seems you need to restart the cordova server though when you have updated files in project/www.