web-dev-qa-db-ja.com

SMSをインボックスからAndroidプログラムで削除するには?

Android電話SMSアプリケーションに登録されたメッセージも、デバイスの受信ボックスに送信されます。ただし、混乱を防ぐために、アプリケーション固有のSMSメッセージを受信ボックスから削除して、これらのメッセージの潜在的なオーバーフローを減らすことができると便利です。

SMS受信トレイからAndroidメッセージを削除するためのプログラム的な方法で決定的な回答を得ることに関する他のGoogleグループに関する質問は、圧迫されていないようです。

したがって、シナリオ:

  • Androidアプリの起動。
  • register SMSメッセージタイプX、Y、およびZ
  • メッセージP、Q、X、Y、Zは時間の経過とともにストリーム配信され、すべて受信トレイに保管されます
  • AndroidアプリケーションはX、Y、Zの受信を検出します(おそらくプログラム割り込みイベントの一部として)
  • プロセスX、Y、Z
  • Desirement !!! X、Y、ZはAndroid受信ボックスから削除されます

終わった?できますか?

97
dmyung

「Android 1.6、着信SMSメッセージブロードキャスト(_Android.provider.Telephony.SMS_RECEIVED_)は「順序付けられたブロードキャスト」として配信されます—つまり、コンポーネントが最初にブロードキャストを受信するシステム。」

これは、着信メッセージを傍受し、それ以上のブロードキャストを中止できることを意味します。

_AndroidManifest.xml_ファイルで、優先度が最高に設定されていることを確認してください。

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

BroadcastReceiveronReceive()メソッドで、メッセージで何かを実行する前に、単にabortBroadcast();を呼び出します

編集:キットカットの時点では、これは明らかに動作していません。

EDIT2:ここでキットカットでそれを行う方法の詳細:

Delete SMS from Android on 4.4.4(影響を受けた行= 0(ゼロ)、削除後)

87
Viktor Fonic

他の人からの提案を使用して、私はそれを機能させたと思います:

(SDK v1 R2を使用)

会話全体を削除する必要があるため、完全ではありませんが、私たちの目的にとっては、少なくともすべてのメッセージが確認および検証されることを知っているため、これは十分な妥協です。フローは、おそらくメッセージをリッスンし、必要なメッセージをキャプチャし、最近受信したメッセージのthread_idを取得するクエリを実行し、delete()呼び出しを実行する必要があります。

私たちの活動:

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

注:content:// sms/inbox /またはcontent:// sms/all /で削除を行うことができませんでした

スレッドが優先されるように見えますが、これは理にかなっていますが、エラーメッセージは私を怒らせただけです。 sms/inbox /またはsms/all /で削除を試みると、おそらく以下が得られます:

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)

追加の参照についても、これをインテントレシーバーのマニフェストに入れてください。

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

受信者タグは次のようには見えないことに注意してください。

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

これらの設定があると、Androidは、Android.phoneが受信したSMSを意図に渡すことを許可しなかったいくつかのクレイジーなアクセス許可の例外を与えました。 、そのRECEIVE_SMS許可属性をインテントに入れないでください!うまくいけば、私より賢い人がなぜそうなのか教えてくれます。

27
dmyung

だから、私は遊びを持っていた、そしてそれはis受信したSMSを削除することが可能です。残念ながら、すべてが普通の航海というわけではありません:(

受信SMSメッセージを受信する受信機があります。 Android SMS着信ルーティングが機能する方法は、メッセージのデコードを担当するコードがブロードキャストを送信することです(残念ながらsendBroadcast()メソッドを使用します)は、メッセージが到着するたびにabortBroadcast())を呼び出すことができるバージョンではありません。

レシーバーは、システムSMSレシーバーの前に呼び出される場合と呼び出されない場合があり、いずれにしても、受信したブロードキャストにはSMSテーブルの__id_列を反映するプロパティがありません。

ただし、停止オブジェクトではないため、SmsMessageを添付オブジェクトとして遅延メッセージを(ハンドラーを介して)簡単に投稿できます。 (自分自身もRunnableを投稿できると思います...)

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

遅延は、メッセージが到着するまでに、すべてのブロードキャストレシーバーが処理を完了し、メッセージがSMSテーブルに安全に収まるようにするためにあります。

メッセージ(またはRunnable)がここで受信されたとき、私は何をしますか:

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

発信元のアドレスとタイムスタンプフィールドを使用して、関心のあるメッセージのみを削除する非常に高い確率を確保します。さらに偏執的になりたい場合は、クエリの一部としてmsg.getMessageBody()コンテンツを含めることができます。

はい、メッセージISは削除されました(やった!)。残念ながら、通知バーは更新されません:(

通知領域を開くと、そこに座っているメッセージが表示されます...しかし、それをタップして開くと、消えます!

私には、これでは十分ではありません-メッセージのすべてのトレースが消えるようにしたい-存在しないときにTXTがあるとユーザーに思わせたくないバグレポート)。

OSの内部では、電話はMessagingNotification.updateNewMessageIndicator(Context)を呼び出しますが、そのクラスはAPIから隠されているため、インジケーターを正確にするためだけにすべてのコードを複製したくありませんでした。

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

androidManifiestでこの権限を使用します

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

_idとthread_idを使用してメッセージを削除することをお勧めします。

Thread_idは、同じユーザーからのメッセージに割り当てられたものです。したがって、thread_idのみを使用すると、送信者からのすべてのメッセージが削除されます。

Uが_idとthread_idの組み合わせを使用する場合、削除しようとしているメッセージそのものを削除します。

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

メッセージの [〜#〜] uri [〜#〜] を見つける必要があります。しかし、一度やると、Android.content.ContentResolver.delete(...)できるはずです。

ここにさらにいくつかあります info

5
Neil

とりあえずこれは完全にはできないと思います。 2つの基本的な問題があります。

  1. SMSを削除しようとしたときに、SMSが既に受信トレイにあることを確認するにはどうすればよいですか?
    SMS_RECEIVEDは順序付けられたブロードキャストではないことに注意してください。
    したがって、dmyungの解決策は、運を完全に試しています。ダグの答えの遅れさえ保証ではありません。

  2. SmsProviderはスレッドセーフではありません( http://code.google.com/p/Android/issues/detail?id=2916#c を参照)
    複数のクライアントが同時に削除と挿入を要求しているという事実により、データが破損したり、即時のランタイム例外が発生したりします。

2
an0

Dmyungのソリューションを使用して動作させることはできませんでした。メッセージIDまたはスレッドIDを取得するときに例外が発生しました。

最後に、次のメソッドを使用してスレッドIDを取得しました。

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

その後、削除できます。ただし、Dougが言ったように、通知はまだあり、通知パネルを開くとメッセージが表示されます。メッセージをタップしたときのみ、実際に空であることがわかりました。

したがって、これが機能する唯一の方法は、システムに配信される前、受信ボックスに到達する前にSMSを実際に何らかの方法でインターセプトすることです。私が間違っている場合は私を修正してください。

2
Stelian Iancu

この関数を使用して、特定のメッセージスレッドを削除するか、必要に応じて変更します

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

  }
}

以下でこの関数を呼び出します:

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

以下を追加することを忘れないでくださいAndroid以下のメインフェスト許可:

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

また、書き込み許可が必要なSMSを削除するためにマニフェストファイルを更新します。

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

このリンクをご覧ください。ロジックの簡単な説明が表示されます。

https://Gist.github.com/5178e798d9a00cac4ddb
通知の時間と実際に保存される時間にはわずかな違いがあるため、少し遅れてdeleteSMS()関数を呼び出してください。詳細については、このリンクもご覧ください.......

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

ありがとう..........

1
viv

デフォルトのSMSアプリの通知をオフにするだけです。すべてのテキストメッセージに対して独自の通知を処理します。

1
Noah Seidman

次のコードを試してください。電話にあるすべてのSMS(受信または送信)が削除されます。

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

abortBroadcast();メソッドを使用して、受信メッセージを受信トレイに移動することを制限できます。

1
AB1209

このメソッドのいずれかを使用して、最後に受信したSMSを選択して削除します。この場合、私は一番上のSMSを取得し、スレッドとSMSのID値を使用して削除します。

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

これを試してみて、これがうまくいくことを100%確信しています:-//アドレスごとに変換全体を削除するために変換アドレスをここに入れてください(メインフェストに読み取り、書き込み許可を追加することを忘れないでください)ここにコードがあります:

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

会話ではなく1つのSMSを削除するサンプル:

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