1 page.title=Penyedia Kalender 2 @jd:body 3 4 <div id="qv-wrapper"> 5 <div id="qv"> 6 <h2>Dalam dokumen ini</h2> 7 <ol> 8 <li><a href="#overview">Dasar-Dasar</a></li> 9 <li><a href="#manifest">Izin Pengguna</a></li> 10 <li><a href="#calendar">Tabel kalender</a> 11 <ol> 12 <li><a href="#query">Membuat query kalender</a></li> 13 <li><a href="#modify-calendar">Memodifikasi kalender</a></li> 14 <li><a href="#insert-calendar">Menyisipkan kalender</a></li> 15 </ol> 16 </li> 17 <li><a href="#events">Tabel Events</a> 18 <ol> 19 <li><a href="#add-event">Menambahkan Kejadian</a></li> 20 <li><a href="#update-event">Memperbarui Kejadian</a></li> 21 <li><a href="#delete-event">Menghapus Kejadian</a></li> 22 </ol> 23 </li> 24 <li><a href="#attendees">Tabel peserta</a> 25 <ol> 26 <li><a href="#add-attendees">Menambahkan Peserta</a></li> 27 </ol> 28 </li> 29 <li><a href="#reminders">Tabel pengingat</a> 30 <ol> 31 <li><a href="#add-reminders">Menambahkan Pengingat</a></li> 32 </ol> 33 </li> 34 <li><a href="#instances">Tabel Instances</a> 35 <ol> 36 <li><a href="#query-instances">Membuat query tabel Instance</a></li> 37 </ol></li> 38 <li><a href="#intents">Intent Kalender</a> 39 <ol> 40 <li><a href="#intent-insert">Menggunakan intent untuk menyisipkan kejadian</a></li> 41 <li><a href="#intent-edit">Menggunakan intent untuk mengedit kejadian</a></li> 42 <li><a href="#intent-view">Menggunakan intent untuk menampilkan data kalender</a></li> 43 </ol> 44 </li> 45 46 <li><a href="#sync-adapter">Adaptor Sinkronisasi</a></li> 47 </ol> 48 49 <h2>Kelas-kelas utama</h2> 50 <ol> 51 <li>{@link android.provider.CalendarContract.Calendars}</li> 52 <li>{@link android.provider.CalendarContract.Events}</li> 53 <li>{@link android.provider.CalendarContract.Attendees}</li> 54 <li>{@link android.provider.CalendarContract.Reminders}</li> 55 </ol> 56 </div> 57 </div> 58 59 <p>Penyedia Kalender adalah repository untuk kejadian kalender seorang pengguna. API 60 Penyedia Kalender memungkinkan Anda melakukan query, menyisipkan, memperbarui, dan menghapus 61 pada kalender, kejadian, peserta, pengingat, dan seterusnya.</p> 62 63 64 <p>API Penyedia Kalender bisa digunakan oleh aplikasi dan adaptor sinkronisasi. Aturannya 65 bervariasi menurut tipe program yang membuat panggilan. Dokumen ini 66 terutama berfokus pada penggunaan API Penyedia Kalender sebagai sebuah aplikasi. Untuk 67 pembahasan ragam adaptor sinkronisasi, lihat 68 <a href="#sync-adapter">Adaptor Sinkronisasi</a>.</p> 69 70 71 <p>Biasanya, untuk membaca atau menulis data kalender, manifes aplikasi harus 72 berisi izin yang sesuai, yang dijelaskan dalam <a href="#manifest">Izin 73 Pengguna</a>. Untuk mempermudah dilakukannya operasi umum, 74 Penyedia Kalender menyediakan satu set intent, seperti dijelaskan dalam <a href="#intents">Intent 75 Kalender</a>. Semua intent ini membawa pengguna ke aplikasi Kalender untuk menyisipkan, menampilkan, 76 dan mengedit kejadian. Pengguna berinteraksi dengan aplikasi Kalender kemudian 77 kembali ke aplikasi semula. Jadi, aplikasi Anda tidak perlu meminta izin, 78 juga tidak perlu menyediakan antarmuka pengguna untuk menampilkan atau membuat kejadian.</p> 79 80 <h2 id="overview">Dasar-Dasar</h2> 81 82 <p><a href="{@docRoot}guide/topics/providers/content-providers.html">Penyedia konten</a> menyimpan data dan menjadikannya bisa diakses oleh 83 aplikasi. Penyedia konten yang ditawarkan oleh platform Android (termasuk Penyedia Kalender) biasanya mengekspos data sebagai satu set tabel berdasarkan 84 model database relasional, dengan tiap baris berupa record dan tiap kolom berupa data 85 yang memiliki tipe dan arti tertentu. Melalui API Penyedia Kalender, aplikasi 86 dan adaptor sinkronisasi bisa mendapatkan akses baca/tulis ke tabel-tabel database yang menyimpan 87 data kalender seorang pengguna.</p> 88 89 <p>Setiap penyedia konten membuka sebuah URI publik (yang dibungkus sebagai objek 90 {@link android.net.Uri} 91 ) yang mengidentifikasikan set datanya secara unik. Penyedia konten yang mengontrol 92 beberapa set data (beberapa tabel) mengekspos URI terpisah untuk tiap set. Semua 93 URI untuk penyedia diawali dengan string "content://". String ini 94 mengidentifikasi data sebagai dikontrol oleh penyedia konten. Penyedia Kalender 95 mendefinisikan konstanta untuk URI masing-masing kelas (tabel). URI ini 96 memiliki format <code><em><class></em>.CONTENT_URI</code>. Misalnya, 97 {@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI}.</p> 98 99 <p>Gambar 1 menampilkan representasi grafis model data Penyedia Kalender. Gambar ini menampilkan 100 tabel dan bidang utama yang saling berkaitan.</p> 101 102 <img src="{@docRoot}images/providers/datamodel.png" alt="Calendar Provider Data Model" /> 103 <p class="img-caption"><strong>Gambar 1.</strong> Model data Penyedia Kalender.</p> 104 105 <p>Seorang pengguna bisa memiliki beberapa kalender, dan kalender yang berbeda bisa dikaitkan dengan tipe akun yang berbeda (Google Calendar, Exchange, dan seterusnya).</p> 106 107 <p>{@link android.provider.CalendarContract} mendefinisikan model data dari informasi yang terkait dengan kalender dan kejadian. Data ini disimpan di sejumlah tabel, yang dicantumkan di bawah ini.</p> 108 109 <table> 110 <tr> 111 <th>Tabel (Kelas)</th> 112 <th>Keterangan</th> 113 </tr> 114 <tr> 115 <td><p>{@link android.provider.CalendarContract.Calendars}</p></td> 116 117 <td>Tabel ini menyimpan 118 informasi khusus kalender. Tiap baris dalam tabel ini berisi data untuk 119 satu kalender, seperti nama, warna, informasi sinkronisasi, dan seterusnya.</td> 120 </tr> 121 <tr> 122 <td>{@link android.provider.CalendarContract.Events}</td> 123 124 <td>Tabel ini menyimpan 125 informasi khusus kejadian. Tiap baris dalam tabel ini berisi informasi untuk satu 126 kejadian—misalnya, judul kejadian, lokasi, waktu mulai, waktu 127 selesai, dan seterusnya. Kejadian bisa terjadi satu kali atau bisa berulang beberapa kali. Peserta, 128 pengingat, dan properti perluasan disimpan dalam tabel terpisah. 129 Masing-masing memiliki sebuah {@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID} 130 yang mengacu {@link android.provider.BaseColumns#_ID} dalam tabel Events.</td> 131 132 </tr> 133 <tr> 134 <td>{@link android.provider.CalendarContract.Instances}</td> 135 136 <td>Tabel ini menyimpan 137 waktu mulai dan waktu selesai setiap bentuk kejadian. Tiap baris dalam tabel ini 138 mewakili satu bentuk kejadian. Untuk kejadian satu kali ada pemetaan 1:1 139 antara instance dan kejadian. Untuk kejadian berulang, beberapa baris akan dibuat 140 secara otomatis yang sesuai dengan beberapa kejadian itu.</td> 141 </tr> 142 <tr> 143 <td>{@link android.provider.CalendarContract.Attendees}</td> 144 145 <td>Tabel ini menyimpan 146 informasi peserta (tamu) kejadian. Tiap baris mewakili satu tamu 147 kejadian. Ini menetapkan tipe tamu dan respons kehadiran tamu 148 untuk kejadian.</td> 149 </tr> 150 <tr> 151 <td>{@link android.provider.CalendarContract.Reminders}</td> 152 153 <td>Tabel ini menyimpan 154 data peringatan/pemberitahuan. Tiap baris mewakili satu peringatan untuk sebuah kejadian. Sebuah 155 kejadian bisa memiliki beberapa pengingat. Jumlah maksimum pengingat per kejadian 156 ditetapkan dalam 157 {@link android.provider.CalendarContract.CalendarColumns#MAX_REMINDERS}, 158 yang diatur oleh adaptor sinkronisasi yang 159 memiliki kalender yang diberikan. Pengingat ditetapkan dalam menit sebelum kejadian 160 dan memiliki metode yang menentukan cara pengguna akan diperingatkan.</td> 161 </tr> 162 163 </table> 164 165 <p>API Penyedia Kalender didesain agar luwes dan tangguh. Sementara itu 166 , Anda perlu memberikan pengalaman pengguna akhir yang baik dan 167 melindungi integritas kalender dan datanya. Untuk mencapainya, berikut ini adalah 168 beberapa hal yang harus diingat saat menggunakan API ini:</p> 169 170 <ul> 171 172 <li><strong>Menyisipkan, memperbarui, dan menampilkan kejadian kalender.</strong> Untuk menyisipkan, mengubah, dan membaca kejadian secara langsung dari Penyedia Kalender, Anda memerlukan <a href="#manifest">izin</a> yang sesuai. Akan tetapi, jika Anda tidak sedang membuat aplikasi atau adaptor sinkronisasi kalender berfitur lengkap, maka tidak perlu meminta izin. Sebagai gantinya, Anda bisa menggunakan intent yang didukung oleh aplikasi Kalender Android untuk menyerahkan operasi baca dan tulis ke aplikasi itu. Bila menggunakan intent, aplikasi Anda akan mengirim pengguna ke aplikasi Kalender untuk melakukan operasi yang diinginkan 173 dalam sebuah formulir yang sudah diisi. Setelah operasi selesai, formulir dikembalikan ke aplikasi Anda. 174 Dengan mendesain aplikasi untuk melakukan operasi umum melalui Kalender, 175 Anda akan memberi pengguna sebuah antarmuka pengguna yang konsisten dan tangguh. Inilah 176 pendekatan yang disarankan. Untuk informasi selengkapnya, lihat <a href="#intents">Intent 177 Kalender</a>.</p> 178 179 180 <li><strong>Adaptor sinkronisasi.</strong> Adaptor sinkronisasi menyinkronkan data kalender 181 pada perangkat pengguna dengan server atau sumber data lain. Dalam tabel 182 {@link android.provider.CalendarContract.Calendars} dan 183 {@link android.provider.CalendarContract.Events}, 184 ada kolom yang dicadangkan untuk digunakan adaptor sinkronisasi. 185 Penyedia dan aplikasi tidak boleh memodifikasinya. Sebenarnya, tabel-tabel itu tidak 186 terlihat kecuali jika diakses sebagai adaptor sinkronisasi. Untuk informasi selengkapnya tentang 187 adaptor sinkronisasi, lihat <a href="#sync-adapter">Adaptor Sinkronisasi</a>.</li> 188 189 </ul> 190 191 192 <h2 id="manifest">Izin Pengguna</h2> 193 194 <p>Untuk membaca data kalender, aplikasi harus menyertakan izin {@link 195 android.Manifest.permission#READ_CALENDAR} dalam file manifesnya. File 196 harus menyertakan izin {@link android.Manifest.permission#WRITE_CALENDAR} 197 untuk menghapus, menyisipkan, atau memperbarui data kalender:</p> 198 199 <pre> 200 <?xml version="1.0" encoding="utf-8"?> 201 <manifest xmlns:android="http://schemas.android.com/apk/res/android"...> 202 <uses-sdk android:minSdkVersion="14" /> 203 <uses-permission android:name="android.permission.READ_CALENDAR" /> 204 <uses-permission android:name="android.permission.WRITE_CALENDAR" /> 205 ... 206 </manifest> 207 </pre> 208 209 210 <h2 id="calendar">Tabel Kalender</h2> 211 212 <p>Tabel {@link android.provider.CalendarContract.Calendars} berisi data 213 untuk tiap kalender. Kolom-kolom 214 berikut ini bisa ditulisi oleh aplikasi maupun <a href="#sync-adapter">adaptor sinkronisasi</a>. 215 Untuk mengetahui daftar lengkap bidang-bidang yang didukung, lihat 216 acuan {@link android.provider.CalendarContract.Calendars}.</p> 217 <table> 218 <tr> 219 <th>Konstanta</th> 220 <th>Keterangan</th> 221 </tr> 222 <tr> 223 <td>{@link android.provider.CalendarContract.Calendars#NAME}</td> 224 <td>Nama kalender.</td> 225 </tr> 226 <tr> 227 <td>{@link android.provider.CalendarContract.Calendars#CALENDAR_DISPLAY_NAME}</td> 228 <td>Nama kalender ini yang ditampilkan kepada pengguna.</td> 229 </tr> 230 <tr> 231 <td>{@link android.provider.CalendarContract.Calendars#VISIBLE}</td> 232 233 <td>Sebuah boolean yang menunjukkan apakah kalender dipilih untuk ditampilkan. Nilai 234 0 menunjukkan bahwa kejadian yang terkait dengan kalender ini tidak boleh 235 ditampilkan. Nilai 1 menunjukkan bahwa kejadian yang terkait dengan kalender ini harus 236 ditampilkan. Nilai ini memengaruhi pembuatan baris dalam tabel {@link 237 android.provider.CalendarContract.Instances}.</td> 238 239 240 </tr> 241 <tr> 242 <td>{@link android.provider.CalendarContract.CalendarColumns#SYNC_EVENTS}</td> 243 244 <td>Sebuah boolean yang menunjukkan apakah kalender harus disinkronkan dan apakah 245 kejadiannya harus disimpan pada perangkat. Nilai 0 berarti jangan menyinkronkan kalender ini atau 246 simpan kejadiannya pada perangkat. Nilai 1 berarti menyinkronkan kejadian untuk kalender ini 247 dan simpan kejadiannya pada perangkat.</td> 248 </tr> 249 </table> 250 251 <h3 id="query">Membuat query kalender</h3> 252 253 <p>Berikut ini adalah contoh yang menampilkan cara mendapatkan kalender yang dimiliki oleh 254 pengguna tertentu. Untuk memudahkan, dalam contoh ini, operasi query ditampilkan dalam 255 thread antarmuka pengguna ("thread utama"). Dalam praktiknya, hal ini harus dilakukan dalam 256 thread asinkron, sebagai ganti pada thread utama. Untuk diskusi selengkapnya, lihat 257 <a href="{@docRoot}guide/components/loaders.html">Loader</a>. Jika Anda tidak sekadar 258 membaca data melainkan memodifikasinya, lihat {@link android.content.AsyncQueryHandler}. 259 </p> 260 261 262 <pre> 263 // Projection array. Creating indices for this array instead of doing 264 // dynamic lookups improves performance. 265 public static final String[] EVENT_PROJECTION = new String[] { 266 Calendars._ID, // 0 267 Calendars.ACCOUNT_NAME, // 1 268 Calendars.CALENDAR_DISPLAY_NAME, // 2 269 Calendars.OWNER_ACCOUNT // 3 270 }; 271 272 // The indices for the projection array above. 273 private static final int PROJECTION_ID_INDEX = 0; 274 private static final int PROJECTION_ACCOUNT_NAME_INDEX = 1; 275 private static final int PROJECTION_DISPLAY_NAME_INDEX = 2; 276 private static final int PROJECTION_OWNER_ACCOUNT_INDEX = 3;</pre> 277 278 279 <div class="sidebox-wrapper"> <div class="sidebox"> <h3>Mengapa Anda harus menyertakan 280 ACCOUNT_TYPE?</h3> <p>Jika Anda membuat query pada {@link 281 android.provider.CalendarContract.Calendars#ACCOUNT_NAME 282 Calendars.ACCOUNT_NAME}, Anda juga harus menyertakan 283 {@link android.provider.CalendarContract.Calendars#ACCOUNT_TYPE Calendars.ACCOUNT_TYPE} 284 dalam pemilihan. Itu karena akun yang bersangkutan 285 hanya dianggap unik mengingat <code>ACCOUNT_NAME</code> dan 286 <code>ACCOUNT_TYPE</code>-nya. <code>ACCOUNT_TYPE</code> adalah string yang sesuai dengan 287 autentikator akun yang digunakan bila akun didaftarkan dengan 288 {@link android.accounts.AccountManager}. Ada juga sebuah tipe akun khusus yang disebut {@link 289 android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL} untuk kalender 290 yang tidak terkait dengan akun perangkat. Akun {@link 291 android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL} tidak 292 disinkronkan.</p> </div> </div> 293 294 295 <p> Di bagian berikutnya pada contoh ini, Anda akan membuat query. Pemilihan 296 akan menetapkan kriteria untuk query. Dalam contoh ini, query mencari 297 kalender yang memiliki <code>ACCOUNT_NAME</code> 298 "sampleuser (a] google.com", <code>ACCOUNT_TYPE</code> 299 "com.google", dan <code>OWNER_ACCOUNT</code> 300 "sampleuser (a] google.com". Jika Anda ingin melihat semua kalender yang 301 telah ditampilkan pengguna, bukan hanya kalender yang dimiliki pengguna, hilangkan <code>OWNER_ACCOUNT</code>. 302 Query tersebut akan menghasilkan objek {@link android.database.Cursor} 303 yang bisa Anda gunakan untuk menyusuri set hasil yang dikembalikan oleh 304 query database. Untuk diskusi selengkapnya tentang penggunaan query dalam penyedia konten, 305 lihat <a href="{@docRoot}guide/topics/providers/content-providers.html">Penyedia Kalender</a>.</p> 306 307 308 <pre>// Run query 309 Cursor cur = null; 310 ContentResolver cr = getContentResolver(); 311 Uri uri = Calendars.CONTENT_URI; 312 String selection = "((" + Calendars.ACCOUNT_NAME + " = ?) AND (" 313 + Calendars.ACCOUNT_TYPE + " = ?) AND (" 314 + Calendars.OWNER_ACCOUNT + " = ?))"; 315 String[] selectionArgs = new String[] {"sampleuser (a] gmail.com", "com.google", 316 "sampleuser (a] gmail.com"}; 317 // Submit the query and get a Cursor object back. 318 cur = cr.query(uri, EVENT_PROJECTION, selection, selectionArgs, null);</pre> 319 320 <p>Bagian berikutnya ini menggunakan kursor untuk merunut set hasil. Bagian ini menggunakan 321 konstanta yang disiapkan pada awal contoh ini untuk menghasilkan nilai-nilai 322 bagi tiap bidang.</p> 323 324 <pre>// Use the cursor to step through the returned records 325 while (cur.moveToNext()) { 326 long calID = 0; 327 String displayName = null; 328 String accountName = null; 329 String ownerName = null; 330 331 // Get the field values 332 calID = cur.getLong(PROJECTION_ID_INDEX); 333 displayName = cur.getString(PROJECTION_DISPLAY_NAME_INDEX); 334 accountName = cur.getString(PROJECTION_ACCOUNT_NAME_INDEX); 335 ownerName = cur.getString(PROJECTION_OWNER_ACCOUNT_INDEX); 336 337 // Do something with the values... 338 339 ... 340 } 341 </pre> 342 343 <h3 id="modify-calendar">Memodifikasi kalender</h3> 344 345 <p>Untuk melakukan pembaruan kalender, Anda bisa menyediakan {@link 346 android.provider.BaseColumns#_ID} kalender itu baik sebagai ID yang ditambahkan ke 347 URI 348 349 ({@link android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()}) 350 atau sebagai item pemilihan pertama. Pemilihan 351 harus diawali dengan <code>"_id=?"</code>, dan 352 <code>selectionArg</code> pertama harus berupa {@link 353 android.provider.BaseColumns#_ID} kalender. 354 Anda juga bisa melakukan pembaruan dengan menuliskan kode ID dalam URI. Contoh ini mengubah 355 nama tampilan kalender dengan pendekatan 356 ({@link android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()}) 357 :</p> 358 359 <pre>private static final String DEBUG_TAG = "MyActivity"; 360 ... 361 long calID = 2; 362 ContentValues values = new ContentValues(); 363 // The new display name for the calendar 364 values.put(Calendars.CALENDAR_DISPLAY_NAME, "Trevor's Calendar"); 365 Uri updateUri = ContentUris.withAppendedId(Calendars.CONTENT_URI, calID); 366 int rows = getContentResolver().update(updateUri, values, null, null); 367 Log.i(DEBUG_TAG, "Rows updated: " + rows);</pre> 368 369 <h3 id="insert-calendar">Menyisipkan kalender</h2> 370 371 <p>Kalender didesain untuk dikelola terutama oleh sebuah adaptor sinkronisasi, sehingga Anda 372 hanya boleh menyisipkan kalender baru sebagai adaptor sinkronisasi. Biasanya, 373 aplikasi hanya bisa membuat perubahan semu pada kalender, misalnya mengubah nama tampilan. Jika 374 perlu membuat sebuah kalender lokal, aplikasi bisa melakukannya dengan melakukan 375 penyisipan kalender sebagai adaptor sinkronisasi, menggunakan {@link 376 android.provider.CalendarContract.SyncColumns#ACCOUNT_TYPE} dari {@link 377 android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL}. 378 {@link android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL} 379 adalah sebuah tipe akun khusus untuk kalender yang tidak 380 terkait dengan akun perangkat. Kalender tipe ini tidak disinkronkan dengan server. Untuk 381 diskusi tentang adaptor sinkronisasi, lihat <a href="#sync-adapter">Adaptor Sinkronisasi</a>.</p> 382 383 <h2 id="events">Tabel Events</h2> 384 385 <p>Tabel {@link android.provider.CalendarContract.Events} berisi detail 386 untuk tiap kejadian. Untuk menambah, memperbarui, atau menghapus kejadian, aplikasi harus 387 menyertakan izin {@link android.Manifest.permission#WRITE_CALENDAR} dalam 388 <a href="#manifest">file manifesnya</a>.</p> 389 390 <p>Kolom-kolom Events berikut ini bisa ditulis oleh aplikasi maupun 391 adaptor sinkronisasi. Untuk mengetahui daftar lengkap bidang-bidang yang didukung, lihat acuan {@link 392 android.provider.CalendarContract.Events}.</p> 393 394 <table> 395 <tr> 396 <th>Konstanta</th> 397 <th>Keterangan</th> 398 </tr> 399 <tr> 400 <td>{@link android.provider.CalendarContract.EventsColumns#CALENDAR_ID}</td> 401 <td>{@link android.provider.BaseColumns#_ID} kalender yang dimiliki kejadian.</td> 402 </tr> 403 <tr> 404 <td>{@link android.provider.CalendarContract.EventsColumns#ORGANIZER}</td> 405 <td>Email pengatur (pemilik) kejadian.</td> 406 </tr> 407 <tr> 408 <td>{@link android.provider.CalendarContract.EventsColumns#TITLE}</td> 409 <td>Judul kejadian.</td> 410 </tr> 411 <tr> 412 <td>{@link android.provider.CalendarContract.EventsColumns#EVENT_LOCATION}</td> 413 <td>Tempat kejadian. </td> 414 </tr> 415 <tr> 416 <td>{@link android.provider.CalendarContract.EventsColumns#DESCRIPTION}</td> 417 <td>Keterangan kejadian.</td> 418 </tr> 419 <tr> 420 <td>{@link android.provider.CalendarContract.EventsColumns#DTSTART}</td> 421 <td>Waktu mulai kejadian dalam milidetik UTC sejak waktu patokan. </td> 422 </tr> 423 <tr> 424 <td>{@link android.provider.CalendarContract.EventsColumns#DTEND}</td> 425 <td>Waktu selesai kejadian dalam milidetik UTC sejak waktu patokan. </td> 426 </tr> 427 <tr> 428 <td>{@link android.provider.CalendarContract.EventsColumns#EVENT_TIMEZONE}</td> 429 <td>Zona waktu kejadian.</td> 430 </tr> 431 <tr> 432 <td>{@link android.provider.CalendarContract.EventsColumns#EVENT_END_TIMEZONE}</td> 433 <td>Zona waktu untuk waktu selesai kejadian.</td> 434 </tr> 435 <tr> 436 <td>{@link android.provider.CalendarContract.EventsColumns#DURATION}</td> 437 438 <td>Durasi kejadian dalam format <a href="http://tools.ietf.org/html/rfc5545#section-3.8.2.5">RFC5545</a>. 439 Misalnya, nilai <code>"PT1H"</code> menyatakan bahwa kejadian 440 akan berlangsung satu jam, dan nilai <code>"P2W"</code> menunjukkan 441 durasi 2 minggu. </td> 442 443 444 </tr> 445 <tr> 446 <td>{@link android.provider.CalendarContract.EventsColumns#ALL_DAY}</td> 447 448 <td>Nilai 1 menunjukkan kejadian ini memakan waktu sehari penuh, seperti yang didefinisikan oleh 449 zona waktu lokal. Nilai 0 menunjukkan kejadian adalah kejadian biasa yang mungkin dimulai 450 dan selesai pada sembarang waktu selama suatu hari.</td> 451 452 453 </tr> 454 455 456 <tr> 457 <td>{@link android.provider.CalendarContract.EventsColumns#RRULE}</td> 458 459 <td>Aturan perulangan untuk format kejadian. Misalnya, 460 <code>"FREQ=WEEKLY;COUNT=10;WKST=SU"</code>. Anda bisa menemukan 461 contoh selengkapnya <a href="http://tools.ietf.org/html/rfc5545#section-3.8.5.3">di sini</a>.</td> 462 463 </tr> 464 465 <tr> 466 <td>{@link android.provider.CalendarContract.EventsColumns#RDATE}</td> 467 <td>Tanggal perulangan kejadian. 468 Anda biasanya menggunakan {@link android.provider.CalendarContract.EventsColumns#RDATE} 469 bersama dengan {@link android.provider.CalendarContract.EventsColumns#RRULE} 470 untuk mendefinisikan satu set agregat 471 kejadian berulang. Untuk diskusi selengkapnya, lihat <a href="http://tools.ietf.org/html/rfc5545#section-3.8.5.2">Spesifikasi RFC5545</a>.</td> 472 </tr> 473 474 <tr> 475 <td>{@link android.provider.CalendarContract.EventsColumns#AVAILABILITY}</td> 476 477 <td>Jika kejadian ini dihitung sebagai waktu sibuk atau waktu bebas yang bisa 478 dijadwalkan. </td> 479 480 </tr> 481 <tr> 482 <td>{@link android.provider.CalendarContract.EventsColumns#GUESTS_CAN_MODIFY}</td> 483 <td>Apakah tamu bisa memodifikasi kejadian atau tidak. </td> 484 </tr> 485 <tr> 486 <td>{@link android.provider.CalendarContract.EventsColumns#GUESTS_CAN_INVITE_OTHERS}</td> 487 <td>Apakah tamu bisa mengundang tamu lain atau tidak. </td> 488 </tr> 489 <tr> 490 <td>{@link android.provider.CalendarContract.EventsColumns#GUESTS_CAN_SEE_GUESTS}</td> 491 <td>Apakah tamu bisa membaca daftar peserta atau tidak.</td> 492 </tr> 493 </table> 494 495 <h3 id="add-event">Menambahkan Kejadian</h3> 496 497 <p>Bila aplikasi Anda menyisipkan kejadian baru, sebaiknya Anda menggunakan 498 Intent {@link android.content.Intent#ACTION_INSERT INSERT}, seperti dijelaskan dalam <a href="#intent-insert">Menggunakan intent untuk menyisipkan kejadian</a>. Akan tetapi, jika 499 perlu, Anda bisa menyisipkan kejadian secara langsung. Bagian ini menjelaskan 500 caranya.</p> 501 502 503 <p>Berikut ini adalah aturan untuk menyisipkan kejadian baru: </p> 504 <ul> 505 506 <li>Anda harus menyertakan {@link 507 android.provider.CalendarContract.EventsColumns#CALENDAR_ID} dan {@link 508 android.provider.CalendarContract.EventsColumns#DTSTART}.</li> 509 510 <li>Anda harus menyertakan {@link 511 android.provider.CalendarContract.EventsColumns#EVENT_TIMEZONE}. Untuk mendapatkan daftar 512 ID zona waktu yang diinstal pada sistem, gunakan {@link 513 java.util.TimeZone#getAvailableIDs()}. Perhatikan bahwa aturan ini tidak berlaku jika 514 Anda menyisipkan kejadian melalui Intent {@link 515 android.content.Intent#ACTION_INSERT INSERT}, yang dijelaskan dalam <a href="#intent-insert">Menggunakan intent untuk menyisipkan kejadian</a>—dalam 516 skenario itu, sebuah zona waktu default akan diberikan.</li> 517 518 <li>Untuk kejadian tidak-berulang, Anda harus menyertakan {@link 519 android.provider.CalendarContract.EventsColumns#DTEND}. </li> 520 521 522 <li>Untuk kejadian berulang, Anda harus menyertakan sebuah {@link 523 android.provider.CalendarContract.EventsColumns#DURATION} selain {@link 524 android.provider.CalendarContract.EventsColumns#RRULE} atau {@link 525 android.provider.CalendarContract.EventsColumns#RDATE}. Perhatikan bahwa aturan ini tidak berlaku jika 526 Anda menyisipkan kejadian melalui Intent {@link 527 android.content.Intent#ACTION_INSERT INSERT}, yang dijelaskan dalam <a href="#intent-insert">Menggunakan intent untuk menyisipkan kejadian</a>—dalam 528 skenario itu, Anda bisa menggunakan {@link 529 android.provider.CalendarContract.EventsColumns#RRULE} bersama {@link android.provider.CalendarContract.EventsColumns#DTSTART} dan {@link android.provider.CalendarContract.EventsColumns#DTEND}, dan aplikasi Calendar 530 akan mengubahnya menjadi durasi secara otomatis.</li> 531 532 </ul> 533 534 <p>Berikut ini adalah contoh penyisipan kejadian. Penyisipan ini dilakukan dalam thread UI 535 demi kemudahan. Dalam praktiknya, penyisipan dan pembaruan harus dilakukan di 536 thread asinkron untuk memindahkan tindakan ke dalam thread latar belakang. Untuk 537 informasi selengkapnya, lihat {@link android.content.AsyncQueryHandler}.</p> 538 539 540 <pre> 541 long calID = 3; 542 long startMillis = 0; 543 long endMillis = 0; 544 Calendar beginTime = Calendar.getInstance(); 545 beginTime.set(2012, 9, 14, 7, 30); 546 startMillis = beginTime.getTimeInMillis(); 547 Calendar endTime = Calendar.getInstance(); 548 endTime.set(2012, 9, 14, 8, 45); 549 endMillis = endTime.getTimeInMillis(); 550 ... 551 552 ContentResolver cr = getContentResolver(); 553 ContentValues values = new ContentValues(); 554 values.put(Events.DTSTART, startMillis); 555 values.put(Events.DTEND, endMillis); 556 values.put(Events.TITLE, "Jazzercise"); 557 values.put(Events.DESCRIPTION, "Group workout"); 558 values.put(Events.CALENDAR_ID, calID); 559 values.put(Events.EVENT_TIMEZONE, "America/Los_Angeles"); 560 Uri uri = cr.insert(Events.CONTENT_URI, values); 561 562 // get the event ID that is the last element in the Uri 563 long eventID = Long.parseLong(uri.getLastPathSegment()); 564 // 565 // ... do something with event ID 566 // 567 //</pre> 568 569 <p class="note"><strong>Catatan:</strong> Perhatikan cara contoh ini menangkap ID kejadian 570 setelah kejadian dibuat. Inilah cara termudah untuk mendapatkan ID kejadian. Anda akan sering 571 memerlukan ID kejadian untuk melakukan operasi kalender lainnya—misalnya, untuk menambahkan 572 peserta atau pengingat ke kejadian.</p> 573 574 575 <h3 id="update-event">Memperbarui Kejadian</h3> 576 577 <p>Bila aplikasi Anda ingin memperbolehkan pengguna mengedit kejadian, sebaiknya 578 gunakan Intent {@link android.content.Intent#ACTION_EDIT EDIT}, seperti 579 dijelaskan dalam <a href="#intent-edit">Menggunakan intent untuk mengedit kejadian</a>. 580 Akan tetapi, jika perlu, Anda bisa mengedit kejadian secara langsung. Untuk melakukan pembaruan 581 suatu kejadian, Anda bisa memberikan <code>_ID</code> 582 kejadian itu sebagai ID yang ditambahkan ke URI ({@link 583 android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()}) 584 atau sebagai item pemilihan pertama. 585 Pemilihan harus dimulai dengan <code>"_id=?"</code>, dan 586 <code>selectionArg</code> yang pertama harus berupa <code>_ID</code> kejadian. Anda juga bisa 587 melakukan pembaruan dengan menggunakan pemilihan tanpa ID. Berikut ini adalah contoh pembaruan 588 kejadian. Contoh ini mengubah judul kejadian dengan pendekatan 589 {@link android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()} 590 :</p> 591 592 593 <pre>private static final String DEBUG_TAG = "MyActivity"; 594 ... 595 long eventID = 188; 596 ... 597 ContentResolver cr = getContentResolver(); 598 ContentValues values = new ContentValues(); 599 Uri updateUri = null; 600 // The new title for the event 601 values.put(Events.TITLE, "Kickboxing"); 602 updateUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID); 603 int rows = getContentResolver().update(updateUri, values, null, null); 604 Log.i(DEBUG_TAG, "Rows updated: " + rows); </pre> 605 606 <h3 id="delete-event">Menghapus Kejadian</h3> 607 608 <p>Anda bisa menghapus kejadian dengan {@link 609 android.provider.BaseColumns#_ID} sebagai ID yang ditambahkan pada URI, atau dengan 610 pemilihan standar. Jika Anda menggunakan ID yang ditambahkan, Anda tidak bisa melakukan pemilihan. 611 Ada dua versi penghapusan: sebagai aplikasi dan sebagai adaptor sinkronisasi. Penghapusan 612 aplikasi mengatur kolom yang <em>dihapus</em> ke 1. Flag ini yang memberi tahu 613 adaptor sinkronisasi bahwa baris telah dihapus dan bahwa penghapusan ini harus 614 diberitahukan ke server. Penghapusan adaptor sinkronisasi menghapus kejadian dari 615 database bersama semua data terkaitnya. Berikut ini adalah contoh aplikasi 616 yang menghapus kejadian melalui {@link android.provider.BaseColumns#_ID}-nya:</p> 617 618 619 <pre>private static final String DEBUG_TAG = "MyActivity"; 620 ... 621 long eventID = 201; 622 ... 623 ContentResolver cr = getContentResolver(); 624 ContentValues values = new ContentValues(); 625 Uri deleteUri = null; 626 deleteUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID); 627 int rows = getContentResolver().delete(deleteUri, null, null); 628 Log.i(DEBUG_TAG, "Rows deleted: " + rows); 629 </pre> 630 631 <h2 id="attendees">Tabel Peserta</h2> 632 633 <p>Tiap baris tabel {@link android.provider.CalendarContract.Attendees} 634 mewakili satu peserta atau tamu dari sebuah kejadian. Memanggil 635 {@link android.provider.CalendarContract.Reminders#query(android.content.ContentResolver, long, java.lang.String[]) query()} 636 akan menghasilkan daftar peserta untuk 637 kejadian dengan {@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID} yang diberikan. 638 {@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID} ini 639 harus cocok dengan {@link 640 android.provider.BaseColumns#_ID} kejadian tertentu.</p> 641 642 <p>Tabel berikut mencantumkan 643 bidang-bidang yang bisa ditulis. Saat menyisipkan peserta baru, Anda harus menyertakan semuanya 644 kecuali <code>ATTENDEE_NAME</code>. 645 </p> 646 647 648 <table> 649 <tr> 650 <th>Konstanta</th> 651 <th>Keterangan</th> 652 </tr> 653 <tr> 654 <td>{@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID}</td> 655 <td>ID kejadian.</td> 656 </tr> 657 <tr> 658 <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_NAME}</td> 659 <td>Nama peserta.</td> 660 </tr> 661 <tr> 662 <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_EMAIL}</td> 663 <td>Alamat email peserta.</td> 664 </tr> 665 <tr> 666 <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_RELATIONSHIP}</td> 667 <td><p>Hubungan peserta dengan kejadian. Salah satu dari:</p> 668 <ul> 669 <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_ATTENDEE}</li> 670 <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_NONE}</li> 671 <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_ORGANIZER}</li> 672 <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_PERFORMER}</li> 673 <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_SPEAKER}</li> 674 </ul> 675 </td> 676 </tr> 677 <tr> 678 <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_TYPE}</td> 679 <td><p>Tipe peserta. Salah satu dari: </p> 680 <ul> 681 <li>{@link android.provider.CalendarContract.AttendeesColumns#TYPE_REQUIRED}</li> 682 <li>{@link android.provider.CalendarContract.AttendeesColumns#TYPE_OPTIONAL}</li> 683 </ul></td> 684 </tr> 685 <tr> 686 <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS}</td> 687 <td><p>Status kehadiran peserta. Salah satu dari:</p> 688 <ul> 689 <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_ACCEPTED}</li> 690 <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_DECLINED}</li> 691 <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_INVITED}</li> 692 <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_NONE}</li> 693 <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_TENTATIVE}</li> 694 </ul></td> 695 </tr> 696 </table> 697 698 <h3 id="add-attendees">Menambahkan Peserta</h3> 699 700 <p>Berikut ini adalah contoh yang menambahkan satu peserta ke kejadian. Perhatikan bahwa 701 {@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID} 702 diperlukan:</p> 703 704 <pre> 705 long eventID = 202; 706 ... 707 ContentResolver cr = getContentResolver(); 708 ContentValues values = new ContentValues(); 709 values.put(Attendees.ATTENDEE_NAME, "Trevor"); 710 values.put(Attendees.ATTENDEE_EMAIL, "trevor (a] example.com"); 711 values.put(Attendees.ATTENDEE_RELATIONSHIP, Attendees.RELATIONSHIP_ATTENDEE); 712 values.put(Attendees.ATTENDEE_TYPE, Attendees.TYPE_OPTIONAL); 713 values.put(Attendees.ATTENDEE_STATUS, Attendees.ATTENDEE_STATUS_INVITED); 714 values.put(Attendees.EVENT_ID, eventID); 715 Uri uri = cr.insert(Attendees.CONTENT_URI, values); 716 </pre> 717 718 <h2 id="reminders">Tabel Pengingat</h2> 719 720 <p>Tiap baris tabel {@link android.provider.CalendarContract.Reminders} 721 mewakili satu pengingat untuk sebuah kejadian. Memanggil 722 {@link android.provider.CalendarContract.Reminders#query(android.content.ContentResolver, long, java.lang.String[]) query()} akan menghasilkan daftar pengingat untuk 723 kejadian dengan 724 {@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID} yang diberikan.</p> 725 726 727 <p>Tabel berikut mencantumkan bidang-bidang yang bisa ditulis untuk pengingat. Semua bidang harus 728 disertakan saat menyisipkan pengingat baru. Perhatikan bahwa adaptor sinkronisasi menetapkan 729 tipe pengingat yang didukungnya dalam tabel {@link 730 android.provider.CalendarContract.Calendars}. Lihat 731 {@link android.provider.CalendarContract.CalendarColumns#ALLOWED_REMINDERS} 732 untuk detailnya.</p> 733 734 735 <table> 736 <tr> 737 <th>Konstanta</th> 738 <th>Keterangan</th> 739 </tr> 740 <tr> 741 <td>{@link android.provider.CalendarContract.RemindersColumns#EVENT_ID}</td> 742 <td>ID kejadian.</td> 743 </tr> 744 <tr> 745 <td>{@link android.provider.CalendarContract.RemindersColumns#MINUTES}</td> 746 <td>Menit yang ditunggu untuk memicu kejadian pengingat.</td> 747 </tr> 748 <tr> 749 <td>{@link android.provider.CalendarContract.RemindersColumns#METHOD}</td> 750 <td><p>Metode alarm, seperti yang diatur pada server. Salah satu dari:</p> 751 <ul> 752 <li>{@link android.provider.CalendarContract.RemindersColumns#METHOD_ALERT}</li> 753 <li>{@link android.provider.CalendarContract.RemindersColumns#METHOD_DEFAULT}</li> 754 <li>{@link android.provider.CalendarContract.RemindersColumns#METHOD_EMAIL}</li> 755 <li>{@link android.provider.CalendarContract.RemindersColumns#METHOD_SMS}</li> 756 </ul></td> 757 </tr> 758 </table> 759 760 <h3 id="add-reminders">Menambahkan Pengingat</h3> 761 762 <p>Contoh ini menambahkan pengingat ke kejadian. Pengingat dipicu 15 763 menit sebelum kejadian.</p> 764 <pre> 765 long eventID = 221; 766 ... 767 ContentResolver cr = getContentResolver(); 768 ContentValues values = new ContentValues(); 769 values.put(Reminders.MINUTES, 15); 770 values.put(Reminders.EVENT_ID, eventID); 771 values.put(Reminders.METHOD, Reminders.METHOD_ALERT); 772 Uri uri = cr.insert(Reminders.CONTENT_URI, values);</pre> 773 774 <h2 id="instances">Tabel Instances</h2> 775 776 <p>Tabel 777 {@link android.provider.CalendarContract.Instances} menyimpan 778 waktu mulai dan waktu selesai kejadian. Tiap baris dalam tabel ini 779 mewakili satu bentuk kejadian. Tabel instance tidak bisa ditulis dan hanya 780 menyediakan sebuah cara untuk membuat query kejadian. </p> 781 782 <p>Tabel berikut mencantumkan beberapa bidang yang bisa Anda query untuk suatu instance. Perhatikan 783 bahwa zona waktu didefinisikan oleh 784 {@link android.provider.CalendarContract.CalendarCache#KEY_TIMEZONE_TYPE} 785 dan 786 {@link android.provider.CalendarContract.CalendarCache#KEY_TIMEZONE_INSTANCES}.</p> 787 788 789 <table> 790 <tr> 791 <th>Konstanta</th> 792 <th>Keterangan</th> 793 </tr> 794 <tr> 795 <td>{@link android.provider.CalendarContract.Instances#BEGIN}</td> 796 <td>Waktu mulai instance, dalam milidetik UTC.</td> 797 </tr> 798 <tr> 799 <td>{@link android.provider.CalendarContract.Instances#END}</td> 800 <td>Waktu selesai instance, dalam milidetik UTC.</td> 801 </tr> 802 <tr> 803 <td>{@link android.provider.CalendarContract.Instances#END_DAY}</td> 804 805 <td>Hari selesai Julian dari instance, relatif terhadap 806 zona waktu Kalender. 807 808 </td> 809 </tr> 810 <tr> 811 <td>{@link android.provider.CalendarContract.Instances#END_MINUTE}</td> 812 813 <td>Menit selesai dari instance yang diukur dari tengah malam di zona waktu 814 Kalender.</td> 815 816 </tr> 817 <tr> 818 <td>{@link android.provider.CalendarContract.Instances#EVENT_ID}</td> 819 <td>Kejadian <code>_ID</code> untuk instance ini.</td> 820 </tr> 821 <tr> 822 <td>{@link android.provider.CalendarContract.Instances#START_DAY}</td> 823 <td>Hari mulai Julian dari instance, relatif terhadap zona waktu Kalender. 824 </td> 825 </tr> 826 <tr> 827 <td>{@link android.provider.CalendarContract.Instances#START_MINUTE}</td> 828 829 <td>Menit mulai dari instance yang diukur dari tengah malam, relatif terhadap 830 zona waktu Kalender. 831 </td> 832 833 </tr> 834 835 </table> 836 837 <h3 id="query-instances">Membuat query tabel Instance</h3> 838 839 <p>Untuk membuat query tabel Instances, Anda perlu menetapkan rentang waktu query 840 dalam URI. Dalam contoh ini, {@link android.provider.CalendarContract.Instances} 841 mendapatkan akses ke bidang {@link 842 android.provider.CalendarContract.EventsColumns#TITLE} melalui 843 implementasi antarmuka {@link android.provider.CalendarContract.EventsColumns}-nya. 844 Dengan kata lain, {@link 845 android.provider.CalendarContract.EventsColumns#TITLE} dihasilkan melalui 846 tampilan database, bukan melalui query terhadap tabel {@link 847 android.provider.CalendarContract.Instances} mentah.</p> 848 849 <pre> 850 private static final String DEBUG_TAG = "MyActivity"; 851 public static final String[] INSTANCE_PROJECTION = new String[] { 852 Instances.EVENT_ID, // 0 853 Instances.BEGIN, // 1 854 Instances.TITLE // 2 855 }; 856 857 // The indices for the projection array above. 858 private static final int PROJECTION_ID_INDEX = 0; 859 private static final int PROJECTION_BEGIN_INDEX = 1; 860 private static final int PROJECTION_TITLE_INDEX = 2; 861 ... 862 863 // Specify the date range you want to search for recurring 864 // event instances 865 Calendar beginTime = Calendar.getInstance(); 866 beginTime.set(2011, 9, 23, 8, 0); 867 long startMillis = beginTime.getTimeInMillis(); 868 Calendar endTime = Calendar.getInstance(); 869 endTime.set(2011, 10, 24, 8, 0); 870 long endMillis = endTime.getTimeInMillis(); 871 872 Cursor cur = null; 873 ContentResolver cr = getContentResolver(); 874 875 // The ID of the recurring event whose instances you are searching 876 // for in the Instances table 877 String selection = Instances.EVENT_ID + " = ?"; 878 String[] selectionArgs = new String[] {"207"}; 879 880 // Construct the query with the desired date range. 881 Uri.Builder builder = Instances.CONTENT_URI.buildUpon(); 882 ContentUris.appendId(builder, startMillis); 883 ContentUris.appendId(builder, endMillis); 884 885 // Submit the query 886 cur = cr.query(builder.build(), 887 INSTANCE_PROJECTION, 888 selection, 889 selectionArgs, 890 null); 891 892 while (cur.moveToNext()) { 893 String title = null; 894 long eventID = 0; 895 long beginVal = 0; 896 897 // Get the field values 898 eventID = cur.getLong(PROJECTION_ID_INDEX); 899 beginVal = cur.getLong(PROJECTION_BEGIN_INDEX); 900 title = cur.getString(PROJECTION_TITLE_INDEX); 901 902 // Do something with the values. 903 Log.i(DEBUG_TAG, "Event: " + title); 904 Calendar calendar = Calendar.getInstance(); 905 calendar.setTimeInMillis(beginVal); 906 DateFormat formatter = new SimpleDateFormat("MM/dd/yyyy"); 907 Log.i(DEBUG_TAG, "Date: " + formatter.format(calendar.getTime())); 908 } 909 }</pre> 910 911 <h2 id="intents">Intent Kalender</h2> 912 <p>Aplikasi Anda tidak memerlukan <a href="#manifest">izin</a> untuk membaca dan menulis data kalender. Sebagai gantinya, aplikasi bisa menggunakan intent yang didukung oleh aplikasi Kalender Android untuk menyerahkan operasi baca dan tulis ke aplikasi itu. Tabel berikut mencantumkan intent yang didukung oleh Penyedia Kalender:</p> 913 <table> 914 <tr> 915 <th>Tindakan</th> 916 <th>URI</th> 917 918 <th>Keterangan</th> 919 <th>Ekstra</th> 920 </tr> 921 <tr> 922 <td><br> 923 {@link android.content.Intent#ACTION_VIEW VIEW} <br></td> 924 <td><p><code>content://com.android.calendar/time/<ms_since_epoch></code></p> 925 Anda juga bisa mengacu ke URI dengan 926 {@link android.provider.CalendarContract#CONTENT_URI CalendarContract.CONTENT_URI}. 927 Untuk contoh yang menggunakan intent ini, lihat <a href="{@docRoot}guide/topics/providers/calendar-provider.html#intent-view">Menggunakan intent untuk menampilkan data kalender</a>. 928 929 </td> 930 <td>Membuka kalender pada waktu yang ditetapkan oleh <code><ms_since_epoch></code>.</td> 931 <td>Tidak ada.</td> 932 </tr> 933 <tr> 934 <td><p>{@link android.content.Intent#ACTION_VIEW VIEW} </p> 935 936 </td> 937 <td><p><code>content://com.android.calendar/events/<event_id></code></p> 938 939 Anda juga bisa mengacu ke URI dengan 940 {@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI}. 941 Untuk contoh yang menggunakan intent ini, lihat <a href="{@docRoot}guide/topics/providers/calendar-provider.html#intent-view">Menggunakan intent untuk menampilkan data kalender</a>. 942 943 </td> 944 <td>Menampilkan kejadian yang ditetapkan oleh <code><event_id></code>.</td> 945 946 <td>{@link android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_BEGIN_TIME}<br> 947 <br> 948 <br> 949 {@link android.provider.CalendarContract#EXTRA_EVENT_END_TIME CalendarContract.EXTRA_EVENT_END_TIME}</td> 950 </tr> 951 952 <tr> 953 <td>{@link android.content.Intent#ACTION_EDIT EDIT} </td> 954 <td><p><code>content://com.android.calendar/events/<event_id></code></p> 955 956 Anda juga bisa mengacu ke URI dengan 957 {@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI}. 958 Untuk contoh penggunaan intent ini, lihat <a href="{@docRoot}guide/topics/providers/calendar-provider.html#intent-edit">Menggunakan intent untuk mengedit kejadian</a>. 959 960 961 </td> 962 <td>Mengedit kejadian yang ditetapkan oleh <code><event_id></code>.</td> 963 964 <td>{@link android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_BEGIN_TIME}<br> 965 <br> 966 <br> 967 {@link android.provider.CalendarContract#EXTRA_EVENT_END_TIME CalendarContract.EXTRA_EVENT_END_TIME}</td> 968 </tr> 969 970 <tr> 971 <td>{@link android.content.Intent#ACTION_EDIT EDIT} <br> 972 <br> 973 {@link android.content.Intent#ACTION_INSERT INSERT} </td> 974 <td><p><code>content://com.android.calendar/events</code></p> 975 976 Anda juga bisa mengacu ke URI dengan 977 {@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI}. 978 Untuk contoh penggunaan intent ini, lihat <a href="{@docRoot}guide/topics/providers/calendar-provider.html#intent-insert">Menggunakan intent untuk menyisipkan kejadian</a>. 979 980 </td> 981 982 <td>Membuat sebuah kejadian.</td> 983 <td>Ekstra apa saja yang tercantum dalam tabel di bawah.</td> 984 </tr> 985 </table> 986 987 <p>Tabel berikut mencantumkan ekstra intent yang didukung oleh Penyedia Kalender: 988 </p> 989 <table> 990 <tr> 991 <th>Ekstra Intent</th> 992 <th>Keterangan</th> 993 </tr> 994 <tr> 995 <td>{@link android.provider.CalendarContract.EventsColumns#TITLE Events.TITLE}</td> 996 <td>Nama kejadian.</td> 997 </tr> 998 <tr> 999 1000 <td>{@link android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME 1001 CalendarContract.EXTRA_EVENT_BEGIN_TIME}</td> 1002 <td>Waktu mulai kejadian dalam milidetik sejak waktu patokan.</td> 1003 </tr> 1004 <tr> 1005 <td>{@link android.provider.CalendarContract#EXTRA_EVENT_END_TIME 1006 CalendarContract.EXTRA_EVENT_END_TIME}</td> 1007 1008 <td>Waktu selesai kejadian dalam milidetik sejak waktu patokan.</td> 1009 </tr> 1010 <tr> 1011 <td>{@link android.provider.CalendarContract#EXTRA_EVENT_ALL_DAY 1012 CalendarContract.EXTRA_EVENT_ALL_DAY}</td> 1013 1014 <td>Sebuah boolean yang menunjukkan bahwa kejadian sehari penuh. Nilai bisa 1015 <code>true</code> atau <code>false</code>.</td> </tr> 1016 <tr> 1017 <td>{@link android.provider.CalendarContract.EventsColumns#EVENT_LOCATION 1018 Events.EVENT_LOCATION}</td> 1019 1020 <td>Lokasi kejadian.</td> 1021 </tr> 1022 <tr> 1023 <td>{@link android.provider.CalendarContract.EventsColumns#DESCRIPTION 1024 Events.DESCRIPTION}</td> 1025 1026 <td>Keterangan kejadian.</td> 1027 </tr> 1028 <tr> 1029 <td> 1030 {@link android.content.Intent#EXTRA_EMAIL Intent.EXTRA_EMAIL}</td> 1031 <td>Alamat email mereka yang harus diundang berupa daftar yang dipisahkan koma.</td> 1032 </tr> 1033 <tr> 1034 <td> 1035 {@link android.provider.CalendarContract.EventsColumns#RRULE Events.RRULE}</td> 1036 <td>Aturan perulangan kejadian.</td> 1037 </tr> 1038 <tr> 1039 <td> 1040 {@link android.provider.CalendarContract.EventsColumns#ACCESS_LEVEL 1041 Events.ACCESS_LEVEL}</td> 1042 1043 <td>Apakah kejadian bersifat privat atau publik.</td> 1044 </tr> 1045 <tr> 1046 <td>{@link android.provider.CalendarContract.EventsColumns#AVAILABILITY 1047 Events.AVAILABILITY}</td> 1048 1049 <td>Jika kejadian ini dihitung sebagai waktu sibuk atau waktu bebas yang bisa dijadwalkan.</td> 1050 1051 </table> 1052 <p>Bagian berikut menjelaskan cara menggunakan semua intent ini.</p> 1053 1054 1055 <h3 id="intent-insert">Menggunakan intent untuk menyisipkan kejadian</h3> 1056 1057 <p>Penggunaan Intent {@link android.content.Intent#ACTION_INSERT INSERT} 1058 akan memungkinkan aplikasi Anda menyerahkan tugas penyisipan kejadian ke Kalender itu sendiri. 1059 Dengan pendekatan ini, aplikasi Anda bahkan tidak perlu menyertakan izin {@link 1060 android.Manifest.permission#WRITE_CALENDAR} dalam <a href="#manifest">file manifesnya</a>.</p> 1061 1062 1063 <p>Bila pengguna menjalankan aplikasi yang menggunakan pendekatan ini, aplikasi akan mengirim 1064 izin ke Kalender untuk menyelesaikan penambahan kejadian. Intent {@link 1065 android.content.Intent#ACTION_INSERT INSERT} menggunakan bidang-bidang ekstra 1066 untuk mengisi formulir lebih dahulu dengan detail kejadian dalam Kalender. Pengguna nanti bisa 1067 membatalkan kejadian, mengedit formulir sebagaimana diperlukan, atau menyimpan kejadian ke 1068 kalender mereka.</p> 1069 1070 1071 1072 <p>Berikut ini adalah cuplikan kode yang menjadwalkan kejadian pada tanggal 19 Januari 2012, yang berjalan 1073 dari 7:30 pagi hingga 8:30 pagi Perhatikan hal-hal berikut tentang cuplikan kode ini:</p> 1074 1075 <ul> 1076 <li>Cuplikan kode ini menetapkan {@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI} 1077 sebagai URI-nya.</li> 1078 1079 <li>Cuplikan kode ini menggunakan bidang-bidang ekstra {@link 1080 android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME 1081 CalendarContract.EXTRA_EVENT_BEGIN_TIME} dan {@link 1082 android.provider.CalendarContract#EXTRA_EVENT_END_TIME 1083 CalendarContract.EXTRA_EVENT_END_TIME} untuk mengisi dahulu formulir 1084 dengan waktu kejadian. Nilai-nilai untuk waktu ini harus dalam milidetik UTC 1085 sejak waktu patokan.</li> 1086 1087 <li>Cuplikan kode ini menggunakan bidang ekstra {@link android.content.Intent#EXTRA_EMAIL Intent.EXTRA_EMAIL} 1088 untuk memberikan daftar undangan yang dipisah koma, yang ditetapkan melalui alamat email.</li> 1089 1090 </ul> 1091 <pre> 1092 Calendar beginTime = Calendar.getInstance(); 1093 beginTime.set(2012, 0, 19, 7, 30); 1094 Calendar endTime = Calendar.getInstance(); 1095 endTime.set(2012, 0, 19, 8, 30); 1096 Intent intent = new Intent(Intent.ACTION_INSERT) 1097 .setData(Events.CONTENT_URI) 1098 .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis()) 1099 .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis()) 1100 .putExtra(Events.TITLE, "Yoga") 1101 .putExtra(Events.DESCRIPTION, "Group class") 1102 .putExtra(Events.EVENT_LOCATION, "The gym") 1103 .putExtra(Events.AVAILABILITY, Events.AVAILABILITY_BUSY) 1104 .putExtra(Intent.EXTRA_EMAIL, "rowan (a] example.com,trevor (a] example.com"); 1105 startActivity(intent); 1106 </pre> 1107 1108 <h3 id="intent-edit">Menggunakan intent untuk mengedit kejadian</h3> 1109 1110 <p>Anda bisa memperbarui kejadian secara langsung, seperti dijelaskan dalam <a href="#update-event">Memperbarui kejadian</a>. Namun penggunaan Intent {@link 1111 android.content.Intent#ACTION_EDIT EDIT} memungkinkan aplikasi yang 1112 tidak memiliki izin untuk menyerahkan pengeditan kejadian ke aplikasi Kalender. 1113 Bila pengguna selesai mengedit kejadian dalam Kalender, pengguna akan dikembalikan ke 1114 aplikasi semula.</p> <p>Berikut ini adalah contoh intent yang mengatur 1115 judul baru bagi kejadian yang ditetapkan dan memungkinkan pengguna mengedit kejadian dalam Kalender.</p> 1116 1117 1118 <pre>long eventID = 208; 1119 Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID); 1120 Intent intent = new Intent(Intent.ACTION_EDIT) 1121 .setData(uri) 1122 .putExtra(Events.TITLE, "My New Title"); 1123 startActivity(intent);</pre> 1124 1125 <h3 id="intent-view">Menggunakan intent untuk menampilkan data kalender</h3> 1126 <p>Penyedia Kalender menyediakan dua cara menggunakan Intent {@link android.content.Intent#ACTION_VIEW VIEW}:</p> 1127 <ul> 1128 <li>Untuk membuka Kalender pada tanggal tertentu.</li> 1129 <li>Untuk menampilkan sebuah kejadian.</li> 1130 1131 </ul> 1132 <p>Berikut ini adalah contoh yang menampilkan cara membuka Kalender pada tanggal tertentu:</p> 1133 <pre>// A date-time specified in milliseconds since the epoch. 1134 long startMillis; 1135 ... 1136 Uri.Builder builder = CalendarContract.CONTENT_URI.buildUpon(); 1137 builder.appendPath("time"); 1138 ContentUris.appendId(builder, startMillis); 1139 Intent intent = new Intent(Intent.ACTION_VIEW) 1140 .setData(builder.build()); 1141 startActivity(intent);</pre> 1142 1143 <p>Berikut ini adalah contoh yang menampilkan cara membuka kejadian untuk menampilkan:</p> 1144 <pre>long eventID = 208; 1145 ... 1146 Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID); 1147 Intent intent = new Intent(Intent.ACTION_VIEW) 1148 .setData(uri); 1149 startActivity(intent); 1150 </pre> 1151 1152 1153 <h2 id="sync-adapter">Adaptor Sinkronisasi</h2> 1154 1155 1156 <p>Hanya ada perbedaan kecil dalam cara aplikasi dan adaptor sinkronisasi 1157 mengakses Penyedia Kalender:</p> 1158 1159 <ul> 1160 <li>Adaptor sinkronisasi perlu menetapkan bahwa dirinya sebuah adaptor sinkronisasi dengan mengatur {@link android.provider.CalendarContract#CALLER_IS_SYNCADAPTER} ke <code>true</code>.</li> 1161 1162 1163 <li>Adaptor sinkronisasi perlu memberikan {@link 1164 android.provider.CalendarContract.SyncColumns#ACCOUNT_NAME} dan {@link 1165 android.provider.CalendarContract.SyncColumns#ACCOUNT_TYPE} sebagai parameter query dalam URI. </li> 1166 1167 <li>Adaptor sinkronisasi memiliki akses tulis ke lebih banyak kolom daripada aplikasi atau widget. 1168 Misalnya, aplikasi hanya bisa mengubah sedikit karakteristik kalender, 1169 misalnya nama, nama tampilan, pengaturan visibilitas, dan apakah kalender 1170 disinkronkan atau tidak. Sebagai perbandingan, adaptor sinkronisasi bisa mengakses bukan hanya kolom-kolom itu, namun banyak kolom lainnya, 1171 misalnya warna kalender, zona waktu, tingkat akses, lokasi, dan seterusnya. 1172 Akan tetapi, adaptor sinkronisasi dibatasi pada <code>ACCOUNT_NAME</code> dan 1173 <code>ACCOUNT_TYPE</code> yang ditetapkannya.</li> </ul> 1174 1175 <p>Berikut ini adalah metode pembantu yang bisa Anda gunakan untuk menghasilkan URI bagi penggunaan dengan adaptor sinkronisasi:</p> 1176 <pre> static Uri asSyncAdapter(Uri uri, String account, String accountType) { 1177 return uri.buildUpon() 1178 .appendQueryParameter(android.provider.CalendarContract.CALLER_IS_SYNCADAPTER,"true") 1179 .appendQueryParameter(Calendars.ACCOUNT_NAME, account) 1180 .appendQueryParameter(Calendars.ACCOUNT_TYPE, accountType).build(); 1181 } 1182 </pre> 1183 <p>Untuk contoh implementasi adaptor sinkronisasi (yang tidak terkait secara khusus dengan Kalender), lihat 1184 <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">SampleSyncAdapter</a>. 1185