How to listen contact inserted/updated/deleted in address book
Asked Answered
R

3

18

There are lots of questions related to it but none of them help me to get the solution.

I am trying to sync all contacts from device to remote server and able to do it easily but when there is a change in contact like update/delete/insert(new contact) unable to find the solution.

Tried using ContentObserver but onChange() is getting called multiple times. It's difficult to find the contact changes data.

    public class ContactService extends Service {

    private int mContactCount;

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mContactCount = getContactCount();

        Log.d("Contact Service", mContactCount + "");

        this.getContentResolver().registerContentObserver(
                ContactsContract.Contacts.CONTENT_URI, true, mObserver);
    }

    private int getContactCount() {
        Cursor cursor = null;
        try {
            cursor = getContentResolver().query(
                    ContactsContract.Contacts.CONTENT_URI, null, null, null,
                    null);
            if (cursor != null) {
                return cursor.getCount();
            } else {
                return 0;
            }
        } catch (Exception ignore) {
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return 0;
    }

    private ContentObserver mObserver = new ContentObserver(new Handler()) {

        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);

            final int currentCount = getContactCount();
            if (currentCount < mContactCount) {
                // CONTACT DELETED.

                Log.d("Contact Service", currentCount + "");

            } else if (currentCount == mContactCount) {
                // CONTACT UPDATED.
            og.d("Contact Service", currentCount+"");

            } else {
                // NEW CONTACT.
                Log.d("Contact Service", currentCount + "");

            }
            mContactCount = currentCount;
        }

    };

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        getContentResolver().unregisterContentObserver(mObserver);
    }
}

But onChange() getting called more than once when there is a update/insert into address book.

can anyone provide me better solution to it?

It would be highly appreciated.

Thanks

Ronaldronalda answered 8/2, 2014 at 19:13 Comment(1)
C
18

The thing about onChange is that it gets called both for delete/add/update so you can't just count the number of contacts since one might have been deleted and one added then you have a changed contact book, but same count. However looking at the version column you should be able to assess which contact is updated or not (after you've obtained one complete copy of the contact book already). Simply check if the version is greater than the one you have already (for the current contact).

Crus answered 13/2, 2014 at 20:58 Comment(5)
is there way a to prevent onChange for getting called only one time whenever there is a insert/update/delete of a contact?Ronaldronalda
You can throttle the onchange calls yourself (filter the calls) by say only accepting one call during a specific time frame or receive all but decide yourself that every five seconds you should send onchange to your own code.Crus
is there any way to fetch contacts based on their status like new contact, updated contact or deleted contact?Ronaldronalda
Upvoted for the sole reason of using contact version to detect changes.Maiga
how to use it ?? any example for it..!! because ContactsContract.SyncColumns is an interface and i'm unable to access it.. help plxEsquiline
I
1

In accordance with Magnus' answer, use this column to retrieve the version code

ContactsContract.RawContacts.VERSION

Insistence answered 24/6, 2017 at 18:52 Comment(0)
H
0

This is working fine for me.

1 - Register service

this.getApplicationContext()
                .getContentResolver()
                .registerContentObserver(
                        ContactsContract.Contacts.CONTENT_URI, true,
                        new ContactsListner(new Handler(),this,getContactCount()));

2 - Definition for getContactCount()

private int getContactCount() {
        Cursor cursor = null;
        try {
            cursor = activity.getContentResolver().query(
                    ContactsContract.Contacts.CONTENT_URI, null, null, null,
                    null);
            if (cursor != null) {
                return cursor.getCount();
            } else {
                return 0;
            }
        } catch (Exception ignore) {
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return 0;
    }

3 - Contact listner class

import android.app.Activity;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.provider.ContactsContract;
import android.widget.Toast;

import androidx.annotation.Nullable;

public class ContactsListner extends ContentObserver {
    /**
     * Creates a content observer.
     *
     * @param handler The handler to run {@link #onChange} on, or null if none.
     *
     *
     */

    Activity activity;
    int contactsCount;

    public ContactsListner(Handler handler, Activity activity, int contactsCount) {
        super(handler);
        this.activity = activity;
        this.contactsCount = contactsCount;
    }




    @Override
    public void onChange(boolean selfChange, @Nullable Uri uri) {
        super.onChange(selfChange, uri);



            int currentContacts = getContactCount();
            Toast.makeText(activity, "Current num is "+currentContacts+"     and recent : "+contactsCount, Toast.LENGTH_SHORT).show();

            if (currentContacts<contactsCount){
                Toast.makeText(activity, "Deleted", Toast.LENGTH_SHORT).show();
            }else if (currentContacts == contactsCount){
                Toast.makeText(activity, "Update occurred", Toast.LENGTH_SHORT).show();
            }else {
                Toast.makeText(activity, "New contact added", Toast.LENGTH_SHORT).show();
            }

            contactsCount = currentContacts;

    }





    private int getContactCount() {
        Cursor cursor = null;
        try {
            cursor = activity.getContentResolver().query(
                    ContactsContract.Contacts.CONTENT_URI, null, null, null,
                    null);
            if (cursor != null) {
                return cursor.getCount();
            } else {
                return 0;
            }
        } catch (Exception ignore) {
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return 0;
    }
}
Hermon answered 29/1, 2021 at 2:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.