Как слушать контакт вставлен/обновлен/удален в адресной книге

Есть много вопросов, связанных с этим, но ни один из них не помогает мне получить решение.

Я пытаюсь синхронизировать все контакты с устройства на удаленный сервер и сделать это легко, но при изменении контакта, такого как update/delete/insert (new contact), не удается найти решение.

Пробовал использовать ContentObserver, но onChange() вызывается несколько раз. Трудно найти данные о контактах.

    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);
    }
}

Но onChange() получает вызов более одного раза при обновлении/вставке в адресную книгу.

может ли кто-нибудь предоставить мне лучшее решение?

Было бы высоко оценено.

Спасибо

Ответы

Ответ 1

Дело в onChange заключается в том, что он вызван как для удаления/добавления/обновления, поэтому вы не можете просто подсчитывать количество контактов, так как один из них мог быть удален, а один добавлен, тогда у вас есть измененная контактная книга, но такой же счет. Однако, глядя на версию column, вы сможете оценить, какой контакт обновлен или нет (после того, как вы получили одну полную копию контактной книги уже). Просто проверьте, больше ли версия выше той, которая у вас уже (для текущего контакта).

Ответ 2

В соответствии с ответом Магнуса, используйте этот столбец для извлечения кода версии

ContactsContract.RawContacts.VERSION

Ответ 3

я сделал это таким образом, и он работал у меня для вызова Log и ContactNumber Change.

in onChange

execute a Query with contentResolver(), and put the data in a List
then something is deleted again execute
 a Query with contentResolver(), and assign it to tempList.
now compare the List and tempList



@Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);    
        final int List = totalContacts();

if (tempList < List) {
something is deleted
then remove the tempList from List you will get the deleted number

}else if (tempList == List) {
something is updated
then remove the tempList from List you will get the deleted number
}else {
       something is added(reverse the Lists)
then remove the List from tempList you will get the deleted number
    }
}