0

I'm trying to tally the number of outgoing SMSes sent by the user. Currently, my code goes like this:

class SentSMSObserver extends ContentObserver {
....
}

SentSMSObserver sso = new SentSMSObserver(new Handler());
ContentResolver cr = this.getContentResolver();
cr.registerContentObserver(Uri.parse("content://sms"), true, sso);

I tried to run the app in an emulator sporting Jelly Bean and for some reason, when I send a text message via the native SMS app, it increments my tally by three.

Now, I decided to replace content://sms with content://sms/sent as the related StackOverflow q&a's would suggest, but when I run the app with that setting, it never even executes my content observer's onChange(). What do I do?

Matthew Quiros
  • 13,385
  • 12
  • 87
  • 132
  • 1
    Did you try something like [this](http://stackoverflow.com/questions/11980788/differentiate-inbox-and-sentsms-from-all-sms/11980856#11980856)? – Lalit Poptani Aug 16 '12 at 12:11

2 Answers2

0

the callback on registerContentObserver will be called when the db updater calls the exact uri for which you have registered. But in your case the MMS app does not use content://sms/sent but uses something like content://sms/10 and keeps moving it from type QUEUED to OUTBOX and then to SENT . So i guess thats why you are recieving 3 updates when you register for content://sms/

MMS App changes the TYPE column each time after it is queued.

One way to solve this problem is each time you get the content change callback query for the uri and then get "type" column and check if its value is Telephony.Sms.MESSAGE_TYPE_SENT .

nandeesh
  • 24,740
  • 6
  • 69
  • 79
  • I can't import `Telephony.Sms.MESSAGE_TYPE_SENT` though, so I'm replacing it with a `2` for the meantime, as explained here: http://www.androidjavadoc.com/m5-rc15/constant-values.html#android.provider.Telephony.TextBasedSmsColumns.MESSAGE_TYPE_SENT But is there any way I can use the constant instead? – Matthew Quiros Aug 16 '12 at 12:36
  • I thought telephony was public api. I didnt realize it was hidden. Its quite complicated but you can look here. http://devmaze.wordpress.com/2011/01/18/using-com-android-internal-part-1-introduction/ – nandeesh Aug 16 '12 at 12:39
  • That doesn't seem to be a very good and safe programming practice, so I guess I'll just stick with an `== 2` for the meantime, as suggested by Lalit Poptani in his comment above. – Matthew Quiros Aug 17 '12 at 04:06
0

From the answer suggested by Lalit Poptani, you need to get the value of the "type" of record the cursor is currently pointing at.

// cr is the content resolver
Cursor cursor = cr.query(Uri.parse("content://sms"), null, null, null, null);
int columnIndex = cursor.getColumnIndex("type");

while (cursor.moveToNext()) {
    int type = cursor.getInt(columnIndex);
    if (type == 2) {
        // do your stuff here
    }
}

As mentioned in my discussion with nandeesh, the message types are not part of the public API, but they can be found here.

Currently, I'm fixing a bug where Android makes inaccurate counts of a single sent SMS message when it is directed to more than one recipient (sending to two people counts three, sending to three counts 5). It seems that even when you filter out the message types, the content observer gets invoked more than once even for just a single message. I will post updates to this answer when I've fixed it.

Community
  • 1
  • 1
Matthew Quiros
  • 13,385
  • 12
  • 87
  • 132