John
John

Reputation: 243

Onchange function of the content observer class being called more than once

I am using a contentObserver to monitor the content of the sms content provider, I have put a Log.d() tag for debugging and the tag in the logcat is being seen more than once meaning the onchange() id being called more than once, how do I prevent this from happening. I have implemented the observer in a service running in the background. Here is the code

package com.messageHider;

 import android.app.Service;
 import android.content.ContentResolver;
 import android.content.Intent;
 import android.database.ContentObserver;
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.IBinder;
 import android.util.Log;
 import android.widget.Toast;

 public class smsSentService extends Service {
ContentResolver contentResolver;
Uri uri=Uri.parse("content://sms/");
Handler handler;
@Override
public IBinder onBind(Intent arg0) {
    return null;
}
@Override
public void onCreate() {
    contentResolver=getContentResolver();
    contentResolver.registerContentObserver(uri, true, new contentObserver(handler));
    Log.d("SENTSERVICE", "Service created");
    super.onCreate();
}
@Override
public void onStart(Intent intent, int startId) {
    Log.d("SENTSERVICE", "Service started");
    super.onStart(intent, startId);
}
@Override
public void onDestroy() {
    super.onDestroy();
}
public class contentObserver extends ContentObserver
{
    public contentObserver(Handler handler) {
        super(handler);

    }
    @Override
    public void onChange(boolean selfChange) {
        Cursor cursor=contentResolver.query(uri, null, null, null, null);
        cursor.moveToFirst();
        String type=cursor.getString(cursor.getColumnIndex("type"));
        Log.d("THEMESSAGE", type);
        super.onChange(selfChange);
    }
}

}


Upvotes: 3

Views: 3390

Answers (4)

james04
james04

Reputation: 1920

In order to observe the content of whatever you want you have to register the observer the way you have. However the onChange callback is getting called with different flags for example ContentResolver.NOTIFY_INSERT or ContentResolver.NOTIFY_UPDATE and others, meaning that some content just got inserted or updated. So inside your contentObserver perhaps you need to check the event that caused the callback to be called

private val contentObserver = object : ContentObserver(Handler(Looper.getMainLooper())) {
        override fun onChange(selfChange: Boolean, uri: Uri?, flags: Int) {
            super.onChange(selfChange, uri, flags)

            uri?.let {
                if (flags == ContentResolver.NOTIFY_INSERT)
                    // do something
            }
        }
    }



....
contentResolver.registerContentObserver(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI, true, contentObserver
        )

The above example observe the content of a new image inserted from the application. I dont know how that could help to your example but i got the same problem as yours until i checked the Flag

Hope this helped..!

Upvotes: 0

francas
francas

Reputation: 331

Just a recommendation: register the content observer on the onResume method and unregister it on the onPause.

Upvotes: 1

garmax1
garmax1

Reputation: 881

You need to override deliverSelfNotifications() to return true.

class contentObserver extends ContentObserver { private Context mContext;

    public contentObserver(Handler handler) {
        super(handler);

    }

    @Override
    public void onChange(boolean selfChange) {
        Cursor cursor=contentResolver.query(uri, null, null, null, null);
        cursor.moveToFirst();
        String type=cursor.getString(cursor.getColumnIndex("type"));
        Log.d("THEMESSAGE", type);
        super.onChange(selfChange);
    }

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

Upvotes: 0

MattC
MattC

Reputation: 12327

I was using a content observer for watching outbound SMS messages and noticed that if you attempted to send an outbound SMS from the emulator, you'd actually see 3 instances of it go by because it was trying to resend the text but failing. Are you also seeing this for inbound text messages as well?

If it's just for outbound SMS messages then look at the SMS status field. A -1 value indicates a failure.

Upvotes: 0

Related Questions