分离所有合并的联系人Android



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

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

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

当插入联系人本身时,您可以添加更多的内容值您可以设置RawContacts。AGGREGATION_MODE为RawContacts。AGGREGATION_MODE_DISABLED

详细信息请参见:http://developer.android.com/reference/android/provider/ContactsContract.RawContacts.html

接受的答案(https://stackoverflow.com/a/7063235/4957915)中的代码片段当然可以完成工作,但我看到了两个问题。

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)。

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

最新更新