Add group contact sync adapter
author"Vincent Veronis"
Sun, 05 Jun 2011 19:41:19 +0200
changeset 893 4200af89661d
parent 892 b9e58686cae3
child 894 c36af805487d
Add group contact sync adapter
src/com/beem/project/beem/account/SyncAdapterService.java
--- a/src/com/beem/project/beem/account/SyncAdapterService.java	Sun May 15 18:51:36 2011 +0200
+++ b/src/com/beem/project/beem/account/SyncAdapterService.java	Sun Jun 05 19:41:19 2011 +0200
@@ -48,6 +48,7 @@
 
 import org.jivesoftware.smack.Roster;
 import org.jivesoftware.smack.RosterEntry;
+import org.jivesoftware.smack.RosterGroup;
 import org.jivesoftware.smack.XMPPConnection;
 import org.jivesoftware.smack.XMPPException;
 import org.jivesoftware.smack.packet.Presence;
@@ -73,7 +74,6 @@
 import android.util.Log;
 
 import com.beem.project.beem.BeemConnection;
-import com.beem.project.beem.BeemService;
 import com.beem.project.beem.R;
 import com.beem.project.beem.utils.Status;
 
@@ -83,6 +83,7 @@
  */
 public class SyncAdapterService extends Service {
 
+    private static final int NB_DB_OPERATION = 50;
     private static final String TAG = "SynAcapterService";
     private static SyncAdapter mSyncAdapter = null;
     private static ContentResolver mContentResolver = null;
@@ -173,6 +174,7 @@
 	} catch (OperationApplicationException e) {
 	    Log.d(TAG, "Error during sync of contact", e);
 	}
+	ops.clear();
     }
 
     /**
@@ -182,18 +184,40 @@
      */
     private static void manageRoster(final Roster r, final Account a) {
 	ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
+	for (RosterGroup group : r.getGroups()) {
+	    if (group != null) {
+		manageGroup(ops, a, group);
+	    }
+	    if (ops.size() > NB_DB_OPERATION)
+		executeOperation(ops);	    
+	}
+	if (ops.size() > 0)
+	    executeOperation(ops);
 	for (RosterEntry entry : r.getEntries()) {
 	    if (entry != null) {
 		long rawContactID = manageEntry(ops, a, entry);
 		addUpdateStatus(ops, entry, r.getPresence(entry.getUser()), rawContactID);
 	    }
-	    if (ops.size() > 100)
+	    if (ops.size() > NB_DB_OPERATION)
 		executeOperation(ops);
 	}
 	if (ops.size() > 0)
 	    executeOperation(ops);
     }
 
+    private static void manageGroup(ArrayList<ContentProviderOperation> ops, Account account, RosterGroup group) {
+	Log.i(TAG, "Sync group : " + group.getName() + " " + group.getEntryCount());
+	long rawGroupID = getRawGroupID(account.name, group.getName());
+	if (rawGroupID == -1) {
+	    ContentProviderOperation.Builder builder = ContentProviderOperation
+		.newInsert(ContactsContract.Groups.CONTENT_URI);
+	    builder.withValue(ContactsContract.Groups.ACCOUNT_NAME, account.name);
+	    builder.withValue(ContactsContract.Groups.ACCOUNT_TYPE, account.type);
+	    builder.withValue(ContactsContract.Groups.TITLE, group.getName());
+	    ops.add(builder.build());
+	}
+    }
+
     /**
      * RosterEntry sync method.
      * @param ops The content provider operation
@@ -214,9 +238,13 @@
 	    values.clear();
 	    ContentProviderOperation.Builder builder = addUpdateStructuredName(entry, rawContactID, true);
 	    ops.add(builder.build());
+	    for (RosterGroup group : entry.getGroups()) {
+		builder = addUpdateGroup(entry, rawContactID, getRawGroupID(account.name, group.getName()), true);
+		ops.add(builder.build());
+	    }
 	    builder = createProfile(entry, rawContactID, account);
 	    ops.add(builder.build());
-	} else { // Found, update
+	} else { // Found, update	   
 	    ContentProviderOperation.Builder builder = addUpdateStructuredName(entry, rawContactID, false);
 	    ops.add(builder.build());
 	}
@@ -253,6 +281,22 @@
 	return builder;
     }
 
+    private static ContentProviderOperation.Builder addUpdateGroup(RosterEntry entry, long rawContactID,
+	long rawGroupID, boolean isInsert) {
+	String displayName = entry.getName() != null ? entry.getName() : entry.getUser();
+	Log.e(TAG + "UPDATE GROUP", "Contact : " + displayName + " GroupID :" + rawGroupID);
+	ContentProviderOperation.Builder builder = null;
+	if (isInsert) {
+	    builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
+	    builder.withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactID);
+	    builder.withValue(ContactsContract.Data.MIMETYPE,
+		ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE);
+	    builder.withValue(ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID, rawGroupID);
+	}
+	//TODO: delete - contact doesnt appear anymore in this group 
+	return builder;
+    }
+
     /**
      * Method to insert or update IM informations.
      * @param entry The roster entry to sync
@@ -289,6 +333,7 @@
 	builder = ContentProviderOperation.newInsert(ContactsContract.StatusUpdates.CONTENT_URI);
 	builder.withValue(ContactsContract.StatusUpdates.PROTOCOL, ContactsContract.CommonDataKinds.Im.PROTOCOL_JABBER);
 	builder.withValue(ContactsContract.StatusUpdates.IM_HANDLE, displayName);
+	//TODO: Get account name
 	builder.withValue(ContactsContract.StatusUpdates.IM_ACCOUNT, "beem@elyzion.net");
 	builder.withValue(ContactsContract.StatusUpdates.STATUS, p.getStatus());
 	builder.withValue(ContactsContract.StatusUpdates.STATUS_RES_PACKAGE, "com.beem.project.beem");
@@ -322,4 +367,19 @@
 	return authorId;
     }
 
+    private static long getRawGroupID(String account, String group) {
+	long authorId = -1;
+	final Cursor c = mContentResolver.query(ContactsContract.Groups.CONTENT_URI,
+	    new String[] { ContactsContract.Groups._ID }, ContactsContract.Groups.ACCOUNT_NAME + "=? AND "
+		+ ContactsContract.Groups.TITLE + "=?", new String[] { account, group }, null);
+	try {
+	    if (c.moveToFirst())
+		authorId = c.getInt(c.getColumnIndex(ContactsContract.RawContacts._ID));
+	} finally {
+	    if (c != null)
+		c.close();
+	}
+	return authorId;
+    }
+
 }