Java 在游标发生1次更改后调用了两次Content Observer onChange方法
我有一个应用程序,我希望将android联系人列表中的详细信息发送到远程服务器,这样用户就可以在线查看他的联系人。 为此,我想通知远程服务器在手机上对联系人列表所做的任何更改 我已经在“Contacts contract.Contacts.CONTENT\u URI”上设置了ContentObserver,该服务在手机启动时启动 我有几次安静,前两次是偶然的,第三次是我最担心的 1:一旦我设置了一个在我的游标上注册ContentObserver的服务,该观察者是否只存在于该服务中?我的意思是,如果服务被终止,contentObserver会继续观察吗 2:我想答案是否定的,但我还是会问。有没有办法知道更新的联系人触发了我的contentObserver的onchange方法?目前,我必须编辑手机上所有联系人的列表,并将其发送到我的远程服务器,只需发送正在更新的联系人的详细信息就可以轻松得多 3:这是我的主要问题,当我更改联系人列表时,onChange方法会连续两次被触发。1个零钱,2个电话。有没有办法管理这件事Java 在游标发生1次更改后调用了两次Content Observer onChange方法,java,android,android-contentprovider,Java,Android,Android Contentprovider,我有一个应用程序,我希望将android联系人列表中的详细信息发送到远程服务器,这样用户就可以在线查看他的联系人。 为此,我想通知远程服务器在手机上对联系人列表所做的任何更改 我已经在“Contacts contract.Contacts.CONTENT\u URI”上设置了ContentObserver,该服务在手机启动时启动 我有几次安静,前两次是偶然的,第三次是我最担心的 1:一旦我设置了一个在我的游标上注册ContentObserver的服务,该观察者是否只存在于该服务中?我的意思是,如
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);
}
}
}
结果在我的logCat中有两条快速行:
detected change in contacts: false
detected change in contacts: false
我做了一个类似的实现,并在日历的事件
URI
上设置了ContentObserver
。我面对了你现在面临的所有问题。所以你的问题和我的解决方案/建议都在这里
1) 一旦我建立了一个在上注册ContentObserver的服务
我的光标,
该观察者是否仅存在于服务中?我是说,如果服务被杀了,
内容观察者是否继续观察
不,它不会通过URI观察您的内容。但这是有解决办法的。您可以创建一个始终运行的服务。由于内存问题或其他意外取消,此服务一被取消,将立即重新创建。它将始终继续运行,除非明确取消它。要在服务类中创建这样的服务覆盖onstart命令(Intent-Intent,int-flags,final-int-startId)
,请返回START\u-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:我想答案是否定的,但我还是会问。还有吗
知道哪一个
正在更新的联系人正在触发我的contentObserver的onchange方法?
目前,我必须整理所有电话联系人的名单,并将其发送给
在我的远程服务器上,只发送正在更新的联系人的详细信息会容易得多
你又猜对了。答案是否定的。无法具体知道哪个联系人已更新。ContentObserver只提供一个事件,让您知道uri所指向的数据已经发生了一些更改。但我认为您处理这种情况的效率很低,因为您正在编译所有联系人的列表并将其发送回服务器。
我建议您在本地存储中维护一个联系人列表,这些联系人已成功发送到服务器。下次当您在
contentObserver
的onChange()
方法中接到呼叫时,您将从content\u URI
获取所有联系人,将其与以前存储的列表进行比较,并仅将更新的联系人发送到服务器
3:这是我的主要问题,当我更改联系人列表时
onChange方法
很快就被解雇了两次。1个零钱,2个电话。有管理的方法吗
这个
是的,这种情况会发生,但我想你的印象是错误的。在我的例子中,它曾经随机发射两到三次甚至更多次。所以我设定了一个时间间隔的阈值。如果再次触发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();
}
}
希望这些建议/解决方案能有所帮助。考虑如何注册观察员。registerContentObserver
的第二个参数是boolean notifyForDescendents
,您已将其设置为true
。因此,当ContactsContract.Contacts.CONTENT\u URI或其任何描述标准URI发生更改时,您将收到通知。可能是对具有给定id的联系人的某些操作会触发特定联系人uri和全局联系人uri的通知,第二个参数为true
您的观察者会同时观察到这两个参数
另一件事是,您可以为特定联系人id uri注册content observer-ContentURI.withAppendedId(ContactsContract.Contacts.content\u uri,contactId)
。然而,这与您的问题无关,但为每个联系人注册单独的观察者看起来相当难看;)
另一个建议是:可能将observer保留为最终字段,而不是在onCreate中重新创建它(但只在那里注册它)
直接到你的3号:两次给你的观察者打电话之间有多长时间?我想你的观察者会因为联系人同步而被呼叫两次,这也会更新数据库。第一次是您的实际更新,第二次是同步完成并在同一联系人行中注册其同步值时
您能关闭同步并查看它是否仍然被调用两次吗?在我自己的代码中遇到了同样的问题,并发现我调用了registerContentObserver()两次。尽管它是针对完全相同的URI并且在同一个类中,但我的onChange(布尔自更改)方法被调用了两次。您可能有两个或多个ContactService实例,它们都注册为相同的ContactsContacts.Contacts.CONTENT\u URI。+1,10000ms秒在所有情况下都能正常工作吗,你有没有从用户那里得到任何反馈,谢谢?我还没有从用户那里得到任何反馈。
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();
}
}