2009-01-07 9 views
95

En teléfonos Android, los mensajes SMS registrados en las aplicaciones también se envían a la bandeja de entrada del dispositivo. Sin embargo, para evitar el desorden, sería bueno poder eliminar los mensajes SMS específicos de la aplicación de la bandeja de entrada para reducir el posible desbordamiento de esos mensajes.¿Cómo eliminar un SMS de la bandeja de entrada en Android mediante programación?

Preguntas sobre otros grupos de Google para obtener una respuesta definitiva de forma programática para eliminar mensajes SMS de la bandeja de entrada de Android no parecen estar presionando.

Así que el escenario:

  • Android App arranque.
  • Registro de mensajes SMS tipos X, Y y Z
  • mensajes P, Q, X, Y, corriente Z, en el transcurso del tiempo, todos los deposita en la bandeja de entrada
  • aplicación Android detecta la recepción de X, Y, Z (presumiblemente como parte del evento de interrupción del programa)
  • proceso X, Y, Z
  • Desirement !!! X, Y, Z se eliminan de la bandeja de entrada de Android

Has it been done? Se puede hacer?

+4

que he encontrado haciendo algo útil con las capacidades de teléfono de Android a ser una experiencia muy desagradable. – BobbyShaftoe

+1

buena pregunta compañero. Estaba buscando algo similar: D cheers –

+3

Lo mejor sería evitar que los SMS lleguen a la bandeja de entrada en primer lugar: http://stackoverflow.com/questions/1741628/can-we-delete-an-sms-in- android-before-it-reaching-the-inbox/2566199 # 2566199 –

Respuesta

5

Deberá encontrar el URI del mensaje. Pero una vez que lo haga, creo que debería ser capaz de android.content.ContentResolver.delete (...).

Aquí hay algunos más info.

27

Uso de sugerencias de otros, creo que tengo que trabajar:

(utilizando el SDK v1 R2)

No es perfecto, ya que tengo que eliminar toda la conversación, pero para nuestros propósitos, es un compromiso suficiente ya que, al menos, sabremos que todos los mensajes serán examinados y verificados. Nuestro flujo probablemente necesite escuchar el mensaje, capturar el mensaje que queremos, realizar una consulta para obtener el thread_id del mensaje recientemente ingresado y realizar la llamada a delete().

en nuestra actividad:

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

Nota: yo no era capaz de hacer una eliminación de contenido: // SMS/bandeja de entrada/o contenido: // SMS/all/

Parece el hilo tiene prioridad, lo cual tiene sentido, pero el mensaje de error solo me envalentonó para estar más enojado. Al intentar la eliminación en SMS/bandeja de entrada/o SMS/todo /, es probable que obtener:

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) 

Como referencia adicional también, asegúrese de poner esto en su manifiesto para su receptor intención:

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

la etiqueta receptor no se parece a esto:

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

Cuando tuve esa configuración, androide me dio algunas excepciones permisos locos que no permitía android.phone a mano del reci ed SMS a mi intención.¡Entonces, NO pongas ese atributo de permiso RECEIVE_SMS en tu intento! Espero que alguien más sabio que yo pueda decirme por qué fue ese el caso.

+0

¿Cómo funciona eso en KitKat? –

+0

¿Puedes ver aquí http://stackoverflow.com/questions/25988574/delete-sms-from-android-on-4-4-4-affected-rows-0zero-after-deleted? –

24

Entonces, tuve una obra de teatro, y es es posible eliminar un SMS recibido. Por desgracia, no todo es un camino de rosas :(

Tengo un receptor que recoge los mensajes SMS entrantes. Ahora, la forma en que funciona el enrutamiento de entrada de Android SMS es que el trozo de código responsable de la decodificación de los mensajes envía un broadcast (se utiliza el método sendBroadcast() -. que por desgracia no es la versión que le permite simplemente llamar abortBroadcast()) cada vez que llega un mensaje

Mi receptor puede o no puede ser llamado antes de que el receptor de los sistemas SMS, y en todo caso la emisión recibida no tiene propiedad que podría reflejar la columna _id en la tabla SMS.

Sin embargo, al no ser tan fácil de detener, me publico (a través de un controlador) un mensaje retrasado con SmsMessage como el objeto adjunto. (Supongo que se puede publicar usted mismo un Ejecutable también ...)

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

El retraso está ahí para asegurarse de que en el momento en que el mensaje llega a todos los receptores de radiodifusión se han terminado sus cosas y el mensaje será segura instalado en la mesa SMS.

Cuando se recibe el mensaje (o Ejecutable) que aquí es lo que hago:

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

utilizo la dirección de origen y el campo de marca de tiempo para asegurar una probabilidad muy alta de borrar sólo el mensaje Estoy interesado en. Si quisiera ser aún más paranoico, podría incluir el contenido msg.getMessageBody() como parte de la consulta.

Sí, se borró el mensaje (¡hurra!). Desafortunadamente la barra de notificaciones no se actualiza :(

Al abrir el área de notificación verá el mensaje de estar allí para usted ... pero cuando se pulsa sobre él para abrirlo - se ha ido

!

Para mí, esto no es lo suficientemente bueno, quiero que desaparezca todo rastro del mensaje. No quiero que el usuario piense que hay un TXT cuando no existe (eso solo causaría informes de errores).

Internamente en el sistema operativo el teléfono llama al MessagingNotification.updateNewMessageIndicator(Context), pero esa clase se ha ocultado de la API, y no quería replicar todo ese código solo por el bien de hacer que el indicador sea preciso.

+0

Doug, esto es genial. Como pregunta, ¿sabes si es necesario hacer la publicación al Manejador? Me pregunto si el SMS está insertado en la base de datos de SMS del sistema antes y se llaman los receptores de difusión. Es probable que tenga que buscar en el sistema operativo para ver dónde ocurre la inserción, pero supongo que la inserción del SMS en alguna base de datos ocurre antes de que se informe a los receptores de difusión. ¿Tiene alguna idea de esto o ya lo ha comprobado? – Hamy

+0

¿Puedes ver aquí http://stackoverflow.com/questions/25988574/delete-sms-from-android-on-4-4-4-affected-rows-0zero-after-deleted? –

2

Creo que esto no se puede hacer perfectamente por el momento. Hay 2 problemas básicos:

  1. ¿Cómo se puede asegurar de que el sms ya está en la bandeja de entrada cuando intenta eliminarlo?
    Observe que SMS_RECEIVED no es una transmisión ordenada.
    Así que la solución de dmyung está probando completamente la suerte; incluso el retraso en la respuesta de Doug no es una garantía.

  2. El SmsProvider no es seguro para subprocesos.(refiérase a http://code.google.com/p/android/issues/detail?id=2916#c0)
    El hecho de que más de un cliente solicite eliminar e insertar en él al mismo tiempo causará daños en los datos o incluso una Excepción Runtime inmediata.

2

no pude conseguir que funcione utilizando la solución de dmyung, me dio una excepción al obtener el identificador de mensaje o ID del tema.

Al final, he utilizado el siguiente método para obtener el ID del tema:

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

Entonces podría suprimirlo. Sin embargo, como dijo Doug, la notificación aún está allí, incluso el mensaje se muestra al abrir el panel de notificaciones. Solo cuando tocas el mensaje, puedo ver que está vacío.

Así que supongo que la única manera de que esto funcione sería interceptar de alguna manera el SMS antes de que llegue al sistema, incluso antes de que llegue a la bandeja de entrada. Sin embargo, dudo que esto sea factible. Por favor corrígeme si estoy equivocado.

+0

Bueno, estás _ mal al interceptar mensajes antes de la bandeja de entrada: puedes recibir una emisión android.provider.Telephony.SMS_RECEIVED, solo necesitas una permsión android.permission.RECEIVE_SMS. Incluso puede detener fácilmente que el mensaje llegue a la bandeja de entrada llamando a abortBroadcast() ya que es una transmisión ordenada. PD Debe ser divertido para ser corregido 2 años después :) – lapis

1

Desactive las notificaciones de la aplicación sms predeterminada. ¡Procese sus propias notificaciones para todos los mensajes de texto!

0

Usted acaba de intente lo siguiente code.It borrará todos los SMS que están todos en el teléfono (recibido o enviado)

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

muestra para borrar un SMS, no conversación:

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

"A partir de Android 1.6, las transmisiones de mensajes SMS entrantes (android.provider.Telephony.SMS_RECEIVED) se envían como una "transmisión ordenada", lo que significa que puede decirle al sistema qué componentes deberían recibir la transmisión primero ".

Esto significa que puede interceptar el mensaje entrante y cancelar la transmisión de él más adelante.

En el archivo AndroidManifest.xml, asegúrese de tener la prioridad establecida en alto:

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

En su BroadcastReceiver, en onReceive() método, antes de realizar cualquier cosa con su mensaje, sólo tiene que llamar abortBroadcast();

EDIT: Como de KitKat, aparentemente esto ya no funciona.

Edit2: Más información sobre cómo hacerlo en KitKat aquí:

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

+3

Hermosa respuesta. Necesita más votos! –

+3

Y asegúrese de ver http://stackoverflow.com/questions/1741628/can-we-delete-an-sms-in-android-before-it-reaches-the-inbox/2566199#2566199 –

+0

+1 Gran respuesta :) –

1

actualización también el archivo de manifiesto como borrar un SMS que necesita permisos de escritura.

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

Es mejor utilizar _id y thread_id para eliminar un mensaje.

Thread_id es algo asignado a los mensajes que provienen del mismo usuario. Por lo tanto, si solo usa thread_id, se eliminarán todos los mensajes del remitente.

Si usa la combinación de _id, thread_id, eliminará el mensaje exacto que desea eliminar.

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

Puede ver aquí http://stackoverflow.com/questions/25988574/delete-sms-from-android-on-4-4-4-affected- rows-0zero-after-deleted? –

1

Ahora abortBroadcast(); método se puede utilizar para restringir el mensaje entrante para ir a la bandeja de entrada.

0

Utilice uno de este método para seleccionar el último SMS recibido y eliminarlo, aquí en este caso estoy consiguiendo los mejores mayoría de los sms y va a eliminar el uso de hilo y valor de ID de 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(); 
} 
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; 
} 

uso de este permiso AndroidManifiest

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

Funciona para mí :) – user1007522

+1

¿Cómo obtenemos sms id? – Dev01

+0

http://wisdomitsol.com/blog/android/sms/read-sms-from-the-inbox-or-sent-folder-programmatically-in-android –

0

Prueba esto estoy 100% seguro de que esto va a funcionar bien: - // sólo hay que poner la dirección de conversión aquí para la conversión de toda borrado por la dirección (no se olvidó de añadir leer, escribir el permiso de mainfest) Aquí es Código:

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

Utilice esta función para borrar cadena de mensajes específico o modificar según sus necesidades:

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

    } 
} 

Llamar a esta función simplemente debajo:

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

No se olvide de añadir el permiso mainfest androide a continuación:

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