@DavidFreitas este enlace no funciona, ¿podría compartir el último enlace?
Khobaib
3
@Khobaib, como siempre, las cosas en Internet son fugaces. Encontré una copia en archive.org stackoverflow.com/a/19966227/40961 , gracias a Dios por ellos (he donado recientemente para mantenerlos en funcionamiento). Pero deberíamos considerar convertir el contenido de la página de web.archive.org/web/20121022021217/http://mobdev.olin.edu/… a la sintaxis de reducción en una respuesta a esta pregunta. Probablemente una hora de trabajo.
David d C e Freitas
Respuestas:
157
Use Content Resolver ( "content: // sms / inbox" ) para leer los SMS que están en la bandeja de entrada.
// public static final String INBOX = "content://sms/inbox";// public static final String SENT = "content://sms/sent";// public static final String DRAFT = "content://sms/draft";Cursor cursor = getContentResolver().query(Uri.parse("content://sms/inbox"),null,null,null,null);if(cursor.moveToFirst()){// must check the result to prevent exceptiondo{String msgData ="";for(int idx=0;idx<cursor.getColumnCount();idx++){
msgData +=" "+ cursor.getColumnName(idx)+":"+ cursor.getString(idx);}// use msgData}while(cursor.moveToNext());}else{// empty box, no SMS}
¡Gracias! Escribiste mal "getColumnName", de lo contrario, funciona de maravilla. Ah, y si alguien va a usar esto, no olvides agregar el permiso android.permission.READ_SMS.
qwerty
1
Gracias. Lo modifiqué :)
Suryavel TR
55
¿Esto también utiliza la API indocumentada que @CommonsWare especificó en su comentario a la respuesta aceptada?
Krishnabhadra
1
¡Atención! No te pierdas moveToFirstcomo yo lo hice.
Alexandr Priymak
44
@ Krishnabhadra Sí. Utiliza el proveedor de contenido indocumentado "content: // sms / inbox".
Esa es una buena pieza de código. Solo una cosa, el tiempo se obtiene en milisegundos. Creo que será mejor que sea un formato legible para humanos comoString receiveDayTime = Functions.dateFromMilisec(Long.valueOf(c.getColumnIndexOrThrow("date")), "hh:mm a MMM dd, yyyy");
Bibaswann Bandyopadhyay
1
¿cuál es el propósito de hacer todo con get y set, yo realmente no entiendo por qué no sólo tiene que utilizar una matriz asociativa o clase cuyos elementos se accede directamente
michnovka
1
@TomasNavara: Consulte este código para comprender el uso de getter y setter. pastebin.com/Nh8YXtyJ
errores ocurren el
@BibaswannBandyopadhyay Si no quieres usar nada excepto las bibliotecas de Android y las bibliotecas de Java. new SimpleDateFormat("hh:mm", Locale.US).format(new Date(Long.parseLong(_time)));Esto te dará 24 horas de tiempo.
Chris - Jr
mActivityno está definido. ¿Que es esto?
dthree
61
Es un proceso trivial. Puedes ver un buen ejemplo en el código fuente SMSPopup
Esto no es parte del SDK de Android. Este código supone incorrectamente que todos los dispositivos son compatibles con este proveedor de contenido no documentado y no compatible. Google ha indicado explícitamente que confiar en esto no es una buena idea: android-developers.blogspot.com/2010/05/…
CommonsWare
1
@ Janusz: No hay medios documentados y compatibles que funcionen en todos los clientes de SMS en todos los dispositivos.
CommonsWare
99
@CommonsWare que es triste de escuchar. Puede que tenga que vivir con esta API entonces.
Janusz
@Omer ¿Alguna idea de cómo contaría la cantidad de mensajes SMS por contacto?
SpicyWeenie
44
El código se ha movido. Al buscar SmsPopupUtils.java me conseguí un nuevo enlace en el código de Google. En caso de que lo muevan nuevamente o lo descontinúen por completo, aquí hay un enlace de respaldo: pastebin.com/iPt7MLyM
KalEl
25
Desde API 19 en adelante, puede hacer uso de la Clase de telefonía para eso; Dado que los valores codificados no recuperarán mensajes en todos los dispositivos porque el proveedor de contenido Uri cambia de dispositivos y fabricantes.
publicvoid getAllSms(Context context){ContentResolver cr = context.getContentResolver();Cursor c = cr.query(Telephony.Sms.CONTENT_URI,null,null,null,null);int totalSMS =0;if(c !=null){
totalSMS = c.getCount();if(c.moveToFirst()){for(int j =0; j < totalSMS; j++){String smsDate = c.getString(c.getColumnIndexOrThrow(Telephony.Sms.DATE));String number = c.getString(c.getColumnIndexOrThrow(Telephony.Sms.ADDRESS));String body = c.getString(c.getColumnIndexOrThrow(Telephony.Sms.BODY));Date dateFormat=newDate(Long.valueOf(smsDate));String type;switch(Integer.parseInt(c.getString(c.getColumnIndexOrThrow(Telephony.Sms.TYPE)))){caseTelephony.Sms.MESSAGE_TYPE_INBOX:
type ="inbox";break;caseTelephony.Sms.MESSAGE_TYPE_SENT:
type ="sent";break;caseTelephony.Sms.MESSAGE_TYPE_OUTBOX:
type ="outbox";break;default:break;}
c.moveToNext();}}
c.close();}else{Toast.makeText(this,"No message to show!",Toast.LENGTH_SHORT).show();}}
Parece ser la única respuesta que no utiliza API indocumentada y no se refiere a bibliotecas de terceros.
Ishamael
Intenté usar este código para recibir mensajes SMS de Hangouts (que es mi aplicación de SMS predeterminada). En cambio, recuperó el último mensaje saliente que envié a través de Messenger ... ¿Sabes qué está causando esto?
Miki P
@MikiP usando mis poderes de adivinanza, diré que la aplicación Messenger te preguntó acerca de cómo reemplazar la administración de SMS con Messenger. Sucede con alguna otra aplicación de mensajería. No tengo otra explicación.
m3nda
2
No olvides llamar a c.close ();
Cícero Moura
1
@SardarAgabejli Si usamos valores codificados como "contenturi: sms", no será lo mismo para todos los dispositivos, pero si usamos la clase de telefonía, obtendremos acceso directo a esa uri o la ruta de sms db de ese dispositivo, es una clase auxiliar para señalar el db de sms
Manoj Perumarath
23
Esta publicación es un poco antigua, pero aquí hay otra solución fácil para obtener datos relacionados con SMS proveedor de contenido en Android:
Cada SMS tiene todos los campos, por lo que puede obtener cualquier información que necesite: dirección, cuerpo, fecha de recepción, tipo (INBOX, SENT, DRAFT, ..), threadId, ...
Bueno ... ¿es ese ("com.aquadeals.seller.services.SmsReceiver") el nombre común del servicio?
m3nda
Sí, ese no es el nombre del servicio, esa es la ruta de clase SmsReceiver en mi aplicación
Venkatesh
¿Por qué necesita permiso para LOCATION?
Zam hundido el
1
Estoy tratando de hacer una aplicación que muestre el contenido de SMS al usuario incluso si la aplicación ha sido eliminada
Anjani Mittal
11
Ya hay muchas respuestas disponibles, pero creo que a todas ellas les falta una parte importante de esta pregunta. Antes de leer los datos de una base de datos interna o su tabla, debemos comprender cómo se almacenan los datos en ella y luego podemos encontrar la solución de la pregunta anterior que es:
¿Cómo puedo leer mensajes SMS desde el dispositivo mediante programación en Android?
Entonces, en la tabla de SMS de Android es como se ve así
Sabe, podemos seleccionar lo que queramos de la base de datos. En nuestro caso solo hemos requerido
identificación, dirección y cuerpo
En caso de leer SMS:
1. Pida permisos
int REQUEST_PHONE_CALL =1;if(ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.READ_SMS)!=PackageManager.PERMISSION_GRANTED){ActivityCompat.requestPermissions(MainActivity.this,newString[]{Manifest.permission.READ_SMS}, REQUEST_PHONE_CALL);}
Proporciona una experiencia de usuario totalmente automatizada, sin requerir que el usuario escriba manualmente códigos de verificación y sin requerir ningún permiso adicional de la aplicación y debe usarse cuando sea posible. Sin embargo, requiere que coloque un código hash personalizado en el cuerpo del mensaje, por lo que también debe tener control sobre el lado del servidor .
Requisitos de mensajes : código hash de 11 dígitos que identifica de forma exclusiva su aplicación
No requiere el código hash personalizado, sin embargo, requiere que el usuario apruebe la solicitud de su aplicación para acceder al mensaje que contiene el código de verificación. Para minimizar las posibilidades de que el usuario muestre un mensaje incorrecto, SMS User Consentfiltrará los mensajes de los remitentes en la lista de Contactos del usuario.
Requisitos de mensaje : código alfanumérico de 4 a 10 dígitos que contiene al menos un número
Requisitos del remitente : el remitente no puede estar en la lista de contactos del usuario
Interacción del usuario : un toque para aprobar
The SMS User Consent APIforma parte de los servicios de Google Play. Para usarlo, necesitará al menos la versión 17.0.0de estas bibliotecas:
El consentimiento del usuario de SMS escuchará los mensajes SMS entrantes que contengan un código único durante un máximo de cinco minutos. No verá ningún mensaje que se envíe antes de que comience. Si conoce el número de teléfono que enviará el código de una sola vez, puede especificar el senderPhoneNumber, o si no null, coincidirá con cualquier número.
smsRetriever.startSmsUserConsent(senderPhoneNumber /* or null */)
Paso 2: Solicite consentimiento para leer un mensaje
Una vez que su aplicación recibe un mensaje que contiene un código único, se le notificará por una transmisión. En este punto, no tiene consentimiento para leer el mensaje; en su lugar, se le otorga un Intentmensaje que puede comenzar a solicitar al usuario para obtener su consentimiento. Dentro de su BroadcastReceiver, muestra el mensaje utilizando Intentel extras. Cuando comience esa intención, solicitará al usuario permiso para leer un solo mensaje. Se les mostrará el texto completo que compartirán con su aplicación.
val consentIntent = extras.getParcelable<Intent>(SmsRetriever.EXTRA_CONSENT_INTENT)
startActivityForResult(consentIntent, SMS_CONSENT_REQUEST)
Paso 3: Analice el código único y complete la verificación por SMS
Cuando el usuario hace clic “Allow”, ¡es hora de leer el mensaje! Dentro de onActivityResultusted puede obtener el texto completo del mensaje SMS de los datos:
val message = data.getStringExtra(SmsRetriever.EXTRA_SMS_MESSAGE)
¡Luego analiza el mensaje SMS y pasa el código único a tu backend!
4-10 digit alphanumeric code containing at least one number¿Puedes explicar qué significa eso? ¿Significa que la longitud del mensaje completo debe ser de 4 a 10 caracteres solo del código sms?
Zeeshan Shabbir
Gracias también
Levon Petrosyan
Esto funciona solo para la verificación OTP ¿verdad? ¿Qué pasa con la lectura de todos los demás mensajes dentro del teléfono, todos los SMS, etc.? ¿Hay alguna nueva API para eso? Avísame. ¡Feliz codificación! :)
Manoj Perumarath
Siempre tenemos el error de tiempo de espera. Por favor, ayúdame
package utils.broadcastreceivers
import android.content.BroadcastReceiverimport android.content.Contextimport android.content.Intentimport android.telephony.SmsMessageimport android.util.LogclassMySMSBroadCastReceiver:BroadcastReceiver(){override fun onReceive(context:Context?, intent:Intent?){var body =""
val bundle = intent?.extras
val pdusArr = bundle!!.get("pdus")asArray<Any>var messages:Array<SmsMessage?>= arrayOfNulls(pdusArr.size)// if SMSis Long and contain more than 1 Message we'll read all of themfor(i in pdusArr.indices){
messages[i]=SmsMessage.createFromPdu(pdusArr[i]asByteArray)}varMobileNumber:String?= messages[0]?.originatingAddress
Log.i(TAG,"MobileNumber =$MobileNumber")
val bodyText =StringBuilder()for(i in messages.indices){
bodyText.append(messages[i]?.messageBody)}
body = bodyText.toString()if(body.isNotEmpty()){// Do something, save SMS in DB or variable , static object or .... Log.i("Inside Receiver :","body =$body")}}}
3-Obtenga permiso de SMS si Android 6 y superior:
if(Build.VERSION.SDK_INT >=Build.VERSION_CODES.M &&ActivityCompat.checkSelfPermission(context!!,Manifest.permission.RECEIVE_SMS
)!=PackageManager.PERMISSION_GRANTED
){// Needs permission
requestPermissions(arrayOf(Manifest.permission.RECEIVE_SMS),
PERMISSIONS_REQUEST_READ_SMS
)}else{// Permission has already been granted}
4- Agregue este código de solicitud a la Actividad o fragmento:
companion object{const val PERMISSIONS_REQUEST_READ_SMS =100}
5- Anulación de verificación de permisos Solicitar resultado divertido:
override fun onRequestPermissionsResult(
requestCode:Int, permissions:Array<outString>,
grantResults:IntArray){when(requestCode){
PERMISSIONS_REQUEST_READ_SMS ->{if(grantResults[0]==PackageManager.PERMISSION_GRANTED){Log.i("BroadCastReceiver","PERMISSIONS_REQUEST_READ_SMS Granted")}else{// toast("Permission must be granted ")}}}}
Para leer el sms escribí una función que devuelve un objeto de conversación:
classConversation(val number:String, val message:List<Message>)classMessage(val number:String, val body:String, val date:Date)
fun getSmsConversation(context:Context, number:String?=null, completion:(conversations:List<Conversation>?)->Unit){
val cursor = context.contentResolver.query(Telephony.Sms.CONTENT_URI,null,null,null,null)
val numbers =ArrayList<String>()
val messages =ArrayList<Message>()var results =ArrayList<Conversation>()while(cursor !=null&& cursor.moveToNext()){
val smsDate = cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Sms.DATE))
val number = cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Sms.ADDRESS))
val body = cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Sms.BODY))
numbers.add(number)
messages.add(Message(number, body,Date(smsDate.toLong())))}
cursor?.close()
numbers.forEach { number ->if(results.find { it.number == number }==null){
val msg = messages.filter { it.number == number }
results.add(Conversation(number = number, message = msg))}}if(number !=null){
results = results.filter { it.number == number }asArrayList<Conversation>}
completion(results)}
Respuestas:
Use Content Resolver ( "content: // sms / inbox" ) para leer los SMS que están en la bandeja de entrada.
Por favor agregue READ_SMS permiso.
Espero que ayude :)
fuente
moveToFirst
como yo lo hice.Establecer aplicación como aplicación de SMS predeterminada
Función para recibir SMS
La clase de SMS está abajo:
No olvides definir el permiso en tu AndroidManifest.xml
fuente
String receiveDayTime = Functions.dateFromMilisec(Long.valueOf(c.getColumnIndexOrThrow("date")), "hh:mm a MMM dd, yyyy");
new SimpleDateFormat("hh:mm", Locale.US).format(new Date(Long.parseLong(_time)));
Esto te dará 24 horas de tiempo.mActivity
no está definido. ¿Que es esto?Es un proceso trivial. Puedes ver un buen ejemplo en el código fuente SMSPopup
Examine los siguientes métodos:
Este es el método de lectura:
fuente
Desde API 19 en adelante, puede hacer uso de la Clase de telefonía para eso; Dado que los valores codificados no recuperarán mensajes en todos los dispositivos porque el proveedor de contenido Uri cambia de dispositivos y fabricantes.
fuente
Esta publicación es un poco antigua, pero aquí hay otra solución fácil para obtener datos relacionados con
SMS
proveedor de contenido en Android:Use esta biblioteca: https://github.com/EverythingMe/easy-content-providers
Obtén todo
SMS
:Cada SMS tiene todos los campos, por lo que puede obtener cualquier información que necesite:
dirección, cuerpo, fecha de recepción, tipo (INBOX, SENT, DRAFT, ..), threadId, ...
Gel todo
MMS
:Gel todo
Thread
:Gel todo
Conversation
:Funciona con
List
oCursor
y hay una aplicación de muestra para ver cómo se ve y funciona.De hecho, hay un soporte para todos los proveedores de contenido de Android como: Contactos, Registros de llamadas, Calendario, ... Documento completo con todas las opciones: https://github.com/EverythingMe/easy-content-providers/wiki/Android- proveedores
Espero que también haya ayudado :)
fuente
Paso 1: primero tenemos que agregar permisos en el archivo de manifiesto como
Paso 2: luego agregue la clase de receptor de sms de servicio para recibir sms
Paso 3: Agregar permiso de tiempo de ejecución
Paso 4: Agregue estas clases en su aplicación y pruebe la clase de interfaz
SmsReceiver.java
fuente
Ya hay muchas respuestas disponibles, pero creo que a todas ellas les falta una parte importante de esta pregunta. Antes de leer los datos de una base de datos interna o su tabla, debemos comprender cómo se almacenan los datos en ella y luego podemos encontrar la solución de la pregunta anterior que es:
¿Cómo puedo leer mensajes SMS desde el dispositivo mediante programación en Android?
Entonces, en la tabla de SMS de Android es como se ve así
Sabe, podemos seleccionar lo que queramos de la base de datos. En nuestro caso solo hemos requerido
En caso de leer SMS:
1. Pida permisos
o
2. Ahora su código va así
Espero que este sea útil. Gracias.
fuente
Los servicios de Google Play tienen dos API que puede usar para optimizar el proceso de verificación basado en SMS
API de recuperación de SMS
Proporciona una experiencia de usuario totalmente automatizada, sin requerir que el usuario escriba manualmente códigos de verificación y sin requerir ningún permiso adicional de la aplicación y debe usarse cuando sea posible. Sin embargo, requiere que coloque un código hash personalizado en el cuerpo del mensaje, por lo que también debe tener control sobre el lado del servidor .
Solicitar verificación de SMS en una aplicación de Android
Realizar verificación de SMS en un servidor
API de consentimiento de usuario de SMS
No requiere el código hash personalizado, sin embargo, requiere que el usuario apruebe la solicitud de su aplicación para acceder al mensaje que contiene el código de verificación. Para minimizar las posibilidades de que el usuario muestre un mensaje incorrecto,
SMS User Consent
filtrará los mensajes de los remitentes en la lista de Contactos del usuario.The SMS User Consent API
forma parte de los servicios de Google Play. Para usarlo, necesitará al menos la versión17.0.0
de estas bibliotecas:Paso 1: Comience a escuchar mensajes SMS
El consentimiento del usuario de SMS escuchará los mensajes SMS entrantes que contengan un código único durante un máximo de cinco minutos. No verá ningún mensaje que se envíe antes de que comience. Si conoce el número de teléfono que enviará el código de una sola vez, puede especificar el
senderPhoneNumber
, o si nonull
, coincidirá con cualquier número.Paso 2: Solicite consentimiento para leer un mensaje
Una vez que su aplicación recibe un mensaje que contiene un código único, se le notificará por una transmisión. En este punto, no tiene consentimiento para leer el mensaje; en su lugar, se le otorga un
Intent
mensaje que puede comenzar a solicitar al usuario para obtener su consentimiento. Dentro de suBroadcastReceiver
, muestra el mensaje utilizandoIntent
elextras
. Cuando comience esa intención, solicitará al usuario permiso para leer un solo mensaje. Se les mostrará el texto completo que compartirán con su aplicación.Paso 3: Analice el código único y complete la verificación por SMS
Cuando el usuario hace clic
“Allow”
, ¡es hora de leer el mensaje! Dentro deonActivityResult
usted puede obtener el texto completo del mensaje SMS de los datos:¡Luego analiza el mensaje SMS y pasa el código único a tu backend!
fuente
4-10 digit alphanumeric code containing at least one number
¿Puedes explicar qué significa eso? ¿Significa que la longitud del mensaje completo debe ser de 4 a 10 caracteres solo del código sms?cambiado por:
fuente
Código de Kotlin para leer SMS:
1- Agregue este permiso a AndroidManifest.xml:
2-Crear una clase de receptor BroadCast:
3-Obtenga permiso de SMS si Android 6 y superior:
4- Agregue este código de solicitud a la Actividad o fragmento:
5- Anulación de verificación de permisos Solicitar resultado divertido:
fuente
La función más fácil
Para leer el sms escribí una función que devuelve un objeto de conversación:
Utilizando:
O obtenga solo una conversación de un número específico:
fuente