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

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

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

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

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

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

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

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

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

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

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

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

ตาราง (ชั้น) คำอธิบาย

CalendarContract.Calendars

ตารางนี้มีข้อมูลที่เจาะจงปฏิทิน แต่ละแถวในตารางนี้มีรายละเอียดของปฏิทินเดียว เช่น ชื่อ สี ข้อมูลการซิงค์ และอื่นๆ
CalendarContract.Events ตารางนี้มีข้อมูลเฉพาะกิจกรรม แต่ละแถวในตารางนี้มีข้อมูลของกิจกรรมเดียว เช่น ชื่อกิจกรรม สถานที่ เวลาเริ่มต้น เวลาสิ้นสุด และอื่นๆ เหตุการณ์อาจเกิดขึ้นเพียงครั้งเดียวหรือเกิดขึ้นซ้ำหลายครั้งก็ได้ ระบบจะเก็บผู้เข้าร่วม การช่วยเตือน และพร็อพเพอร์ตี้เพิ่มเติมไว้ในตารางแยกต่างหาก โดยแต่ละรายการจะมี EVENT_ID ที่อ้างอิง _ID ในตารางเหตุการณ์
CalendarContract.Instances ตารางนี้มีเวลาเริ่มต้นและสิ้นสุดของเหตุการณ์แต่ละรายการ แต่ละแถวในตารางนี้แสดงถึงการเกิดเหตุการณ์ครั้งเดียว สําหรับเหตุการณ์ที่เกิดขึ้นเพียงครั้งเดียว จะมีการแมปอินสแตนซ์กับเหตุการณ์แบบ 1:1 สําหรับเหตุการณ์ที่เกิดขึ้นซ้ำ ระบบจะสร้างหลายแถวโดยอัตโนมัติซึ่งสอดคล้องกับการเกิดเหตุการณ์นั้นหลายครั้ง
CalendarContract.Attendees ตารางนี้มีข้อมูลผู้เข้าร่วม (ผู้เข้าร่วม) กิจกรรม แต่ละแถวแสดงแขก 1 คนของกิจกรรม โดยระบุประเภทของผู้เข้าร่วมและคำตอบการเข้าร่วมของผู้เข้าร่วมสำหรับกิจกรรม
CalendarContract.Reminders ตารางนี้มีข้อมูลการแจ้งเตือน แต่ละแถวจะแสดงการแจ้งเตือนรายการเดียวสำหรับเหตุการณ์ กิจกรรมหนึ่งๆ มีการช่วยเตือนได้หลายรายการ จำนวนการช่วยเตือนสูงสุดต่อกิจกรรมจะระบุไว้ใน 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 นับตั้งแต่เริ่มต้น
DTEND เวลาที่เหตุการณ์สิ้นสุดในหน่วยมิลลิวินาที UTC นับตั้งแต่เริ่มต้น
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 thread เพื่อลดความซับซ้อน ในทางปฏิบัติ การแทรกและอัปเดตควรทำในเทรดแบบไม่พร้อมกันเพื่อย้ายการดำเนินการไปไว้ในเทรดเบื้องหลัง ดูข้อมูลเพิ่มเติมได้ที่ 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
//
//

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

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

เมื่อแอปพลิเคชันต้องการอนุญาตให้ผู้ใช้แก้ไขกิจกรรม เราขอแนะนําให้ใช้ EDIT Intent ตามที่อธิบายไว้ในการใช้ 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 แบบ ได้แก่ แบบแอปพลิเคชันและอะแดปเตอร์การซิงค์ การลบแอปพลิเคชันจะตั้งค่าคอลัมน์ลบแล้วเป็น 1 Flag นี้จะบอกอะแดปเตอร์การซิงค์ว่ามีการลบแถวแล้ว และควรนำไปเผยแพร่ไปยังเซิร์ฟเวอร์ การลบอะแดปเตอร์การซิงค์จะนำเหตุการณ์ออกจากฐานข้อมูลพร้อมกับข้อมูลที่เกี่ยวข้องทั้งหมด ต่อไปนี้คือตัวอย่างแอปพลิเคชันที่มีการลบเหตุการณ์ผ่าน _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 ที่ผู้ให้บริการปฏิทินรองรับ

Intent Extra คำอธิบาย
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

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

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

  • โดยระบุ Events.CONTENT_URI เป็น 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 เพื่อดูข้อมูลปฏิทิน

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

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

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

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
  • อะแดปเตอร์การซิงค์มีสิทธิ์เขียนในคอลัมน์มากกว่าแอปพลิเคชันหรือวิดเจ็ต ตัวอย่างเช่น แอปพลิเคชันจะแก้ไขได้เพียงบางลักษณะของปฏิทิน เช่น ชื่อ ชื่อที่แสดง การตั้งค่าระดับการเข้าถึง และการซิงค์ปฏิทินหรือไม่ ในทางกลับกัน ตัวเชื่อมข้อมูลจะเข้าถึงได้ไม่เพียงคอลัมน์เหล่านั้นเท่านั้น แต่ยังเข้าถึงคอลัมน์อื่นๆ อีกมากมาย เช่น สีปฏิทิน เขตเวลา ระดับการเข้าถึง ตำแหน่ง และอื่นๆ อย่างไรก็ตาม อะแดปเตอร์การซิงค์จะจำกัดอยู่ที่ 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();
 }