2012-02-07 12 views
9

Dzięki ICS mamy teraz interfejsy API dla kalendarza! :)Jaki jest najlepszy sposób na obsługę aktualizacji, gdy kalendarz synchronizuje nowe zdarzenia?

Moje pytanie brzmi: jak ustalimy, czy wydarzenie zostało zaktualizowane. Najlepiej byłoby to zrobić za pomocą BroadcastReceiver, ale nie sądzę, że jest publicznie dostępny. Wydarzenie jest transmitowane, ale nie sądzę, aby było dostępne dla aplikacji niesystemowych.

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) 

To jest moja praca na teraz. Czy istnieje lepszy sposób? Użytkownicy widzą usługę działającą przez dłuższy czas i często ją zabijają, aby oszczędzać baterię.

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

Świetna robota wokół teraz. – Adam

+0

z jakiegoś powodu, za każdym razem, gdy utworzę wydarzenie w kalendarzu, otrzymuję powiadomienie wiele razy. dlaczego to się dzieje? –

Odpowiedz

6

używam statyczną klasę singleton (można również rozszerzyć aplikacji) z metod rejestracji/wyrejestrowania wielu obserwatorów różnych dostawców, takich jak dostawcy (-ów) kalendarzowego. Przechowuję to w HashMap, dzięki czemu mogę określić, którzy obserwatorzy są zarejestrowani w późniejszym czasie.

Jest brzydki, ale wydaje się, że nie ma lepszego rozwiązania.

EDIT Odbiornik:

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

Z tej oczywistej deklaracji:

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

złapie zmiany zdarzeń i kalendarzy w ICS. Jeśli korzystasz ze starego nieudokumentowanego dostawcy kalendarza, jedynym rozwiązaniem jest ContentObserver w klasach statycznych lub usługach.

+0

W tym momencie nie ma emisji, więc muszę użyć ContentObserver, co oznacza, że ​​muszę mieć usługę uruchomioną przez cały czas, aby ją odsłuchać ... – runor49

+1

Ten filtr powinien przechwycić transmisję, o której wspomniałeś w swoim pytanie i wydaje się być jedną z metod, którą aplikacja kalendarza giełdowego używa do aktualizacji swojego widgetu (https://github.com/android/platform_packages_apps_calendar/blob/master/src/com/android/calendar/widget/CalendarAppWidgetService.java). Zobacz artykuł CalendarFactory klasa. Jeśli używasz statycznej klasy singleton (lub rozszerzenia aplikacji), nie będziesz musiał korzystać z usługi. To niekoniecznie jest lepsze, po prostu alternatywa, która może pomóc użytkownikom zabić twoją usługę. – roflharrison

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

przechwyci powiadomienie zdarzenie (np: 30 min przed rozpoczęciem imprezy)

Powiązane problemy