Dhwanik Gandhi
Dhwanik Gandhi

Reputation: 685

Android How to detect contact list is changed?

I have implemented a ContentObserver, using this method I'm only able to be notified if a change occurs on a contact

but I don't know which contact has been added , deleted or updated ??

! Any suggestions ? how do i know which particular contact is modified ?

i am getting all contact list by using following method .

    public void readContacts() {

    System.out.println("   reading contact ");
    String phoneNumber = null;
    Uri CONTENT_URI = ContactsContract.Contacts.CONTENT_URI;
    String _ID = ContactsContract.Contacts._ID;
    String DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME;
    String HAS_PHONE_NUMBER = ContactsContract.Contacts.HAS_PHONE_NUMBER;

    Uri PhoneCONTENT_URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
    String Phone_CONTACT_ID = ContactsContract.CommonDataKinds.Phone.CONTACT_ID;
    String NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;

    StringBuffer output = new StringBuffer();
    ContentResolver contentResolver = getContentResolver();

    Cursor cursor = contentResolver.query(CONTENT_URI, null, null, null,
            null);

    if (cursor.getCount() > 0) {
        while (cursor.moveToNext()) {
            String contact_id = cursor
                    .getString(cursor.getColumnIndex(_ID));
            String name = cursor.getString(cursor
                    .getColumnIndex(DISPLAY_NAME));
            // int id =
            // Integer.parseInt(cursor.getString(cursor.getColumnIndex(
            // HAS_PHONE_NUMBER )));
            int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor
                    .getColumnIndex(HAS_PHONE_NUMBER)));
            if (hasPhoneNumber > 0) {
                output.append("\n First Name:" + name);

                System.out.println(" CONTACT NAME  : " + name);
                Contact_Name.add(name);

                // Query and loop for every phone number of the contact
                Cursor phoneCursor = contentResolver.query(
                        PhoneCONTENT_URI, null, Phone_CONTACT_ID + " = ?",
                        new String[] { contact_id }, null);

                phoneCursor.moveToNext();

                phoneNumber = phoneCursor.getString(phoneCursor
                        .getColumnIndex(NUMBER));
                output.append("\n Phone number:" + phoneNumber);
                System.out.println(" CONTACT number  : " + phoneNumber);

                phoneNumber = phoneNumber.replaceAll("\\s", "");
                // phoneNumber = phoneNumber.substring(phoneNumber.length()
                // - 10);
                // System.err.println("Mobile no."+phoneNumber);
                Contact_Number.add(phoneNumber);

                phoneCursor.close();
            }
            output.append("\n");
        }
    }

}

and i am observing contact list is being some changed by regestring and using following code .

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

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

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

        final int currentCount = getContactCount();
        if (currentCount < mContactCount) {
            System.out.println("  Deleted contact");
        } else if (currentCount == mContactCount) {
            System.out.println("  upated contact");
        } else {
            System.out.println("  inserted contact");
        }
        mContactCount = currentCount;

    }

}; 

Upvotes: 2

Views: 6334

Answers (2)

min2bro
min2bro

Reputation: 4638

Check if the version is greater than the one you have already (for the current contact). This is fast and more accurate then the current process your are following, since OnChange is called for all the items (delete, add or update).

So counting the # of contacts doesn't make much sense because a contact would have been updated then deleted and new contact added. the count is same in this case.

http://developer.android.com/reference/android/provider/ContactsContract.SyncColumns.html#VERSION

Upvotes: 2

Davide
Davide

Reputation: 614

Try to use this implementation for you Contacts array

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class ActiveList<T> extends ArrayList<T> implements Serializable {

    private static final long serialVersionUID = 870605912858223939L;
    transient private List<ActiveListListener<T>> listeners;

    public interface ActiveListListener<T> {
        void onAdd(T item);

        void onInsert(int location, T item);

        void onAddAll(Collection<? extends T> items);

        void onClear();
    }

    @Override
    public synchronized void clear() {
        super.clear();
        fireChangedEvent();
    }

    @Override
    public synchronized int size() {
        return super.size();
    }

    @Override
    public synchronized T get(int index) {
        return super.get(index);
    }

    @Override
    public synchronized boolean add(T item) {
        boolean success = super.add(item);
        if (success) {
            fireAddEvent(item);
        }
        return success;
    }

    @Override
    public synchronized void add(int index, T item) {
        super.add(index, item);
        fireInsertEvent(index, item);
    }

    @Override
    public synchronized boolean addAll(int index, Collection<? extends T> items) {
        boolean success = super.addAll(index, items);
        if (success) {
            fireAddAllEvent(items);
        }
        return success;
    }

    @Override
    public synchronized boolean addAll(Collection<? extends T> items) {
        boolean success = super.addAll(items);
        if (success) {
            fireAddAllEvent(items);
        }
        return success;

    }

    public synchronized void addListener(ActiveListListener<T> listener) {
        if (this.listeners == null) {
            listeners = Lists.newArrayList();
        }
        this.listeners.add(listener);
    }

    public synchronized void removeListener(ActiveListListener<T> listener) {
        if (this.listeners != null) {
            this.listeners.remove(listener);
        }
    }

    private void fireChangedEvent() {
        if (this.listeners == null)
            return;
        for (ActiveListListener<T> listener : listeners) {
            listener.onClear();
        }
    }

    private void fireInsertEvent(int location, T item) {
        if (this.listeners == null)
            return;
        for (ActiveListListener<T> listener : listeners) {
            listener.onInsert(location, item);
        }
    }

    private void fireAddEvent(T item) {
        if (this.listeners == null)
            return;
        for (ActiveListListener<T> listener : listeners) {
            listener.onAdd(item);
        }
    }

    private void fireAddAllEvent(Collection<? extends T> items) {
        if (this.listeners == null)
            return;
        for (ActiveListListener<T> listener : listeners) {
            listener.onAddAll(items);
        }
    }
}

In your Activity or Adapter

protected ActiveList.ActiveListListener<Contact> activeListListener = new ActiveList.ActiveListListener<Contact>() {
        @Override
        public void onAdd(Contact c) {
            // do something
        }

        @Override
        public void onInsert(final int location, final Contact c) {
            // do something
        }

        @Override
        public void onClear() {
            // do something
        }

        @Override
        public void onAddAll(List<Contact> cs) {
            // do something
        }
    };

and in your Array

((ActiveList<Contact>) this.contacts).addListener(activeListListener);

See example https://github.com/davidevallicella/UnivrApp/

Upvotes: 0

Related Questions