【问题标题】:List events for specific day in Android 4+ (ALL_DAY issue)列出 Android 4+ 中特定日期的事件(ALL_DAY 问题)
【发布时间】:2012-10-05 18:17:09
【问题描述】:

我正在尝试在 Android 4+ 中获取所选日期发生的所有事件。

据我了解,CalendarContract.Instances 是获取事件的最简单方法,因为它同时处理重复事件和单次事件。

但是,我在处理时间戳的方式上存在一些问题。具体来说,它似乎以不同的方式对待 ALL_DAY 事件。

我从以下代码开始(start 是我获取事件的那一天,毫秒“数学”是为了避免从第二天上午 12 点开始的不必要事件,日历使用默认时区) .

public Cursor fetchCursor(Calendar start) {
    Calendar end = (Calendar) start.clone();
    end.add(Calendar.DATE, 1);

    long startTime = start.getTimeInMillis() + 1;
    long endTime = end.getTimeInMillis() - 1;

    ContentResolver resolver = mContext.getContentResolver();
    return CalendarContract.Instances.query(resolver, projection, startTime, endTime);
}

这段代码似乎适用于许多极端情况、不同时区、跨越多天的事件......除了全天事件之外的所有内容。

当我检查带有 ALL_DAY 标志的返回事件时:

    Cursor c = fetchCursor(date);
    Log.e("SIZE", String.valueOf(c.getCount()));
    while (c.moveToNext()) {
        long begin = c.getLong(2); // CalendarContract.Instances.BEGIN
        long end = c.getLong(3);   // CalendarContract.Instances.END
        Date beginDate = new Date(begin);
        Date endDate = new Date(end);
        Log.e("EVENT", String.valueOf(begin) + " - " + String.valueOf(end));
        Log.e("EVENT", beginDate.toString() + " - " + endDate.toString());
    }

我得到了:EVENT(10075): Thu Sep 13 02:00:00 CEST 2012 - Sat Sep 15 02:00:00 CEST 2012

对我来说,query 期望范围从 MY TIMEZONE 中的纪元开始和结束以毫秒为单位(但 API 声明它需要基于 UTC 的时间戳)。但是标记为 ALL_DAY 的事件自 UTC 纪元以来使用毫秒(因此由于 +2 时区,我得到了 2 个额外的小时)。

我还尝试计算和添加时区偏移量。然后一整天的活动都很好,但其他一切......不是。

private long getTimezoneOffset(TimeZone zone, long date) {
    long delta = zone.getOffset(date);
    return delta;
}

private long getTimeInUTC(Calendar date) {
    long time = date.getTimeInMillis();
    time += getTimezoneOffset(date.getTimeZone(), time);
    return time;
}

public Cursor fetchCursor(Calendar start) {
    Calendar end = (Calendar) start.clone();
    end.add(Calendar.DATE, 1);

    long startTime = getTimeInUTC(start) + 1;
    long endTime = getTimeInUTC(end) - 1;

    ContentResolver resolver = mContext.getContentResolver();
    return CalendarContract.Instances.query(resolver, projection, startTime, endTime);
}

虽然通过遍历光标、更改 ALL_DAY 事件和删除不必要的事件来解决此问题很简单,但我想知道是否有更好的方法。或者也许这是Android错误?但如果这是一个错误,那么为什么系统日历可以正常工作?这种不一致的行为对我来说似乎很奇怪。

谢谢。

【问题讨论】:

  • 你能发布一个你如何手动执行此操作的示例吗?我很困惑
  • 是的,google 的日历 api 似乎有很多错误......这个 api 中有很多非常童年和愚蠢的错误:(
  • 现在是 2014 年,错误似乎仍然存在...... ALL_DAY 事件使用时区而不是 UTC,因为它们应该。请参阅此错误报告:code.google.com/p/android/issues/detail?id=14051
  • 你有没有解决过如何优雅地处理这个问题?否则我会悬赏它!正在为完全相同的问题而苦苦挣扎。
  • 我提出了类似的问题,我悬赏:stackoverflow.com/questions/27516398/…。不过,似乎可行的一个技巧是在显示 all_day 事件时将格式化程序设置为 UTC。例如。 if (isAllDay) formatter.setTimeZone (TimeZone.getTimeZone ("UTC"));

标签: android android-4.0-ice-cream-sandwich android-calendar


【解决方案1】:

Calendar api 也依赖于某些设备,您的代码在Android - 4.4.4 KitKat 中运行良好,但在其他设备中却没有。以下代码在我测试过的所有设备上都能完美运行。

试试这个:

public Cursor fetchCursor(Calendar start) {
    Calendar end = (Calendar) start.clone();
    end.add(Calendar.DATE, 1);
    ContentResolver resolver = this.getContentResolver();
    return CalendarContract.Instances.query(resolver,  new String[] { "calendar_id", "title", "description",
                "dtstart", "dtend", "eventLocation" }, start.getTimeInMillis(),
                end.getTimeInMillis());
}

【讨论】:

    猜你喜欢
    • 2014-08-13
    • 1970-01-01
    • 1970-01-01
    • 2013-03-06
    • 2013-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    相关资源
    最近更新 更多