Je développe une application qui stockera tous les sms entrants et sortants dans un fichier texte sur la carte SD.
Je peux écouter les messages entrants en utilisant le récepteur de diffusion. J'ai du mal à écouter les SMS sortants.
Je sais dans une certaine mesure qu'un observateur de contenu sur la boîte ou la boîte d'envoi envoyée doit être défini, mais je ne sais pas comment le faire.
Comment cela peut-il être fait?
Fondamentalement, vous devez enregistrer un observateur de contenu ... quelque chose comme ceci:
ContentResolver contentResolver = context.getContentResolver();
contentResolver.registerContentObserver(Uri.parse("content://sms/out"),true, yourObserver);
yourObserver
est un objet (new YourObserver(new Handler())
) qui pourrait ressembler à ceci:
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
}
}
Alors, comment obtenez-vous exactement le contenu du SMS? Vous devez utiliser 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 :)
Celui-ci est mon approche pour résoudre ce
Créez un observateur de contenu à l'intérieur
@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;
}
Créer la classe d'observateur
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
}
}
}
J'ai ajouté une méthode smsChecker () pour vérifier si le nouveau message est exactement le même que le dernier message
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 je ne me trompe pas, nous utilisons "content: // sms/sent" si nous voulons UNIQUEMENT vérifier tous les messages envoyés, "content: // sms/out" si nous voulons UNIQUEMENT vérifier tous les messages à l'intérieur de la boîte d'envoi, et "contenu : // sms "si nous voulons vérifier TOUS les messages.
Ceci est ma version, qui a été vérifiée 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;
}
}
Placez ce code là où l'observateur doit être activé
ContentResolver contentResolver = getContentResolver();
contentResolver.registerContentObserver(Uri.parse("content://sms"), true, new smsObserver(new Handler()));
Cela suppose que vous utilisez une activité. N'oubliez pas que vous aurez besoin d'une référence de contexte pour appeler getContentResolver()
à partir d'un service ou d'un récepteur.
J'ai vu ce qui ne va pas. c'est sur la ligne:
contentResolver.registerContentObserver(Uri.parse("content://sms/sent"), true, _myObserver);
vous devez supprimer '/ sent' et écrire simplement 'content: // sms' son est déjà spécifié dans le ContentObserver pour rechercher les sms envoyés.