How can I read SMS messages from the device programmatically in Android?

后端 未结 11 2349
情深已故
情深已故 2020-11-22 02:48

I want to retrieve the SMS messages from the device and display them?

相关标签:
11条回答
  • 2020-11-22 02:55

    Use Content Resolver ("content://sms/inbox") to read SMS which are in inbox.

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

    Please add READ_SMS permission.

    I Hope it helps :)

    0 讨论(0)
  • 2020-11-22 03:04

    This post is a little bit old, but here is another easy solution for getting data related to SMS content provider in Android:

    Use this lib: https://github.com/EverythingMe/easy-content-providers

    • Get all SMS:

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

      Each Sms has all fields, so you can get any info you need:
      address, body, receivedDate, type(INBOX, SENT, DRAFT, ..), threadId, ...

    • Gel all MMS:

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

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

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

    It works with List or Cursor and there is a sample app to see how it looks and works.

    In fact, there is a support for all Android content providers like: Contacts, Call logs, Calendar, ... Full doc with all options: https://github.com/EverythingMe/easy-content-providers/wiki/Android-providers

    Hope it also helped :)

    0 讨论(0)
  • 2020-11-22 03:04
    String WHERE_CONDITION = unreadOnly ? SMS_READ_COLUMN + " = 0" : null;
    

    changed by:

    String WHERE_CONDITION = unreadOnly ? SMS_READ_COLUMN + " = 0 " : SMS_READ_COLUMN + " = 1 ";
    
    0 讨论(0)
  • 2020-11-22 03:06

    It is a trivial process. You can see a good example in the source code SMSPopup

    Examine the following methods:

    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)
    

    this is the method for reading:

    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;
    }
    
    0 讨论(0)
  • 2020-11-22 03:10

    There are lots of answers are already available but i think all of them are missing an important part of this question. Before reading data from an internal database or its table we have to understand how data is stored in it and then we can find the solution of the above question that is :

    How can I read SMS messages from the device programmatically in Android?

    So,In android SMS table is like look like this

    Know,we can select whatever we want from the database.In our case we have only required

    id,address and body

    In case of reading SMS:

    1.Ask for permissions

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

    or

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

    2.Now your code goes like this

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

    I hope this one will be helpful. Thanks.

    0 讨论(0)
  • 2020-11-22 03:11

    Google Play services has two APIs you can use to streamline the SMS-based verification process

    SMS Retriever API

    Provides a fully automated user experience, without requiring the user to manually type verification codes and without requiring any extra app permissions and should be used when possible. It does, however, require you to place a custom hash code in the message body, so you must have control over server side as well.

    • Message requirements - 11-digit hash code that uniquely identifies your app
    • Sender requirements - None
    • User interaction - None

    Request SMS Verification in an Android App

    Perform SMS Verification on a Server

    SMS User Consent API

    Does not require the custom hash code, however require the user to approve your app's request to access the message containing the verification code. In order to minimize the chances of surfacing the wrong message to the user, SMS User Consent will filter out messages from senders in the user's Contacts list.

    • Message requirements - 4-10 digit alphanumeric code containing at least one number
    • Sender requirements - Sender cannot be in the user's Contacts list
    • User interaction - One tap to approve

    The SMS User Consent API is part of Google Play Services. To use it you’ll need at least version 17.0.0 of these libraries:

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

    Step 1: Start listening for SMS messages

    SMS User Consent will listen for incoming SMS messages that contain a one-time-code for up to five minutes. It won’t look at any messages that are sent before it’s started. If you know the phone number that will send the one-time-code, you can specify the senderPhoneNumber, or if you don’t null will match any number.

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

    Step 2: Request consent to read a message

    Once your app receives a message containing a one-time-code, it’ll be notified by a broadcast. At this point, you don’t have consent to read the message — instead you’re given an Intent that you can start to prompt the user for consent. Inside your BroadcastReceiver, you show the prompt using the Intent in the extras. When you start that intent, it will prompt the user for permission to read a single message. They’ll be shown the entire text that they will share with your app.

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

    Step 3: Parse the one-time-code and complete SMS Verification

    When the user clicks “Allow” — it’s time to actually read the message! Inside of onActivityResult you can get the full text of the SMS Message from the data:

    val message = data.getStringExtra(SmsRetriever.EXTRA_SMS_MESSAGE)
    

    You then parse the SMS message and pass the one-time-code to your backend!

    0 讨论(0)
提交回复
热议问题