web-dev-qa-db-fra.com

Comment supprimer un SMS de la boîte de réception de Android par programmation?)?

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

Questions sur les autres groupes Google pour obtenir une réponse définitive sur une méthode programmée pour supprimer SMS les messages de la boîte de réception Android ne semblent pas pressants.).

Donc le scénario:

  • Démarrage de l'application Android.
  • enregistrer SMS les types de message 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 (probablement dans le cadre de l'événement d'interruption du programme)
  • processus X, Y, Z
  • Desirement !!! X, Y, Z sont supprimés de la Android corbeille d'arrivée

At-il été fait? Cela peut-il être fait?

97
dmyung

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

Cela signifie que vous pouvez intercepter les messages entrants et abandonner ultérieurement leur diffusion.

Dans votre fichier _AndroidManifest.xml_, assurez-vous que la priorité est définie sur priorité 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>
_

Dans votre méthode BroadcastReceiver, dans la méthode onReceive(), avant d'effectuer quoi que ce soit avec votre message, appelez simplement abortBroadcast();

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

EDIT2: Plus d’informations sur la façon de le faire sur KitKat ici:

Supprimer SMS de Android sur 4.4.4 (lignes concernées 0 (zéro), après avoir été supprimées))) ==

87
Viktor Fonic

En utilisant les suggestions des autres, je pense que je l’ai obtenu au travail:

(en utilisant SDK v1 R2)

Ce n'est pas parfait, car je dois supprimer toute la conversation, mais pour nos besoins, il s'agit d'un compromis suffisant, car nous saurons au moins que tous les messages seront examinés et vérifiés. Notre flux devra probablement ensuite écouter le message, capturer le message souhaité, lancer 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);

Remarque: je n'ai pas pu supprimer le contenu: // sms/inbox/ou le contenu: // sms/all /.

On dirait que le fil est prioritaire, ce qui a du sens, mais le message d'erreur ne fait que m'encourager à être plus en colère. En essayant de supprimer sur sms/inbox/ou sms/all /, vous obtiendrez probablement:

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, assurez-vous de le mettre dans votre manifeste pour le destinataire de votre 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 destinataire ne ressemble pas à ceci:

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

Lorsque j’avais ces paramètres, Android m’a donné des exceptions d’autorisations délirantes qui ne permettaient pas à Android.phone de transmettre le SMS à mon intention. Donc , NE METTEZ PAS cet attribut d'autorisation RECEIVE_SMS dans votre intention! J'espère qu'une personne plus sage que moi pourra me dire pourquoi.

27
dmyung

J'ai donc joué, et il est possible de supprimer un SMS reçu. Malheureusement, tout n'est pas simple :(

J'ai un récepteur qui détecte les messages entrants SMS. Maintenant, la manière dont le Android SMS fonctionne le routage entrant est que le morceau de code responsable du décodage des messages envoie une diffusion (il utilise la méthode sendBroadcast()) - qui, malheureusement, n'est PAS la version permettant d'appeler simplement abortBroadcast()) chaque fois qu'un message arrive.

Mon destinataire peut ou ne peut pas être appelé avant le récepteur Systèmes SMS) et, dans tous les cas, la diffusion reçue ne possède aucune propriété qui pourrait refléter la colonne _id Dans le SMS table.

Cependant, n'étant pas du genre à pouvoir être arrêté aussi facilement, je poste moi-même (via un gestionnaire) un message différé avec SmsMessage en tant qu'objet attaché. (Je suppose que vous pourriez aussi publier un Runnable ...)

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

Le délai est là pour garantir que, au moment où le message arrivera, tous les récepteurs de diffusion auront terminé leur travail et que le message sera installé en toute sécurité 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 assurer une très grande probabilité de supprimer SEULEMENT le message qui m'intéresse. Si je voulais être encore plus paranoïaque, je pourrais inclure le contenu msg.getMessageBody() dans la requête.

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

Lorsque vous ouvrez la zone de notification, le message s'affiche pour vous ... mais lorsque vous appuyez dessus, le message disparaît!

Pour moi, cela ne suffit pas - je veux que toute trace du message disparaisse - je ne veux pas que l'utilisateur pense qu'il y a un TXT quand il n'y en a pas (que ne causerait que des rapports de bugs).

En interne, dans le système d'exploitation, le téléphone appelle MessagingNotification.updateNewMessageIndicator(Context), mais cette classe a été masquée à l'API et je ne voulais pas reproduire tout ce code simplement pour que l'indicateur soit exact.

24
Doug
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"/>
11
Atif Mahmood

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

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

Si vous utilisez la combinaison de _id, thread_id, alors le message exact que vous souhaitez supprimer sera supprimé.

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

Vous aurez besoin de trouver le URI du message. Mais une fois que vous faites je pense que vous devriez être capable de Android.content.ContentResolver.delete (...) le.

Voici quelques autres info .

5
Neil

Je pense que cela ne peut pas être parfaitement fait pour le moment. Il y a 2 problèmes de base:

  1. Comment pouvez-vous vous assurer que le SMS est déjà dans la boîte de réception lorsque vous essayez de le supprimer?
    Notez que SMS_RECEIVED n'est pas une diffusion ordonnée.
    La solution de dmyung consiste donc à tenter sa chance; Même le retard dans la réponse de Doug n'est pas une garantie.

  2. Le SmsProvider n'est pas thread-safe. (Voir http://code.google.com/p/Android/issues/detail?id=2916#c )
    Le fait que plusieurs clients demandent la suppression et l’insertion simultanément entraîne la corruption des données, voire une exception immédiate d’exécution.

2
an0

Je ne pouvais pas le faire fonctionner avec la solution de dmyung, cela me donnait une exception lorsque j'obtenais l'identifiant du message ou celui du thread.

En fin de compte, j'ai utilisé la méthode suivante pour obtenir l'identifiant du thread:

private long getThreadId(Context context) {
    long threadId = 0;

    String SMS_READ_COLUMN = "read";
    String WHERE_CONDITION = SMS_READ_COLUMN + " = 0";
    String SORT_ORDER = "date DESC";
    int count = 0;

    Cursor cursor = context.getContentResolver().query(
                    SMS_INBOX_CONTENT_URI,
          new String[] { "_id", "thread_id", "address", "person", "date", "body" },
                    WHERE_CONDITION,
                    null,
                    SORT_ORDER);

    if (cursor != null) {
            try {
                count = cursor.getCount();
                if (count > 0) {
                    cursor.moveToFirst();
                    threadId = cursor.getLong(1);                              
                }
            } finally {
                    cursor.close();
            }
    }


    return threadId;
}

Ensuite, je pourrais le supprimer. Cependant, comme l'a dit Doug, la notification est toujours là, même le message est affiché lors de l'ouverture du panneau de notification. Ce n'est qu'en tapotant sur le message que je peux voir qu'il est vide.

Donc, je suppose que la seule façon de procéder serait d'intercepter en quelque sorte le SMS avant qu'il soit transmis au système, avant même qu'il n'atteigne la boîte de réception. Cependant, je doute fortement que cela soit faisable. S'il vous plaît Corrige moi si je me trompe.

2
Stelian Iancu

tilisez cette fonction pour supprimer un fil de discussion spécifique ou modifier en fonction de vos besoins:

public void delete_thread(String thread) 
{ 
  Cursor c = getApplicationContext().getContentResolver().query(
  Uri.parse("content://sms/"),new String[] { 
  "_id", "thread_id", "address", "person", "date","body" }, null, null, null);

 try {
  while (c.moveToNext()) 
      {
    int id = c.getInt(0);
    String address = c.getString(2);
    if (address.equals(thread)) 
        {
     getApplicationContext().getContentResolver().delete(
     Uri.parse("content://sms/" + id), null, null);
    }

       }
} catch (Exception e) {

  }
}

Appelez cette fonction simplement ci-dessous:

delete_thread("54263726");//you can pass any number or thread id here

N'oubliez pas d'ajouter Android autorisation du mainfest ci-dessous:

<uses-permission Android:name="Android.permission.WRITE_SMS"/>
2
Ashish Sahu

Mettez également à jour le fichier de manifeste de manière à supprimer un SMS dont vous avez besoin d'autorisations d'écriture.

<uses-permission Android:name="Android.permission.WRITE_SMS"/>
1
Wasif Kirmani

Jetez un coup d’œil à ce lien, il vous donnera une brève idée de la logique:

https://Gist.github.com/5178e798d9a00cac4ddb
Appelez simplement la fonction deleteSMS () avec un certain retard, car il existe une légère différence entre le moment de la notification et le moment où il est réellement enregistré ...., pour plus de détails, consultez également ce lien ... .......

http://htmlcoderhelper.com/how-to-delete-sms-from-inbox-in-Android-programmatically/

Merci..........

1
viv

Il suffit de désactiver les notifications pour l'application SMS par défaut. Traitez vos propres notifications pour tous les messages texte!

1
Noah Seidman

Vous venez d’essayer le code suivant. Il supprimera tous les sms qui sont tous dans le téléphone (reçus ou envoyés)

Uri uri = Uri.parse("content://sms");

ContentResolver contentResolver = getContentResolver();

Cursor cursor = contentResolver.query(uri, null, null, null,
  null);



while (cursor.moveToNext()) {

 long thread_id = cursor.getLong(1);
 Uri thread = Uri.parse("content://sms/conversations/"
   + thread_id);
 getContentResolver().delete(thread, null, null);
}
1
Rajamohan Sugumaran

Maintenant, la méthode abortBroadcast(); peut être utilisée pour limiter le message entrant à la boîte de réception.

1
AB1209

Utilisez l’une de ces méthodes pour sélectionner le dernier reçu SMS) et supprimez-le, ici dans ce cas, je reçois le top des sms et je vais le supprimer à l’aide du thread et de la valeur id de sms,

try {
    Uri uri = Uri.parse("content://sms/inbox");
    Cursor c = v.getContext().getContentResolver().query(uri, null, null, null, null);
    int i = c.getCount();

    if (c.moveToFirst()) {
    }
} catch (CursorIndexOutOfBoundsException ee) {
    Toast.makeText(v.getContext(), "Error :" + ee.getMessage(), Toast.LENGTH_LONG).show();
}
0
Pir Fahim Shah
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    SMSData sms = (SMSData) getListAdapter().getItem(position);
    Toast.makeText(getApplicationContext(), sms.getBody(),
            Toast.LENGTH_LONG).show();
    Toast.makeText(getApplicationContext(), sms.getNumber(),
            Toast.LENGTH_LONG).show();

    deleteSms(sms.getId());

}

public boolean deleteSms(String smsId) {
    boolean isSmsDeleted = false;
    try {
        MainActivity.this.getContentResolver().delete(
                Uri.parse("content://sms/" + smsId), null, null);
        isSmsDeleted = true;

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

Essayez ceci, je suis sûr à 100% que cela fonctionnera bien: - // il suffit de mettre l’adresse de conversion ici pour supprimer toute la conversion par adresse (n’oubliez pas d’ajouter une permission de lecture, d’écriture dans le mainfest) Voici le code:

String address="put address only";

Cursor c = getApplicationContext().getContentResolver().query(Uri.parse("content://sms/"), new String[] { "_id", "thread_id", "address", "person", "date", "body" }, null, null, null);

try {
    while (c.moveToNext()) {
        int id = c.getInt(0);
        String address = c.getString(2);
        if(address.equals(address)){
        getApplicationContext().getContentResolver().delete(Uri.parse("content://sms/" + id), null, null);}
    }
} catch(Exception e) {

}
0
Ashish Sahu

Exemple pour supprimer un SMS, pas une conversation:

getContentResolver().delete(Uri.parse("content://sms/conversations/" + threadID), "_id = ?", new String[]{id});
0
embo