Escuchar SMS salientes o cuadro enviado en Android


Estoy desarrollando una aplicación que almacenará todos los sms entrantes y salientes en un archivo de texto en la tarjeta SD.

Puedo escuchar mensajes entrantes usando broadcast receiver. Me resulta muy difícil escuchar SMS salientes.

Sé hasta cierto punto que un observador de contenido en el cuadro enviado o bandeja de salida necesita ser configurado, pero no sé cómo hacerlo.

¿Cómo se puede hacer esto?

 32
Author: Vivek, 2011-04-27

4 answers

Básicamente, tienes que registrar un observador de contenido... algo como esto:

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

yourObserver es un objeto (new YourObserver(new Handler())) que podría verse así:

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
    }
}

Entonces, ¿cómo se obtiene exactamente el contenido del SMS? Debes usar un 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 :)
 47
Author: Cristian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-27 18:30:23

Este es mi enfoque para resolver esto

  1. Crear un servicio que llamó desde otra actividad
  2. Crea un observador de contenido dentro de él

     @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. Crear la clase observer

    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. He añadido un método smsChecker() para comprobar si el nuevo mensaje es el mismo que el último mensaje

    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;
    }
    

Si no me equivoco, usamos "content: / / sms / sent" si solo queremos revisar todos los mensajes enviados, "content: / / sms / out" si SOLO queremos comprobar todos los mensajes dentro de la bandeja de salida, y" contenido://sms " si queremos comprobar TODOS los mensajes.

 5
Author: baskara,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-19 17:58:32

Esta es mi versión, que ha sido verificada en 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;
    }
}

Coloque este código donde el observador debe estar habilitado

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

Esto supone que estás usando una actividad. Recuerde que necesitará una referencia de contexto para llamar a getContentResolver() desde un servicio o receptor.

 2
Author: Abandoned Cart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-29 17:31:53

Vi lo que sale mal. está en la línea:

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

Debes eliminar '/ sent 'y simplemente escribir' content: / / sms' su ya está especificado en el ContentObserver para buscar en sms enviados.

 0
Author: el_tamanois,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-15 07:16:48