Xamarin.Android Takvimi

Takvim API'si

Android 4'te kullanıma sunulan yeni bir takvim API'leri kümesi, takvim sağlayıcısına veri okumak veya yazmak için tasarlanmış uygulamaları destekler. Bu API'ler etkinlikleri, katılımcıları ve anımsatıcıları okuma ve yazma özelliği de dahil olmak üzere takvim verileriyle çok sayıda etkileşim seçeneğini destekler. Uygulamanızda takvim sağlayıcısını kullanarak, API aracılığıyla eklediğiniz veriler Android 4 ile birlikte gelen yerleşik takvim uygulamasında görünür.

İzin Ekleme

Uygulamanızdaki yeni takvim API'leriyle çalışırken yapmanız gereken ilk şey Android bildirimine uygun izinleri eklemektir. Takvim verilerini okumanıza ve/veya yazmanıza bağlı olarak eklemeniz gereken izinler ve android.permission.WRITE_CALENDARşeklindedirandroid.permisson.READ_CALENDAR.

Takvim Sözleşmesini Kullanma

İzinleri ayarladıktan sonra, sınıfını CalendarContract kullanarak takvim verileriyle etkileşim kurabilirsiniz. Bu sınıf, uygulamaların takvim sağlayıcısıyla etkileşime geçtiğinde kullanabileceği bir veri modeli sağlar. , CalendarContract uygulamaların Uris'i takvimler ve etkinlikler gibi takvim varlıklarına çözümlemesine olanak tanır. Ayrıca, her varlıktaki takvim adı ve kimliği veya bir olayın başlangıç ve bitiş tarihi gibi çeşitli alanlarla etkileşim kurmanın bir yolunu sağlar.

Şimdi Takvim API'sini kullanan bir örneğe bakalım. Bu örnekte, takvimleri ve etkinliklerini listelemenin yanı sıra takvime yeni bir olay eklemeyi inceleyeceğiz.

Takvimleri Listeleme

İlk olarak, takvim uygulamasında kaydedilmiş takvimlerin nasıl numaralandırıldığını inceleyelim. Bunu yapmak için bir CursorLoaderörneği oluşturabiliriz. Android 3.0'da (API 11) CursorLoader kullanıma sunulan, bir ContentProviderkullanmanın tercih edilen yoludur. En azından takvimler ve döndürmek istediğimiz sütunlar için içerik Uri'sini belirtmemiz gerekir; bu sütun belirtimi projeksiyon olarak bilinir.

yöntemini çağırmak CursorLoader.LoadInBackground , takvim sağlayıcısı gibi veriler için bir içerik sağlayıcısı sorgulamamıza olanak tanır. LoadInBackground gerçek yükleme işlemini gerçekleştirir ve sorgunun sonuçlarıyla birlikte bir Cursor döndürür.

hem CalendarContract içeriği Uri hem de projeksiyonu belirtmemize yardımcı olur. Takvimleri sorgulama içeriğini Uri almak için özelliğini şu şekilde kullanabiliriz CalendarContract.Calendars.ContentUri :

var calendarsUri = CalendarContract.Calendars.ContentUri;

CalendarContract hangi takvim sütunlarını istediğimizi belirtmek için kullanmak eşit derecede basittir. Yalnızca sınıfındaki CalendarContract.Calendars.InterfaceConsts alanları bir diziye ekleriz. Örneğin, aşağıdaki kod takvimin kimliğini, görünen adını ve hesap adını içerir:

string[] calendarsProjection = {
    CalendarContract.Calendars.InterfaceConsts.Id,
    CalendarContract.Calendars.InterfaceConsts.CalendarDisplayName,
    CalendarContract.Calendars.InterfaceConsts.AccountName
};

Id kısa süre içinde göreceğimiz gibi, kullanıcı arabirimine veri bağlamak için bir SimpleCursorAdapter kullanıyorsanız dahil edilmesi önemlidir. İçerik Uri'sini ve projeksiyonu hazırlayarak ve yöntemini çağırarak CursorLoader.LoadInBackground aşağıda gösterildiği gibi takvim verilerini içeren bir imleç döndüreceğizCursorLoader:

var loader = new CursorLoader(this, calendarsUri, calendarsProjection, null, null, null);
var cursor = (ICursor)loader.LoadInBackground();

Bu örneğin kullanıcı arabirimi, listedeki her öğenin tek bir ListViewtakvimi temsil eden bir öğesini içerir. Aşağıdaki XML, öğesini içeren işaretlemeyi ListViewgösterir:

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

Ayrıca, ayrı bir XML dosyasına yerleştirdiğimiz her liste öğesi için kullanıcı arabirimini aşağıdaki gibi belirtmemiz gerekir:

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

Bu noktadan sonra, verileri imleçten kullanıcı arabirimine bağlamak normal Android kodundan ibarettir. Aşağıdaki gibi bir SimpleCursorAdapter kullanacağız:

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;

Yukarıdaki kodda, bağdaştırıcı dizide belirtilen sütunları alır ve imleçteki sourceColumns her takvim girdisi için dizideki targetResources kullanıcı arabirimi öğelerine yazar. Burada kullanılan Etkinlik bir alt sınıfıdır ListActivity; bağdaştırıcıyı ListAdapter ayarladığımız özelliği içerir.

Burada, içinde takvim bilgilerinin görüntülendiği ListViewbitiş sonucunu gösteren bir ekran görüntüsü vardır:

İki takvim girdisini görüntüleyen öykünücüde çalışan CalendarDemo

Takvim Olaylarını Listeleme

Şimdi belirli bir takvim için olayları nasıl numaralandıracaklarına bakalım. Yukarıdaki örnekten sonra, kullanıcı takvimlerden birini seçtiğinde olayların listesini sunacağız. Bu nedenle, önceki kodda öğe seçimini işlememiz gerekir:

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

Bu kodda, Takvimin Kimliğini Intent'e geçirerek türünde EventListActivitybir Etkinlik açmak için bir Intent oluşturuyoruz. Olaylar için hangi takvimin sorgulanacağına ilişkin kimliği bilmemiz gerekir. 's OnCreate yöntemindeEventListActivity, kimliği aşağıda gösterildiği gibi dosyasından Intent aebiliriz:

_calId = Intent.GetIntExtra ("calId", -1);

Şimdi bu takvim kimliği için olayları sorgulayalım. Olayları sorgulama işlemi, daha önce bir takvim listesi için sorguladığımıza benzer, ancak bu kez sınıfıyla CalendarContract.Events çalışacağız. Aşağıdaki kod olayları almak için bir sorgu oluşturur:

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

Bu kodda, önce özelliğinden CalendarContract.Events.ContentUri olaylar için içeriği Uri alacağız. Ardından eventsProjection dizisinde almak istediğimiz olay sütunlarını belirtiriz. Son olarak, bu bilgilerle bir CursorLoader örneği oluşturur ve olay verileriyle bir döndürmek Cursor için yükleyicinin LoadInBackground yöntemini çağırırız.

Olay verilerini kullanıcı arabiriminde görüntülemek için, takvim listesini görüntülemek için daha önce yaptığımız gibi işaretlemeyi ve kodu kullanabiliriz. Yine, aşağıdaki kodda gösterildiği gibi verileri bir'e ListView bağlamak için kullanırızSimpleCursorAdapter:

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;

Bu kod ile daha önce takvim listesini göstermek için kullandığımız kod arasındaki temel fark, satırda ayarlanan bir ViewBinderkullanımıdır:

adapter.ViewBinder = new ViewBinder ();

sınıfı, ViewBinder değerleri görünümlere nasıl bağlayacağımızı daha fazla denetlememize olanak tanır. Bu durumda, olay başlangıç zamanını aşağıdaki uygulamada gösterildiği gibi milisaniyeden tarih dizesine dönüştürmek için kullanırız:

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

Aşağıda gösterildiği gibi olayların listesi görüntülenir:

Üç takvim olayını görüntüleyen örnek uygulamanın ekran görüntüsü

Takvim Olayı Ekleme

Takvim verilerini nasıl okuyacağımızı gördük. Şimdi bir takvime nasıl etkinlik ekleneceğini görelim. Bunun işe yarayacağı için, daha önce bahsettiğimiz izni eklediğinizden android.permission.WRITE_CALENDAR emin olun. Takvime etkinlik eklemek için şunları yapacağız:

  1. Örnek ContentValues oluşturma.
  2. Örneği doldurmak için sınıfından ContentValues anahtarları CalendarContract.Events.InterfaceConsts kullanın.
  3. Olay başlangıç ve bitiş saatlerinin saat dilimlerini ayarlayın.
  4. Olay verilerini takvime eklemek için bir ContentResolver kullanın.

Aşağıdaki kodda şu adımlar gösterilmektedir:

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

Saat dilimini ayarlamazsak türünde Java.Lang.IllegalArgumentException bir özel durum oluşturulacağını unutmayın. Olay zamanı değerlerinin dönemden bu yana milisaniye cinsinden ifade edilmesi gerektiğinden, tarih belirtimlerimizi milisaniye biçimine dönüştürmek için bir GetDateTimeMS yöntem (içinde EventListActivity) oluştururuz:

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

Olay listesi kullanıcı arabirimine bir düğme ekler ve düğmenin tıklama olay işleyicisinde yukarıdaki kodu çalıştırırsak, olay takvime eklenir ve aşağıda gösterildiği gibi listemizde güncelleştirilir:

Takvim olaylarının ardından Örnek Olay Ekle düğmesinin yer aldığı örnek uygulamanın ekran görüntüsü

Takvim uygulamasını açarsak etkinliğin de orada yazıldığını görürüz:

Seçili takvim olayını görüntüleyen takvim uygulamasının ekran görüntüsü

Gördüğünüz gibi Android, uygulamaların takvim özelliklerini sorunsuz bir şekilde tümleştirmesine olanak tanıyarak takvim verilerini almak ve kalıcı hale getirmek için güçlü ve kolay erişim sağlar.