Escucha SMS salientes o caja enviada en Android
Estoy desarrollando una aplicación que almacenará todos los sms entrantes y salientes en un archivo de texto en tarjeta SD.
Puedo escuchar los mensajes entrantes usando el receptor de la difusión. Me resulta muy difícil escuchar SMS salientes.
- ¿Es BroadcastReceiver.onReceive llamado exactamente una vez por sms?
- ¿Cómo puedo enviar mensajes SMS en el BACKGROUND usando Android?
- Excepción de puntero nulo, Parcel.ReadException al enviar SMS?
- Estructura de datos utilizada para mensajes SMS en Android
- ¿Cómo comprobar el número de teléfono propio introducido por el usuario en EditText?
Sé que hasta cierto punto que un observador de contenido en la caja enviada o bandeja de salida debe ser establecido, pero no sé cómo hacerlo.
¿Cómo se puede hacer esto?
- BroadcastReceiver para SMS de varias partes
- Android: detecta SMS saliente, cuenta incorrecta
- Enviar y leer el contenido de SMS enviado a través de la aplicación nativa de SMS cordova
- Diferenciar los informes de entrega de dos SMS separados
- ¿Cómo pasar datos a BroadcastReceiver?
- Twilio vs google voz api para SMS
- Uso de SMS para verificar el número de teléfono de un dispositivo
- Recibir SMS en la aplicación para Android
Básicamente, tienes que registrar un observador de contenido … algo así:
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 exactamente obtener el contenido del SMS? Debe utilizar 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 :)
Este es mi enfoque para resolver esto
- Crear un servicio que llamó desde otra actividad
-
Crear 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; }
-
Crear la clase de observador
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 } } }
-
He añadido un método smsChecker () para comprobar si el nuevo mensaje es igual al ú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, utilizamos "content: // sms / send" si SOLAMENTE queremos comprobar todos los mensajes enviados, "content: // sms / out" si SOLAMENTE queremos comprobar todos los mensajes dentro de outbox y "content : // sms "si queremos comprobar TODOS los mensajes.
Esta es mi versión, que se ha verificado 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á utilizando una actividad. Recuerde que necesitará una referencia Context para llamar a getContentResolver()
desde dentro de un servicio o receptor.
Vi lo que pasa. Está en la línea
contentResolver.registerContentObserver(Uri.parse("content://sms/sent"), true, _myObserver);
Debes eliminar '/ enviado' y simplemente escribir 'content: // sms' ya está especificado en el ContentObserver para ver los sms enviados.
- Android gradle buildTypes: Clase duplicada
- ¿Cómo sé que el mapa está listo para utilizarse cuando se utiliza el SupportMapFragment?