问题描述
我正在开发一个应用程序,在该应用程序中我应该能够访问所有联系人,能够更新或删除任何联系人中的号码。
我想删除联系人中的几个号码。我正在使用 batchOperations 来执行删除操作。
phone = ContactsContract.Data.RAW_CONTACT_ID + " = ? AND " +
ContactsContract.Data.MIMETYPE + " = ? AND " +
ContactsContract.CommonDataKinds.Phone._ID + " = ?";
String[] phoneArgs = new String[]{Integer.toString(rawContactId),ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE,String.valueOf(id)};
batchOperations.add(ContentProviderOperation.newDelete(Data.CONTENT_URI).withSelection(phone,phoneArgs).build());
this.mContext.getContentResolver().applyBatch("com.android.contacts",batchOperations);
batchOperations.clear();
我正在使用这部分代码从联系人中删除特定号码。使用调试器,对于示例删除操作,我发现值为:
raw_contact_id = 4093
id = 21579
这些值对应于样本联系人中一组号码中的特定号码(“+814444444444”)。(请参考下图)
但是号码仍然没有被删除。在过去的几个小时里,我一直试图弄清楚,但无法解决。请帮忙。
解决方法
您可以构建要删除的特定项目的 uri,而不是提供 selection + selectionArgs,如下所示:
fetch(`https://pokemonrevolution.net/spawns/land_spawns.json`)
.then((res) => res.json())
.then(data => data.filter((p) => p.Pokemon === "Pikachu"))
.then(data => {
var mapLength = 0,tierLength = 0,minLevelLength = 0,maxLevelLength = 0,memberOnlyLength = 0,itemLength = 0;
data.forEach(dataPoint => {
mapLength = (mapLength > dataPoint.Map.length) ? mapLength : dataPoint.Map.length;
tierLength = (tierLength > dataPoint.Tier.toString().length) ? tierLength : dataPoint.Tier.toString().length;
minLevelLength = (minLevelLength > dataPoint.MinLVL.toString().length) ? minLevelLength : dataPoint.MinLVL.toString().length;
maxLevelLength = (maxLevelLength > dataPoint.MaxLVL.toString().length) ? maxLevelLength : dataPoint.MaxLVL.toString().length;
if (dataPoint.MemberOnly) {
memberOnlyLength = (memberOnlyLength > "Yes") ? memberOnlyLength : 3
} else {
memberOnlyLength = (memberOnlyLength > "No") ? memberOnlyLength : 2
}
})
console.log(mapLength)
console.log(tierLength)
console.log(minLevelLength)
console.log(maxLevelLength)
console.log(memberOnlyLength)
console.log(itemLength)
data.map(dataPoint => {
dataPoint.Map = dataPoint.Map.padEnd(mapLength + 5)
dataPoint.Tier = dataPoint.Tier.toString().padEnd(tierLength + 5)
dataPoint.MinLVL = dataPoint.MinLVL.toString().padEnd(minLevelLength + 5)
dataPoint.MaxLVL = dataPoint.MaxLVL.toString().padEnd(maxLevelLength + 5)
if (dataPoint.MemberOnly) {
dataPoint.MemberOnly = "Yes".padEnd(memberOnlyLength + 5)
} else {
dataPoint.MemberOnly = "No".padEnd(memberOnlyLength + 5)
}
if (dataPoint.Item == null) {
dataPoint.Item = "-"
}
return dataPoint
})
totalString = "#Map".padEnd(mapLength + 5) + "Area " + "Rarity".padEnd(tierLength + 5) + "Min LVL".padEnd(minLevelLength + 5) + "Max LVL".padEnd(maxLevelLength + 5) + "Members Only".padEnd(memberOnlyLength + 5) + "Item" + "\n";
data.forEach(dataPoint => {
totalString += [dataPoint.Map,"Land ","Tier " + dataPoint.Tier,dataPoint.MinLVL,dataPoint.MaxLVL,dataPoint.MemberOnly,dataPoint.Item].join('') + "\n"
})
console.log(totalString)
})
其他一些注意事项:
- 始终检查
Uri phoneUri = ContentUris.withAppendedId(Data.CONTENT_URI,phoneId); batchOperations.add(ContentProviderOperation.newDelete(phoneUri).build());
的返回值,如果返回值为 false,则说明您的代码/权限存在问题。 - 使用常量
applyBatch
而不是硬编码的字符串“com.android.contacts”。
观察到的行为的另一个原因是电话“+814444444444”存储在聚合成单个联系人的多个 ContactsContract.AUTHORITY
上。
在这种情况下,即使您从 RawContact A 中正确删除了该行,联系人配置文件仍会从 RawContact B 中获取号码。
当安装了某些应用(例如 RawContacts
)时,电话号码尤其如此,这些应用倾向于将联系人的电话号码复制到他们自己帐户下的单独 Whatsapp
。
如果这是问题所在,您需要从持有该电话的所有联系人的 RawContact
中删除电话号码。
编辑
以下是转储属于特定联系人的所有电话号码以及保存它们的原始联系人的方法:
RawContacts
另外,请注意 String selection = Data.CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?";
String[] selectionArgs = new String[] { contactId.toString(),Phone.CONTENT_ITEM_TYPE };
String[] projection = new String[] { Data.CONTACT_ID,Data.RAW_CONTACT_ID,Data.DATA1 };
Cursor cur = getContentResolver().query(Data.CONTENT_URI,projection,selection,selectionArgs,projection);
DatabaseUtils.dumpCursor(cur);
不是整数,而是一个长整数。