Search code examples
javaandroidsmscontentobserver

Listening to outgoing sms not working android


I am trying to listen to outgoing sms messages. I was following the accepted answer here but it is not working. I'm not sure where I am going wrong. I am no familiar at all with Content Observers so forgive my ignorance.

I wanted to create it in a service so it would be running all the time. here is my code in that service:

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;

public class SmsOutgoingObserver extends Service {
    public SmsOutgoingObserver() {
    }
    /* this method handles a single incoming request */
    @Override
    public int onStartCommand(Intent intent, int flags, int id) {

        Log.d("OUTGOING", "RUNNING SERVICE");

        return START_STICKY; // stay running
    }
    @Override
    public IBinder onBind(Intent intent) {
        return null; // disable binding
    }

    public class SmsObserver extends ContentObserver {

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

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

            Uri uriSMSURI = Uri.parse("content://sms/out");
            Cursor cr = SmsOutgoingObserver.this.getContentResolver().query(uriSMSURI, null, null, null, null);

            cr.moveToNext();
            String address = cur.getString(cr.getColumnIndex("body"));

            Log.d("OUTGOING", address);

            cr.close();

            //Database.messageReceived(SmsOutgoingObserver.this, address);
        }
    }
}

What am I doing wrong?


Solution

  • In addition to the silly mistake on my part that @CommonsWare pointed out, me missing

    @Override
    public void onCreate() {
        super.onCreate();
    
        ContentResolver contentResolver = this.getContentResolver();
        contentResolver.registerContentObserver(Uri.parse("content://sms/out"),true, new SmsObserver(new Handler()));
    }
    

    the other issue was actually in these two lines

    contentResolver.registerContentObserver(Uri.parse("content:&‌​#47;/sms/out‌​"),true, new SmsObserver(new Handler()));
    

    and

    Uri uriSMSURI = Uri.parse("content://sms/out");
    

    where I changed the content://sms/out to content://sms and then proceeded to check for the type to make sure the change I was getting was actually an outgoing message. I also had to make sure to check for multiple calls like so:

    if (cr.getInt(cr.getColumnIndex("type")) == 2) {
        if(id != cr.getInt(cr.getColumnIndex(cr.getColumnName(0)))) {
            id = cr.getInt(cr.getColumnIndex(cr.getColumnName(0)));
    
            String address = cr.getString(cr.getColumnIndex("address"));
            Database.messageSent(SmsOutgoingObserver.this, address);
                Log.d("OUTGOING", address);
            } else {
                Log.d("OUTGOING", "MESSAGE ALREADY LOGGED");
            }
         };
    }
    

    and simply defined private int id = 0; as a global variable