(下面添加了工作代码摘录)
我的应用需要收到所有联系人的插入和删除(可能还有更新,但不太重要)的通知。这意味着当应用程序启动时,它需要一个更改列表。在运行时应立即通知它(甚至可以在运行时对应用程序外部的联系人进行更改吗?)。
我应该使用 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);
}