¿Cómo eliminar un SMS de la bandeja de entrada en Android mediante progtwigción?

En los 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.

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

Entonces el escenario:

  • Inicio de la aplicación Android.
  • registrar mensajes SMS tipo X, Y y Z
  • mensajes P, Q, X, Y, Z transmitidos a lo largo del tiempo, todos depositados en la bandeja de entrada
  • La aplicación Android detecta la recepción de X, Y, Z (presumiblemente como parte del evento de interrupción del progtwig)
  • proceso X, Y, Z
  • Desirement !!! X, Y, Z se eliminan de la bandeja de entrada de Android

Ha sido hecho? Se puede hacer?

“A partir de Android 1.6, las transmisiones de mensajes SMS entrantes ( android.provider.Telephony.SMS_RECEIVED ) se entregan 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 su archivo AndroidManifest.xml , asegúrese de tener la prioridad establecida en el más alto:

      

En su método BroadcastReceiver , en el método onReceive() , antes de realizar cualquier abortBroadcast(); con su mensaje, simplemente llame a abortBroadcast();

EDITAR: A partir de KitKat, aparentemente esto ya no funciona.

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

Eliminar SMS de android en 4.4.4 (filas afectadas = 0 (cero), después de eliminarse)

Usando sugerencias de otros, creo que lo hice funcionar:

(usando SDK v1 R2)

No es perfecto, ya que necesito 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: No pude hacer una eliminación en el contenido: // sms / inbox / o contenido: // sms / all /

Parece que el hilo tiene prioridad, lo que tiene sentido, pero el mensaje de error solo me envalentonó para estar más enojado. Al intentar eliminar en sms / inbox / o sms / all /, probablemente obtendrá:

 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) 

Para referencia adicional también, asegúrese de poner esto en su manifiesto para su receptor intencionado:

      

Tenga en cuenta que la etiqueta del receptor no se ve así:

  

Cuando tuve esas configuraciones, android me dio algunas excepciones locas de permisos que no permitían a android.phone entregar el SMS recibido según mi intención. ¡Entonces, NO pongas ese atributo de permiso RECEIVE_SMS en tu bash! Espero que alguien más sabio que yo pueda decirme por qué fue ese el caso.

Entonces, tuve una jugada, y es posible eliminar un SMS recibido. Lamentablemente, no todo es simple navegación 🙁

Tengo un receptor que capta los mensajes SMS entrantes. Ahora, la forma en que funciona el enrutamiento de SMS de Android sendBroadcast() que la pieza de código responsable de decodificar los mensajes envía una difusión (usa el método sendBroadcast() que lamentablemente NO es la versión que le permite simplemente llamar a abortBroadcast() ) cada vez que abortBroadcast() un mensaje llega

Mi receptor puede o no ser llamado antes que el receptor de Systems SMS, y en cualquier caso la transmisión recibida no tiene ninguna propiedad que pueda reflejar la columna _id en la tabla de SMS.

Sin embargo, al no ser tan fácil de detener, me publico (a través de un Handler) un mensaje retrasado con SmsMessage como el objeto adjunto. (Supongo que también podrías publicar un Runnable …)

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

La demora está allí para garantizar que, cuando llegue el mensaje, todos los receptores de difusión hayan terminado sus cosas y el mensaje se instalará de forma segura en la mesa de SMS.

Cuando el mensaje (o Runnable) se recibe 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())}); 

Uso la dirección de origen y el campo de marca de tiempo para asegurar una probabilidad muy alta de eliminar ÚNICAMENTE el mensaje que me interesa. Si quisiera ser aún más paranoico, podría incluir el contenido de msg.getMessageBody() como parte de la consulta.

Sí, el mensaje ES eliminado (¡hurra!). Lamentablemente, la barra de notificaciones no se actualiza 🙁

Cuando abras el área de notificación, verás que el mensaje está ahí para ti … pero cuando lo tocas para abrirlo, ¡ya no está!

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 lo hay (eso solo causaría informes de errores).

Internamente en el sistema operativo, el teléfono llama a 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.

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

usa este permiso en AndroidManifiest

  

Es mejor usar _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, todos los mensajes del remitente se eliminarán.

Si usa la combinación de _id, thread_id, entonces 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)} ); 

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 algo más de información .

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

  1. ¿Cómo puede asegurarse de que el sms ya está en la bandeja de entrada cuando intenta eliminarlo?
    Observe que SMS_RECEIVED no es una transmisión ordenada.
    Entonces, la solución de dmyung es probar la suerte por completo; incluso el retraso en la respuesta de Doug no es una garantía.

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

No pude hacer que funcionara usando la solución de dmyung, me dio una excepción cuando recibía el ID del mensaje o el ID del hilo.

Al final, utilicé el siguiente método para obtener el ID del hilo:

 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 eliminarlo. 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 forma 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.

Utilice esta función para eliminar un hilo de mensaje 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) { } } 

Llame a esta función simplemente a continuación:

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

No olvides agregar el permiso de usuario principal de Android a continuación:

  

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

Solo eche un vistazo a este enlace, le dará una breve idea de la lógica:

https://gist.github.com/5178e798d9a00cac4ddb
Simplemente llame a la función deleteSMS () con un poco de retraso, porque hay una pequeña diferencia entre el momento de la notificación y cuándo se guarda realmente …, para más detalles, eche un vistazo a este enlace también …….. ..

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

Gracias……….

También actualice el archivo de manifiesto para eliminar un sms que necesita permisos de escritura.

  

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

Ejemplo para eliminar un mensaje de texto, no conversación:

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

Intenta con el siguiente código. Eliminará 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); } 
 @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; } 

Prueba esto, estoy 100% seguro de que esto funcionará bien: – // simplemente pon la dirección de conversión aquí para eliminar la conversión completa por dirección (no olvides agregar permiso de lectura, escritura en mainfest) Aquí está el 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) { } 

Utilice uno de este método para seleccionar el último SMS recibido y eliminarlo, aquí en este caso estoy obteniendo el máximo de sms y voy a eliminar usando el hilo y el valor de identificación 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(); }