Click here to Skip to main content
Click here to Skip to main content

How to Add to Calendar Events in an Hybrid Android Application

, 1 Apr 2013
Rate this:
Please Sign up or sign in to vote.
This article will show you how to access your Android Calendar Events in a Hybrid Android Application.

Introduction

The Cordova PhoneGap Library is an awesome JavaSript library that allows developers to implement native functionality in hybrid applications. But, PhoneGap only provides a limited range of functionality. For example, it doesn't provide a way to add to your phones local Calendar Events. However, there is a simple solution using the cordova Java library. This article will explain how to use the cordova library to implement this feature (Note: This article is assuming you have your file structure set up correctly).

Using the Code

There are several parts to this. First, we will start of with the JavaScript. You must first make sure you have the latest PhoneGap library by visiting PhoneGap.com.

Include the cordova.js file and your code to execute the cordova callNativeFunction in your index.html. The callNativeFunction is a cordova defined function which is used to call your apps native function which in this case will create the event. This function has three parameters: the first is a result handler that prints the result of the call, the second parameter is the error handling function which will execute if there is an error in the call, the last parameter "returnSuccess" is the message to the native function. In our case, returnSuccess will contain all the information needed to create the event. For example, the date/time and name of the event. The calendarPlugin object is a JavaScript object that you will create, but you need to create this object in a different JavaScript file. We will discuss this part later.

<script type="text/javascript" src="cordova.js"></script>
 <script type="text/javascript" src="calendarPlugin.js"></script>
 <script>
	 function callNativePlugin(returnSuccess){
                    calendarPlugin.callNativeFunction
                    (nativePluginResultHandler, nativePluginErrorHandler, returnSuccess);
                }

	function nativePluginResultHandler(result){
                    console.log("SUCCESS:\r\n" + result);
                }

    function nativePluginErrorHandler(error){
                    alert("Error: \r\n" + error);
                }
 </script>

Now in your Sencha view, add a button with a tap listener.

 {
	xtype:'button',
	width:100,
	height:44,
	ui:'red',
	listeners:{
		tap:function(){
			 callNativePlugin('success,' + eventTitleData + ',' 
			 + eventEndDateData +
			 ',' + eventStartDateData + ',' + 
			 eventLocationData + ',' +eventDescriptionData);
		}
	}
 }

Now that we have all the HTML and JavaScript set up, it is time to make the calendarPlugin object. Create a new JavaScript file named calendarPlugin.js and add the following code snippet. Let me explain this code a little. Here, we are defining an object with the property callNativeFunction. The callNativeFunction is a JavaScript function which executes the cordova.exe function. There are only two parameters you need to worry about. One is the name of the Android class you are calling. In this case, it's the "com.myPlugins.CalendarPlugin class that we will define later". Next it's the action "addToCalendar" which we will define in our CalendarPlugin class.

	var calendarPlugin = {
	callNativeFunction: function(success, fail, resultType){
	 return cordova.exec(success, fail,
							"com.myPlugins.CalendarPlugin",
							"addToCalendar",[resultType]);
	}
};

Now that we have completed all the steps for the JavaScript side, I will start discussing what is needed in the Android side. Under the www folder, add your calendarPlugin.js file. Now, we need to create our Android class to handle the call from cordova and execute the code to add calendar events. Before we create our Java file, we need to add the following line inside the Plugins tag to our config.xml file under the res/xml folder.

<plugin name="com.myPlugins.CalendarPlugin" 
value="com.myPlugins.CalendarPlugin"/>

config - Click to enlarge image

Create a package called "com.MyPlugins" and a class called "CalendarPlugin". This class will extend the CordovaPlugin class which will allow us to implement our cordova plugin. Your Plugin class must override one of the execute methods defined by cordova. In our case, we are calling the execute method with an action to perform, data in the form of JSON and a callback method. Specify an intent with the action "ACTION_EDIT" which will provide editable access to a given data. Then call intent.setType(), this is used to specify a type and not data for the intent. In this case, we are specifying type uri of "vnd.android.cursor.item/event". A cursor is an object that provides random read access to rows and columns in databases. In this case, it's the Event database. Lastly, make sure to provide information to your event by calling intent.putExtra(Events.TITLE, "YouTitle"), etc. You can find out more about which kind of fields the CalendarContract.Events object has by visiting the Android development documentation.

package com.myPlugins;
/***
* CalendarPlugin
*@author Kevin Morfin
**/

import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;

import org.apache.cordova.api.CallbackContext;
import org.apache.cordova.api.CordovaPlugin;

import org.json.JSONArray;
import org.json.JSONException;

import android.content.Intent;

import android.provider.CalendarContract;
import android.provider.CalendarContract.Events;
import android.util.Log;

public class CalendarPlugin extends CordovaPlugin {
	public static final String ACTION_STRING = "addToCalendar";
	public static final String PARAMETER = "success";

	@Override
	public boolean execute(String action, JSONArray data, 
	CallbackContext callbackContext) throws JSONException {
		if (ACTION_STRING.equals(action)){

			//map month string values to integer value
			Map<string,integer> months = new HashMap<string,integer>();
			months.put("Jan", 0);
			months.put("Feb", 1);
			months.put("Mar",2);
			months.put("Apr", 3);
			months.put("May", 4);
			months.put("Jun", 5);
			months.put("Jul", 6);
			months.put("Aug", 7);
			months.put("Sep", 8);
			months.put("Oct", 9);
			months.put("Nov", 10);
			months.put("Dec", 11);

			Intent intent = new Intent(Intent.ACTION_EDIT);
			intent.setType("vnd.android.cursor.item/event");

			try{
				String [] calendarData = data.getString(0).split(",");

				//parse trough calendar start date and time

				String [] start = calendarData[4].split("\\s+");

				int month = months.get(start[1]);
				int day = Integer.parseInt(start[2]);
				int year = Integer.parseInt(start[3]);

				String [] time = start[4].split(":");
				int hour = Integer.parseInt(time[0]);
				int minutes = Integer.parseInt(time[1]);

				GregorianCalendar date1 = 
				new GregorianCalendar(year, month, day, hour, minutes);

				Log.d("beginTime", "time" +date1.getTime());

				//parse trough calendar end date and time
				String [] start2 = calendarData[3].split("\\s+");

				Log.d("EndTime", start2[1]);

				int month2 = months.get(start2[1]);
				int day2 = Integer.parseInt(start2[2]);
				int year2 = Integer.parseInt(start2[3]);

				String [] time2 = start2[4].split(":");
				int hour2 = Integer.parseInt(time2[0]);
				int minutes2 = Integer.parseInt(time2[1]);

				GregorianCalendar date2 = 
				new GregorianCalendar(year2, month2, day2, hour2, minutes2);

				intent.putExtra(Events.TITLE, calendarData[1]);
	            intent.putExtra(CalendarContract.EXTRA_EVENT_ALL_DAY, true);
	            intent.putExtra
	            (CalendarContract.EXTRA_EVENT_BEGIN_TIME, date1.getTimeInMillis());
	            intent.putExtra
	            (CalendarContract.EXTRA_EVENT_END_TIME, date2.getTimeInMillis());
	            intent.putExtra(CalendarContract.EventsEntity.EVENT_LOCATION, 
	            calendarData[5] + calendarData[6] + calendarData[7]);
	            intent.putExtra
	            (CalendarContract.EventsEntity.DESCRIPTION, calendarData[8]);
			}
			catch(Exception e){
				Log.d("Error with Calendar Plugins:",e.getMessage());
				return false;
			}

			this.cordova.startActivityForResult(this, intent, 0);

            return true;
		}
		return false;
	}
}

History

  • 31st March, 2013: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Kevin Morfin

United States United States
No Biography provided

Comments and Discussions

 
GeneralMy vote of 5 PinmemberMihai MOGA10-May-13 18:33 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140827.1 | Last Updated 1 Apr 2013
Article Copyright 2013 by Kevin Morfin
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid