Разделить все объединенные контакты Android - PullRequest
2 голосов
/ 12 августа 2011

Я создаю приложение синхронизации Bluetooth с Outlook Express. Вся работа была проделана фантастически хорошо, но у меня осталась одна маленькая проблема. Когда я синхронизирую свои контакты из Outlook в Android, он объединяет контакты с похожими именами. Например, если у меня есть два контакта «Наджи» и «Наджи Улла», то после синхронизации они будут объединены в Android под одним именем «Наджи». Есть ли решение для разделения всех слитых контактов программно?

Ответы [ 4 ]

4 голосов
/ 15 августа 2011

Я нашел решение самостоятельно, если у кого-то есть такая же проблема, он может найти этот пост.

  private void separate_merged_contacts(){
    Cursor cur1 = obj.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,new String[]{"_id"} , null, null,null);
    Cursor cur_raw;
    ArrayList<String> raw_contact_id = new ArrayList<String>();
    ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
    while (cur1.moveToNext()) {
        raw_contact_id.clear();
        ops.clear();
        for (int i = 0; i < cur1.getColumnCount(); i++) {
        cur_raw = obj.getContentResolver().query(ContactsContract.RawContacts.CONTENT_URI, new String[]{ContactsContract.RawContacts._ID}, ContactsContract.RawContacts.CONTACT_ID+"=?",new String[]{cur1.getString(cur1.getColumnIndex(ContactsContract.Contacts._ID))} , null);
        while(cur_raw.moveToNext()){
            for (int i = 0; i < cur_raw.getColumnCount(); i++) {
                raw_contact_id.add(cur_raw.getString(cur_raw.getColumnIndexOrThrow(ContactsContract.RawContacts._ID)));
            }
        }
        for(int i=0 ; i<raw_contact_id.size();i++){
            for(int j=0;j<raw_contact_id.size();j++)
                ops.add(ContentProviderOperation.newUpdate(ContactsContract.AggregationExceptions.CONTENT_URI)
                        .withValue(AggregationExceptions.TYPE,AggregationExceptions.TYPE_KEEP_SEPARATE)
                        .withValue(AggregationExceptions.RAW_CONTACT_ID1,Integer.parseInt(raw_contact_id.get(i)))
                        .withValue(AggregationExceptions.RAW_CONTACT_ID2,Integer.parseInt(raw_contact_id.get(j))).build());
                try {
                    obj.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        }
    }
}
1 голос
/ 22 ноября 2013

При вставке самого контакта вы можете добавить еще одно значение контента. Вы можете установить RawContacts.AGGREGATION_MODE как RawContacts.AGGREGATION_MODE_DISABLED

Подробнее см. http://developer.android.com/reference/android/provider/ContactsContract.RawContacts.html

0 голосов
/ 24 февраля 2018

Улучшенный код из ответа Наджхи Улла работал для меня как шарм.

    ContentResolver contentResolver = getContentResolver();
    if (contentResolver != null) {
        Cursor contactCursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, new String[]{"_id"}, null, null, null);
        if (contactCursor != null) {
            ArrayList<String> rawContactIds = new ArrayList<>();
            ArrayList<ContentProviderOperation> ops = new ArrayList<>();
            while (contactCursor.moveToNext()) {
                rawContactIds.clear();
                ops.clear();
                for (int i = 0; i < contactCursor.getColumnCount(); i++) {
                    Cursor cursorRawContact = contentResolver.query(ContactsContract.RawContacts.CONTENT_URI, new String[]{ContactsContract.RawContacts._ID}, ContactsContract.RawContacts.CONTACT_ID + "=?", new String[]{contactCursor.getString(contactCursor.getColumnIndex(ContactsContract.Contacts._ID))}, null);
                    if (cursorRawContact != null) {
                        while (cursorRawContact.moveToNext()) {
                            rawContactIds.add(cursorRawContact.getString(cursorRawContact.getColumnIndexOrThrow(ContactsContract.RawContacts._ID)));
                        }
                        for (String rawContactId : rawContactIds) {
                            for (String rawContactId2 : rawContactIds) {
                                ops.add(ContentProviderOperation.newUpdate(ContactsContract.AggregationExceptions.CONTENT_URI)
                                        .withValue(ContactsContract.AggregationExceptions.TYPE, ContactsContract.AggregationExceptions.TYPE_KEEP_SEPARATE)
                                        .withValue(ContactsContract.AggregationExceptions.RAW_CONTACT_ID1, Integer.parseInt(rawContactId))
                                        .withValue(ContactsContract.AggregationExceptions.RAW_CONTACT_ID2, Integer.parseInt(rawContactId2)).build());
                            }
                            try {
                                contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                        cursorRawContact.close();
                    }
                }
            }
            contactCursor.close();
        }
    }
0 голосов
/ 09 апреля 2017

Фрагмент кода в принятом ответе (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).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...