我试图让所有事件在 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错误?但如果这是一个错误,那么为什么系统日历可以正常工作?这种不一致的行为对我来说似乎很奇怪。
谢谢。