Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Interfejs API kalendarza
Nowy zestaw interfejsów API kalendarza wprowadzony w systemie Android 4 obsługuje aplikacje przeznaczone do odczytywania lub zapisywania danych u dostawcy kalendarza. Te interfejsy API obsługują wiele opcji interakcji z danymi kalendarza, w tym możliwość odczytywania i zapisywania zdarzeń, uczestników i przypomnień. Korzystając z dostawcy kalendarza w aplikacji, dane dodawane za pośrednictwem interfejsu API będą wyświetlane w wbudowanej aplikacji kalendarza dostarczanej z systemem Android 4.
Dodawanie uprawnień
Podczas pracy z nowymi interfejsami API kalendarza w aplikacji należy najpierw dodać odpowiednie uprawnienia do manifestu systemu Android. Uprawnienia, które należy dodać, to android.permisson.READ_CALENDAR i android.permission.WRITE_CALENDAR, w zależności od tego, czy odczytujesz i/lub zapisujesz dane kalendarza.
Korzystanie z kontraktu kalendarza
Po ustawieniu uprawnień możesz wchodzić w interakcje z danymi kalendarza przy użyciu CalendarContract klasy . Ta klasa udostępnia model danych, którego aplikacje mogą używać podczas interakcji z dostawcą kalendarza. Aplikacja CalendarContract umożliwia aplikacjom rozpoznawanie jednostki kalendarza, takich jak kalendarze i zdarzenia. Umożliwia również interakcję z różnymi polami w każdej jednostce, takimi jak nazwa i identyfikator kalendarza, lub data rozpoczęcia i zakończenia zdarzenia.
Przyjrzyjmy się przykładowi korzystającego z interfejsu API kalendarza. W tym przykładzie sprawdzimy, jak wyliczać kalendarze i ich wydarzenia, a także jak dodawać nowe wydarzenie do kalendarza.
Wyświetlanie listy kalendarzy
Najpierw sprawdźmy, jak wyliczyć kalendarze zarejestrowane w aplikacji kalendarza. W tym celu możemy utworzyć wystąpienie obiektu CursorLoader. Wprowadzony w systemie Android 3.0 (interfejs API 11) CursorLoader jest preferowanym sposobem korzystania z programu ContentProvider. Co najmniej musimy określić identyfikator URI zawartości dla kalendarzy i kolumn, które chcemy zwrócić; ta specyfikacja kolumny jest znana jako projekcja.
CursorLoader.LoadInBackground Wywołanie metody umożliwia wykonywanie zapytań o dostawcę zawartości dla danych, takich jak dostawca kalendarza.
LoadInBackground wykonuje rzeczywistą operację ładowania i zwraca element Cursor z wynikami zapytania.
Pomaga CalendarContract nam określić zarówno zawartość Uri , jak i projekcję. Aby uzyskać zawartość Uri do wykonywania zapytań dotyczących kalendarzy, możemy po prostu użyć właściwości podobnej do następującej CalendarContract.Calendars.ContentUri :
var calendarsUri = CalendarContract.Calendars.ContentUri;
Użyj elementu , CalendarContract aby określić, które kolumny kalendarza chcemy, są równie proste. Wystarczy dodać pola w CalendarContract.Calendars.InterfaceConsts klasie do tablicy. Na przykład następujący kod zawiera identyfikator kalendarza, nazwę wyświetlaną i nazwę konta:
string[] calendarsProjection = {
CalendarContract.Calendars.InterfaceConsts.Id,
CalendarContract.Calendars.InterfaceConsts.CalendarDisplayName,
CalendarContract.Calendars.InterfaceConsts.AccountName
};
Jest Id to ważne, jeśli używasz elementu SimpleCursorAdapter do powiązania danych z interfejsem użytkownika, jak wkrótce zobaczymy. Po utworzeniu identyfikatora URI zawartości i projekcji CursorLoader tworzymy wystąpienie metody i wywołujemy CursorLoader.LoadInBackground metodę , aby zwrócić kursor z danymi kalendarza, jak pokazano poniżej:
var loader = new CursorLoader(this, calendarsUri, calendarsProjection, null, null, null);
var cursor = (ICursor)loader.LoadInBackground();
Interfejs użytkownika dla tego przykładu zawiera element ListViewz każdym elementem na liście reprezentującym pojedynczy kalendarz. Poniższy kod XML przedstawia znaczniki, które obejmują element ListView:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="@android:id/android:list"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Ponadto musimy określić interfejs użytkownika dla każdego elementu listy, który umieszczamy w osobnym pliku XML w następujący sposób:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView android:id="@+id/calDisplayName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16dip" />
<TextView android:id="@+id/calAccountName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12dip" />
</LinearLayout>
Od tego momentu jest to zwykły kod systemu Android, aby powiązać dane z kursora z interfejsu użytkownika. Użyjemy elementu w SimpleCursorAdapter następujący sposób:
string[] sourceColumns = {
CalendarContract.Calendars.InterfaceConsts.CalendarDisplayName,
CalendarContract.Calendars.InterfaceConsts.AccountName };
int[] targetResources = {
Resource.Id.calDisplayName, Resource.Id.calAccountName };
SimpleCursorAdapter adapter = new SimpleCursorAdapter (this,
Resource.Layout.CalListItem, cursor, sourceColumns, targetResources);
ListAdapter = adapter;
W powyższym kodzie adapter pobiera kolumny określone w sourceColumns tablicy i zapisuje je w elementach interfejsu użytkownika w targetResources tablicy dla każdego wpisu kalendarza w kursorze. Działanie używane w tym miejscu jest podklasą ListActivity; zawiera ListAdapter właściwość, do której ustawiamy adapter.
Oto zrzut ekranu przedstawiający wynik końcowy z informacjami kalendarza wyświetlanymi w pliku ListView:
Wyświetlanie listy zdarzeń kalendarza
Następnie przyjrzyjmy się, jak wyliczyć zdarzenia dla danego kalendarza. Korzystając z powyższego przykładu, przedstawimy listę zdarzeń, gdy użytkownik wybierze jeden z kalendarzy. W związku z tym musimy obsłużyć wybór elementu w poprzednim kodzie:
ListView.ItemClick += (sender, e) => {
int i = (e as ItemEventArgs).Position;
cursor.MoveToPosition(i);
int calId =
cursor.GetInt (cursor.GetColumnIndex (calendarsProjection [0]));
var showEvents = new Intent(this, typeof(EventListActivity));
showEvents.PutExtra("calId", calId);
StartActivity(showEvents);
};
W tym kodzie tworzysz intencję, aby otworzyć działanie typu EventListActivity, przekazując identyfikator kalendarza w intencji. Będziemy potrzebować identyfikatora, aby wiedzieć, który kalendarz będzie wysyłać zapytania dotyczące zdarzeń. W metodzie EventListActivity"s OnCreate " możemy pobrać identyfikator z obiektu , Intent jak pokazano poniżej:
_calId = Intent.GetIntExtra ("calId", -1);
Teraz odpytujmy zdarzenia dla tego identyfikatora kalendarza. Proces wykonywania zapytań o zdarzenia jest podobny do sposobu, w jaki wykonaliśmy zapytanie o listę kalendarzy wcześniej, tym razem będziemy pracować z klasą CalendarContract.Events . Poniższy kod tworzy zapytanie w celu pobrania zdarzeń:
var eventsUri = CalendarContract.Events.ContentUri;
string[] eventsProjection = {
CalendarContract.Events.InterfaceConsts.Id,
CalendarContract.Events.InterfaceConsts.Title,
CalendarContract.Events.InterfaceConsts.Dtstart
};
var loader = new CursorLoader(this, eventsUri, eventsProjection,
String.Format ("calendar_id={0}", _calId), null, "dtstart ASC");
var cursor = (ICursor)loader.LoadInBackground();
W tym kodzie najpierw uzyskujemy zawartość Uri zdarzeń z CalendarContract.Events.ContentUri właściwości . Następnie określamy kolumny zdarzeń, które chcemy pobrać w tablicy eventsProjection.
Na koniec utworzymy wystąpienie CursorLoader elementu za pomocą tych informacji i wywołamy metodę modułu ładującego LoadInBackground , aby zwrócić Cursor element z danymi zdarzenia.
Aby wyświetlić dane zdarzenia w interfejsie użytkownika, możemy użyć znaczników i kodu tak jak wcześniej, aby wyświetlić listę kalendarzy. Ponownie użyjemy polecenia SimpleCursorAdapter , aby powiązać dane z elementem ListView , jak pokazano w poniższym kodzie:
string[] sourceColumns = {
CalendarContract.Events.InterfaceConsts.Title,
CalendarContract.Events.InterfaceConsts.Dtstart };
int[] targetResources = {
Resource.Id.eventTitle,
Resource.Id.eventStartDate };
var adapter = new SimpleCursorAdapter (this, Resource.Layout.EventListItem,
cursor, sourceColumns, targetResources);
adapter.ViewBinder = new ViewBinder ();
ListAdapter = adapter;
Główną różnicą między tym kodem a kodem użytym wcześniej do pokazania listy kalendarzy jest użycie elementu ViewBinder, który jest ustawiony w wierszu:
adapter.ViewBinder = new ViewBinder ();
Klasa ViewBinder umożliwia nam dalszą kontrolę nad tym, jak wiążemy wartości z widokami. W tym przypadku używamy go do konwertowania czasu rozpoczęcia zdarzenia z milisekund na ciąg daty, jak pokazano w następującej implementacji:
class ViewBinder : Java.Lang.Object, SimpleCursorAdapter.IViewBinder
{
public bool SetViewValue (View view, Android.Database.ICursor cursor,
int columnIndex)
{
if (columnIndex == 2) {
long ms = cursor.GetLong (columnIndex);
DateTime date = new DateTime (1970, 1, 1, 0, 0, 0,
DateTimeKind.Utc).AddMilliseconds (ms).ToLocalTime ();
TextView textView = (TextView)view;
textView.Text = date.ToLongDateString ();
return true;
}
return false;
}
}
Spowoduje to wyświetlenie listy zdarzeń, jak pokazano poniżej:
Dodawanie zdarzenia kalendarza
Widzieliśmy, jak odczytywać dane kalendarza. Teraz zobaczmy, jak dodać zdarzenie do kalendarza. Aby to zadziałało, pamiętaj o dołączeniu wspomnianego android.permission.WRITE_CALENDAR wcześniej uprawnienia. Aby dodać zdarzenie do kalendarza, będziemy:
- Utwórz
ContentValueswystąpienie. - Użyj kluczy z
CalendarContract.Events.InterfaceConstsklasy, aby wypełnićContentValueswystąpienie. - Ustaw strefy czasowe dla godzin rozpoczęcia i zakończenia zdarzenia.
- Użyj kontrolki ,
ContentResolveraby wstawić dane zdarzenia do kalendarza.
Poniższy kod ilustruje następujące kroki:
ContentValues eventValues = new ContentValues ();
eventValues.Put (CalendarContract.Events.InterfaceConsts.CalendarId,
_calId);
eventValues.Put (CalendarContract.Events.InterfaceConsts.Title,
"Test Event from M4A");
eventValues.Put (CalendarContract.Events.InterfaceConsts.Description,
"This is an event created from Xamarin.Android");
eventValues.Put (CalendarContract.Events.InterfaceConsts.Dtstart,
GetDateTimeMS (2011, 12, 15, 10, 0));
eventValues.Put (CalendarContract.Events.InterfaceConsts.Dtend,
GetDateTimeMS (2011, 12, 15, 11, 0));
eventValues.Put(CalendarContract.Events.InterfaceConsts.EventTimezone,
"UTC");
eventValues.Put(CalendarContract.Events.InterfaceConsts.EventEndTimezone,
"UTC");
var uri = ContentResolver.Insert (CalendarContract.Events.ContentUri,
eventValues);
Pamiętaj, że jeśli nie ustawimy strefy czasowej, zostanie zgłoszony wyjątek typu Java.Lang.IllegalArgumentException . Ponieważ wartości czasu zdarzenia muszą być wyrażone w milisekundach od epoki, tworzymy metodę GetDateTimeMS (w EventListActivity), aby przekonwertować nasze specyfikacje dat na format milisekund:
long GetDateTimeMS (int yr, int month, int day, int hr, int min)
{
Calendar c = Calendar.GetInstance (Java.Util.TimeZone.Default);
c.Set (Java.Util.CalendarField.DayOfMonth, 15);
c.Set (Java.Util.CalendarField.HourOfDay, hr);
c.Set (Java.Util.CalendarField.Minute, min);
c.Set (Java.Util.CalendarField.Month, Calendar.December);
c.Set (Java.Util.CalendarField.Year, 2011);
return c.TimeInMillis;
}
Jeśli dodamy przycisk do interfejsu użytkownika listy zdarzeń i uruchomimy powyższy kod w procedurze obsługi zdarzeń kliknięcia przycisku, zdarzenie zostanie dodane do kalendarza i zaktualizowane na naszej liście, jak pokazano poniżej:
Jeśli otworzymy aplikację kalendarza, zobaczymy, że zdarzenie jest tam również zapisywane:
Jak widać, system Android umożliwia zaawansowany i łatwy dostęp do pobierania i utrwalania danych kalendarza, dzięki czemu aplikacje mogą bezproblemowo integrować funkcje kalendarza.



