无法在android N中创建日历事件

时间:2016-12-16 19:06:08

标签: android android-calendar android-7.0-nougat android-7.1-nougat

我在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)

1 个答案:

答案 0 :(得分:0)

我发布这些信息,不是真正的解决方案,而是我的结论,以防我可以帮助处于相同情况的人。

显然,Google在某些情况下忘记授予日历权限。所以我的猜测是,在日历中无意中删除了对日历的支持:

旧应用(目标低于23,Android M)

新设备(使用Android N,24及更高版本)

根据文档,如果你的目标是低于23,你不必担心运行时权限,但似乎使用日历API有一些要求没有得到妥善解决。 在我的应用程序(难以)迁移到Android Studio并定位到更新的API(23-24)之后,我的日历最终可以保存事件。

相关问题