2012-02-07 11 views
9

¡Con ICS, ahora tenemos API para el Calendario! :)¿Cuál es la mejor manera de manejar actualizaciones cuando el calendario sincroniza nuevos eventos?

Mi pregunta es, ¿cómo determinamos si un evento ha sido actualizado. Idealmente, esto podría hacerse con un BroadcastReceiver, pero no creo que haya uno que sea públicamente accesible. Hay algún evento transmitido, pero no creo que sea accesible para aplicaciones que no sean del sistema.

02-06 23:05:05.316: I/CalendarProvider2(9201): Sending notification intent: Intent { act=android.intent.action.PROVIDER_CHANGED dat=content://com.android.calendar } 
02-06 23:05:05.320: W/ContentResolver(9201): Failed to get type for: content://com.android.calendar (Unknown URL content://com.android.calendar) 

Este es mi trabajo por el momento. ¿Hay una mejor manera? Los usuarios pueden obtener squimish si ven un servicio en funcionamiento durante mucho tiempo y, a menudo lo matará para ahorrar batería.

public class CalendarUpdatedService extends Service { 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 

     int returnValue = super.onStartCommand(intent, flags, startId); 

     getContentResolver().registerContentObserver(
       CalendarContract.Events.CONTENT_URI, true, observer); 

     return returnValue; 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

    ContentObserver observer = new ContentObserver(new Handler()) { 

     @Override 
     public boolean deliverSelfNotifications() { 
      return true; 
     } 

     @Override 
     public void onChange(boolean selfChange) { 
      super.onChange(selfChange); 

      //code goes here to update 
     } 
    }; 

} 
+0

gran trabajo alrededor por ahora. – Adam

+0

por alguna razón, cada vez que creo un evento en el calendario, me notifican varias veces. ¿por qué está sucediendo? –

Respuesta

6

utilizo una clase Singleton estática (también se puede extender la aplicación) con los métodos para registrar/anular el registro de múltiples observadores diferentes proveedores, tales como el proveedor (s) calendario. Guardo esto en un HashMap para poder determinar qué observadores están registrados más adelante.

Es feo pero no parece ser una solución mejor.

EDITAR Este receptor:

public class CalendarChangedReceiver extends BroadcastReceiver { 
    private static final String TAG = "CalendarChangedReceiver"; 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     Log.d(TAG, "calendar changed! "+intent.toUri(Intent.URI_INTENT_SCHEME)); 
    } 
} 

Con esta declaración manifiesta:

<receiver android:name=".CalendarChangedReceiver"> 
    <intent-filter> 
     <action android:name="android.intent.action.PROVIDER_CHANGED"/> 
     <data android:scheme="content"/> 
     <data android:host="com.android.calendar"/> 
    </intent-filter> 
</receiver> 

cogerá cambios en los eventos y calendarios en ICS. Si está utilizando el antiguo proveedor de calendario no documentado, la única solución es ContentObserver (s) en una clase o servicio estático.

+0

No hay una transmisión en este momento, así que tengo que usar un ContentObserver, lo que significa que tengo que tener un servicio en funcionamiento todo el tiempo para escucharlo ... – runor49

+1

Ese filtro debería captar la transmisión que mencionaste en tu pregunta y parece ser un método que la aplicación de calendario de acciones utiliza para actualizar su widget (https://github.com/android/platform_packages_apps_calendar/blob/master/src/com/android/calendar/widget/CalendarAppWidgetService.java) vea el CalendarioFactory clase. Si usa una clase de Singleton estática (o extiende la Aplicación), entonces no tendrá que usar un servicio. Esto no es necesariamente mejor, solo una alternativa que podría ayudar a los usuarios a eliminar su servicio. – roflharrison

0
<intent-filter> 
     <action android:name="android.intent.action.EVENT_REMINDER" /> 
     <data android:scheme="content"/> 
     <data android:host="com.android.calendar"/> 
    </intent-filter> 

capturará la notificación del evento (por ejemplo: 30 minutos antes del evento)

Cuestiones relacionadas