@DavidFreitas este link não está funcionando, você pode compartilhar o último link?
Khobaib
3
@ Khobaib, como sempre, as coisas na internet são passageiras. Encontrei uma cópia no archive.org stackoverflow.com/a/19966227/40961 , graças a Deus por eles (doei recentemente para mantê-los funcionando). Mas devemos considerar a conversão do conteúdo da página de web.archive.org/web/20121022021217/http://mobdev.olin.edu/… para sintaxe de remarcação em uma resposta a esta pergunta. Provavelmente uma hora de trabalho.
David d C e Freitas
Respostas:
157
Use o resolvedor de conteúdo ( "content: // sms / inbox" ) para ler o SMS que está na caixa 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}
Obrigado! Você digitou incorretamente "getColumnName"; além disso, ele funciona como um encanto. Ah, e se alguém usar isso, não se esqueça de adicionar a permissão android.permission.READ_SMS.
QWERTY
1
Obrigado. Eu modifiquei :) #
Suryavel TR
5
Isso também usa a API não documentada que @CommonsWare especificou em seu comentário para a resposta aceita?
precisa saber é o seguinte
1
Atenção! Não perca moveToFirstcomo eu.
Alexandr Priymak
4
@Krishnabhadra Yes. Ele usa o provedor de conteúdo "document: // sms / inbox" não documentado.
Esse é um bom pedaço de código. Apenas uma coisa, o tempo é obtido em milissegundos. Eu acho que será melhor torná-lo um formato legível por humanos comoString receiveDayTime = Functions.dateFromMilisec(Long.valueOf(c.getColumnIndexOrThrow("date")), "hh:mm a MMM dd, yyyy");
Bibaswann Bandyopadhyay
1
qual é o propósito de fazer tudo com getter e setter, eu realmente não entendo por que não usar um array assoc ou classe cujos elementos são acessados diretamente
michnovka
1
@TomasNavara: verifique este código para entender o uso de getter e setter. pastebin.com/Nh8YXtyJ
erros acontecem
@BibaswannBandyopadhyay Se você não quiser usar nada, exceto as bibliotecas Android e as bibliotecas Java. new SimpleDateFormat("hh:mm", Locale.US).format(new Date(Long.parseLong(_time)));Isso lhe dará tempo de 24 horas.
Chris - Jr
mActivitynão está definido. O que é isso?
dthree
61
É um processo trivial. Você pode ver um bom exemplo no código-fonte SMSPopup
Isso não faz parte do SDK do Android. Esse código pressupõe incorretamente que todos os dispositivos suportem esse provedor de conteúdo não documentado e não suportado. Google indicou explicitamente que depender de esta não é uma boa idéia: android-developers.blogspot.com/2010/05/...
CommonsWare
1
@ Janusz: Não há meios documentados e suportados que funcionem em todos os clientes SMS em todos os dispositivos.
CommonsWare
9
@CommonsWare que é triste de ouvir. Pode ter que viver com essa API então.
Janusz
@Omer Alguma idéia de como você contaria o número de mensagens SMS por contato?
SpicyWeenie
4
O código foi movido. Pesquisando SmsPopupUtils.java me deu um novo link para ele no código do google. No caso de eles se movem-lo novamente ou interrompê-la completamente, aqui está um link de backup - pastebin.com/iPt7MLyM
kalel
25
A partir da API 19, você pode fazer uso da classe de telefonia para isso; Como os valores marcados não recuperam mensagens em todos os dispositivos, porque o provedor de conteúdo Uri muda de dispositivos e 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 a única resposta que não usa API não documentada e não se refere a bibliotecas de terceiros.
Ishamael 19/01/19
Tentei usar esse código para receber mensagens SMS do Hangouts (que é meu aplicativo de SMS padrão). Em vez disso, ele recuperou a última mensagem que enviei via Messenger ... Você sabe o que está causando isso?
Miki P
@MikiP usando meus poderes de adivinhação, direi que o Messenger App pediu para você substituir o gerenciamento de SMS pelo Messenger. Isso acontece com outro aplicativo de mensagens. Não tenho outra explicação.
M3nda 17/08
2
Não esqueça de chamar c.close ();
Cícero Moura
1
@SardarAgabejli Se usarmos valores rígidos como "contenturi: sms", não será o mesmo para todos os dispositivos, mas se usarmos a classe Telephony, obteremos acesso direto a essa interface do usuário ou ao caminho do sms db desse dispositivo. uma classe auxiliar para apontar para o db de sms
Manoj Perumarath
23
Esta postagem é um pouco antiga, mas aqui está outra solução fácil para obter dados relacionados ao SMSprovedor de conteúdo no Android:
Cada SMS tem todos os campos, para que você possa obter qualquer informação que você precise: endereço, corpo, dataData, tipo (INBOX, SENT, DRAFT, ..), threadId, ...
Bem ... é esse ("com.aquadeals.seller.services.SmsReceiver") o nome do serviço comum?
M3nda
Ya que não é o nome do serviço, que é SmsReceiver caminho de classe em meu aplicativo
Venkatesh
Por que precisa de permissão para LOCATION?
Zam Sunk
1
Eu estou tentando fazer um aplicativo que aparece o conteúdo sms para o usuário mesmo se o aplicativo foi morto
Anjani Mittal
11
Já existem muitas respostas disponíveis, mas acho que todas elas estão faltando uma parte importante desta pergunta. Antes de ler os dados de um banco de dados interno ou de sua tabela, precisamos entender como os dados são armazenados nele e, em seguida, podemos encontrar a solução da pergunta acima:
Como posso ler mensagens SMS do dispositivo programaticamente no Android?
Então, na tabela SMS do Android, é assim:
Saiba, podemos selecionar o que quisermos do banco de dados. No nosso caso, apenas solicitamos
id, endereço e corpo
Em caso de leitura de SMS:
1. Peça permissões
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);}
Fornece uma experiência de usuário totalmente automatizada, sem exigir que o usuário digite manualmente códigos de verificação e sem exigir permissões extras de aplicativos e deve ser usado quando possível. No entanto, exige que você coloque um código de hash personalizado no corpo da mensagem, portanto, você também deve ter controle sobre o lado do servidor .
Requisitos de mensagem - código hash de 11 dígitos que identifica exclusivamente seu aplicativo
Não requer o código hash personalizado, mas exige que o usuário aprove a solicitação do seu aplicativo para acessar a mensagem que contém o código de verificação. Para minimizar as chances de aparecer a mensagem errada para o usuário, SMS User Consentfiltrará as mensagens dos remetentes na lista de contatos do usuário.
Requisitos de mensagem - código alfanumérico de 4 a 10 dígitos contendo pelo menos um número
Requisitos do remetente - O remetente não pode estar na lista de contatos do usuário
Interação do usuário - um toque para aprovar
The SMS User Consent APIfaz parte do Google Play Services. Para usá-lo, você precisará de pelo menos a versão 17.0.0dessas bibliotecas:
O consentimento do usuário do SMS escutará as mensagens SMS recebidas que contenham um código único por até cinco minutos. Ele não examinará nenhuma mensagem enviada antes de ser iniciada. Se você souber o número de telefone que enviará o código único, poderá especificar o senderPhoneNumber, ou se não nullcorresponderá a nenhum número.
smsRetriever.startSmsUserConsent(senderPhoneNumber /* or null */)
Etapa 2: solicitar consentimento para ler uma mensagem
Depois que seu aplicativo receber uma mensagem contendo um código único, ele será notificado por uma transmissão. Neste ponto, você não tem consentimento para ler a mensagem. Em vez disso, você recebe um Intentaviso de que pode começar a solicitar o consentimento do usuário. Dentro do seu BroadcastReceiver, você mostra o prompt usando o Intentno extras. Quando você inicia essa intenção, ele solicita ao usuário permissão para ler uma única mensagem. Eles mostrarão o texto inteiro que compartilharão com seu aplicativo.
val consentIntent = extras.getParcelable<Intent>(SmsRetriever.EXTRA_CONSENT_INTENT)
startActivityForResult(consentIntent, SMS_CONSENT_REQUEST)
Etapa 3: analisar o código único e concluir a verificação por SMS
Quando o usuário clica “Allow”- é hora de realmente ler a mensagem! Dentro de onActivityResultvocê, você pode obter o texto completo da mensagem SMS a partir dos dados:
val message = data.getStringExtra(SmsRetriever.EXTRA_SMS_MESSAGE)
Você analisa a mensagem SMS e passa o código único para o seu back-end!
4-10 digit alphanumeric code containing at least one numberVocê pode explicar o que isso significa? Isso significa que o comprimento da mensagem inteira deve ser de 4 a 10 caracteres apenas do código sms?
Zeeshan Shabbir
Obrigado também
Levon Petrosyan
Isso funciona apenas para verificação OTP, certo? Que tal ler todas as outras mensagens dentro do telefone, todos os SMS, etc? Existe alguma nova API para isso? Entre em contato. Feliz codificação! :)
Manoj Perumarath
Sempre temos o erro de tempo limite. Por favor me ajude
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-Obtenha permissão de SMS se o Android 6 e 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- Adicione este código de solicitação à Atividade ou fragmento:
companion object{const val PERMISSIONS_REQUEST_READ_SMS =100}
5- Substituição da permissão de verificação 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 ler o sms, escrevi uma função que retorna um objeto de conversa:
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)}
Respostas:
Use o resolvedor de conteúdo ( "content: // sms / inbox" ) para ler o SMS que está na caixa de entrada.
Por favor, adicione a permissão READ_SMS .
Espero que ajude :)
fonte
moveToFirst
como eu.Definir aplicativo como aplicativo SMS padrão
Função para receber SMS
A classe Sms está abaixo:
Não se esqueça de definir a permissão no seu AndroidManifest.xml
fonte
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)));
Isso lhe dará tempo de 24 horas.mActivity
não está definido. O que é isso?É um processo trivial. Você pode ver um bom exemplo no código-fonte SMSPopup
Examine os seguintes métodos:
este é o método para leitura:
fonte
A partir da API 19, você pode fazer uso da classe de telefonia para isso; Como os valores marcados não recuperam mensagens em todos os dispositivos, porque o provedor de conteúdo Uri muda de dispositivos e fabricantes.
fonte
Esta postagem é um pouco antiga, mas aqui está outra solução fácil para obter dados relacionados ao
SMS
provedor de conteúdo no Android:Use esta lib: https://github.com/EverythingMe/easy-content-providers
Obter tudo
SMS
:Cada SMS tem todos os campos, para que você possa obter qualquer informação que você precise:
endereço, corpo, dataData, tipo (INBOX, SENT, DRAFT, ..), threadId, ...
Gel tudo
MMS
:Gel tudo
Thread
:Gel tudo
Conversation
:Ele funciona com
List
ouCursor
e existe um aplicativo de exemplo para ver como ele funciona e como funciona.De fato, há suporte para todos os provedores de conteúdo do Android, como: Contatos, Logs de chamadas, Calendário ... Documento completo com todas as opções: https://github.com/EverythingMe/easy-content-providers/wiki/Android- fornecedores
Espero que também tenha ajudado :)
fonte
Etapa 1: primeiro temos que adicionar permissões no arquivo de manifesto, como
Etapa 2: em seguida, adicione a classe de receptor de serviço sms para receber sms
Etapa 3: adicionar permissão de tempo de execução
Etapa 4: adicione essas classes ao seu aplicativo e teste a classe Interface
SmsReceiver.java
fonte
Já existem muitas respostas disponíveis, mas acho que todas elas estão faltando uma parte importante desta pergunta. Antes de ler os dados de um banco de dados interno ou de sua tabela, precisamos entender como os dados são armazenados nele e, em seguida, podemos encontrar a solução da pergunta acima:
Como posso ler mensagens SMS do dispositivo programaticamente no Android?
Então, na tabela SMS do Android, é assim:
Saiba, podemos selecionar o que quisermos do banco de dados. No nosso caso, apenas solicitamos
Em caso de leitura de SMS:
1. Peça permissões
ou
2.Agora, seu código fica assim
Espero que este seja útil. Obrigado.
fonte
Os serviços do Google Play têm duas APIs que você pode usar para otimizar o processo de verificação por SMS
API do SMS Retriever
Fornece uma experiência de usuário totalmente automatizada, sem exigir que o usuário digite manualmente códigos de verificação e sem exigir permissões extras de aplicativos e deve ser usado quando possível. No entanto, exige que você coloque um código de hash personalizado no corpo da mensagem, portanto, você também deve ter controle sobre o lado do servidor .
Solicitar verificação de SMS em um aplicativo Android
Executar verificação de SMS em um servidor
API de consentimento do usuário do SMS
Não requer o código hash personalizado, mas exige que o usuário aprove a solicitação do seu aplicativo para acessar a mensagem que contém o código de verificação. Para minimizar as chances de aparecer a mensagem errada para o usuário,
SMS User Consent
filtrará as mensagens dos remetentes na lista de contatos do usuário.The SMS User Consent API
faz parte do Google Play Services. Para usá-lo, você precisará de pelo menos a versão17.0.0
dessas bibliotecas:Etapa 1: comece a ouvir as mensagens SMS
O consentimento do usuário do SMS escutará as mensagens SMS recebidas que contenham um código único por até cinco minutos. Ele não examinará nenhuma mensagem enviada antes de ser iniciada. Se você souber o número de telefone que enviará o código único, poderá especificar o
senderPhoneNumber
, ou se nãonull
corresponderá a nenhum número.Etapa 2: solicitar consentimento para ler uma mensagem
Depois que seu aplicativo receber uma mensagem contendo um código único, ele será notificado por uma transmissão. Neste ponto, você não tem consentimento para ler a mensagem. Em vez disso, você recebe um
Intent
aviso de que pode começar a solicitar o consentimento do usuário. Dentro do seuBroadcastReceiver
, você mostra o prompt usando oIntent
noextras
. Quando você inicia essa intenção, ele solicita ao usuário permissão para ler uma única mensagem. Eles mostrarão o texto inteiro que compartilharão com seu aplicativo.Etapa 3: analisar o código único e concluir a verificação por SMS
Quando o usuário clica
“Allow”
- é hora de realmente ler a mensagem! Dentro deonActivityResult
você, você pode obter o texto completo da mensagem SMS a partir dos dados:Você analisa a mensagem SMS e passa o código único para o seu back-end!
fonte
4-10 digit alphanumeric code containing at least one number
Você pode explicar o que isso significa? Isso significa que o comprimento da mensagem inteira deve ser de 4 a 10 caracteres apenas do código sms?Alterado por:
fonte
Código Kotlin para ler SMS:
1- Adicione esta permissão ao AndroidManifest.xml:
2-Crie uma classe BroadCastreceiver:
3-Obtenha permissão de SMS se o Android 6 e superior:
4- Adicione este código de solicitação à Atividade ou fragmento:
5- Substituição da permissão de verificação Solicitar resultado divertido:
fonte
A função mais fácil
Para ler o sms, escrevi uma função que retorna um objeto de conversa:
Usando:
Ou obtenha apenas uma conversa de número específico:
fonte