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 ContentProvider
kullanmanı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 ListView
takvimi temsil eden bir öğesini içerir. Aşağıdaki XML, öğesini içeren işaretlemeyi ListView
gö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 ListView
bitiş sonucunu gösteren bir ekran görüntüsü vardır:
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 EventListActivity
bir 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 ViewBinder
kullanı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ı 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:
- Örnek
ContentValues
oluşturma. - Örneği doldurmak için sınıfından
ContentValues
anahtarlarıCalendarContract.Events.InterfaceConsts
kullanın. - Olay başlangıç ve bitiş saatlerinin saat dilimlerini ayarlayın.
- 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 uygulamasını açarsak etkinliğin de orada yazıldığını görürüz:
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.