user2243110
user2243110

Reputation: 133

Intercept Incoming SMS Message and Modify it

Is there a way to intercept an incoming SMS message, and then modify it before presenting it to the user?

If yes to any of the above, could you please provide some pointers to it?

My preferred-solution priority-order is as follows:

  1. Phonegap
  2. Mono
  3. Native

Thank you all in advance!!

EDIT:

For people wondering what is the purpose of this, basically I would like to put a word as a "label" in the sms depending on the content, so when I view the sms, I can see something like "IMPORTANT: blah blah blah", instead of just "blah blah blah".

Upvotes: 8

Views: 11743

Answers (3)

BostonGeorge
BostonGeorge

Reputation: 3190

Yes there is a way, but unfortunately since the rollout of KitKat it isn't that easy any more. To work on versions > Jelly Bean you must have your application run as the default SMS application, that is to modify and abortBroadcast(). For 4.3 and below, create a broadcast receiver and do something like the following:

public void onReceive( Context context, Intent intent ) {
    // Get the SMS map from Intent
    Bundle extras = intent.getExtras();

    String messages = "";

    if ( extras != null ) {
        // Get received SMS array
        Object[] smsExtra = (Object[]) extras.get( SMS_EXTRA_NAME );

        // Get ContentResolver object for pushing encrypted SMS to the incoming folder
        ContentResolver contentResolver = context.getContentResolver();

        for ( int i = 0; i < smsExtra.length; ++i ) {
            SmsMessage sms = SmsMessage.createFromPdu((byte[])smsExtra[i]);

            String body = sms.getMessageBody().toString();
            String address = sms.getOriginatingAddress();

            // Here is where you modify the body of the message!
            messages += "SMS from " + address + " :\n";                   
            messages += body + "\n";

            putSmsToDatabase( contentResolver, sms );
        }
    }
}

private void putSmsToDatabase( ContentResolver contentResolver, SmsMessage sms ) {

    // Create SMS row
    ContentValues values = new ContentValues();
    values.put( ADDRESS, sms.getOriginatingAddress() );
    values.put( DATE, sms.getTimestampMillis() );
    values.put( READ, MESSAGE_IS_NOT_READ );
    values.put( STATUS, sms.getStatus() );
    values.put( TYPE, MESSAGE_TYPE_INBOX );
    values.put( SEEN, MESSAGE_IS_NOT_SEEN );

    try {
        values.put( BODY, sms.getMessageBody() ); // May need sms.getMessageBody.toString()
    }
    catch ( Exception e ) { 
        e.printStackTrace(); 
    }

    // Push row into the SMS table
   contentResolver.insert( Uri.parse( SMS_URI ), values );
}

This info was obtained from here

Almost forgot...constants..

public static final String SMS_EXTRA_NAME = "pdus";
public static final String SMS_URI = "content://sms";

public static final String ADDRESS = "address";
public static final String PERSON = "person";
public static final String DATE = "date";
public static final String READ = "read";
public static final String STATUS = "status";
public static final String TYPE = "type";
public static final String BODY = "body";
public static final String SEEN = "seen";

public static final int MESSAGE_TYPE_INBOX = 1;
public static final int MESSAGE_TYPE_SENT = 2;

public static final int MESSAGE_IS_NOT_READ = 0;
public static final int MESSAGE_IS_READ = 1;

public static final int MESSAGE_IS_NOT_SEEN = 0;
public static final int MESSAGE_IS_SEEN = 1;

Upvotes: 2

Sharad Mhaske
Sharad Mhaske

Reputation: 1103

try out this- //register this class as receiver in manifest file for SMS_RECEIVED intent

  public class SmsReceiver extends BroadcastReceiver {

    private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(SMS_RECEIVED)) {
              abortBroadcast();**this is prevent message to deliver to user**

            Bundle bundle = intent.getExtras();
            if (bundle != null) {
                // get sms objects
                Object[] pdus = (Object[]) bundle.get("pdus");
                if (pdus.length == 0) {
                    return;
                }
                // large message might be broken into many
                SmsMessage[] messages = new SmsMessage[pdus.length];
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < pdus.length; i++) {
                    messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
                    sb.append(messages[i].getMessageBody());
                }
                String sender = messages[0].getOriginatingAddress();
                String message = sb.toString();
                Toast.makeText(context, message, Toast.LENGTH_SHORT).show();

               SmsManager sms = SmsManager.getDefault();
               sms.sendTextMessage(phoneNumber, null, message, null, null);//phone number will be your number. 
            }
        }
    }
}

Upvotes: 5

Dimitar Marinov
Dimitar Marinov

Reputation: 942

Sure! The EASIEST way on iOS is just to create a trigger on the SMS database - /var/mobile/Library/SMS/sms.db

CREATE TRIGGER AFTER INSERT ON message 

then update the record!

The more advanced way of doing it, is hooking private methods, but I won't go that deep right now, you just need to explore the methods :)

BTW, you in any way you NEED a jailbroken device

Upvotes: 2

Related Questions