(выдержка из рабочего кода добавлена ниже)
Мое приложение должно быть уведомлено обо всех вставках и удалениях (и, возможно, обновлениях, но менее важных) контактов. Это означает, что при запуске приложения ему потребуется список изменений. Пока оно работает, оно должно быть немедленно уведомлено (возможно ли вообще вносить изменения в контакты вне приложения во время его работы?).
Должен ли я использовать ContentObserver? Нужна ли мне услуга? Есть ли способ при запуске приложения получить список изменений, произошедших с момента последнего запуска приложения?
Спасибо.
ContentObserver действительно работает. Однако для контактов он делает гораздо меньше, чем я надеялся. Вы получаете только уведомление о том, что что-то изменилось (на самом деле, вы можете получить несколько уведомлений). Ты не узнаешь, что изменилось. Хотя лучше, чем отсутствие уведомления, я думаю.
Когда вы получите уведомление, вам нужно будет выполнить запросы, чтобы узнать, изменились ли какие-либо из интересующих вас контактов. Если вам нужно проверить их все, я думаю, вам лучше использовать SyncAdapter.
Вот код, который я в итоге использовал. Сначала подкласс ContentObserver; это получает уведомления от любого провайдера, с которым вы регистрируетесь (см. следующий блок кода):
class MainContentObserver extends ContentObserver
{
public MainContentObserver (Handler handler)
{
super (handler);
}
@Override
public void onChange (boolean selfChange)
{
Message msg = handler.obtainMessage();
msg.what = CONTACTS_CHANGED; // const int declared elsewhere
msg.obj = null;
handler.sendMessage (msg);
}
}
Вот второй блок - это onCreate из вашей активности (или он может быть в onResume). Есть две важные части. Во-первых, я реализую и создаю экземпляр обработчика. Это будет получать «сообщения» от наблюдателя, который работает в отдельном потоке, и передавать их моей активности. Вторая часть — это создание наблюдателя, которое происходит через вызов регистра.
@Override
public void onCreate (Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// receive notices from our background threads.
handler = new Handler()
{
@Override
public void handleMessage (Message msg)
{
if (msg.what == CONTACTS_CHANGED) // const int declared elsewhere
System.out.println ("handler: contacts changed");
else
throw new IllegalArgumentException ("unrecognized handler message source: " + msg.what);
}
};
// register content observer for contact changes
contactsObserver = new MainContentObserver (handler);
getContentResolver().registerContentObserver (ContactsContract.AUTHORITY_URI, true,
contactsObserver);
... other initialization ...
}
Наконец, еще один блок кода - вам нужно отменить регистрацию наблюдателя или (я читал) у вас будет утечка памяти. (Если вы зарегистрируетесь в onResume, обязательно отмените регистрацию в onPause.)
@Override
public void onDestroy ()
{
super.onDestroy();
getContentResolver().unregisterContentObserver (contactsObserver);
}