我在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
}
我可以通过此错误找到的所有内容都与Calendar API调用有关,而与内容提供商无关(我的猜测是内部使用的是Calendar API,而且由于缺少身份验证而失败了?)。 但是,我查看了提供程序文档https://developer.android.com/guide/topics/providers/calendar-provider.html,但未找到任何身份验证要求。
我在AOSP中查找当前日历应用程序中的更改但我找不到任何相关内容。它们作为同步适配器运行,使您可以写一些我没有使用的特殊列,因此我不认为这是问题的原因。
我也在考虑使用Calendar API,但这不是理想的,因为它不能脱机工作,而且Calendar API文档本身也说明:“注意:本快速入门的目的是演示如何使用Android应用程序中的日历API。然而,生产日历应用程序将通过使用日历提供程序内容提供程序而受益,该提供程序脱机工作,接收推送,是平台的良好匹配。“
我一直在努力工作,没有运气,玩谷歌游戏客户端/服务库,尝试使用谷歌登录,清单权限和几个样本,毕竟我不知道还有什么去现在,如果你们中的任何一个人能够让我知道在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)
答案 0 :(得分:0)
我发布这些信息,不是真正的解决方案,而是我的结论,以防我可以帮助处于相同情况的人。
显然,Google在某些情况下忘记授予日历权限。所以我的猜测是,在日历中无意中删除了对日历的支持:
旧应用(目标低于23,Android M)
和
新设备(使用Android N,24及更高版本)
根据文档,如果你的目标是低于23,你不必担心运行时权限,但似乎使用日历API有一些要求没有得到妥善解决。 在我的应用程序(难以)迁移到Android Studio并定位到更新的API(23-24)之后,我的日历最终可以保存事件。