浏览代码

Fix Sort Contact
Avoid duplicate contacts

alejandro 7 年之前
父节点
当前提交
d1f7e2aa5f

+ 51 - 2
src/main/java/com/owncloud/android/services/ContactsImportJob.java

@@ -21,14 +21,22 @@
 
 package com.owncloud.android.services;
 
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.ContactsContract;
 import android.support.annotation.NonNull;
 
 import com.evernote.android.job.Job;
 import com.evernote.android.job.util.support.PersistableBundleCompat;
 import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.ui.fragment.contactsbackup.ContactListFragment;
 
 import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.TreeMap;
 
 import ezvcard.Ezvcard;
 import ezvcard.VCard;
@@ -62,9 +70,30 @@ public class ContactsImportJob extends Job {
         try {
             ContactOperations operations = new ContactOperations(getContext(), accountName, accountType);
             vCards.addAll(Ezvcard.parse(file).all());
+            Collections.sort(vCards, new ContactListFragment.VCardComparator());
+            Cursor cursor = getContext().getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null,
+                    null, null, null);
 
-            for (int i = 0; i < intArray.length; i++ ){
-                operations.insertContact(vCards.get(intArray[i]));
+            TreeMap<VCard, Long> ownContactList = new TreeMap<>(new ContactListFragment.VCardComparator());
+            if (cursor != null && cursor.getCount() > 0) {
+                cursor.moveToFirst();
+                for (int i = 0; i < cursor.getCount(); i++) {
+                    VCard vCard = getContactFromCursor(cursor);
+                    if (vCard != null) {
+                        ownContactList.put(vCard, cursor.getLong(cursor.getColumnIndex("NAME_RAW_CONTACT_ID")));
+                    }
+                    cursor.moveToNext();
+                }
+            }
+
+
+            for (int i = 0; i < intArray.length; i++) {
+                VCard vCard = vCards.get(intArray[i]);
+                if (!ownContactList.containsKey(vCard)) {
+                    operations.insertContact(vCard);
+                } else {
+                    operations.updateContact(vCard, ownContactList.get(vCard));
+                }
             }
         } catch (Exception e) {
             Log_OC.e(TAG, e.getMessage());
@@ -72,4 +101,24 @@ public class ContactsImportJob extends Job {
 
         return Result.SUCCESS;
     }
+
+    private VCard getContactFromCursor(Cursor cursor) {
+        String lookupKey = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
+        Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);
+        VCard vCard = null;
+        try {
+            InputStream inputStream = getContext().getContentResolver().openInputStream(uri);
+            ArrayList<VCard> vCardList = new ArrayList<>();
+            vCardList.addAll(Ezvcard.parse(inputStream).all());
+            if (vCardList.size() > 0) {
+                vCard = vCardList.get(0);
+            }
+
+        } catch (IOException e) {
+            Log_OC.d(TAG, e.getMessage());
+        }
+        return vCard;
+    }
+
+
 }

+ 18 - 1
src/main/java/com/owncloud/android/ui/fragment/contactsbackup/ContactListFragment.java

@@ -31,6 +31,7 @@ import android.content.IntentFilter;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Handler;
 import android.provider.ContactsContract;
@@ -179,7 +180,6 @@ public class ContactListFragment extends FileFragment {
                             } else {
                                 return -1;
                             }
-
                         }
                     }
                 });
@@ -492,6 +492,23 @@ public class ContactListFragment extends FileFragment {
             }
         }
     }
+
+    public static class VCardComparator implements Comparator<VCard> {
+        @Override
+        public int compare(VCard o1, VCard o2) {
+            if (o1.getFormattedName() != null && o2.getFormattedName() != null) {
+                return o1.getFormattedName().getValue().compareTo(o2.getFormattedName().getValue());
+            } else {
+                if (o1.getFormattedName() == null) {
+                    return 1; // Send the contact to the end of the list
+                } else {
+                    return -1;
+                }
+            }
+        }
+
+    }
+
 }
 
 class ContactListAdapter extends RecyclerView.Adapter<ContactListFragment.ContactItemViewHolder> {

+ 53 - 0
src/main/java/third_parties/ezvcard_android/ContactOperations.java

@@ -141,6 +141,59 @@ public class ContactOperations {
         context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, operations);
     }
 
+    public void updateContact(VCard vcard, Long key) throws RemoteException, OperationApplicationException {
+
+        List<NonEmptyContentValues> contentValues = new ArrayList<NonEmptyContentValues>();
+        convertName(contentValues, vcard);
+        convertNickname(contentValues, vcard);
+        convertPhones(contentValues, vcard);
+        convertEmails(contentValues, vcard);
+        convertAddresses(contentValues, vcard);
+        convertIms(contentValues, vcard);
+
+        // handle Android Custom fields..This is only valid for Android generated Vcards. As the Android would
+        // generate NickName, ContactEvents other than Birthday and RelationShip with this "X-ANDROID-CUSTOM" name
+        convertCustomFields(contentValues, vcard);
+
+        // handle Iphone kinda of group properties. which are grouped together.
+        convertGroupedProperties(contentValues, vcard);
+
+        convertBirthdays(contentValues, vcard);
+
+        convertWebsites(contentValues, vcard);
+        convertNotes(contentValues, vcard);
+        convertPhotos(contentValues, vcard);
+        convertOrganization(contentValues, vcard);
+
+        ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>(contentValues.size());
+        ContentValues cv = account.getContentValues();
+        //ContactsContract.RawContact.CONTENT_URI needed to add account, backReference is also not needed
+        long contactID = key;
+        ContentProviderOperation operation;
+
+        for (NonEmptyContentValues values : contentValues) {
+            cv = values.getContentValues();
+            if (cv.size() == 0) {
+                continue;
+            }
+
+            String mimeType = cv.getAsString("mimetype");
+            cv.remove("mimetype");
+            //@formatter:off
+            operation =
+                    ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
+                            .withSelection(ContactsContract.Data.RAW_CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ? ", new String[]{"" + contactID, "" + mimeType})
+                            .withValues(cv)
+                            .build();
+            //@formatter:on
+            operations.add(operation);
+        }
+
+        // Executing all the insert operations as a single database transaction
+        context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, operations);
+
+    }
+
     private void convertName(List<NonEmptyContentValues> contentValues, VCard vcard) {
         NonEmptyContentValues values = new NonEmptyContentValues(ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);