I want to retrieve the SMS messages from the device and display them?
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 :)
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 :)
String WHERE_CONDITION = unreadOnly ? SMS_READ_COLUMN + " = 0" : null;
changed by:
String WHERE_CONDITION = unreadOnly ? SMS_READ_COLUMN + " = 0 " : SMS_READ_COLUMN + " = 1 ";
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;
}
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.
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.
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.
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!