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 ; ListActivity
termasuk ListAdapter
properti tempat kami mengatur adaptor.
Berikut adalah cuplikan layar yang memperlihatkan hasil akhir, dengan info kalender ditampilkan di ListView
:
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. EventListActivity
Dalam 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:
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:
- Buat
ContentValues
instans. - Gunakan kunci dari
CalendarContract.Events.InterfaceConsts
kelas untuk mengisiContentValues
instans. - Atur zona waktu untuk waktu mulai dan berakhir peristiwa.
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:
Jika kita membuka aplikasi kalender, maka kita akan melihat bahwa acara ditulis di sana juga:
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.