本課程說明如何使用 Intent
插入新聯絡人或修改聯絡人的資料。Intent
不會直接存取聯絡人供應程式,而是會啟動聯絡人應用程式,該應用程式會執行適當的 Activity
。針對本課程所述的修改動作,如果您在 Intent
中傳送擴充資料,系統會在啟動的 Activity
的 UI 中輸入這些資料。
建議您使用 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 參考資料的摘要區段,位於「Update」標題下方。
最後,請傳送意圖。系統隨即會顯示「聯絡人」應用程式編輯畫面。使用者完成編輯並儲存後,聯絡人應用程式就會顯示聯絡人清單。當使用者按一下「Back」,系統便會顯示您的應用程式。
建立意圖
如要編輯聯絡人,請呼叫 Intent(action)
來建立含有 ACTION_EDIT
動作的意圖。呼叫 setDataAndType()
即可將意圖的資料值設為聯絡人的 Contacts.CONTENT_LOOKUP_URI
,並將 MIME 類型設為 Contacts.CONTENT_ITEM_TYPE
MIME 類型。由於呼叫 setType()
會覆寫 Intent
的現有資料值,因此您必須同時設定資料和 MIME 類型。
如要取得聯絡人的 Contacts.CONTENT_LOOKUP_URI
,請使用聯絡人的 Contacts._ID
和 Contacts.LOOKUP_KEY
值做為引數來呼叫 Contacts.getLookupUri(id, lookupkey)
。
注意:聯絡人的 LOOKUP_KEY
值是擷取聯絡人時應使用的 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) 以上版本中,聯絡人應用程式發生問題會導致導覽錯誤。當應用程式傳送編輯意圖給聯絡人應用程式,而使用者按一下「返回」後就會看到聯絡人清單畫面,進行編輯和儲存聯絡人。如要返回應用程式,使用者必須按一下「Recents」,然後選擇您的應用程式。
如要在 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
資料表中的部分資料欄無法修改。這些資料欄會列在「Update」標題下方,類別 ContactsContract.Contacts
的 API 參考資料摘要部分。
傳送意圖
最後,請傳送您已建構的意圖。例如:
Kotlin
// Sends the Intent startActivity(editIntent)
Java
// Sends the Intent startActivity(editIntent);
允許使用者透過意圖選擇插入或編輯
您可以讓使用者選擇要插入聯絡人或編輯現有聯絡人,方法是傳送包含 ACTION_INSERT_OR_EDIT
動作的 Intent
。舉例來說,電子郵件用戶端應用程式可讓使用者將內送電子郵件地址新增至新聯絡人,或是將其新增為現有聯絡人的額外地址。將這個意圖的 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);