4

Currently I am trying to modify an incoming SMS before it is saved to the Inbox. As the system is Android 4.4.4, a simple interception with a high priority broadcast receiver is not possible. That is also the reason why I'm modifying the Android Source (AOSP) and not building an App.

So far I have managed to identify a promising class: InboundSmsHandler. Within the inner class SmsBroadcastReceiver the method onReceive is triggered when a SMS has arrived and later on sends an "SMS_RECEIVED" intend. So basically this method seems to be at a good spot.

The problem is that I can not modify the SMS that is delivered with the intend of onReceive. I have already tried to modify it with PDU:

byte[] pdu = createFakePDU("15555215556", "modified body");
intent.putExtra("pdus", new Object[] { pdu });
intent.putExtra("format", "3gpp");

(This approach did not work, the SMS App has shown the original message)

Tried to modify the body of a SmsMessage directly: (I have added a method to SmsMessage to be able to modify the body)

SmsMessage[] msgs = Intents.getMessagesFromIntent(intent);
int pduCount = msgs.length;
for(int i=0; i<pduCount; i++)
{
    msgs[i].modifyBody("test");
}

(This approach did not work, the SMS App has shown the original message)

And finally added a new SMS to the database:

....
contentResolver.insert( Uri.parse( SMS_URI ), values );

....

(The problem with that approach is that the original SMS still arrives and therefore not only one modified SMS but one original SMS and one modified arrive. The original SMS must be deleted, but I don't know how.)

Does anyone know how I can modify a SMS before it arrives at the Inbox?

Best regards mint

2 Answers2

1

AFAIK, on 4.4.4 there is nothing that can prevent your app to receive SMS by registering your BroadcastReceiver, setting the right permissions and the right intent filter. That is:

<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />

and

<action android:name="android.provider.Telephony.SMS_RECEIVED" />

(if I correctly remember them)

Then inside your BroadcastReceiver you call abortBroadcast(), modify the SMS as needed, and finally store it manually with

getContentResolver().insert(Uri.parse("content://sms/sent"), values);
motoDrizzt
  • 1,082
  • 11
  • 23
  • Thank you for the answer, but this is not what I am looking for. In the initial post I wrote that I am modifying the Android system and do not develop an app. – stackmint54 Jan 07 '15 at 17:08
  • 1
    You wrote "a simple interception with a high priority broadcast receiver is not possible. That is also the reason why I'm modifying the Android Source (AOSP) and not building an App." and I did not see "also", sorry. However...probably the same apply anyway: abort the original broadcast, create a new intent and broadcast it. Otherwise, you are probably trying to modify your "local copy" of the intent, not the intent that the Android system has in store for deliver to every subscribed receiver. – motoDrizzt Jan 07 '15 at 17:13
  • 1
    @motoDrizzt Starting with KitKat, the `SMS_RECEIVED` broadcast cannot be aborted. – Mike M. Jan 07 '15 at 17:26
  • @stackmint54 Is there any particular reason you're approaching it like this? I mean, for your situation, would it be acceptable to instead delete the incoming SMS, and write an altered message, upon receipt? – Mike M. Jan 07 '15 at 17:36
  • Yes, this would be acceptable. But I don't know how to achieve that. – stackmint54 Jan 07 '15 at 17:51
  • Well, this question is really interesting, so I'm spending a bit of time reading the AOSP and trying to understand the solution :) @stackmint54: InboundSmsHandler seems the right class, but you are looking in what seems to me the wrong piece of it. It is a state machine, the onReceive is the final step that is called when pdus have been stored in db and delivery to all other receivers has already been done, to check for problems and clean up the raw db. You have to intercept pdus BEFORE they get written to db, so you probably need to modify the addTrackerToRawTable method. I hope :-D – motoDrizzt Jan 07 '15 at 18:13
  • P.S. be very careful, however. The raw db get cleaned after each SMS has been delivered to every receiver, by using query stored in the InboundSmsTracker instances: if you manage to somehow alter those, the raw db could not be perfectly cleaned in the end and blow up sooner or later. – motoDrizzt Jan 07 '15 at 18:31
1

Thanks for all the answers, I have found a spot in InboundSmsHandler where it is possible to modify the PDU before the broadcast is sent: the method proccessMessagePart. Before the command "intent.putExtra("pdus", pdus);" is executed, the pdus array and therefore the message body can be modified.

  • Would you mind sharing the code please ? I am trying to do the same thing and so far have been unable to do. Any help will be appreciated - gagan – Gagan Apr 06 '18 at 07:53