ภาพรวมของผู้ให้บริการปฏิทิน

ผู้ให้บริการปฏิทินคือที่เก็บสำหรับกิจกรรมในปฏิทินของผู้ใช้ ปฏิทินผู้ให้บริการ API ช่วยให้คุณดำเนินการค้นหา แทรก อัปเดต และลบปฏิทิน กิจกรรม ผู้เข้าร่วม การช่วยเตือน และอื่นๆ ได้

แอปพลิเคชันและอะแดปเตอร์การซิงค์สามารถใช้ Calendar Provider API ได้ กฎจะแตกต่างกันไปตามประเภทของโปรแกรมที่เรียกใช้ เอกสารนี้มุ่งเน้นที่การใช้ Calendar Provider API เป็นแอปพลิเคชันเป็นหลัก สำหรับ อภิปรายว่าอะแดปเตอร์การซิงค์แตกต่างกันอย่างไร โปรดดู ซิงค์อะแดปเตอร์

ปกติแล้ว หากต้องการอ่านหรือเขียนข้อมูลปฏิทิน ไฟล์ Manifest ของแอปพลิเคชันต้องมีสิทธิ์ที่เหมาะสมตามที่อธิบายไว้ในสิทธิ์ของผู้ใช้ เพื่อให้การดำเนินงานทั่วไปง่ายขึ้น ผู้ให้บริการมีชุดของ Intent ตามที่อธิบายไว้ในปฏิทิน Intent Intent เหล่านี้จะนำผู้ใช้ไปยังแอปพลิเคชันปฏิทินเพื่อแทรก ดู และแก้ไขกิจกรรม ผู้ใช้โต้ตอบกับแอปพลิเคชันปฏิทิน กลับไปยังแอปพลิเคชันเดิม ดังนั้นแอปพลิเคชันของคุณจึงไม่จำเป็นต้องขอสิทธิ์หรือต้องมีอินเทอร์เฟซผู้ใช้เพื่อดูหรือสร้างเหตุการณ์

ข้อมูลเบื้องต้น

ผู้ให้บริการเนื้อหาจะเก็บข้อมูลและทำให้ข้อมูลนั้นเข้าถึงได้ แอปพลิเคชัน โดยปกติแล้ว ผู้ให้บริการเนื้อหาที่แพลตฟอร์ม Android นำเสนอ (รวมถึงผู้ให้บริการปฏิทิน) จะแสดงข้อมูลเป็นชุดตารางตามรูปแบบฐานข้อมูลเชิงสัมพันธ์ โดยแต่ละแถวคือระเบียนและแต่ละคอลัมน์คือข้อมูลประเภทหนึ่งๆ ที่มีความหมายเฉพาะ แอปพลิเคชันผ่านทาง Calendar Provider API และอะแดปเตอร์สำหรับซิงค์จะได้รับสิทธิ์การอ่าน/เขียนตารางฐานข้อมูลที่เก็บ ข้อมูลปฏิทินของผู้ใช้

ผู้ให้บริการเนื้อหาทุกรายจะแสดง URI สาธารณะ (รวม Uri ) ที่ระบุชุดข้อมูลโดยไม่ซ้ำกัน ผู้ให้บริการเนื้อหาที่ควบคุม ชุดข้อมูลหลายชุด (หลายตาราง) จะแสดง URI แยกกันสำหรับแต่ละชุดข้อมูล URI ทั้งหมดสำหรับผู้ให้บริการจะขึ้นต้นด้วยสตริง "content://" ช่วงเวลานี้ ระบุว่าข้อมูลถูกควบคุมโดยผู้ให้บริการเนื้อหา CalendarProvider จะกำหนดค่าคงที่สำหรับ URI ของคลาส (ตาราง) แต่ละคลาส เหล่านี้ URI มีรูปแบบเป็น <class>.CONTENT_URI เช่น Events.CONTENT_URI

รูปที่ 1 แสดงการนำเสนอแบบกราฟิกสำหรับโมเดลข้อมูลของผู้ให้บริการปฏิทิน ซึ่งจะแสดงตารางหลักและช่องที่ลิงก์ตารางเหล่านั้นเข้าด้วยกัน

โมเดลข้อมูลของผู้ให้บริการปฏิทิน

รูปที่ 1 โมเดลข้อมูลของผู้ให้บริการปฏิทิน

ผู้ใช้มีปฏิทินได้หลายรายการ และปฏิทินต่างๆ สามารถเชื่อมโยงกับบัญชีประเภทต่างๆ ได้ (Google ปฏิทิน, Exchange และอื่นๆ)

CalendarContract กำหนดโมเดลข้อมูลของปฏิทินและข้อมูลที่เกี่ยวข้องกับกิจกรรม ข้อมูลนี้จะจัดเก็บไว้ในตารางต่างๆ ที่แสดงด้านล่าง

ตาราง (คลาส) คำอธิบาย

CalendarContract.Calendars

ตารางนี้มีข้อมูลที่เจาะจงปฏิทิน แต่ละแถวในตารางนี้มีรายละเอียดของปฏิทินเดียว เช่น ชื่อ สี ข้อมูลการซิงค์ และอื่นๆ
CalendarContract.Events ตารางนี้มีข้อมูลเฉพาะกิจกรรม แต่ละแถวในตารางนี้มีข้อมูลของกิจกรรมเดียว เช่น ชื่อกิจกรรม สถานที่ เวลาเริ่มต้น เวลาสิ้นสุด และอื่นๆ เหตุการณ์อาจเกิดขึ้นเพียงครั้งเดียวหรือเกิดขึ้นซ้ำหลายครั้งก็ได้ ระบบจะจัดเก็บผู้เข้าร่วม การช่วยเตือน และพร็อพเพอร์ตี้เพิ่มเติมไว้ในตารางแยกต่างหาก แต่ละคนมี EVENT_ID ที่อ้างอิง _ID ในตารางเหตุการณ์
CalendarContract.Instances ตารางนี้มีค่า เวลาเริ่มต้นและสิ้นสุดสำหรับแต่ละเหตุการณ์ แต่ละแถวในตารางนี้ แสดงถึงเหตุการณ์เดียว สําหรับเหตุการณ์ที่เกิดขึ้นเพียงครั้งเดียว ระบบจะแมปอินสแตนซ์กับเหตุการณ์แบบ 1:1 สําหรับเหตุการณ์ที่เกิดขึ้นซ้ำ ระบบจะสร้างหลายแถวโดยอัตโนมัติซึ่งสอดคล้องกับการเกิดเหตุการณ์นั้นหลายครั้ง
CalendarContract.Attendees ตารางนี้มีข้อมูลผู้เข้าร่วมกิจกรรม (ผู้มาเยือน) แต่ละแถวแสดงแขก 1 คนของกิจกรรม โดยระบุประเภทของผู้เข้าร่วมและคำตอบการเข้าร่วมของผู้เข้าร่วมสำหรับกิจกรรม
CalendarContract.Reminders ตารางนี้มีข้อมูลการแจ้งเตือน แต่ละแถวแสดงการแจ้งเตือนรายการเดียวสําหรับเหตุการณ์ CANNOT TRANSLATE กิจกรรมมีการช่วยเตือนได้หลายรายการ จำนวนสูงสุดของการแจ้งเตือนต่อกิจกรรมคือ ที่ระบุใน MAX_REMINDERS, ซึ่งตั้งค่าโดยอะแดปเตอร์การซิงค์ที่ เป็นเจ้าของปฏิทินที่ระบุ การช่วยเตือนจะระบุเป็นนาทีก่อนเหตุการณ์ และจะมีเมธอดที่กําหนดวิธีแจ้งเตือนผู้ใช้

Calendar Provider API ออกแบบมาให้ยืดหยุ่นและมีประสิทธิภาพ ในขณะเดียวกัน คุณต้องมอบประสบการณ์การใช้งานที่ดีให้แก่ผู้ใช้ปลายทางและปกป้องความสมบูรณ์ของปฏิทิน รวมถึงข้อมูลในปฏิทิน ด้วยเหตุนี้ สิ่งที่ควรคำนึงถึงเมื่อใช้ API มีดังนี้

  • การแทรก อัปเดต และดูกิจกรรมในปฏิทิน หากต้องการแทรก แก้ไข และอ่านกิจกรรมจากผู้ให้บริการปฏิทินโดยตรง คุณต้องมีสิทธิ์ที่เหมาะสม แต่ถ้าคุณไม่ได้สร้างแอปพลิเคชันปฏิทินที่สมบูรณ์หรืออะแดปเตอร์การซิงค์ ก็ไม่จำเป็นต้องขอสิทธิ์เหล่านี้ คุณสามารถใช้ Intent ที่แอปพลิเคชันปฏิทินของ Android รองรับเพื่อส่งต่อการดำเนินการอ่านและเขียนไปยังแอปพลิเคชันนั้นได้ เมื่อใช้ Intent แอปพลิเคชันจะส่งผู้ใช้ไปยังแอปพลิเคชันปฏิทินเพื่อดำเนินการที่ต้องการ ในแบบฟอร์มที่กรอกไว้ล่วงหน้า เมื่อเสร็จแล้ว ระบบจะนำคุณกลับไปยังแอปพลิเคชัน การออกแบบแอปพลิเคชันให้ดำเนินการทั่วไปผ่านปฏิทินจะช่วยให้ผู้ใช้มีอินเทอร์เฟซผู้ใช้ที่มีประสิทธิภาพและใช้งานได้ง่าย ซึ่งเป็นแนวทางที่แนะนำ สำหรับข้อมูลเพิ่มเติม โปรดดูที่ปฏิทิน Intent
  • ซิงค์อะแดปเตอร์ อะแดปเตอร์การซิงค์จะซิงค์ข้อมูลปฏิทินในอุปกรณ์ของผู้ใช้กับเซิร์ฟเวอร์หรือแหล่งข้อมูลอื่น ใน CalendarContract.Calendars และ CalendarContract.Events ตาราง จะมีคอลัมน์ที่สงวนไว้ให้อะแดปเตอร์ซิงค์ที่จะใช้ ผู้ให้บริการและแอปพลิเคชันไม่ควรแก้ไข ที่จริงแล้ว พวกเขาไม่ได้ มองเห็นได้ เว้นแต่จะเข้าถึงเป็นอะแดปเตอร์การซิงค์ โปรดดูข้อมูลเพิ่มเติมเกี่ยวกับอะแดปเตอร์การซิงค์ที่หัวข้ออะแดปเตอร์การซิงค์

สิทธิ์ของผู้ใช้

หากต้องการอ่านข้อมูลปฏิทิน แอปพลิเคชันต้องรวมสิทธิ์ READ_CALENDAR ในไฟล์ Manifest ทั้งนี้ ต้องมีสิทธิ์ WRITE_CALENDAR เพื่อลบ แทรก หรืออัปเดตข้อมูลปฏิทิน

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"...>
    <uses-sdk android:minSdkVersion="14" />
    <uses-permission android:name="android.permission.READ_CALENDAR" />
    <uses-permission android:name="android.permission.WRITE_CALENDAR" />
    ...
</manifest>

ตารางปฏิทิน

ตาราง CalendarContract.Calendars มีรายละเอียดสำหรับปฏิทินแต่ละรายการ ดังต่อไปนี้ ทั้งแอปพลิเคชันและอะแดปเตอร์การซิงค์สามารถเขียนคอลัมน์ปฏิทินได้ ดูรายการช่องทั้งหมดที่รองรับได้ที่CalendarContract.Calendarsข้อมูลอ้างอิง

ค่าคงที่ คำอธิบาย
NAME ชื่อของปฏิทิน
CALENDAR_DISPLAY_NAME ชื่อของปฏิทินนี้ที่แสดงต่อผู้ใช้
VISIBLE บูลีนที่ระบุว่ามีการเลือกปฏิทินที่จะแสดงหรือไม่ ค่า 0 บ่งบอกว่าไม่ควรแสดงกิจกรรมที่เชื่อมโยงกับปฏิทินนี้ ค่า 1 บ่งชี้ว่ากิจกรรมที่เชื่อมโยงกับปฏิทินนี้ควร ได้อีกด้วย ค่านี้ส่งผลต่อการสร้างแถวในตาราง CalendarContract.Instances
SYNC_EVENTS บูลีนที่ระบุว่าปฏิทินควรได้รับการซิงค์และ เหตุการณ์ที่จัดเก็บไว้ในอุปกรณ์ ค่า 0 ระบุว่าไม่ต้องซิงค์ปฏิทินนี้หรือ จัดเก็บเหตุการณ์ไว้ในอุปกรณ์ ค่า 1 บอกว่าซิงค์กิจกรรมสำหรับปฏิทินนี้ และจัดเก็บเหตุการณ์ไว้ในอุปกรณ์

ระบุประเภทบัญชีสำหรับการดำเนินการทั้งหมด

หากค้นหาใน Calendars.ACCOUNT_NAME คุณต้องรวม Calendars.ACCOUNT_TYPE ไว้ในการเลือกด้วย เนื่องจากระบบจะถือว่าบัญชีหนึ่งๆ ซ้ำกันก็ต่อเมื่อทั้ง ACCOUNT_NAME และ ACCOUNT_TYPE ของบัญชีนั้นตรงกัน ACCOUNT_TYPE คือสตริงที่สอดคล้องกับโปรแกรมตรวจสอบสิทธิ์ของบัญชีที่ใช้เมื่อลงทะเบียนบัญชีด้วย AccountManager นอกจากนี้ยังมีบัญชีประเภทพิเศษที่เรียกว่า ACCOUNT_TYPE_LOCAL สำหรับปฏิทินที่ไม่ได้เชื่อมโยงกับบัญชีอุปกรณ์ บัญชี ACCOUNT_TYPE_LOCAL จะไม่ซิงค์

ค้นหาปฏิทิน

ต่อไปนี้เป็นตัวอย่างที่แสดงวิธีรับปฏิทินที่เป็นของผู้ใช้รายหนึ่ง เพื่อความเรียบง่าย ในตัวอย่างนี้การดำเนินการค้นหาจะแสดงใน เทรดอินเทอร์เฟซผู้ใช้ ("เทรดหลัก") ในทางปฏิบัติ ขั้นตอนนี้ควรทำแบบไม่พร้อมกัน แทนที่จะเป็นเทรดหลัก สำหรับการสนทนาเพิ่มเติม โปรดดูที่ เครื่องมือโหลด หากคุณไม่เพียงแต่จะอ่านข้อมูล แต่ยังแก้ไขข้อมูลด้วย โปรดดูAsyncQueryHandler

Kotlin

// Projection array. Creating indices for this array instead of doing
// dynamic lookups improves performance.
private val EVENT_PROJECTION: Array<String> = arrayOf(
        CalendarContract.Calendars._ID,                     // 0
        CalendarContract.Calendars.ACCOUNT_NAME,            // 1
        CalendarContract.Calendars.CALENDAR_DISPLAY_NAME,   // 2
        CalendarContract.Calendars.OWNER_ACCOUNT            // 3
)

// The indices for the projection array above.
private const val PROJECTION_ID_INDEX: Int = 0
private const val PROJECTION_ACCOUNT_NAME_INDEX: Int = 1
private const val PROJECTION_DISPLAY_NAME_INDEX: Int = 2
private const val PROJECTION_OWNER_ACCOUNT_INDEX: Int = 3

Java

// Projection array. Creating indices for this array instead of doing
// dynamic lookups improves performance.
public static final String[] EVENT_PROJECTION = new String[] {
    Calendars._ID,                           // 0
    Calendars.ACCOUNT_NAME,                  // 1
    Calendars.CALENDAR_DISPLAY_NAME,         // 2
    Calendars.OWNER_ACCOUNT                  // 3
};

// The indices for the projection array above.
private static final int PROJECTION_ID_INDEX = 0;
private static final int PROJECTION_ACCOUNT_NAME_INDEX = 1;
private static final int PROJECTION_DISPLAY_NAME_INDEX = 2;
private static final int PROJECTION_OWNER_ACCOUNT_INDEX = 3;

ในส่วนถัดไปของตัวอย่างเป็นการสร้างคำค้นหา ตัวเลือก ระบุเกณฑ์สำหรับการค้นหา ในตัวอย่างนี้ คําค้นหาจะมองหาปฏิทินที่มี ACCOUNT_NAME "hera@example.com", ACCOUNT_TYPE "com.example" และ OWNER_ACCOUNT "hera@example.com" หากต้องการดูปฏิทินทั้งหมดที่ผู้ใช้ดู ไม่ใช่แค่ปฏิทินที่ผู้ใช้เป็นเจ้าของ ให้ละเว้น OWNER_ACCOUNT การค้นหาแสดงผล Cursor ที่คุณสามารถใช้เพื่อข้ามผ่านชุดผลลัพธ์ที่ฐานข้อมูลส่งคืน คำถาม หากต้องการดูการสนทนาเพิ่มเติมเกี่ยวกับการใช้คำค้นหาในผู้ให้บริการเนื้อหา ดูผู้ให้บริการเนื้อหา

Kotlin

// Run query
val uri: Uri = CalendarContract.Calendars.CONTENT_URI
val selection: String = "((${CalendarContract.Calendars.ACCOUNT_NAME} = ?) AND (" +
        "${CalendarContract.Calendars.ACCOUNT_TYPE} = ?) AND (" +
        "${CalendarContract.Calendars.OWNER_ACCOUNT} = ?))"
val selectionArgs: Array<String> = arrayOf("hera@example.com", "com.example", "hera@example.com")
val cur: Cursor = contentResolver.query(uri, EVENT_PROJECTION, selection, selectionArgs, null)

Java

// Run query
Cursor cur = null;
ContentResolver cr = getContentResolver();
Uri uri = Calendars.CONTENT_URI;
String selection = "((" + Calendars.ACCOUNT_NAME + " = ?) AND ("
                        + Calendars.ACCOUNT_TYPE + " = ?) AND ("
                        + Calendars.OWNER_ACCOUNT + " = ?))";
String[] selectionArgs = new String[] {"hera@example.com", "com.example",
        "hera@example.com"};
// Submit the query and get a Cursor object back.
cur = cr.query(uri, EVENT_PROJECTION, selection, selectionArgs, null);

ส่วนถัดไปนี้จะใช้เคอร์เซอร์เพื่อไปยังชุดผลลัพธ์ โดยใช้ ค่าคงที่ที่ตั้งค่าไว้ในตอนแรกของตัวอย่างเพื่อให้แสดงผลค่า สำหรับแต่ละช่อง

Kotlin

// Use the cursor to step through the returned records
while (cur.moveToNext()) {
    // Get the field values
    val calID: Long = cur.getLong(PROJECTION_ID_INDEX)
    val displayName: String = cur.getString(PROJECTION_DISPLAY_NAME_INDEX)
    val accountName: String = cur.getString(PROJECTION_ACCOUNT_NAME_INDEX)
    val ownerName: String = cur.getString(PROJECTION_OWNER_ACCOUNT_INDEX)
    // Do something with the values...
}

Java

// Use the cursor to step through the returned records
while (cur.moveToNext()) {
    long calID = 0;
    String displayName = null;
    String accountName = null;
    String ownerName = null;

    // Get the field values
    calID = cur.getLong(PROJECTION_ID_INDEX);
    displayName = cur.getString(PROJECTION_DISPLAY_NAME_INDEX);
    accountName = cur.getString(PROJECTION_ACCOUNT_NAME_INDEX);
    ownerName = cur.getString(PROJECTION_OWNER_ACCOUNT_INDEX);

    // Do something with the values...

   ...
}

แก้ไขปฏิทิน

หากต้องการอัปเดตปฏิทิน ให้ระบุ _ID ของปฏิทินเป็นรหัสต่อท้าย Uri (withAppendedId()) หรือเป็นรายการการเลือกรายการแรก การเลือกควรขึ้นต้นด้วย "_id=?" และ selectionArg แรกควรเป็น _ID ของปฏิทิน และยังอัปเดตด้วยการเข้ารหัสรหัสใน URI ได้ด้วย ตัวอย่างนี้จะเปลี่ยนชื่อที่แสดงของปฏิทินโดยใช้แนวทาง (withAppendedId()) ดังนี้

Kotlin

const val DEBUG_TAG: String = "MyActivity"
...
val calID: Long = 2
val values = ContentValues().apply {
    // The new display name for the calendar
    put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, "Trevor's Calendar")
}
val updateUri: Uri = ContentUris.withAppendedId(CalendarContract.Calendars.CONTENT_URI, calID)
val rows: Int = contentResolver.update(updateUri, values, null, null)
Log.i(DEBUG_TAG, "Rows updated: $rows")

Java

private static final String DEBUG_TAG = "MyActivity";
...
long calID = 2;
ContentValues values = new ContentValues();
// The new display name for the calendar
values.put(Calendars.CALENDAR_DISPLAY_NAME, "Trevor's Calendar");
Uri updateUri = ContentUris.withAppendedId(Calendars.CONTENT_URI, calID);
int rows = getContentResolver().update(updateUri, values, null, null);
Log.i(DEBUG_TAG, "Rows updated: " + rows);

แทรกปฏิทิน

ปฏิทินได้รับการออกแบบมาให้ได้รับการจัดการโดยใช้อะแดปเตอร์การซิงค์เป็นหลัก คุณจึง ควรแทรกปฏิทินใหม่เป็นอะแดปเตอร์การซิงค์เท่านั้น ส่วนใหญ่แล้ว แอปพลิเคชันจะทำการเปลี่ยนแปลงปฏิทินได้เพียงผิวเผินเท่านั้น เช่น เปลี่ยนชื่อที่แสดง ถ้า แอปพลิเคชันจำเป็นต้องสร้างปฏิทินในเครื่อง ซึ่งสามารถทำได้โดย การแทรกปฏิทินเป็นอะแดปเตอร์การซิงค์ โดยใช้ ACCOUNT_TYPE จาก ACCOUNT_TYPE_LOCAL ACCOUNT_TYPE_LOCAL เป็นบัญชีประเภทพิเศษสำหรับปฏิทินที่ไม่ได้เชื่อมโยงกับบัญชีอุปกรณ์ ปฏิทินประเภทนี้จะไม่ซิงค์กับเซิร์ฟเวอร์ สำหรับ สำหรับเรื่องอะแดปเตอร์การซิงค์ โปรดดูอะแดปเตอร์การซิงค์

ตารางเหตุการณ์

ตาราง CalendarContract.Events มีรายละเอียดสำหรับแต่ละเหตุการณ์ หากต้องการเพิ่ม อัปเดต หรือลบกิจกรรม แอปพลิเคชันต้อง รวมสิทธิ์ WRITE_CALENDAR ไว้ใน ไฟล์ Manifest

คอลัมน์เหตุการณ์ต่อไปนี้เขียนได้ทั้งในแอปพลิเคชันและการซิงค์ อะแดปเตอร์ ดูรายการฟิลด์ทั้งหมดที่รองรับได้ที่ข้อมูลอ้างอิง CalendarContract.Events

ค่าคงที่ คำอธิบาย
CALENDAR_ID _ID ของปฏิทินที่มีกิจกรรมนี้
ORGANIZER อีเมลของผู้จัด (เจ้าของ) กิจกรรม
TITLE ชื่อกิจกรรม
EVENT_LOCATION สถานที่จัดกิจกรรม
DESCRIPTION คำอธิบายของกิจกรรม
DTSTART เวลาที่เหตุการณ์เริ่มต้นเป็นมิลลิวินาที UTC นับตั้งแต่ Epoch
DTEND เวลาที่เหตุการณ์สิ้นสุดในหน่วยมิลลิวินาที UTC นับตั้งแต่ Epoch
EVENT_TIMEZONE เขตเวลาของกิจกรรม
EVENT_END_TIMEZONE เขตเวลาสำหรับเวลาสิ้นสุดของกิจกรรม
DURATION ระยะเวลาของเหตุการณ์ในรูปแบบ RFC5545 เช่น ค่า "PT1H" ระบุว่าเหตุการณ์ ควรอยู่ที่ 1 ชั่วโมง และค่า "P2W" หมายถึง 2 สัปดาห์
ALL_DAY ค่า 1 หมายความว่ากิจกรรมนี้ใช้เวลาทั้งวัน ตามที่กำหนดโดย เขตเวลาท้องถิ่น ค่า 0 บ่งบอกว่าเป็นกิจกรรมปกติที่อาจเริ่มต้นและสิ้นสุดได้ทุกเมื่อในระหว่างวัน
RRULE กฎการเกิดซ้ำสำหรับรูปแบบกิจกรรม สำหรับ ตัวอย่างเช่น "FREQ=WEEKLY;COUNT=10;WKST=SU" คุณดู ตัวอย่างเพิ่มเติมที่นี่
RDATE วันที่ของกิจกรรมที่เกิดซ้ำ โดยทั่วไปคุณจะใช้ RDATE ร่วมกับ RRULE เพื่อกำหนดชุดรวมของการเกิดซ้ำ ดูการพูดคุยเพิ่มเติมได้ในข้อกำหนด RFC5545
AVAILABILITY กิจกรรมนี้นับเป็นช่วงเวลาที่ไม่ว่างหรือเป็นเวลาว่างที่สามารถ ตามกำหนดเวลา
GUESTS_CAN_MODIFY ผู้เข้าร่วมจะแก้ไขกิจกรรมได้หรือไม่
GUESTS_CAN_INVITE_OTHERS กำหนดว่าผู้เข้าร่วมจะเชิญผู้เข้าร่วมคนอื่นๆ ได้หรือไม่
GUESTS_CAN_SEE_GUESTS กำหนดว่าผู้เข้าร่วมสามารถดูรายชื่อผู้เข้าร่วมได้หรือไม่

เพิ่มเหตุการณ์

เมื่อแอปพลิเคชันแทรกเหตุการณ์ใหม่ เราขอแนะนําให้ใช้ INSERTIntent ตามที่อธิบายไว้ในการใช้ Intent เพื่อแทรกเหตุการณ์ อย่างไรก็ตาม หากคุณ คุณก็สามารถแทรกเหตุการณ์ได้โดยตรง ส่วนนี้จะอธิบายวิธีดำเนินการดังกล่าว

กฎสำหรับการแทรกเหตุการณ์ใหม่มีดังนี้

  • คุณต้องใส่ CALENDAR_ID และ DTSTART
  • คุณต้องใส่ EVENT_TIMEZONE วิธีรับรายการ ของรหัสเขตเวลาที่ติดตั้งของระบบ ให้ใช้ getAvailableIDs() โปรดทราบว่ากฎนี้จะไม่มีผลหากคุณแทรกเหตุการณ์ผ่าน Intent INSERT ซึ่งอธิบายไว้ในการใช้ Intent เพื่อแทรกเหตุการณ์ ในกรณีนี้ ระบบจะระบุเขตเวลาเริ่มต้น
  • สำหรับกิจกรรมที่เกิดซ้ำ คุณต้องใส่ DTEND
  • สำหรับเหตุการณ์ที่เกิดซ้ำ คุณต้องใส่ DURATION นอกเหนือจาก RRULE หรือ RDATE โปรดทราบว่ากฎนี้ใช้ไม่ได้ในกรณีต่อไปนี้ คุณกำลังแทรกเหตุการณ์ผ่าน Intent ของ INSERT ที่อธิบายไว้ในการใช้ Intent เพื่อแทรกเหตุการณ์ ซึ่งในนั้น คุณจะใช้ RRULE ร่วมกับ DTSTART และ DTEND และแอปพลิเคชันปฏิทินได้ จะแปลงเป็นระยะเวลาโดยอัตโนมัติ

ต่อไปนี้เป็นตัวอย่างของการแทรกเหตุการณ์ ขั้นตอนนี้ดำเนินการใน UI ชุดข้อความเพื่อความเรียบง่าย ในทางปฏิบัติ การป้อนข้อมูลและการอัปเดตควรทําในเธรดแบบไม่สอดคล้องกันเพื่อย้ายการดำเนินการไปยังเธรดเบื้องหลัง สำหรับข้อมูลเพิ่มเติม โปรดดูข้อมูลเพิ่มเติมที่ AsyncQueryHandler

Kotlin

val calID: Long = 3
val startMillis: Long = Calendar.getInstance().run {
    set(2012, 9, 14, 7, 30)
    timeInMillis
}
val endMillis: Long = Calendar.getInstance().run {
    set(2012, 9, 14, 8, 45)
    timeInMillis
}
...

val values = ContentValues().apply {
    put(CalendarContract.Events.DTSTART, startMillis)
    put(CalendarContract.Events.DTEND, endMillis)
    put(CalendarContract.Events.TITLE, "Jazzercise")
    put(CalendarContract.Events.DESCRIPTION, "Group workout")
    put(CalendarContract.Events.CALENDAR_ID, calID)
    put(CalendarContract.Events.EVENT_TIMEZONE, "America/Los_Angeles")
}
val uri: Uri = contentResolver.insert(CalendarContract.Events.CONTENT_URI, values)

// get the event ID that is the last element in the Uri
val eventID: Long = uri.lastPathSegment.toLong()
//
// ... do something with event ID
//
//

Java

long calID = 3;
long startMillis = 0;
long endMillis = 0;
Calendar beginTime = Calendar.getInstance();
beginTime.set(2012, 9, 14, 7, 30);
startMillis = beginTime.getTimeInMillis();
Calendar endTime = Calendar.getInstance();
endTime.set(2012, 9, 14, 8, 45);
endMillis = endTime.getTimeInMillis();
...

ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
values.put(Events.DTSTART, startMillis);
values.put(Events.DTEND, endMillis);
values.put(Events.TITLE, "Jazzercise");
values.put(Events.DESCRIPTION, "Group workout");
values.put(Events.CALENDAR_ID, calID);
values.put(Events.EVENT_TIMEZONE, "America/Los_Angeles");
Uri uri = cr.insert(Events.CONTENT_URI, values);

// get the event ID that is the last element in the Uri
long eventID = Long.parseLong(uri.getLastPathSegment());
//
// ... do something with event ID
//
//

หมายเหตุ: ดูว่าตัวอย่างนี้จับเหตุการณ์อย่างไร รหัสหลังสร้างกิจกรรม วิธีนี้เป็นวิธีที่ง่ายที่สุดในการรับรหัสกิจกรรม คุณมักจะต้องใช้รหัสกิจกรรมเพื่อดำเนินการอื่นๆ ในปฏิทิน เช่น เพิ่มผู้เข้าร่วมหรือการช่วยเตือนในกิจกรรม

กิจกรรมการอัปเดต

เมื่อแอปพลิเคชันต้องการอนุญาตให้ผู้ใช้แก้ไขกิจกรรม เราขอแนะนำให้คุณใช้ EDITIntent ตามที่อธิบายไว้ในการใช้ Intent เพื่อแก้ไขกิจกรรม แต่หากต้องการ คุณสามารถแก้ไขกิจกรรมได้โดยตรง หากต้องการอัปเดตเหตุการณ์ ให้ระบุ _ID ของเหตุการณ์เป็นรหัสต่อท้าย Uri (withAppendedId()) หรือเป็นรายการการเลือกรายการแรก การเลือกควรขึ้นต้นด้วย "_id=?" และ selectionArg แรกควรเป็น _ID ของเหตุการณ์ นอกจากนี้ คุณยังอัปเดตโดยใช้การเลือกที่ไม่มีรหัสได้ด้วย ลองดูตัวอย่างการอัปเดต กิจกรรม โดยจะเปลี่ยนชื่อกิจกรรมโดยใช้แนวทางต่อไปนี้ withAppendedId()

Kotlin

val DEBUG_TAG = "MyActivity"
...
val eventID: Long = 188
...
val values = ContentValues().apply {
    // The new title for the event
    put(CalendarContract.Events.TITLE, "Kickboxing")
}
val updateUri: Uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID)
val rows: Int = contentResolver.update(updateUri, values, null, null)
Log.i(DEBUG_TAG, "Rows updated: $rows")

Java

private static final String DEBUG_TAG = "MyActivity";
...
long eventID = 188;
...
ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
Uri updateUri = null;
// The new title for the event
values.put(Events.TITLE, "Kickboxing");
updateUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
int rows = cr.update(updateUri, values, null, null);
Log.i(DEBUG_TAG, "Rows updated: " + rows);

ลบกิจกรรม

คุณสามารถลบเหตุการณ์ได้โดยใช้ _ID เป็นรหัสต่อท้ายใน URI หรือใช้การเลือกมาตรฐาน หากใช้รหัสที่ต่อท้าย คุณจะเลือกตัวเลือกไม่ได้ด้วย การลบมี 2 แบบ ได้แก่ แบบแอปพลิเคชันและอะแดปเตอร์การซิงค์ CANNOT TRANSLATE การลบแอปพลิเคชันจะกำหนดคอลัมน์ deleted เป็น 1 ธงนี้ซึ่งบอกให้ อะแดปเตอร์การซิงค์ที่ลบแถวไปแล้ว และการลบนี้ควรจะเป็น เผยแพร่ไปยังเซิร์ฟเวอร์ การลบอะแดปเตอร์การซิงค์จะนำเหตุการณ์ออกจากฐานข้อมูลพร้อมกับข้อมูลที่เกี่ยวข้องทั้งหมด นี่เป็นตัวอย่างแอปพลิเคชัน กำลังลบกิจกรรมผ่าน _ID:

Kotlin

val DEBUG_TAG = "MyActivity"
...
val eventID: Long = 201
...
val deleteUri: Uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID)
val rows: Int = contentResolver.delete(deleteUri, null, null)
Log.i(DEBUG_TAG, "Rows deleted: $rows")

Java

private static final String DEBUG_TAG = "MyActivity";
...
long eventID = 201;
...
ContentResolver cr = getContentResolver();
Uri deleteUri = null;
deleteUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
int rows = cr.delete(deleteUri, null, null);
Log.i(DEBUG_TAG, "Rows deleted: " + rows);

ตารางผู้เข้าร่วม

แต่ละแถวของตาราง CalendarContract.Attendees จะแสดงถึงผู้เข้าร่วมหรือแขก 1 คนของกิจกรรม การเรียกใช้ query() จะแสดงรายชื่อผู้เข้าร่วมกิจกรรมที่มี EVENT_ID ที่ระบุ EVENT_IDเครื่องนี้ ต้องตรงกับ _ID ของเหตุการณ์ใดเหตุการณ์หนึ่ง

ตารางต่อไปนี้แสดงรายการช่องที่เขียนได้ เมื่อแทรกผู้เข้าร่วมใหม่ คุณต้องระบุผู้เข้าร่วมทั้งหมด ยกเว้น ATTENDEE_NAME

ค่าคงที่ คำอธิบาย
EVENT_ID รหัสของเหตุการณ์
ATTENDEE_NAME ชื่อผู้เข้าร่วม
ATTENDEE_EMAIL อีเมลของผู้เข้าร่วม
ATTENDEE_RELATIONSHIP

ความสัมพันธ์ของผู้เข้าร่วมกับกิจกรรม ข้อใดข้อหนึ่งต่อไปนี้

ATTENDEE_TYPE

ประเภทผู้เข้าร่วม ข้อใดข้อหนึ่ง:

ATTENDEE_STATUS

สถานะการเข้าร่วมของผู้เข้าร่วม ข้อใดข้อหนึ่งต่อไปนี้

เพิ่มผู้เข้าร่วม

ภาพต่อไปนี้เป็นตัวอย่างที่เพิ่มผู้เข้าร่วม 1 คนในกิจกรรม โปรดทราบว่า EVENT_ID ต้องระบุ:

Kotlin

val eventID: Long = 202
...
val values = ContentValues().apply {
    put(CalendarContract.Attendees.ATTENDEE_NAME, "Trevor")
    put(CalendarContract.Attendees.ATTENDEE_EMAIL, "trevor@example.com")
    put(
        CalendarContract.Attendees.ATTENDEE_RELATIONSHIP,
        CalendarContract.Attendees.RELATIONSHIP_ATTENDEE
    )
    put(CalendarContract.Attendees.ATTENDEE_TYPE, CalendarContract.Attendees.TYPE_OPTIONAL)
    put(
        CalendarContract.Attendees.ATTENDEE_STATUS,
        CalendarContract.Attendees.ATTENDEE_STATUS_INVITED
    )
    put(CalendarContract.Attendees.EVENT_ID, eventID)
}
val uri: Uri = contentResolver.insert(CalendarContract.Attendees.CONTENT_URI, values)

Java

long eventID = 202;
...
ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
values.put(Attendees.ATTENDEE_NAME, "Trevor");
values.put(Attendees.ATTENDEE_EMAIL, "trevor@example.com");
values.put(Attendees.ATTENDEE_RELATIONSHIP, Attendees.RELATIONSHIP_ATTENDEE);
values.put(Attendees.ATTENDEE_TYPE, Attendees.TYPE_OPTIONAL);
values.put(Attendees.ATTENDEE_STATUS, Attendees.ATTENDEE_STATUS_INVITED);
values.put(Attendees.EVENT_ID, eventID);
Uri uri = cr.insert(Attendees.CONTENT_URI, values);

ตารางการช่วยเตือน

แต่ละแถวของตาราง CalendarContract.Reminders หมายถึงการช่วยเตือนรายการเดียวสำหรับกิจกรรม การโทร query() แสดงรายการการช่วยเตือนสำหรับ ที่มี EVENT_ID

ตารางต่อไปนี้แสดงรายการช่องที่เขียนได้สำหรับช่วยเตือน โดยต้องใส่ข้อมูลทั้งหมดเมื่อแทรกการช่วยเตือนใหม่ โปรดทราบว่าอะแดปเตอร์การซิงค์จะระบุ ประเภทของการช่วยเตือนที่รองรับในตาราง CalendarContract.Calendars โปรดดู ALLOWED_REMINDERS เพื่อดูรายละเอียด

ค่าคงที่ คำอธิบาย
EVENT_ID รหัสของเหตุการณ์
MINUTES จำนวนนาทีก่อนถึงเวลาของกิจกรรมที่การช่วยเตือนควรเริ่มทำงาน
METHOD

วิธีการตั้งปลุกตามที่ตั้งไว้บนเซิร์ฟเวอร์ ข้อใดข้อหนึ่งต่อไปนี้

เพิ่มการแจ้งเตือน

ตัวอย่างนี้จะเพิ่มการช่วยเตือนลงในกิจกรรม การช่วยเตือนเริ่มทำงาน 15 ครั้ง นาทีก่อนถึงกิจกรรม

Kotlin

val eventID: Long = 221
...
val values = ContentValues().apply {
    put(CalendarContract.Reminders.MINUTES, 15)
    put(CalendarContract.Reminders.EVENT_ID, eventID)
    put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT)
}
val uri: Uri = contentResolver.insert(CalendarContract.Reminders.CONTENT_URI, values)

Java

long eventID = 221;
...
ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
values.put(Reminders.MINUTES, 15);
values.put(Reminders.EVENT_ID, eventID);
values.put(Reminders.METHOD, Reminders.METHOD_ALERT);
Uri uri = cr.insert(Reminders.CONTENT_URI, values);

ตารางอินสแตนซ์

ตาราง CalendarContract.Instances มีค่า เวลาเริ่มต้นและสิ้นสุดสำหรับการเกิดเหตุการณ์ แต่ละแถวในตารางนี้ แสดงถึงเหตุการณ์เดียว ตารางอินสแตนซ์เป็นแบบเขียนไม่ได้และมีไว้เพื่อใช้ค้นหาการเกิดเหตุการณ์เท่านั้น

ตารางต่อไปนี้แสดงช่องบางส่วนที่คุณใช้ค้นหาอินสแตนซ์ได้ หมายเหตุ เขตเวลานั้นจะกำหนดตาม KEY_TIMEZONE_TYPE และ KEY_TIMEZONE_INSTANCES

ค่าคงที่ คำอธิบาย
BEGIN เวลาเริ่มต้นของอินสแตนซ์ในหน่วยมิลลิวินาที UTC
END เวลาสิ้นสุดของอินสแตนซ์ในหน่วยมิลลิวินาที UTC
END_DAY วันที่สิ้นสุดของอินสแตนซ์จูเลียนซึ่งสัมพันธ์กับเวลาของปฏิทิน
END_MINUTE นาทีสิ้นสุดของอินสแตนซ์วัดจากเที่ยงคืนใน เขตเวลาของปฏิทิน
EVENT_ID _ID ของเหตุการณ์สำหรับอินสแตนซ์นี้
START_DAY วันเริ่มต้นจูเลียนของอินสแตนซ์ซึ่งเกี่ยวข้องกับเขตเวลาของปฏิทิน
START_MINUTE นาทีเริ่มต้นของอินสแตนซ์วัดจากเที่ยงคืนเมื่อเทียบกับ เขตเวลาของปฏิทิน

ค้นหาตารางอินสแตนซ์

ในการค้นหาตารางอินสแตนซ์ คุณต้องระบุช่วงเวลาสำหรับการค้นหา ใน URI ในตัวอย่างนี้ CalendarContract.Instances เข้าถึงฟิลด์ TITLE ผ่าน การใช้งานอินเทอร์เฟซ CalendarContract.EventsColumns กล่าวคือ TITLE จะแสดงผลผ่าน มุมมองฐานข้อมูล ไม่ใช่การค้นหาตาราง CalendarContract.Instances ที่เป็นข้อมูลดิบ

Kotlin

const val DEBUG_TAG: String = "MyActivity"
val INSTANCE_PROJECTION: Array<String> = arrayOf(
        CalendarContract.Instances.EVENT_ID, // 0
        CalendarContract.Instances.BEGIN, // 1
        CalendarContract.Instances.TITLE // 2
)

// The indices for the projection array above.
const val PROJECTION_ID_INDEX: Int = 0
const val PROJECTION_BEGIN_INDEX: Int = 1
const val PROJECTION_TITLE_INDEX: Int = 2

// Specify the date range you want to search for recurring
// event instances
val startMillis: Long = Calendar.getInstance().run {
    set(2011, 9, 23, 8, 0)
    timeInMillis
}
val endMillis: Long = Calendar.getInstance().run {
    set(2011, 10, 24, 8, 0)
    timeInMillis
}

// The ID of the recurring event whose instances you are searching
// for in the Instances table
val selection: String = "${CalendarContract.Instances.EVENT_ID} = ?"
val selectionArgs: Array<String> = arrayOf("207")

// Construct the query with the desired date range.
val builder: Uri.Builder = CalendarContract.Instances.CONTENT_URI.buildUpon()
ContentUris.appendId(builder, startMillis)
ContentUris.appendId(builder, endMillis)

// Submit the query
val cur: Cursor = contentResolver.query(
        builder.build(),
        INSTANCE_PROJECTION,
        selection,
        selectionArgs, null
)
while (cur.moveToNext()) {
    // Get the field values
    val eventID: Long = cur.getLong(PROJECTION_ID_INDEX)
    val beginVal: Long = cur.getLong(PROJECTION_BEGIN_INDEX)
    val title: String = cur.getString(PROJECTION_TITLE_INDEX)

    // Do something with the values.
    Log.i(DEBUG_TAG, "Event: $title")
    val calendar = Calendar.getInstance().apply {
        timeInMillis = beginVal
    }
    val formatter = SimpleDateFormat("MM/dd/yyyy")
    Log.i(DEBUG_TAG, "Date: ${formatter.format(calendar.time)}")
}

Java

private static final String DEBUG_TAG = "MyActivity";
public static final String[] INSTANCE_PROJECTION = new String[] {
    Instances.EVENT_ID,      // 0
    Instances.BEGIN,         // 1
    Instances.TITLE          // 2
  };

// The indices for the projection array above.
private static final int PROJECTION_ID_INDEX = 0;
private static final int PROJECTION_BEGIN_INDEX = 1;
private static final int PROJECTION_TITLE_INDEX = 2;
...

// Specify the date range you want to search for recurring
// event instances
Calendar beginTime = Calendar.getInstance();
beginTime.set(2011, 9, 23, 8, 0);
long startMillis = beginTime.getTimeInMillis();
Calendar endTime = Calendar.getInstance();
endTime.set(2011, 10, 24, 8, 0);
long endMillis = endTime.getTimeInMillis();

Cursor cur = null;
ContentResolver cr = getContentResolver();

// The ID of the recurring event whose instances you are searching
// for in the Instances table
String selection = Instances.EVENT_ID + " = ?";
String[] selectionArgs = new String[] {"207"};

// Construct the query with the desired date range.
Uri.Builder builder = Instances.CONTENT_URI.buildUpon();
ContentUris.appendId(builder, startMillis);
ContentUris.appendId(builder, endMillis);

// Submit the query
cur =  cr.query(builder.build(),
    INSTANCE_PROJECTION,
    selection,
    selectionArgs,
    null);

while (cur.moveToNext()) {
    String title = null;
    long eventID = 0;
    long beginVal = 0;

    // Get the field values
    eventID = cur.getLong(PROJECTION_ID_INDEX);
    beginVal = cur.getLong(PROJECTION_BEGIN_INDEX);
    title = cur.getString(PROJECTION_TITLE_INDEX);

    // Do something with the values.
    Log.i(DEBUG_TAG, "Event:  " + title);
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(beginVal);
    DateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
    Log.i(DEBUG_TAG, "Date: " + formatter.format(calendar.getTime()));
    }
 }

Intent ของปฏิทิน

แอปพลิเคชันของคุณไม่จำเป็นต้องมีสิทธิ์ในการอ่านและเขียนข้อมูลปฏิทิน โดยสามารถใช้ Intent ที่แอปพลิเคชันปฏิทินของ Android รองรับเพื่อส่งต่อการดำเนินการอ่านและเขียนไปยังแอปพลิเคชันนั้นแทน ตารางต่อไปนี้แสดง Intent ที่ผู้ให้บริการปฏิทินรองรับ

การทำงาน URI คำอธิบาย เพิ่มเติม

VIEW

content://com.android.calendar/time/<ms_since_epoch>

นอกจากนี้ คุณยังอ้างอิง URI ด้วย CalendarContract.CONTENT_URI ได้ด้วย สำหรับตัวอย่างของการใช้ Intent นี้ โปรดดูการใช้ Intent เพื่อดูข้อมูลปฏิทิน
เปิดปฏิทินตามเวลาที่ระบุโดย <ms_since_epoch> ไม่มี

VIEW

content://com.android.calendar/events/<event_id>

นอกจากนี้คุณยังดู URI ได้ด้วย Events.CONTENT_URI สำหรับตัวอย่างของการใช้ Intent นี้ โปรดดูการใช้ Intent เพื่อดูข้อมูลปฏิทิน
ดูเหตุการณ์ที่ <event_id> ระบุ CalendarContract.EXTRA_EVENT_BEGIN_TIME


CalendarContract.EXTRA_EVENT_END_TIME
EDIT

content://com.android.calendar/events/<event_id>

นอกจากนี้ คุณยังอ้างอิง URI ด้วย Events.CONTENT_URI ได้ด้วย ดูตัวอย่างการใช้ Intent นี้ได้ที่การใช้ Intent เพื่อแก้ไขเหตุการณ์
แก้ไขเหตุการณ์ที่ <event_id> ระบุ CalendarContract.EXTRA_EVENT_BEGIN_TIME


CalendarContract.EXTRA_EVENT_END_TIME
EDIT

INSERT

content://com.android.calendar/events

นอกจากนี้ คุณยังอ้างอิง URI ด้วย Events.CONTENT_URI ได้ด้วย สำหรับตัวอย่างการใช้ Intent นี้ โปรดดูการใช้ Intent เพื่อแทรกเหตุการณ์
สร้างกิจกรรม ฟีเจอร์พิเศษที่ระบุไว้ในตารางด้านล่าง

ตารางต่อไปนี้แสดงรายการข้อมูลเพิ่มเติมของ Intent ที่ผู้ให้บริการปฏิทินรองรับ

ความตั้งใจเพิ่มเติม คำอธิบาย
Events.TITLE ชื่อเหตุการณ์
CalendarContract.EXTRA_EVENT_BEGIN_TIME เวลาเริ่มต้นของเหตุการณ์เป็นมิลลิวินาทีนับจากจุดเริ่มต้น
CalendarContract.EXTRA_EVENT_END_TIME เวลาสิ้นสุดเหตุการณ์เป็นมิลลิวินาทีจาก Epoch
CalendarContract.EXTRA_EVENT_ALL_DAY บูลีนที่ระบุว่ากิจกรรมนั้นเกิดขึ้นทั้งวัน ค่าอาจเป็น true หรือ false
Events.EVENT_LOCATION สถานที่จัดกิจกรรม
Events.DESCRIPTION คำอธิบายกิจกรรม
Intent.EXTRA_EMAIL อีเมลของผู้ที่จะเชิญเป็นรายการที่คั่นด้วยคอมมา
Events.RRULE กฎการเกิดซ้ำสำหรับกิจกรรม
Events.ACCESS_LEVEL ระบุว่ากิจกรรมเป็นแบบส่วนตัวหรือสาธารณะ
Events.AVAILABILITY หากกิจกรรมนี้นับเป็นเวลาที่ไม่ว่างหรือเป็นเวลาว่างที่สามารถกำหนดเวลาใหม่ได้

ส่วนต่อไปนี้จะอธิบายวิธีใช้ Intent เหล่านี้

ใช้ Intent เพื่อแทรกเหตุการณ์

การใช้ Intent INSERT ช่วยให้แอปพลิเคชันของคุณส่งงานการแทรกกิจกรรมไปยังปฏิทินเอง วิธีนี้จะทำให้แอปพลิเคชันของคุณไม่จำเป็นต้องมีสิทธิ์ WRITE_CALENDAR ในไฟล์ Manifest อีกด้วย

เมื่อผู้ใช้เรียกใช้แอปพลิเคชันที่ใช้วิธีนี้ แอปพลิเคชันจะส่ง ในปฏิทินเพื่อเพิ่มกิจกรรมให้เสร็จสิ้น Intent ของ INSERT ใช้ช่องเพิ่มเติมเพื่อ กรอกรายละเอียดของกิจกรรมในปฏิทินไว้ล่วงหน้าในแบบฟอร์ม จากนั้นผู้ใช้จะยกเลิกกิจกรรม แก้ไขแบบฟอร์มตามต้องการ หรือบันทึกกิจกรรมลงในปฏิทินก็ได้

ต่อไปนี้คือข้อมูลโค้ดที่กำหนดเวลาเหตุการณ์ในวันที่ 19 มกราคม 2012 ซึ่งเริ่มตั้งแต่เวลา 07:30 น. ถึง 08:30 น. โปรดทราบข้อมูลต่อไปนี้เกี่ยวกับข้อมูลโค้ดนี้

  • มีการระบุ Events.CONTENT_URI ในชื่ออูรี
  • โดยใช้ช่อง CalendarContract.EXTRA_EVENT_BEGIN_TIME และอีก CalendarContract.EXTRA_EVENT_END_TIME ช่องเพื่อเติมข้อมูลในแบบฟอร์มล่วงหน้า พร้อมกับเวลาของกิจกรรม ค่าของเวลาเหล่านี้ต้องเป็นมิลลิวินาที UTC นับจากจุดเริ่มต้น
  • โดยใช้Intent.EXTRA_EMAIL ช่องเพิ่มเติมเพื่อระบุรายชื่อผู้ได้รับเชิญที่คั่นด้วยคอมมา ซึ่งระบุตามอีเมล

Kotlin

val startMillis: Long = Calendar.getInstance().run {
    set(2012, 0, 19, 7, 30)
    timeInMillis
}
val endMillis: Long = Calendar.getInstance().run {
    set(2012, 0, 19, 8, 30)
    timeInMillis
}
val intent = Intent(Intent.ACTION_INSERT)
        .setData(CalendarContract.Events.CONTENT_URI)
        .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, startMillis)
        .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endMillis)
        .putExtra(CalendarContract.Events.TITLE, "Yoga")
        .putExtra(CalendarContract.Events.DESCRIPTION, "Group class")
        .putExtra(CalendarContract.Events.EVENT_LOCATION, "The gym")
        .putExtra(CalendarContract.Events.AVAILABILITY, CalendarContract.Events.AVAILABILITY_BUSY)
        .putExtra(Intent.EXTRA_EMAIL, "rowan@example.com,trevor@example.com")
startActivity(intent)

Java

Calendar beginTime = Calendar.getInstance();
beginTime.set(2012, 0, 19, 7, 30);
Calendar endTime = Calendar.getInstance();
endTime.set(2012, 0, 19, 8, 30);
Intent intent = new Intent(Intent.ACTION_INSERT)
        .setData(Events.CONTENT_URI)
        .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis())
        .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis())
        .putExtra(Events.TITLE, "Yoga")
        .putExtra(Events.DESCRIPTION, "Group class")
        .putExtra(Events.EVENT_LOCATION, "The gym")
        .putExtra(Events.AVAILABILITY, Events.AVAILABILITY_BUSY)
        .putExtra(Intent.EXTRA_EMAIL, "rowan@example.com,trevor@example.com");
startActivity(intent);

ใช้ Intent เพื่อแก้ไขกิจกรรม

คุณสามารถอัปเดตเหตุการณ์ได้โดยตรงตามที่อธิบายไว้ในการอัปเดตเหตุการณ์ แต่การใช้ Intent EDIT จะทำให้แอปพลิเคชันที่ ไม่มีสิทธิ์ส่งต่อการแก้ไขกิจกรรมไปยังแอปพลิเคชันปฏิทิน เมื่อแก้ไขกิจกรรมในปฏิทินเสร็จแล้ว ระบบจะนําผู้ใช้กลับไปยังแอปพลิเคชันเดิม

ต่อไปนี้คือตัวอย่าง Intent ที่ตั้งชื่อใหม่ให้กับกิจกรรมที่ระบุและอนุญาตให้ผู้ใช้แก้ไขกิจกรรมในปฏิทิน

Kotlin

val eventID: Long = 208
val uri: Uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID)
val intent = Intent(Intent.ACTION_EDIT)
        .setData(uri)
        .putExtra(CalendarContract.Events.TITLE, "My New Title")
startActivity(intent)

Java

long eventID = 208;
Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
Intent intent = new Intent(Intent.ACTION_EDIT)
    .setData(uri)
    .putExtra(Events.TITLE, "My New Title");
startActivity(intent);

ใช้ Intent เพื่อดูข้อมูลปฏิทิน

ผู้ให้บริการปฏิทินมีวิธีใช้ VIEW Intent 2 วิธีดังนี้

  • วิธีเปิดปฏิทินไปที่วันที่ที่ต้องการ
  • วิธีดูกิจกรรม

ต่อไปนี้เป็นตัวอย่างที่แสดงวิธีเปิดปฏิทินไปยังวันที่ที่ต้องการ

Kotlin

val startMillis: Long
...
val builder: Uri.Builder = CalendarContract.CONTENT_URI.buildUpon()
        .appendPath("time")
ContentUris.appendId(builder, startMillis)
val intent = Intent(Intent.ACTION_VIEW)
        .setData(builder.build())
startActivity(intent)

Java

// A date-time specified in milliseconds since the epoch.
long startMillis;
...
Uri.Builder builder = CalendarContract.CONTENT_URI.buildUpon();
builder.appendPath("time");
ContentUris.appendId(builder, startMillis);
Intent intent = new Intent(Intent.ACTION_VIEW)
    .setData(builder.build());
startActivity(intent);

นี่คือตัวอย่างที่แสดงวิธีเปิดกิจกรรมเพื่อดู

Kotlin

val eventID: Long = 208
...
val uri: Uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID)
val intent = Intent(Intent.ACTION_VIEW).setData(uri)
startActivity(intent)

Java

long eventID = 208;
...
Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
Intent intent = new Intent(Intent.ACTION_VIEW)
   .setData(uri);
startActivity(intent);

ซิงค์อะแดปเตอร์

แอปพลิเคชันและอะแดปเตอร์การซิงค์มีความแตกต่างกันเพียงเล็กน้อยเท่านั้น เข้าถึงผู้ให้บริการปฏิทิน:

  • อะแดปเตอร์การซิงค์ต้องระบุว่าเป็นอะแดปเตอร์การซิงค์โดยการตั้งค่า CALLER_IS_SYNCADAPTER เป็น true
  • อะแดปเตอร์การซิงค์ต้องระบุ ACCOUNT_NAME และ ACCOUNT_TYPE เป็นพารามิเตอร์การค้นหาใน URI
  • อะแดปเตอร์การซิงค์มีสิทธิ์เขียนคอลัมน์มากกว่าแอปพลิเคชันหรือวิดเจ็ต เช่น แอปพลิเคชันจะแก้ไขลักษณะของปฏิทินได้เพียง 2-3 ข้อ เช่น ชื่อ ชื่อที่แสดง การตั้งค่าระดับการเข้าถึง และกำหนดว่าปฏิทิน ซิงค์แล้ว เมื่อเปรียบเทียบกันแล้ว อะแดปเตอร์การซิงค์ไม่เพียงสามารถเข้าถึงคอลัมน์เหล่านั้น แต่สามารถเข้าถึงคอลัมน์อื่นๆ ได้ เช่น สีปฏิทิน เขตเวลา ระดับการเข้าถึง สถานที่ และอื่นๆ อย่างไรก็ตาม อะแดปเตอร์การซิงค์จะจำกัดเฉพาะ ACCOUNT_NAME และ ACCOUNT_TYPE ที่ระบุไว้

วิธีการของตัวช่วยที่คุณสามารถใช้เพื่อส่งคืน URI สำหรับใช้กับอะแดปเตอร์การซิงค์มีดังนี้

Kotlin

fun asSyncAdapter(uri: Uri, account: String, accountType: String): Uri {
    return uri.buildUpon()
            .appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
            .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, account)
            .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, accountType).build()
}

Java

static Uri asSyncAdapter(Uri uri, String account, String accountType) {
    return uri.buildUpon()
        .appendQueryParameter(android.provider.CalendarContract.CALLER_IS_SYNCADAPTER,"true")
        .appendQueryParameter(Calendars.ACCOUNT_NAME, account)
        .appendQueryParameter(Calendars.ACCOUNT_TYPE, accountType).build();
 }