Вопрос

I am working on an Android application. I have to add events to native Android calendar. So I tried the following code:

if (Build.VERSION.SDK_INT >= 8 ) {
    l_eventUri = Uri.parse("content://com.android.calendar/events");
} else {
    l_eventUri = Uri.parse("content://calendar/events");
}

Cursor cursor = getContentResolver() .query(Uri.parse(getCalendarUriBase(this)),new String[] { "calendar_id", "displayname"}, null,null, null);
cursor.moveToFirst();
// fetching calendars name
String CNames[] = new String[cursor.getCount()];
// fetching calendars id
int[] CalIds = new int[cursor.getCount()];
for (int i = 0; i < CNames.length; i++) {
    CalIds[i] = cursor.getInt(0);
    CNames[i] = cursor.getString(1);
    cursor.moveToNext();
}

// get calendar
Calendar cal = Calendar.getInstance();     
Uri EVENTS_URI = Uri.parse(getCalendarUriBase(this) + "events");
ContentResolver cr = getContentResolver();

// event insert
ContentValues values = new ContentValues();
values.put("calendar_id",111);
values.put("title", "Reminder Title");
values.put("allDay", 0);
values.put("dtstart", cal.getTimeInMillis() + 11*60*1000); // event starts at 11 minutes from now
values.put("dtend", cal.getTimeInMillis()+60*60*1000); // ends 60 minutes from now
values.put("description", "Reminder description");
//Event Id
values.put("_id", 23);  
//0~ default; 1~ confidential; 2~ private; 3~ public
values.put("visibility", 0);
//0~ false; 1~ true
values.put("hasAlarm", 1);
//status: 0~ tentative; 1~ confirmed; 2~ canceled
values.put("eventStatus", 1);
//0~ opaque, no timing conflict is allowed; 1~ transparency, allow overlap of scheduling
values.put("transparency", 0);
Uri event = cr.insert(EVENTS_URI, values);

// reminder insert
Uri REMINDERS_URI = Uri.parse(getCalendarUriBase(this) + "reminders");
values = new ContentValues();
values.put( "event_id", Long.parseLong(event.getLastPathSegment()));
values.put( "method", 1 );
values.put( "minutes", 10 );
cr.insert( REMINDERS_URI, values );

private String getCalendarUriBase(Activity act) {
    String calendarUriBase = null;
    Uri calendars = Uri.parse("content://calendar/calendars");
    Cursor managedCursor = null;
    try {
        managedCursor = act.managedQuery(calendars, null, null, null, null);
    } catch (Exception e) {
    }

    if (managedCursor != null) {
        calendarUriBase = "content://calendar/";
    } else {
        calendars = Uri.parse("content://com.android.calendar/calendars");
        try {
            managedCursor = act.managedQuery(calendars, null, null, null, null);
        } catch (Exception e) {
        }
        if (managedCursor != null) {
            calendarUriBase = "content://com.android.calendar/";
        }
    }
    return calendarUriBase;
}

When I run this code, I am getting the IllegalArgumentException.

java.lang.IllegalArgumentException: Unknown URL content://com.android.calendar/

I think the error is because of getCalendarUriBase() method. I searched a lot for other ways, but so far most of the developers following the above code snippet because this will work for every Android versions. How to fix it?

Это было полезно?

Решение

You missed calendars when you try to execute this line

Cursor cursor = getContentResolver().query(
    Uri.parse(getCalendarUriBase(this)), /* <-- unknown URL content */
    new String[] { "calendar_id", "displayname" },
    null,null,null);

resulting in IllegalArgumentException.

Just add the calendars after getCalendarUriBase(this).

Cursor cursor = getContentResolver().query(
    Uri.parse(getCalendarUriBase(this)+"calendars"),
    new String[] { "_id", "displayName" },
    null,null,null);

Note:

  • Use _id to get the calendar ID if you query from calendars table. calendar_id is defined as a foreign key in other tables (e.g. events).
  • Use displayName for GingerBread or below. For Ice Cream Sandwich and above, use calendar_displayName.

When adding an event, you need to include: calendar ID, start date, end date (or recurrence rule), and event timezone. You have included all but the timezone. Try adding

values.put("eventTimezone", TimeZone.getDefault().getID());

before inserting the event.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top