Bagikan melalui


Kalender Xamarin.Android

API Kalender

Sekumpulan API kalender baru yang diperkenalkan di Android 4 mendukung aplikasi yang dirancang untuk membaca atau menulis data ke penyedia kalender. API ini mendukung banyak opsi interaksi dengan data kalender, termasuk kemampuan untuk membaca dan menulis acara, peserta, dan pengingat. Dengan menggunakan penyedia kalender di aplikasi Anda, data yang Anda tambahkan melalui API akan muncul di aplikasi kalender bawaan yang dilengkapi dengan Android 4.

Menambahkan Izin

Saat bekerja dengan API kalender baru di aplikasi Anda, hal pertama yang perlu Anda lakukan adalah menambahkan izin yang sesuai ke manifes Android. Izin yang perlu Anda tambahkan adalah android.permisson.READ_CALENDAR dan android.permission.WRITE_CALENDAR, tergantung pada apakah Anda membaca dan/atau menulis data kalender.

Menggunakan Kontrak Kalender

Setelah mengatur izin, Anda dapat berinteraksi dengan data kalender dengan menggunakan CalendarContract kelas . Kelas ini menyediakan model data yang dapat digunakan aplikasi saat berinteraksi dengan penyedia kalender. memungkinkan CalendarContract aplikasi untuk menyelesaikan Uri ke entitas kalender, seperti kalender dan acara. Ini juga menyediakan cara untuk berinteraksi dengan berbagai bidang di setiap entitas, seperti nama dan ID kalender, atau tanggal mulai dan selesai acara.

Mari kita lihat contoh yang menggunakan API Kalender. Dalam contoh ini, kita akan memeriksa cara menghitung kalender dan acaranya, serta cara menambahkan acara baru ke kalender.

Daftar Kalender

Pertama, mari kita periksa cara menghitung kalender yang telah terdaftar di aplikasi kalender. Untuk melakukan ini, kita dapat membuat instans CursorLoader. Diperkenalkan di Android 3.0 (API 11), CursorLoader adalah cara yang lebih disukai untuk menggunakan ContentProvider. Minimal, kita harus menentukan Uri konten untuk kalender dan kolom yang ingin kita kembalikan; spesifikasi kolom ini dikenal sebagai proyeksi.

Memanggil CursorLoader.LoadInBackground metode memungkinkan kami mengkueri penyedia konten untuk data, seperti penyedia kalender. LoadInBackground melakukan operasi pemuatan aktual Cursor dan mengembalikan dengan hasil kueri.

Membantu CalendarContract kami menentukan konten Uri dan proyeksi. Untuk mendapatkan konten Uri untuk mengkueri kalender, kita cukup menggunakan CalendarContract.Calendars.ContentUri properti seperti ini:

var calendarsUri = CalendarContract.Calendars.ContentUri;

CalendarContract Menggunakan untuk menentukan kolom kalender mana yang kita inginkan yang sama-sama sederhana. Kami hanya menambahkan bidang di kelas ke CalendarContract.Calendars.InterfaceConsts array. Misalnya, kode berikut menyertakan ID kalender, nama tampilan, dan nama akun:

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

Id Penting untuk disertakan jika Anda menggunakan SimpleCursorAdapter untuk mengikat data ke UI, seperti yang akan segera kita lihat. Dengan konten Uri dan proyeksi di tempat, kami membuat instans CursorLoader dan memanggil CursorLoader.LoadInBackground metode untuk mengembalikan kursor dengan data kalender seperti yang ditunjukkan di bawah ini:

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

UI untuk contoh ini berisi ListView, dengan setiap item dalam daftar yang mewakili satu kalender. XML berikut menunjukkan markup yang menyertakan 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>

Selain itu, kita perlu menentukan UI untuk setiap item daftar, yang kita tempatkan dalam file XML terpisah sebagai berikut:

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

Mulai saat ini, hanya kode Android normal untuk mengikat data dari kursor ke UI. Kami akan menggunakan SimpleCursorAdapter sebagai berikut:

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;

Dalam kode di atas, adaptor mengambil kolom yang ditentukan dalam sourceColumns array dan menulisnya ke elemen antarmuka pengguna dalam targetResources array untuk setiap entri kalender dalam kursor. Aktivitas yang digunakan di sini adalah subkelas ; ListActivitytermasuk ListAdapter properti tempat kami mengatur adaptor.

Berikut adalah cuplikan layar yang memperlihatkan hasil akhir, dengan info kalender ditampilkan di ListView:

CalendarDemo berjalan di emulator, menampilkan dua entri kalender

Mencantumkan Acara Kalender

Selanjutnya mari kita lihat cara menghitung acara untuk kalender tertentu. Berdasarkan contoh di atas, kami akan menyajikan daftar acara saat pengguna memilih salah satu kalender. Oleh karena itu, kita harus menangani pemilihan item di kode sebelumnya:

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

Dalam kode ini, kami membuat Niat untuk membuka Aktivitas jenis EventListActivity, meneruskan ID kalender dalam Niat. Kita akan memerlukan ID untuk mengetahui kalender mana yang akan dikueri untuk acara. EventListActivityDalam metode iniOnCreate, kita dapat mengambil ID dari seperti yang ditunjukkan Intent di bawah ini:

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

Sekarang mari kita kueri peristiwa untuk ID kalender ini. Proses untuk mengkueri peristiwa mirip dengan cara kami mengkueri daftar kalender sebelumnya, hanya kali ini kita akan bekerja dengan CalendarContract.Events kelas . Kode berikut membuat kueri untuk mengambil peristiwa:

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

Dalam kode ini, pertama-tama kita mendapatkan konten Uri untuk peristiwa dari CalendarContract.Events.ContentUri properti . Kemudian kita menentukan kolom peristiwa yang ingin kita ambil dalam array eventsProjection. Terakhir, kami membuat instans CursorLoader dengan informasi ini dan memanggil metode loader LoadInBackground untuk mengembalikan Cursor dengan data peristiwa.

Untuk menampilkan data peristiwa di UI, kita dapat menggunakan markup dan kode seperti yang kita lakukan sebelumnya untuk menampilkan daftar kalender. Sekali lagi, kami menggunakan SimpleCursorAdapter untuk mengikat data ke seperti yang ListView ditunjukkan dalam kode berikut:

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;

Perbedaan utama antara kode ini dan kode yang kami gunakan sebelumnya untuk menampilkan daftar kalender adalah penggunaan ViewBinder, yang diatur pada baris:

adapter.ViewBinder = new ViewBinder ();

Kelas ini ViewBinder memungkinkan kami mengontrol lebih lanjut bagaimana kami mengikat nilai ke tampilan. Dalam hal ini, kami menggunakannya untuk mengonversi waktu mulai peristiwa dari milidetik menjadi string tanggal, seperti yang ditunjukkan dalam implementasi berikut:

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

Ini menampilkan daftar peristiwa seperti yang ditunjukkan di bawah ini:

Cuplikan layar contoh aplikasi yang menampilkan tiga acara kalender

Menambahkan Acara Kalender

Kami telah melihat cara membaca data kalender. Sekarang mari kita lihat cara menambahkan acara ke kalender. Agar ini berfungsi, pastikan untuk menyertakan izin yang android.permission.WRITE_CALENDAR kami sebutkan sebelumnya. Untuk menambahkan acara ke kalender, kami akan:

  1. Buat ContentValues instans.
  2. Gunakan kunci dari CalendarContract.Events.InterfaceConsts kelas untuk mengisi ContentValues instans.
  3. Atur zona waktu untuk waktu mulai dan berakhir peristiwa.
  4. ContentResolver Gunakan untuk menyisipkan data peristiwa ke dalam kalender.

Kode di bawah ini mengilustrasikan langkah-langkah berikut:

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

Perhatikan bahwa jika kita tidak mengatur zona waktu, pengecualian jenis Java.Lang.IllegalArgumentException akan dilemparkan. Karena nilai waktu peristiwa harus dinyatakan dalam milidetik sejak zaman, kami membuat GetDateTimeMS metode (dalam EventListActivity) untuk mengonversi spesifikasi tanggal menjadi format milidetik:

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

Jika kita menambahkan tombol ke antarmuka pengguna daftar acara dan menjalankan kode di atas di tombol klik penanganan aktivitas, acara ditambahkan ke kalender dan diperbarui dalam daftar kami seperti yang ditunjukkan di bawah ini:

Cuplikan layar aplikasi contoh dengan acara kalender diikuti dengan tombol Tambahkan Peristiwa Sampel

Jika kita membuka aplikasi kalender, maka kita akan melihat bahwa acara ditulis di sana juga:

Cuplikan layar aplikasi kalender yang menampilkan acara kalender yang dipilih

Seperti yang Anda lihat, Android memungkinkan akses yang kuat dan mudah untuk mengambil dan mempertahankan data kalender, memungkinkan aplikasi untuk mengintegrasikan kemampuan kalender dengan mulus.