Android 使用Intent修改聯(lián)系人信息

2018-08-02 17:46 更新

編寫(xiě):spencer198711 - 原文:http://developer.android.com/training/contacts-provider/modify-data.html

這一課介紹如何使用Intent去插入一個(gè)新的聯(lián)系人或者修改聯(lián)系人的數(shù)據(jù)。我們不是直接訪(fǎng)問(wèn)Contacts Provider,而是通過(guò)Intent啟動(dòng)Contacts應(yīng)用去運(yùn)行適當(dāng)?shù)?a rel="external nofollow" target="_blank" target="_blank">Activity。對(duì)于這一課中描述的數(shù)據(jù)修改行為,如果你向Intent發(fā)送擴(kuò)展的數(shù)據(jù),它會(huì)自動(dòng)填充進(jìn)啟動(dòng)的Activity頁(yè)面中。

使用Intent去插入或者更新一個(gè)聯(lián)系人是比較推薦的修改Contacts Provider的做法。原因如下:

  • 節(jié)省了我們自行開(kāi)發(fā)UI和編寫(xiě)代碼的時(shí)間和精力。
  • 避免了由于不按照Contacts Provider的規(guī)則去修改而產(chǎn)生的錯(cuò)誤。
  • 減少應(yīng)用需要申請(qǐng)的權(quán)限數(shù)量。因?yàn)槲覀兊膽?yīng)用把修改行為委托給已經(jīng)擁有寫(xiě)Contacts Provider權(quán)限的Contacts應(yīng)用,所以我們的應(yīng)用不需要再去申請(qǐng)這個(gè)權(quán)限,。

使用Intent插入新的聯(lián)系人

當(dāng)我們的應(yīng)用接收到新的數(shù)據(jù)時(shí),我們通常會(huì)允許用戶(hù)去插入一個(gè)新的聯(lián)系人。例如,一個(gè)餐館評(píng)論應(yīng)用可以允許用戶(hù)在評(píng)論餐館的時(shí)候,把這個(gè)餐館添加為一個(gè)聯(lián)系人。可以使用Intent去做這個(gè)任務(wù),使用我們擁有的盡可能多的數(shù)據(jù)去創(chuàng)建對(duì)應(yīng)的Intent,然后發(fā)送這個(gè)Intent到Contacts應(yīng)用。

使用Contacts應(yīng)用去插入一個(gè)聯(lián)系人將會(huì)向Contacts Provider中的ContactsContract.RawContacts表中插入一個(gè)原始聯(lián)系人。必要的情況下,在創(chuàng)建原始聯(lián)系人的時(shí)候,Contacts應(yīng)用將會(huì)提示用戶(hù)選擇賬戶(hù)類(lèi)型和要使用的賬戶(hù)。如果聯(lián)系人已經(jīng)存在,Contacts應(yīng)用也會(huì)告知用戶(hù)。用戶(hù)將會(huì)有取消插入的選項(xiàng),在這種情況下不會(huì)有聯(lián)系人被創(chuàng)建。想要知道更多關(guān)于原始聯(lián)系人的信息,請(qǐng)參閱Contacts Provider的API指導(dǎo)。

創(chuàng)建一個(gè)Intent

利用Intents.Insert.ACTION創(chuàng)建一個(gè)新的Intent對(duì)象,并設(shè)置其MIME類(lèi)型為RawContacts.CONTENT_TYPE。例如:

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

如果我們已經(jīng)獲得了此聯(lián)系人的詳細(xì)信息,比如說(shuō)電話(huà)號(hào)碼或者email地址,那么我們可以把它們作為擴(kuò)展數(shù)據(jù)添加到Intent中。對(duì)于鍵值,需要使用Intents.Insert中對(duì)應(yīng)的常量。Contacts應(yīng)用將會(huì)在插入界面顯示這些數(shù)據(jù),以便用戶(hù)作進(jìn)一步的數(shù)據(jù)編輯和數(shù)據(jù)添加。

/* Assumes EditText fields in your UI contain an email address
 * and a phone number.
 *
 */
private EditText mEmailAddress = (EditText) findViewById(R.id.email);
private EditText mPhoneNumber = (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(Intents.Insert.EMAIL, mEmailAddress.getText())
/*
 * In this example, sets the email type to be a work email.
 * You can set other email types as necessary.
 */
      .putExtra(Intents.Insert.EMAIL_TYPE, CommonDataKinds.Email.TYPE_WORK)
// Inserts a phone number
      .putExtra(Intents.Insert.PHONE, mPhoneNumber.getText())
/*
 * In this example, sets the phone type to be a work phone.
 * You can set other phone types as necessary.
 */
      .putExtra(Intents.Insert.PHONE_TYPE, Phone.TYPE_WORK);

一旦我們創(chuàng)建好Intent,調(diào)用startActivity()將其發(fā)送到Contacts應(yīng)用。

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

這個(gè)調(diào)用將會(huì)打開(kāi)Contacts應(yīng)用的界面,并允許用戶(hù)進(jìn)入一個(gè)新的聯(lián)系人。這個(gè)聯(lián)系人的賬戶(hù)類(lèi)型和賬戶(hù)名字列在屏幕的上方。一旦用戶(hù)輸入數(shù)據(jù)并點(diǎn)擊確定,Contacts應(yīng)用的聯(lián)系人列表則會(huì)顯示出來(lái)。用戶(hù)可以點(diǎn)擊Back鍵返回到我們自己創(chuàng)建的應(yīng)用。

使用Intent編輯已經(jīng)存在的聯(lián)系人

如果用戶(hù)已經(jīng)選擇了一個(gè)感興趣的聯(lián)系人,使用Intent去編輯這個(gè)已存在的聯(lián)系人會(huì)很有用。例如,一個(gè)用來(lái)查找擁有郵政地址但是缺少郵政編碼的聯(lián)系人的應(yīng)用,可以給用戶(hù)提供查找郵政編碼的選項(xiàng),然后把找到的郵政編碼添加到這個(gè)聯(lián)系人中。

使用Intent編輯已經(jīng)存在的聯(lián)系人,同插入一個(gè)聯(lián)系人的步驟類(lèi)似。像前面介紹的使用Intent插入新的聯(lián)系人創(chuàng)建一個(gè)Intent,但是需要給這個(gè)Intent添加對(duì)應(yīng)聯(lián)系人的Contacts.CONTENT_LOOKUP_URI和MIME類(lèi)型Contacts.CONTENT_ITEM_TYPE。如果想要使用已經(jīng)擁有的詳情信息編輯這個(gè)聯(lián)系人,我們需要把這些數(shù)據(jù)放到Intent的擴(kuò)展數(shù)據(jù)中。同時(shí)注意有些列是不能使用Intent編輯的,這些不可編輯的列在ContactsContract.Contacts 摘要部分“Update”標(biāo)題下有列出。

最后,發(fā)送這個(gè)Intent。Contacts應(yīng)用會(huì)顯示一個(gè)編輯界面作為回應(yīng)。當(dāng)用戶(hù)編輯完成并保存,Contacts應(yīng)用會(huì)顯示一個(gè)聯(lián)系人列表。當(dāng)用戶(hù)點(diǎn)擊Back,我們自己的應(yīng)用會(huì)出現(xiàn)。

創(chuàng)建Intent

為了能夠編輯一個(gè)聯(lián)系人,需要調(diào)用Intent(action)去創(chuàng)建一個(gè)擁有ACTION_EDIT行為的Intent。調(diào)用setDataAndType()去設(shè)置這個(gè)Intent要編輯的聯(lián)系人的Contacts.CONTENT_LOOKUP_URI和MIME類(lèi)型Contacts.CONTENT_ITEM_TYPE。因?yàn)檎{(diào)用setType()會(huì)重寫(xiě)Intent當(dāng)前的數(shù)據(jù),所以我們必須同時(shí)設(shè)置數(shù)據(jù)和MIME類(lèi)型。

為了得到聯(lián)系人的Contacts.CONTENT_LOOKUP_URI,需要調(diào)用Contacts.getLookupUri(id, lookupkey)方法,該方法的參數(shù)分別是聯(lián)系人的Contacts._ID和Contacts.LOOKUP_KEY。

以下的代碼片段展示了如何創(chuàng)建這個(gè)Intent:

// The Cursor that contains the Contact row
    public Cursor mCursor;
    // The index of the lookup key column in the cursor
    public int mLookupKeyIndex;
    // The index of the contact's _ID value
    public int mIdIndex;
    // The lookup key from the Cursor
    public String mCurrentLookupKey;
    // The _ID value from the Cursor
    public long mCurrentId;
    // A content URI pointing to the contact
    Uri mSelectedContactUri;
    ...
    /*
     * 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
    mLookupKeyIndex = mCursor.getColumnIndex(Contacts.LOOKUP_KEY);
    // Gets the lookup key value
    mCurrentLookupKey = mCursor.getString(mLookupKeyIndex);
    // Gets the _ID column index
    mIdIndex = mCursor.getColumnIndex(Contacts._ID);
    mCurrentId = mCursor.getLong(mIdIndex);
    mSelectedContactUri =
            Contacts.getLookupUri(mCurrentId, 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(mSelectedContactUri,Contacts.CONTENT_ITEM_TYPE);

添加導(dǎo)航標(biāo)志

在Android 4.0(API版本14)和更高的版本,Contacts應(yīng)用中的一個(gè)問(wèn)題會(huì)導(dǎo)致錯(cuò)誤的頁(yè)面導(dǎo)航。我們的應(yīng)用發(fā)送一個(gè)編輯聯(lián)系人的Intent到Contacts應(yīng)用,用戶(hù)編輯并保存這個(gè)聯(lián)系人,當(dāng)用戶(hù)點(diǎn)擊Back鍵的時(shí)候會(huì)看到聯(lián)系人列表頁(yè)面。用戶(hù)需要點(diǎn)擊最近使用的應(yīng)用,然后選擇我們的應(yīng)用,才能返回到我們自己的應(yīng)用。

要在Android 4.0.3(API版本15)及以后的版本解決此問(wèn)題,需要添加finishActivityOnSaveCompleted擴(kuò)展數(shù)據(jù)參數(shù)到這個(gè)Intent,并將它的值設(shè)置為true。Android 4.0之前的版本也能夠接受這個(gè)參數(shù),但是不起作用。為了設(shè)置擴(kuò)展數(shù)據(jù),請(qǐng)按照以下方式去做:

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

添加其他的擴(kuò)展數(shù)據(jù)

對(duì)Intent添加額外的擴(kuò)展數(shù)據(jù),需要調(diào)用putExtra()??梢詾槌R?jiàn)的聯(lián)系人數(shù)據(jù)字段添加擴(kuò)展數(shù)據(jù),這些常見(jiàn)字段的key值可以從Intents.Insert API參考文檔中查到。記住ContactsContract.Contacts表中有些列是不能編輯的,這些列在ContactsContract.Contacts的摘要部分“Update”標(biāo)題下有列出。

發(fā)送Intent

最后,發(fā)送我們已經(jīng)構(gòu)建好的Intent。例如:

    // Sends the Intent
    startActivity(editIntent);

使用Intent讓用戶(hù)去選擇是插入還是編輯聯(lián)系人

我們可以通過(guò)發(fā)送帶有ACTION_INSERT_OR_EDIT行為的Intent,讓用戶(hù)去選擇是插入聯(lián)系人還是編輯已有的聯(lián)系人。例如,一個(gè)email客戶(hù)端應(yīng)用會(huì)允許用戶(hù)添加一個(gè)收件地址到新的聯(lián)系人,或者僅僅作為額外的郵件地址添加到已有的聯(lián)系人。需要為這個(gè)Intent設(shè)置MIME類(lèi)型Contacts.CONTENT_ITEM_TYPE,但是不需要設(shè)置數(shù)據(jù)URI。

當(dāng)我們發(fā)送這個(gè)Intent后,Contacts應(yīng)用會(huì)展示一個(gè)聯(lián)系人列表。用戶(hù)可以選擇是插入一個(gè)新的聯(lián)系人還是挑選一個(gè)存在的聯(lián)系人去編輯。任何添加到Intent中的擴(kuò)展數(shù)據(jù)字段都會(huì)填充在界面上。我們可以使用任何在Intents.Insert中指定的的key值。以下的代碼片段展示了如何構(gòu)建和發(fā)送這個(gè)Intent:

// 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(Contacts.CONTENT_ITEM_TYPE);
    // Add code here to insert extended data, if desired
    ...
    // Sends the Intent with an request ID
    startActivity(intentInsertEdit);


以上內(nèi)容是否對(duì)您有幫助:
在線(xiàn)筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)