Android'de cihazdan SMS mesajlarını programlı olarak nasıl okuyabilirim?


249

SMS mesajlarını cihazdan alıp görüntülemek istiyorum?


@David Freitas Güvenilir bağlantı +1
Shahzad Imam

3
@DavidFreitas bu bağlantı çalışmıyor, lütfen en son bağlantıyı paylaşabilir misiniz?
Khobaib

3
@Khobaib, her zamanki gibi internetteki şeyler geçicidir. Archive.org stackoverflow.com/a/19966227/40961 adresinde bir kopya buldum , onlar için şükürler olsun. Ancak, sayfanın içeriğini web.archive.org/web/20121022021217/http://mobdev.olin.edu/… ' dan bu soruya verilen bir yanıtta işaretleme sözdizimine dönüştürmeyi düşünmeliyiz . Muhtemelen bir saatlik bir çalışma.
David d C e Freitas

Yanıtlar:


157

Gelen kutusundaki SMS'leri okumak için İçerik Çözümleyici'yi ( "içerik: // sms / gelen kutusu" ) kullanın.

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

Lütfen READ_SMS ekleyin izni .

Umut ediyorum bu yardım eder :)


7
Teşekkür ederim! "GetColumnName" ifadesini yanlış yazdınız, bunun dışında bir cazibe gibi çalışır. Oh, ve eğer birisi bunu kullanacaksa, android.permission.READ_SMS iznini eklemeyi unutmayın.
qwerty

1
Teşekkürler. Ben değiştirdim :)
Suryavel TR

5
Bu, @CommonsWare'in kabul edilen cevaba yaptığı yorumunda belirtildiği belgelenmemiş api'yi de kullanıyor mu?
Krishnabhadra

1
Dikkat! moveToFirstBenim yaptığım gibi kaçırmayın .
Alexandr Priymak

4
@ Krishnabhadra Evet. Belgelenmemiş "content: // sms / inbox" içerik sağlayıcısını kullanır.
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();
    }

Uygulamayı varsayılan SMS uygulaması olarak ayarla

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

SMS alma fonksiyonu

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

Sms sınıfı aşağıdadır:

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

}

AndroidManifest.xml dosyasında izin tanımlamayı unutmayın

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

2
Güzel bir kod parçası. Sadece bir şey, zaman milisaniye olarak elde edilir. Bence insan tarafından okunabilir bir format yapmak daha iyi olacakString receiveDayTime = Functions.dateFromMilisec(Long.valueOf(c.getColumnIndexOrThrow("date")), "hh:mm a MMM dd, yyyy");
Bibaswann Bandyopadhyay 13:15

1
getter ve setter ile her şeyi yapmanın amacı nedir, gerçekten neden elemanlarına doğrudan erişilen bir assoc dizisi veya sınıfı
kullanmıyorsunuz

1
@TomasNavara: Alıcı ve ayarlayıcı kullanımını anlamak için bu kodu kontrol edin. pastebin.com/Nh8YXtyJ
Bugs

@BibaswannBandyopadhyay Eğer android kütüphaneleri ve java kütüphaneleri dışında bir şey kullanmak istemiyorsanız. new SimpleDateFormat("hh:mm", Locale.US).format(new Date(Long.parseLong(_time)));Bu size 24 saat zaman verecektir.
Chris - Jr

mActivityTanımlanmadı. Bu nedir?
dthree

61

Bu önemsiz bir süreç. SMSPopup kaynak kodunda iyi bir örnek görebilirsiniz

Aşağıdaki yöntemleri inceleyin:

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)

bu okuma yöntemi:

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
Bu Android SDK'sının bir parçası değildir. Bu kod, tüm cihazların bu belgesiz ve desteklenmeyen içerik sağlayıcısını desteklediğini yanlış varsayıyor. Google, buna güvenmenin iyi bir fikir olmadığını açıkça belirtti: android-developers.blogspot.com/2010/05/…
CommonsWare

1
@Janusz: Tüm cihazlardaki tüm SMS istemcilerinde çalışan belgelenmiş ve desteklenen bir araç yoktur.
CommonsWare

9
@CommonsWare duymak üzücü. O zaman bu API ile yaşamak zorunda kalabilirsiniz.
Janusz

@Omer Kişi başına SMS mesajı sayısını nasıl sayacağınıza dair bir fikriniz var mı?
SpicyWeenie

4
Kod taşındı. SmsPopupUtils.java araması bana Google kodunda yeni bir bağlantı getirdi. Tekrar hareket ettirmeleri veya tamamen
kesmeleri

25

API 19'dan itibaren bunun için Telefon Sınıfı'nı kullanabilirsiniz; İçerik sağlayıcı Uri, cihazlardan ve üreticilerden değiştiği için sabit değerler her cihazda mesaj alamayacağından.

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
Belgelenmemiş API kullanmayan ve üçüncü taraf kitaplıklarına atıfta bulunmayan tek yanıt gibi görünüyor.
İshamael

Hangouts'tan SMS iletileri almak için bu kodu kullanmaya çalıştım (varsayılan SMS uygulamam). Bunun yerine, Messenger aracılığıyla gönderdiğim son giden mesajı aldı ... Buna neyin sebep olduğunu biliyor musunuz?
Miki P

@MikiP tahmin güçlerimi kullanarak Messenger App'in SMS yönetimini Messenger ile değiştirmek istediğini söyleyeceğim. Başka bir mesajlaşma uygulaması ile olur. Başka bir açıklamam yok.
m3nda

2
C.close () işlevini çağırmayı unutmayın;
Cícero Moura

1
@SardarAgabejli "contenturi: sms" gibi sabit çekirdekli değerler kullanırsak, bu her cihaz için aynı olmaz, ancak Telefon sınıfını kullanırsak, o conet uri'ye veya o cihazın sms db yoluna doğrudan erişiriz, sms db işaret bir yardımcı sınıf
Manoj Perumarath

23

Bu gönderi biraz eski, ama burada ilgili verileri almak için başka bir kolay çözüm SMS Android'de içerik sağlayıcıyla :

Bu lib'i kullanın: https://github.com/EverythingMe/easy-content-providers

  • Tümünü al SMS:

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

    Her Sms tüm alanlara sahiptir, böylece ihtiyacınız olan herhangi bir bilgiyi alabilirsiniz:
    adres, gövde, alınan Tarih, tür (INBOX, SENT, DRAFT, ..), threadId, ...

  • Tüm jel MMS:

    List<Mms> mmses = telephonyProvider.getMms(Filter.ALL).getList();
  • Tüm jel Thread:

    List<Thread> threads = telephonyProvider.getThreads().getList();
  • Tüm jel Conversation:

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

ListVeya ile çalışırCursor ve nasıl göründüğünü ve çalıştığını görmek için örnek bir uygulama vardır.

Aslında, tüm Android içerik sağlayıcıları için bir destek var: Kişiler, Çağrı günlükleri, Takvim, ... Tüm seçeneklere sahip tam doküman: https://github.com/EverythingMe/easy-content-providers/wiki/Android- sağlayıcılar

Umarım da yardımcı oldu :)


1
Github üzerindeki kaynak kodu ve örnekler oldukça faydalıdır. Bu, en yaygın sağlayıcılar için iyi bir sarıcı / cephedir. Teşekkür ederim.
m3nda

14

Adım 1: İlk olarak, manifest dosyasına aşağıdaki gibi izinler eklemeliyiz

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

Adım 2: Daha sonra SMS almak için servis sms alıcı sınıfı ekleyin

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

3. Adım: Çalışma zamanı izni ekleyin

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

4. Adım: Bu sınıfları uygulamanıza ekleyin ve Interface sınıfını test edin

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

Desen ne yapar?
Mark Buikema

Peki ... ("com.aquadeals.seller.services.SmsReceiver") ortak hizmet adı mı?
m3nda

Ya hizmet adı değil, bu benim app SmsReceiver sınıf yolu
Venkatesh

LOCATION için neden izne ihtiyacınız var?
Zam Sunk

1
Ben app öldürülmüş olsa bile kullanıcıya sms içeriği açılır bir uygulama yapmaya çalışıyorum
Anjani Mittal

11

Zaten çok sayıda cevap var ama hepsinin bu sorunun önemli bir bölümünü eksik olduğunu düşünüyorum. Dahili bir veritabanından veya tablosundan veri okumadan önce verilerin nasıl saklandığını anlamalıyız ve daha sonra yukarıdaki sorunun çözümünü bulabiliriz:

Android'de cihazdan SMS mesajlarını programlı olarak nasıl okuyabilirim?

Yani, Android SMS tablosunda şöyle görünmek

resim açıklamasını buraya girin

Veritabanından istediğimizi seçebiliriz, bizim durumumuzda sadece

kimlik, adres ve gövde

SMS okunması durumunda:

1. izin isteyin

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

veya

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

2.Şimdi kodunuz böyle gider

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

Umarım bu yardımcı olur. Teşekkürler.


7

Google Play hizmetlerinde SMS tabanlı doğrulama işlemini kolaylaştırmak için kullanabileceğiniz iki API vardır

SMS Retriever API'sı

Kullanıcının doğrulama kodlarını manuel olarak yazmasını gerektirmeden ve fazladan uygulama izni gerektirmeden tam otomatik bir kullanıcı deneyimi sağlar ve mümkün olduğunda kullanılmalıdır. Bununla birlikte, ileti gövdesine özel bir karma kodu yerleştirmenizi gerektirir, bu nedenle sunucu tarafında da kontrol sahibi olmanız gerekir .

  • Mesaj gereksinimleri - Uygulamanızı benzersiz şekilde tanımlayan 11 haneli karma kod
  • Gönderen gereksinimleri - Yok
  • Kullanıcı etkileşimi - Yok

Android Uygulamasında SMS Doğrulama İsteğinde Bulunma

Sunucuda SMS Doğrulama Gerçekleştirme

SMS Kullanıcı Onayı API'sı

Özel karma kodu gerektirmez, ancak kullanıcının doğrulama kodunu içeren mesaja erişim isteğini onaylamasını gerektirir. Kullanıcıya yanlış iletinin ortaya SMS User Consentçıkma olasılığını en aza indirgemek için kullanıcının Kişiler listesindeki gönderenlerden gelen iletileri filtreleyecektir.

  • Mesaj gereksinimleri - En az bir sayı içeren 4-10 haneli alfasayısal kod
  • Gönderen gereksinimleri - Gönderen, kullanıcının Kişiler listesinde olamaz
  • Kullanıcı etkileşimi - Onaylamak için bir kez hafifçe vurun

The SMS User Consent APIGoogle Play Hizmetlerinin bir parçasıdır. Kullanmak için 17.0.0şu kitaplıkların en az sürümüne ihtiyacınız olacak :

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

1. Adım: SMS mesajlarını dinlemeye başlayın

SMS Kullanıcı Onayı, beş dakikaya kadar bir kerelik kod içeren gelen SMS mesajlarını dinleyecektir. Başlamadan önce gönderilen iletilere bakmaz. Bir kerelik kodu gönderecek telefon numarasını biliyorsanız senderPhoneNumber, veya nullherhangi bir numarayla eşleşmeyecek şekilde belirtebilirsiniz .

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

2. Adım: Bir mesajı okumak için onay isteyin

Uygulamanız bir kerelik kod içeren bir ileti aldığında, bir yayın tarafından bildirilir. Bu noktada, mesajı okuma izniniz yoktur - bunun yerine Intentkullanıcıdan onay almanızı isteyebileceğiniz bir mesaj verilir . İçerideki BroadcastReceiver, kullandığınız istemi göstermek Intentde extras. Bu amacı başlattığınızda, kullanıcıdan tek bir mesajı okuma izni ister. Uygulamanızla paylaşacakları metnin tamamı gösterilir.

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

resim açıklamasını buraya girin

Adım 3: Bir defalık kodu ayrıştırın ve SMS Doğrulamasını tamamlayın

Kullanıcı tıkladığında “Allow”- mesajı gerçekten okuma zamanı! İçinizde onActivityResultSMS Mesajının tam metnini verilerden alabilirsiniz:

val message = data.getStringExtra(SmsRetriever.EXTRA_SMS_MESSAGE)

Daha sonra SMS mesajını ayrıştırır ve bir kerelik kodu arka ucunuza geçirirsiniz!


4-10 digit alphanumeric code containing at least one numberBunun ne anlama geldiğini açıklayabilir misiniz? Tüm mesajın uzunluğunun sadece sms kodunun 4-10 karakteri olması gerektiği anlamına mı geliyor?
Zeeshan Shabbir

Teşekkür ederim
Levon Petrosyan

Bu sadece OTP doğrulaması için geçerli değil mi? Telefondaki diğer tüm mesajları, tüm SMS'leri vb. Okumaya ne dersiniz? Bunun için yeni bir API var mı, lütfen bana bildirin. Mutlu kodlama! :)
Manoj Perumarath

Her zaman zaman aşımı hatası aldık. Lütfen bana yardım et
Manikandan K

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

tarafından değiştirildi:

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

2

SMS okumak için Kotlin Kodu:

1- Bu izni AndroidManifest.xml dosyasına ekleyin:

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

2-BroadCastreceiver Sınıfı Yaratın:

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")
        }
    }
 }

3-Android 6 ve üzeri sürümlerde SMS İzni Alın:

   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- Bu istek kodunu Aktivite veya parçaya ekleyin:

 companion object {
    const val PERMISSIONS_REQUEST_READ_SMS = 100
   }

5- Geçersiz kılma İzni kontrol et Sonuç eğlencesi iste:

 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

En kolay fonksiyon

Sms okumak için bir Konuşma nesnesi döndüren bir işlev yazdım:

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

Kullanımı:

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

Veya yalnızca belirli bir numarada sohbet edin:

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}")
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.