Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intercept, read and cancel SMS message

Tags:

android

sms

I am looking for a way to hook SMSManager or a lower level mechanism such that I can intercept, read and cancel any outgoing SMS messages before they are sent.

like image 452
Tom Avatar asked Apr 08 '11 01:04

Tom


2 Answers

Obviously this isn't what you want to hear, but Android is simply not designed to permit 3rd party applications to interfere with each other or over-ride the user's free choice.

It does not provide a "hook" type of mechanism for hard interception of basic functionality, short of modifying the build of Android itself installed on the device.

The device administrator interfaces do not include anything for regulating sms.

Yes, occasionally people make products utilizing various "hack" methods to accomplish such things to some extent, but they are contrary to the design of the platform and thus either unreliable or likely to break when various "bug fix" type improvements are made to android. Or they come with limitation in scope, for example replacing the home screen and thus limiting what is easily launched - but only so long as that home screen app remains selected, and not being able to regulate other sources of intents.

You may find an idea attractive enough that you decide to run with it, but bear in mind that unless it's a future introduction to the API intended for doing this kind of thing you would most likely be leveraging an oversight in the design of the platform which it's quite likely will soon be corrected.

like image 86
Chris Stratton Avatar answered Nov 15 '22 07:11

Chris Stratton


Better late then never :)

I have spent 2 days on this... And dont want any other to waste their time :)

  1. Make a service, and register a content observer in service class

UPDATE : added SMS Model Class

      public class SMS {
        public Date date;
        public String from;
        public String message;
        public String to;

        public SMS(String paramString1, String paramString2, String paramString3,Date paramDate) {
            this.from = paramString1;
            this.to = paramString2;
            this.message = paramString3;
            this.date = paramDate;
        }
     }

    public class ServiceClass extends Service implements SMSListener {
    public static boolean sendSms = true;
    private final IBinder mBinder = new LocalBinder();
    public static MyContentObserver mSMSObserver;
    private Context ctx;
    public static SMS param_SMS;
    int myID = -1;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
            // TODO Auto-generated method stub

            myID = startId;
            sendSms = true;
            Context localContext = getApplicationContext();
            ctx = localContext;

            mSMSObserver = new MyContentObserver(null);
            mSMSObserver.setSMSListener(this);
            mSMSObserver.start(localContext);

            return Service.START_STICKY;
     }

        @Override
        public void onDestroy() {
            // TODO Auto-generated method stub
            SharedPreferences prefs = getApplicationContext().getSharedPreferences(
                    "appData", 0);

            if (prefs.getBoolean(CommonStrings.KEY_PREFS_TOGGLE, false)) {

                super.onDestroy();
                Log.e("OnDestroy", "Stopping Service");
                Context localContext = getApplicationContext();
                mSMSObserver.stop(localContext);

                try {
                    stopSelf(myID);
                    Log.e("Stopping self", "Stopping Service");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public IBinder onBind(Intent intent) {
            // TODO Auto-generated method stub
            Log.e("OnBinder", "OnBinder");
            return null;
        }

        @Override
        public void reportIncomingSms(SMS paramSMS) {
            // TODO Auto-generated method stub

        }

        public void reportOutgoingSms(SMS paramSMS) {
            if (!MainActivity.stopped) {
                Log.e("OUT GOING SMS DETECTED", "OUT GOING SMS DETECTED");
                sendSms = true;
                param_SMS = paramSMS;

                // DO ANY THING, Out going Msg detected...

            }
        }

        public class LocalBinder extends Binder {
            public LocalBinder() {
            }

            public ServiceClass getService() {
                return ServiceClass.this;
            }
        }
    }
  1. Extend Content Observer

    public class MyContentObserver extends ContentObserver {
    
    public static final int MESSAGE_TYPE_ALL = 0;
    public static final int MESSAGE_TYPE_DRAFT = 3;
    public static final int MESSAGE_TYPE_FAILED = 5;
    public static final int MESSAGE_TYPE_INBOX = 1;
    public static final int MESSAGE_TYPE_OUTBOX = 4;
    public static final int MESSAGE_TYPE_QUEUED = 6;
    public static final int MESSAGE_TYPE_SENT = 2;
    public static final String TYPE = "type";
    private SMSListener mSMSListener;
    public static long _id;
    private ContentObserver observer;
        public MyContentObserver(Handler handler) {
        super(handler);
        // TODO Auto-generated constructor stub
        }
        private void readFromOutgoingSMS(Context paramContext) {
        if (!MainActivity.stopped) {
            Cursor localCursor = paramContext.getContentResolver().query(
            Uri.parse("content://sms"), null, null, null, null);
            long l = 0;
            int i;
            if (localCursor.moveToNext()) {
                l = localCursor.getLong(localCursor.getColumnIndex("_id"));
                String str1 = localCursor.getString(localCursor
                        .getColumnIndex("protocol"));
                i = localCursor.getInt(localCursor.getColumnIndex("type"));
                if ((str1 != null) || (i != 6))
                    localCursor.close();
                    if (i == 6) {
                    int j = localCursor.getColumnIndex("body");
                    int k = localCursor.getColumnIndex("address");
                    Date localDate = new Date(localCursor.getLong(localCursor
                            .getColumnIndex("date")));
                    String str2 = localCursor.getString(k);
                    String str3 = localCursor.getString(j);
                    localCursor.close();
                        _id = l;
                      // Delete SMS and Save the sms content to custom type variable
                    if (deleteSms(paramContext, l)) {
                        SMS localSMS = new SMS("", str2, str3, localDate);
                        this.mSMSListener.reportOutgoingSms(localSMS);
                    } else {
                        localCursor.close();
                    }
                }
            }
        }
    }
    
    public static boolean deleteSms(Context paramContext, long paramLong) {
        Uri localUri = ContentUris.withAppendedId(Uri.parse("content://sms"),
                paramLong);
        boolean bool = false;
        if (localUri != null) {
            try {
                int j = paramContext.getContentResolver().delete(localUri,
                        null, null);
                if (j == 1)
                    bool = true;
                else
                    bool = false;
            } catch (Exception localException) {
                localException.printStackTrace();
                bool = false;
            }
        }
        return bool;
    }
    
    private void registerContentObserver(final Context paramContext) {
            this.observer = new ContentObserver(null) {
                    public void onChange(boolean paramAnonymousBoolean) {
                        readFromOutgoingSMS(paramContext);
                    }
                };
                paramContext.getContentResolver().registerContentObserver(
                    Uri.parse("content://sms"), true, this.observer);
            }
                public void setSMSListener(SMSListener paramSMSListener) {
                this.mSMSListener = paramSMSListener;
            }
            public void start(Context paramContext) {
                registerContentObserver(paramContext);
                listenForIncomingSms(paramContext);
            }
    
            public void stop(Context paramContext) {
                paramContext.getContentResolver().unregisterContentObserver(
                        this.observer);
            }
            private void listenForIncomingSms(Context paramContext) {
            //.....
            }
    
    }
    
  2. SMS LIstener

     public abstract interface SMSListener {
     public abstract void reportIncomingSms(SMS paramSMS);
    
     public abstract void reportOutgoingSms(SMS paramSMS);
       }
    

Permissions Needed:

   <uses-permission android:name="android.permission.READ_SMS" />
   <uses-permission android:name="android.permission.READ_CONTACTS" />
like image 23
Nadeem Iqbal Avatar answered Nov 15 '22 08:11

Nadeem Iqbal