Перехват исходящих SMS - PullRequest
       34

Перехват исходящих SMS

29 голосов
/ 26 сентября 2011

Можно ли перехватить исходящее SMS до его фактической отправки, получить его содержимое, а затем проигнорировать / отправить его в соответствии с некоторыми критериями?

например.заблокировать весь международный текст (числа с начальным 00), но разрешить все остальное.

Ответы [ 5 ]

19 голосов
/ 17 октября 2011

Входящие SMS

Вы можете перехватить входящий смс через прослушиватель смс с помощью приемника Broadcast. Вы можете изменить входящий смс или уничтожить его так, чтобы он не доходил до входящей почты.

Исходящие SMS

Вы можете прослушивать исходящие смс, поставив content observer над content://sms/out, но вы не можете изменить его с помощью собственного приложения sms. Очевидно, что вы можете изменять содержимое content://sms/out, но оно не имеет смысла.

8 голосов
/ 13 октября 2011

Исходя из того, что я смог найти, кажется, что ответ либо: "Это невозможно" , либо, что это возможно, но вам нужно напишите свое собственное приложение для SMS , чтобы вы получили текст до того, как он стал SMS, и затем вы можете выполнить любые проверки на него, прежде чем вызвать API, чтобы фактически поставить его в очередь для отправки.1006 * Извините = (

7 голосов
/ 12 октября 2011

Насколько я знаю, вы можете следить за исходящими SMS-сообщениями, но не можете остановить их отправку.

Вот как вы можете обнаружить исходящие SMS-сообщения: Прослушивание исходящих SMS или отправленныхокно в Android

Но так как это делается в основном путем чтения из базы данных, я сомневаюсь, что вы можете остановить отправку SMS.

Желаю вам удачи.

Эммануил

5 голосов
/ 14 ноября 2012

Это то, что я сделал, чтобы надеяться, что OutgoingSMSReceiver поможет кому-нибудь, дя!

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");
    }
}
2 голосов
/ 02 января 2014

Основываясь на ответе "Саад Акбар", я заставляю его работать, но только с рутированным устройством с разрешением 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" />
...