webentwicklung-frage-antwort-db.com.de

Wie kann man SMS aus dem Posteingang Android programmgesteuert löschen?

Auf Android Handys SMS Für Anwendungen registrierte Nachrichten werden ebenfalls an den Posteingang des Geräts gesendet. Um jedoch Unordnung zu vermeiden, ist es hilfreich, Anwendungen entfernen zu können spezifische SMS Nachrichten aus dem Posteingang, um den möglichen Überlauf dieser Nachrichten zu reduzieren.

Fragen zu anderen Google-Gruppen nach einer endgültigen Antwort auf programmgesteuerte Weise zum Löschen von SMS Nachrichten aus dem Android Posteingang) scheinen nicht dringlich zu sein.

Also das Szenario:

  • Start der Android App.
  • register SMS Nachrichtentypen X, Y und Z
  • nachrichten P, Q, X, Y, Z strömen im Laufe der Zeit ein, alle im Posteingang abgelegt
  • Android-Anwendung erkennt Empfang von X, Y, Z (vermutlich als Teil des Programmunterbrechungsereignisses)
  • verarbeite X, Y, Z
  • Wunsch !!! X, Y, Z werden aus dem Android Posteingang gelöscht

Wurde es getan? Kann es gemacht werden?

97
dmyung

"Ab Android 1.6, eingehende SMS= Nachrichtensendungen (Android.provider.Telephony.SMS_RECEIVED) Werden als" bestellte Sendung "geliefert - das heißt, Sie können sagen, dass das System, welche Komponenten die Sendung zuerst empfangen sollen. "

Dies bedeutet, dass Sie eingehende Nachrichten abfangen und die Übertragung später abbrechen können.

Stellen Sie in Ihrer AndroidManifest.xml - Datei sicher, dass die Priorität auf die höchste festgelegt ist:

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

Rufen Sie in Ihrer BroadcastReceiver in onReceive() -Methode einfach abortBroadcast(); auf, bevor Sie etwas mit Ihrer Nachricht ausführen.

EDIT: Ab KitKat funktioniert dies anscheinend nicht mehr.

EDIT2: Weitere Informationen zur Verwendung von KitKat finden Sie hier:

Löschen SMS aus Android am 4.4.4 (Betroffene Zeilen = 0 (Null), nach dem Löschen)

87
Viktor Fonic

Ich benutze Vorschläge von anderen und denke, ich habe es zum Laufen gebracht:

(mit SDK v1 R2)

Es ist nicht perfekt, da ich die gesamte Konversation löschen muss, aber für unsere Zwecke ist es ein ausreichender Kompromiss, da wir zumindest wissen, dass alle Nachrichten geprüft und verifiziert werden. Unser Flow muss dann wahrscheinlich auf die Nachricht warten, auf die gewünschte Nachricht aufzeichnen, eine Abfrage durchführen, um die thread_id der kürzlich eingehenden Nachricht abzurufen, und den delete () -Aufruf ausführen.

In unserer Tätigkeit:

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

Hinweis: Ich konnte Inhalte nicht löschen: // sms/inbox/oder Inhalte: // sms/all /

Anscheinend hat der Thread Vorrang, was Sinn macht, aber die Fehlermeldung hat mich nur ermutigt, wütender zu sein. Wenn Sie versuchen, das Löschen in sms/inbox/oder sms/all/durchzuführen, erhalten Sie wahrscheinlich:

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)

Stellen Sie auch als zusätzliche Referenz sicher, dass Sie dies in Ihr Manifest für Ihren Vorsatzempfänger aufnehmen:

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

Beachten Sie, dass das Empfänger-Tag nicht so aussieht:

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

Als ich diese Einstellungen hatte, gab Android) mir einige verrückte Ausnahmen, die es Android.phone nicht erlaubten, die empfangenen SMS zu meiner Absicht weiterzugeben. Also Setzen Sie dieses RECEIVE_SMS-Berechtigungsattribut NICHT in Ihre Absicht ein! Hoffentlich kann mir jemand, der klüger als ich ist, sagen, warum dies der Fall war.

27
dmyung

Also, ich hatte ein Spiel, und es ist ist möglich, eine empfangene SMS zu löschen. Leider ist nicht alles glatt :(

Ich habe einen Empfänger, der eingehende SMS Nachrichten aufnimmt. Die Art und Weise, wie das Android SMS eingehende Routing funktioniert, ist, dass der Code, der für das Dekodieren der Nachrichten verantwortlich ist, eine Rundsendung sendet (er verwendet die sendBroadcast() -Methode - was leider NICHT die Version ist Damit können Sie einfach abortBroadcast()) aufrufen, wenn eine Nachricht eintrifft.

Mein Empfänger wird möglicherweise vor dem Systemempfänger SMS angerufen oder nicht, und die empfangene Sendung verfügt in keinem Fall über eine Eigenschaft, die die Spalte _id In der Tabelle SMS widerspiegeln könnte.

Da ich jedoch nicht so einfach gestoppt werden kann, poste ich mir selbst (über einen Handler) eine verzögerte Nachricht mit der SmsMessage als angefügtem Objekt. (Ich nehme an, du könntest dir auch ein Runnable posten ...)

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

Die Verzögerung soll sicherstellen, dass bis zum Eintreffen der Nachricht alle Rundfunkempfänger ihre Sendungen beendet haben und die Nachricht sicher in der Tabelle SMS verzeichnet ist.

Wenn die Nachricht (oder Runnable) empfangen wird, tue ich Folgendes:

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

Ich verwende die Ursprungsadresse und das Zeitstempelfeld, um sicherzustellen, dass NUR die Nachricht, die mich interessiert, mit sehr hoher Wahrscheinlichkeit gelöscht wird. Wenn ich noch paranoider sein möchte, könnte ich den Inhalt msg.getMessageBody() in die Abfrage einbeziehen.

Ja, die Nachricht IS wurde gelöscht (Hurra!). Leider wurde die Benachrichtigungsleiste nicht aktualisiert :(

Wenn Sie den Benachrichtigungsbereich öffnen, wird die Nachricht für Sie angezeigt. Wenn Sie jedoch darauf tippen, um sie zu öffnen, ist sie verschwunden.

Für mich ist das nicht gut genug - ich möchte, dass alle Spuren der Nachricht verschwinden - ich möchte nicht, dass der Benutzer denkt, dass es ein TXT gibt, wenn dies nicht der Fall ist (das würde nur Fehlerberichte verursachen) ).

Intern im Betriebssystem ruft das Telefon MessagingNotification.updateNewMessageIndicator(Context) auf, aber ich habe diese Klasse vor der API verborgen, und ich wollte nicht den gesamten Code replizieren, nur um den Indikator korrekt zu machen.

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

verwenden Sie diese Berechtigung in AndroidManifiest

<uses-permission Android:name="Android.permission.WRITE_SMS"/>
11
Atif Mahmood

Es ist besser, die _id und die thread_id zu verwenden, um eine Nachricht zu löschen.

Thread_id ist etwas, das den Nachrichten desselben Benutzers zugewiesen ist. Wenn Sie also nur thread_id verwenden, werden alle Nachrichten vom Absender gelöscht.

Wenn Sie die Kombination aus _id und thread_id verwenden, wird genau die Nachricht gelöscht, die Sie löschen möchten.

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

Sie müssen das URI der Nachricht finden. Aber wenn Sie dies tun, sollten Sie in der Lage sein, Android.content.ContentResolver.delete (...).

Hier noch ein paar mehr info .

5
Neil

Ich denke, das kann vorerst nicht perfekt gemacht werden. Es gibt zwei grundlegende Probleme:

  1. Wie können Sie sicherstellen, dass sich die SMS bereits im Posteingang befindet, wenn Sie versuchen, sie zu löschen?
    Beachten Sie, dass SMS_RECEIVED keine bestellte Sendung ist.
    Dmyungs Lösung ist es also, sein Glück auf die Probe zu stellen. Selbst die Verzögerung in Dougs Antwort ist keine Garantie.

  2. Der SmsProvider ist nicht threadsicher. (Siehe http://code.google.com/p/Android/issues/detail?id=2916#c )
    Die Tatsache, dass mehrere Clients gleichzeitig das Löschen und Einfügen anfordern, führt zu einer Beschädigung der Daten oder sogar zu einer sofortigen Laufzeitausnahme.

2
an0

Ich konnte es nicht mit der Lösung von dmyung zum Laufen bringen. Es gab eine Ausnahme, als ich entweder die Nachrichten-ID oder die Thread-ID erhielt.

Am Ende habe ich die folgende Methode verwendet, um die Thread-ID zu erhalten:

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

Dann könnte ich es löschen. Wie Doug bereits sagte, ist die Benachrichtigung immer noch vorhanden, auch wenn die Meldung beim Öffnen des Benachrichtigungsfelds angezeigt wird. Nur beim Tippen auf die Nachricht konnte ich tatsächlich sehen, dass sie leer ist.

Ich schätze, die einzige Möglichkeit wäre, das SMS) irgendwie abzufangen, bevor es an das System geliefert wird, bevor es überhaupt den Posteingang erreicht. Ich bezweifle jedoch, dass dies machbar ist. Bitte korrigiere mich wenn ich falsch liege.

2
Stelian Iancu

Verwenden Sie diese Funktion, um einen bestimmten Nachrichtenthread zu löschen oder nach Ihren Wünschen zu ändern:

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) {

  }
}

Rufen Sie diese Funktion einfach unten auf:

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

Vergiss nicht, Android Hauptfest-Berechtigung unten hinzuzufügen:

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

Aktualisieren Sie auch die Manifestdatei, um eine SMS zu löschen, für die Sie Schreibberechtigungen benötigen.

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

Schauen Sie sich einfach diesen Link an, er gibt Ihnen einen kurzen Überblick über die Logik:

https://Gist.github.com/5178e798d9a00cac4ddb
Rufen Sie einfach die Funktion deleteSMS () mit einiger Verzögerung auf, da es einen kleinen Unterschied zwischen dem Zeitpunkt der Benachrichtigung und dem Zeitpunkt des Speicherns gibt. .......

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

Vielen Dank..........

1
viv

Deaktivieren Sie einfach die Benachrichtigungen für die Standard-SMS-App. Verarbeiten Sie Ihre eigenen Benachrichtigungen für alle Textnachrichten!

1
Noah Seidman

Sie probieren einfach den folgenden Code aus. Es werden alle SMS gelöscht, die sich alle im Telefon befinden (empfangen oder gesendet).

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

Jetzt kann die Methode abortBroadcast(); verwendet werden, um die eingehende Nachricht auf den Posteingang zu beschränken.

1
AB1209

Verwenden Sie eine dieser Methoden, um die zuletzt empfangene SMS und löschen Sie es, hier in diesem Fall bekomme ich die meisten SMS und werde mit Thread und ID-Wert von SMS löschen,

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

Versuchen Sie dies, ich bin 100% sicher, dass dies gut funktioniert: - // setzen Sie einfach die Konvertierungsadresse hier, um die gesamte Konvertierung nach Adresse zu löschen.

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

Beispiel zum Löschen einer SMS, nicht eines Gesprächs:

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