Android ContactsContract: Last Modified Time

Я хотел бы клонировать Android Contacts Phone в свой собственный SQLite db. Чтобы сэкономить время, клонирование должно запускаться, когда единственный контакт создается или обновляется в системе Android. Таким образом, я хочу иметь "последнее измененное время" каждого контакта.

Для уровня API 18 или выше кажется, что я получаю последнее измененное время контакта с одним человеком, используя ContactsContract.Contacts.CONTACT_LAST_UPDATED_TIMESTAMP. Однако для уровня API 17 или ниже кажется, что есть некоторые обсуждения, перед которыми предлагалось использовать "ContactsContract.RawContacts.VERSION" или "CONTACT_STATUS_TIMESTAMP".

Для "CONTACT_STATUS_TIMESTAMP" он всегда возвращает ZERO или null. Для "ContactsContract.RawContacts.VERSION" версия осталась прежней, когда я обновил фотографию, номер телефона или электронную почту контакта с человеком.

Рад, если кто-то укажет на ошибки, которые я сделал...

Ссылка: как получить последнюю дату изменения для списка контактов (Добавить/Удалить/Изменить)

Ответы

Ответ 1

Вы можете получить уведомление, когда что-то изменится с помощью ContentObserver. Затем вам нужно будет получить правильный контакт самостоятельно. Конечно, это означает, что вам нужно открыть свое приложение, когда контакт изменится или (более разумно) работает фоновый сервис.

В вашей службе создайте наблюдателя контента:

myObserver = new ContentObserver(new Handler()) {

    @Override
    public void onChange(boolean selfChange) {
        super.onChange(selfChange);
        if (!selfChange) {
            //Note: when this (older) callback is used you need to loop through 
            //and find the contact yourself (by using the dirty field)
        }
    }

    @Override
    public void onChange(boolean selfChange, Uri uri) {
        super.onChange(selfChange, uri);
        if (!selfChange) {
            //Note: if you receive a uri, it has contact id
            long rawContactId = ContentUris.parseId(uri);
            //Note: be careful which thread you are on here (dependent on handler)
        }
    }

};

//NOTE: Then you need to remember to register and unregister the observer.
//getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, myObserver);
//getContentResolver().unregisterContentObserver(myObserver);

Ваше предложение использовать грязное не является хорошим решением в одиночку, так как это только временно указывает, что агрегированный контакт (владелец) должен быть обновлен, потому что что-то в RawContact изменилось. Это означает, что если контакт синхронизируется до того, как ваше приложение будет открыто, грязное уже неверно (0).

Также обратите внимание, что в документации для столбца упоминается, что он был добавлен в API 18, так как вам известно, только ниже 18 требуется обходной путь. поэтому первый шаг - убедиться, что вы используете столбец, когда можете

if (Build.VERSION.SDK_INT >=  Build.VERSION_CODES.JELLY_BEAN_MR2) {
    //continue with existing code
} else {
    //use workaround (start service, or at least register observer)
}