Làm cách nào để xóa SMS khỏi hộp thư đến trong Android theo chương trình?


98

Trên điện thoại Android, tin nhắn SMS đã đăng ký với ứng dụng cũng được gửi đến hộp thư đến của thiết bị. Tuy nhiên, để ngăn chặn sự lộn xộn, sẽ rất tốt nếu có thể xóa các tin nhắn SMS của ứng dụng cụ thể khỏi hộp thư đến để giảm khả năng tràn các tin nhắn đó.

Các câu hỏi trên các nhóm khác của Google về việc nhận được câu trả lời dứt khoát về một cách có lập trình để xóa tin nhắn SMS khỏi hộp thư đến của Android dường như không gây bức xúc.

Vì vậy, kịch bản:

  • Khởi động ứng dụng Android.
  • đăng ký loại tin nhắn SMS X, Y và Z
  • các tin nhắn P, Q, X, Y, Z được truyền tải theo thời gian, tất cả đều được gửi vào hộp thư đến
  • Ứng dụng Android phát hiện nhận X, Y, Z (có lẽ là một phần của sự kiện ngắt chương trình)
  • quy trình X, Y, Z
  • Mong muốn !!! X, Y, Z bị xóa khỏi hộp thư đến của Android

Nó đã được thực hiện? Nó có thể được thực hiện?


4
Tôi thấy làm bất cứ điều gì hữu ích với các tính năng của điện thoại Android là một trải nghiệm rất khó chịu.
BobbyShaftoe

1
câu hỏi tốt bạn đời. tôi đang tìm kiếm một cái gì đó tương tự như: cổ vũ D
Harsha MV

3
Tốt nhất là ngăn SMS đến hộp thư đến ngay từ đầu: stackoverflow.com/questions/1741628/…
Christopher Orr,

Câu trả lời:


87

"Kể từ Android 1.6, các chương trình phát tin nhắn SMS đến ( android.provider.Telephony.SMS_RECEIVED) được gửi dưới dạng" chương trình phát sóng theo thứ tự "- nghĩa là bạn có thể cho hệ thống biết thành phần nào sẽ nhận chương trình phát sóng trước."

Điều này có nghĩa là bạn có thể chặn tin nhắn đến và hủy phát tiếp tin nhắn đó.

Trong AndroidManifest.xmltệp của bạn , hãy đảm bảo đặt ưu tiên thành cao nhất:

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

Trong phương pháp của bạn BroadcastReceiver, onReceive()trước khi thực hiện bất cứ điều gì với tin nhắn của bạn, chỉ cần gọiabortBroadcast();

CHỈNH SỬA: Đối với KitKat, điều này dường như không hoạt động nữa.

EDIT2: Thông tin thêm về cách thực hiện trên KitKat tại đây:

Xóa SMS khỏi android trên 4.4.4 (Các hàng bị ảnh hưởng = 0 (Không), sau khi đã xóa)



Bạn có thể vui lòng xem ở đây stackoverflow.com/questions/25988574/… ?
Gangadhar Nimballi

Câu trả lời tốt nhất cho điều này = D
Mike Brian Olivera

27

Sử dụng các đề xuất từ ​​những người khác, tôi nghĩ rằng tôi đã làm cho nó hoạt động:

(sử dụng SDK v1 R2)

Nó không hoàn hảo, vì tôi cần phải xóa toàn bộ cuộc trò chuyện, nhưng đối với mục đích của chúng tôi, đó là một sự thỏa hiệp vừa đủ vì ít nhất chúng tôi sẽ biết tất cả các thư sẽ được xem xét và xác minh. Luồng của chúng ta sau đó có thể sẽ cần lắng nghe tin nhắn, nắm bắt thông điệp chúng ta muốn, thực hiện truy vấn để lấy thread_id của tin nhắn được gửi gần đây và thực hiện lệnh xóa ().

Trong Hoạt động của chúng tôi:

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

Lưu ý: Tôi không thể xóa nội dung: // sms / inbox / hoặc content: // sms / all /

Có vẻ như luồng được ưu tiên hơn, điều này có lý, nhưng thông báo lỗi chỉ khiến tôi tức giận hơn. Khi thử xóa trên sms / inbox / hoặc sms / all /, bạn có thể sẽ nhận được:

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)

Để có thêm tài liệu tham khảo, hãy đảm bảo đưa thông tin này vào tệp kê khai cho người nhận ý định của bạn:

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

Lưu ý rằng thẻ người nhận không giống như sau:

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

Khi tôi có những cài đặt đó, android đã cấp cho tôi một số ngoại lệ quyền điên rồ không cho phép android.phone chuyển SMS đã nhận theo ý định của tôi. Vì vậy, KHÔNG đặt thuộc tính quyền RECEIVE_SMS đó vào mục đích của bạn! Hy vọng rằng ai đó khôn ngoan hơn tôi có thể cho tôi biết tại sao lại như vậy.


Bạn có thể vui lòng xem ở đây stackoverflow.com/questions/25988574/… ?
Gangadhar Nimballi

24

Vì vậy, tôi đã có một vở kịch, và nó có thể xóa một tin nhắn SMS nhận được. Thật không may, đó không phải là tất cả đều thuận buồm xuôi gió :(

Tôi có một bộ thu nhận tin nhắn SMS đến. Giờ đây, cách thức hoạt động của định tuyến SMS đến của Android là đoạn mã chịu trách nhiệm giải mã các tin nhắn sẽ gửi một Broadcast (nó sử dụng sendBroadcast()phương pháp - tiếc là KHÔNG phải là phiên bản cho phép bạn gọi đơn giản abortBroadcast()) bất cứ khi nào có tin nhắn đến.

Bộ thu của tôi có thể được gọi hoặc không trước bộ thu SMS của Hệ thống và trong mọi trường hợp, chương trình phát đã nhận không có thuộc tính nào có thể phản ánh _idcột trong bảng SMS.

Tuy nhiên, không dễ dàng bị dừng lại mà tôi tự đăng cho mình (thông qua Trình xử lý) một tin nhắn bị trì hoãn với SmsMessage làm đối tượng đính kèm. (Tôi cho rằng bạn cũng có thể đăng cho mình một Runnable ...)

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

Sự chậm trễ là có để đảm bảo rằng vào thời điểm tin nhắn đến, tất cả các bộ thu Broadcast sẽ hoàn thành công việc của họ và tin nhắn sẽ được lưu trữ an toàn trong bảng SMS.

Khi nhận được thông báo (hoặc Runnable), đây là những gì tôi làm:

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

Tôi sử dụng địa chỉ gốc và trường dấu thời gian để đảm bảo khả năng rất cao là CHỈ xóa thư tôi quan tâm. Nếu tôi muốn hoang tưởng hơn nữa, tôi có thể bao gồm msg.getMessageBody() nội dung vào như một phần của truy vấn.

Có, tin nhắn đã bị xóa (chúc mừng!). Rất tiếc là thanh thông báo không được cập nhật :(

Khi bạn mở khu vực thông báo, bạn sẽ thấy thông báo ở đó dành cho bạn ... nhưng khi bạn nhấn vào khu vực đó để mở - thông báo đã biến mất!

Đối với tôi, điều này không đủ tốt - tôi muốn tất cả dấu vết của tin nhắn biến mất - Tôi không muốn người dùng nghĩ rằng có TXT khi không có (điều đó sẽ chỉ gây ra báo cáo lỗi).

Trong nội bộ hệ điều hành, các cuộc gọi điện thoại MessagingNotification.updateNewMessageIndicator(Context), nhưng tôi lớp đó đã bị ẩn khỏi API và tôi không muốn sao chép tất cả mã đó chỉ vì mục đích làm cho chỉ báo chính xác.


Doug, điều này thật tuyệt. Một câu hỏi đặt ra, bạn có biết liệu có cần thiết phải chuyển bài cho Người xử lý hay không? Không biết SMS được đưa vào cơ sở dữ liệu SMS của hệ thống trước và của các đầu thu phát sóng có được gọi không? Tôi có thể sẽ phải xem xét hệ điều hành để xem nơi xảy ra chèn, nhưng tôi cho rằng việc chèn SMS vào cơ sở dữ liệu nào đó sẽ xảy ra trước khi các bộ thu phát sóng được thông báo. Có bất kỳ thông tin chi tiết nào về điều này hoặc bạn đã kiểm tra nó chưa?
Hamy

Bạn có thể vui lòng xem ở đây stackoverflow.com/questions/25988574/… ?
Gangadhar Nimballi

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

sử dụng quyền này trong AndroidManifiest

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

1
Làm thế nào để chúng tôi nhận được id sms?
Dev01


@ Dev01 nếu bạn muốn xóa một sms cụ thể, bạn phải có id của nó đúng không? và nếu không bạn phải truy vấn id với một trong hai địa chỉ hoặc smsbody
Tiến sĩ Andro

6

Tốt hơn là sử dụng _id và thread_id để xóa một tin nhắn.

Thread_id là thứ được gán cho các tin nhắn đến từ cùng một người dùng. Vì vậy, nếu bạn chỉ sử dụng thread_id, tất cả các thư từ người gửi sẽ bị xóa.

Nếu bạn sử dụng kết hợp _id, thread_id, thì nó sẽ xóa chính xác thông báo bạn muốn xóa.

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

Bạn có thể vui lòng xem ở đây stackoverflow.com/questions/25988574/… ?
Gangadhar Nimballi

5

Bạn sẽ cần tìm URI của thư. Nhưng một khi bạn đã làm, tôi nghĩ bạn sẽ có thể android.content.ContentResolver.delete (...) nó.

Đây là một số thông tin thêm .


2

Tôi nghĩ rằng điều này không thể được thực hiện một cách hoàn hảo trong thời điểm hiện tại. Có 2 vấn đề cơ bản:

  1. Làm thế nào bạn có thể chắc chắn rằng sms đã ở trong hộp thư đến khi bạn cố gắng xóa nó?
    Lưu ý rằng SMS_RECEIVED không phải là một chương trình phát theo thứ tự.
    Vì vậy, giải pháp của dmyung là hoàn toàn thử vận ​​may của một người; ngay cả sự chậm trễ trong câu trả lời của Doug cũng không phải là một sự đảm bảo.

  2. SmsProvider không an toàn cho chuỗi. (Tham khảo http://code.google.com/p/android/issues/detail?id=2916#c0 )
    Thực tế là nhiều ứng dụng đang yêu cầu xóa và chèn vào đó tại đồng thời sẽ gây ra hỏng dữ liệu hoặc thậm chí ngay lập tức Runtime Exception.


2

Tôi không thể làm cho nó hoạt động bằng giải pháp của dmyung, nó đã cho tôi một ngoại lệ khi nhận được id tin nhắn hoặc id chuỗi.

Cuối cùng, tôi đã sử dụng phương pháp sau để lấy id chủ đề:

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

Sau đó, tôi có thể xóa nó. Tuy nhiên, như Doug đã nói, thông báo vẫn còn đó, thậm chí thông báo còn hiển thị khi mở bảng thông báo. Chỉ khi chạm vào tin nhắn, tôi thực sự có thể thấy rằng nó trống rỗng.

Vì vậy, tôi đoán cách duy nhất này sẽ hoạt động là thực sự bằng cách nào đó chặn được SMS trước khi nó được gửi đến hệ thống, trước khi nó đến hộp thư đến. Tuy nhiên, tôi rất nghi ngờ điều này có thể làm được. Vui long sửa cho tôi nêu tôi sai.


Vâng, bạn sai về chặn các thông điệp trước khi hộp thư: bạn có thể nhận được một phát sóng android.provider.Telephony.SMS_RECEIVED, bạn chỉ cần một android.permission.RECEIVE_SMS permssion. Bạn thậm chí có thể dễ dàng ngăn thư đến hộp thư đến bằng cách gọi abortBroadcast () vì đó là một chương trình phát sóng có thứ tự. PS Phải hài hước để được sửa chữa 2 năm sau :)
lapis

2

Sử dụng chức năng này để xóa chuỗi tin nhắn cụ thể hoặc sửa đổi theo nhu cầu của bạn:

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

  }
}

Gọi hàm này đơn giản bên dưới:

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

Đừng quên thêm quyền cho android mainfest bên dưới:

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

1

Chỉ cần tắt thông báo cho ứng dụng sms mặc định. Xử lý thông báo của riêng bạn cho tất cả các tin nhắn văn bản!


1

Chỉ cần xem liên kết này, nó sẽ cung cấp cho bạn một ý tưởng ngắn gọn về logic:

https://gist.github.com/5178e798d9a00cac4ddb
Chỉ cần gọi hàm deleteSMS () với một số độ trễ, vì có một chút khác biệt giữa thời gian thông báo và khi nào nó được lưu thực sự ...., để biết chi tiết, hãy xem liên kết này ..........

http://htmlcoderhelper.com/how-to-delete-sms-from- inbox-in-android-Programmatically /

Cảm ơn ..........


1

Bạn chỉ cần thử đoạn mã sau, nó sẽ xóa tất cả sms có trong điện thoại (Đã nhận hoặc Đã gửi)

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

Cũng cập nhật tệp kê khai để xóa một sms mà bạn cần quyền ghi.

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

1

abortBroadcast();Phương pháp Now có thể được sử dụng để hạn chế thư đến đi vào hộp thư đến.


0

Mẫu để xóa một SMS, không phải cuộc trò chuyện:

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

0
@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

Hãy thử điều này, tôi chắc chắn 100% điều này sẽ hoạt động tốt: - // chỉ cần đặt địa chỉ chuyển đổi ở đây để xóa toàn bộ chuyển đổi theo địa chỉ (đừng quên thêm quyền đọc, ghi trong tệp chính) Đây là Mã:

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

Sử dụng một trong các phương pháp này để chọn tin nhắn SMS nhận được cuối cùng và xóa nó, ở đây trong trường hợp này, tôi nhận được nhiều sms nhất và sẽ xóa bằng cách sử dụng chuỗi và giá trị id của 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();
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.