2009-01-07 87 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"/> 
相关问题