将所有合并的联系人Android分开

时间:2011-08-12 06:17:20

标签: android contacts android-contacts outlook

我正在使用Outlook Express创建蓝牙同步应用程序。所有的工作都做得非常好,但我还有一个小问题。当我将联系人从Outlook同步到Android时,它会合并具有相似名称的联系人。例如,如果我有两个名为“Najhi”和“Najhi Ullah”的联系人,那么在同步之后,它们将以Android名称“Najhi”合并到Android中。是否有任何解决方案以编程方式分离所有合并的联系人?

4 个答案:

答案 0 :(得分:4)

如果有人遇到同样的问题,我自己找到了解决方案,他们可以找到这篇文章。

  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 :(得分:1)

插入联系人本身时,您可以添加一个内容值 您可以将RawContacts.AGGREGATION_MODE设置为RawContacts.AGGREGATION_MODE_DISABLED

有关详细信息,请参阅: http://developer.android.com/reference/android/provider/ContactsContract.RawContacts.html

答案 2 :(得分:0)

接受的答案(https://stackoverflow.com/a/7063235/4957915)中的代码段确实完成了工作,但我发现它有2个问题。

1)我们正在为AggregationExceptions表创建不必要的条目。如果我们有1,000个原始联系人,那么我们最终将获得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不支持&#34;删除&#34;操作(https://developer.android.com/reference/android/provider/ContactsContract.AggregationExceptions.html)。

答案 3 :(得分:0)

来自najhi ullah答案的改进代码对我来说就像魅力一样。

    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();
        }
    }