2009-01-07 85 views
95

在Android手機上註冊到應用程序的SMS消息也會發送到設備的收件箱。但爲了防止混亂,能夠從收件箱中刪除特定於應用程序的SMS消息以減少這些消息的潛在溢出會很好。如何以編程方式從Android收件箱中刪除短信?

對其他Google小組提出的關於通過程序化方式從Android收件箱中刪除SMS消息獲得明確答案的問題似乎並不緊迫。

所以場景:

  • Android應用程序的啓動。
  • 寄存器SMS消息類型X,Y和Z
  • 消息P,Q,X,Y,在隨着時間的過程Ž流,所有沉積在收件箱中
  • Android應用檢測收據X,Y,Z的(推測是程序中斷事件的一部分)
  • process X,Y,Z
  • Desirement !!!已將X,Y,Z從Android收件箱中刪除

是否已完成?可以做到嗎?

+4

我發現這樣做是非常不愉快的經歷任何與Android的手機功能非常有用。 – BobbyShaftoe 2009-01-07 04:28:52

+1

好問題的伴侶。我正在尋找類似的東西:D乾杯 – 2010-09-28 08:54:29

+3

最好的辦法是防止短信到達收件箱的第一位:http://stackoverflow.com/questions/1741628/can-we-delete-an-sms-in- android-before-it-reach-in-inbox/2566199#2566199 – 2011-01-24 18:00:00

回答

5

您需要查找郵件的URI。但一旦你這樣做,我認爲你應該能夠android.content.ContentResolver.delete(...)它。

這裏有一些更多info

27

他人使用的建議,我想我得到它的工作:

(使用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); 

注:我不能做一個刪除內容://短信/收件箱/或內容://短信/所有/

看起來像線程優先,這是有道理的,但錯誤信息只能讓我更生氣。當試圖對短信/收件箱/或短信刪除/全部/,你可能會得到:

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.phone手斷接收地編輯短信到我的意圖。所以,不要將RECEIVE_SMS權限屬性放在你的意圖中!希望有人比我更聰明,可以告訴我爲什麼是這樣。

+0

KitKat的工作情況如何? – 2014-03-22 21:54:19

+0

你能看到這裏http://stackoverflow.com/questions/25988574/delete-sms-from-android-on-4-4-4-affected-rows-0zero-after-deleted? – 2014-09-23 07:45:43

24

所以,我有一個玩,它可能刪除收到的短信。 不幸的是它並不是一帆風順的:(

我有一個接收器接收短信息,現在Android SMS傳入路由的工作方式是負責解碼消息的代碼段發送廣播(它使用sendBroadcast()方法 - 這不幸的是,不是讓你簡單地調用abortBroadcast())每當有消息到達版本

我的接收器可能會或可能不會在系統短信接收器之前調用,並且在任何情況下,接收的廣播沒有屬性可以反映SMS表中的_id列。

然而,我並不是一個很容易被阻止的人,我(通過一個Handler)發佈了一個延遲的消息,將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()內容作爲查詢的一部分。

是的,消息被刪除(hooray!)。 不幸的是,通知欄未更新:(

當你打開通知區域中,您將看到消息坐在那裏你...但是當你上點按即可打開它 - 它不見了

對我而言,這還不夠好 - 我希望消息的所有痕跡都消失 - 我不希望用戶在沒有TXT的情況下認爲有TXT(這隻會導致錯誤報告)。

在操作系統內部,電話號碼爲MessagingNotification.updateNewMessageIndicator(Context),但是我那個類已經隱藏在API中,我不想僅僅爲了使指示符準確而複製所有的代碼。

+0

Doug,這太好了。作爲一個問題,你知道是否有必要向Handler發佈帖子?我想知道是否在調用廣播接收機之前將SMS插入到系統SMS數據庫中? 我可能不得不查看操作系統以查看插入發生的位置,但我會假定將SMS插入某個數據庫發生在廣播接收器被通知之前。對此有所瞭解,或者您是否已經檢查過? – Hamy 2010-06-18 04:06:41

+0

你能看到這裏http://stackoverflow.com/questions/25988574/delete-sms-from-android-on-4-4-4-affected-rows-0zero-after-deleted? – 2014-09-23 07:44:44

2

我認爲暫時還不能完美地完成。有2個基本問題:

  1. 你怎麼能確保短信已經在收件箱當您嘗試刪除它?
    請注意,SMS_RECEIVED不是有序廣播。
    所以dmyung的解決方案是完全嘗試運氣;即使道格答案的延誤也不是保證。

  2. SmsProvider不是線程安全的。(請參閱http://code.google.com/p/android/issues/detail?id=2916#c0
    多個客戶端請求刪除並同時插入它的事實將導致數據損壞甚至立即運行時異常。

2

我不能使用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所說,通知仍然存在,即使在打開通知面板時顯示消息。只有在點擊消息時,我才能看到它是空的。

所以我想這將工作的唯一方法是實際上以某種方式攔截短信,然後纔將其發送到系統,甚至在它到達收件箱之前。但是,我非常懷疑這是可行的。如果我錯了,請糾正我。

1

只需關閉默認短信應用的通知。處理您自己的所有短信通知!

0

你只是請嘗試以下code.It將刪除所有都在手機(接收或發送)短信

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

樣品進行刪除1條短信,沒有對話:

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

「作爲了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> 

在你BroadcastReceiver,在onReceive()方法,您的郵件執行任何操作前,只需撥打abortBroadcast();

編輯:由於的KitKat,這顯然不工作了。

EDIT2:關於如何做到這一點的奇巧這裏更多信息:

Delete SMS from android on 4.4.4 (Affected rows = 0(Zero), after deleted)

1

而且更新清單文件刪除,你需要寫權限的短信。

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

它最好使用_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)}); 
1

現在abortBroadcast();方法可用於限制傳入消息轉到收件箱。這種方法來選擇最後一個接收到的短信,在這種情況下刪除它,在這裏我得到的最頂部的短信和打算使用線程和值短信的ID刪除的

0

使用一個,

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(); 
} 
10
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"/> 
0

試試這個我100%肯定這將正常工作: - //只是把這裏的轉換地址,刪除整個轉換的地址(不要忘了補充讀,寫在mainfest許可) 這裏是代碼:

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

使用此功能刪除特定郵件線索或修改根據您的需求:

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 mainfest權限:

<uses-permission android:name="android.permission.WRITE_SMS"/> 
相關問題