Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

onChange method of ContentObserver not called when SMS message is read on Android

Tags:

android

I was looking quite a bit on the forums for determining how many SMS messages I have that were not read. The code below seems to work good for received messages, but once I actually read the message the onChange of the ContentObserver is not being called. So, on incoming SMS message the onChange is getting called and I get the correct number, but after reading the message it is not being called. The device is Samsung Note running Android 2.3.6 not rooted. Any help will be appreciated.

public class UnreadSMSContentObserver extends ContentObserver {
    private static final String myTAG="PhoneInfoSMS";
    private static final Uri SMS_INBOX = Uri.parse("content://sms/inbox");

    private ContentResolver mContentResolver;
    private Handler mHandler;
    public int unreadSMS;
    private static final String TAG = "PhoneInfoSMS";

    public UnreadSMSContentObserver(ContentResolver cr, Handler h) {
        super(null);
        mContentResolver = cr;
        mHandler = h;
    }

    public int getUnreadSMS() {
        if (mContentResolver != null) {
            try {
                Cursor c = mContentResolver.query(SMS_INBOX, null, "read = 0", null, null);
                if (c != null) {
                    unreadSMS = c.getCount(); 
                    c.deactivate();
                    Log.d(TAG, unreadSMS + " unread SMS messages");
                    }
                }
            catch (Exception ex) {
                Log.e("ERROR: " + ex.toString(), "");
            }
        }
        return unreadSMS;
    }

    @Override
    public void onChange(boolean selfChange) {
        Log.d(myTAG, "onChange");
        if (mContentResolver != null) {
            getUnreadSMS();
            mHandler.obtainMessage(PhoneInfoServer.CONTENTO_INFOCHANGED, PhoneInfoServer.CONTENTO_US, unreadSMS).sendToTarget();
            Log.d(myTAG, "done");
        }
    }
}

In the manifest file I have the following permissions:

"android.permission.READ_CONTACTS"
"android.permission.READ_SMS"
"android.permission.GET_ACCOUNTS"
"android.permission.BATTERY_STATS"
"android.permission.BLUETOOTH"
"android.permission.BLUETOOTH_ADMIN"
"android.permission.BROADCAST_SMS"
"android.permission.RECEIVE_SMS"
"android.permission.BROADCAST_SMS"
"android.permission.RECEIVE_MMS"

The way I set it up on the calling service is: in the onCreate of the service I do:

mContentResolver = this.getContentResolver();
mUnreadSMSContentObserver = new UnreadSMSContentObserver(mContentResolver, mContentObserversHandler);

in the onStartCommand of the service I do:

mContentResolver.registerContentObserver(Uri.parse("content://sms/"), true, mUnreadSMSContentObserver);               
mContentResolver.registerContentObserver(Uri.parse("content://sms/inbox/"), true, mUnreadSMSContentObserver);

I tried only the content://sms/ and only content://sms/inbox/ and both... did not solve the problem.

P.S. Similar method for the missed calls works perfect!

The application+service is sending over Bluetooth the battery data, missed calls and unread SMS messages to an Arduino based device that displays it on an LED screen. Why? Two reasons: first, this is my first Android program made for fun. The second is I am not carrying the phone with me at home all the time, and it is typically in my home office. If I did not hear it ringing I will still be able to see the LED display telling me I had calls or SMS when passing by.

like image 752
zmashiah Avatar asked May 31 '12 22:05

zmashiah


1 Answers

this solution has worked for me :

 context.getContentResolver().
                registerContentObserver(Uri.parse("content://mms-sms/"), true, smsObserver);
like image 72
SUcpinar Avatar answered Nov 10 '22 14:11

SUcpinar