java - Content Observer onChange 方法在 1 次光标更改后调用两次

标签 java android android-contentprovider

我有一个应用程序,我希望将 android 联系人列表中的详细信息发送到远程服务器,以便用户可以在线查看他的联系人。 为此,我想将手机上对联系人列表所做的任何更改通知远程服务器。

我在“ContactsContract.Contacts.CONTENT_URI”上设置了一个 ContentObserver,该服务在手机启动时启动。

我有几个问题,前两个是偶然的,第三个是我主要关心的问题。

1:一旦我设置了一个在我的光标上注册 ContentObserver 的服务,该观察者是否只存在于服务中?我的意思是,如果服务被杀死,contentObserver 会继续观察吗?

2:我怀疑答案是否定的,但我还是会问。是否知道正在更新的联系人正在触发我的 contentObserver 的 onchange 方法?目前我必须编译手机上所有联系人的列表并将它们发送到我的远程服务器,发送正在更新的联系人的详细信息会容易得多。

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);
        }
    }
}

在我的 logCat 中快速生成 2 行:

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

最佳答案

我做了一个类似的实现,并在日历的事件 URI 上设置了一个 ContentObserver。我面临着所有的问题,你现在面临着。所以你对我的解决方案/建议的问题就在这里......

1) Once I have set up a service that registers a ContentObserver on my Cursor, does that observer only exist within the service? I mean, if the service is killed, does the contentObserver continue to observe?

不,它不会通过 URI 观察您的内容。但有解决办法。您可以创建一个始终运行的服务。由于某些内存问题或其他意外解除,该服务将在被解除后立即重新创建。除非明确解除,否则它将始终继续运行。要在您的服务类中创建此类服务覆盖 OnStartCommand(Intent intent, int flags, final int startId) 并返回 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: I suspect the answer is no, but I will ask anyway. Is there anyway of knowing which contact being updated is triggering the onchange method of my contentObserver? currently I have to compile the list of all teh contacts on the phone and send them off to my remote server, it would be so much easier to just send details of the contacts being updated.

你又猜对了。:)。答案是否定的。
无法具体知道哪个联系人已更新。 ContentObserver 只是提供一个事件,让您知道 uri 指向的数据发生了一些变化。但是我认为您处理这种情况的效率很低,因为您正在编译所有联系人的列表并将它们发送回服务器。
我建议您在本地存储中维护一个成功发送到服务器的联系人列表。下次当您在 contentObserveronChange() 方法中接到电话时,您会从 content_URI 获取所有 contacts,将它们与先前存储的列表进行比较,并仅将更新的联系人发送到服务器。

3: This is my main question, when I make a change to my Contact List the onChange method is being fired twice in quick succession. 1 change, 2 calls. Is there anyway of managing this?

是的,这会发生,但我猜你的印象是错误的。就我而言,它曾经随机发射两次或三次甚至更多次。所以我设置了一个 threshold_time 间隔。如果再次触发 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();
        }

    }  

希望这些建议/解决方案会有所帮助。

关于java - Content Observer onChange 方法在 1 次光标更改后调用两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10173996/

相关文章:

java - Java 是 "pass-by-reference"还是 "pass-by-value"?

java - 接收通用类类型

java - 是否有任何理由在 Maven 中为我自己的传递依赖项保留显式依赖声明?

android - 以语音识别模式启动安卓键盘

android - 如何在android中获取字符串的像素宽度?

android - 什么时候做 - java.io.FileNotFoundException : No content provider?

java - 使用 Java FlowLayout

android - 转发图像 URI Intent

java - 获取从图库中选择的图像的路径(在 SD 卡上)

android - 尝试添加新联系人时如何汇总联系人数据?