Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Content Observer's onChange Method fired multiple Times

I know you are tempted to mark this a duplicate but wait, let's go through this again with my detailed (but failed) attempts.

Strategy 1: Algorithm: Answer

  1. The first time the onChange is fired, get the id of the row updated

  2. The next time the onChange is fired again get id of row updated

  3. Match the id

  4. Ignore if same id

Problem with this approach is that it is vulnerable to race conditions. If by the time you get the id of the updated row, onChange has fired for the second time, this Algorithm fails. This originated from my personal experience while testing on slow machines or machines working at peak capacity.

Strategy 2: Algorithm:Answer

Override deliverSelfNotifications() to return true.

This seems promising at first but fails to work. The code I used for reference:

In Main Activity:OnCreate Method I register:

getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, new CtObserver(new Handler()));

Then in a separate Class:

package com.example.testproject;

import android.database.ContentObserver;
import android.os.Handler;
import android.util.Log;

/**
 * @author Time Traveller
 */

public class CtObserver extends ContentObserver {

public CtObserver(Handler handler) {
    super(handler);
}

public  boolean  deliverSelfNotifications(){
    return true;
}

@Override
public void onChange(boolean selfChange) {
    super.onChange(selfChange);
    Log.e("onChange","Fired");
}
}

Why you should contribute to this answer:
Quering SMS content Provider is the only way for Non Default Apps to capture the event for the Sent SMS. But till now I have not found any convincing fully functional answer for this method. So we really need to get some minds on this !!.

Questions:

  1. What is the functional(non tweaked) way of simply knowing that a SMS was written to the Content Provider only once?
  2. What is the correct way of using deliverSelfNotifications() in Content Observer Class?

You need not answer all the questions, just tell us anything you know.

like image 809
Dilnoor Singh Avatar asked Mar 19 '15 19:03

Dilnoor Singh


1 Answers

deliverSelfNotifications() most possibly designed to separate data changes from presentation changes. For example, content could be sorted in your app, but there are no need for external applications to acquire data again just because it was sorted, since most time this will be irrelevant (that application probably uses different presentation anyway). In other words - this method controls if you want to receive changes made to content by provider itself which may or may not actually reflect data changes in meaningful to you application ways.

In order to use it you need a ContentObservable implementation that makes use of self-change notifications.

For another question i'd like to suggest HashSet for storing message ids. With it you can compare id of message to all ever processed messages, not just last one, thus eliminating problem you stated.

like image 91
weaknespase Avatar answered Nov 16 '22 14:11

weaknespase