PhoneGap JavaScript API Vs Native Components (Plugins)

In the world of Apps building an App for one device might not be enough for you to conquer the mobile world while building Apps for each platform individualy is time consuming and not so cost effective. Here comes PhoneGap to the rescue. PhoneGap is a platform for developing cross platform Apps, it uses HTML 5, Javascript and CSS. PhoneGap follows open source standards.

This allows developers to develop amazing apps for free, and can easily run on any mobile platform.

Building applications for each device–iPhone, Android, Windows Mobile and more- requires different frameworks and languages. PhoneGap bridges Web Applications and Mobile Devices using Standards-based Web technologies.

PhoneGap has two Components :

1. The PhoneGap Core Libraries are designed to handle common tasks supported by most devices-

a) Access geolocation from the PhoneGap JavaScript API

b) Access contacts from the PhoneGap JavaScript API

c) Invoke a call

2. PhoneGap’s JavaScript API makes those common phone functions available to JavaScript to run in the Browser (Native WebView).

Along with its Cross-platform Advantage PhoneGap comes with following Limitations:

i) Writing Javascript to do heavyweight data processing will typically be much slower than writing native code for the device and serving the results to a front-end.

ii) If we want to do some background processing (e.g. background services in Android), Javascript cannot achieve it.

iii) Similarly, if we plan to implement a very Complex Business Functionality, a preference would be given to the native language.

For such complex tasks, it is best to delegate the responsibility to Native Components.

Extend PhoneGap Framework – Create Native Components (Plugins)

The solution to the Limitations is to:

1. Create a Custom Native Component (Plugin): This Native Component(Plugin) would be built for each platform you plan to support.

2. Create a Custom Javascript API: All these Native Components (Plugins) needs to adhere to the Custom JavaScript API, which exposes their functionality to the JavaScript running in the Browser.

Thus, overall PhoneGap Architecture becomes:

phonegap architecture

They are Not Cross Platform:

Suppose you are developing a PhoneGap Plugin for two platforms: iOS and Android, you need-

1. One JavaScript file for Android, along with a Java file(Native Component) for Android.

2. A different JavaScript file for iOS, along with pair of .h and .m files (Native Components) for iOS.

Both JavaScript files can (and should) have the same interface for the developer who consumes it, but the implementations of each interface would be different.

Developing Android PhoneGap Plugin:

Regardless of which platform you begin developing with, following two methods play the key Role:

1. PluginResult.execute() is your core Native function: The JavaScript that you will write in your JS plugin will need to call Phonegap.exec (successCallback, failCallback, pluginName, action, [args]). That’s a JavaScript function, found in phonegap-version.x.x.js (or cordova-1.7.0rc1.jar or higher) that expects a function named “execute” on the Native Plugin side.

2. Phonegap.exec() is your core JS function: The Native Plugin need to define one call to Phonegap.exec() on the JS side.

“CopyImagesPlugin”: This plugin lets you copy any number of image resources form assets to the Device SD-Card.

Step 1: Create a new PhoneGap Project (along with all PhoneGap dependencies) using New Project Wizard in Eclipse. If You have not installed PhoneGap Development Addin to eclipse, then you can do it in following manner:

Open Eclipse -> Click on ‘Help’ on MenuBar-> ‘Install New Software’ ->

click on ‘Add’ button at new Window-> and copy following url to Location field:

https://svn.codespot.com/a/eclipselabs.org/mobile-web-development-with-phonegap/tags/r1.2/download

Give any name to Name Field. E.g. ‘Phonegap Addin Tool’

Click on ‘ok’ button this will start downloading al required Softwares.

Click ‘Next’ and finish the installation Wazard.

It will ask to Restart Eclipse and eclipce toolbar now includes PhoneGap icon as shown in below image:

eclipse phonegap

Step 2: Implement the Plugin Class: “CopyToSdCard”

/**
* Android PhoneGap Plugin to Copy images form Assets to SD-Card
*/
package com.phonegap.plugins.test;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.json.JSONArray;
import org.json.JSONException;
import android.util.Log;
import com.phonegap.api.Plugin;
import com.phonegap.api.PluginResult;

public class CopyToSdCard extends Plugin
{
@Override
public PluginResult execute(String action, JSONArray args, String callbackId) {

if (!action.equals(“copyFiles”))
return new PluginResult(PluginResult.Status.INVALID_ACTION);

try {
String arr_length = args.getString(0);
String fileUrl =args.getString(1);

String fileName = args.getString(1);

String dirName =
“/mnt/sdcard/”+args.getString(2);

Boolean overwrite =false;

return this.downloadUrl(fileUrl, dirName, fileName,Integer.parseInt(arr_length), overwrite, callbackId);

} catch (JSONException e) {

e.printStackTrace();
return new PluginResult(PluginResult.Status.JSON_EXCEPTION, e.getMessage());

} catch (InterruptedException e) {
e.printStackTrace();
return new PluginResult(PluginResult.Status.ERROR, e.getMessage());
}

}

private PluginResult downloadUrl(String fileUrl, String dirName, String fileName,int arr_length, Boolean overwrite, String callbackId) throws InterruptedException, JSONException {

try {
if(dirName.equalsIgnoreCase(“null”))
return new PluginResult(PluginResult.Status.OK, “invalid”);

Log.d(“PhoneGapLog”, “Copying “+fileUrl + ” into ” + dirName + “/” + fileName);

for(int index=0;index<arr_length-2;index++)
{
File dir = new File(dirName);
if (!dir.exists()) {
Log.d(“PhoneGapLog”, “directory ” + dirName + ” created”);
dir.mkdirs();
}
String name=”image_”+index;
if(index==0)
{
continue;
}
File file = new File(dirName, name+”.jpg”);

if (!overwrite && file.exists()) {
Log.e(“SaveToSdCardPlugin”, “File already exist”);
return new PluginResult(PluginResult.Status.OK, “exist”);
}

InputStream is=CopyToSdCard.this.ctx.getAssets().open(“www/images/” +name+”.jpg”);
byte[] buffer = new byte[1024];
int readed = 0,
totalReaded = 0;

FileOutputStream fos = new FileOutputStream(file);

while ((readed = is.read(buffer)) > 0) {

fos.write(buffer, 0, readed);
totalReaded += readed;
}
fos.close();

Log.e(“PhoneGapLog”, “Copy finished”);

}
return new PluginResult(PluginResult.Status.OK, “done”);

}
catch (FileNotFoundException e) {
Log.e(“PhoneGapLog”, “File Not Found: ” + e);
return new PluginResult(PluginResult.Status.ERROR, 404);
}
catch (IOException e) {
Log.e(“PhoneGapLog”, “Error: ” + e);
return new PluginResult(PluginResult.Status.ERROR, e.getMessage());
}

}
}

Step 3: Implement Plugin JavaScript

1. Create a file called copyToSdCard.js

2. In it create a class named CopyToSdCard.

3. Create a member function named copyFiles ().

4. In copyFiles () function call PhoneGap.exec(<>, <>,<>,<>,<>);

5. Finally register both CopyToSdCard class as an JavaScript Plugin and register Java Class as the native Plugin (invoked from Javascript)

Below is the complete Source code for copyToSdCard.js file:

function CopyToSdCard() {}

Downloader.prototype.copyFiles = function(index,fileUrl,dirName, params, win, fail) {

//Make params hash optional.
if (!fail) win = params;
PhoneGap.exec(win, fail, “CopyToSdCard”, ” copyFiles”, [index,fileUrl,dirName, params]);
};

PhoneGap.addConstructor(function() {
PhoneGap.addPlugin(“CopyImagesPlugin”, new CopyToSdCard());
/*’CopyImagesPlugin’ is the name with ‘CopyToSdCard’ Plugin is registered in res/xml.plugins.xml
*/
});

Installing Plugins for Android

On Android, the plugin Java source code needs to be included in your PhoneGap Android project either in source form or as a JAR library.

In addition, the JavaScript for the plugin needs to be added to the ./assets/www/* folder of your PhoneGap Android project and linked in your HTML source code.

Finally an additional element needs to be added to the ./res/xml/plugins.xml file. The plugins.xml file describes what plugins are allowed to be called from JavaScript.

Step 4: Register plugin to res/xml/plugin.xml file:

 

Step 5: Add following javascript reference to your html file:

 

Step 6: Add following javascript code to html file:



 

Finally, call the above javascript method saveToSdFromAssets () from your Html file say on a button click as below:

Save to SD Card

Similarly, The same plugin can be developed for iOS and other mobile Platforms in respective Native Language (in case of android its Java).

At TechAhead, we have experience of creating cross platform mobile apps for our clients. If you have any requirement for cross platform mobile application development, contact us on info@techaheadcorp.com for FREE 30 minutes no obligation consultation with our mobile apps experts($200 Value).

Credits: wiki.phonegap.com

By Vinay M Joshi Vinay works as a Senior Android Developer at TechAhead Software, a leading Mobile & Web Application Development company which helps brands to reach, connect, interact with their audience through web and mobile effectively. With over 2+ years of experience in Android Development, he is a technology enthusiast and has a passion for writing.