I am creating an android application and within my app there is a module dealing with contact synchronization in which i sync contacts from user contact.
List with server contact list to filter users who are registered in the app, similar to Whatsapp, telegram, Facebook.
Now my main problem is how to perform contact sync, currently i am using a sync adapter in which i get all the contact from user contact list and send it to the server to perform the sync but this method is slow and utilities a lot of phone resources,
So am opting for a better method, if you know of any kind of help please refer me.
That being said i come across content observer, which in someway it works a bit better.it notifies me when a contact is added or edited but fails to notify correctly when a contact is deleted, am using the
ContactsContract.Contacts.CONTACT_LAST_UPDATED_TIMESTAMP
,
Secondly it only notifies when the app is running and not when the its killed, how to run it in the background, and also if its possible how can i integrate it in the sync adapter to check periodically or is there a sync adapter means to perform this contact sync. any help toward finding a proper means to sync contacts will be appreciated
heres my code
public class ContentObserver extends android.database.ContentObserver
{
private Context mContext;
private static final String TAG="Contenr_observer_tag";
public ContentObserver(Handler handler,Context context) {
super(handler);
this.mContext=context;
Log.d(TAG,"occures here");
}
@Override
public void onChange(boolean selfChange) {
this.onChange(selfChange);
}
@Override
public void onChange(boolean selfChange, Uri uri) {
Cursor cursor=mContext.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,null,null,
null,ContactsContract.Contacts.CONTACT_LAST_UPDATED_TIMESTAMP+" DESC");
if (cursor.moveToNext()){
String id=cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
String name=cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
Log.d(TAG,"contact id: "+id);
Log.d(TAG,"contact name "+name);
}
cursor.close();
}
}
So having confirmed you only need to check phone number of all contacts, I assume you've tried something like this:
Cursor c1 = cr.query(Contacts.CONTENT_URI,null,null,null,null);
while (c1.moveToNext()) {
long contactId = cur.getLong(...);
Cursor c2 = cr.query(Phone.CONTENT_URI, null, Phone.CONTACT_ID + "=" + contactId, null, null);
String phone = c2.getString(...);
// add phone to some list or map
}
sendAllPhonesToServer();
This is indeed slow, as it requires many queries - as the number of contacts of the device - but you can do better.
Map<Long, String> phonesMap = new HashMap<>(); // mapping from contactId to phone
String[] projection = new String[] { Phone.CONTACT_ID, Phone.NORMALIZED_NUMBER }; // if you need to support API 15 and below, change to Phone.NUMBER
Cursor c = cr.query(Phone.CONTENT_URI,projection,null,null,null);
while (c.moveToNext()) {
long contactId = c.getLong(0);
String phone = c.getString(1);
phonesMap.put(contactId, phone);
}
sendAllPhonesToServer(phonesMap);
This should be pretty fast, and easy to implement, put it in your SyncAdapter and have it run periodically by Android (doesn't require your app running in order to have your SyncAdapter to run)