Làm cách nào tôi có thể đọc tin nhắn SMS từ thiết bị lập trình trong Android?


249

Tôi muốn lấy tin nhắn SMS từ thiết bị và hiển thị chúng?


@David Freitas Liên kết đáng tin cậy +1
Shahzad Imam

3
@DavidFreitas liên kết này không hoạt động, bạn có thể chia sẻ liên kết tốt nhất không?
Khobaib

3
@Khobaib, như thường lệ, những thứ trên internet là thoáng qua. Tôi đã tìm thấy một bản sao trên archive.org stackoverflow.com/a/19966227/40961 , cảm ơn chúa vì chúng (tôi đã quyên góp gần đây để giữ cho chúng chạy). Nhưng chúng ta nên xem xét chuyển đổi nội dung của trang từ web.archive.org/web/20121022021217/http://mobdev.olin.edu/ Lỗi để đánh dấu cú pháp trong câu trả lời cho câu hỏi này. Có lẽ là một giờ làm việc.
David d C e Freitas

Câu trả lời:


157

Sử dụng Trình giải quyết nội dung ( "nội dung: // sms / hộp thư đến" ) để đọc SMS trong hộp thư đế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
}

Vui lòng thêm READ_SMS quyền .

Tôi hy vọng nó sẽ giúp :)


7
Cảm ơn bạn! Bạn viết sai chính tả "getColumnName", ngoài ra nó hoạt động như một lá bùa. Ồ, và nếu có ai sẽ sử dụng điều này, đừng quên thêm quyền cho phép.READ_SMS.
qwerty

1
Cảm ơn. Tôi đã sửa đổi nó :)
Suryavel TR

5
Điều này cũng sử dụng api không có giấy tờ mà @CommonsWare đã chỉ định trong nhận xét của mình cho câu trả lời được chấp nhận?
Krishnabhadra

1
Chú ý! Đừng bỏ lỡ moveToFirstnhư tôi đã làm.
Alexandr Priymak

4
@Krishnabhadra Vâng. Nó sử dụng nhà cung cấp nội dung "nội dung: // sms / hộp thư đến" không có giấy tờ.
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();
    }

Đặt ứng dụng làm ứng dụng SMS mặc định

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

Chức năng nhận 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;
}

Lớp Sms bên dưới:

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

}

Đừng quên xác định quyền trong AndroidManifest.xml của bạn

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

2
Đó là một đoạn mã hay. Chỉ cần một điều, thời gian thu được tính bằng mili giây. Tôi nghĩ sẽ tốt hơn nếu biến nó thành định dạng dễ đọc của con người nhưString receiveDayTime = Functions.dateFromMilisec(Long.valueOf(c.getColumnIndexOrThrow("date")), "hh:mm a MMM dd, yyyy");
Bibaswann Bandyopadhyay

1
Mục đích của việc tạo ra mọi thứ với getter và setter là gì, tôi thực sự không hiểu tại sao không sử dụng một mảng PGS hoặc lớp có các phần tử được truy cập trực tiếp
michnovka

1
@TomasNavara: Kiểm tra mã này để hiểu cách sử dụng getter và setter. pastebin.com/Nh8YXtyJ
Lỗi xảy ra vào

@BibaswannBandyopadhyay Nếu bạn không muốn sử dụng bất cứ thứ gì ngoại trừ thư viện android & thư viện java. new SimpleDateFormat("hh:mm", Locale.US).format(new Date(Long.parseLong(_time)));Điều này sẽ cung cấp cho bạn thời gian 24 giờ.
Chris - Jr

mActivitykhông được xác định. Cái này là cái gì?
dthree

61

Đó là một quá trình tầm thường. Bạn có thể thấy một ví dụ hay trong mã nguồn SMSPopup

Kiểm tra các phương pháp sau:

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)

đây là phương pháp để đọc:

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
Đây không phải là một phần của SDK Android. Mã này đưa ra giả định không chính xác rằng tất cả các thiết bị hỗ trợ nhà cung cấp nội dung không có giấy tờ và không được hỗ trợ này. Google đã chỉ ra một cách rõ ràng rằng dựa vào điều này không phải là một ý tưởng tốt: android-developers.blogspot.com/2010/05/...
CommonsWare

1
@Janusz: Không có tài liệu và phương tiện được hỗ trợ nào hoạt động trên tất cả các máy khách SMS trên tất cả các thiết bị.
CommonsWare

9
@CommonsWare thật buồn khi nghe. Có thể phải sống với API này rồi.
Janusz

@Omer Bạn có biết bạn sẽ đếm số lượng tin nhắn SMS trên mỗi số liên lạc không?
SpicyWeenie

4
Mã đã được di chuyển. Tìm kiếm SmsPopupUtils.java đã cho tôi một liên kết mới đến nó trong mã google. Trong trường hợp họ di chuyển lại hoặc ngừng hoàn toàn, đây là một liên kết dự phòng - pastebin.com/iPt7MLyM
KalEl

25

Từ API 19 trở đi, bạn có thể sử dụng Lớp điện thoại cho điều đó; Vì các giá trị được bảo vệ sẽ không truy xuất thư trong mọi thiết bị vì nhà cung cấp nội dung Uri thay đổi từ thiết bị và nhà sản xuất.

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
Có vẻ là câu trả lời duy nhất không sử dụng API không có giấy tờ và không đề cập đến các thư viện của bên thứ ba.
Ishamael

Tôi đã thử sử dụng mã này để nhận tin nhắn SMS từ Hangouts (đây là ứng dụng SMS mặc định của tôi). Thay vào đó, nó đã lấy được tin nhắn gửi đi cuối cùng mà tôi đã gửi qua Messenger ... Bạn có biết điều gì gây ra điều này không?
Miki P

@MikiP sử dụng khả năng đoán của tôi, tôi sẽ nói rằng Ứng dụng Messenger đã hỏi bạn về việc thay thế quản lý SMS bằng Messenger. Nó xảy ra với một số ứng dụng nhắn tin khác. Tôi không có lời giải thích nào khác.
m3nda

2
Đừng quên gọi c.close ();
Cícero Moura

1
@SardarAgabj một lớp người trợ giúp để chỉ vào db của sms
Manoj Perumarath

23

Bài đăng này hơi cũ, nhưng đây là một giải pháp dễ dàng khác để lấy dữ liệu liên quan đến SMSnhà cung cấp nội dung trong Android:

Sử dụng lib này: https://github.com/EverythingMe/easy-content-providers

  • Nhận tất cả SMS:

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

    Mỗi Sms có tất cả các trường, vì vậy bạn có thể nhận được bất kỳ thông tin nào bạn cần:
    địa chỉ, cơ thể, receiveDate, loại (INBOX, SENT, DRAFT, ..), threadId, ...

  • Gel tất cả MMS:

    List<Mms> mmses = telephonyProvider.getMms(Filter.ALL).getList();
  • Gel tất cả Thread:

    List<Thread> threads = telephonyProvider.getThreads().getList();
  • Gel tất cả Conversation:

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

Nó hoạt động với Listhoặc Cursorvà có một ứng dụng mẫu để xem nó trông như thế nào và hoạt động.

Trên thực tế, có một hỗ trợ cho tất cả các nhà cung cấp nội dung Android như: Danh bạ, Nhật ký cuộc gọi, Lịch, ... Tài liệu đầy đủ với tất cả các tùy chọn: https://github.com/EverythingMe/easy-content-providers/wiki/Android- nhà cung cấp

Hy vọng nó cũng có ích :)


1
Mã nguồn và các ví dụ trên github khá hữu ích. Đây là một trình bao bọc / mặt tiền tốt cho hầu hết các nhà cung cấp phổ biến. Cảm ơn bạn.
m3nda

14

Bước 1: đầu tiên chúng ta phải thêm quyền trong tệp kê khai như

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

Bước 2: sau đó thêm lớp nhận dịch vụ sms để nhận sms

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

Bước 3: Thêm quyền thời gian chạy

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

Bước 4: Thêm lớp này trong ứng dụng của bạn và kiểm tra lớp Giao diện

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

Mô hình làm gì?
Đánh dấu Buikema

Chà ... đó có phải là ("com.aquadeals.seller.service.SmsReceiver") tên dịch vụ phổ biến không?
m3nda

Ya đó không phải là tên dịch vụ, đó là đường dẫn lớp SmsReceiver trong ứng dụng của tôi
Venkatesh

Tại sao cần sự cho phép cho VỊ TRÍ?
Zam Sunk

1
Tôi đang cố gắng tạo một ứng dụng bật lên nội dung sms cho người dùng ngay cả khi ứng dụng đã bị giết
Anigate Mittal

11

Có rất nhiều câu trả lời đã có sẵn nhưng tôi nghĩ tất cả chúng đều thiếu một phần quan trọng của câu hỏi này. Trước khi đọc dữ liệu từ cơ sở dữ liệu nội bộ hoặc bảng của nó, chúng ta phải hiểu cách lưu trữ dữ liệu trong đó và sau đó chúng ta có thể tìm ra giải pháp cho câu hỏi trên đó là:

Làm cách nào tôi có thể đọc tin nhắn SMS từ thiết bị lập trình trong Android?

Vì vậy, trong bảng SMS của android giống như thế này

nhập mô tả hình ảnh ở đây

Biết, chúng tôi có thể chọn bất cứ điều gì chúng tôi muốn từ cơ sở dữ liệu. Trong trường hợp của chúng tôi, chúng tôi chỉ yêu cầu

id, địa chỉ và cơ thể

Trong trường hợp đọc SMS:

1.Ask cho phép

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

hoặc là

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

2.Bây giờ mã của bạn đi như thế này

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

Tôi hy vọng điều này sẽ hữu ích. Cảm ơn.


7

Dịch vụ Google Play có hai API bạn có thể sử dụng để hợp lý hóa quy trình xác minh dựa trên SMS

API truy xuất SMS

Cung cấp trải nghiệm người dùng hoàn toàn tự động, không yêu cầu người dùng nhập mã xác minh theo cách thủ công và không yêu cầu bất kỳ quyền ứng dụng bổ sung nào và nên được sử dụng khi có thể. Tuy nhiên, nó yêu cầu bạn đặt mã băm tùy chỉnh trong phần thân thông báo, do đó bạn cũng phải có quyền kiểm soát phía máy chủ .

  • Yêu cầu về tin nhắn - Mã băm gồm 11 chữ số xác định duy nhất ứng dụng của bạn
  • Yêu cầu người gửi - Không có
  • Tương tác người dùng - Không có

Yêu cầu xác minh SMS trong ứng dụng Android

Thực hiện xác minh SMS trên máy chủ

API đồng ý người dùng SMS

Không yêu cầu mã băm tùy chỉnh, tuy nhiên yêu cầu người dùng phê duyệt yêu cầu của ứng dụng của bạn để truy cập thư chứa mã xác minh. Để giảm thiểu cơ hội phát thông báo sai cho người dùng, SMS User Consentsẽ lọc ra các tin nhắn từ người gửi trong danh sách Liên hệ của người dùng.

  • Yêu cầu tin nhắn - Mã chữ số 4-10 chữ số chứa ít nhất một số
  • Yêu cầu người gửi - Người gửi không thể có trong danh sách Liên hệ của người dùng
  • Tương tác người dùng - Một chạm để phê duyệt

The SMS User Consent APIlà một phần của Dịch vụ Google Play. Để sử dụng, bạn sẽ cần ít nhất phiên bản 17.0.0của các thư viện này:

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

Bước 1: Bắt đầu nghe tin nhắn SMS

Sự đồng ý của người dùng SMS sẽ lắng nghe các tin nhắn SMS đến có chứa mã một lần trong tối đa năm phút. Nó sẽ không nhìn vào bất kỳ tin nhắn nào được gửi trước khi nó bắt đầu. Nếu bạn biết số điện thoại sẽ gửi mã một lần, bạn có thể chỉ định senderPhoneNumberhoặc nếu bạn không nullkhớp với bất kỳ số nào.

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

Bước 2: Yêu cầu đồng ý đọc tin nhắn

Khi ứng dụng của bạn nhận được tin nhắn chứa mã một lần, nó sẽ được thông báo bằng một chương trình phát sóng. Tại thời điểm này, bạn không có sự đồng ý để đọc tin nhắn - thay vào đó bạn được cung cấp Intentrằng bạn có thể bắt đầu nhắc nhở người dùng đồng ý. Trong của bạn BroadcastReceiver, bạn hiển thị lời nhắc bằng cách sử dụng Intenttrong extras. Khi bạn bắt đầu ý định đó, nó sẽ nhắc người dùng cho phép đọc một tin nhắn. Họ sẽ được hiển thị toàn bộ văn bản mà họ sẽ chia sẻ với ứng dụng của bạn.

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

nhập mô tả hình ảnh ở đây

Bước 3: Phân tích mã một lần và hoàn tất Xác minh SMS

Khi người dùng nhấp “Allow”- đây là lúc để thực sự đọc tin nhắn! Bên trong onActivityResultbạn có thể nhận được toàn bộ tin nhắn SMS từ dữ liệu:

val message = data.getStringExtra(SmsRetriever.EXTRA_SMS_MESSAGE)

Sau đó, bạn phân tích tin nhắn SMS và chuyển mã một lần đến phần phụ trợ của bạn!


4-10 digit alphanumeric code containing at least one numberBạn có thể giải thích điều đó có nghĩa là gì? Có nghĩa là độ dài của toàn bộ tin nhắn phải là 4-10 ký tự của mã sms?
Zeeshan Shabbir

Cũng cảm ơn bạn
Levon Petrosyan

Điều này chỉ hoạt động để xác minh OTP phải không? Còn việc đọc tất cả các tin nhắn khác trong điện thoại, tất cả SMS thì sao? Có API mới nào không, xin vui lòng cho tôi biết. Chúc mừng mã hóa! :)
Manoj Perumarath

Chúng tôi đã luôn luôn có lỗi thời gian chờ. Xin hãy giúp tôi
Manikandan K

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

Thay đổi bởi:

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

2

Mã Kotlin để đọc SMS:

1- Thêm quyền này vào AndroidManifest.xml:

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

2-Tạo một lớp 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")
        }
    }
 }

3-Nhận quyền SMS nếu Android 6 trở lê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- Thêm mã yêu cầu này vào Hoạt động hoặc đoạn:

 companion object {
    const val PERMISSIONS_REQUEST_READ_SMS = 100
   }

5- Ghi đè Kiểm tra permisstion Yêu cầu kết quả thú vị:

 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

Chức năng dễ nhất

Để đọc sms tôi đã viết một hàm trả về một đối tượng Hội thoại:

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

Sử dụng:

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

Hoặc chỉ nhận được cuộc trò chuyện của số cụ thể:

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}")
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.