Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: content observer's "onChange()" method is called multiple times

I am using a content observer for content://sms. I am writing all the messages to a text file in SD card. But the onChange() method in the content observer is called multiple times and the same message is written multiple times to the text file. How to avoid this? Also I want to know if having the content observer will slow down the phone.

like image 800
Vivek Avatar asked May 17 '11 05:05

Vivek


3 Answers

You need to override deliverSelfNotifications() to return true.

class ObserverSms extends ContentObserver {
private Context mContext;

public ObserverSms(Context context, Handler handler) {
    super(handler);
    mContext = context;
}

@Override
public boolean deliverSelfNotifications() {
    return true;
}

@Override
public void onChange(boolean selfChange) {
    super.onChange(selfChange);
    MyLog.logDebugInConsole(TAG, "Sms Database Changed");
}
}
like image 149
garmax1 Avatar answered Oct 15 '22 18:10

garmax1


Vivek, please ensure that you unregister your content observer any time you leave the activity e.g. in onDestroy() method, call unregisterContentObserver(). Hope this help ! (in my case it worked)

like image 33
Vasu Avatar answered Oct 15 '22 19:10

Vasu


Try this to avoid multiple execution of onChange()

private Context context;
    private static int initialPos;
    private static final String TAG = "SMSContentObserver";
    private static final Uri uriSMS = Uri.parse("content://sms/sent");

    public SmsObserver(Handler handler, Context ctx) {
        super(handler);
        context = ctx;
        trackMeData = context.getSharedPreferences("LockedSIM", 0);
        initialPos = getLastMsgId();

    }

    @Override
    public void onChange(boolean selfChange) {
        super.onChange(selfChange);
        queryLastSentSMS();
    }

    public int getLastMsgId() {

        Cursor cur = context.getContentResolver().query(uriSMS, null, null, null, null);
        cur.moveToFirst();
        int lastMsgId = cur.getInt(cur.getColumnIndex("_id"));
        Log.i(TAG, "Last sent message id: " + String.valueOf(lastMsgId));
        return lastMsgId;
    }

    protected void queryLastSentSMS() {

        new Thread(new Runnable() {

            @Override
            public void run() {
                Cursor cur =
                    context.getContentResolver().query(uriSMS, null, null, null, null);

                if (cur.moveToNext()) {



                    try {

                        String body = cur.getString(cur.getColumnIndex("body"));

                        if (initialPos != getLastMsgId()) {

                            String receiver = cur.getString(cur.getColumnIndex("address"));
                            Log.i("account", myDeviceId);
                            Log.i("date", day + "-" + month + "-" + year + " "
                                + hour + ":" + minute + ":" + seconde);
                            Log.i("sender", myTelephoneNumber);
                            Log.i("receiver", receiver );


                            // Then, set initialPos to the current position.
                            initialPos = getLastMsgId();

                            sendsmstoph(receiver, body);
                        }
                    } catch (Exception e) {
                        // Treat exception here
                    }
                }
                cur.close();
            }
        }).start();

    }
like image 1
arjun Avatar answered Oct 15 '22 17:10

arjun