草庐IT

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

coder 2023-06-09 原文

我有一个应用程序,我希望将 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 - Content Observer onChange 方法在 1 次光标更改后调用两次的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  5. ruby-on-rails - Ruby on Rails 迁移,将表更改为 MyISAM - 2

    如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设

  6. Ruby 方法() 方法 - 2

    我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby​​-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco

  7. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  8. ruby - Highline 询问方法不会使用同一行 - 2

    设置:狂欢ruby1.9.2高线(1.6.13)描述:我已经相当习惯在其他一些项目中使用highline,但已经有几个月没有使用它了。现在,在Ruby1.9.2上全新安装时,它似乎不允许在同一行回答提示。所以以前我会看到类似的东西:require"highline/import"ask"Whatisyourfavoritecolor?"并得到:Whatisyourfavoritecolor?|现在我看到类似的东西:Whatisyourfavoritecolor?|竖线(|)符号是我的终端光标。知道为什么会发生这种变化吗? 最佳答案

  9. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  10. ruby - 多个属性的 update_column 方法 - 2

    我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2

随机推荐