Sync Events with Android Calendar | Google Calendar and By Default Calendar of Android | Android Breakdown

Android Breakdown
Sync events with android calendar

Sync Events in Android Calendar

Syncing events in android calendar is the topic, which is quite hard or time consuming task to do nowadays, where android is upgrading in too many levels. So we have searched a lot over internet and didn't find any good example, which will provide us the way to implement the code for all levels of android. Some of code was only working below 4.2 and Google is providing calendar api, which we didn't want to use. Because calendar syncing should be offline (without internet).


So here we are giving two methods for both calendars, one method is for android default calendar, which comes with the devices under 4.2 (default calendar can be found installed in 4.2+ devices, because it depends on device manufacturing company). And another method is for google calendar, which is coming with almost all new devices. Remember this google method, which we are providing is not based on calendar api, which makes it important and useful.

Let's start

First of all give permissions in AndroidMenifest.xml file.
    <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
    <uses-permission android:name="android.permission.READ_CALENDAR"/>
    <uses-permission android:name="android.permission.WRITE_CALENDAR"/>

So here is a method named saveEvents(List data), where we have to pass the list of events (Event is an object which contains some attributes like event name, address, time etc.)
    public void saveEvents(List<Event> data) {

    //Todo show progress bar here.

        /*HERE WE ARE CHECKING BOTH METHODS, IF BOTH OF THEM RETURNS FALSE IT MEANS DEVICES DOESN'T HAS CALENDAR*/
        if (!saveEventDefaultCalendar(data) && !saveEventGoogleCalendar(data)) {
            Toast.makeText(getContext(), "No Calendar Available", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(getContext(), "Synced Successfully", Toast.LENGTH_SHORT).show();
        }

//Todo hide progress bar here.

    }

Syncing with Google Calendar (without using calendar api)

Now we take turn toward google calendar. Here is a method which sync events with google calendar returning boolean value (if true, means event added else not added).


    private boolean saveEventsGoogleCalendar(List<Event> data) {
        try {
            String possibleEmail = "";

            \*To sync with google calendar we need to get the gmail account of user currently logged in*\
            Account[] accounts = AccountManager.get(getContext()).getAccountsByType("com.google");
            for (Account account : accounts) {
                possibleEmail = account.name;
            }


            ContentValues values = new ContentValues();
            values.put(CalendarContract.Calendars.ACCOUNT_NAME,possibleEmail);
            values.put(CalendarContract.Calendars.ACCOUNT_TYPE,CalendarContract.ACCOUNT_TYPE_LOCAL);
            values.put(CalendarContract.Calendars.NAME,"[Your App Name Here]");
            values.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME,"[Your App Name Here]");

            //You can choose color from this site.
            //https://developer.android.com/reference/android/graphics/Color.html
            values.put(CalendarContract.Calendars.CALENDAR_COLOR,0xffff0000);
            values.put(CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL,CalendarContract.Calendars.CAL_ACCESS_OWNER);
            values.put(CalendarContract.Calendars.OWNER_ACCOUNT,possibleEmail);

            //Set timezone according to you or you can use TimeZone.getDefault().getID() to get device's timezone.
            values.put(CalendarContract.Calendars.CALENDAR_TIME_ZONE,TimeZone.getDefault().getID());
            values.put(CalendarContract.Calendars.SYNC_EVENTS,1);


            Uri.Builder builder =CalendarContract.Calendars.CONTENT_URI.buildUpon();
            builder.appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME,possibleEmail);
            builder.appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE,CalendarContract.ACCOUNT_TYPE_LOCAL);
            builder.appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER,"true");

            Uri uri = getActivity().getContentResolver().insert(builder.build(), values);


            for (Event event : data) {


                long calId = getCalendarId(possibleEmail);//A function to get calendar Id
                if (calId == -1) {
                    return false;
                }

                Calendar cal = new GregorianCalendar(event.getYear, event.getMonth, event.getDay);

                cal.setTimeZone(TimeZone.getTimeZone(TimeZone.getDefault().getID()));
                cal.set(Calendar.HOUR, Integer.parseInt(event.getHour()));
                cal.set(Calendar.MINUTE, 0);
                cal.set(Calendar.SECOND, 0);
                cal.set(Calendar.MILLISECOND, 0);


                long start = cal.getTimeInMillis();

                ContentValues contentValues = new ContentValues();
                contentValues.put(CalendarContract.Events.DTSTART, start);
                
                //WE WANTED ONLY 1 HOUR EVENT THATS WHY WE PASSED SAME IN DTEND. IF YOU WANT MORE THAN 1 HOUR YOU CAN MODIFY DTEND 
                contentValues.put(CalendarContract.Events.DTEND, start);

                contentValues.put(CalendarContract.Events.TITLE, event.getEventname());
                contentValues.put(CalendarContract.Events.EVENT_LOCATION, event.getAddress());
                contentValues.put(CalendarContract.Events.CALENDAR_ID, calId);
                contentValues.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());
                contentValues.put(CalendarContract.Events.DESCRIPTION, event.getDescription());
                contentValues.put(CalendarContract.Events.ACCESS_LEVEL, CalendarContract.Events.ACCESS_DEFAULT);
                contentValues.put(CalendarContract.Events.AVAILABILITY, CalendarContract.Events.ACCESS_PUBLIC);


                 /*OPTIONAL*/
                //RULES IF YOU WANT TO SET LIKE DAILY EVENT FOR PARTICULAR TIME OR ACCORDING TO DAYS LIKE MONDAY, TUESDAY ETC.
                //contentValues.put(CalendarContract.Events.RRULE,"FREQ=DAILY;COUNT=20;BYDAY=MO,TU,WE,TH,FR;WKST=MO");
                //contentValues.put(CalendarContract.Events.SELF_ATTENDEE_STATUS, CalendarContract.Events.STATUS_CONFIRMED);
                //contentValues.put(CalendarContract.Events.ALL_DAY, 1);
                //contentValues.put(CalendarContract.Events.ORGANIZER, "some.mail@some.address.com");
                //contentValues.put(CalendarContract.Events.GUESTS_CAN_INVITE_OTHERS, 1);
                //contentValues.put(CalendarContract.Events.GUESTS_CAN_MODIFY, 1);

                Uri uriInsert = getActivity().getContentResolver().insert(CalendarContract.Events.CONTENT_URI, contentValues);
           
                /*SAVE EVENT ID IF YOU WANT FOR FUTURE OPERATIONS LIKE UPDATE, DELETE ETC.*/
                //long eventId = new Long(uriInsert.getLastPathSegment());
            }

            return true;

        } catch (Exception e) {
            Log.e("Error",e.toString());
            return false;
        }
    }

    private long getCalendarId(String possibleEmail) {

        String[] projection = new String[]{CalendarContract.Calendars._ID};
        String selection =CalendarContract.Calendars.ACCOUNT_NAME +" = ? AND " +CalendarContract.Calendars.ACCOUNT_TYPE +" = ? ";
        
        String[] selArgs =new String[]{possibleEmail,CalendarContract.ACCOUNT_TYPE_LOCAL};
        Cursor cursor = getActivity().getContentResolver().query(CalendarContract.Calendars.CONTENT_URI, projection, selection, selArgs, null);

        if (cursor.moveToFirst()) {
            return cursor.getLong(0);
        }
        return -1;
    }




Syncing with Android By Default Calendar

So finally we have done syncing work of google calendar. Now default calendar's turn here, same parameter with same returning boolean value.

 
private boolean saveEventsDefaultCalendar(List<Event> data) {
        try {
            for (Event event : data) {
                //calendar id is 1 for default calendar
                long calID = 1;
                long startMillis = 0;
                long endMillis = 0;

                Calendar beginTime = Calendar.getInstance();


                beginTime.set(event.getYear(), event.getMonth(), event.getDay(), Integer.parseInt(event.getHour()), 0);
                startMillis = beginTime.getTimeInMillis();
                Calendar endTime = Calendar.getInstance();
                endTime.set(event.getYear(), event.getMonth(), event.getDay(), Integer.parseInt(event.getHour()) + 1, 0);
                endMillis = endTime.getTimeInMillis();


                ContentResolver cr = getActivity().getContentResolver();
                ContentValues values = new ContentValues();
                values.put(CalendarContract.Events.DTSTART, startMillis);
                values.put(CalendarContract.Events.DTEND, endMillis);
                values.put(CalendarContract.Events.TITLE, event.getEventName());
                values.put(CalendarContract.Events.DESCRIPTION, event.getDescription());
                values.put(CalendarContract.Events.EVENT_LOCATION, event.getAddress());
                values.put(CalendarContract.Events.CALENDAR_ID, calID);
                values.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());
                Uri uri = cr.insert(CalendarContract.Events.CONTENT_URI, values);

                long eventID = Long.parseLong(uri.getLastPathSegment());
                Log.i("RunnerBecomes", "event id: " + eventID);


                // Save the eventId into the Task object for possible future delete.
                Long eventId = Long.parseLong(uri.getLastPathSegment());

            }

            return true;

        } catch (Exception e) {
            Utils.printLog(e.toString());
            return false;
        }
    }


So finally we implemented both the methods in our app to sync events in calendar (google/default calendar both). Here is a screen shot of added event below.
Android Breakdown
Added events in calendar


That's it for today, if you still have any confusion, clear them by commenting below.
And Be Updated with our YouTube Channel.

Comments