I
I
ins1der12112016-08-05 12:04:38
Android
ins1der1211, 2016-08-05 12:04:38

Problem with CAlendar API?

Hello. I'm having a problem with the calendar API. The problem is: I am creating a new calendar in the CalendarContract.Calendars table using CALLER_IS_SYNC_ADAPTER. The calendar is created without problems

public void createCalendarWithId(int userId) {
Uri createUri = asSyncAdapter(CalendarContract.Calendars.CONTENT_URI);
ContentValues cv = new ContentValues();
cv.put(CalendarContract.Calendars.NAME, "Calendar " + userId);
cv.put(CalendarContract.Calendars.CALENDAR_COLOR, "");
cv.put(CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL, CalendarContract.Calendars.CAL_ACCESS_OWNER);
cv.put(CalendarContract.Calendars.OWNER_ACCOUNT, "Owner");
cv.put(CalendarContract.Calendars.ACCOUNT_NAME, mContext.getString(R.string.app_name));
cv.put(CalendarContract.Calendars.ACCOUNT_TYPE, CalendarContract.ACCOUNT_TYPE_LOCAL);
mContext.getContentResolver().insert(createUri, cv);
}

private Uri asSyncAdapter(Uri uri) {
return uri.buildUpon()
.appendQueryParameter(android.provider.CalendarContract.CALLER_IS_SYNCADAPTER,"true")
.appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, mContext.getString(R.string.app_name))
.appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, CalendarContract.ACCOUNT_TYPE_LOCAL).build();
}

After that, I add new events to this calendar. I do it like this:
public void createEventForCalendarWithId(String calendarId, long startTime, String description, String title) {
ContentValues cv = new ContentValues();
cv.put(CalendarContract.Events.DTSTART, startTime);
cv.put(CalendarContract.Events.DTEND, startTime);
cv.put(CalendarContract.Events.TITLE, title);
cv.put(CalendarContract.Events.DESCRIPTION, description);
cv.put(CalendarContract.Events.CALENDAR_ID, calendarId);
cv.put(CalendarContract.Events.EVENT_TIMEZONE, String.valueOf(TimeZone.getDefault()));
Uri insertedEvent = mContext.getContentResolver().insert(CalendarContract.Events.CONTENT_URI, cv);
String eventId = String.valueOf(ContentUris.parseId(insertedEvent));
createReminderForEventWithId(eventId, 2);
}

I create reminders for these events:
public void createReminderForEventWithId(String eventId, int minutes) {
ContentValues cv = new ContentValues();
cv.put(CalendarContract.Reminders.MINUTES, minutes);
cv.put(CalendarContract.Reminders.EVENT_ID, eventId);
cv.put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT);
mContext.getContentResolver().insert(CalendarContract.Reminders.CONTENT_URI, cv);
}

Events are added to both my app's calendar and the built-in calendar. reminders are also added. But when I try to open an event in the standard calendar, this very standard calendar crashes. When you switch to an event from a reminder, the same thing comes out.
The only difference between the event created from my calendar and the event created from the standard calendar is the absence of ACCOUNT_NAME (I realized this when trying to edit the event, on some devices this can be done without going into the event itself). But at the same time, for the calendar I created, I specified both ACCOUNT_NAME and ACCOUNT_TYPE. For some reason, this information is not pulled up in Events. I tried to write ACCOUNT_NAME and ACCOUNT_TYPE similar to creating a new calendar (via CALLER_AS_SYNC_ADAPTER). As a result: the same result.
public void createEventForCalendarWithId(String calendarId, long startTime, String description, String title) {
    Uri anyChanges = asSyncAdapterForEvents(CalendarContract.Events.CONTENT_URI);
        ContentValues cv = new ContentValues();
        cv.put(CalendarContract.Events.DTSTART, startTime);
        cv.put(CalendarContract.Events.DTEND, startTime);
        cv.put(CalendarContract.Events.TITLE, title);
        cv.put(CalendarContract.Events.DESCRIPTION, description);
        cv.put(CalendarContract.Events.CALENDAR_ID, calendarId);
        cv.put(CalendarContract.Events.EVENT_TIMEZONE, String.valueOf(TimeZone.getDefault()));
        Uri insertedEvent = mContext.getContentResolver().insert(anyChanges, cv);
        String eventId = String.valueOf(ContentUris.parseId(insertedEvent));
        createReminderForEventWithId(eventId, 2);
    }

private Uri asSyncAdapterForEvents(Uri uri) {
return uri.buildUpon()
.appendQueryParameter(android.provider.CalendarContract.CALLER_IS_SYNCADAPTER,"true")
.appendQueryParameter(CalendarContract.Events.ACCOUNT_NAME, mContext.getString(R.string.app_name))
.appendQueryParameter(CalendarContract.Events.ACCOUNT_TYPE, CalendarContract.ACCOUNT_TYPE_LOCAL).build();
}

Then I tried to write these fields "directly". But the application crashes when trying to write these values ​​to the database. And the stack trace reports something strange.
public void createEventForCalendarWithId(String calendarId, long startTime, String description, String title) {
ContentValues cv = new ContentValues();
cv.put(CalendarContract.Events.ACCOUNT_NAME, mContext.getString(R.string.app_name));
cv.put(CalendarContract.Events.ACCOUNT_TYPE, CalendarContract.ACCOUNT_TYPE_LOCAL);
cv.put(CalendarContract.Events.DTSTART, startTime);
cv.put(CalendarContract.Events.DTEND, startTime);
cv.put(CalendarContract.Events.TITLE, title);
cv.put(CalendarContract.Events.DESCRIPTION, description);
cv.put(CalendarContract.Events.CALENDAR_ID, calendarId);
cv.put(CalendarContract.Events.EVENT_TIMEZONE, String.valueOf(TimeZone.getDefault()));
Uri insertedEvent = mContext.getContentResolver().insert(CalendarContract.Events.CONTENT_URI, cv);
String eventId = String.valueOf(ContentUris.parseId(insertedEvent));
createReminderForEventWithId(eventId, 2);
}

Fatal Exception: java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:304)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java: 231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java :818)
Caused by java.lang.IllegalArgumentException: Only the provider may write to account_name
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:172)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:142)
at android.content. ContentProviderProxy.insert(ContentProviderNative.java:476)
at android.content.ContentResolver.insert(ContentResolver.java:1265)
at com.bnsf.jobfinder.jobfinder.calendar.CalendarManager.createEventForCalendarWithId(CalendarManager.java:156)
at com.bnsf .jobfinder.jobfinder.calendar.AddEventActivity$CreateEventAsyncTask.doInBackground(AddEventActivity.java:169)
at com.bnsf.jobfinder.jobfinder.calendar.AddEventActivity$CreateEventAsyncTask.doInBackground(AddEventActivity.java:156)
at android.os.AsyncTask$2.call(AsyncTask.java:292)
at java.util.concurrent.FutureTask.run( FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$ Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
I'm trying to write values ​​to ACCOUNT_NAME and ACCOUNT_TYPE through a ContentResolver which in turn calls a ContentProvider, so the message that only a ContentProvider can write to these columns seems odd.
Sample project on github: https://github.com/ins1der1211/CalendarTrouble.git
Any ideas?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
G
glebas1986, 2017-06-27
@glebas1986

Met the same problem. You are doing everything right, but you forgot to specify when creating the calendar, the CalendarContract.Calendars.CALENDAR_DISPLAY_NAME
Calendar field, when opening an event, shows which calendar it belongs to, for this it takes calendar_displayName, but if it does not find it, it simply falls. Add it and it will work

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question