Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Open Calendar App on a specific calendar

I want to open up the Calendar application from an android application but with a specific calendarId.

My code:

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

startActivityForResult(calIntent, RESULT_CODE_OPEN);

But the intent open with the last Calendar used. I want open a specific one with his calendar ID.

How can I do that?

like image 582
user3433863 Avatar asked Mar 18 '14 15:03

user3433863


1 Answers

A bit of history: Looking into Calendar App sources, i found this section of manifest which indicates what class handles Intent.ACTION_EDIT, EditEventActivity.java. Then I found this line; calendarId is obtained from extra data. so...

Open an EditEvent - (answer to original question)

Put an extra long on the Intent with key CalendarContract.Events.CALENDAR_ID and the corresponding calendarId like this sample:

long calendarId = 1234; // here goes your calendar Id

final Intent calIntent = new Intent(Intent.ACTION_EDIT)
       .setType("vnd.android.cursor.item/event")
       .putExtra(CalendarContract.Events.CALENDAR_ID, calendarId);

startActivityForResult(calIntent, RESULT_CODE_OPEN);

Open the Calendar app with the month week view on specific calendar - (answer to bounty question - PART 1)

This approach is a bit different. Before open Calendar app, you should make invisible all calendars but no the selected one. So, I've created a helper function to do exactly that.

private void makeAllCalendarsInvisibleExcept(long calendarId) {
    ContentValues updateValues = new ContentValues();
    updateValues.put(CalendarContract.Calendars.VISIBLE, 0);

    // make all invisible
    getContentResolver().update(CalendarContract.Calendars.CONTENT_URI,
            updateValues, null, null);

    updateValues.clear();
    updateValues.put(CalendarContract.Calendars.VISIBLE, 1);


    // make calendarId visible
    getContentResolver().update(CalendarContract.Calendars.CONTENT_URI,
            updateValues, where, null);
}

And here how to setup it:

makeAllCalendarsInvisibleExcept(calendarId);
Intent calIntent = new Intent();
// for google calendar, first parameter should be "com.google.android.calendar"
// this is intended for android calendar.
ComponentName cn = new ComponentName("com.android.calendar", "com.android.calendar.LaunchActivity");
calIntent.setComponent(cn);
startActivityForResult(calIntent, 4567);

AFAIK, no way to open month view. But research never ends, i will do an update ASAP.

In the DemoApp I've created two extra helper methods to push and restore calendars visibility state. Take a look arround pushCalendarVisibility and restoreCalendarVisibility and onActivityResult

Note: I've tested the app with and without Google calendar installed. AFAIK on Google Calendar shown only DAY view, not WEEK neither MONTH.

In all cases shown only events on selected calendar.

Get calendarId and Account Name - (answer to bounty question - PART 2)

calendarId abd Account Name can be obtained using CalendarContract.Calendars, like this:

// since API14 
Uri uri = CalendarContract.Calendars.CONTENT_URI;

String[] projection = new String[] {
        CalendarContract.Calendars._ID,
        CalendarContract.Calendars.VISIBLE,
        CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL,
        CalendarContract.Calendars.CALENDAR_DISPLAY_NAME,
        CalendarContract.Calendars.ACCOUNT_NAME,
};

Cursor calendarCursor = getContentResolver().query(uri, projection, null, null, null);
while (calendarCursor.moveToNext()) {

    // calendarId
    long calendarId = calendarCursor.getLong(0);

    // get visibility, warning: if calendar is not visible Intent.ACTION_EDIT doesn't work.
    boolean calendarVisible = calendarCursor.getInt(1) == 1;

    // get if it's owned, warning: if calendar is not owned Intent.ACTION_EDIT doesn't work.
    boolean calendarOwned = calendarCursor.getInt(2) == CalendarContract.Calendars.CAL_ACCESS_OWNER;

    // get calendar display name
    String calendarName = calendarCursor.getString(3);

    // get account name
    String accountName = calendarCursor.getString(4);

    // do something

}

Note: There are more available options for calendar projection, advice read CalendarContract.Calendars

Limitations

This features is available since API Level 14, Android 4.0 (ICE_CREAM_SANDWICH)

Demo App

Complete example in this GitHub repository. (Android Studio 1.0.0 project) Requires Calendars synced and must be owned by the account and must be visible. UPDATE: example up to date

Tested on Android 4.1.1 and Android 5.0 Lollipop Preview

like image 187
rnrneverdies Avatar answered Sep 28 '22 22:09

rnrneverdies