Фрагмент кода в принятом ответе (https://stackoverflow.com/a/7063235/4957915), безусловно, выполняет свою работу, но я вижу 2 проблемы с ним.
1) Мы создаем ненужные записи в таблице AggregationExceptions. Если у нас будет 1000 необработанных контактов, мы получим 1 000 000 записей. Любые телефоны, произведенные за последние несколько лет, должны быть в состоянии справиться с этим, не пропуская ритм, но это все еще пустая трата.
2) Что еще более важно, после разделения контактов вы можете или не сможете снова объединить эти контакты, в зависимости от того, как введены записи. Единственный способ решить эту проблему - удалить неустранимый контакт и создать его заново.
Лучшим подходом является обновление только существующих записей AggregationExceptions.
ArrayList<ContentProviderOperation> operations = new ArrayList<>();
// Get all entries in AggregationExceptions.
cursor = mContext.getContentResolver().query(
ContactsContract.AggregationExceptions.CONTENT_URI,
null, null, null, null);
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
columnIndex = cursor.getColumnIndex(ContactsContract.AggregationExceptions.TYPE);
int type = cursor.getInt(columnIndex);
columnIndex = cursor.getColumnIndex(ContactsContract.AggregationExceptions.RAW_CONTACT_ID1);
long rawContactId1 = cursor.getLong(columnIndex);
columnIndex = cursor.getColumnIndex(ContactsContract.AggregationExceptions.RAW_CONTACT_ID2);
long rawContactId2 = cursor.getLong(columnIndex);
ContentProviderOperation.Builder builder = ContentProviderOperation.newUpdate(
ContactsContract.AggregationExceptions.CONTENT_URI);
builder.withValue(ContactsContract.AggregationExceptions.TYPE,
ContactsContract.AggregationExceptions.TYPE_KEEP_SEPARATE); // <--
builder.withValue(ContactsContract.AggregationExceptions.RAW_CONTACT_ID1, rawContactId1);
builder.withValue(ContactsContract.AggregationExceptions.RAW_CONTACT_ID2, rawContactId2);
operations.add(builder.build());
}
cursor.close();
if (!operations.isEmpty()) {
try {
mContext.getContentResolver().applyBatch(ContactsContract.AUTHORITY, operations);
} catch (Exception e) {
e.printStackTrace();
}
}
Обратите внимание, что Android выполняет объединение контактов (т.е. объединение) автоматически, когда контакты похожи друг на друга: например, 2 контакта с одинаковым отображаемым именем. В этом случае не будет записи AggregationExceptions для этих объединенных контактов. Это автоматически.
Если вы объединяете 2 контакта вручную с помощью приложения Контакты, то новая запись AggregationExceptions будет добавлена с помощью TYPE_KEEP_TOGETHER, но ничего не будет изменено для самих необработанных контактов. Если вы вручную разделите объединенные контакты, то запись с TYPE_KEEP_TOGETHER будет помечена как удаленная, и будет добавлена новая запись с TYPE_KEEP_SEPARATE. Помните, что после добавления записи она будет существовать до тех пор, пока не будет удален соответствующий контакт, поскольку AggregationExceptions не поддерживает операцию удаления (https://developer.android.com/reference/android/provider/ContactsContract.AggregationExceptions.html).