แก้ไขรายชื่อติดต่อโดยใช้ Intent

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

ขอแนะนำให้ใช้ Intent เพื่อแทรกหรืออัปเดตรายชื่อติดต่อรายการเดียว วิธีแก้ไขผู้ให้บริการรายชื่อติดต่อ ด้วยเหตุผลต่อไปนี้

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

แทรกรายชื่อติดต่อใหม่โดยใช้ Intent

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

การป้อนรายชื่อติดต่อโดยใช้แอปรายชื่อติดต่อจะแทรกรายชื่อติดต่อดิบใหม่ลงในตาราง ContactsContract.RawContacts ของผู้ให้บริการรายชื่อติดต่อ หากจำเป็น แอปรายชื่อติดต่อจะแจ้งผู้ใช้เกี่ยวกับประเภทบัญชีและบัญชีที่จะใช้เมื่อสร้างข้อมูลดิบ รายชื่อติดต่อ แอปรายชื่อติดต่อจะแจ้งให้ผู้ใช้ทราบด้วยหากมีรายชื่อติดต่อดิบอยู่แล้ว เพื่อให้ผู้ใช้มี ในการยกเลิกการแทรก ในกรณีที่ไม่มีการสร้างรายชื่อติดต่อ เพื่อเรียนรู้ เพิ่มเติมเกี่ยวกับข้อมูลติดต่อดิบ โปรดดู ผู้ให้บริการรายชื่อติดต่อ คู่มือ API

สร้าง Intent

หากต้องการเริ่มต้น ให้สร้างออบเจ็กต์ Intent ใหม่ด้วยการดำเนินการ Intents.Insert.ACTION ตั้งค่าประเภท MIME เป็น RawContacts.CONTENT_TYPE เช่น

Kotlin

...
// Creates a new Intent to insert a contact
val intent = Intent(ContactsContract.Intents.Insert.ACTION).apply {
    // Sets the MIME type to match the Contacts Provider
    type = ContactsContract.RawContacts.CONTENT_TYPE
}

Java

...
// Creates a new Intent to insert a contact
Intent intent = new Intent(ContactsContract.Intents.Insert.ACTION);
// Sets the MIME type to match the Contacts Provider
intent.setType(ContactsContract.RawContacts.CONTENT_TYPE);

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

Kotlin

private var emailAddress: EditText? = null
private var phoneNumber: EditText? = null
...
/* Assumes EditText fields in your UI contain an email address
 * and a phone number.
 *
 */
emailAddress = findViewById(R.id.email)
phoneNumber = findViewById(R.id.phone)
...
/*
 * Inserts new data into the Intent. This data is passed to the
 * contacts app's Insert screen
 */
intent.apply {
    // Inserts an email address
    putExtra(ContactsContract.Intents.Insert.EMAIL, emailAddress?.text)
    /*
     * In this example, sets the email type to be a work email.
     * You can set other email types as necessary.
     */
    putExtra(
            ContactsContract.Intents.Insert.EMAIL_TYPE,
            ContactsContract.CommonDataKinds.Email.TYPE_WORK
    )
    // Inserts a phone number
    putExtra(ContactsContract.Intents.Insert.PHONE, phoneNumber?.text)
    /*
     * In this example, sets the phone type to be a work phone.
     * You can set other phone types as necessary.
     */
    putExtra(
            ContactsContract.Intents.Insert.PHONE_TYPE,
            ContactsContract.CommonDataKinds.Phone.TYPE_WORK
    )
}

Java

private EditText emailAddress = null;
private EditText phoneNumber = null;
...
/* Assumes EditText fields in your UI contain an email address
 * and a phone number.
 *
 */
emailAddress = (EditText) findViewById(R.id.email);
phoneNumber = (EditText) findViewById(R.id.phone);
...
/*
 * Inserts new data into the Intent. This data is passed to the
 * contacts app's Insert screen
 */
// Inserts an email address
intent.putExtra(ContactsContract.Intents.Insert.EMAIL, emailAddress.getText())
/*
 * In this example, sets the email type to be a work email.
 * You can set other email types as necessary.
 */
      .putExtra(ContactsContract.Intents.Insert.EMAIL_TYPE,
            ContactsContract.CommonDataKinds.Email.TYPE_WORK)
// Inserts a phone number
      .putExtra(ContactsContract.Intents.Insert.PHONE, phoneNumber.getText())
/*
 * In this example, sets the phone type to be a work phone.
 * You can set other phone types as necessary.
 */
      .putExtra(ContactsContract.Intents.Insert.PHONE_TYPE,
            ContactsContract.CommonDataKinds.Phone.TYPE_WORK);

เมื่อสร้าง Intent แล้ว ให้ส่งโดยการโทร startActivity()

Kotlin

    /* Sends the Intent
     */
    startActivity(intent)

Java

    /* Sends the Intent
     */
    startActivity(intent);

การเรียกนี้จะเปิดหน้าจอในแอปรายชื่อติดต่อซึ่งอนุญาตให้ผู้ใช้ป้อนรายชื่อติดต่อใหม่ ประเภทบัญชีและชื่อบัญชีของรายชื่อติดต่อจะแสดงที่ด้านบนของหน้าจอ เมื่อผู้ใช้ป้อนข้อมูลและคลิกเสร็จสิ้น รายชื่อติดต่อของแอปรายชื่อติดต่อจะปรากฏขึ้น ผู้ใช้จะกลับไปที่แอปได้โดยคลิกกลับ

แก้ไขรายชื่อติดต่อที่มีอยู่โดยใช้ Intent

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

หากต้องการแก้ไขรายชื่อติดต่อที่มีอยู่โดยใช้ Intent ให้ใช้ขั้นตอนที่คล้ายกับการแทรกรายชื่อติดต่อ สร้าง Intent ตามที่อธิบายไว้ในส่วนแทรกรายชื่อติดต่อใหม่โดยใช้ Intent แต่ให้เพิ่ม Contacts.CONTENT_LOOKUP_URI ของผู้ติดต่อและประเภท MIME Contacts.CONTENT_ITEM_TYPE ลงใน Intent หากต้องการแก้ไขรายชื่อติดต่อด้วยรายละเอียดที่มีอยู่แล้ว ให้ใส่รายละเอียดเหล่านั้นไว้ในข้อมูลเพิ่มเติมของ Intent โปรดทราบว่าคอลัมน์ชื่อบางคอลัมน์จะแก้ไขโดยใช้ Intent ไม่ได้ คอลัมน์เหล่านี้จะแสดงอยู่ในส่วนสรุปของข้อมูลอ้างอิง API สำหรับคลาส ContactsContract.Contacts ในส่วนหัว "อัปเดต"

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

สร้าง Intent

หากต้องการแก้ไขรายชื่อติดต่อ ให้เรียกใช้ Intent(action) เพื่อสร้าง Intent ที่มีการดำเนินการ ACTION_EDIT โทร setDataAndType() เพื่อตั้งค่าข้อมูลสำหรับฟิลด์ Intent ไปยัง Contacts.CONTENT_LOOKUP_URI ของรายชื่อติดต่อและประเภท MIME เพื่อ Contacts.CONTENT_ITEM_TYPE ประเภท MIME; เพราะการโทรหา setType() จะเขียนทับค่าข้อมูลปัจจุบันสำหรับ Intent คุณต้องตั้งค่าข้อมูลและประเภท MIME พร้อมกัน

หากต้องการรับ Contacts.CONTENT_LOOKUP_URI ของผู้ติดต่อ ให้เรียกใช้ Contacts.getLookupUri(id, lookupkey) พร้อมค่า Contacts._ID และ Contacts.LOOKUP_KEY ของผู้ติดต่อเป็นอาร์กิวเมนต์

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

ข้อมูลโค้ดต่อไปนี้แสดงวิธีสร้าง Intent

Kotlin

    // The Cursor that contains the Contact row
    var mCursor: Cursor? = null
    // The index of the lookup key column in the cursor
    var lookupKeyIndex: Int = 0
    // The index of the contact's _ID value
    var idIndex: Int = 0
    // The lookup key from the Cursor
    var currentLookupKey: String? = null
    // The _ID value from the Cursor
    var currentId: Long = 0
    // A content URI pointing to the contact
    var selectedContactUri: Uri? = null
    ...
    /*
     * Once the user has selected a contact to edit,
     * this gets the contact's lookup key and _ID values from the
     * cursor and creates the necessary URI.
     */
    mCursor?.apply {
        // Gets the lookup key column index
        lookupKeyIndex = getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY)
        // Gets the lookup key value
        currentLookupKey = getString(lookupKeyIndex)
        // Gets the _ID column index
        idIndex = getColumnIndex(ContactsContract.Contacts._ID)
        currentId = getLong(idIndex)
        selectedContactUri = ContactsContract.Contacts.getLookupUri(currentId, mCurrentLookupKey)
    }

    // Creates a new Intent to edit a contact
    val editIntent = Intent(Intent.ACTION_EDIT).apply {
        /*
         * Sets the contact URI to edit, and the data type that the
         * Intent must match
         */
        setDataAndType(selectedContactUri, ContactsContract.Contacts.CONTENT_ITEM_TYPE)
    }

Java

    // The Cursor that contains the Contact row
    public Cursor mCursor;
    // The index of the lookup key column in the cursor
    public int lookupKeyIndex;
    // The index of the contact's _ID value
    public int idIndex;
    // The lookup key from the Cursor
    public String currentLookupKey;
    // The _ID value from the Cursor
    public long currentId;
    // A content URI pointing to the contact
    Uri selectedContactUri;
    ...
    /*
     * Once the user has selected a contact to edit,
     * this gets the contact's lookup key and _ID values from the
     * cursor and creates the necessary URI.
     */
    // Gets the lookup key column index
    lookupKeyIndex = mCursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY);
    // Gets the lookup key value
    currentLookupKey = mCursor.getString(lookupKeyIndex);
    // Gets the _ID column index
    idIndex = mCursor.getColumnIndex(ContactsContract.Contacts._ID);
    currentId = mCursor.getLong(idIndex);
    selectedContactUri =
            Contacts.getLookupUri(currentId, mCurrentLookupKey);
    ...
    // Creates a new Intent to edit a contact
    Intent editIntent = new Intent(Intent.ACTION_EDIT);
    /*
     * Sets the contact URI to edit, and the data type that the
     * Intent must match
     */
    editIntent.setDataAndType(selectedContactUri, ContactsContract.Contacts.CONTENT_ITEM_TYPE);

เพิ่ม Flag การนําทาง

ใน Android 4.0 (API เวอร์ชัน 14) ขึ้นไป ปัญหาในแอปรายชื่อติดต่อจะทําให้การนําทางไม่ถูกต้อง เมื่อแอปของคุณส่งคำขอแก้ไขไปยังแอปรายชื่อติดต่อ และผู้ใช้แก้ไขและบันทึก รายชื่อติดต่อ เมื่อคลิกกลับ ก็จะเห็นหน้าจอรายชื่อติดต่อ หากต้องการกลับไปที่แอปของคุณ ผู้ใช้จะต้องคลิกล่าสุดแล้วเลือกแอปของคุณ

หากต้องการแก้ปัญหานี้ใน Android 4.0.3 (API เวอร์ชัน 15) ขึ้นไป ให้เพิ่มคีย์ข้อมูลแบบขยาย finishActivityOnSaveCompleted ลงใน Intent โดยให้ค่าเป็น true Android เวอร์ชันก่อน Android 4.0 จะยอมรับคีย์นี้ แต่จะใช้งานไม่ได้ หากต้องการตั้งค่าข้อมูลแบบขยาย ให้ทําดังนี้

Kotlin

    // Sets the special extended data for navigation
    editIntent.putExtra("finishActivityOnSaveCompleted", true)

Java

    // Sets the special extended data for navigation
    editIntent.putExtra("finishActivityOnSaveCompleted", true);

เพิ่มข้อมูลแบบขยายอื่นๆ

หากต้องการเพิ่มข้อมูลเพิ่มเติมลงใน Intent ให้เรียกใช้ putExtra() ตามต้องการ คุณสามารถเพิ่มข้อมูลเพิ่มเติมสำหรับช่องติดต่อทั่วไปได้โดยใช้ค่าคีย์ที่ระบุไว้ใน Intents.Insert โปรดทราบว่า ไม่สามารถแก้ไขคอลัมน์ในตาราง ContactsContract.Contacts ได้ คอลัมน์เหล่านี้แสดงอยู่ในส่วนสรุปของข้อมูลอ้างอิง API สำหรับคลาส ContactsContract.Contacts ใต้ส่วนหัว "อัปเดต"

ส่ง Intent

สุดท้าย ให้ส่ง Intent ที่คุณสร้างขึ้น เช่น

Kotlin

    // Sends the Intent
    startActivity(editIntent)

Java

    // Sends the Intent
    startActivity(editIntent);

อนุญาตให้ผู้ใช้เลือกที่จะแทรกหรือแก้ไขโดยใช้ความตั้งใจ

คุณสามารถอนุญาตให้ผู้ใช้เลือกว่าจะแทรกผู้ติดต่อหรือแก้ไขผู้ติดต่อที่มีอยู่โดยการส่ง Intent ที่มีการดำเนินการ ACTION_INSERT_OR_EDIT ตัวอย่างเช่น แอปโปรแกรมรับส่งอีเมลอาจ อนุญาตให้ผู้ใช้เพิ่มอีเมลขาเข้าในรายชื่อติดต่อใหม่ หรือเพิ่มเป็นอีเมลสํารอง สำหรับรายชื่อติดต่อที่มีอยู่ ตั้งค่าประเภท MIME สำหรับ Intent นี้เป็น Contacts.CONTENT_ITEM_TYPE, แต่ไม่ได้ตั้งค่า URI ข้อมูล

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

Kotlin

    // Creates a new Intent to insert or edit a contact
    val intentInsertEdit = Intent(Intent.ACTION_INSERT_OR_EDIT).apply {
        // Sets the MIME type
        type = ContactsContract.Contacts.CONTENT_ITEM_TYPE
    }
    // Add code here to insert extended data, if desired

    // Sends the Intent with an request ID
    startActivity(intentInsertEdit)

Java

    // Creates a new Intent to insert or edit a contact
    Intent intentInsertEdit = new Intent(Intent.ACTION_INSERT_OR_EDIT);
    // Sets the MIME type
    intentInsertEdit.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
    // Add code here to insert extended data, if desired
    ...
    // Sends the Intent with an request ID
    startActivity(intentInsertEdit);