使用意圖修改聯絡人

本課程將說明如何使用 Intent 插入新聯絡人或修改聯絡人的資料。您不必直接存取聯絡人供應程式, Intent 會啟動「聯絡人」應用程式,該應用程式會執行適當的 Activity。針對本課程所述的修改動作,如果您在 Intent 中傳送擴充資料,系統會將該資料輸入已啟動的 Activity 使用者介面。

建議使用 Intent 插入或更新單一聯絡人 修改聯絡人供應程式的方式,原因如下:

  • 這樣一來,您就不必花費時間和心力自行開發 UI 和程式碼。
  • 可避免導入因違反 聯絡人提供者的規則。
  • 可減少您需要要求的權限數量。您的應用程式不需要寫入聯絡人供應器的權限,因為它會將修改工作委派給已具備該權限的聯絡人應用程式。

使用意圖插入新聯絡人

您通常會希望在應用程式收到新資料時,允許使用者插入新聯絡人。舉例來說,餐廳評論應用程式可讓使用者在評論餐廳時,將餐廳新增為聯絡人。如要使用意圖執行這項操作,請使用盡可能多的資料建立意圖,然後將意圖傳送至聯絡人應用程式。

使用「聯絡人」應用程式插入聯絡人時,系統會將新的原始聯絡人插入聯絡人 提供者的 ContactsContract.RawContacts 表格。如有需要,聯絡人應用程式會在建立原始聯絡人時,提示使用者選擇要使用的帳戶類型和帳戶。如果原始聯絡人已存在,聯絡人應用程式也會通知使用者。使用者可以選擇取消插入,在這種情況下,系統不會建立聯絡人。如要進一步瞭解原始聯絡人,請參閱 Contacts Provider API 指南。

建立意圖

首先,請使用 Intents.Insert.ACTION 動作建立新的 Intent 物件。將 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);

如果您已經擁有聯絡人的詳細資料 (例如電話號碼或電子郵件地址),可以 以擴充資料的形式插入意圖中如果是鍵值,請使用 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 編輯現有聯絡人的功能,這個方法就很實用 已選擇一位興趣聯絡人。舉例來說,如果應用程式發現聯絡人有郵遞地址,但缺少郵遞區號,則可讓使用者選擇查詢郵遞區號,然後將其新增至聯絡人。

如要使用意圖編輯現有聯絡人,請採用類似以下的程序: 插入聯絡人按照「使用意圖插入新聯絡人」一節所述建立意圖,但請將聯絡人的 Contacts.CONTENT_LOOKUP_URI 和 MIME 類型 Contacts.CONTENT_ITEM_TYPE 新增至意圖。如果您想編輯已擁有的聯絡人詳細資料,可以將這些資料放入意圖的擴充資料中。請注意,有些 您無法使用意圖編輯名稱欄;這些資料欄會列在摘要中 ContactsContract.Contacts 類別的 API 參考資料一節 。

最後,傳送意圖。為了回應,聯絡人應用程式會顯示編輯畫面。當使用者 編輯完畢並儲存編輯內容後,「聯絡人」應用程式就會顯示聯絡人清單。使用者點選「返回」後,系統就會顯示您的應用程式。

建立意圖

如要編輯聯絡人,請呼叫 Intent(action) 來建立含有動作 ACTION_EDIT 的意圖。呼叫 setDataAndType() 即可將意圖的資料值設為聯絡人的 Contacts.CONTENT_LOOKUP_URI,並將 MIME 類型設為 Contacts.CONTENT_ITEM_TYPE MIME 類型。由於對 setType() 的呼叫會覆寫 Intent 的目前資料值,因此您必須同時設定資料和 MIME 類型。

如要取得聯絡人的Contacts.CONTENT_LOOKUP_URI,請撥打 將 Contacts.getLookupUri(id, lookupkey) 傳送給聯絡人的 Contacts._IDContacts.LOOKUP_KEY 值設為 引數。

注意:聯絡人的 LOOKUP_KEY的值為 您用來擷取聯絡人的 ID。即使供應商變更聯絡人的資料列 ID 以處理內部作業,此 ID 仍會保持不變。

下列程式碼片段說明如何建立意圖:

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

新增導覽標記

在 Android 4.0 (API 版本 14) 以上版本中,聯絡人應用程式的問題造成聯絡人應用程式錯誤 導覽。當應用程式將編輯意圖傳送至聯絡人應用程式,且使用者編輯並儲存聯絡人時,當他們點選「Back」時,就會看到聯絡人清單畫面。如要返回應用程式,他們必須點選「近期」並選擇應用程式。

如要在 Android 4.0.3 (API 版本 15) 以上版本中解決這個問題,請新增擴充套件 資料索引鍵 finishActivityOnSaveCompleted 傳送給意圖,值為 true。 Android 4.0 以下版本的 Android 裝置接受這個金鑰,但沒有任何作用。如要設定擴充資料,請按照下列步驟操作:

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」表格中的資料欄。 這些欄會列在 ContactsContract.Contacts 類別 API 參考資料的摘要部分,標題為「Update」。

傳送意圖

最後,請傳送您建構的意圖。例如:

Kotlin

    // Sends the Intent
    startActivity(editIntent)

Java

    // Sends the Intent
    startActivity(editIntent);

讓使用者選擇使用意圖插入或編輯

您可以讓使用者選擇要插入聯絡人,還是編輯現有聯絡人,方法是傳送 包含動作的Intent ACTION_INSERT_OR_EDIT。舉例來說,電子郵件用戶端應用程式 允許使用者將外來電子郵件地址新增為聯絡人,或將該地址新增為其他聯絡人 現有聯絡人的地址。將此意圖的 MIME 類型設為 Contacts.CONTENT_ITEM_TYPE,但不要設定資料 URI。

傳送此意圖時,「聯絡人」應用程式會顯示聯絡人清單。 使用者可以插入新聯絡人,或是選擇現有聯絡人進行編輯。 您新增至意圖的任何擴充資料欄位,都會填入出現的畫面。您可以使用 Intents.Insert 中指定的任何鍵值。下列程式碼片段說明如何建構並傳送意圖:

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