Intercepting Outgoing SMS
Asked Answered
G

5

30

Is it possible to intercept outgoing SMS before it is actually sent, get its contents then ignore / send it according to some criteria?

eg. block all international text (numbers with leading 00), but allow everything else.

Germ answered 26/9, 2011 at 2:37 Comment(5)
Sounds interesting, can we have more detail though ? What have you tried so far?Funky
This may help you. #2736071Koziel
In fact there is some Intent sent from the application (inspect the source code): Mms/SmsReceiverService: [SMS]Receiver handleMessage : Action =com.android.mms.transaction.SEND_MESSAGE. But it is not ordered broadcast and you cannot stop it from reaching its destination.Teleprinter
I make it work on Emulator !! https://mcmap.net/q/500570/-is-it-possible-to-block-outgoing-smsGuardado
Look out for Read all sms https://mcmap.net/q/500571/-listening-to-outgoing-sms-not-working-androidCurse
D
19

Incoming SMS

You can intercept an incoming sms thru sms listener using Broadcast receiver.You can modify the incoming sms or destroy it so that it does not reaches inbox.

Outgoing SMS

You can listen for outgoing sms by putting content observer over content://sms/out but you can not modify it with the native sms app.You can obviously modify the content of content://sms/out but it has no point.

Diseased answered 17/10, 2011 at 7:48 Comment(3)
I see. I'm gonna try a few things with content://sms/out (like killing the radio when it triggers, although getting the message from the "outbox" is still a problem.) Thanks!Germ
There is no requirement for a sent SMS to be available in any ContentProvider.Uncap
Can I stop a message from being sent?Heda
E
8

Based on what I've been able to find, it seems as though the answer is either, "It's impossible" or, that it could be possible, but you'd need to write your own SMS app, so that you received the text before it became an SMS, and then you could perform whatever checks you'd like on it before calling the API to actually queue it to be sent.

Sorry =(

Excitor answered 13/10, 2011 at 5:1 Comment(0)
P
7

As far as I know, you can spy on outgoing SMS messages but you cannot stop them from being sent out.

Here's how you can detect the outgoing SMS messages: Listen outgoing SMS or sent box in Android

But since this is done basically by reading from a database, I doubt you can stop the SMS from leaving.

I wish you good luck.

Emmanuel

Perfidy answered 12/10, 2011 at 18:27 Comment(0)
F
5

This is what i have done to make an OutgoingSMSReceiver hope it helps some one some dya!

public final class OutgoingSMSReceiver extends Service {


    private static final String CONTENT_SMS = "content://sms/";
    private CallerHistoryDataSource  database =  new  CallerHistoryDataSource(UCDGlobalContextProvider.getContext());
    static String messageId="";


    private class MyContentObserver extends ContentObserver {



        public MyContentObserver() {
            super(null);
        }

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


            Uri uriSMSURI = Uri.parse(CONTENT_SMS);
            Cursor cur = UCDGlobalContextProvider.getContext().getContentResolver().query(uriSMSURI, null, null, null, null);
             // this will make it point to the first record, which is the last SMS sent
            cur.moveToNext();

            String message_id = cur.getString(cur.getColumnIndex("_id"));
            String type = cur.getString(cur.getColumnIndex("type"));

            if(type.equals(Constants.SMS_TYPE_OUTGOING)){

                /**
                 *  onChange is fired multiple times for a single SMS, this is to prevent multiple entries in db.
                 * 
                 */
                if(!message_id.equals(messageId))
                {
                    String content = cur.getString(cur.getColumnIndex("body"));
                    String msisdnWithCountryCodeOrPrefix = cur.getString(cur.getColumnIndex("address"));
                    String msisdn = MSISDNPreFixHandler.fixMsisdn(msisdnWithCountryCodeOrPrefix);

                    Sms sms = new Sms();
                    sms.setType(Constants.SMS_TYPE_OUTGOING);
                    sms.setMsisdn(msisdn);
                    sms.setContent(content);



        Log.i("MyContentObserver", "Sent SMS saved: "+content);                                     

                }
                messageId = message_id;

            }

    }


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




    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        MyContentObserver contentObserver = new MyContentObserver();
        ContentResolver contentResolver = getBaseContext().getContentResolver();
        contentResolver.registerContentObserver(Uri.parse(CONTENT_SMS),true, contentObserver);
        //Log.v("Caller History: Service Started.", "OutgoingSMSReceiverService");
    }

    @Override
    public void onDestroy() {
        //Log.v("Caller History: Service Stopped.", "OutgoingSMSReceiverService");    
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        //Log.v("Caller History: Service Started.", "OutgoingSMSReceiverService");
        /**
         *   Constant to return from onStartCommand(Intent, int, int): if this service's process is killed while it is started 
         *   (after returning from onStartCommand(Intent, int, int)), then leave it in the started state but don't retain this delivered intent. 
         *   Later the system will try to re-create the service. Because it is in the started state, it will guarantee to call 
         *   onStartCommand(Intent, int, int) after creating the new service instance; if there are not any pending start commands to be 
         *   delivered to the service, it will be called with a null intent object, so you must take care to check for this.
         *   This mode makes sense for things that will be explicitly started and stopped to run for arbitrary periods of time, such as a 
         *   service performing background music playback.
         */
        return START_STICKY;

    }

    @Override
    public void onStart(Intent intent, int startid) {
        Log.v("Caller History: Service Started.", "OutgoingSMSReceiverService");
    }
}
Freshwater answered 14/11, 2012 at 7:36 Comment(1)
CallerHistoryDataSource can't resolve import using api target 23 min19Curse
G
2

Based on "Saad Akbar" response , i make it work but only with rooted device with permission MODIFY_PHONE_STATE

public class OutgoingSMSReceiver extends Service
{

private static final String CONTENT_SMS = "content://sms/";
static String messageId = "";

private class MyContentObserver extends ContentObserver
{

    Context context;
    private SharedPreferences prefs;
    private String phoneNumberBlocked;

    public MyContentObserver(Context context) {
        super(null);
        this.context = context;
    }

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

        prefs = context.getSharedPreferences("com.example.testcall", Context.MODE_PRIVATE);
        phoneNumberBlocked = prefs.getString("numero", "");

        Uri uriSMSURI = Uri.parse(CONTENT_SMS);
        Cursor cur = context.getContentResolver().query(uriSMSURI, null, null, null, null);

        if (cur.moveToNext())
        {
            String message_id = cur.getString(cur.getColumnIndex("_id"));
            String type = cur.getString(cur.getColumnIndex("type"));
            String numeroTelephone=cur.getString(cur.getColumnIndex("address")).trim();

            if (numeroTelephone.equals(phoneNumberBlocked))
            {
                if (cur.getString(cur.getColumnIndex("type")).equals("6"))
                {                       
                    ContentValues values = new ContentValues();
                    values.put("type", "5");
                    context.getContentResolver().update(uriSMSURI,values,"_id= "+message_id,null);                          
                }
                else if(cur.getString(cur.getColumnIndex("type")).equals("5"))
                {                           context.getContentResolver().delete(uriSMSURI,"_id=?",new String[] { message_id});                      
                }
            }
        }
    }

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

@Override
public void onCreate()
{
    MyContentObserver contentObserver = new MyContentObserver(getApplicationContext());
    ContentResolver contentResolver = getBaseContext().getContentResolver();
    contentResolver.registerContentObserver(Uri.parse(CONTENT_SMS), true, contentObserver);

}

}

<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
Guardado answered 2/1, 2014 at 15:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.