Подтвердить что ты не робот

Как заставить Android ContentObserver для ContactsContract обнаруживать добавленный, обновленный или удаленный контакт?

Я могу получить общее уведомление "о том, что произошла смена базы данных контактов", но я хочу знать конкретную запись, которая была вставлена, обновлена ​​или удалена. Ниже приведен код, который регистрируется и получает уведомление onChange. К сожалению, это не является специфическим, что делает мою обработку исчерпывающей и неэффективной.

Вот заглушка кода:

            if ((mNativeContactsObserver == null) && (mHandler == null)) {
            mHandler = new Handler(this.getMainLooper()) {
            };
            mNativeContactsObserver = new ContentObserver(mHandler) {
                @Override
                public void onChange(boolean selfChange) {
                    super.onChange(selfChange);

                    Bundle data = null;
                    Message message = mHandler.obtainMessage();
                    if (message != null) {
                        data = message.getData();
                        if (data != null) {
                            Logs.d(TAG, "Message = [" + message.toString() + "] data=[" + data.toString() + "]");
                            Logs.d(TAG, "Contents = [" + message.describeContents() + "]");
                        }
                    }

                    if (!selfChange) {
                        final Account accountListen = MySyncAdapter.lookupAccount(TAG, getApplicationContext(), getUserProfile().getAccountId(), AUTHORITY_MY_SYNC);
                        Logs.d(TAG, "onChange!? account: " + accountListen.name);
                        if (!ContentResolver.isSyncPending(account, ContactsContract.AUTHORITY) 
                                && (!ContentResolver.isSyncActive(account, ContactsContract.AUTHORITY))) {
                            Bundle extras = new Bundle();
                            extras.putInt(MySyncAdapter.EXTRA_SYNC_TYPE, MySyncAdapter.REQUEST_SYNC_NATIVE_CHANGED);
                            ContentResolver.requestSync(accountListen, ContactsContract.AUTHORITY, extras);
                        } else {
                            Logs.w(TAG, "There is a pending sync.  This request is ignored.");
                        }
                    }
                }
            };
        }
        Uri uriContactsListen = ContactsContract.Contacts.CONTENT_URI.buildUpon().appendEncodedPath("#").build();
        Logs.i(TAG, "Register listening for native contacts changes. [" + uriContactsListen + "]");
        cr.registerContentObserver(uriContactsListen, true, mNativeContactsObserver);
4b9b3361

Ответ 1

У меня этот код в базовом классе Application.

private ContentObserver contactObserver = new ContactObserver();

private class ContactObserver extends ContentObserver {

    public ContactObserver() {
        super(null);
    }

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

        // Since onChange do not sent which user have been changed, you 
        // have to figure out how to match it with your data.
        // Note: Contact is  one of my classes.
        for (Contact contact : getContacts()) {
            if (!contact.isLinked())
                continue;

            String selection = ContactsContract.Data._ID + " = ?";
            String[] selectionArgs = new String[] { contact.getSystemId() };
            String[] projection = new String[] { ContactsContract.Data.DISPLAY_NAME };
            Cursor cursor = getContentResolver().query(
                    ContactsContract.Contacts.CONTENT_URI, projection,
                    selection, selectionArgs, null);

            if (!cursor.moveToFirst())
                return;

            String name = cursor.getString(0);

            if (contact.getUsername().equalsIgnoreCase(name))
                continue;

            contact.setUserName(name);

        }
    }
}

Относительно того, что вы можете поставить в проекции, проверьте здесь

Unfortunately, it is not specific which makes my processing exhaustive and inefficient.

Было бы здорово, если в следующие выпуски Android также будет отправлен идентификатор контакта, который был только что изменен.

Надеюсь, что это поможет

Ответ 2

Наконец, по крайней мере, я могу обнаружить это Обновить/Удалить/Вставить посмотреть на мой метод OnChange, как показано ниже

 @Override
       public void onChange(boolean selfChange) {
           super.onChange(selfChange);
           Log.e("ContactChangeObserver", "onChange");

           // 0 Update , 1 Delete , 2 Added
 // Get count from phone contacts
           final int currentCount = contactDBOperaion.getContactsCountFromPhone();

 // Get count from your sqlite database
           int mContactCount= DbContacts.getInstance().getContactsCount();

           if (currentCount < mContactCount) {
               // DELETE HAPPEN.
               Log.e("Status", "Deletion");
               contactDBOperaion.SyncContacts(1);
           } else if (currentCount == mContactCount) {
               // UPDATE HAPPEN.
               contactDBOperaion.SyncContacts(0);
           } else {
               // INSERT HAPPEN.
               Log.e("Status", "Insertion");
               contactDBOperaion.SyncContacts(2);
           }
       }

Когда произошло Обновление, я обновляю все контакты

Когда произошел Вставить, я вставляю новую добавленную строку, после проверки isExist в существующей базе данных

Когда Удалить еще не найдено решение

Ответ 3

Прежде всего, вы должны зарегистрировать свой контентный сервер, чтобы получать уведомление об изменении.

Сделайте это, позвонив:

registerContentObserver();

Здесь спецификации: registerContetObserver

После того, как вы захотите уведомить всех слушателей, когда произойдет изменение:

contentResolver.notifyChange();

Здесь спецификации для этого: notifyChange

Надеюсь, что это поможет;)

Приветствия!

Ответ 4

Используйте Loaders для запроса и отображения списка контактов на вашем устройстве Android на вашем эмуляторе. Они автоматически обнаруживают изменения в базовых данных и отражают их в пользовательском интерфейсе.