![](/img/trans.png)
[英]ANDROID: How do I filter a list of Contacts with a CursorLoader based on a list of standardized phone numbers
[英]How can I update the phone numbers of contacts in Android Studios
我是使用 android studio 開發應用程序的新手,我決定制作一個應用程序來編輯我的手機聯系人的電話號碼,作為我的第一個測試應用程序。
我使用一個類來獲取有關我手機上所有聯系人的信息,然后我創建了一個列表視圖,其中顯示了聯系人的姓名、ID、頭像和注冊的電話號碼。
該信息是從 ContactsContract.Contacts 表中獲取的。 到目前為止,這一切正常。
但是現在我必須編輯所有聯系人的電話號碼,但我不知道該怎么做。 我一直在瀏覽 Android 開發人員文檔,但找不到任何可以幫助我的東西。 在這種情況下,我不想使用 Intent。
我有這個用於獲取所有聯系人信息的 kotlin 類是這樣的:
@file:Suppress("unused")
package com.example.uimx
import android.Manifest
import android.content.ContentUris
import android.content.Context
import android.net.Uri
import android.provider.ContactsContract
import androidx.annotation.RequiresPermission
@RequiresPermission(Manifest.permission.READ_CONTACTS)
fun Context.isContactExists(
phoneNumber: String
): Boolean {
val lookupUri = Uri.withAppendedPath(
ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
Uri.encode(phoneNumber)
)
val projection = arrayOf(
ContactsContract.PhoneLookup._ID,
ContactsContract.PhoneLookup.NUMBER,
ContactsContract.PhoneLookup.DISPLAY_NAME
)
contentResolver.query(lookupUri, projection, null, null, null).use {
return (it?.moveToFirst() == true)
}
}
@RequiresPermission(Manifest.permission.READ_CONTACTS)
@JvmOverloads
fun Context.retrieveAllContacts(
searchPattern: String = "",
retrieveAvatar: Boolean = true,
limit: Int = -1,
offset: Int = -1
): List<ContactData> {
val result: MutableList<ContactData> = mutableListOf()
contentResolver.query(
ContactsContract.Contacts.CONTENT_URI,
CONTACT_PROJECTION,
if (searchPattern.isNotBlank()) "${ContactsContract.Contacts.DISPLAY_NAME_PRIMARY} LIKE '%?%'" else null,
if (searchPattern.isNotBlank()) arrayOf(searchPattern) else null,
if (limit > 0 && offset > -1) "${ContactsContract.Contacts.DISPLAY_NAME_PRIMARY} ASC LIMIT $limit OFFSET $offset"
else ContactsContract.Contacts.DISPLAY_NAME_PRIMARY + " ASC"
)?.use {
if (it.moveToFirst()) {
do {
val contactId = it.getLong(it.getColumnIndex(CONTACT_PROJECTION[0]))
val name = it.getString(it.getColumnIndex(CONTACT_PROJECTION[2])) ?: ""
val hasPhoneNumber = it.getString(it.getColumnIndex(CONTACT_PROJECTION[3])).toInt()
val phoneNumber: List<String> = if (hasPhoneNumber > 0) {
retrievePhoneNumber(contactId)
} else mutableListOf()
val avatar = if (retrieveAvatar) retrieveAvatar(contactId) else null
result.add(ContactData(contactId, name, phoneNumber, avatar))
} while (it.moveToNext())
}
}
return result
}
private fun Context.retrievePhoneNumber(contactId: Long): List<String> {
val result: MutableList<String> = mutableListOf()
contentResolver.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
"${ContactsContract.CommonDataKinds.Phone.CONTACT_ID} =?",
arrayOf(contactId.toString()),
null
)?.use {
if (it.moveToFirst()) {
do {
result.add(it.getString(it.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)))
} while (it.moveToNext())
}
}
return result
}
private fun Context.retrieveAvatar(contactId: Long): Uri? {
return contentResolver.query(
ContactsContract.Data.CONTENT_URI,
null,
"${ContactsContract.Data.CONTACT_ID} =? AND ${ContactsContract.Data.MIMETYPE} = '${ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE}'",
arrayOf(contactId.toString()),
null
)?.use {
if (it.moveToFirst()) {
val contactUri = ContentUris.withAppendedId(
ContactsContract.Contacts.CONTENT_URI,
contactId
)
Uri.withAppendedPath(
contactUri,
ContactsContract.Contacts.Photo.CONTENT_DIRECTORY
)
} else null
}
}
private val CONTACT_PROJECTION = arrayOf(
ContactsContract.Contacts._ID,
ContactsContract.Contacts.LOOKUP_KEY,
ContactsContract.Contacts.DISPLAY_NAME_PRIMARY,
ContactsContract.Contacts.HAS_PHONE_NUMBER
)
data class ContactData(
val contactId: Long,
val name: String,
val phoneNumber: List<String>,
val avatar: Uri?
)
我准備了一個按鈕,用於接收單擊事件並調用一個函數,該函數將使用腳本替換所有聯系人的所有電話號碼,為我將為每個聯系人定義的新電話號碼。
我有我在互聯網上獲得的下一個代碼,但我無法讓它在我的應用程序中工作。
private int updateContactPhoneByID(long rawContactId)
{
int ret = 0;
ContentResolver contentResolver = getContentResolver();
// Update data table phone number use contact raw contact id.
if(rawContactId > -1) {
// Update mobile phone number.
updatePhoneNumber(contentResolver, rawContactId, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE, "66666666666666");
// Update work mobile phone number.
updatePhoneNumber(contentResolver, rawContactId, ContactsContract.CommonDataKinds.Phone.TYPE_WORK_MOBILE, "8888888888888888");
// Update home phone number.
updatePhoneNumber(contentResolver, rawContactId, ContactsContract.CommonDataKinds.Phone.TYPE_HOME, "99999999999999999");
ret = 1;
}else
{
ret = 0;
}
return ret;
}
/* Update phone number with raw contact id and phone type.*/
private void updatePhoneNumber(ContentResolver contentResolver, long rawContactId, int phoneType, String newPhoneNumber)
{
// Create content values object.
ContentValues contentValues = new ContentValues();
// Put new phone number value.
contentValues.put(ContactsContract.CommonDataKinds.Phone.NUMBER, newPhoneNumber);
// Create query condition, query with the raw contact id.
StringBuffer whereClauseBuf = new StringBuffer();
// Specify the update contact id.
whereClauseBuf.append(ContactsContract.Data.RAW_CONTACT_ID);
whereClauseBuf.append("=");
whereClauseBuf.append(rawContactId);
// Specify the row data mimetype to phone mimetype( vnd.android.cursor.item/phone_v2 )
whereClauseBuf.append(" and ");
whereClauseBuf.append(ContactsContract.Data.MIMETYPE);
whereClauseBuf.append(" = '");
String mimetype = ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE;
whereClauseBuf.append(mimetype);
whereClauseBuf.append("'");
// Specify phone type.
whereClauseBuf.append(" and ");
whereClauseBuf.append(ContactsContract.CommonDataKinds.Phone.TYPE);
whereClauseBuf.append(" = ");
whereClauseBuf.append(phoneType);
// Update phone info through Data uri.Otherwise it may throw java.lang.UnsupportedOperationException.
Uri dataUri = ContactsContract.Data.CONTENT_URI;
// Get update data count.
int updateCount = contentResolver.update(dataUri, contentValues, whereClauseBuf.toString(), null);
}
如何使上述腳本工作以使用我擁有的信息更新正確的聯系表。
我認為您對 contactId 和 rawContactId 有混淆。
當您從設備讀取所有聯系人時,您將獲得該聯系人的contactId
,但您嘗試使用的updateContactPhoneByID
方法需要一個不同的rawContactId
。
簡而言之, ContactsContract.Contacts
表中的每個Contact
RawContacts
多個RawContacts
組成,每個Contact
通常由某個不同的應用程序或帳戶同步(例如,一個來自您的個人 Google 帳戶的 RawContact,另一個來自您的工作 Google 帳戶的 RawContact,另一個來自 Whatsapp ,以及來自 Yahoo 的一個),所有這些RawContacts
的詳細信息都加入以構成一個單一的聯系人配置文件。
我不確定您希望編輯如何工作,如果聯系人有多個電話號碼,您是想用一個新電話號碼替換所有這些電話,還是允許用戶在您的編輯屏幕中鍵入多個電話?
無論如何,這里有一個小的 kotlin 函數,它接受一個 contactId 和一個現有的電話號碼 X,並用一個新號碼替換那個單一號碼。 我希望你能適應你的需要。
private fun updatePhone(contactId:Long, existingNumber:String, newNumber:String) {
val contentValues = ContentValues()
contentValues.put(Phone.NUMBER, newNumber)
val where = Data.CONTACT_ID + "=?" + " AND " + Data.MIMETYPE + "=?" + " AND " + Phone.NUMBER + "=?"
val whereArgs = arrayOf<String>((contactId).toString(), Phone.CONTENT_ITEM_TYPE, existingNumber)
contentResolver.update(Data.CONTENT_URI, contentValues, where, whereArgs)
}
請注意, existingNumber
參數必須與 ContactsContract DB 中的字符串完全匹配。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.