Content Observer onChange метод, вызываемый дважды после 1 изменения курсора

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

Я установил ContentObserver в «ContactsContract.Contacts.CONTENT_URI» из службы, которая запускается при загрузке телефона.

У меня есть несколько quiestions, первые 2 являются случайными, третье – моя главная проблема.

1: Как только я настроил службу, которая регистрирует ContentObserver на моем курсоре, этот наблюдатель существует только в службе? Я имею в виду, что если служба убита, продолжает ли контент-контент?

2: Я подозреваю, что ответ отрицательный, но я все равно спрошу. Есть ли вообще знать, какой контакт обновляется, вызывает метод onchange моего contentObserver? В настоящее время мне приходится составлять список всех контактов на телефоне и отправлять их на мой удаленный сервер, было бы намного проще просто отправлять детали обновляемых контактов.

3: Это мой главный вопрос, когда я вношу изменения в свой Список контактов, метод onChange запускается дважды в быстрой последовательности. 1 изменение, 2 вызова. Есть ли способ управления этим?

public class ContactService extends Service { JSONArray contactList; @Override public IBinder onBind(Intent arg0) { return null; } @Override public void onCreate() { Log.i("C2DM","content observers initialised"); super.onCreate(); //Call Log Content Provider observer MyContentContactsObserver contactsObserver = new MyContentContactsObserver(); ContactService.this.getContentResolver().registerContentObserver (ContactsContract.Contacts.CONTENT_URI, true, contactsObserver); } private class MyContentContactsObserver extends ContentObserver { public MyContentContactsObserver() { super(null); } @Override public void onChange(boolean selfChange) { super.onChange(selfChange); Log.i("LOG","detected change in contacts: "+selfChange); } } } 

REsults в 2 быстрых строках в моем logCat:

  detected change in contacts: false detected change in contacts: false 

Solutions Collecting From Web of "Content Observer onChange метод, вызываемый дважды после 1 изменения курсора"

Я сделал аналогичную реализацию и установил ContentObserver через URI событий календаря. И я столкнулся со всеми проблемами, с которыми вы сейчас сталкиваетесь. Итак, ваш вопрос с моими решениями / предложениями здесь.

1) Как только я настроил службу, которая регистрирует ContentObserver на моем курсоре, этот наблюдатель существует только внутри службы? Я имею в виду, что если служба убита, продолжает ли контент-контент?

Нет, он не будет соблюдать содержимое вашего содержимого через URI. Но есть решение этого. Вы можете создать всегда запущенный сервис. Эта услуга будет создана снова, как только она будет уволена из-за проблемы с памятью или другого неожиданного увольнения. Он всегда будет продолжать работать, если он явно не будет уволен. Чтобы создать такую ​​службу, переопределите OnStartCommand(Intent intent, int flags, final int startId) в вашем классе Service и верните START_STICKY . Посмотрите на код ниже.

 public int onStartCommand(Intent intent, int flags, final int startId) { String authenticationKey = ((MainApplication) getApplicationContext()).getDbConnector().getUserAuthDefault() ; // if user is not registered yet, stop this service, it may be called from boot reciever. if(authenticationKey == null){ stopSelf(); } // restart, if we get killed. return START_STICKY; } 

,

2: Я подозреваю, что ответ отрицательный, но я все равно спрошу. Есть ли вообще знать, какой контакт обновляется, вызывает метод onchange моего contentObserver? В настоящее время мне приходится составлять список всех контактов на телефоне и отправлять их на мой удаленный сервер, было бы намного проще просто отправлять детали обновляемых контактов.

Вы снова догадались, что это правильно. :). ответ – нет.
Невозможно точно узнать, какой контакт был обновлен. ContentObserver просто предоставляет событие, дающее вам знать, что некоторые изменения были внесены в данные, указанные uri. Но я думаю, что вы справляетесь с ситуацией неэффективно, поскольку вы составляете список всех контактов и отправляете их обратно на сервер.
Я предлагаю вам поддерживать список контактов, которые успешно отправляются на сервер, в локальном хранилище. И в следующий раз, когда вы получите вызов onChange() метода contentObserver вы получите все contacts из content_URI , сравните их с ранее сохраненным списком и отправите только обновленные контакты на сервер.

3: Это мой главный вопрос, когда я вношу изменения в свой Список контактов, метод onChange запускается дважды в быстрой последовательности. 1 изменение, 2 вызова. Есть ли способ управления этим?

Да, это происходит, но я думаю, что вы ошибаетесь. В моем случае он срабатывал случайным образом дважды или трижды или даже больше раз. Поэтому я установил интервал порогового значения. ContentObserver интервал, в течение которого, если ContentObserver будет запущен снова, я не буду его обрабатывать. Я сделал что-то вроде этого ..

 long lastTimeofCall = 0L; long lastTimeofUpdate = 0L; long threshold_time = 10000; /* (non-Javadoc) * @see android.database.ContentObserver#onChange(boolean) */ @Override public void onChange(boolean selfChange) { super.onChange(selfChange); Log.d("content service", "on change called"); lastTimeofCall = System.currentTimeMillis(); if(lastTimeofCall - lastTimeofUpdate > threshold_time){ //write your code to find updated contacts here lastTimeofUpdate = System.currentTimeMillis(); } } 

Надеюсь, эти предложения / решения помогут.

Подумайте, как вы регистрируете своего наблюдателя. Второй аргумент registerContentObserverboolean notifyForDescendents , вы установили его в true . Поэтому вы будете уведомлены, если были изменены либо ContactsContract.Contacts.CONTENT_URI, либо какой-либо из его descandants uris. Возможно, что некоторая операция для контакта с заданными идентификаторами запускает уведомление как для конкретного контакта uri, так и для глобальных контактов uri – со вторым аргументом, который true ваш наблюдатель наблюдает и то, и другое.

Другое дело, что вы можете регистрировать контент-наблюдателя для определенного идентификатора контакта uri – ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId) . Это, однако, не имеет ничего общего с вашей проблемой, но регистрация отдельного наблюдателя для каждого контакта выглядит довольно уродливо;)

Другое предложение: возможно, чтобы наблюдатель был в качестве конечного поля, не воссоздайте его в onCreate (но зарегистрируйте его там).

 public class ContactService extends Service { private final ContentObserver contactsObserver = new ContentObserver(null) { @Override public void onChange(boolean selfChange) { super.onChange(selfChange); Log.i("LOG","detected change in contacts: "+selfChange); //your code here } }; @Override public IBinder onBind(Intent arg0) { return null; } @Override public void onCreate() { super.onCreate(); getContentResolver().registerContentObserver( ContactsContract.Contacts.CONTENT_URI, true, contactsObserver); } @Override public void onDestroy() { getContentResolver().unregisterContentObserver(contactsObserver); super.onDestroy(); } } 

Придёт прямо к твоему номеру. 3: Сколько времени между двумя вызовами вашего наблюдателя? Я думаю, что ваш наблюдатель вызывается дважды из-за синхронизации контактов, которая также обновляет базу данных. То есть. Первый раз – ваше фактическое обновление, второй раз – когда синхронизация завершена и регистрирует значения синхронизации в той же строке контактов.

Не могли бы вы отключить синхронизацию и посмотреть, будет ли она дважды вызываться?

У вас может быть два или более экземпляра ContactService, для которых все они зарегистрированы в том же приложении ContactsContract.Contacts.CONTENT_URI.

Столкнулась с той же проблемой в моем собственном коде и выяснила, что я дважды вызывал registerContentObserver (). Хотя это было для того же самого URI и в том же классе, мой метод onChange (boolean selfChange) был вызван дважды в результате.