--- a/src/com/beem/project/beem/account/SyncAdapterService.java Thu Mar 31 21:49:28 2011 +0200
+++ b/src/com/beem/project/beem/account/SyncAdapterService.java Wed Apr 13 22:51:44 2011 +0200
@@ -9,7 +9,6 @@
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.util.StringUtils;
import android.accounts.Account;
import android.accounts.OperationCanceledException;
@@ -17,15 +16,18 @@
import android.content.ContentProviderClient;
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
+import android.content.OperationApplicationException;
import android.content.SyncResult;
+import android.database.Cursor;
+import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
+import android.os.RemoteException;
import android.provider.ContactsContract;
-import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.RawContacts;
-import android.provider.ContactsContract.CommonDataKinds.Im;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.util.Log;
@@ -72,56 +74,94 @@
BeemConnection beemco = new BeemConnection(mContext.getSharedPreferences(account.name, MODE_PRIVATE), null);
beemco.setNoPresence();
XMPPConnection con = new XMPPConnection(beemco.getConnectionConfiguration());
+ Roster roster = null;
try {
con.connect();
con.login(beemco.getLogin(), beemco.getPassword(), "BEEM_SYNC_ADAPTER");
+ roster = con.getRoster();
- Roster roster = con.getRoster();
- if (roster != null) {
- for (RosterEntry entry : roster.getEntries()) {
- if (entry != null) {
- addEntry(account, entry);
- }
- }
- }
- } catch (XMPPException e) {
+ } catch (XMPPException e) {
Log.e(TAG, "Error while connecting with syncAdapter", e);
+ } catch (IllegalStateException e) {
+ Log.e(TAG, "Not connected to server", e);
+ }
+ if (roster != null) {
+ manageRoster(roster, account);
}
con.disconnect();
}
- private static void addEntry(Account account, RosterEntry entry) {
+ private static void executeOperation(ArrayList<ContentProviderOperation> ops) {
+ try {
+ mContentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
+ } catch (RemoteException e) {
+ Log.d(TAG, "Error during sync of contact", e);
+ } catch (OperationApplicationException e) {
+ Log.d(TAG, "Error during sync of contact", e);
+ }
+ }
+
+ private static void manageRoster(final Roster r, final Account a) {
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
- int rawContactInsertIndex = ops.size();
+ for (RosterEntry entry : r.getEntries()) {
+ if (entry != null) {
+ manageEntry(ops, a, entry);
+ }
+ if (ops.size() > 100)
+ executeOperation(ops);
+ }
+ if (ops.size() > 0)
+ executeOperation(ops);
+ }
- ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(RawContacts.CONTENT_URI);
- builder.withValue(RawContacts.ACCOUNT_NAME, account.name);
- builder.withValue(RawContacts.ACCOUNT_TYPE, account.type);
- builder.withValue(RawContacts.SYNC1, entry.getUser());
- ops.add(builder.build());
+ private static void manageEntry(ArrayList<ContentProviderOperation> ops, Account account, RosterEntry entry) {
- builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
- builder.withValueBackReference(Data.RAW_CONTACT_ID, rawContactInsertIndex);
- builder.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
- builder.withValue(StructuredName.DISPLAY_NAME, entry.getUser());
- ops.add(builder.build());
-
- builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
- builder.withValueBackReference(Data.RAW_CONTACT_ID, 0);
- builder.withValue(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE);
- builder.withValue(Im.DATA, entry.getUser());
- builder.withValue(Im.PROTOCOL, Im.PROTOCOL_JABBER);
- ops.add(builder.build());
-
- try {
- mContentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
- Log.i(TAG, "added contact " + entry.getUser());
- } catch (Exception e) {
- Log.d(TAG, "Error during add of contact", e);
+ long rawContactID = getRawContactID(account.name, entry.getUser());
+ if (rawContactID == -1) { // Not found in database, add new
+ ContentValues values = new ContentValues();
+ values.put(ContactsContract.RawContacts.ACCOUNT_TYPE, account.type);
+ values.put(ContactsContract.RawContacts.ACCOUNT_NAME, account.name);
+ values.put(ContactsContract.RawContacts.SOURCE_ID, entry.getUser());
+ Uri rawContactUri = mContentResolver.insert(ContactsContract.RawContacts.CONTENT_URI, values);
+ rawContactID = ContentUris.parseId(rawContactUri);
+ values.clear();
+ ContentProviderOperation.Builder builder = buildStructuredName(ContentProviderOperation
+ .newInsert(ContactsContract.Data.CONTENT_URI), entry, rawContactID);
+ ops.add(builder.build());
+ } else { // Found, update
+ // if newUpdate instead of newInster ... fail update : all rows = 1 row
+ ContentProviderOperation.Builder builder = buildStructuredName(ContentProviderOperation
+ .newInsert(ContactsContract.Data.CONTENT_URI), entry, rawContactID);
+ ops.add(builder.build());
}
}
+ private static ContentProviderOperation.Builder buildStructuredName(ContentProviderOperation.Builder builder,
+ RosterEntry entry, long rawContactID) {
+ String displayName = entry.getName() != null ? entry.getName() : entry.getUser();
+ builder.withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactID);
+ builder.withValue(ContactsContract.Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
+ builder.withValue(StructuredName.DISPLAY_NAME, displayName);
+ return builder;
+ }
+
+ private static long getRawContactID(String account, String jid) {
+ long authorId = -1;
+ final Cursor c = mContentResolver.query(ContactsContract.RawContacts.CONTENT_URI, new String[] {
+ ContactsContract.RawContacts._ID, ContactsContract.RawContacts.SOURCE_ID },
+ ContactsContract.RawContacts.ACCOUNT_NAME + "=? AND " + ContactsContract.RawContacts.SOURCE_ID + "=?",
+ new String[] { account, jid }, null);
+ try {
+ if (c.moveToFirst())
+ authorId = c.getInt(c.getColumnIndex(ContactsContract.RawContacts._ID));
+ } finally {
+ if (c != null)
+ c.close();
+ }
+ return authorId;
+ }
+
}