我正在将我的应用程序与 Android 默认联系人应用程序集成。我想在每个联系人详细信息中显示一个选项“xyz using MyApp”。我可以在“帐户”部分中看到我的应用程序,其中包含同步联系人的选项,但仍然是我的应用程序不会与现有联系人合并,而是创建一个新联系人并合并到其中。
performSync()方法
private static void addContact(ContentResolver contentResolver,int name, int phoneNumber) {
Log.i("XYZ", "Adding contact: " + name);
ArrayList<ContentProviderOperation> operationList = new ArrayList<ContentProviderOperation>();
//Create our RawContact
ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI);
builder.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, name);
builder.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, "com.example.xyz.myapplication");
builder.withValue(ContactsContract.RawContacts.SYNC1, phoneNumber);
operationList.add(builder.build());
//Create a Data record of common type 'StructuredName' for our RawContact
builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
builder.withValueBackReference(ContactsContract.CommonDataKinds.StructuredName.RAW_CONTACT_ID, 0);
builder.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
builder.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name);
operationList.add(builder.build());
//Create a Data record of custom type "vnd.android.cursor.item/vnd.com.example.xyz.myapplication.profile" to display a link to the Last.fm profile
builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
builder.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0);
builder.withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/vnd.com.example.xyz.myapplication.profile");
builder.withValue(ContactsContract.Data.DATA1, phoneNumber);
builder.withValue(ContactsContract.Data.DATA2, "Last.fm Profile");
builder.withValue(ContactsContract.Data.DATA3, "View profile");
operationList.add(builder.build());
try {
contentResolver.applyBatch(ContactsContract.AUTHORITY, operationList);
} catch (Exception e) {
Log.e("XYZ", "Something went wrong during creation! " + e);
e.printStackTrace();
}
}
最佳答案
在您的addContact
代码中,您缺少告诉Contacts DB
将新的原始联系人加入现有联系人的部分,因此该联系人现在将包含您的在联系人应用程序中打开该联系人时,将显示 raw-contact 和您的应用程序特定行。
查看此答案,了解如何将 RawContact
加入现有联系人:why won't contacts aggregate?
您可能需要将一些 RawContact ID
传递给您的 addContact 方法,以便它能够将两者连接在一起。
更新
我们不要将聚合操作与 RawContact
插入操作一起应用,而是尝试分成两个 applyBatch
调用,同时,让我们将新的原始联系人与 < strong>所有现有原始联系人,而不仅仅是其中之一。
尝试以下代码,确保将现有的 contact-id(不是原始联系人 ID)和新的原始联系人 ID 传递给它。
private void joinIntoExistingContact(long existingContactId, long newRawContactId) {
// get all existing raw-contact-ids that belong to the contact-id
List<Long> existingRawIds = new ArrayList<>();
Cursor cur = getContentResolver().query(RawContacts.CONTENT_URI, new String[] { RawContacts._ID }, RawContacts.CONTACT_ID + "=" + existingContactId, null, null);
while (cur.moveToNext()) {
existingRawIds.add(cur.getLong(0));
}
cur.close();
Log.i("Join", "Found " + existingRawIds.size() + " raw-contact-ids");
List<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
// go over all existing raw ids, and join with our new one
for (Long existingRawId : existingRawIds) {
Builder builder = ContentProviderOperation.newUpdate(AggregationExceptions.CONTENT_URI);
builder.withValue(AggregationExceptions.TYPE, AggregationExceptions.TYPE_KEEP_TOGETHER);
builder.withValue(AggregationExceptions.RAW_CONTACT_ID1, newRawContactId);
builder.withValue(AggregationExceptions.RAW_CONTACT_ID2, existingRawId);
ops.add(builder.build());
}
contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
}
附注
不要打开两个duplicate questions ,一个就够了。
另一更新
您似乎对 ID 感到有些困惑。
有Data
ID、RawContact
ID 和Contact
ID。
CommonDataKinds.Phone._ID
将返回一个 Data
ID,标识数据表中存储该电话号码的特定行。
您也可以从 Phone
表中获取其他 ID,请使用:
CommonDataKinds.Phone.RAW_CONTACT_ID
CommonDataKinds.Phone.CONTACT_ID
您可以在这里阅读更多内容: https://stackoverflow.com/a/50084029/819355
关于android - 创建新联系人而不是更新现有联系人,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52905223/