Tin tức về sản phẩm

Cách đáng tin cậy hơn để thêm và chỉnh sửa người liên hệ trên Android

6 phút đọc
Xem hồ sơ của Roxanna Aliabadi Walker
Roxanna Aliabadi Walker Nhà quản lý sản phẩm, Android

Những thay đổi sắp tới

Những ứng dụng nhắm đến bản phát hành Android sắp tới sẽ không thể ghi trực tiếp vào danh bạ bằng quyền WRITE_CONTACTS nữa. Thay vào đó, bạn có thể sử dụng các ý định liên hệ chuẩn (ACTION_INSERT, ACTION_EDIT và ACTION_INSERT_OR_EDIT). Để xem cách triển khai tham chiếu đầy đủ, hãy xem hướng dẫn dành cho nhà phát triển về cách sửa đổi người liên hệ bằng ý định. 

Trên các thiết bị chạy bản phát hành Android sắp tới, ba ý định liên hệ này sẽ hoạt động nhất quán và không cần quyền nào cả. Nếu ứng dụng của bạn nhắm đến bản phát hành Android sắp tới trở lên và cố gắng ghi trực tiếp vào danh bạ, thì những thao tác ghi đó sẽ bị từ chối và dẫn đến SecurityException hoặc từ chối quyền. Đối với một số ít ứng dụng cần có quyền truy cập rộng để tạo và sửa đổi danh bạ, một quyền truy cập đặc biệt mới cho ứng dụng (MANAGE_CONTACTS) sẽ được ra mắt trong Android 17 QPR2 (quý 4 năm 2026). Hôm nay, Google Play sẽ phát hành các nguyên tắc mới về quyền truy cập vào danh bạ, bao gồm cả MANAGE_CONTACTS.

Lý do chúng tôi làm việc này

Hiện tại, nếu ứng dụng của bạn cần lưu dù chỉ một người liên hệ, thì bạn có thể đang yêu cầu quyền WRITE_CONTACTS. Tuy nhiên, quyền này cấp quyền truy cập rộng, cho phép ứng dụng thực hiện các thay đổi trên diện rộng đối với danh bạ trên thiết bị ở chế độ nền, ngay cả khi không có hoạt động tương tác của người dùng. Hầu hết các ứng dụng không cần quyền truy cập rộng như vậy.

Mặc dù có các giải pháp thay thế, nhưng chúng tôi nhận được ý kiến phản hồi rằng các giải pháp đó cần được chuẩn hoá hơn nữa trên toàn hệ sinh thái. Trước đây, ý định liên hệ hoạt động khác nhau tuỳ theo thiết bị. Một số trình chỉnh sửa đã bỏ dữ liệu bạn truyền vào, chẳng hạn như ảnh của người liên hệ. Trên một số thiết bị, nút quay lại đã lưu người liên hệ mà người dùng không có ý định lưu hoặc người dùng khó tìm thấy lựa chọn "tạo người liên hệ mới". Vì vậy, xin phép là lựa chọn hợp lý. Chúng tôi đang khắc phục tất cả những vấn đề này trong phiên bản Android sắp tới và yêu cầu các thiết bị chạy phiên bản này phải tuân theo cùng một tiêu chuẩn.

Nội dung thay thế

Thêm hoặc chỉnh sửa người liên hệ: sử dụng ý định liên hệ

Khi bạn sử dụng các ý định này (ACTION_INSERT, ACTION_EDIT và ACTION_INSERT_OR_EDIT), hệ thống sẽ xử lý phần việc nặng nhọc bằng cách trình bày một trải nghiệm trình chỉnh sửa danh bạ rõ ràng,  chuẩn hoá. Thao tác này sẽ mở ra một biểu mẫu nửa trang nhanh cho các mục mới hoặc cho phép người dùng dễ dàng tìm kiếm và thêm thông tin vào một người liên hệ hiện có. Người dùng có thể mở rộng liền mạch thành trình chỉnh sửa toàn trang để điền thêm thông tin chi tiết mà ứng dụng của bạn không cần có quyền ghi trực tiếp. Hãy xem bản mô phỏng UX dự kiến dưới đây: 

01_Quick_Insert_Half_Sheet_Prefilled.png
Ảnh chụp màn hình 2 – Tiêu đề: Bản mô phỏng toàn trang của tính năng Tạo người liên hệ mới: Ảnh chụp màn hình giao diện người dùng Android dự kiến, cho thấy trình chỉnh sửa người liên hệ toàn màn hình có bộ chọn hình đại diện, các trường tên, điện thoại và email. Thiết kế này được gắn nhãn "UX not Final" (Trải nghiệm người dùng chưa hoàn thiện).

Hình 1: Tạo người liên hệ mới  *Trải nghiệm người dùng chưa hoàn thiện*

Figure02_01_Add_To_Existing_0_Search_State_Half_Sheet.png
Ảnh chụp màn hình 2 – Tiêu đề: Bản minh hoạ toàn trang của tính năng "Thêm thông tin vào một người liên hệ hiện có": Ảnh chụp màn hình giao diện người dùng Android dự kiến, cho thấy trình chỉnh sửa người liên hệ toàn màn hình có bộ chọn hình đại diện, các trường tên, điện thoại và email. Thiết kế toàn trang có các khối thông tin hiển thị dần cho các trường phụ. Thiết kế này được gắn nhãn "Trải nghiệm người dùng chưa hoàn thiện".

Hình 2: Thêm thông tin vào một người liên hệ hiện có *Trải nghiệm người dùng chưa hoàn thiện*


Lưu ý: Các nhà sản xuất thiết bị khác nhau có thể sửa đổi trải nghiệm người dùng cho phù hợp với kiểu hệ điều hành của họ, nhưng hành vi sẽ không thay đổi.


Bạn có thể đơn giản hoá quy trình tạo bằng cách truyền tải trọng dữ liệu không bắt buộc (gọi là Extras) cùng với ý định:

  • EXTRA_ACCOUNT đề xuất tài khoản mà người liên hệ lưu vào, điều này sẽ giúp ích nếu ứng dụng của bạn đồng bộ hoá danh bạ. Tính năng bổ sung này đã tồn tại, nhưng khả năng hỗ trợ tuỳ theo thiết bị. Kể từ bản phát hành Android sắp tới, tính năng hỗ trợ sẽ được chuẩn hoá trên các thiết bị.
  • EXTRA_PHOTO_URI tự động điền trước ảnh của người liên hệ bằng một ảnh. Trình chỉnh sửa sẽ xử lý quyền đọc URI cho bạn. Đây là tính năng mới trong bản phát hành Android sắp tới và sẽ được hỗ trợ trên toàn hệ sinh thái.

Trước: ghi trực tiếp bằng WRITE_CONTACTS (Dẫn đến SecurityException hoặc từ chối cấp quyền sau khi ứng dụng của bạn nhắm đến bản phát hành Android sắp tới.)

 

// Requires android.permission.WRITE_CONTACTS
fun saveContactDirectly(context: Context, name: String, phone: String, account: Account) {
    val ops = arrayListOf(
        ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
            .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, account.type)
            .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, account.name)
            .build(),
        ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
            .withValue(
                ContactsContract.Data.MIMETYPE,
                ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE
            )
            .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name)
            .build(),
        ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
            .withValue(
                ContactsContract.Data.MIMETYPE,
                ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE
            )
            .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phone)
            .build()
    )
    context.contentResolver.applyBatch(ContactsContract.AUTHORITY, ops)
}

 

 

Sau: mở trình chỉnh sửa danh bạ (Không cần quyền.)

 

fun saveContactWithEditor(
    context: Context,
    name: String,
    phone: String,
    account: Account,
    photoUri: Uri
) {
    val intent = Intent(Intent.ACTION_INSERT, ContactsContract.Contacts.CONTENT_URI).apply {
        putExtra(ContactsContract.Intents.Insert.NAME, name)
        putExtra(ContactsContract.Intents.Insert.PHONE, phone)
        // Suggest which account the contact is saved to
        putExtra(ContactsContract.Intents.Insert.EXTRA_ACCOUNT, account)
        // New in the upcoming Android release: pre-fill the contact photo
        putExtra(ContactsContract.Intents.Insert.EXTRA_PHOTO_URI, photoUri)
        clipData = ClipData.newRawUri("", photoUri)
        addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
    }
    context.startActivity(intent)
}

 

Trước: cập nhật trực tiếp một người liên hệ hiện có

 

// Requires android.permission.WRITE_CONTACTS
fun addPhoneDirectly(context: Context, rawContactId: Long, phone: String) {
    val values = ContentValues().apply {
        put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId)
        put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
        put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone)
    }
    context.contentResolver.insert(ContactsContract.Data.CONTENT_URI, values)
}

Sau: cho phép người dùng chọn một người liên hệ để cập nhật hoặc tạo người liên hệ mới

fun addPhoneWithEditor(context: Context, phone: String) {
    val intent = Intent(Intent.ACTION_INSERT_OR_EDIT).apply {
        type = ContactsContract.Contacts.CONTENT_ITEM_TYPE
        putExtra(ContactsContract.Intents.Insert.PHONE, phone)
    }
    context.startActivity(intent)
}

Nếu bạn đã biết người liên hệ cần cập nhật, hãy sử dụng ACTION_EDIT với URI của người liên hệ đó:

fun editKnownContact(context: Context, contactUri: Uri, phone: String) {
    val intent = Intent(Intent.ACTION_EDIT, contactUri).apply {
        putExtra(ContactsContract.Intents.Insert.PHONE, phone)
    }
    context.startActivity(intent)
}

 

Chọn người liên hệ: sử dụng Trình chọn người liên hệ

Nếu bạn chỉ cần đọc những người liên hệ mà người dùng chọn, hãy sử dụng Trình chọn người liên hệ, có từ Android 17. Ứng dụng này không cần quyền.

Ứng dụng gọi điện và nhắn tin: sử dụng Danh bạ người dùng

Một số ứng dụng thêm các thao tác "Gọi bằng…" hoặc "Nhắn tin bằng…" vào danh bạ để mọi người có thể bắt đầu cuộc gọi hoặc cuộc trò chuyện từ ứng dụng Điện thoại hoặc Ứng dụng Danh bạ. Nếu ứng dụng của bạn hiện làm việc này bằng cách ghi thêm các mục vào danh bạ của người dùng, hãy chuyển sang Danh bạ người dùng, sẽ có trong Android QPR2 (quý 4 năm 2026). Đây là một thư mục hệ thống mới, nơi ứng dụng của bạn xuất bản cách mọi người có thể liên hệ với nhau trong ứng dụng mà không cần chỉnh sửa danh bạ của người dùng.

Ví dụ về cách ứng dụng có thể di chuyển

Để xem cách các phương án thay thế này hoạt động trong thực tế, dưới đây là một số ví dụ về cách các loại ứng dụng khác nhau có thể tiếp cận quyền truy cập vào danh bạ:

Loại ứng dụng mẫu (không độc quyền).Đường dẫn di chuyển đề xuất
Ứng dụng mạng xã hội, thanh toán ngang hàng và đi chung xeNếu ứng dụng của bạn cho phép người dùng tìm bạn bè, chia hoá đơn hoặc chia sẻ trạng thái chuyến đi, thì bạn hoàn toàn không cần quyền truy cập danh bạ. Sử dụng Trình chọn người liên hệ để chọn người liên hệ một lần và chạy ACTION_INSERT bằng EXTRA_PHOTO_URI khi người dùng nhấn vào "Lưu vào Danh bạ" trên một hồ sơ.
Ứng dụng quét danh thiếp và kết nối tại sự kiệnNếu ứng dụng của bạn quét huy hiệu hoặc mã QR và lưu một người liên hệ mới (hoặc thêm số điện thoại công việc vào mục nhập của một đồng nghiệp hiện có), hãy sử dụng ACTION_INSERT hoặc ACTION_INSERT_OR_EDIT. Trình chỉnh sửa nửa trang chuẩn hoá sẽ tự động điền trước các trường được phân tích cú pháp (tên, công ty, điện thoại, email và ảnh) để người dùng có thể xác minh và lưu bằng một lần nhấn mà không cần cấp quyền ở chế độ nền.
Ứng dụng gọi điện và nhắn tin qua VoIPThay vì yêu cầu WRITE_CONTACTS chèn các hàng tuỳ chỉnh "Gọi bằng…" hoặc "Nhắn tin bằng…" vào sổ địa chỉ của người dùng, hãy xuất bản siêu dữ liệu về khả năng kết nối thông qua Danh bạ và sử dụng ACTION_INSERT khi người dùng thêm người liên hệ mới từ một chuỗi trò chuyện.
Ứng dụng CRM và đồng bộ hoá đám mây dành cho doanh nghiệpNếu ứng dụng của bạn thực hiện việc đồng bộ hoá danh bạ hai chiều liên tục ở chế độ nền với một tài khoản đám mây hoặc tài khoản doanh nghiệp (trong trường hợp không thể nhắc người dùng bằng giao diện người dùng ý định cho mọi bản ghi), thì ứng dụng của bạn đủ điều kiện khai báo MANAGE_CONTACTS 

Các thay đổi cần kiểm tra

  • Trình chỉnh sửa không hỗ trợ các loại dữ liệu tuỳ chỉnh. Nếu bạn truyền các hàng Insert.DATA có loại MIME khác với loại ContactsContract.CommonDataKinds chuẩn, thì trình chỉnh sửa sẽ tự động bỏ qua các loại MIME đó.
  • SHOW_OR_CREATE_CONTACT không được trình chỉnh sửa hệ thống xử lý. Các ứng dụng Danh bạ có sẵn trên thiết bị vẫn có thể xử lý ý định này. Để có hành vi nhất quán trên các thiết bị, hãy sử dụng ACTION_INSERT_OR_EDIT.
  • Theo mặc định, thao tác ghi sẽ không thành công. Sau khi bạn nhắm đến bản phát hành Android sắp tới, mọi thao tác ghi trực tiếp mà không có MANAGE_CONTACTS sẽ dẫn đến SecurityException or permission denial. Hãy kiểm tra xem có lỗi này không.

Tôi có cần MANAGE_CONTACTS không?

Thường là không. Nếu ứng dụng của bạn lưu hoặc chỉnh sửa danh bạ theo yêu cầu của người dùng, thì các ý định nêu trên sẽ giúp bạn thực hiện việc này mà không cần quyền và không cần khai báo trên Play Console.

MANAGE_CONTACTS dành cho những ứng dụng có mục đích cốt lõi là quản lý danh bạ, trong trường hợp các ý định là chưa đủ. Ví dụ:

Ứng dụng của bạn…Bạn cần MANAGE_CONTACTS?
Lưu người liên hệ từ cuộc trò chuyện, danh thiếp hoặc đơn đặt hàng.Không, hãy dùng ACTION_INSERT
Thêm số điện thoại hoặc email vào một người liên hệ hiện có.Không, hãy dùng ACTION_INSERT_OR_EDIT hoặc ACTION_EDIT
Cho phép người dùng chọn người liên hệ để mời, chia sẻ hoặc thanh toán.Không, hãy dùng Trình chọn người liên hệ
Thêm hành động gọi điện hoặc nhắn tin cho người liên hệ.Không, hãy sử dụng Danh bạ người dùng
Có màn hình chỉnh sửa danh bạ mang thương hiệu riêng.Không, chỉ có giao diện tuỳ chỉnh thì không đủ điều kiện
Là một ứng dụng chuyên quản lý danh bạ hoặc thay thế trình quay số.Có khả năng
Là một ứng dụng nhận dạng người gọi và chống cuộc gọi rác, có chức năng cập nhật hàng loạt mục trong sổ địa chỉ.Có khả năng
Đồng bộ hoá danh bạ với tài khoản doanh nghiệp hoặc tài khoản đám mây ở chế độ nền.Có khả năng
Sao lưu/khôi phục hàng loạt danh bạ hoặc chuyển dữ liệu từ điện thoại này sang điện thoại khác.Có khả năng
Đặt nhạc chuông tuỳ chỉnh cho từng người liên hệ.Có khả năng

Cách hoạt động:

  • MANAGE_CONTACTS là một quyền truy cập đặc biệt của ứng dụng. Đây không phải là hộp thoại thời gian chạy. Người dùng bật quyền này trong phần Cài đặt > Quyền truy cập đặc biệt của ứng dụng > Quản lý danh bạ.
// Opens Settings > Apps > Special app access > Manage contacts
val intent = Intent(Settings.ACTION_MANAGE_CONTACTS, Uri.fromParts("package", packageName, null))
context.startActivity(intent)
  • Phạm vi này bao gồm việc đọc, thêm, chỉnh sửa và xoá người liên hệ, tài khoản và dữ liệu trong Thư mục người dùng. Bạn cũng không cần yêu cầu quyền READ_CONTACTS.
  • Để phát hành ứng dụng trên Google Play bằng quyền MANAGE_CONTACTS, bạn cần gửi một bản khai báo trong Play Console để giải thích lý do ý định không đủ cho chức năng cốt lõi của ứng dụng.

Các bước di chuyển

  • Tìm các lượt ghi danh bạ. Tìm kiếm mã của bạn cho WRITE_CONTACTS, ContactsContract.RawContacts.CONTENT_URI, ContactsContract.Data.CONTENT_URI và applyBatch(ContactsContract.AUTHORITY, …).
  • Thay thế mỗi thao tác ghi do người dùng thực hiện bằng một ý định: ACTION_INSERT cho người liên hệ mới và ACTION_EDIT hoặc ACTION_INSERT_OR_EDIT cho nội dung cập nhật.
  • Chỉ sử dụng các kiểu dữ liệu chuẩn trong Insert.DATA. Chuyển các thao tác gọi điện hoặc nhắn tin sang Danh bạ.
  • Quyết định xem bạn có thực sự cần MANAGE_CONTACTS hay không bằng cách sử dụng bảng ở trên. Nếu có, hãy lên kế hoạch khai báo trong Play Console.
  • Xoá WRITE_CONTACTS khỏi tệp kê khai khi không còn đường dẫn mã nào cần đến quyền này.

Dòng thời gian

Thời điểmĐiều gì xảy ra
Ngày 21 tháng 10 năm 2026Google Play công bố chính sách MANAGE_CONTACTS
Năm 2026 (Bản phát hành nền tảng hằng quý 2 của Android 17)MANAGE_CONTACTS quyền được cấp
2027 (Bản phát hành Android sắp tới)WRITE_CONTACTS không còn cấp quyền ghi cho các ứng dụng nhắm đến bản phát hành Android sắp tới. Ý định liên hệ được chuẩn hoá trên các thiết bị
Năm 2027, không sớm hơn bản phát hành Android sắp tớiPlay Console yêu cầu các ứng dụng sử dụng MANAGE_CONTACTS phải gửi biểu mẫu khai báo
Năm 2027, không sớm hơn bản phát hành Android sắp tớiBắt buộc phải tuân thủ chính sách của Play

Câu hỏi thường gặp

  • Điều này có ảnh hưởng đến mọi ứng dụng không?
    • Thay đổi về việc ngừng sử dụng WRITE_CONTACTS chỉ áp dụng cho các ứng dụng nhắm đến bản phát hành Android sắp tới và sau đó. Các ứng dụng nhắm đến phiên bản cũ vẫn giữ nguyên hành vi hiện tại, tuy nhiên, trình chỉnh sửa danh bạ mới được chuẩn hoá sẽ có sẵn cho tất cả ứng dụng chạy trên hệ điều hành mới, bất kể SDK mục tiêu của các ứng dụng đó.
  • Ứng dụng của tôi có thể xoá danh bạ bằng ý định không?
    • Không. Không có ý định xoá người liên hệ. Người dùng xoá người liên hệ trong ứng dụng danh bạ của họ. Các ứng dụng có quyền MANAGE_CONTACTS có thể xoá người liên hệ trực tiếp.
  • Tôi đã có màn hình chỉnh sửa thông tin liên hệ của riêng mình. Tôi có thể giữ lại không?
    • Chỉ khi ứng dụng của bạn đủ điều kiện sử dụng MANAGE_CONTACTS. Việc muốn giữ lại một thiết kế tuỳ chỉnh không phải là lý do chính đáng.
  • MANAGE_CONTACTS có thay thế READ_CONTACTS không?
    • MANAGE_CONTACTS bao gồm quyền đọc nên bạn không cần yêu cầu cả hai, nhưng nhiều ứng dụng đủ điều kiện cho READ_CONTACTS mà không cần sửa đổi danh bạ. Các ứng dụng này có thể tiếp tục yêu cầu quyền READ_CONTACTS.
  • Còn người dùng của tôi trên các phiên bản Android cũ thì sao?
    • Ý định liên hệ cũng hoạt động trên các phiên bản cũ hơn, do ứng dụng danh bạ của thiết bị xử lý. Hầu hết các ứng dụng sẽ hoạt động tốt trên mọi thiết bị sử dụng các ý định này. Nếu ứng dụng của bạn bị ảnh hưởng bởi một vấn đề cụ thể về tính nhất quán chỉ được giải quyết trong các phiên bản mới nhất, thì bạn có thể giữ quyền WRITE_CONTACTS trong tệp kê khai trong phạm vi maxSdkVersion thích hợp.
Tác giả:
Tiếp tục đọc