我正在用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();
}
}