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.
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.
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.
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 =(
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
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");
}
}
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" />