page.title=Trình cung cấp Danh bạ @jd:body
Trình cung cấp Danh bạ là một thành phần Android mạnh mẽ và linh hoạt có chức năng quản lý kho dữ liệu trung tâm về con người của thiết bị. Trình cung cấp Danh bạ là nguồn của những dữ liệu mà bạn thấy trong ứng dụng danh bạ của thiết bị, và bạn cũng có thể truy cập dữ liệu của nó trong ứng dụng của chính mình và chuyển dữ liệu giữa thiết bị và các dịch vụ trực tuyến. Trình cung cấp chứa đủ loại nguồn dữ liệu và cố gắng quản lý nhiều dữ liệu nhất có thể cho mỗi người, kết quả là tổ chức của nó trở nên phức tạp. Vì điều này, API của trình cung cấp bao gồm một tập mở rộng gồm các lớp hợp đồng và giao diện tạo điều kiện cho việc truy xuất và sửa đổi dữ liệu.
Hướng dẫn này trình bày những nội dung sau:
Hướng dẫn này giả sử rằng bạn biết những nội dung cơ bản về trình cung cấp nội dung Android. Để tìm hiểu thêm về trình cung cấp nội dung Android, hãy đọc hướng dẫn Nội dung Cơ bản về Trình cung cấp Nội dung. Ứng dụng mẫu Trình điều hợp Đồng bộ Mẫu là một ví dụ về cách sử dụng một trình điều hợp đồng bộ để chuyển dữ liệu giữa Trình cung cấp Danh bạ và ứng dụng mẫu được lưu trữ bởi Dịch vụ Web Google.
Trình cung cấp Danh bạ là một thành phần của trình cung cấp nội dung Android. Nó chứa ba loại dữ liệu về một người, từng loại tương ứng với một bảng do trình cung cấp đưa ra, như được minh họa trong hình 1:
Hình 1. Cấu trúc bảng của Trình cung cấp Danh bạ.
Ba bảng này thường được đề cập theo tên các lớp hợp đồng của chúng. Các lớp này sẽ định nghĩa các hằng số cho URI nội dung, tên cột và giá trị cột được sử dụng bởi các bảng:
Các bảng khác được đại diện bởi các lớp hợp đồng trong {@link android.provider.ContactsContract} là bảng phụ mà Trình cung cấp Danh bạ sử dụng để quản lý thao tác của nó hoặc hỗ trợ các chức năng cụ thể trong ứng dụng danh bạ hoặc điện thoại của thiết bị.
Một liên lạc thô thể hiện dữ liệu của một người xuất phát từ một loại tài khoản và tên tài khoản riêng. Vì Trình cung cấp Danh bạ cho phép nhiều hơn một dịch vụ trực tuyến làm nguồn dữ liệu cho một người, Trình cung cấp Danh bạ cho phép nhiều liên lạc thô cho cùng một người. Nhiều liên lạc thô cũng cho phép người dùng kết hợp dữ liệu của một người từ nhiều hơn một tài khoản từ cùng loại tài khoản.
Hầu hết dữ liệu của một liên lạc thô không được lưu giữ trong bảng {@link android.provider.ContactsContract.RawContacts}. Thay vào đó, nó được lưu giữ trong một hoặc nhiều hàng trong bảng {@link android.provider.ContactsContract.Data}. Mỗi hàng dữ liệu có một cột {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID Data.RAW_CONTACT_ID} chứa giá trị {@code android.provider.BaseColumns#_ID RawContacts._ID} của hàng {@link android.provider.ContactsContract.RawContacts} mẹ của nó.
Các cột quan trọng trong bảng {@link android.provider.ContactsContract.RawContacts} được liệt kê trong bảng 1. Hãy đọc các lưu ý theo sau bảng dưới đây:
Bảng 1. Các cột liên lạc thô quan trọng.
Tên cột | Sử dụng | Lưu ý |
---|---|---|
{@link android.provider.ContactsContract.SyncColumns#ACCOUNT_NAME} | Tên tài khoản cho loại tài khoản là nguồn của liên lạc thô này. Ví dụ, tên tài khoản của một tài khoản Google là một trong các địa chỉ Gmail của chủ sở hữu thiết bị. Xem mục nhập tiếp theo cho {@link android.provider.ContactsContract.SyncColumns#ACCOUNT_TYPE} để biết thêm thông tin. | Định dạng của tên này áp dụng theo loại tài khoản của nó. Đó không nhất thiết là một địa chỉ e-mail. |
{@link android.provider.ContactsContract.SyncColumns#ACCOUNT_TYPE} |
Loại tài khoản là nguồn của liên lạc thô này. Ví dụ, loại tài khoản
của một tài khoản Google là com.google . Luôn xác định loại tài khoản của bạn
bằng một mã định danh miền cho một miền mà bạn sở hữu hoặc kiểm soát. Điều này đảm bảo rằng loại tài khoản
của bạn là duy nhất.
|
Một loại tài khoản cung cấp dữ liệu danh bạ thường có một trình điều hợp đồng bộ liên kết để đồng bộ hoá với Trình điều hợp Đồng bộ. |
{@link android.provider.ContactsContract.RawContactsColumns#DELETED} | Cờ "đã xóa" cho một liên lạc thô. | Cờ này cho phép Trình cung cấp Danh bạ duy trì hàng bên trong tới khi trình điều hợp đồng bộ có thể xóa hàng đó khỏi máy chủ của chúng rồi cuối cùng là xóa hàng khỏi kho lưu giữ. |
Sau đây là các ghi chú quan trọng về bảng {@link android.provider.ContactsContract.RawContacts}:
Ví dụ, nếu bạn muốn ứng dụng của mình duy trì dữ liệu danh bạ cho dịch vụ dựa trên nền web của mình với miền {@code com.example.dataservice}, và tài khoản của người dùng cho dịch vụ của bạn là {@code becky.sharp@dataservice.example.com}, trước tiên, người dùng phải thêm "loại" tài khoản ({@code com.example.dataservice}) và "tên" tài khoản ({@code becky.smart@dataservice.example.com}) trước khi ứng dụng của bạn có thể thêm hàng liên lạc thô. Bạn có thể giải thích yêu cầu này với người dùng bằng tài liệu, hoặc bạn có thể nhắc người dùng thêm loại và tên này, hoặc cả hai. Loại tài khoản và tên tài khoản được trình bày chi tiết hơn trong phần sau.
Để hiểu cách hoạt động của liên lạc thô, hãy xét người dùng "Emily Dickinson", cô ta có ba tài khoản người dùng sau được xác định trên thiết bị của mình:
emily.dickinson@gmail.com
emilyd@gmail.com
Người dùng này đã kích hoạt Đồng bộ Danh bạ cho cả ba tài khoản này trong cài đặt Tài khoản.
Giả sử Emily Dickinson mở một cửa sổ trình duyệt, đăng nhập vào Gmail bằng tài khoản
emily.dickinson@gmail.com
, mở
Danh bạ, và thêm "Thomas Higginson". Sau đó, cô đăng nhập vào Gmail bằng tài khoản
emilyd@gmail.com
và gửi một e-mail tới "Thomas Higginson", làm vậy sẽ tự động
thêm người này làm một liên lạc. Cô ấy cũng theo dõi "colonel_tom" (ID Twitter của Thomas Higginson) trên
Twitter.
Trình cung cấp Danh bạ sẽ tạo ba liên lạc thô do kết quả của việc làm này:
emily.dickinson@gmail.com
.
Loại tài khoản người dùng là Google.
emilyd@gmail.com
.
Loại tài khoản người dùng cũng là Google. Có một liên lạc thô thứ hai ngay cả khi
tên giống với một tên trước đó, vì người này đã được thêm cho một
tài khoản người dùng khác.
Như đề cập trước đó, dữ liệu của một liên lạc thô được lưu giữ trong một hàng
{@link android.provider.ContactsContract.Data} được liên kết với giá trị
_ID
của liên lạc thô. Điều này cho phép một liên lạc thô có nhiều thực thể cùng loại
dữ liệu chẳng hạn như địa chỉ e-mail hay số điện thoại. Ví dụ, nếu
"Thomas Higginson" của {@code emilyd@gmail.com} (hàng liên lạc thô cho Thomas Higginson
liên kết với tài khoản Google emilyd@gmail.com
) có một địa chỉ e-mail nhà là
thigg@gmail.com
và một địa chỉ e-mail cơ quan là
thomas.higginson@gmail.com
, Trình cung cấp Danh bạ sẽ lưu trữ hai hàng địa chỉ e-mail đó
và liên kết cả hai với liên lạc thô.
Để ý rằng các loại dữ liệu khác nhau được lưu giữ trong một bảng này. Các hàng tên hiển thị, số điện thoại, e-mail, địa chỉ gửi thư, ảnh và chi tiết trang web đều được tìm thấy trong bảng {@link android.provider.ContactsContract.Data}. Để giúp quản lý điều này, bảng {@link android.provider.ContactsContract.Data} có một số cột có tên mô tả, và các cột còn lại có tên chung. Các nội dung của cột tên mô tả có cùng ý nghĩa không phụ thuộc vào loại dữ liệu trong hàng, trong khi nội dung của cột tên chung có ý nghĩa khác nhau tùy vào loại dữ liệu.
Một số ví dụ về tên cột mô tả là:
_ID
của liên lạc thô đối với dữ liệu này.
Có 15 cột chung được đặt tên DATA1
thông qua
DATA15
thường có sẵn và thêm bốn cột
chung SYNC1
thông qua SYNC4
mà chỉ được sử dụng bởi trình điều hợp
đồng bộ. Các hằng số tên cột chung luôn có tác dụng, không phụ thuộc vào loại
dữ liệu mà hàng đó chứa.
Cột DATA1
được đánh chỉ mục. Trình cung cấp Danh bạ luôn sử dụng cột này cho
dữ liệu mà trình cung cấp kỳ vọng sẽ là đối tượng truy vấn thường xuyên nhất. Ví dụ,
trong một hàng e-mail, cột này chứa địa chỉ e-mail thực sự.
Theo quy ước, cột DATA15
được dành để lưu giữ dữ liệu Binary Large Object
(BLOB) chẳng hạn như hình thu nhỏ của ảnh.
Để tạo điều kiện làm việc với các cột đối với một kiểu hàng cụ thể, Trình cung cấp Danh bạ cũng cung cấp các hằng số tên cột theo kiểu, được định nghĩa trong các lớp con của {@link android.provider.ContactsContract.CommonDataKinds}. Các hằng số chỉ cấp một tên hằng số khác cho cùng tên cột, điều này giúp bạn truy cập dữ liệu trong một hàng thuộc một kiểu cụ thể.
Ví dụ, lớp {@link android.provider.ContactsContract.CommonDataKinds.Email} định nghĩa các hằng số tên cột theo kiểu cho một hàng {@link android.provider.ContactsContract.Data} mà có kiểu MIME {@link android.provider.ContactsContract.CommonDataKinds.Email#CONTENT_ITEM_TYPE Email.CONTENT_ITEM_TYPE}. Lớp chứa hằng số {@link android.provider.ContactsContract.CommonDataKinds.Email#ADDRESS} cho cột địa chỉ e-mail. Giá trị thực sự của {@link android.provider.ContactsContract.CommonDataKinds.Email#ADDRESS} là "data1", giá trị này giống hệt như tên chung của cột.
Chú ý: Không được thêm dữ liệu tùy chỉnh của chính bạn vào bảng
{@link android.provider.ContactsContract.Data} bằng cách sử dụng một hàng có một trong các kiểu MIME được xác định trước
của trình cung cấp. Nếu làm vậy, bạn có thể làm mất dữ liệu hoặc khiến trình cung cấp
gặp trục trặc. Ví dụ, bạn không nên thêm một hàng có kiểu MIME
{@link android.provider.ContactsContract.CommonDataKinds.Email#CONTENT_ITEM_TYPE
Email.CONTENT_ITEM_TYPE} mà chứa tên người dùng thay vì địa chỉ e-mail trong cột
DATA1
. Nếu sử dụng kiểu MIME tùy chỉnh của mình cho hàng, khi đó bạn được tự do
định nghĩa tên cột theo kiểu của chính mình và sử dụng các cột theo cách bạn muốn.
Hình 2 minh họa cách các cột mô tả và cột dữ liệu xuất hiện trong hàng {@link android.provider.ContactsContract.Data}, và cách mà tên cột theo kiểu "phủ lên" tên cột chung
Hình 2. Tên cột theo kiểu và tên cột chung.
Bảng 2 liệt kê các lớp tên cột theo kiểu thường được sử dụng nhất:
Bảng 2. Lớp tên cột theo kiểu
Lớp ánh xạ | Kiểu dữ liệu | Lưu ý |
---|---|---|
{@link android.provider.ContactsContract.CommonDataKinds.StructuredName} | Dữ liệu tên của liên lạc thô liên kết với hàng dữ liệu này. | Một liên lạc thô chỉ có một trong những hàng này. |
{@link android.provider.ContactsContract.CommonDataKinds.Photo} | Ảnh chính của liên lạc thô được liên kết với hàng dữ liệu này. | Một liên lạc thô chỉ có một trong những hàng này. |
{@link android.provider.ContactsContract.CommonDataKinds.Email} | Địa chỉ e-mail của liên lạc thô được liên kết với hàng dữ liệu này. | Một liên lạc thô có thể có nhiều địa chỉ e-mail. |
{@link android.provider.ContactsContract.CommonDataKinds.StructuredPostal} | Địa chỉ cổng của liên lạc thô được liên kết với hàng dữ liệu này. | Một liên lạc thô có thể có nhiều địa chỉ cổng. |
{@link android.provider.ContactsContract.CommonDataKinds.GroupMembership} | Mã định danh liên kết liên lạc thô với một trong các nhóm trong Trình cung cấp Danh bạ. | Nhóm là một tính năng tùy chọn của loại tài khoản và tên tài khoản. Chúng được mô tả chi tiết hơn trong phần Nhóm liên lạc. |
Trình cung cấp Danh bạ kết hợp các hàng liên lạc thô giữa tất cả các loại tài khoản và tên tài khoản để tạo thành một liên lạc. Điều này tạo điều kiện để hiển thị và sửa đổi tất cả dữ liệu mà một người dùng đã thu thập cho một người. Trình cung cấp Danh bạ quản lý việc tạo các hàng liên lạc mới và tổng hợp các liên lạc thô với hàng liên lạc hiện có. Ứng dụng lẫn trình điều hợp đồng bộ đều không được cho phép thêm liên lạc và một số cột trong một hàng liên lạc là cột chỉ đọc.
Lưu ý: Nếu bạn cố gắng thêm một liên lạc vào Trình cung cấp Danh bạ có một {@link android.content.ContentResolver#insert(Uri,ContentValues) insert()}, bạn sẽ gặp lỗi ngoại lệ {@link java.lang.UnsupportedOperationException}. Nếu bạn cố gắng cập nhật một cột mà được liệt kê là "chỉ đọc," cập nhật sẽ bị bỏ qua.
Trình cung cấp Danh bạ tạo một liên lạc mới để hồi đáp lại việc thêm một liên lạc thô mới không khớp với bất kỳ liên lạc nào hiện có. Trình cung cấp cũng làm vậy nếu dữ liệu của một liên lạc thô hiện có thay đổi sao cho nó không còn khớp với liên lạc mà trước đó nó được gắn với. Nếu một ứng dụng hoặc trình điều hợp đồng bộ tạo một liên lạc thô mới mà khớp với một liên lạc hiện tại, liên lạc thô mới sẽ được tổng hợp vào liên lạc hiện có.
Trình cung cấp Danh bạ sẽ liên kết một hàng liên lạc với các hàng liên lạc thô của nó bằng cột
_ID
của hàng liên lạc đó trong bảng {@link android.provider.ContactsContract.Contacts Contacts}
. Cột CONTACT_ID
của bảng liên lạc thô
{@link android.provider.ContactsContract.RawContacts} chứa các giá trị _ID
cho
các hàng liên lạc liên kết với từng hàng liên lạc thô.
Bảng {@link android.provider.ContactsContract.Contacts} cũng có cột {@code android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY} mà là một liên kết "cố định" với hàng liên lạc đó. Vì Trình cung cấp Danh bạ tự động duy trì các liên lạc, nó có thể thay đổi giá trị {@code android.provider.BaseColumns#_ID} của một hàng liên lạc hồi đáp lại một sự tổng hợp hoặc đồng bộ. Ngay cả khi điều này xảy ra, URI nội dung {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI} kết hợp với {@code android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY} của liên lạc sẽ vẫn chỉ về hàng liên lạc đó, vì thế bạn có thể sử dụng {@code android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY} để duy trì các liên kết đến liên lạc "yêu thích", v.v. Cột này có định dạng riêng không liên quan tới định dạng của cột {@code android.provider.BaseColumns#_ID}.
Hình 3 minh họa mối liên quan giữa ba bảng chính này với nhau.
Hình 3. Mối quan hệ giữa các bảng Danh bạ, Liên lạc Thô, và Chi tiết.
Người dùng nhập dữ liệu danh bạ trực tiếp vào thiết bị, nhưng dữ liệu cũng đi đến Trình cung cấp Danh bạ từ các dịch vụ web thông qua trình điều hợp đồng bộ, giúp tự động chuyển dữ liệu giữa thiết bị và các dịch vụ. Trình điều hợp đồng bộ chạy ngầm dưới sự kiểm soát của hệ thống, và chúng gọi các phương pháp {@link android.content.ContentResolver} để quản lý dữ liệu.
Trong Android, dịch vụ web mà một trình điều hợp đồng bộ làm việc cùng sẽ được xác định bằng một loại tài khoản. Mỗi trình điều hợp đồng bộ làm việc với một loại tài khoản, nhưng nó có thể hỗ trợ nhiều tên tài khoản cho loại đó. Các loại tài khoản và tên tài khoản được mô tả sơ qua trong phần Các nguồn dữ liệu liên lạc thô. Các định nghĩa sau trình bày chi tiết hơn và mô tả mối liên quan giữa loại và tên tài khoản với các trình điều hợp đồng bộ và dịch vụ.
google.com
. Giá trị này tương ứng với loại tài khoản được sử dụng bởi
{@link android.accounts.AccountManager}.
Loại tài khoản không nhất thiết phải duy nhất. Một người dùng có thể cấu hình nhiều tài khoản Google Contacts và tải xuống dữ liệu của chúng vào Trình cung cấp Danh bạ; điều này có thể xảy ra nếu người dùng có một tập hợp các liên lạc cá nhân cho một tên tài khoản cá nhân, và một tập hợp khác cho cơ quan. Tên tài khoản thường là duy nhất. Cùng nhau, chúng xác định một dòng dữ liệu cụ thể giữa Trình cung cấp Danh bạ và một dịch vụ bên ngoài.
Nếu muốn chuyển dữ liệu từ dịch vụ của bạn sang Trình cung cấp Danh bạ, bạn cần ghi vào trình điều hợp đồng bộ của chính mình. Điều này được mô tả chi tiết hơn trong phần Trình điều hợp Đồng bộ Trình cung cấp Danh bạ.
Hình 4 minh họa cách mà Trình cung cấp Danh bạ phù hợp với dòng dữ liệu về con người. Trong hộp được đánh dấu "trình điều hợp đồng bộ," mỗi trình điều hợp được ghi nhãn theo loại tài khoản của nó.
Hình 4. Luồng dữ liệu của Trình cung cấp Danh bạ.
Những ứng dụng muốn truy cập Trình cung cấp Danh bạ phải yêu cầu các quyền sau:
AndroidManifest.xml
với phần tử
<uses-permission>
là
<uses-permission android:name="android.permission.READ_CONTACTS">
.
AndroidManifest.xml
với phần tử
<uses-permission>
là
<uses-permission android:name="android.permission.WRITE_CONTACTS">
.
Những quyền này không mở rộng sang dữ liệu hồ sơ người dùng. Hồ sơ người dùng và các quyền được yêu cầu được đề cập trong phần sau, Hồ sơ Người dùng.
Nhớ rằng dữ liệu danh bạ của người dùng là dữ liệu cá nhân và nhạy cảm. Người dùng quan tâm về quyền riêng tư của họ, vì thế họ không muốn các ứng dụng thu thập dữ liệu về mình hoặc danh bạ của mình. Nếu không rõ ràng về lý do bạn cần quyền truy cập dữ liệu danh bạ của họ, họ có thể cho ứng dụng của bạn đánh giá thấp hoặc từ chối cài đặt ứng dụng.
Bảng {@link android.provider.ContactsContract.Contacts} có một hàng đơn chứa
dữ liệu hồ sơ cho người dùng của thiết bị. Dữ liệu này mô tả user
của thiết bị chứ không phải
của một trong các liên lạc của người dùng. Hàng liên lạc hồ sơ được liên kết với hàng
liên lạc thô đối với từng hệ thống sử dụng hồ sơ.
Mỗi hàng liên lạc thô của hồ sơ có thể có nhiều hàng dữ liệu. Các hằng số để truy cập hồ sơ
người dùng có sẵn trong lớp {@link android.provider.ContactsContract.Profile}.
Truy cập hồ sơ người dùng đòi hỏi phải có các quyền đặc biệt. Ngoài các quyền {@link android.Manifest.permission#READ_CONTACTS} và {@link android.Manifest.permission#WRITE_CONTACTS} cần để đọc và ghi, truy cập hồ sơ người dùng còn yêu cầu quyền {@code android.Manifest.permission#READ_PROFILE} và {@code android.Manifest.permission#WRITE_PROFILE} tương ứng cho quyền truy cập đọc và ghi.
Nhớ rằng bạn nên coi hồ sơ của một người dùng là nội dung nhạy cảm. Quyền {@code android.Manifest.permission#READ_PROFILE} cho phép bạn truy cập dữ liệu xác định cá nhân của người dùng thiết bị. Chắc chắn phải nói cho người dùng biết lý do tại sao bạn cần các quyền truy cập hồ sơ người dùng trong phần mô tả ứng dụng của mình.
Để truy xuất hàng liên lạc chứa hồ sơ của người dùng, hãy gọi {@link android.content.ContentResolver#query(Uri,String[], String, String[], String) ContentResolver.query()}. Đặt URI nội dung thành {@link android.provider.ContactsContract.Profile#CONTENT_URI} và không cung cấp bất kỳ tiêu chí lựa chọn nào. Bạn cũng có thể sử dụng URI nội dung này làm URI cơ sở để truy xuất các liên lạc thô hoặc dữ liệu cho hồ sơ. Ví dụ, đoạn mã HTML này truy xuất dữ liệu cho hồ sơ:
// Sets the columns to retrieve for the user profile mProjection = new String[] { Profile._ID, Profile.DISPLAY_NAME_PRIMARY, Profile.LOOKUP_KEY, Profile.PHOTO_THUMBNAIL_URI }; // Retrieves the profile from the Contacts Provider mProfileCursor = getContentResolver().query( Profile.CONTENT_URI, mProjection , null, null, null);
Lưu ý: Nếu bạn truy xuất nhiều hàng liên lạc và muốn xác định xem một trong số chúng có phải là hồ sơ người dùng không, hãy kiểm tra cột {@link android.provider.ContactsContract.ContactsColumns#IS_USER_PROFILE} của hàng. Cột này được đặt thành "1" nếu liên lạc là hồ sơ người dùng.
Trình cung cấp Danh bạ quản lý dữ liệu theo dõi trạng thái của dữ liệu danh bạ trong kho lưu giữ. Siêu dữ liệu về kho lưu giữ này được lưu giữ ở nhiều nơi khác nhau, bao gồm các hàng bảng Liên lạc Thô, Dữ liệu, và Danh bạ, bảng {@link android.provider.ContactsContract.Settings}, và bảng {@link android.provider.ContactsContract.SyncState}. Bảng sau đây cho biết ảnh hưởng của từng mục trong siêu dữ liệu này:
Bảng 3. Siêu dữ liệu trong Trình cung cấp Danh bạ
Bảng | Cột | Giá trị | Ý nghĩa |
---|---|---|---|
{@link android.provider.ContactsContract.RawContacts} | {@link android.provider.ContactsContract.SyncColumns#DIRTY} | "0" - không thay đổi kể từ lần đồng bộ cuối cùng. |
Đánh dấu các liên lạc thô đã được thay đổi trên thiết bị và phải được đồng bộ trở lại
máy chủ. Giá trị được đặt tự động bởi Trình cung cấp Danh bạ khi các ứng dụng
Android cập nhật một hàng.
Các trình điều hợp đồng bộ sửa đổi bảng liên lạc thô hoặc dữ liệu nên luôn nối xâu {@link android.provider.ContactsContract#CALLER_IS_SYNCADAPTER} với URI nội dung mà chúng sử dụng. Làm vậy sẽ ngăn không cho trình cung cấp đánh dấu hàng là không tốt. Nếu không, các sửa đổi trình điều hợp đồng bộ xem như sửa đổi cục bộ và được gửi tới máy chủ, ngay cả khi máy chủ là nguồn sửa đổi. |
"1" - đã thay đổi kể từ lần đồng bộ cuối cùng, cần được đồng bộ lại máy chủ. | |||
{@link android.provider.ContactsContract.RawContacts} | {@link android.provider.ContactsContract.SyncColumns#VERSION} | Số phiên bản của hàng này. | Trình cung cấp Danh bạ tự động tăng dần giá trị này bất cứ khi nào hàng hoặc dữ liệu có liên quan của hàng thay đổi. |
{@link android.provider.ContactsContract.Data} | {@link android.provider.ContactsContract.DataColumns#DATA_VERSION} | Số phiên bản của hàng này. | Trình cung cấp Danh bạ tự động tăng dần giá trị này bất cứ khi nào hàng dữ liệu bị thay đổi. |
{@link android.provider.ContactsContract.RawContacts} | {@link android.provider.ContactsContract.SyncColumns#SOURCE_ID} | Một xâu giá trị xác định duy nhất liên lạc thô này cho tài khoản mà nó được tạo trong đó. |
Khi một trình điều hợp đồng bộ tạo một liên lạc thô mới, cột này nên được đặt thành
ID duy nhất của máy chủ dành cho liên lạc thô đó. Khi một ứng dụng Android tạo một liên lạc thô
mới, ứng dụng đó sẽ để trống cột này. Điều này báo hiệu với trình điều hợp
đồng bộ rằng nó nên tạo một liên lạc thô mới trên máy chủ, và lấy một
giá trị cho {@link android.provider.ContactsContract.SyncColumns#SOURCE_ID}.
Cụ thể, id nguồn phải là duy nhất đối với từng loại tài khoản và nên ổn định giữa các lần đồng bộ:
|
{@link android.provider.ContactsContract.Groups} | {@link android.provider.ContactsContract.GroupsColumns#GROUP_VISIBLE} | "0" - Các liên lạc trong nhóm này không nên được hiển thị trong UI ứng dụng Android. | Cột này dành cho tính tương thích với các máy chủ mà cho phép người dùng ẩn các liên lạc trong một số nhóm. |
"1" - Các liên lạc trong nhóm này được cho phép hiển thị trong UI ứng dụng. | |||
{@link android.provider.ContactsContract.Settings} | {@link android.provider.ContactsContract.SettingsColumns#UNGROUPED_VISIBLE} | "0" - Đối với tài khoản và loại tài khoản này, những liên lạc không thuộc về nhóm được ẩn đối với UI ứng dụng Android. | Theo mặc định, các liên lạc được hiển thị nếu không có liên lạc thô nào của chúng thuộc về một nhóm (Tư cách thành viên nhóm đối với một liên lạc thô được thể hiện bằng một hoặc nhiều hàng {@link android.provider.ContactsContract.CommonDataKinds.GroupMembership} trong bảng {@link android.provider.ContactsContract.Data}). Bằng cách đặt cờ này trong hàng bảng {@link android.provider.ContactsContract.Settings} đối với một loại tài khoản và tài khoản, bạn có thể buộc những liên lạc không có nhóm phải hiển thị. Một công dụng của cờ này đó là để hiển thị liên lạc từ các máy chủ không sử dụng nhóm. |
"1" - Đối với tài khoản và loại tài khoản này, những liên lạc không thuộc về nhóm sẽ được hiển thị đối với UI ứng dụng. | |||
{@link android.provider.ContactsContract.SyncState} | (tất cả) | Sử dụng bảng này để lưu giữ siêu dữ liệu cho trình điều hợp đồng bộ của bạn. | Với bảng này, bạn có thể lưu giữ trạng thái đồng bộ và các dữ liệu khác liên quan tới đồng bộ một cách lâu dài trên thiết bị. |
Phần này mô tả các hướng dẫn về truy cập dữ liệu từ Trình cung cấp Danh bạ, tập trung vào những nội dung sau:
Thực hiện sửa đổi từ một trình điều hợp đồng bộ cũng được đề cập chi tiết hơn trong phần Trình điều hợp Đồng bộ Trình cung cấp Danh bạ.
Vì các bảng của Trình cung cấp Danh bạ được tổ chức theo một phân cấp, thường sẽ hữu ích nếu truy xuất một hàng và tất cả hàng "con" được liên kết với nó. Ví dụ, để hiển thị tất cả thông tin cho một người, bạn có thể muốn truy xuất tất cả hàng {@link android.provider.ContactsContract.RawContacts} đối với một hàng {@link android.provider.ContactsContract.Contacts} đơn, hoặc tất cả hàng {@link android.provider.ContactsContract.CommonDataKinds.Email} đối với một hàng {@link android.provider.ContactsContract.RawContacts} đơn. Để tạo điều kiện cho điều này, Trình cung cấp Danh bạ sẽ cung cấp các cấu trúc thực thể đóng vai trò như liên kết cơ sở dữ liệu giữa các bảng.
Thực thể giống như một bảng bao gồm các cột được chọn từ một bảng mẹ và bảng con của nó. Khi bạn truy vấn một thực thể, bạn cung cấp một dự thảo và các tiêu chí dựa trên các cột có sẵn từ thực thể. Kết quả là một {@link android.database.Cursor} trong đó chứa một hàng cho từng hàng bảng con được truy xuất. Ví dụ, nếu bạn truy vấn {@link android.provider.ContactsContract.Contacts.Entity} cho một tên liên lạc và tất cả hàng {@link android.provider.ContactsContract.CommonDataKinds.Email} đối với tất cả liên lạc thô cho tên đó, bạn sẽ nhận lại một {@link android.database.Cursor} chứa một hàng cho mỗi hàng {@link android.provider.ContactsContract.CommonDataKinds.Email}.
Các thực thể sẽ đơn giản hóa việc truy vấn. Bằng cách sử dụng một thực thể, bạn có thể truy xuất ngay lập tức tất cả dữ liệu danh bạ cho một liên lạc hoặc liên lạc thô, thay vì phải truy vấn bảng mẹ trước để nhận một ID, và rồi phải truy xuất bảng con bằng ID đó. Đồng thời, Trình cung cấp Danh bạ xử lý một truy vấn đối với một thực thể trong một giao tác đơn, điều này đảm bảo rằng dữ liệu được truy xuất sẽ được nhất quán trong nội bộ.
Lưu ý: Một thực thể thường không chứa tất cả cột của bảng mẹ và bảng con. Nếu bạn cố gắng làm việc với một tên cột không có trong danh sách các hằng số tên cột đối với thực thể đó, bạn sẽ nhận được một {@link java.lang.Exception}.
Đoạn mã HTML sau cho biết cách truy xuất tất cả hàng liên lạc thô cho một liên lạc. Đoạn mã HTML là bộ phận của một ứng dụng lớn hơn có hai hoạt động, "chính" và "chi tiết". Hoạt động chính hiển thị một danh sách các hàng liên lạc; khi người dùng chọn một hàng, hoạt động sẽ gửi ID của hàng tới hoạt động chi tiết. Hoạt động chi tiết sử dụng {@link android.provider.ContactsContract.Contacts.Entity} để hiển thị tất cả hàng dữ liệu từ tất cả liên lạc thô được liên kết với liên lạc đã chọn.
Đoạn mã HTML này được lấy từ hoạt động "chi tiết":
... /* * Appends the entity path to the URI. In the case of the Contacts Provider, the * expected URI is content://com.google.contacts/#/entity (# is the ID value). */ mContactUri = Uri.withAppendedPath( mContactUri, ContactsContract.Contacts.Entity.CONTENT_DIRECTORY); // Initializes the loader identified by LOADER_ID. getLoaderManager().initLoader( LOADER_ID, // The identifier of the loader to initialize null, // Arguments for the loader (in this case, none) this); // The context of the activity // Creates a new cursor adapter to attach to the list view mCursorAdapter = new SimpleCursorAdapter( this, // the context of the activity R.layout.detail_list_item, // the view item containing the detail widgets mCursor, // the backing cursor mFromColumns, // the columns in the cursor that provide the data mToViews, // the views in the view item that display the data 0); // flags // Sets the ListView's backing adapter. mRawContactList.setAdapter(mCursorAdapter); ... @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { /* * Sets the columns to retrieve. * RAW_CONTACT_ID is included to identify the raw contact associated with the data row. * DATA1 contains the first column in the data row (usually the most important one). * MIMETYPE indicates the type of data in the data row. */ String[] projection = { ContactsContract.Contacts.Entity.RAW_CONTACT_ID, ContactsContract.Contacts.Entity.DATA1, ContactsContract.Contacts.Entity.MIMETYPE }; /* * Sorts the retrieved cursor by raw contact id, to keep all data rows for a single raw * contact collated together. */ String sortOrder = ContactsContract.Contacts.Entity.RAW_CONTACT_ID + " ASC"; /* * Returns a new CursorLoader. The arguments are similar to * ContentResolver.query(), except for the Context argument, which supplies the location of * the ContentResolver to use. */ return new CursorLoader( getApplicationContext(), // The activity's context mContactUri, // The entity content URI for a single contact projection, // The columns to retrieve null, // Retrieve all the raw contacts and their data rows. null, // sortOrder); // Sort by the raw contact ID. }
Khi hoàn thành việc tải, {@link android.app.LoaderManager} gọi ra một lệnh gọi lại đến {@link android.app.LoaderManager.LoaderCallbacks#onLoadFinished(Loader, D) onLoadFinished()}. Một trong các tham đối đến với phương pháp này là một {@link android.database.Cursor} với các kết quả của truy vấn. Trong ứng dụng của chính mình, bạn có thể nhận dữ liệu từ {@link android.database.Cursor} này để hiển thị nó hoặc thao tác thêm với nó.
Bất cứ khi nào có thể, bạn nên chèn, cập nhật và xóa dữ liệu trong Trình cung cấp Danh bạ trong "chế độ hàng loạt", bằng cách tạo một {@link java.util.ArrayList} của các đối tượng {@link android.content.ContentProviderOperation} và gọi {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()}. Vì Trình cung cấp Danh bạ thực hiện tất cả thao tác trong một {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()} trong một giao tác đơn, các sửa đổi của bạn sẽ không bao giờ ra khỏi kho lưu giữ danh bạ một cách không nhất quán. Sửa đổi hàng loạt cũng tạo điều kiện cho việc chèn một liên lạc thô và dữ liệu chi tiết của liên lạc tại cùng thời điểm.
Lưu ý: Để sửa đổi một liên lạc thô đơn, hãy xét gửi một ý định tới ứng dụng danh bạ của thiết bị thay vì xử lý sửa đổi trong ứng dụng của bạn. Việc làm này được mô tả chi tiết hơn trong phần Truy xuất và sửa đổi bằng ý định.
Sửa đổi hàng loạt chứa nhiều thao tác có thể chặn các tiến trình khác,
dẫn đến trải nghiệm người dùng tổng thể không tốt. Để sắp xếp tổ chức tất cả sửa đổi mà bạn muốn
thực hiện trong ít danh sách riêng nhất có thể, và đồng thời ngăn chúng
chặn hệ thống, bạn nên đặt các điểm kết quả cho một hoặc nhiều thao tác.
Điểm kết quả là một đối tượng {@link android.content.ContentProviderOperation} có giá trị
{@link android.content.ContentProviderOperation#isYieldAllowed()} được đặt thành
true
. Khi các Trình cung cấp Danh bạ gặp phải một điểm kết quả, nó tạm dừng công việc để
cho phép các tiến trình khác chạy và đóng giao tác hiện tại. Khi trình cung cấp bắt đầu lại, nó
tiếp tục với thao tác tiếp theo trong {@link java.util.ArrayList} và bắt đầu một giao tác
mới.
Điểm kết quả dẫn đến có nhiều hơn một giao tác trên mỗi lệnh gọi tới {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()}. Vì điều này, bạn nên đặt một điểm kết quả cho thao tác cuối cùng đối với một tập hợp các hàng có liên quan. Ví dụ, bạn nên đặt một điểm kết quả cho thao tác cuối cùng trong một tập hợp mà thêm các hàng liên lạc thô và hàng dữ liệu liên kết của chúng, hoặc thao tác cuối cùng đối với một tập hợp các hàng liên quan tới một liên lạc riêng lẻ.
Điểm kết quả cũng là một đơn vị thao tác nguyên tử. Tất cả truy cập giữa hai điểm kết quả sẽ hoặc thành công hoặc thất bại như một đơn vị riêng lẻ. Nếu bạn không đặt bất kỳ điểm kết quả nào, thao tác nguyên tử nhỏ nhất chính là toàn bộ loạt thao tác. Nếu sử dụng điểm kết quả, bạn ngăn cản các thao tác làm giảm hiệu suất của hệ thống, đồng thời đảm bảo rằng một tập con của thao tác là tập nguyên tử.
Khi bạn đang chèn một hàng liên lạc thô mới và các hàng dữ liệu liên kết của nó như một tập hợp các đối tượng {@link android.content.ContentProviderOperation}, bạn phải liên kết các hàng dữ liệu với hàng liên lạc thô bằng cách chèn giá trị {@code android.provider.BaseColumns#_ID} của liên lạc thô làm giá trị {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID}. Tuy nhiên, giá trị này không có sẵn khi bạn đang tạo {@link android.content.ContentProviderOperation} cho hàng dữ liệu, vì bạn chưa áp dụng {@link android.content.ContentProviderOperation} cho hàng liên lạc thô. Để khắc phục điều này, lớp {@link android.content.ContentProviderOperation.Builder} có phương pháp {@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()}. Phương pháp này cho phép bạn chèn hoặc sửa đổi một cột bằng kết quả của một thao tác trước đó.
Phương pháp {@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()} có hai tham đối:
key
previousResult
previousResult
là chỉ mục
của một trong những kết quả này, nó được truy xuất và lưu giữ với giá trị key
. Điều này cho phép bạn chèn một bản ghi liên lạc thô mới và nhận lại giá trị
{@code android.provider.BaseColumns#_ID} của nó, rồi thực hiện một "tham chiếu ngược" về
giá trị đó khi bạn thêm một hàng {@link android.provider.ContactsContract.Data}.
Toàn bộ mảng kết quả được tạo khi bạn lần đầu gọi
{@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()},
với kích cỡ bằng với kích cỡ của {@link java.util.ArrayList} của các đối tượng
{@link android.content.ContentProviderOperation} mà bạn cung cấp. Tuy nhiên, tất cả
các phần tử trong mảng kết quả được đặt thành null
, và nếu bạn cố gắng
thực hiện tham chiếu ngược tới một kết quả cho một thao tác chưa được áp dụng,
{@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()}
sẽ đưa ra một lỗi {@link java.lang.Exception}.
Các đoạn mã HTML sau minh họa cách chèn một liên lạc thô mới và dữ liệu hàng loạt. Chúng
bao gồm mã thiết lập một điểm kết quả và sử dụng một tham chiếu lại. Đoạn mã HTML là một
phiên bản mở rộng của phương pháp createContacEntry()
, nó là một phần của lớp
ContactAdder
trong ứng dụng mẫu
Contact Manager
.
Đoạn mã HTML đầu tiên truy xuất dữ liệu liên lạc từ UI. Tại điểm này, người dùng đã chọn tài khoản mà liên lạc thô mới nên được thêm cho tài khoản đó.
// Creates a contact entry from the current UI values, using the currently-selected account. protected void createContactEntry() { /* * Gets values from the UI */ String name = mContactNameEditText.getText().toString(); String phone = mContactPhoneEditText.getText().toString(); String email = mContactEmailEditText.getText().toString(); int phoneType = mContactPhoneTypes.get( mContactPhoneTypeSpinner.getSelectedItemPosition()); int emailType = mContactEmailTypes.get( mContactEmailTypeSpinner.getSelectedItemPosition());
Đoạn mã HTML tiếp theo tạo một thao tác để chèn hàng liên lạc thô vào bảng {@link android.provider.ContactsContract.RawContacts}:
/* * Prepares the batch operation for inserting a new raw contact and its data. Even if * the Contacts Provider does not have any data for this person, you can't add a Contact, * only a raw contact. The Contacts Provider will then add a Contact automatically. */ // Creates a new array of ContentProviderOperation objects. ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); /* * Creates a new raw contact with its account type (server type) and account name * (user's account). Remember that the display name is not stored in this row, but in a * StructuredName data row. No other data is required. */ ContentProviderOperation.Builder op = ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI) .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, mSelectedAccount.getType()) .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, mSelectedAccount.getName()); // Builds the operation and adds it to the array of operations ops.add(op.build());
Tiếp theo, mã tạo các hàng dữ liệu cho hàng tên hiển thị, điện thoại và e-mail.
Từng đối tượng bộ dựng thao tác sẽ sử dụng {@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()} để nhận {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID}. Tham chiếu đó sẽ trỏ ngược về đối tượng {@link android.content.ContentProviderResult} từ thao tác đầu tiên, là thao tác thêm hàng liên lạc thô và trả về giá trị {@code android.provider.BaseColumns#_ID} mới của nó. Kết quả là, mỗi hàng dữ liệu được tự động liên kết bởi {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID} của nó với hàng {@link android.provider.ContactsContract.RawContacts} mới mà nó thuộc về.
Đối tượng {@link android.content.ContentProviderOperation.Builder} thêm hàng e-mail sẽ được gắn cờ bằng {@link android.content.ContentProviderOperation.Builder#withYieldAllowed(boolean) withYieldAllowed()}, mà điều này đặt một điểm kết quả:
// Creates the display name for the new raw contact, as a StructuredName data row. op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) /* * withValueBackReference sets the value of the first argument to the value of * the ContentProviderResult indexed by the second argument. In this particular * call, the raw contact ID column of the StructuredName data row is set to the * value of the result returned by the first operation, which is the one that * actually adds the raw contact row. */ .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) // Sets the data row's MIME type to StructuredName .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE) // Sets the data row's display name to the name in the UI. .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name); // Builds the operation and adds it to the array of operations ops.add(op.build()); // Inserts the specified phone number and type as a Phone data row op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) /* * Sets the value of the raw contact id column to the new raw contact ID returned * by the first operation in the batch. */ .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) // Sets the data row's MIME type to Phone .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE) // Sets the phone number and type .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phone) .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, phoneType); // Builds the operation and adds it to the array of operations ops.add(op.build()); // Inserts the specified email and type as a Phone data row op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) /* * Sets the value of the raw contact id column to the new raw contact ID returned * by the first operation in the batch. */ .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) // Sets the data row's MIME type to Email .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE) // Sets the email address and type .withValue(ContactsContract.CommonDataKinds.Email.ADDRESS, email) .withValue(ContactsContract.CommonDataKinds.Email.TYPE, emailType); /* * Demonstrates a yield point. At the end of this insert, the batch operation's thread * will yield priority to other threads. Use after every set of operations that affect a * single contact, to avoid degrading performance. */ op.withYieldAllowed(true); // Builds the operation and adds it to the array of operations ops.add(op.build());
Đoạn mã HTML cuối cùng hiển thị lệnh gọi tới {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()} mà chèn liên lạc thô mới và các hàng dữ liệu.
// Ask the Contacts Provider to create a new contact Log.d(TAG,"Selected account: " + mSelectedAccount.getName() + " (" + mSelectedAccount.getType() + ")"); Log.d(TAG,"Creating contact: " + name); /* * Applies the array of ContentProviderOperation objects in batch. The results are * discarded. */ try { getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops); } catch (Exception e) { // Display a warning Context ctx = getApplicationContext(); CharSequence txt = getString(R.string.contactCreationFailure); int duration = Toast.LENGTH_SHORT; Toast toast = Toast.makeText(ctx, txt, duration); toast.show(); // Log exception Log.e(TAG, "Exception encountered while inserting contact: " + e); } }
Thao tác hàng loạt cũng cho phép bạn triển khai kiểm soát đồng thời lạc quan, một phương pháp áp dụng các giao tác sửa đổi mà không phải khóa kho lưu giữ liên quan. Để sử dụng phương pháp này, bạn áp dụng giao tác đó rồi kiểm tra các sửa đổi khác mà có thể đã được thực hiện tại cùng thời điểm. Nếu bạn thấy đã diễn ra một sửa đổi không nhất quán, hãy quay lui giao tác của bạn và thử lại.
Kiểm soát đồng thời lạc quan rất hữu ích đối với thiết bị di động, khi đó mỗi lúc chỉ có một người dùng và việc truy cập đồng thời vào một kho lưu giữ dữ liệu hiếm khi xảy ra. Vì không sử dụng khóa nên không bị lãng phí thời gian cho việc thiết đặt khóa hay chờ các giao tác khác nhả khóa của mình.
Để sử dụng kiểm soát đồng thời lạc quan trong khi đang cập nhật một hàng {@link android.provider.ContactsContract.RawContacts} đơn, hãy làm theo các bước sau:
Nếu hàng liên lạc thô được cập nhật bởi một thao tác khác giữa thời điểm bạn đọc hàng và thời điểm bạn cố gắng sửa đổi nó, "xác nhận" {@link android.content.ContentProviderOperation} sẽ thất bại, và toàn bộ loạt thao tác sẽ được rút khỏi. Sau đó, bạn có thể chọn thử lại loạt hoặc thực hiện một hành động khác.
Đoạn mã HTML sau minh họa cách tạo một "xác nhận" {@link android.content.ContentProviderOperation} sau khi truy vấn một liên lạc thô đơn bằng cách sử dụng một {@link android.content.CursorLoader}:
/* * The application uses CursorLoader to query the raw contacts table. The system calls this method * when the load is finished. */ public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { // Gets the raw contact's _ID and VERSION values mRawContactID = cursor.getLong(cursor.getColumnIndex(BaseColumns._ID)); mVersion = cursor.getInt(cursor.getColumnIndex(SyncColumns.VERSION)); } ... // Sets up a Uri for the assert operation Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, mRawContactID); // Creates a builder for the assert operation ContentProviderOperation.Builder assertOp = ContentProviderOperation.netAssertQuery(rawContactUri); // Adds the assertions to the assert operation: checks the version and count of rows tested assertOp.withValue(SyncColumns.VERSION, mVersion); assertOp.withExpectedCount(1); // Creates an ArrayList to hold the ContentProviderOperation objects ArrayList ops = new ArrayList<ContentProviderOperationg>; ops.add(assertOp.build()); // You would add the rest of your batch operations to "ops" here ... // Applies the batch. If the assert fails, an Exception is thrown try { ContentProviderResult[] results = getContentResolver().applyBatch(AUTHORITY, ops); } catch (OperationApplicationException e) { // Actions you want to take if the assert operation fails go here }
Việc gửi một ý định tới ứng dụng danh bạ của thiết bị cho phép bạn truy cập Trình cung cấp Danh bạ một cách gián tiếp. Ý định sẽ khởi động UI ứng dụng danh bạ của thiết bị, trong đó người dùng có thể thực hiện công việc liên quan tới danh bạ. Với kiểu truy cập này, người dùng có thể:
Nếu người dùng đang chèn hoặc cập nhật dữ liệu, bạn có thể thu thập dữ liệu trước và gửi nó như một phần của ý định.
Khi bạn sử dụng ý định để truy cập Trình cung cấp Danh bạ thông qua ứng dụng danh bạ của thiết bị, bạn không phải ghi UI hay mã của chính mình để truy nhập trình cung cấp. Bạn cũng không phải yêu cầu quyền đọc hoặc ghi đến trình cung cấp. Ứng dụng danh bạ của thiết bị có thể cấp quyền đọc đối với một liên lạc cho bạn, và vì bạn đang thực hiện sửa đổi đối với trình cung cấp thông qua một ứng dụng khác, bạn không cần phải có quyền ghi.
Tiến trình chung để gửi một ý định nhằm truy cập một trình cung cấp được mô tả chi tiết trong hướng dẫn Nội dung Cơ bản về Trình cung cấp Nội dung trong phần "Truy cập dữ liệu thông qua ý định." Hành động, kiểu MIME, và các giá trị dữ liệu bạn sử dụng cho các tác vụ có sẵn được tóm tắt trong Bảng 4, trong khi các giá trị phụ thêm mà bạn có thể sử dụng với {@link android.content.Intent#putExtra(String, String) putExtra()} được liệt kê trong tài liệu tham khảo cho {@link android.provider.ContactsContract.Intents.Insert}:
Bảng 4. Ý định của Trình cung cấp Danh bạ.
Tác vụ | Hành động | Dữ liệu | Kiểu MIME | Lưu ý |
---|---|---|---|---|
Chọn một liên lạc từ danh sách | {@link android.content.Intent#ACTION_PICK} |
Một trong:
|
Không sử dụng |
Hiển thị một danh sách các liên lạc thô hoặc danh sách dữ liệu từ một liên lạc thô, tùy vào kiểu
URI nội dung mà bạn cung cấp.
Gọi
{@link android.app.Activity#startActivityForResult(Intent, int) startActivityForResult()},
nó trả về URI nội dung của hàng được chọn. Hình thức của URI là URI nội dung
của bảng với |
Chèn một liên lạc thô mới | {@link android.provider.ContactsContract.Intents.Insert#ACTION Insert.ACTION} | Không áp dụng | {@link android.provider.ContactsContract.RawContacts#CONTENT_TYPE RawContacts.CONTENT_TYPE}, kiểu MIME cho một tập hợp liên các lạc thô. | Hiển thị màn hình Thêm Liên lạc của ứng dụng danh bạ của thiết bị. Các giá trị phụ thêm mà bạn thêm vào ý định sẽ được hiển thị. Nếu được gửi bằng {@link android.app.Activity#startActivityForResult(Intent, int) startActivityForResult()}, URI nội dung của liên lạc thô mới thêm sẽ được chuyển lại cho phương pháp gọi lại {@link android.app.Activity#onActivityResult(int, int, Intent) onActivityResult()} của hoạt động của bạn trong tham đối {@link android.content.Intent}, trong trường "dữ liệu". Để nhận giá trị, hãy gọi {@link android.content.Intent#getData()}. |
Chỉnh sửa một liên lạc | {@link android.content.Intent#ACTION_EDIT} | {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI} đối với liên lạc. Hoạt động của trình chỉnh sửa sẽ cho phép người dùng chỉnh sửa bất kỳ dữ liệu nào được liên kết với liên lạc này. | {@link android.provider.ContactsContract.Contacts#CONTENT_ITEM_TYPE Contacts.CONTENT_ITEM_TYPE}, một liên lạc đơn. | Hiển thị màn hình Chỉnh sửa Liên lạc trong ứng dụng danh bạ. Các giá trị phụ thêm mà bạn thêm vào ý định sẽ được hiển thị. Khi người dùng nhấp vào Xong để lưu các chỉnh sửa, hoạt động của bạn quay lại tiền cảnh. |
Hiển thị một trình chọn mà cũng có thể thêm dữ liệu. | {@link android.content.Intent#ACTION_INSERT_OR_EDIT} | Không áp dụng | {@link android.provider.ContactsContract.Contacts#CONTENT_ITEM_TYPE} |
Ý định này luôn hiển thị màn hình bộ chọn của ứng dụng danh bạ. Người dùng có thể hoặc
chọn một liên lạc để chỉnh sửa, hoặc thêm một liên lạc mới. Hoặc màn hình chỉnh sửa hoặc màn hình thêm
sẽ xuất hiện, tùy vào lựa chọn của người dùng, và dữ liệu phụ thêm mà bạn chuyển trong ý định
sẽ được hiển thị. Nếu ứng dụng của bạn hiển thị dữ liệu chẳng hạn như e-mail hoặc số điện thoại, hãy sử dụng
ý định này để cho phép người dùng thêm dữ liệu vào một liên lạc hiện tại.
liên lạc,
Lưu ý: Không cần gửi một giá trị tên trong phần phụ thêm của ý định, vì người dùng luôn chọn một tên hiện có hoặc thêm một tên mới. Thêm nữa, nếu bạn gửi một tên, và người dùng chọn thực hiện chỉnh sửa, ứng dụng danh bạ sẽ hiển thị tên mà bạn gửi, ghi đè giá trị trước. Nếu người dùng không để ý thấy điều này và lưu chỉnh sửa, giá trị cũ sẽ bị mất. |
Ứng dụng danh bạ của thiết bị không cho phép bạn xóa một liên lạc thô hay bất kỳ dữ liệu nào bằng một ý định. Thay vào đó, để xóa một liên lạc thô, hãy sử dụng {@link android.content.ContentResolver#delete(Uri, String, String[]) ContentResolver.delete()} hoặc {@link android.content.ContentProviderOperation#newDelete(Uri) ContentProviderOperation.newDelete()}.
Đoạn mã HTML sau minh họa cách xây dựng và gửi một ý định để chèn một liên lạc thô mới và dữ liệu:
// Gets values from the UI String name = mContactNameEditText.getText().toString(); String phone = mContactPhoneEditText.getText().toString(); String email = mContactEmailEditText.getText().toString(); String company = mCompanyName.getText().toString(); String jobtitle = mJobTitle.getText().toString(); // Creates a new intent for sending to the device's contacts application Intent insertIntent = new Intent(ContactsContract.Intents.Insert.ACTION); // Sets the MIME type to the one expected by the insertion activity insertIntent.setType(ContactsContract.RawContacts.CONTENT_TYPE); // Sets the new contact name insertIntent.putExtra(ContactsContract.Intents.Insert.NAME, name); // Sets the new company and job title insertIntent.putExtra(ContactsContract.Intents.Insert.COMPANY, company); insertIntent.putExtra(ContactsContract.Intents.Insert.JOB_TITLE, jobtitle); /* * Demonstrates adding data rows as an array list associated with the DATA key */ // Defines an array list to contain the ContentValues objects for each row ArrayList<ContentValues> contactData = new ArrayList<ContentValues>(); /* * Defines the raw contact row */ // Sets up the row as a ContentValues object ContentValues rawContactRow = new ContentValues(); // Adds the account type and name to the row rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_TYPE, mSelectedAccount.getType()); rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_NAME, mSelectedAccount.getName()); // Adds the row to the array contactData.add(rawContactRow); /* * Sets up the phone number data row */ // Sets up the row as a ContentValues object ContentValues phoneRow = new ContentValues(); // Specifies the MIME type for this data row (all data rows must be marked by their type) phoneRow.put( ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE ); // Adds the phone number and its type to the row phoneRow.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone); // Adds the row to the array contactData.add(phoneRow); /* * Sets up the email data row */ // Sets up the row as a ContentValues object ContentValues emailRow = new ContentValues(); // Specifies the MIME type for this data row (all data rows must be marked by their type) emailRow.put( ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE ); // Adds the email address and its type to the row emailRow.put(ContactsContract.CommonDataKinds.Email.ADDRESS, email); // Adds the row to the array contactData.add(emailRow); /* * Adds the array to the intent's extras. It must be a parcelable object in order to * travel between processes. The device's contacts app expects its key to be * Intents.Insert.DATA */ insertIntent.putParcelableArrayListExtra(ContactsContract.Intents.Insert.DATA, contactData); // Send out the intent to start the device's contacts app in its add contact activity. startActivity(insertIntent);
Vì kho lưu giữ danh bạ chứa dữ liệu quan trọng và nhạy cảm mà người dùng cho là đúng và cập nhật, Trình cung cấp Danh bạ có các quy tắc về toàn vẹn dữ liệu được định nghĩa rõ ràng. Bạn có trách nhiệm tuân theo những quy tắc này khi sửa đổi dữ liệu danh bạ. Các quy tắc quan trọng được liệt kê ở đây:
Bằng cách tạo và sử dụng các kiểu MIME tùy chỉnh của chính mình, bạn có thể chèn, chỉnh sửa, xóa và truy xuất các hàng dữ liệu của chính mình trong bảng {@link android.provider.ContactsContract.Data}. Các hàng của bạn bị giới hạn bằng cách sử dụng cột được định nghĩa trong {@link android.provider.ContactsContract.DataColumns}, mặc dù bạn có thể ánh xạ tên cột theo kiểu của chính mình với tên cột mặc định. Trong ứng dụng danh bạ của thiết bị, dữ liệu cho các hàng của bạn được hiển thị nhưng không thể chỉnh sửa hay xóa được, và người dùng không thể thêm dữ liệu bổ sung. Để cho phép người dùng sửa đổi các hàng dữ liệu tùy chỉnh của mình, bạn phải cung cấp một hoạt động trình chỉnh sửa trong ứng dụng của chính mình.
Để hiển thị dữ liệu tùy chỉnh của mình, hãy cung cấp một tệp contacts.xml
chứa một phần tử
<ContactsAccountType>
và một hoặc nhiều phần tử con
<ContactsDataKind>
của nó. Điều này được mô tả chi tiết hơn trong
phần <ContactsDataKind> element
.
Để tìm hiểu thêm về các kiểu MIME tùy chỉnh, hãy đọc hướng dẫn Tạo một Trình cung cấp Nội dung.
Trình cung cấp Danh bạ được thiết kế riêng để xử lý đồng bộ hoá dữ liệu danh bạ giữa một thiết bị và một dịch vụ trực tuyến. Điều này cho phép người dùng tải dữ liệu hiện có xuống một thiết bị mới và tải dữ liệu hiện có lên một tài khoản mới. Đồng bộ hoá cũng đảm bảo rằng người dùng có sẵn dữ liệu mới nhất, không phụ thuộc vào nguồn của các bổ sung và thay đổi. Một ưu điểm khác của đồng bộ hoá đó là nó khiến dữ liệu danh bạ có sẵn ngay cả khi thiết bị không được kết nối với mạng.
Mặc dù bạn có thể triển khai đồng bộ hoá theo nhiều cách, hệ thống Android cung cấp một khuôn khổ đồng bộ hóa bổ trợ có khả năng tự động hóa những tác vụ sau:
Để sử dụng khuôn khổ này, bạn phải cung cấp một phần bổ trợ trình điều hợp đồng bộ. Mỗi trình điều hợp đồng bộ là duy nhất đối với một dịch vụ và trình cung cấp nội dung, nhưng có thể xử lý nhiều tên tài khoản cho cùng dịch vụ. Khuôn khổ cũng cho phép nhiều trình điều hợp đồng bộ cho cùng dịch vụ và trình cung cấp.
Bạn triển khai một trình điều hợp đồng bộ làm lớp con của {@link android.content.AbstractThreadedSyncAdapter} và cài đặt nó như một phần của một ứng dụng Android. Hệ thống biết về trình điều hợp đồng bộ từ các phần tử trong bản kê khai ứng dụng của nó, và từ một tệp XML đặc biệt được chỉ đến trong bản kê khai. Tệp XML sẽ định nghĩa loại tài khoản cho dịch vụ trực tuyến và thẩm quyền cho trình cung cấp nội dung, cùng nhau chúng xác định duy nhất một trình điều hợp. Trình điều hợp đồng bộ không được kích hoạt cho tới khi người dùng thêm một tài khoản cho loại tài khoản của trình điều hợp đồng bộ và kích hoạt đồng bộ hoá cho trình cung cấp nội dung mà trình điều hợp đồng bộ sẽ đồng bộ cùng. Tại thời điểm đó, hệ thống bắt đầu quản lý trình điều hợp, gọi nó nếu cần thiết để đồng bộ hoá giữa trình cung cấp nội dung và máy chủ.
Lưu ý: Việc sử dụng một loại tài khoản để tham gia nhận biết trình điều hợp đồng bộ sẽ cho phép
hệ thống phát hiện và nhóm cùng nhau những trình điều hợp đồng bộ truy cập các dịch vụ khác nhau từ
cùng tổ chức. Ví dụ, các trình điều hợp đồng bộ cho dịch vụ trực tuyến của Google đều có cùng
loại tài khoản com.google
. Khi người dùng thêm một tài khoản Google vào thiết bị của mình, tất cả
trình điều hợp đồng bộ được cài đặt cho dịch vụ Google được liệt kê cùng nhau; mỗi trình điều hợp đồng bộ
được liệt kê sẽ đồng bộ với một trình cung cấp nội dung khác nhau trên thiết bị.
Vì hầu hết dịch vụ đều yêu cầu người dùng xác minh danh tính của họ trước khi truy cập dữ liệu, hệ thống Android cung cấp một khuôn khổ xác thực tương tự như và thường được sử dụng cùng với khuôn khổ của trình điều hợp đồng bộ. Khuôn khổ xác thực sử dụng các trình xác thực bổ trợ là lớp con của {@link android.accounts.AbstractAccountAuthenticator}. Một trình xác thực sẽ xác minh danh tính của người dùng theo các bước sau:
Nếu dịch vụ chấp nhận thông tin xác thực, trình xác thực có thể lưu giữ thông tin xác thực đó để sử dụng sau. Vì khuôn khổ trình xác thực bổ trợ, {@link android.accounts.AccountManager} có thể cung cấp quyền truy cập bất kỳ token xác thực nào mà một trình xác thực hỗ trợ và chọn hiện ra, chẳng hạn như token xác thực OAuth2.
Mặc dù không yêu cầu xác thực, phần lớn dịch vụ danh bạ đều sử dụng nó. Tuy nhiên, bạn không phải sử dụng khuôn khổ xác thực của Android để thực hiện xác thực.
Để triển khai một trình điều hợp đồng bộ cho Trình cung cấp Danh bạ, bạn bắt đầu bằng cách tạo một ứng dụng Android chứa:
Trong ứng dụng mẫu
Trình điều hợp Đồng bộ Mẫu, tên lớp của dịch vụ này là
com.example.android.samplesync.syncadapter.SyncService
.
Trong ứng dụng mẫu
Trình điều hợp Đồng bộ Mẫu, trình điều hợp đồng bộ được định nghĩa trong lớp
com.example.android.samplesync.syncadapter.SyncAdapter
.
Trong ứng dụng mẫu
Trình điều hợp Đồng bộ Mẫu, tên lớp của dịch vụ này là
com.example.android.samplesync.authenticator.AuthenticationService
.
Trong ứng dụng mẫu
Trình điều hợp Đồng bộ Mẫu, trình xác thực được định nghĩa trong lớp
com.example.android.samplesync.authenticator.Authenticator
.
<service>
ở bản kê khai của ứng dụng. Những phần tử này
chứa các phần tử con
<meta-data>
mà cung cấp dữ liệu cụ thể cho
hệ thống:
<meta-data>
cho dịch vụ trình điều hợp đồng bộ sẽ trỏ về
tệp XML res/xml/syncadapter.xml
. Đến lượt mình, tệp này quy định
một URI cho dịch vụ web mà sẽ được đồng bộ hóa với Trình cung cấp Danh bạ,
và một loại tài khoản cho dịch vụ web.
<meta-data>
cho trình xác thực sẽ trỏ về tệp XML
res/xml/authenticator.xml
. Đến lượt mình, tệp này quy định
loại tài khoản mà trình xác thực này hỗ trợ, cũng như các tài nguyên UI mà
xuất hiện trong tiến trình xác thực. Loại tài khoản được quy định trong phần tử
này phải giống như loại tài khoản được quy định cho trình điều hợp
đồng bộ.
Các bảng {@code android.provider.ContactsContract.StreamItems} và {@code android.provider.ContactsContract.StreamItemPhotos} quản lý dữ liệu đến từ các mạng xã hội. Bạn có thể ghi một trình điều hợp đồng bộ mà thêm dữ liệu luồng từ mạng của chính mình vào những bảng này, hoặc bạn có thể đọc dữ liệu luồng từ những bảng này và hiển thị nó trong ứng dụng của chính mình, hoặc cả hai. Với những tính năng này, các dịch vụ và ứng dụng mạng xã hội của bạn có thể được tích hợp vào trải nghiệm mạng xã hội của Android.
Các mục dòng dữ liệu luôn được liên kết với một liên lạc thô.
{@code android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID} liên kết với giá trị
_ID
của liên lạc thô mới. Loại tài khoản và tên tài khoản của liên lạc thô
cũng được lưu giữ trong hàng mục dòng.
Lưu giữ dữ liệu từ luồng của bạn vào những cột sau:
Để hiển thị thông tin nhận dạng cho các mục dòng của bạn, hãy sử dụng {@code android.provider.ContactsContract.StreamItemsColumns#RES_ICON}, {@code android.provider.ContactsContract.StreamItemsColumns#RES_LABEL}, và {@code android.provider.ContactsContract.StreamItemsColumns#RES_PACKAGE} để liên kết với các tài nguyên trong ứng dụng của mình.
Bảng {@code android.provider.ContactsContract.StreamItems} chứa các cột {@code android.provider.ContactsContract.StreamItemsColumns#SYNC1} thông qua {@code android.provider.ContactsContract.StreamItemsColumns#SYNC4} dành riêng để sử dụng trình điều hợp đồng bộ.
Bảng {@code android.provider.ContactsContract.StreamItemPhotos} lưu giữ ảnh được liên kết với một mục dòng. Cột {@code android.provider.ContactsContract.StreamItemPhotosColumns#STREAM_ITEM_ID} của bảng liên kết với các giá trị trong {@code android.provider.BaseColumns#_ID} của bảng {@code android.provider.ContactsContract.StreamItems}. Các tham chiếu ảnh được lưu giữ trong bảng ở những cột này:
Những bảng này hoạt động giống như các bảng chính khác trong Trình cung cấp Danh bạ, ngoại trừ:
null
. Truy vấn
trả về một Con chạy chứa một hàng đơn, với cột đơn
{@code android.provider.ContactsContract.StreamItems#MAX_ITEMS}.
Lớp {@code android.provider.ContactsContract.StreamItems.StreamItemPhotos} định nghĩa một bảng con {@code android.provider.ContactsContract.StreamItemPhotos} chứa các hàng ảnh cho một mục dòng đơn.
Dữ liệu từ luồng xã hội được quản lý bởi Trình cung cấp Danh bạ, kết hợp với ứng dụng danh bạ của thiết bị, cung cấp một cách hiệu quả để kết nối hệ thống mạng xã hội của bạn với các liên lạc hiện tại. Có sẵn những tính năng sau:
Đồng bộ hóa thường xuyên các mục dòng với Trình cung cấp Danh bạ giống như các trường hợp đồng bộ hoá khác. Để tìm hiểu thêm về đồng bộ hoá, hãy xem phần Trình điều hợp Đồng bộ Trình cung cấp Danh bạ. Việc đăng ký thông tin và mời liên lạc được đề cập trong hai phần tiếp theo.
Để đăng ký để trình điều hợp đồng bộ của bạn nhận thông báo khi người dùng xem một liên lạc do trình điều hợp đồng bộ của bạn quản lý:
contacts.xml
trong thư mục res/xml/
của dự án của bạn. Nếu đã có tệp này, bạn có thể bỏ qua bước này.
<ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android">
.
Nếu phần tử này đã tồn tại, bạn có thể bỏ qua bước này.
viewContactNotifyService="serviceclass"
vào phần tử, trong đó
serviceclass
là tên lớp được đáp ứng đầy đủ của dịch vụ
mà sẽ nhận ý định từ ứng dụng danh bạ của thiết bị. Đối với dịch vụ
trình thông báo, hãy sử dụng một lớp mở rộng {@link android.app.IntentService}, để cho phép dịch vụ
nhận các ý định. Dữ liệu trong ý định đến chứa URI nội dung của liên lạc
thô mà người dùng đã nhấp vào. Từ dịch vụ trình thông báo, bạn có thể gắn kết với rồi gọi trình điều hợp đồng bộ
của bạn để cập nhật dữ liệu cho liên lạc thô.
Để đăng ký một hoạt động sẽ được gọi khi người dùng nhấp vào một mục dòng hay ảnh hoặc cả hai:
contacts.xml
trong thư mục res/xml/
của dự án của bạn. Nếu đã có tệp này, bạn có thể bỏ qua bước này.
<ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android">
.
Nếu phần tử này đã tồn tại, bạn có thể bỏ qua bước này.
viewStreamItemActivity="activityclass"
vào phần tử đó, trong đó
activityclass
là tên lớp được xác định đầy đủ của hoạt động
mà sẽ nhận ý định từ ứng dụng danh bạ của thiết bị.
viewStreamItemPhotoActivity="activityclass"
vào phần tử đó, trong đó
activityclass
là tên lớp được xác định đầy đủ của hoạt động
mà sẽ nhận ý định từ ứng dụng danh bạ của thiết bị.
Phần tử <ContactsAccountType>
được mô tả chi tiết hơn trong mục
phần tử <ContactsAccountType>.
Ý định đến chứa URI nội dung của mục hoặc ảnh mà người dùng đã nhấp vào. Để có các hoạt động riêng cho các mục văn bản và ảnh, hãy sử dụng cả hai thuộc tính trong cùng tệp.
Người dùng không phải rời ứng dụng danh bạ của thiết bị để mời một liên lạc tới trang mạng xã hội của bạn. Thay vào đó, bạn có thể thiết đặt để ứng dụng danh bạ của thiết bị gửi một ý định để mời liên lạc đó tới một trong các hoạt động của mình. Để thiết đặt điều này:
contacts.xml
trong thư mục res/xml/
của dự án của bạn. Nếu đã có tệp này, bạn có thể bỏ qua bước này.
<ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android">
.
Nếu phần tử này đã tồn tại, bạn có thể bỏ qua bước này.
inviteContactActivity="activityclass"
inviteContactActionLabel="@string/invite_action_label"
activityclass
là tên lớp được xác định đầy đủ của hoạt động
mà sẽ nhận được ý định. Giá trị invite_action_label
là một xâu văn bản được hiển thị trong menu Thêm Kết nối trong ứng dụng danh bạ
của thiết bị.
Lưu ý: ContactsSource
là một tên tag không được chấp nhận đối với
ContactsAccountType
.
Tệp contacts.xml
chứa các phần tử XML có chức năng kiểm soát tương tác giữa
trình điều hợp đồng bộ và ứng dụng của bạn với ứng dụng danh bạ và Trình cung cấp Danh bạ. Những
phần tử này được mô tả trong các mục sau.
Phần tử <ContactsAccountType>
kiểm soát tương tác giữa
ứng dụng của bạn với ứng dụng danh bạ. Nó có những cú pháp sau:
<ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android" inviteContactActivity="activity_name" inviteContactActionLabel="invite_command_text" viewContactNotifyService="view_notify_service" viewGroupActivity="group_view_activity" viewGroupActionLabel="group_action_text" viewStreamItemActivity="viewstream_activity_name" viewStreamItemPhotoActivity="viewphotostream_activity_name">
chứa trong:
res/xml/contacts.xml
có thể chứa:
<ContactsDataKind>
Mô tả:
Khai báo các thành phần Android và nhãn UI mà cho phép người dùng mời một trong các liên lạc của mình đến một mạng xã hội, thông báo người dùng khi một trong các luồng mạng xã hội của họ được cập nhật, v.v.
Để ý rằng tiền tố thuộc tính android:
không nhất thiết áp dụng cho các thuộc tính
của <ContactsAccountType>
.
Thuộc tính:
NotifierService.java
trong ứng dụng mẫu
SampleSyncAdapter
.
Ví dụ, nếu bạn cài đặt ứng dụng Google+ trên thiết bị của mình và bạn đồng bộ Google+ với ứng dụng danh bạ, bạn sẽ thấy các vòng tròn Google+ được liệt kê thành các nhóm trong tab Nhóm của ứng dụng danh bạ của bạn. Nếu bạn nhấp vào một vòng tròn Google+, bạn sẽ thấy những người trong vòng tròn đó được liệt kê thành một "nhóm". Phía bên trên của hiển thị, bạn sẽ thấy một biểu tượng Google+; nếu bạn nhấp vào đó, điều khiển sẽ chuyển sang ứng dụng Google+. Ứng dụng danh bạ làm điều này bằng {@code viewGroupActivity}, bằng cách sử dụng biểu tượng Google+ làm giá trị của {@code viewGroupActionLabel}.
Một mã định danh tài nguyên xâu được cho phép cho thuộc tính này.
Phần tử <ContactsDataKind>
kiểm soát việc hiển thị các hàng
dữ liệu tùy chỉnh của ứng dụng của bạn trong UI của ứng dụng danh bạ. Nó có những cú pháp sau:
<ContactsDataKind android:mimeType="MIMEtype" android:icon="icon_resources" android:summaryColumn="column_name" android:detailColumn="column_name">
chứa trong:
<ContactsAccountType>
Mô tả:
Sử dụng phần tử này để ứng dụng danh bạ hiển thị các nội dung trong một hàng dữ liệu tùy chỉnh như
một phần chi tiết của một liên lạc thô. Mỗi phần tử con <ContactsDataKind>
của <ContactsAccountType>
đại diện cho một kiểu hàng dữ liệu tùy chỉnh mà trình điều hợp
đồng bộ của bạn thêm vào bảng {@link android.provider.ContactsContract.Data}. Thêm một phần tử
<ContactsDataKind>
cho mỗi kiểu MIME tùy chỉnh mà bạn sử dụng. Bạn không phải
thêm phần tử nếu có một hàng dữ liệu tùy chỉnh mà bạn không muốn hiển thị dữ liệu.
Thuộc tính:
vnd.android.cursor.item/vnd.example.locationstatus
có thể là một kiểu
MIME tùy chỉnh cho một hàng dữ liệu có chức năng ghi lại vị trí được biết đến cuối cùng của một liên lạc.
Bên cạnh các tính năng chính được mô tả trong các phần trước, Trình cung cấp Danh bạ còn cung cấp những tính năng hữu ích sau khi làm việc với dữ liệu danh bạ:
Trình cung cấp Danh bạ có thể tùy chọn đánh nhãn các bộ sưu tập liên lạc có liên quan bằng dữ liệu nhóm. Nếu máy chủ liên kết với một tài khoản người dùng muốn duy trì nhóm, trình điều hợp đồng bộ cho loại tài khoản của tài khoản đó sẽ chuyển dữ liệu nhóm giữa Trình cung cấp Danh bạ và máy chủ. Khi người dùng thêm một liên lạc mới vào máy chủ, trình điều hợp đồng bộ phải thêm nhóm mới vào bảng {@link android.provider.ContactsContract.Groups}. Nhóm hoặc các nhóm mà một liên lạc thô thuộc về được lưu giữ trong bảng {@link android.provider.ContactsContract.Data}, bằng cách sử dụng kiểu MIME {@link android.provider.ContactsContract.CommonDataKinds.GroupMembership}.
Nếu bạn đang thiết kế một trình điều hợp đồng bộ mà sẽ thêm dữ liệu liên lạc thô từ máy chủ tới Trình cung cấp Danh bạ, và bạn không sử dụng các nhóm, khi đó bạn cần báo cho Trình cung cấp làm các dữ liệu của bạn thấy được. Trong đoạn mã được thực hiện khi một người dùng thêm một tài khoản vào thiết bị, hãy cập nhật hàng {@link android.provider.ContactsContract.Settings} mà Trình cung cấp Danh bạ thêm cho tài khoản. Trong hàng này, đặt giá trị của cột {@link android.provider.ContactsContract.SettingsColumns#UNGROUPED_VISIBLE Settings.UNGROUPED_VISIBLE} thành 1. Khi bạn làm vậy, Trình cung cấp Danh bạ sẽ luôn làm cho dữ liệu danh bạ của bạn thấy được, ngay cả khi bạn không sử dụng nhóm.
Bảng {@link android.provider.ContactsContract.Data} lưu giữ ảnh thành hàng với kiểu MIME {@link android.provider.ContactsContract.CommonDataKinds.Photo#CONTENT_ITEM_TYPE Photo.CONTENT_ITEM_TYPE}. Cột {@link android.provider.ContactsContract.RawContactsColumns#CONTACT_ID} của hàng được liên kết với cột {@code android.provider.BaseColumns#_ID} của liên lạc thô mà nó thuộc về. Lớp {@link android.provider.ContactsContract.Contacts.Photo} định nghĩa một bảng con của {@link android.provider.ContactsContract.Contacts} chứa thông tin ảnh về ảnh chính của một liên lạc, đây là ảnh chính của liên lạc thô chính của liên lạc. Tương tự, lớp {@link android.provider.ContactsContract.RawContacts.DisplayPhoto} định nghĩa một bảng con của {@link android.provider.ContactsContract.RawContacts} chứa thông tin ảnh đối với ảnh chính của một liên lạc thô.
Tài liệu tham khảo cho {@link android.provider.ContactsContract.Contacts.Photo} và {@link android.provider.ContactsContract.RawContacts.DisplayPhoto} có các ví dụ về việc truy xuất thông tin ảnh. Không có lớp thuận tiện cho việc truy xuất hình thu nhỏ chính đối với một liên lạc thô, nhưng bạn có thể gửi một truy vấn tới bảng {@link android.provider.ContactsContract.Data}, chọn {@code android.provider.BaseColumns#_ID} của liên lạc thô, {@link android.provider.ContactsContract.CommonDataKinds.Photo#CONTENT_ITEM_TYPE Photo.CONTENT_ITEM_TYPE}, và cột {@link android.provider.ContactsContract.Data#IS_PRIMARY} để tìm hàng ảnh chính của liên lạc thô.
Dữ liệu từ luồng xã hội đối với một người cũng có thể bao gồm ảnh. Những ảnh này được lưu giữ trong bảng {@code android.provider.ContactsContract.StreamItemPhotos}, được mô tả chi tiết hơn trong phần Ảnh từ luồng xã hội.