我写了一个简单的代码,使用官方网站上的教程将日常活动插入日历。 http://developer.android.com/guide/topics/providers/calendar-provider.html
ContentResolver cr = context.getContentResolver();
ContentValues values = new ContentValues();
values.put(Events.DTSTART, dueDate.getTime());
values.put(Events.ALL_DAY, true);
values.put(Events.DTEND, dueDate.getTime());
values.put(Events.TITLE, "Some Event");
values.put(Events.CALENDAR_ID, mCalID);
TimeZone tz = TimeZone.getDefault();
values.put(Events.EVENT_TIMEZONE, tz.getID());
Uri uri = cr.insert(Events.CONTENT_URI, values);
我发现当我在运行4.03的Acer设备上打开Google日历应用时,输入的日期已经转回了1天。我当地的时区是Sydney,GMT + 10。
所以我去设置时将当地时区改为美国东部(GMT -5)并运行相同的代码并且日期没有变化。然后我将时区改为GMT + 2,伊斯坦布尔,日期也发生了变化。然后我改为伦敦GMT 0,没有转变。
当我进行非全天活动时,无论时区如何,都会在日历中输入正确的时间。
我发现的最接近的错误报告就是这个 http://code.google.com/p/android/issues/detail?id=14051
我是否遗漏了代码中的内容,或者其他人也遇到了这个问题。
修改 在使用内容解析器读取事件数据时进一步检查
ContentResolver cr = context.getContentResolver();
Uri uri = CalendarContract.Events.CONTENT_URI;
String selection =CalendarContract.Events._ID + "=?";
String [] selectionArgs = new String[]{String.valueOf(eventID)};
转换为日期时的长度值是正确的日期和时间,例如。 2013年2月14日12.00 AEST(悉尼时间)。因此,问题必须出在Google日历阅读这些值的方式中。当我从Android中的日历应用程序手动添加一整天活动,并使用内容解析器读取时间时,它是AEST(悉尼时间)的日期和上午11点,相当于悉尼的+11 GMT关闭设置。 因此,需要在GMT中输入全天事件以避免这种情况,但在文档中没有提到这一点。
所以现在我正在改变时间,以避免这个问题。
答案 0 :(得分:6)
一些想法:
[1]“如果allDay设置为1,则eventTimezone必须为TIMEZONE_UTC且时间必须对应于午夜边界。”
[2] http://developer.android.com/reference/android/provider/CalendarContract.Events.html
答案 1 :(得分:0)
如果我的活动是一整天活动,我将其转换为当地时间。这使得全天活动保持在正确的日期。如果不是整天,我就像往常一样离开它。我不认为这是一个很好的解决方案,但它有效,如果有人发现问题,请告诉我。
var startDate = yourCalendarEvent.StartDate;
if (yourCalendarEvent.IsAllDay)
{
startDate = startDate.ToLocalTime();
}
Java.Util.GregorianCalendar calStartDate = new Java.Util.GregorianCalendar(startDate.Year, startDate.Month - 1, startDate.Day, startDate.Hour, startDate.Minute, startDate.Second);
intent.PutExtra(CalendarContract.ExtraEventBeginTime, calStartDate.TimeInMillis);
答案 2 :(得分:0)
CalendarContract.EventsColumns状态的文档"如果allDay设置为1,则eventTimezone必须为TIMEZONE_UTC且时间必须对应于午夜边界。"
我确保在查询API后返回预期日期的解决方案是a)设置日期与UTC对齐的开始和结束事件值。 b)调整查询后返回的时间,以考虑设备时区和DST。
A)
@Before
public void setup(){
...
mJavaCalendar = Calendar.getInstance();
mInputStart = getUtcDate(
mJavaCalendar.get(Calendar.YEAR),
mJavaCalendar.get(Calendar.MONTH),
mJavaCalendar.get(Calendar.DAY_OF_MONTH));
}
private long getUtcDate(int year, int month, int day){
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
calendar.set(year, month, day,0, 0, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTimeInMillis();
}
@Test
public void jCalAlldayTzDflt0000To2400(){
mTodayEvent.setEventStart(mInputStart);
mTodayEvent.setEventEnd(mTodayEvent.getEventStart() + DateUtils.DAY_IN_MILLIS);
mTodayEvent.setAllDay(true);
...
}
b)中
public static long getTzAdjustedDate(long date){
TimeZone tzDefault = TimeZone.getDefault();
return date - tzDefault.getOffset(date);
}
public void getCorrectDate(cursor){
isAllDay() == 1 ? DateTimeUtils.getTzAdjustedDate(cursor.getLong(INST_PROJECTION_BEGIN_INDEX)) :
cursor.getLong(INST_PROJECTION_BEGIN_INDEX));
我希望这会有所帮助。