Tổng quan về trình cung cấp lịch

Trình cung cấp lịch là một kho lưu trữ các sự kiện trên lịch của người dùng. Chiến lược phát hành đĩa đơn Calendar Provider API cho phép bạn thực hiện truy vấn, chèn, cập nhật và xoá thao tác trên lịch, sự kiện, người tham dự, lời nhắc, v.v.

Các ứng dụng và bộ điều hợp đồng bộ hoá có thể sử dụng API Nhà cung cấp Lịch. Các quy tắc sẽ khác nhau tuỳ thuộc vào loại chương trình đang thực hiện lệnh gọi. Tài liệu này chủ yếu tập trung vào việc sử dụng API Trình cung cấp lịch dưới dạng một ứng dụng. Để thảo luận về sự khác biệt của các bộ điều hợp đồng bộ hoá, hãy xem Bộ điều hợp đồng bộ hoá.

Thông thường, để đọc hoặc ghi dữ liệu lịch, tệp kê khai của ứng dụng phải bao gồm các quyền thích hợp, được mô tả trong phần Quyền của người dùng. Để thực hiện các thao tác chung dễ dàng hơn, Lịch Nhà cung cấp đưa ra một tập hợp ý định, như mô tả trong Lịch Ý định. Các ý định này đưa người dùng đến ứng dụng Lịch để chèn, xem và chỉnh sửa sự kiện. Người dùng tương tác với ứng dụng Lịch, sau đó sẽ trở lại ứng dụng ban đầu. Do đó, ứng dụng của bạn không cần yêu cầu quyền cũng không cần cung cấp giao diện người dùng để xem hoặc tạo sự kiện.

Thông tin cơ bản

Trình cung cấp nội dung lưu trữ dữ liệu và cho phép các ứng dụng truy cập vào dữ liệu đó. Các trình cung cấp nội dung do nền tảng Android cung cấp (bao gồm cả Trình cung cấp lịch) thường hiển thị dữ liệu dưới dạng một tập hợp các bảng dựa trên mô hình cơ sở dữ liệu quan hệ, trong đó mỗi hàng là một bản ghi và mỗi cột là dữ liệu của một loại và ý nghĩa cụ thể. Thông qua API Trình cung cấp lịch, các ứng dụng và trình chuyển đổi đồng bộ hoá có thể có quyền đọc/ghi vào các bảng cơ sở dữ liệu chứa dữ liệu lịch của người dùng.

Mỗi trình cung cấp nội dung đều hiển thị một URI công khai (được gói dưới dạng đối tượng Uri) giúp xác định duy nhất tập dữ liệu của trình cung cấp nội dung đó. Trình cung cấp nội dung kiểm soát nhiều tập dữ liệu (nhiều bảng) hiển thị một URI riêng biệt cho mỗi tập dữ liệu. Tất cả URI cho trình cung cấp đều bắt đầu bằng chuỗi "content://". Chiến dịch này xác định dữ liệu do một nhà cung cấp nội dung kiểm soát. Lịch Trình cung cấp xác định hằng số cho URI cho từng lớp (bảng). Các URI này có định dạng <class>.CONTENT_URI. Ví dụ: Events.CONTENT_URI.

Hình 1 cho thấy mô hình dữ liệu của Nhà cung cấp lịch dưới dạng đồ hoạ. Bảng này cho thấy các bảng chính và các trường liên kết các bảng với nhau.

Mô hình dữ liệu của nhà cung cấp lịch

Hình 1. Mô hình dữ liệu của Nhà cung cấp lịch.

Một người dùng có thể có nhiều lịch và các lịch khác nhau có thể được liên kết với các loại tài khoản khác nhau (Lịch Google, Exchange, v.v.).

CalendarContract xác định mô hình dữ liệu của lịch và thông tin liên quan đến sự kiện. Dữ liệu này được lưu trữ trong một số bảng, được liệt kê dưới đây.

Bảng (Lớp) Mô tả

CalendarContract.Calendars

Bảng này chứa thông tin cụ thể về lịch. Mỗi hàng trong bảng này chứa thông tin chi tiết về một lịch, chẳng hạn như tên, màu sắc, thông tin đồng bộ hoá, v.v.
CalendarContract.Events Bảng này chứa thông tin cụ thể về sự kiện. Mỗi hàng trong bảng này có thông tin về một sự kiện, chẳng hạn như tiêu đề sự kiện, vị trí, thời gian bắt đầu, thời gian kết thúc, v.v. Sự kiện có thể xảy ra một lần hoặc có thể lặp lại nhiều lần. Người tham dự, lời nhắc và thuộc tính mở rộng được lưu trữ trong các bảng riêng. Mỗi sự kiện đều có một EVENT_ID tham chiếu đến _ID trong bảng Sự kiện.
CalendarContract.Instances Bảng này chứa thời gian bắt đầu và kết thúc của mỗi lần xuất hiện sự kiện. Mỗi hàng trong bảng này biểu thị một lần xuất hiện sự kiện. Đối với các sự kiện diễn ra một lần, có mối liên kết 1:1 đối với sự kiện. Đối với các sự kiện định kỳ, nhiều hàng sẽ tự động được tạo tương ứng với nhiều lần xuất hiện của sự kiện đó.
CalendarContract.Attendees Bảng này chứa thông tin về người tham dự sự kiện (khách). Mỗi hàng đại diện cho một khách của sự kiện. Trường này chỉ định loại khách và phản hồi tham dự của khách cho sự kiện.
CalendarContract.Reminders Bảng này chứa dữ liệu cảnh báo/thông báo. Mỗi hàng đại diện cho một cảnh báo duy nhất cho một sự kiện. Một sự kiện có thể có nhiều lời nhắc. Số lời nhắc tối đa cho mỗi sự kiện được chỉ định trong MAX_REMINDERS. Giá trị này do trình chuyển đổi đồng bộ hoá sở hữu lịch nhất định đặt. Lời nhắc được chỉ định vài phút trước khi sự kiện diễn ra và có một phương thức xác định cách thông báo cho người dùng.

Calendar Provider API được thiết kế để linh hoạt và mạnh mẽ. Tại đồng thời, điều quan trọng là phải cung cấp trải nghiệm tốt cho người dùng cuối và bảo vệ tính toàn vẹn của lịch và dữ liệu của lịch. Để đạt được mục tiêu này, một số điều cần lưu ý khi sử dụng API:

  • Chèn, cập nhật và xem sự kiện trên lịch. Để chèn, sửa đổi và đọc trực tiếp sự kiện từ Nhà cung cấp lịch, bạn cần có quyền thích hợp. Tuy nhiên, nếu bạn không xây dựng ứng dụng lịch hoàn chỉnh hoặc bộ điều hợp đồng bộ hoá thì không cần yêu cầu các quyền này. Thay vào đó, bạn có thể dùng các ý định được ứng dụng Lịch của Android hỗ trợ để chuyển giao các thao tác đọc và ghi cho ứng dụng đó. Khi bạn sử dụng các ý định đó, ứng dụng của bạn sẽ đưa người dùng đến ứng dụng Lịch để thực hiện thao tác mong muốn vào một biểu mẫu được điền trước. Sau khi hoàn tất, các giấy tờ này sẽ được trả về đơn đăng ký của bạn. Bằng cách thiết kế ứng dụng của mình để thực hiện các thao tác phổ biến thông qua Lịch, bạn cung cấp cho người dùng giao diện người dùng mạnh mẽ và nhất quán. Đây là phương pháp đề xuất. Để biết thêm thông tin, hãy xem phần Ý định trong Lịch.
  • Bộ điều hợp đồng bộ hoá. Bộ chuyển đổi đồng bộ hoá sẽ đồng bộ hoá dữ liệu lịch trên thiết bị của người dùng với một máy chủ hoặc nguồn dữ liệu khác. Trong bảng CalendarContract.CalendarsCalendarContract.Events, có các cột dành riêng cho bộ chuyển đổi đồng bộ hoá. Nhà cung cấp và ứng dụng không được sửa đổi các giá trị này. Trên thực tế, chúng không hiển thị trừ phi được truy cập dưới dạng bộ điều hợp đồng bộ hoá. Để biết thêm thông tin về bộ chuyển đổi đồng bộ hoá, hãy xem phần Bộ chuyển đổi đồng bộ hoá.

Quyền của người dùng

Để đọc dữ liệu lịch, ứng dụng phải đưa quyền READ_CALENDAR vào tệp kê khai. Tệp này phải bao gồm quyền WRITE_CALENDAR để xoá, chèn hoặc cập nhật dữ liệu lịch:

<?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>

Bảng Lịch

Bảng CalendarContract.Calendars chứa thông tin chi tiết về từng lịch. Nội dung sau đây Cả ứng dụng và bộ điều hợp đồng bộ hoá đều có thể ghi các cột Lịch. Để biết danh sách đầy đủ các trường được hỗ trợ, hãy xem Tham chiếu CalendarContract.Calendars.

Hằng số Mô tả
NAME Tên của lịch.
CALENDAR_DISPLAY_NAME Tên của lịch này được hiển thị với người dùng.
VISIBLE Giá trị boolean cho biết lịch có được chọn để hiển thị hay không. Giá trị 0 cho biết rằng các sự kiện liên kết với lịch này sẽ không được hiển thị. Giá trị 1 cho biết rằng các sự kiện được liên kết với lịch này phải hiển thị. Giá trị này ảnh hưởng đến việc tạo hàng trong bảng CalendarContract.Instances.
SYNC_EVENTS Giá trị boolean cho biết lịch có cần được đồng bộ hoá và có các sự kiện được lưu trữ trên thiết bị. Giá trị 0 có nghĩa là không đồng bộ hoá lịch này hoặc lưu trữ sự kiện của lịch trên thiết bị. Giá trị 1 cho biết sự kiện đồng bộ hoá của lịch này và lưu trữ các sự kiện của sự kiện đó trên thiết bị.

Bao gồm một loại tài khoản cho tất cả các hoạt động

Nếu truy vấn trên một Calendars.ACCOUNT_NAME, bạn cũng phải thêm Calendars.ACCOUNT_TYPE trong phần lựa chọn. Đó là vì một tài khoản cụ thể chỉ được coi là duy nhất vì cả ACCOUNT_NAMEACCOUNT_TYPE. ACCOUNT_TYPE là chuỗi tương ứng với trình xác thực tài khoản được sử dụng khi tài khoản được đăng ký bằng AccountManager. Ngoài ra, còn có một loại tài khoản đã gọi ACCOUNT_TYPE_LOCAL cho lịch không được liên kết với tài khoản thiết bị. ACCOUNT_TYPE_LOCAL tài khoản không nhận được đã đồng bộ hoá.

Truy vấn lịch

Sau đây là ví dụ minh hoạ cách lấy lịch do một người dùng cụ thể sở hữu. Để cho đơn giản, trong ví dụ này, hoạt động truy vấn được hiển thị trong luồng giao diện người dùng ("luồng chính"). Trong thực tế, việc này nên được thực hiện trong quá trình thay vì trên luồng chính. Để thảo luận thêm, hãy xem phần Trình tải. Nếu bạn không chỉ đọc dữ liệu nhưng sửa đổi dữ liệu đó, hãy xem 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;

Trong phần tiếp theo của ví dụ, bạn tạo truy vấn của mình. Lựa chọn này chỉ định tiêu chí cho truy vấn. Trong ví dụ này, truy vấn đang tìm kiếm các lịch có ACCOUNT_NAME "hera@example.com", ACCOUNT_TYPE "com.example" và OWNER_ACCOUNT "hera@example.com". Nếu bạn muốn xem tất cả lịch mà người dùng đã xem, chứ không chỉ những lịch mà người dùng sở hữu, hãy bỏ qua OWNER_ACCOUNT. Truy vấn này trả về một đối tượng Cursor mà bạn có thể sử dụng để duyệt qua tập hợp kết quả do truy vấn cơ sở dữ liệu trả về. Để thảo luận thêm về việc sử dụng truy vấn trong trình cung cấp nội dung, xem Nhà cung cấp nội dung.

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);

Phần tiếp theo này sử dụng con trỏ để duyệt qua tập hợp kết quả. Hàm này sử dụng các hằng số được thiết lập ở đầu ví dụ để trả về giá trị cho từng trường.

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...

   ...
}

Sửa đổi lịch

Để cập nhật lịch, bạn có thể cung cấp _ID của lịch dưới dạng mã nhận dạng được thêm vào Uri (withAppendedId()) hoặc dưới dạng mục lựa chọn đầu tiên. Lựa chọn phải bắt đầu bằng "_id=?" và mã đầu tiên selectionArg phải là _ID của lịch. Bạn cũng có thể cập nhật bằng cách mã hoá mã nhận dạng trong URI. Ví dụ này thay đổi tên hiển thị của một lịch bằng cách sử dụng phương pháp (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);

Chèn lịch

Lịch được thiết kế để chủ yếu được quản lý bằng bộ chuyển đổi đồng bộ hoá, vì vậy, bạn chỉ nên chèn lịch mới dưới dạng bộ chuyển đổi đồng bộ hoá. Trong hầu hết trường hợp, các ứng dụng chỉ có thể thực hiện những thay đổi bề ngoài đối với lịch, chẳng hạn như thay đổi tên hiển thị. Nếu cần tạo lịch cục bộ, ứng dụng có thể thực hiện việc này bằng cách chèn lịch dưới dạng bộ điều hợp đồng bộ hoá, sử dụng ACCOUNT_TYPE của ACCOUNT_TYPE_LOCAL. ACCOUNT_TYPE_LOCAL là loại tài khoản đặc biệt dành cho những lịch không được liên kết với tài khoản thiết bị. Loại lịch này không được đồng bộ hoá với máy chủ. Đối với thảo luận về bộ điều hợp đồng bộ hoá, xem Bộ điều hợp đồng bộ hoá.

Bảng sự kiện

Bảng CalendarContract.Events chứa thông tin chi tiết cho các sự kiện riêng lẻ. Để thêm, cập nhật hoặc xoá sự kiện, ứng dụng phải bao gồm quyền WRITE_CALENDAR trong tệp kê khai.

Các cột Sự kiện sau đây có thể ghi bởi cả ứng dụng và quá trình đồng bộ hoá bộ chuyển đổi. Để biết danh sách đầy đủ các trường được hỗ trợ, hãy xem tài liệu tham khảo CalendarContract.Events.

Hằng số Mô tả
CALENDAR_ID _ID của lịch mà sự kiện thuộc về.
ORGANIZER Email của người tổ chức (chủ sở hữu) sự kiện.
TITLE Tiêu đề của sự kiện.
EVENT_LOCATION Địa điểm diễn ra sự kiện.
DESCRIPTION Nội dung mô tả về sự kiện.
DTSTART Thời gian sự kiện bắt đầu tính bằng mili giây UTC kể từ thời gian bắt đầu của hệ thống.
DTEND Thời gian kết thúc sự kiện tính bằng mili giây theo giờ UTC kể từ thời gian bắt đầu của hệ thống.
EVENT_TIMEZONE Múi giờ của sự kiện.
EVENT_END_TIMEZONE Múi giờ của thời gian kết thúc sự kiện.
DURATION Thời lượng của sự kiện ở định dạng RFC5545. Ví dụ: giá trị của "PT1H" cho biết rằng sự kiện sẽ kéo dài một giờ và giá trị "P2W" cho biết kéo dài 2 tuần.
ALL_DAY Giá trị 1 cho biết sự kiện này diễn ra trong cả ngày, theo múi giờ địa phương. Giá trị 0 cho biết đó là một sự kiện thông thường có thể bắt đầu và kết thúc vào bất kỳ thời điểm nào trong ngày.
RRULE Quy tắc định kỳ cho định dạng sự kiện. Để ví dụ: "FREQ=WEEKLY;COUNT=10;WKST=SU". Bạn có thể tìm thêm ví dụ tại đây.
RDATE Ngày lặp lại của sự kiện. Bạn thường dùng RDATE cùng với RRULE để xác định một tập hợp tổng hợp lặp lại. Để thảo luận thêm, hãy xem quy cách RFC5545.
AVAILABILITY Nếu sự kiện này được tính là thời gian bận hoặc là thời gian rảnh, thì đã được lên lịch.
GUESTS_CAN_MODIFY Khách có thể sửa đổi sự kiện hay không.
GUESTS_CAN_INVITE_OTHERS Liệu khách có thể mời khách khác hay không.
GUESTS_CAN_SEE_GUESTS Liệu khách có thể xem danh sách người tham dự hay không.

Thêm sự kiện

Khi ứng dụng của bạn chèn một sự kiện mới, bạn nên sử dụng Ý định INSERT, như mô tả trong phần Sử dụng ý định để chèn một sự kiện. Tuy nhiên, nếu cần, bạn có thể chèn sự kiện trực tiếp. Phần này mô tả cách thực hiện này.

Sau đây là các quy tắc chèn sự kiện mới:

  • Bạn phải bao gồm CALENDAR_IDDTSTART.
  • Bạn phải thêm EVENT_TIMEZONE. Để nhận danh sách mã múi giờ đã cài đặt của hệ thống, hãy sử dụng getAvailableIDs(). Xin lưu ý rằng quy tắc này không áp dụng nếu bạn đang chèn một sự kiện thông qua Ý định INSERT, được mô tả trong phần Sử dụng ý định để chèn sự kiện – trong trường hợp đó, hệ thống sẽ cung cấp múi giờ mặc định.
  • Đối với các sự kiện không định kỳ, bạn phải thêm DTEND.
  • Đối với các sự kiện định kỳ, bạn phải thêm DURATION ngoài RRULE hoặc RDATE. Xin lưu ý rằng quy tắc này không áp dụng nếu bạn đang chèn một sự kiện thông qua Ý định INSERT, được mô tả trong phần Sử dụng ý định để chèn một sự kiện. Trong trường hợp đó, bạn có thể sử dụng RRULE kết hợp với DTSTARTDTEND, và ứng dụng Lịch sẽ tự động chuyển đổi thành thời lượng.

Dưới đây là ví dụ về cách chèn sự kiện. Thao tác này đang được thực hiện trong giao diện người dùng để đơn giản hoá. Trong thực tế, bạn nên chèn và cập nhật trong một luồng không đồng bộ để di chuyển thao tác vào luồng ở chế độ nền. Để biết thêm thông tin, hãy xem 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
//
//

Lưu ý: Hãy xem ví dụ này ghi lại mã sự kiện sau khi sự kiện được tạo. Đây là cách dễ nhất để lấy mã sự kiện. Bạn thường xuyên cần mã sự kiện để thực hiện các thao tác khác trên lịch (ví dụ: để thêm người tham dự hoặc lời nhắc tham gia một sự kiện.

Sự kiện cập nhật

Khi ứng dụng của bạn muốn cho phép người dùng chỉnh sửa một sự kiện, bạn nên sử dụng Ý định EDIT, như mô tả trong phần Sử dụng ý định để chỉnh sửa sự kiện. Tuy nhiên, nếu cần, bạn có thể trực tiếp chỉnh sửa sự kiện. Để cập nhật một Sự kiện, bạn có thể cung cấp _ID của sự kiện dưới dạng mã nhận dạng được thêm vào Uri (withAppendedId()) hoặc dưới dạng mục lựa chọn đầu tiên. Lựa chọn phải bắt đầu bằng "_id=?"selectionArg đầu tiên phải là _ID của sự kiện. Bạn có thể đồng thời cập nhật bằng cách sử dụng lựa chọn không có ID. Sau đây là ví dụ về cách cập nhật một sự kiện. Thao tác này thay đổi tiêu đề của sự kiện bằng cách sử dụng withAppendedId() phương pháp tiếp cận:

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);

Xóa sự kiện

Bạn có thể xoá một sự kiện bằng cách _ID của sự kiện đó dưới dạng một mã nhận dạng được nối thêm trên URI, hoặc bằng cách sử dụng lựa chọn chuẩn. Nếu sử dụng mã nhận dạng được thêm vào, bạn cũng không thể chọn. Có hai phiên bản xoá: dưới dạng ứng dụng và dưới dạng trình chuyển đổi đồng bộ hoá. Thao tác xoá ứng dụng sẽ đặt cột đã xoá thành 1. Cờ này cho biết bộ điều hợp đồng bộ hoá mà hàng đã bị xoá và thao tác xoá này sẽ được truyền đến máy chủ. Thao tác xoá trình chuyển đổi đồng bộ hoá sẽ xoá sự kiện khỏi cơ sở dữ liệu cùng với tất cả dữ liệu liên quan. Sau đây là một ví dụ về cách áp dụng xoá một sự kiện thông qua _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);

Bảng người tham dự

Mỗi hàng của bảng CalendarContract.Attendees đại diện cho một khách mời hoặc người tham dự sự kiện. Việc gọi query() sẽ trả về danh sách người tham dự cho sự kiện có EVENT_ID đã cho. EVENT_ID này phải khớp với _ID của một sự kiện cụ thể.

Bảng sau đây liệt kê các trường có thể ghi. Khi chèn một người tham dự mới, bạn phải thêm tất cả người tham dự ngoại trừ ATTENDEE_NAME.

Hằng số Mô tả
EVENT_ID Mã của sự kiện.
ATTENDEE_NAME Tên của người tham dự.
ATTENDEE_EMAIL Địa chỉ email của người tham dự.
ATTENDEE_RELATIONSHIP

Mối quan hệ của người tham dự với sự kiện. Một trong những trường hợp sau:

ATTENDEE_TYPE

Loại người tham dự. Một trong các lựa chọn sau:

ATTENDEE_STATUS

Trạng thái tham dự của người tham dự. Một trong các lựa chọn sau:

Thêm người tham dự

Dưới đây là ví dụ về cách thêm một người tham dự vào một sự kiện. Lưu ý rằng EVENT_ID là bắt buộc:

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);

Bảng lời nhắc

Mỗi hàng của bảng CalendarContract.Reminders đại diện cho một lời nhắc cho một sự kiện. Việc gọi query() sẽ trả về danh sách lời nhắc cho sự kiện có EVENT_ID đã cho.

Bảng sau đây liệt kê các trường có thể ghi cho lời nhắc. Bạn phải đưa tất cả các thông tin này vào khi chèn lời nhắc mới. Lưu ý rằng bộ điều hợp đồng bộ hoá chỉ định các loại lời nhắc mà chúng hỗ trợ trong bảng CalendarContract.Calendars. Hãy xem ALLOWED_REMINDERS để biết thông tin chi tiết.

Hằng số Mô tả
EVENT_ID Mã của sự kiện.
MINUTES Số phút trước sự kiện mà lời nhắc sẽ kích hoạt.
METHOD

Phương thức báo thức, như đã đặt trên máy chủ. Một trong các lựa chọn sau:

Thêm lời nhắc

Ví dụ này thêm lời nhắc vào sự kiện. Lời nhắc kích hoạt 15 phút trước sự kiện.

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);

Bảng đối tượng

Bảng CalendarContract.Instances chứa thời gian bắt đầu và kết thúc của các lần xuất hiện sự kiện. Mỗi hàng trong bảng này biểu thị một lần xuất hiện sự kiện. Bạn không thể ghi vào bảng thực thể và bảng này chỉ cung cấp cách truy vấn các lần xuất hiện sự kiện.

Bảng sau đây liệt kê một số trường mà bạn có thể truy vấn cho một thực thể. Lưu ý rằng múi giờ được xác định bằng KEY_TIMEZONE_TYPEKEY_TIMEZONE_INSTANCES.

Hằng số Mô tả
BEGIN Thời gian bắt đầu của thực thể, tính bằng mili giây theo giờ UTC.
END Thời gian kết thúc của thực thể, tính bằng mili giây theo giờ UTC.
END_DAY Ngày kết thúc theo lịch Julian của thực thể, tương ứng với múi giờ của Lịch.
END_MINUTE Phút kết thúc của thực thể được tính từ nửa đêm theo múi giờ của Lịch.
EVENT_ID _ID của sự kiện cho phiên bản này.
START_DAY Ngày bắt đầu của phiên bản Julian, tương ứng với múi giờ của Lịch.
START_MINUTE Số phút bắt đầu của thực thể được tính từ nửa đêm, tương ứng với múi giờ của Lịch.

Truy vấn bảng thực thể

Để truy vấn bảng Instances (Thực thể), bạn cần chỉ định một khoảng thời gian cho truy vấn trong URI. Trong ví dụ này, CalendarContract.Instances có quyền truy cập vào trường TITLE thông qua việc triển khai giao diện CalendarContract.EventsColumns. Nói cách khác, TITLE được trả về thông qua chế độ xem cơ sở dữ liệu, chứ không phải thông qua truy vấn bảng CalendarContract.Instances thô.

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()));
    }
 }

Ý định về lịch

Ứng dụng của bạn không cần quyền để đọc và ghi dữ liệu lịch. Thay vào đó, ứng dụng có thể sử dụng các ý định được ứng dụng Lịch của Android hỗ trợ để chuyển các thao tác đọc và ghi cho ứng dụng đó. Bảng sau đây liệt kê các ý định được Trình cung cấp lịch hỗ trợ:

Hành động URI Mô tả Thông tin bổ sung

VIEW

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

Bạn cũng có thể tham chiếu đến URI bằng CalendarContract.CONTENT_URI. Để biết ví dụ về cách sử dụng ý định này, hãy xem phần Sử dụng ý định để xem dữ liệu lịch.
Mở lịch theo thời gian do <ms_since_epoch> chỉ định. Không có.

VIEW

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

Bạn cũng có thể tham chiếu đến URI bằng Events.CONTENT_URI. Để biết ví dụ về cách sử dụng ý định này, hãy xem phần Sử dụng ý định để xem dữ liệu lịch.
Xem sự kiện do <event_id> chỉ định. CalendarContract.EXTRA_EVENT_BEGIN_TIME


CalendarContract.EXTRA_EVENT_END_TIME
EDIT

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

Bạn cũng có thể tham chiếu đến URI bằng Events.CONTENT_URI. Để biết ví dụ về cách sử dụng ý định này, hãy xem phần Sử dụng ý định để chỉnh sửa sự kiện.
Chỉnh sửa sự kiện do <event_id> chỉ định. CalendarContract.EXTRA_EVENT_BEGIN_TIME


CalendarContract.EXTRA_EVENT_END_TIME
EDIT

INSERT

content://com.android.calendar/events

Bạn cũng có thể tham chiếu đến URI bằng Events.CONTENT_URI. Để biết ví dụ về cách sử dụng ý định này, hãy xem phần Sử dụng ý định để chèn một sự kiện.
Tạo một sự kiện. Mọi tính năng bổ sung được liệt kê trong bảng dưới đây.

Bảng sau đây liệt kê các ý định bổ sung được Nhà cung cấp lịch hỗ trợ:

Ý định bổ sung Mô tả
Events.TITLE Tên sự kiện.
CalendarContract.EXTRA_EVENT_BEGIN_TIME Thời gian bắt đầu sự kiện tính bằng mili giây từ thời gian bắt đầu của hệ thống.
CalendarContract.EXTRA_EVENT_END_TIME Thời gian kết thúc sự kiện tính bằng mili giây từ thời gian bắt đầu của hệ thống.
CalendarContract.EXTRA_EVENT_ALL_DAY Giá trị boolean cho biết một sự kiện diễn ra cả ngày. Giá trị có thể là true hoặc false.
Events.EVENT_LOCATION Địa điểm diễn ra sự kiện.
Events.DESCRIPTION Nội dung mô tả sự kiện.
Intent.EXTRA_EMAIL Địa chỉ email của những người bạn muốn mời dưới dạng danh sách được phân tách bằng dấu phẩy.
Events.RRULE Quy tắc lặp lại cho sự kiện.
Events.ACCESS_LEVEL Sự kiện là riêng tư hay công khai.
Events.AVAILABILITY Nếu sự kiện này được tính là thời gian bận hoặc là thời gian rảnh có thể được lên lịch hơn.

Các phần sau đây mô tả cách sử dụng những ý định này.

Sử dụng một ý định để chèn sự kiện

Việc sử dụng Ý định INSERT cho phép ứng dụng của bạn chuyển nhiệm vụ chèn sự kiện sang chính Lịch. Với phương pháp này, ứng dụng của bạn thậm chí không cần có quyền WRITE_CALENDAR trong tệp kê khai.

Khi người dùng chạy một ứng dụng sử dụng phương pháp này, ứng dụng sẽ gửi họ vào Lịch để hoàn tất việc thêm sự kiện. Ý định INSERT sử dụng các trường bổ sung để điền sẵn thông tin chi tiết về sự kiện trong Lịch vào một biểu mẫu. Người dùng có thể sau đó huỷ sự kiện, chỉnh sửa biểu mẫu nếu cần hoặc lưu sự kiện vào lịch.

Dưới đây là một đoạn mã lên lịch một sự kiện vào ngày 19 tháng 1 năm 2012, chạy từ 7:30 đến 8:30. Hãy lưu ý những điều sau về đoạn mã này:

  • Phương thức này chỉ định Events.CONTENT_URI làm URI.
  • Phương thức này sử dụng các trường bổ sung CalendarContract.EXTRA_EVENT_BEGIN_TIMECalendarContract.EXTRA_EVENT_END_TIME để điền sẵn thời gian của sự kiện vào biểu mẫu. Các giá trị cho những thời điểm này phải tính bằng mili giây theo giờ UTC kể từ thời gian bắt đầu.
  • Phương thức này sử dụng trường bổ sung Intent.EXTRA_EMAIL để cung cấp danh sách khách mời được phân tách bằng dấu phẩy, được chỉ định theo địa chỉ 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);

Sử dụng một ý định để chỉnh sửa sự kiện

Bạn có thể cập nhật trực tiếp một sự kiện, như mô tả trong phần Cập nhật sự kiện. Tuy nhiên, việc sử dụng Ý định EDIT cho phép một ứng dụng không có quyền chuyển việc chỉnh sửa sự kiện sang ứng dụng Lịch. Khi người dùng chỉnh sửa xong sự kiện trong Lịch, họ sẽ được đưa trở lại ứng dụng ban đầu.

Dưới đây là ví dụ về một ý định đặt tiêu đề cho một sự kiện cụ thể và cho phép người dùng chỉnh sửa sự kiện đó trong Lịch.

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);

Sử dụng ý định để xem dữ liệu lịch

Nhà cung cấp lịch cung cấp hai cách để sử dụng Ý định VIEW:

  • Để mở Lịch theo một ngày cụ thể.
  • Để xem sự kiện.

Dưới đây là ví dụ cho thấy cách mở Lịch để xem một ngày cụ thể:

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);

Dưới đây là ví dụ minh hoạ cách mở một sự kiện để xem:

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);

Bộ điều hợp đồng bộ hoá

Chỉ có những khác biệt nhỏ về cách ứng dụng và bộ điều hợp đồng bộ hoá truy cập vào Nhà cung cấp lịch:

  • Bộ chuyển đổi đồng bộ hoá cần chỉ định rằng đó là bộ chuyển đổi đồng bộ hoá bằng cách đặt CALLER_IS_SYNCADAPTER thành true.
  • Bộ điều hợp đồng bộ hoá cần cung cấp ACCOUNT_NAMEACCOUNT_TYPE dưới dạng tham số truy vấn trong URI.
  • Bộ điều hợp đồng bộ hoá có quyền ghi nhiều cột hơn so với ứng dụng hoặc tiện ích. Ví dụ: một ứng dụng chỉ có thể sửa đổi một số đặc điểm của lịch, chẳng hạn như tên, tên hiển thị, chế độ hiển thị và liệu lịch có được đồng bộ hoá hay không. Để so sánh, bộ điều hợp đồng bộ hoá có thể truy cập không chỉ những cột đó mà còn truy cập vào nhiều cột khác, như màu lịch, múi giờ, cấp truy cập, vị trí, v.v. Tuy nhiên, bộ chuyển đổi đồng bộ hoá chỉ được giới hạn ở ACCOUNT_NAMEACCOUNT_TYPE mà bộ chuyển đổi đó chỉ định.

Dưới đây là phương thức trợ giúp bạn có thể sử dụng để trả về URI nhằm sử dụng với bộ điều hợp đồng bộ hoá:

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();
 }