我在从 Android N 开始的完整日历应用程序中遇到了一个奇怪的问题。我想知道我是否遗漏了什么,或者 Android N 上的日历提供程序是否有问题。
我正在使用日历内容提供程序来管理日历。可以打开、编辑、删除和创建事件(从 Android 2.1 到 Marshmallow),但现在在 N 上无法创建新事件。尝试创建新事件时,事件会短暂出现在事件列表中,然后消失。查看日志时,这就是真正发生的情况:
EventHandler::InsertEvent: Forbidden Entity[ id=2172 calendar_id=1 calendar_sync_id=-899202677 ]
com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden {
"errors": [
{
"reason": "forbidden",
"domain": "global",
"message": "Forbidden"
}],
"message": "Forbidden",
"code": 403
}
我能找到的所有与此错误有关的内容都与日历 API 调用有关,而不是与内容提供者有关(我的猜测是内部正在使用日历 API,并且由于缺乏身份验证而失败了?)。但是,我查看了提供者文档https://developer.android.com/guide/topics/providers/calendar-provider.html并且找不到任何身份验证要求。
我从 AOSP 中查找了当前日历应用程序中的更改,但找不到任何相关内容。它们作为同步适配器运行,使您可以在一些我不使用的特殊列上进行写入,所以我认为这不是问题的原因。
我也在考虑使用日历 API,但这不是我们所希望的,因为它不能脱机工作,而且日历 API 文档本身指出:“注意:本快速入门的目的是演示日历 API 在“
我已经在这方面工作了很长时间,但没有运气,使用 Google Play 客户端/服务库,尝试使用 Google 登录、清单权限和几个示例,毕竟我不知道现在还能去哪里,我如果你们中的任何人能让我知道在 Android N 上编写日历事件时可能出了什么问题或预期的方法是什么,我将不胜感激。
太感谢了
这里的代码:
public Uri AddCalendarEntry(CalendarEventObject eventObject) {
ContentValues event = new ContentValues();
if (eventObject.getCalendar() != null) {
event.put(CalendarContract.Events.CALENDAR_ID, Integer.parseInt(eventObject.getCalendar().getId()));
} else {
Log.e (DEBUG_TAG,"calendar id not available ");
return null;
}
event.put(CalendarContract.Events.TITLE, eventObject.getSubject());
event.put(CalendarContract.Events.DESCRIPTION, eventObject.getDescription());
event.put(CalendarContract.Events.EVENT_LOCATION, eventObject.getLocation());
event.put(CalendarContract.Events.STATUS, CalendarContract.Events.STATUS_CONFIRMED);
event.put(CalendarContract.Events.HAS_ALARM, 1); // 0 for false, 1 for true
// All day events must use timezone UTC, others can use default
if (eventObject.isAllDay()) {
event.put(CalendarContract.Events.ALL_DAY, 1); // 1 for true
event.put(CalendarContract.Events.EVENT_TIMEZONE, Time.TIMEZONE_UTC);
} else {
event.put(CalendarContract.Events.ALL_DAY, 0); // 0 for false
event.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().toString());
}
// Recurrent events must use "duration", normal events should use "dtend"
event.put(CalendarContract.Events.DTSTART, eventObject.getStartDateTime());
String recurrence = eventObject.getRecurrence();
if (recurrence != null && !TextUtils.isEmpty(recurrence)) {
String duration = datesToDuration(eventObject.getStartDateTime(), eventObject.getEndDateTime());
event.put(CalendarContract.Events.DURATION, duration);
event.put(CalendarContract.Events.RRULE, recurrence);
} else {
event.put(CalendarContract.Events.DTEND, eventObject.getEndDateTime());
}
Uri eventsUri = CalendarContract.Events.CONTENT_URI;
Uri insertedUri = null;
try {
insertedUri = mainActivity.getContentResolver().insert(eventsUri, event);
} catch(Exception e) {
Log.e(DEBUG_TAG, "Error creating event " + e);
}
return insertedUri;
}
这里是完整的跟踪:
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:321)
at
com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1065)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
at com.google.android.syncadapters.calendar.CalendarRequestExecutor.executeInternal(CalendarRequestExecutor.java:146)
at com.google.android.syncadapters.calendar.CalendarRequestExecutor.execute(CalendarRequestExecutor.java:120)
at com.google.android.syncadapters.calendar.EventHandler.sendEntityToServer(EventHandler.java:485)
at com.google.android.syncadapters.calendar.CalendarSyncAdapterApiary.sendEntityToServer(CalendarSyncAdapterApiary.java:4084)
at com.google.android.syncadapters.calendar.CalendarSyncAdapterApiary.processLocalChanges(CalendarSyncAdapterApiary.java:4031)
at com.google.android.syncadapters.calendar.CalendarSyncAdapterApiary.processLocalChangesForHandler(CalendarSyncAdapterApiary.java:3970)
at com.google.android.syncadapters.calendar.CalendarSyncAdapterApiary.performUpsync(CalendarSyncAdapterApiary.java:791)
at com.google.android.syncadapters.calendar.CalendarSyncAdapterApiary.performSync(CalendarSyncAdapterApiary.java:691)
at com.google.android.syncadapters.calendar.CalendarSyncAdapterApiary.onPerformLoggedSync(CalendarSyncAdapterApiary.java:504)
at com.android.emailcommon.syncadapter.LoggingThreadedSyncAdapter.onPerformSync(LoggingThreadedSyncAdapter.java:50)
at android.content.AbstractThreadedSyncAdapter$SyncThread.run(AbstractThreadedSyncAdapter.java:272)