99 votes

Comment supprimer un SMS de la boîte de réception dans Android de manière programmatique ?

Sur les téléphones Android, les SMS enregistrés dans les applications sont également envoyés dans la boîte de réception de l'appareil. Cependant, pour éviter l'encombrement, il serait bon de pouvoir supprimer de la boîte de réception les SMS spécifiques à une application afin de réduire le débordement potentiel de ces messages.

Les questions posées sur d'autres groupes Google pour obtenir une réponse définitive sur un moyen programmatique de supprimer les SMS de la boîte de réception Android ne semblent pas pressantes.

Donc le scénario :

  • Démarrage d'une application Android.
  • enregistrer les types de messages SMS X, Y et Z
  • Les messages P, Q, X, Y, Z affluent au fil du temps, tous déposés dans la boîte de réception.
  • L'application Android détecte la réception de X,Y,Z (vraisemblablement dans le cadre de l'événement d'interruption du programme).
  • processus X,Y,Z
  • Désir ! !! X,Y,Z sont supprimés de la boîte de réception Android

Cela a-t-il été fait ? Peut-on le faire ?

4 votes

J'ai trouvé que faire quoi que ce soit d'utile avec les capacités téléphoniques d'Android était une expérience très désagréable.

1 votes

Bonne question mon pote. Je cherchais quelque chose de similaire :D cheers

3 votes

Le mieux serait d'empêcher le SMS d'atteindre la boîte de réception : stackoverflow.com/questions/1741628/

87voto

Viktor Fonic Points 1269

" À partir d'Android 1.6, les diffusions de messages SMS entrants ( android.provider.Telephony.SMS_RECEIVED ) sont livrés en tant que "diffusion ordonnée" - ce qui signifie que vous pouvez indiquer au système quels composants doivent recevoir la diffusion en premier."

Cela signifie que vous pouvez intercepter un message entrant et interrompre sa diffusion par la suite.

En su AndroidManifest.xml veillez à ce que la priorité soit la plus élevée :

<receiver android:name=".receiver.SMSReceiver" android:enabled="true">
    <intent-filter android:priority="1000">
        <action android:name="android.provider.Telephony.SMS_RECEIVED" />
    </intent-filter>
</receiver>

En su BroadcastReceiver en onReceive() avant d'effectuer quoi que ce soit avec votre message, il suffit d'appeler abortBroadcast();

EDIT : A partir de KitKat, cela ne fonctionne plus apparemment.

EDIT2 : Plus d'infos sur comment le faire sur KitKat ici :

Supprimer les SMS d'Android sur 4.4.4 (Lignes affectées = 0(Zéro), après supprimé)

3 votes

Et assurez-vous de voir stackoverflow.com/questions/1741628/

0 votes

Pouvez-vous s'il vous plaît voir ici stackoverflow.com/questions/25988574/ ?

0 votes

La meilleure réponse à cette question =D

27voto

dmyung Points 3611

En utilisant les suggestions des autres, je pense avoir réussi à le faire fonctionner :

(en utilisant le SDK v1 R2)

Ce n'est pas parfait, puisque je dois supprimer toute la conversation, mais pour nos besoins, c'est un compromis suffisant car nous saurons au moins que tous les messages seront examinés et vérifiés. Notre flux devra probablement écouter le message, capturer le message que nous voulons, effectuer une requête pour obtenir le thread_id du message récemment entré et effectuer l'appel delete().

Dans notre activité :

Uri uriSms = Uri.parse("content://sms/inbox");
Cursor c = getContentResolver().query(uriSms, null,null,null,null); 
int id = c.getInt(0);
int thread_id = c.getInt(1); //get the thread_id
getContentResolver().delete(Uri.parse("content://sms/conversations/" + thread_id),null,null);

Note : Je n'ai pas été en mesure de faire une suppression sur content://sms/inbox/ ou content://sms/all/.

On dirait que le fil de discussion a la priorité, ce qui est logique, mais le message d'erreur ne fait que m'enhardir et me mettre encore plus en colère. Si vous essayez de supprimer des messages sur sms/inbox/ ou sms/all/, vous obtiendrez probablement le message suivant :

java.lang.IllegalArgumentException: Unknown URL
    at com.android.providers.telephony.SmsProvider.delete(SmsProvider.java:510)
    at android.content.ContentProvider$Transport.delete(ContentProvider.java:149)
    at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:149)

Pour une référence supplémentaire aussi, assurez-vous de mettre ceci dans votre manifeste pour votre récepteur d'intention :

<receiver android:name=".intent.MySmsReceiver">
    <intent-filter>
        <action android:name="android.provider.Telephony.SMS_RECEIVED"></action>
    </intent-filter>
</receiver>

Notez que l'étiquette du récepteur ne ressemble pas à ceci :

<receiver android:name=".intent.MySmsReceiver" 
    android:permission="android.permission.RECEIVE_SMS">

Lorsque j'avais ces paramètres, Android me donnait des exceptions de permissions farfelues qui ne permettaient pas à Android.phone de transmettre les SMS reçus à mon intention. Donc, NE METTEZ PAS cet attribut de permission RECEIVE_SMS dans votre intention ! J'espère que quelqu'un de plus sage que moi pourra me dire pourquoi c'était le cas.

0 votes

Pouvez-vous s'il vous plaît voir ici stackoverflow.com/questions/25988574/ ?

24voto

Doug Points 201

Donc, j'ai fait une pièce, et c'est est Il est possible de supprimer un SMS reçu. Malheureusement, tout n'est pas rose :(

J'ai un récepteur qui capte les messages SMS entrants. La façon dont le routage des SMS entrants d'Android fonctionne est que le morceau de code responsable du décodage des messages envoie une diffusion (il utilise la balise sendBroadcast() qui, malheureusement, n'est PAS la version qui vous permet d'appeler simplement la méthode abortBroadcast() ) dès qu'un message arrive.

Mon récepteur peut ou non être appelé avant le récepteur SMS de Systems, et dans tous les cas, la diffusion reçue n'a aucune propriété qui pourrait refléter la _id dans le tableau SMS.

Cependant, comme je ne suis pas du genre à me laisser arrêter aussi facilement, je poste moi-même (via un Handler) un message différé avec le SmsMessage comme objet attaché. (Je suppose que vous pourriez aussi vous poster un Runnable...)

handler.sendMessageDelayed(handler.obtainMessage(MSG_DELETE_SMS, msg), 2500);

Ce délai permet de s'assurer qu'au moment où le message arrive, tous les récepteurs de diffusion auront terminé leur travail et que le message sera bien rangé dans la table SMS.

Lorsque le message (ou Runnable) est reçu, voici ce que je fais :

case MSG_DELETE_SMS:
    Uri deleteUri = Uri.parse("content://sms");
    SmsMessage msg = (SmsMessage)message.obj;

    getContentResolver().delete(deleteUri, "address=? and date=?", new String[] {msg.getOriginatingAddress(), String.valueOf(msg.getTimestampMillis())});

J'utilise l'adresse d'origine et le champ d'horodatage pour garantir une probabilité très élevée de supprimer UNIQUEMENT le message qui m'intéresse. Si je voulais être encore plus paranoïaque, je pourrais inclure le champ msg.getMessageBody() dans le cadre de la requête.

Oui, le message est supprimé (hourra !). Malheureusement, la barre de notification n'est pas mise à jour :(

Lorsque vous ouvrez la zone de notification, vous voyez le message qui s'y trouve... mais lorsque vous tapez dessus pour l'ouvrir, il a disparu !

Je ne veux pas que l'utilisateur pense qu'il y a un TXT alors qu'il n'y en a pas (cela ne ferait que provoquer des rapports de bogue).

En interne, dans l'OS, le téléphone appelle MessagingNotification.updateNewMessageIndicator(Context) Mais cette classe a été cachée de l'API, et je ne voulais pas reproduire tout ce code juste pour rendre l'indicateur précis.

0 votes

Doug, c'est génial. Comme question, savez-vous s'il est nécessaire de faire le post au Handler ? Je me demande si le SMS est inséré dans la base de données SMS du système avant que les récepteurs de diffusion ne soient appelés ? Je vais probablement devoir regarder dans le système d'exploitation pour voir où se fait l'insertion, mais je présume que l'insertion du SMS dans une base de données se fait avant que les récepteurs de diffusion ne soient informés. Avez-vous une idée sur ce point ou l'avez-vous déjà vérifié ?

0 votes

Pouvez-vous s'il vous plaît voir ici stackoverflow.com/questions/25988574/ ?

11voto

Atif Mahmood Points 1059
public boolean deleteSms(String smsId) {
    boolean isSmsDeleted = false;
    try {
        mActivity.getContentResolver().delete(Uri.parse("content://sms/" + smsId), null, null);
        isSmsDeleted = true;

    } catch (Exception ex) {
        isSmsDeleted = false;
    }
    return isSmsDeleted;
}

utiliser cette permission dans AndroidManifiest

<uses-permission android:name="android.permission.WRITE_SMS"/>

1 votes

Comment obtenir l'identifiant sms ?

0 votes

0 votes

@Dev01si vous voulez supprimer un sms particulier vous devez avoir son id n'est-ce pas ? et si non vous devez interroger l'id avec l'adresse ou le smsbody.

6voto

Naresh Kavali Points 51

Il est préférable d'utiliser l'_id et le thread_id pour supprimer un message.

Thread_id est un élément attribué aux messages provenant du même utilisateur. Ainsi, si vous utilisez uniquement le thread_id, tous les messages de l'expéditeur seront supprimés.

Si vous utilisez la combinaison de _id, thread_id, alors il supprimera le message exact que vous cherchez à supprimer.

Uri thread = Uri.parse( "content://sms");
int deleted = contentResolver.delete( thread, "thread_id=? and _id=?", new String[]{String.valueOf(thread_id), String.valueOf(id)} );

0 votes

Pouvez-vous s'il vous plaît voir ici stackoverflow.com/questions/25988574/ ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X