Come posso leggere i messaggi SMS dal dispositivo a livello di codice su Android?


249

Voglio recuperare i messaggi SMS dal dispositivo e visualizzarli?


@David Freitas Link affidabile +1
Shahzad Imam

3
@DavidFreitas questo link non funziona, puoi condividere il link più recente?
Khobaib,

3
@ Khobaib, come al solito le cose su Internet sono fugaci. Ho trovato una copia su archive.org stackoverflow.com/a/19966227/40961 , meno male per loro (ho fatto una donazione di recente per farli funzionare). Ma dovremmo considerare di convertire il contenuto della pagina da web.archive.org/web/20121022021217/http://mobdev.olin.edu/… in markdown sintassi in una risposta a questa domanda. Probabilmente un'ora di lavoro.
David d C e Freitas,

Risposte:


157

Utilizzare Content Resolver ( "content: // sms / inbox" ) per leggere gli SMS che si trovano nella posta in arrivo.

// 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 exception
    do {
       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
}

Aggiungi l' autorizzazione READ_SMS .

Spero possa essere d'aiuto :)


7
Grazie! Hai sbagliato a scrivere "getColumnName", a parte questo funziona come un incantesimo. Oh, e se qualcuno lo utilizzerà, non dimenticare di aggiungere l'autorizzazione android.permission.READ_SMS.
Qwerty,

1
Grazie. L'ho modificato :)
Suryavel TR

5
Questo utilizza anche l'API non documentata che @CommonsWare ha specificato nel suo commento alla risposta accettata?
Krishnabhadra il

1
Attenzione! Non perdere moveToFirstcome ho fatto io.
Alexandr Priymak,

4
@Krishnabhadra Sì. Utilizza il provider di contenuti "content: // sms / inbox" non documentato.
pm_labs

79
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        final String myPackageName = getPackageName();
        if (!Telephony.Sms.getDefaultSmsPackage(this).equals(myPackageName)) {

            Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
            intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, myPackageName);
            startActivityForResult(intent, 1);
        }else {
            List<Sms> lst = getAllSms();
        }
    }else {
        List<Sms> lst = getAllSms();
    }

Imposta l'app come app SMS predefinita

    @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
    if (resultCode == RESULT_OK) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            final String myPackageName = getPackageName();
            if (Telephony.Sms.getDefaultSmsPackage(mActivity).equals(myPackageName)) {

                List<Sms> lst = getAllSms();
            }
        }
    }
}
}

Funzione per ricevere SMS

public List<Sms> getAllSms() {
    List<Sms> lstSms = new ArrayList<Sms>();
    Sms objSms = new Sms();
    Uri message = Uri.parse("content://sms/");
    ContentResolver cr = mActivity.getContentResolver();

    Cursor c = cr.query(message, null, null, null, null);
    mActivity.startManagingCursor(c);
    int totalSMS = c.getCount();

    if (c.moveToFirst()) {
        for (int i = 0; i < totalSMS; i++) {

            objSms = new Sms();
            objSms.setId(c.getString(c.getColumnIndexOrThrow("_id")));
            objSms.setAddress(c.getString(c
                    .getColumnIndexOrThrow("address")));
            objSms.setMsg(c.getString(c.getColumnIndexOrThrow("body")));
            objSms.setReadState(c.getString(c.getColumnIndex("read")));
            objSms.setTime(c.getString(c.getColumnIndexOrThrow("date")));
            if (c.getString(c.getColumnIndexOrThrow("type")).contains("1")) {
                objSms.setFolderName("inbox");
            } else {
                objSms.setFolderName("sent");
            }

            lstSms.add(objSms);
            c.moveToNext();
        }
    }
    // else {
    // throw new RuntimeException("You have no SMS");
    // }
    c.close();

    return lstSms;
}

La classe SMS è al di sotto:

public class Sms{
private String _id;
private String _address;
private String _msg;
private String _readState; //"0" for have not read sms and "1" for have read sms
private String _time;
private String _folderName;

public String getId(){
return _id;
}
public String getAddress(){
return _address;
}
public String getMsg(){
return _msg;
}
public String getReadState(){
return _readState;
}
public String getTime(){
return _time;
}
public String getFolderName(){
return _folderName;
}


public void setId(String id){
_id = id;
}
public void setAddress(String address){
_address = address;
}
public void setMsg(String msg){
_msg = msg;
}
public void setReadState(String readState){
_readState = readState;
}
public void setTime(String time){
_time = time;
}
public void setFolderName(String folderName){
_folderName = folderName;
}

}

Non dimenticare di definire l'autorizzazione nel tuo AndroidManifest.xml

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

2
È un bel pezzo di codice. Solo una cosa, il tempo è ottenuto in millisecondi. Penso che sarà meglio renderlo un formato leggibile dall'uomo comeString receiveDayTime = Functions.dateFromMilisec(Long.valueOf(c.getColumnIndexOrThrow("date")), "hh:mm a MMM dd, yyyy");
Bibaswann Bandyopadhyay,

1
qual è lo scopo di fare tutto con getter e setter, davvero non capisco perché non usare semplicemente un array assoc o una classe i cui elementi sono accessibili direttamente
michnovka,

1
@TomasNavara: controlla questo codice per comprendere l'uso di getter e setter. pastebin.com/Nh8YXtyJ
Bugs Happen

@BibaswannBandyopadhyay Se non vuoi usare nulla tranne le librerie Android e le librerie Java. new SimpleDateFormat("hh:mm", Locale.US).format(new Date(Long.parseLong(_time)));Questo ti darà 24 ore di tempo.
Chris - Jr

mActivitynon è definito. Cos'è questo?
tre

61

È un processo banale. Puoi vedere un buon esempio nel codice sorgente SMSPopup

Esamina i seguenti metodi:

SmsMmsMessage getSmsDetails(Context context, long ignoreThreadId, boolean unreadOnly)
long findMessageId(Context context, long threadId, long _timestamp, int messageType
void setMessageRead(Context context, long messageId, int messageType)
void deleteMessage(Context context, long messageId, long threadId, int messageType)

questo è il metodo per leggere:

SmsMmsMessage getSmsDetails(Context context,
                            long ignoreThreadId, boolean unreadOnly)
{
   String SMS_READ_COLUMN = "read";
   String WHERE_CONDITION = unreadOnly ? SMS_READ_COLUMN + " = 0" : null;
   String SORT_ORDER = "date DESC";
   int count = 0;
   // Log.v(WHERE_CONDITION);
   if (ignoreThreadId > 0) {
      // Log.v("Ignoring sms threadId = " + ignoreThreadId);
      WHERE_CONDITION += " AND thread_id != " + ignoreThreadId;
   }
   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();
            // String[] columns = cursor.getColumnNames();
            // for (int i=0; i<columns.length; i++) {
            // Log.v("columns " + i + ": " + columns[i] + ": " + cursor.getString(i));
            // }                                         
            long messageId = cursor.getLong(0);
            long threadId = cursor.getLong(1);
            String address = cursor.getString(2);
            long contactId = cursor.getLong(3);
            String contactId_string = String.valueOf(contactId);
            long timestamp = cursor.getLong(4);

            String body = cursor.getString(5);                             
            if (!unreadOnly) {
                count = 0;
            }

            SmsMmsMessage smsMessage = new SmsMmsMessage(context, address,
                          contactId_string, body, timestamp,
                          threadId, count, messageId, SmsMmsMessage.MESSAGE_TYPE_SMS);
            return smsMessage;
         }
      } finally {
         cursor.close();
      }
   }               
   return null;
}

47
Questo non fa parte dell'SDK di Android. Questo codice presuppone erroneamente che tutti i dispositivi supportino questo provider di contenuti non documentato e non supportato. Google ha esplicitamente indicato che fare affidamento su questo non è una buona idea: android-developers.blogspot.com/2010/05/…
CommonsWare

1
@Janusz: non esiste alcun mezzo documentato e supportato che funzioni su tutti i client SMS su tutti i dispositivi.
CommonsWare il

9
@CommonsWare che è triste da ascoltare. Quindi potrebbe essere necessario convivere con questa API.
Janusz,

@Omer Qualche idea su come contare il numero di messaggi SMS per contatto?
SpicyWeenie,

4
Il codice è stato spostato. La ricerca di SmsPopupUtils.java mi ha procurato un nuovo link ad esso nel codice di Google. Nel caso in cui lo spostino di nuovo o lo interrompano completamente, ecco un link di backup - pastebin.com/iPt7MLyM
KalEl,

25

Dall'API 19 in poi puoi utilizzare la Classe di telefonia per questo; Poiché i valori hardcored non recuperano i messaggi in tutti i dispositivi perché il provider di contenuti Uri cambia da dispositivi e produttori.

public void 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= new Date(Long.valueOf(smsDate));
                String type;
                switch (Integer.parseInt(c.getString(c.getColumnIndexOrThrow(Telephony.Sms.TYPE)))) {
                    case Telephony.Sms.MESSAGE_TYPE_INBOX:
                        type = "inbox";
                        break;
                    case Telephony.Sms.MESSAGE_TYPE_SENT:
                        type = "sent";
                        break;
                    case Telephony.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();
    }
}

9
Sembra essere l'unica risposta che non utilizza API non documentate e non fa riferimento a librerie di terze parti.
Ishamael,

Ho provato a utilizzare questo codice per ricevere messaggi SMS da Hangouts (che è la mia app SMS predefinita). Invece, ha recuperato l'ultimo messaggio in uscita che ho inviato tramite Messenger ... Sai cosa sta causando questo?
Miki P

@MikiP, usando i miei poteri di indovinare, dirò che l'app Messenger ti ha chiesto di sostituire la gestione degli SMS con Messenger. Succede con qualche altra app di messaggistica. Non ho altra spiegazione.
m3nda,

2
Non dimenticare di chiamare c.close ();
Cícero Moura,

1
@SardarAgabejli Se utilizziamo valori hardcored come "contenturi: sms" non sarà lo stesso per tutti i dispositivi, ma se utilizziamo la classe di telefonia, stiamo ottenendo l'accesso diretto a quel conetnt uri o al percorso degli sms db di quel dispositivo, è una classe di supporto per indicare il db di sms
Manoj Perumarath il

23

Questo post è un po 'vecchio, ma ecco un'altra semplice soluzione per ottenere dati relativi al SMSprovider di contenuti in Android:

Usa questa lib: https://github.com/EverythingMe/easy-content-providers

  • Ottieni tutto SMS:

    TelephonyProvider telephonyProvider = new TelephonyProvider(context);
    List<Sms> smses = telephonyProvider.getSms(Filter.ALL).getList();

    Ogni SMS ha tutti i campi, quindi puoi ottenere tutte le informazioni di cui hai bisogno:
    indirizzo, corpo, ricevutoData, tipo (INBOX, SENT, DRAFT, ..), threadId, ...

  • Gel tutto MMS:

    List<Mms> mmses = telephonyProvider.getMms(Filter.ALL).getList();
  • Gel tutto Thread:

    List<Thread> threads = telephonyProvider.getThreads().getList();
  • Gel tutto Conversation:

    List<Conversation> conversations = telephonyProvider.getConversations().getList();

Funziona con Listo Cursore c'è un'app di esempio per vedere come appare e funziona.

In realtà, esiste un supporto per tutti i fornitori di contenuti Android come: Contatti, Registro chiamate, Calendario, ... Documento completo con tutte le opzioni: https://github.com/EverythingMe/easy-content-providers/wiki/Android- fornitori

Spero che abbia aiutato anche :)


1
Il codice sorgente e gli esempi su github sono abbastanza utili. Questo è un buon wrapper / facciata per i provider più comuni. Grazie.
m3nda,

14

Passaggio 1: prima dobbiamo aggiungere le autorizzazioni nel file manifest come

<uses-permission android:name="android.permission.RECEIVE_SMS" android:protectionLevel="signature" />
<uses-permission android:name="android.permission.READ_SMS" />

Passaggio 2: quindi aggiungere la classe ricevente sms di servizio per ricevere sms

<receiver android:name="com.aquadeals.seller.services.SmsReceiver">
    <intent-filter>
        <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
    </intent-filter>
</receiver>

Passaggio 3: aggiungere l'autorizzazione di runtime

private boolean checkAndRequestPermissions()
{
    int sms = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS);

    if (sms != PackageManager.PERMISSION_GRANTED)
    {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_SMS}, REQUEST_ID_MULTIPLE_PERMISSIONS);
        return false;
    }
    return true;
}

Passaggio 4: aggiungi queste classi nella tua app e testa la classe Interface

public interface SmsListener {
   public void messageReceived(String messageText);
}

SmsReceiver.java

public class SmsReceiver extends BroadcastReceiver {
private static SmsListener mListener;
public Pattern p = Pattern.compile("(|^)\\d{6}");
@Override
public void onReceive(Context context, Intent intent) {
    Bundle data  = intent.getExtras();
    Object[] pdus = (Object[]) data.get("pdus");
    for(int i=0;i<pdus.length;i++)
    {
        SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdus[i]);
        String sender = smsMessage.getDisplayOriginatingAddress();
        String phoneNumber = smsMessage.getDisplayOriginatingAddress();
        String senderNum = phoneNumber ;
        String messageBody = smsMessage.getMessageBody();
        try
        {
  if(messageBody!=null){
   Matcher m = p.matcher(messageBody);
    if(m.find()) {
      mListener.messageReceived(m.group(0));  }
 else {}}  }
        catch(Exception e){} } }
public static void bindListener(SmsListener listener) {
    mListener = listener; }}

Cosa fa lo schema?
Mark Buikema,

Bene ... è quello ("com.aquadeals.seller.services.SmsReceiver") il nome del servizio comune?
m3nda,

Ya che non è il nome del servizio, che è il percorso di classe SmsReceiver nella mia app
Venkatesh,

Perché è necessaria l'autorizzazione per LOCATION?
Zam Sunk,

1
sto cercando di creare un'app che visualizzi all'utente il contenuto degli sms anche se l'app è stata uccisa
Anjani Mittal,

11

Ci sono molte risposte già disponibili ma penso che a tutte loro manchi una parte importante di questa domanda. Prima di leggere i dati da un database interno o dalla sua tabella, dobbiamo capire come sono archiviati i dati in esso e quindi possiamo trovare la soluzione della domanda precedente che è:

Come posso leggere i messaggi SMS dal dispositivo a livello di codice su Android?

Quindi, in Android la tabella SMS è simile a questa

inserisci qui la descrizione dell'immagine

Sappi, possiamo selezionare ciò che vogliamo dal database. Nel nostro caso abbiamo solo richiesto

ID, indirizzo e corpo

In caso di lettura di SMS:

1. Chiedere autorizzazioni

int REQUEST_PHONE_CALL = 1;

   if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_SMS}, REQUEST_PHONE_CALL);
        }

o

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

2.Ora il tuo codice va così

// Create Inbox box URI
Uri inboxURI = Uri.parse("content://sms/inbox");

// List required columns
String[] reqCols = new String[]{"_id", "address", "body"};

// Get Content Resolver object, which will deal with Content Provider
ContentResolver cr = getContentResolver();

// Fetch Inbox SMS Message from Built-in Content Provider
Cursor c = cr.query(inboxURI, reqCols, null, null, null);

// Attached Cursor with adapter and display in listview
adapter = new SimpleCursorAdapter(this, R.layout.a1_row, c,
        new String[]{"body", "address"}, new int[]{
        R.id.A1_txt_Msg, R.id.A1_txt_Number});
lst.setAdapter(adapter);

Spero che questo possa essere utile. Grazie.


7

I servizi di Google Play hanno due API che puoi utilizzare per semplificare il processo di verifica basato su SMS

API di SMS Retriever

Fornisce un'esperienza utente completamente automatizzata, senza richiedere all'utente di digitare manualmente i codici di verifica e senza richiedere ulteriori autorizzazioni per le app e deve essere utilizzata quando possibile. Tuttavia, richiede di inserire un codice hash personalizzato nel corpo del messaggio, quindi è necessario avere anche il controllo sul lato server .

  • Requisiti del messaggio : codice hash di 11 cifre che identifica in modo univoco l'app
  • Requisiti del mittente : nessuno
  • Interazione dell'utente - Nessuna

Richiedi la verifica SMS in un'app Android

Esegui la verifica SMS su un server

API di consenso dell'utente SMS

Non richiede il codice hash personalizzato, tuttavia richiede all'utente di approvare la richiesta della tua app per accedere al messaggio contenente il codice di verifica. Al fine di ridurre al minimo le possibilità di diffondere all'utente un messaggio errato, SMS User Consentfiltrerà i messaggi dai mittenti nell'elenco Contatti dell'utente.

  • Requisiti del messaggio : codice alfanumerico di 4-10 cifre contenente almeno un numero
  • Requisiti del mittente : il mittente non può essere nell'elenco Contatti dell'utente
  • Interazione dell'utente : un tocco per approvare

The SMS User Consent APIfa parte di Google Play Services. Per usarlo avrai bisogno almeno della versione 17.0.0di queste librerie:

implementation "com.google.android.gms:play-services-auth:17.0.0"
implementation "com.google.android.gms:play-services-auth-api-phone:17.1.0"

Passaggio 1: iniziare ad ascoltare i messaggi SMS

Il consenso dell'utente SMS ascolterà i messaggi SMS in arrivo che contengono un codice unico per un massimo di cinque minuti. Non esaminerà alcun messaggio inviato prima che venga avviato. Se si conosce il numero di telefono che invierà il codice una tantum, è possibile specificare il senderPhoneNumber, o in caso contrario non nullcorrisponderà a nessun numero.

 smsRetriever.startSmsUserConsent(senderPhoneNumber /* or null */)

Passaggio 2: richiedere il consenso per leggere un messaggio

Una volta che la tua app riceve un messaggio contenente un codice una tantum, verrà notificata da una trasmissione. A questo punto, non hai il consenso a leggere il messaggio, ma ti viene dato Intentil permesso di iniziare a chiedere all'utente il consenso. All'interno del tuo BroadcastReceiver, mostri il prompt usando Intentin extras. Quando si avvia tale intento, verrà chiesto all'utente l'autorizzazione a leggere un singolo messaggio. Verrà mostrato l'intero testo che condivideranno con la tua app.

val consentIntent = extras.getParcelable<Intent>(SmsRetriever.EXTRA_CONSENT_INTENT)
startActivityForResult(consentIntent, SMS_CONSENT_REQUEST)

inserisci qui la descrizione dell'immagine

Passaggio 3: analizzare il codice unico e completare la verifica SMS

Quando l'utente fa clic “Allow”, è ora di leggere effettivamente il messaggio! All'interno di onActivityResultte puoi ottenere il testo completo del messaggio SMS dai dati:

val message = data.getStringExtra(SmsRetriever.EXTRA_SMS_MESSAGE)

Quindi analizzi il messaggio SMS e passi il codice unico al tuo backend!


4-10 digit alphanumeric code containing at least one numberPuoi spiegare cosa significa? Significa che la lunghezza dell'intero messaggio dovrebbe essere di 4-10 caratteri del solo codice sms?
Zeeshan Shabbir,

Grazie così
Levon Petrosyan

Questo funziona solo per la verifica OTP giusto? Che ne dici di leggere tutti gli altri messaggi all'interno del telefono, tutti gli SMS ecc.? C'è qualche nuova API per questo, per favore fatemi sapere. Buona programmazione! :)
Manoj Perumarath,

Abbiamo sempre avuto l'errore di timeout. Ti prego, aiutami
Manikandan K,

2
String WHERE_CONDITION = unreadOnly ? SMS_READ_COLUMN + " = 0" : null;

modificato da:

String WHERE_CONDITION = unreadOnly ? SMS_READ_COLUMN + " = 0 " : SMS_READ_COLUMN + " = 1 ";

2

Codice Kotlin per leggere SMS:

1- Aggiungi questa autorizzazione ad AndroidManifest.xml:

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

2-Creare una classe BroadCastreceiver:

package utils.broadcastreceivers

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.telephony.SmsMessage
import android.util.Log

class MySMSBroadCastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
    var body = ""
    val bundle = intent?.extras
    val pdusArr = bundle!!.get("pdus") as Array<Any>
    var messages: Array<SmsMessage?>  = arrayOfNulls(pdusArr.size)

 // if SMSis Long and contain more than 1 Message we'll read all of them
    for (i in pdusArr.indices) {
        messages[i] = SmsMessage.createFromPdu(pdusArr[i] as ByteArray)
    }
      var MobileNumber: 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")
        }
    }
 }

Autorizzazione SMS 3-Get se Android 6 e versioni successive:

   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- Aggiungi questo codice di richiesta ad Attività o frammento:

 companion object {
    const val PERMISSIONS_REQUEST_READ_SMS = 100
   }

5- Sostituisci Verifica permessi Richiedi risultato divertente:

 override fun onRequestPermissionsResult(
    requestCode: Int, permissions: Array<out String>,
    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  ")
            }
        }
    }
}

1

La funzione più semplice

Per leggere gli sms ho scritto una funzione che restituisce un oggetto Conversation:

class Conversation(val number: String, val message: List<Message>)
class Message(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 } as ArrayList<Conversation>
        }

        completion(results)
    }

usando:

getSmsConversation(this){ conversations ->
    conversations.forEach { conversation ->
        println("Number: ${conversation.number}")
        println("Message One: ${conversation.message[0].body}")
        println("Message Two: ${conversation.message[1].body}")
    }
}

O ottieni solo la conversazione di un numero specifico:

getSmsConversation(this, "+33666494128"){ conversations ->
    conversations.forEach { conversation ->
        println("Number: ${conversation.number}")
        println("Message One: ${conversation.message[0].body}")
        println("Message Two: ${conversation.message[1].body}")
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.