2012-02-07 13 views
9

Con ICS, ora abbiamo le API per il calendario! :)Qual è il modo migliore per gestire gli aggiornamenti quando il calendario sincronizza nuovi eventi?

La mia domanda è, come determinare se un evento è stato aggiornato. Idealmente, questo potrebbe essere fatto con un BroadcastReceiver, ma non credo che ce ne sia uno pubblicamente accessibile. C'è qualche evento trasmesso, ma non penso sia accessibile alle app non di 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) 

Questo è il mio lavoro intorno per ora. C'è un modo migliore? Gli utenti possono diventare schizzinosi se vedono un servizio in esecuzione per lungo tempo e spesso lo uccideranno per risparmiare la durata della batteria.

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

Grande lavoro in giro per ora. – Adam

+0

per qualche motivo, ogni volta che creo un evento nel calendario, ricevo notifiche più volte. perché sta succedendo? –

risposta

6

Io uso una classe Singleton statico (si potrebbe anche estendere Application) con i metodi per registrare/unregister molteplici osservatori per i fornitori diversi, come il provider di calendario (s). Lo memorizzo in una HashMap in modo da poter determinare quali osservatori sono registrati in un secondo momento.

È brutto ma non sembra essere una soluzione migliore.

EDIT Questo ricevitore:

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 questa dichiarazione manifesta:

<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> 

prenderà modifiche agli eventi e calendari a ICS. Se si utilizza il vecchio provider di calendario non documentato, l'unica soluzione è ContentObserver (s) in una classe o un servizio statico.

+0

Non c'è una trasmissione a questo punto, quindi devo usare un ContentObserver, il che significa che devo avere un servizio in esecuzione tutto il tempo per ascoltarlo ... – runor49

+1

Questo filtro dovrebbe intercettare la trasmissione che hai citato nel tuo domanda e sembra essere un metodo che l'app del calendario azionario utilizza per aggiornare il suo widget (https://github.com/android/platform_packages_apps_calendar/blob/master/src/com/android/calendar/widget/CalendarAppWidgetService.java) vedi CalendarFactory classe. Se si utilizza una classe Singleton statica (o si estende l'applicazione), non sarà necessario utilizzare un servizio. Questo non è necessariamente migliore, solo un'alternativa che potrebbe aiutare gli utenti a uccidere il tuo servizio. – roflharrison

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

catturerà la notifica dell'evento (ad esempio: 30 minuti prima dell'inizio della manifestazione)

Problemi correlati