Skip to content Skip to sidebar Skip to footer

Android History Content Observer

I implemented content observer of history but it is behaving weird.For every change in history its onChange() function runs 3-5 times. static class BrowserOberser extends ContentOb

Solution 1:

This is how I finally solved the problem for my case atleast(I wanted to read history when there is change in history)

@OverridepublicvoidonChange(boolean selfChange) {
        super.onChange(selfChange);
        /**
         * Get SharedPreferneces of the user
         */
        SharedPreferences pref= myContext.getSharedPreferences("com.tpf.sbrowser", 
                Context.MODE_PRIVATE);
        longwherelong= pref.getLong("Date", 0);
        DatabaseManager db=newDatabaseManager(myContext,1);
        String[] proj = newString[] { Browser.BookmarkColumns.TITLE,
                Browser.BookmarkColumns.URL, BookmarkColumns.DATE,};
        Stringsel= Browser.BookmarkColumns.BOOKMARK + " = 0"; 
        CursormCur= myContext.getContentResolver().query(
                Browser.BOOKMARKS_URI, proj, sel, null, null);
        Log.d("onChange", "cursorCount"+mCur.getCount());
        mCur.moveToFirst(); 
        Stringtitle=""; 
        Stringurl=""; 
        long lastVisitedDate=0;
        DbMessagemsg=newDbMessage(lastVisitedDate,url, title);
        /**
         * Start reading the user history and dump into database
         */if(mCur.moveToFirst() && mCur.getCount() > 0) { 
              while (mCur.isAfterLast() == false) {
                  title =mCur.getString(0); 
                  url = mCur.getString(1); 
                  lastVisitedDate =mCur.getLong(2); 
                  if ((lastVisitedDate>wherelong) && (!title.equals(url))) {
                      msg.set(lastVisitedDate, url, title);
                      db.InsertWithoutEnd(msg);
                      pref.edit().putBoolean("BrowserHistoryRead", true).commit();
                      pref.edit().putLong("Date", lastVisitedDate).commit();
                      myContext.updateTime(wherelong,lastVisitedDate);
                      wherelong=lastVisitedDate;
                  }
                  mCur.moveToNext(); 
              } 
          }
    }

But still if would be great if someone could tell which iteration of onChange(in the simple code of question) corresponds to exactly which state in page loading. From what I learned, in first iteration title was same as url and in the third iteration the correct page title was present. But during redirection, onChange got called upto 5 times. So can someone confirm which iteration coressponds to which stage?

Solution 2:

I think I may find the answer. First I want to say that my English is limited, I hope that you can understand me.

Indeed, onChange(); runs several times for each change in history, at least two times.

Because when user use the browser to browse a website, the system add a history in database, and onChange(); is called. But right now the system don't know the title of the url. After the system got the title of the url, the system updates the database and onChange(); is called second time.

And, if the url is redirecting during the time, every time the system gets a new url, the system will update the database too, so onChange(); is called too. So, I think onChange will be called several times every change. Hope you can understand my English.

Solution 3:

The exact way in which history is updated is an implementation detail you probably do not want to be relying on. Rather than trying to guess whether the update is finished or not based on the values of various fields, I would suggest restarting a timer each time onChange(..) is called. If the timer expires, you can be reasonably certain that history has finished updating.

Edit Example of how to use a timer:

staticclassBrowserOberserextendsContentObserverimplementsRunnable {
    privateHandler h;

    publicBrowserOberser() {
        super(null);
        h = newHandler();
    }

    @OverridepublicbooleandeliverSelfNotifications() {
        returntrue;
    }

    @OverridepublicvoidonChange(boolean selfChange) {
        super.onChange(selfChange);
        h.removeCallbacks(this);
        h.postDelayed(this, 500);
    }

    publicvoidrun() {
        Log.d("history observer", "change timer elapsed");
    }

}

Post a Comment for "Android History Content Observer"