android android-4.0-ice-cream-sandwich android-calendar

Listar eventos para un día específico en Android 4+(problema ALL_DAY)



android-4.0-ice-cream-sandwich android-calendar (1)

Estoy intentando que todos los eventos ocurran en un día seleccionado en Android 4+.

Según tengo entendido, CalendarContract.Instances es la forma más fácil de obtener eventos, ya que maneja tanto eventos recurrentes como eventos de una sola vez.

Sin embargo, tengo algunos problemas con su forma de manejar las marcas de tiempo. Para ser específico, parece tratar los eventos ALL_DAY de manera diferente.

Comencé con el siguiente código ( start es el día en el que voy a buscar eventos, milisegundos "matemáticas" es para evitar eventos innecesarios a partir de las 12 am del día siguiente, el calendario usa la zona horaria predeterminada).

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); }

Este código parece funcionar bien con muchos casos de borde, diferentes zonas horarias, eventos que abarcan varios días ... todo excepto los eventos de todo el día.

Cuando examiné el evento devuelto con el indicador 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 : EVENT(10075): Thu Sep 13 02:00:00 CEST 2012 - Sat Sep 15 02:00:00 CEST 2012 .

Para mí, parece que la query espera que el rango comience y termine en milis desde la época en MY TIMEZONE (aunque la API indica que necesita una marca de tiempo basada en UTC). Pero los eventos marcados como ALL_DAY usan milis desde la época en UTC (así que obtengo 2 horas adicionales debido a la zona horaria +2).

También intenté calcular y agregar la compensación de zona horaria. Entonces todos los eventos del día funcionaron bien, pero todo lo demás ... no.

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); }

Si bien hay una forma bastante fácil de solucionar este problema mediante la iteración sobre el cursor, la modificación de los eventos ALL_DAY y la eliminación de eventos innecesarios, me gustaría saber si existe una mejor manera. O tal vez esto es error de Android? Pero si es un error, ¿por qué el Calendario del sistema funciona bien? Este comportamiento inconsistente me parece extraño.

Gracias.


Calendar api del Calendar también depende del dispositivo, su código funciona perfectamente en Android - 4.4.4 KitKat pero no en otros dispositivos. El siguiente código funciona perfectamente en todos los dispositivos en los que he probado.

Prueba esto:

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()); }