PhoneGap Plugin : Programmatically adding dynamic native options menu on Android

We have been working on a PhoneGap based mobile application. PhoneGap allows wrapping HTML5 based applications as native applications for iOS, Android, Windows Phone and other platforms. So what you can do is, develop one web application that can be delivered as a native application on several mobile platforms. To provide the user experience of a native application, PhoneGap also has a plugin framework that can be used for calling native functionality like camera, photo gallery, location from JavaScript in the web application.

We needed a plugin for showing native Android menus from the JavaScript, with a further requirement being that the image and text of these menus would be specified in the JavaScript call dynamically, so that web application may show different native Android menus on different screens. The purpose of this article is to help those who want to achieve this dynamic options menu in Android, and this can be useful not only on PhoneGap based application, but also for programmatically creating option menus in native Android applications.

Step 1: Create the JavaScript API for the PhoneGap plugin

if (typeof PhoneGap !== "undefined") {
	/**
	 * Constructor
	 */
	function Tab() {
		this._callback;
	}

	/**
	 * show - Add options menu dynamically.
	 */
	Tab.prototype.show = function(options, cb) {

		this._callback = cb;
		return PhoneGap.exec(cb, failureCallback, 'TabPlugin', 'show', options);
	};

	Tab.prototype.hide = function(options) {
		return PhoneGap.exec('', '', 'TabPlugin', 'hide', options);
	};

	function failureCallback(err) {
		console.log("tabPlugin.js failed: " + err);
	}

	PhoneGap.addConstructor(function() {
		if (!window.plugins) {
			window.plugins = {};
		}
		window.plugins.tab = new Tab();
	});
};

Step 2: Now the main plugin class that will be called from the JavaScript API above. It parses the JSON to get the text and images to be displayed and saves these in SharedPreferences.

public class TabPlugin extends Plugin {

	public static final String OPTION_MENU = "menu";
	public static final String ME = "TabPlugin";
	public static final String prefName = "TabPlugin";

	@Override
	public PluginResult execute(String action, JSONArray data, String callbackId) {

		if (action.equalsIgnoreCase("show")) {
			this.show(data, callbackId);
		return new PluginResult(PluginResult.Status.OK, "ok");
	}

	public synchronized void show(final JSONArray tabItems, String callbackId) {

		JSONObject jsonObject = new JSONObject();
		try {
			jsonObject.put(OPTION_MENU, tabItems);
			String menu = jsonObject.toString();

			SharedPreferences settings = ctx.getApplicationContext().getSharedPreferences(prefName, 0);
			SharedPreferences.Editor editor = settings.edit();
			editor.putString(OPTION_MENU, jsonObject.toString());
			editor.commit();

		} catch (JSONException e) { // Do error checking }
	}


}

Step 3: Call to the plugin’s show function with the images and text required

showTabBar: function() {
var menus = [
						{
							"image" : "http://xxxxxx.com/home_tab.png",
							"name" : "Home",
							"jsCall" : "document.location = 'http://xxxxxx.com/home.html';"
						},
						{
							"image" : "http://xxxxxx.com/profile_tab.png",
							"name" : "Profile",
							"jsCall" : "document.location = 'http://xxxxxx.com/profile.html';"
						},
						{
							"image" : "http://xxxxxx.com/messages_tab.png",
							"name" : "Messages",
							"jsCall" : "document.location = 'http://www.xxxxxx.com/messages.html';"
						} ];

	  		window.plugins.tab.show(menus, function() {
	  		});

	    }

Final step is to use the options to generate options menu:

@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		SharedPreferences settings = this.getSharedPreferences(
				TabPlugin.prefName, 0);
		menu.clear();
		try {
			JSONObject obj = new JSONObject(settings.getString(
					TabPlugin.OPTION_MENU, "{}"));
			JSONArray tabItems = obj.getJSONArray(TabPlugin.OPTION_MENU);

			if (tabItems != null) {

				for (int i = 0, n = tabItems.length(); i < n; i++) {

					JSONObject j = tabItems.optJSONObject(i);
					if (j == null) {
						continue;
					}
					MenuItem mi = menu.add(Menu.NONE, Menu.NONE, i,
							j.optString("name"));
					String url = j.optString("image", "");
					if (url.startsWith("http://")) {

						try {

							mi.setIcon(getIcon(url));
						} catch (Exception e) {

						}

					} else {
						String fileName = url
								.substring(0, url.lastIndexOf("."));

						int resId = getResources().getIdentifier(fileName,
								"drawable", "com.xxx.phonegap");
						mi.setIcon(resId);
					}
				}

			}
		} catch (JSONException e) {

		}

		return true;
	}

After the implementation, menus would look like this:

We hope using this, you would able to add dynamic options menu in your android application.

Pragmaapps offers specific development consulting and outsourcing services for Android application platform. Our experience of developing applications in the mobile domain,we can assist you to move your website to mobile platform. Feel free to contact us if you have any question related to this plugin or your website.

Leave a Comment

Scroll to Top