Прослушивание исходящих SMS или отправленных ящиков в Android - PullRequest
32 голосов
/ 27 апреля 2011

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

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

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

Как это можно сделать?

Ответы [ 4 ]

47 голосов
/ 27 апреля 2011

По сути, вам необходимо зарегистрировать обозреватель контента ... примерно так:

ContentResolver contentResolver = context.getContentResolver();
contentResolver.registerContentObserver(Uri.parse("content://sms/out"),true, yourObserver);

yourObserver - это объект (new YourObserver(new Handler())), который может выглядеть следующим образом:

class YourObserver extends ContentObserver {

    public YourObserver(Handler handler) {
        super(handler);
    }

    @Override
    public void onChange(boolean selfChange) {
        super.onChange(selfChange);
        // save the message to the SD card here
    }
}

Итак, как именно вы получаете содержание SMS?Вы должны использовать Cursor:

// save the message to the SD card here
Uri uriSMSURI = Uri.parse("content://sms/out");
Cursor cur = this.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 content = cur.getString(cur.getColumnIndex("body"));
// use cur.getColumnNames() to get a list of all available columns...
// each field that compounds a SMS is represented by a column (phone number, status, etc.)
// then just save all data you want to the SDcard :)
5 голосов
/ 19 марта 2015

Это мой подход к решению

  1. Создание службы, которая вызывается из другой активности
  2. Создать в нем обозреватель контента

     @Override
     public int onStartCommand(Intent intent, int flag, int startId) {
     MyObserver myObserver = new MyObserver(new Handler());
     ContentResolver contentResolver = this.getApplicationContext().getContentResolver();
     contentResolver.registerContentObserver(Uri.parse("content://sms/sent"), true, myObserver);
     return START_STICKY;
     }
    
  3. Создать класс наблюдателя

    class MyObserver extends ContentObserver {
    
    public MyObserver(Handler handler) {
        super(handler);
    }
    
    @Override
    public void onChange(boolean selfChange) {
        super.onChange(selfChange);
        Uri uriSMSURI = Uri.parse("content://sms/sent");
        Cursor cur = getContentResolver().query(uriSMSURI, null, null, null, null);
        cur.moveToNext();
        String content = cur.getString(cur.getColumnIndex("body"));
        String smsNumber = cur.getString(cur.getColumnIndex("address"));
        if (smsNumber == null || smsNumber.length() <= 0) {
            smsNumber = "Unknown";
        }
        cur.close();
    
        if(smsChecker( "OutgoingSMS to " + smsNumber + ": " + content)) {
            //save data into database/sd card here
        }
    }
    }
    
  4. Я добавил метод smsChecker (), чтобы проверить, совпадает ли новое сообщение с последним сообщением

    public boolean smsChecker(String sms) {
    boolean flagSMS = true;
    
    if (sms.equals(lastSMS)) {
        flagSMS = false;
    }
    else {
        lastSMS = sms;
    }
    //if flagSMS = true, those 2 messages are different
    return flagSMS;
    }
    

если я не ошибаюсь, мы используем «content: // sms / sent», если мы ТОЛЬКО хотим проверять все отправленные сообщения, «content: // sms / out», если мы ТОЛЬКО хотим проверять все сообщения внутри исходящих, и "content: // sms", если мы хотим проверить ВСЕ сообщения.

2 голосов
/ 13 апреля 2017

Это моя версия, которая была проверена в Android 6.0 +

class smsObserver extends ContentObserver {

    private String lastSmsId;

    public smsObserver(Handler handler) {
        super(handler);
    }

    @Override
    public void onChange(boolean selfChange) {
        super.onChange(selfChange);
        Uri uriSMSURI = Uri.parse("content://sms/sent");
        Cursor cur = getContentResolver().query(uriSMSURI, null, null, null, null);
        cur.moveToNext();
        String id = cur.getString(cur.getColumnIndex("_id"));
        if (smsChecker(id)) {
            String address = cur.getString(cur.getColumnIndex("address"));
            // Optional: Check for a specific sender
            if (address.equals(phoneNumber)) {
                String message = cur.getString(cur.getColumnIndex("body"));
                // Use message content for desired functionality
            }
        }
    }

    // Prevent duplicate results without overlooking legitimate duplicates
    public boolean smsChecker(String smsId) {
        boolean flagSMS = true;

        if (smsId.equals(lastSmsId)) {
            flagSMS = false;
        }
        else {
            lastSmsId = smsId;
        }

        return flagSMS;
    }
}

Поместите этот код, где должен быть включен наблюдатель

ContentResolver contentResolver = getContentResolver();
contentResolver.registerContentObserver(Uri.parse("content://sms"), true, new smsObserver(new Handler()));

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

0 голосов
/ 15 апреля 2016

Я видел, что идет не так.его в строке:

 contentResolver.registerContentObserver(Uri.parse("content://sms/sent"), true, _myObserver);

вы должны удалить '/ sent' и просто написать 'content: // sms', он уже указан в ContentObserver для просмотра отправленных sms.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...