Android – Listen For Incoming SMS Messages
public class SmsListener extends BroadcastReceiver{
private SharedPreferences preferences;
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")){
Bundle bundle = intent.getExtras(); //---get the SMS message passed in---
SmsMessage[] msgs = null;
String msg_from;
if (bundle != null){
//---retrieve the SMS message received---
try{
Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsMessage[pdus.length];
for(int i=0; i<msgs.length; i++){
msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
msg_from = msgs[i].getOriginatingAddress();
String msgBody = msgs[i].getMessageBody();
}
}catch(Exception e){
// Log.d("Exception caught",e.getMessage());
}
}
}
}
}
Note: In your manifest file add the BroadcastReceiver-
<receiver android:name=".listener.SmsListener">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
Add this permission:
<uses-permission android:name="android.permission.RECEIVE_SMS" />
Detecting incoming SMS messages
The Android app needs SMS receive/read permission to retrieve SMS content.
Google has introduced SMS Retriever API, this API allows to retrieve the OTP without needing of the SMS permission in your application.
Add These Dependency for SMS Retriever API
implementation 'com.google.android.gms:play-services-base:16.0.1'
implementation 'com.google.android.gms:play-services-identity:16.0.0'
implementation 'com.google.android.gms:play-services-auth:16.0.1'
implementation 'com.google.android.gms:play-services-auth-api-phone:16.0.0'
Then craete an interface like below:
public interface OnNewMessageListener {
void onNewMessageReceived(String activationCode);
}
Then, create a broadCastReceiver to catch sms:
public class SmsBroadcastReceiver extends BroadcastReceiver {
OnNewMessageListener onNewMessageListener;
public SmsBroadcastReceiver() {
}
public SmsBroadcastReceiver(OnNewMessageListener onNewMessageListener) {
this.onNewMessageListener = onNewMessageListener;
}
@Override
public void onReceive(Context context, Intent intent) {
if (SmsRetriever.SMS_RETRIEVED_ACTION.equals(intent.getAction())) {
Bundle extras = intent.getExtras();
if (extras != null) {
Status status = (Status) extras.get(SmsRetriever.EXTRA_STATUS);
if (status != null)
switch (status.getStatusCode()) {
case CommonStatusCodes.SUCCESS:
// Get SMS message contents
String message = (String) extras.get(SmsRetriever.EXTRA_SMS_MESSAGE);
// Extract one-time code from the message and complete verification
// by sending the code back to your server.
if (!TextUtils.isEmpty(message)) {
String activationCode = null;
Pattern p = Pattern.compile("your pattern like \\b\\d{4}\\b");
Matcher m = p.matcher(message);
if (m.find()) {
activationCode = (m.group(0)); // The matched substring
}
if (onNewMessageListener != null && !TextUtils.isEmpty(activationCode))
onNewMessageListener.onNewMessageReceived(activationCode);
}
break;
case CommonStatusCodes.TIMEOUT:
// Waiting for SMS timed out (5 minutes)
// Handle the error ...
break;
}
}
}
}
}
At your AndroidManifest
declare broadcastReceiver:
<receiver
android:name=".SmsBroadcastReceiver"
android:exported="true"
tools:ignore="ExportedReceiver">
<intent-filter>
<action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED" />
</intent-filter>
</receiver>
Inside your activity add these code:
private SmsBroadcastReceiver smsListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Get an instance of SmsRetrieverClient, used to start listening for a matching
// SMS message.
SmsRetrieverClient client = SmsRetriever.getClient(Objects.requireNonNull(getContext()) /* context */);
// Starts SmsRetriever, which waits for ONE matching SMS message until timeout
// (5 minutes). The matching SMS message will be sent via a Broadcast Intent with
// action SmsRetriever#SMS_RETRIEVED_ACTION.
Task<Void> task = client.startSmsRetriever();
// Listen for success/failure of the start Task. If in a background thread, this
// can be made blocking using Tasks.await(task, [timeout]);
task.addOnSuccessListener(aVoid -> {
// Successfully started retriever, expect broadcast intent
// ...
});
task.addOnFailureListener(e -> {
// Failed to start retriever, inspect Exception for more details
// ...
});
OnNewMessageListener onNewMessageListener = activationCode -> {
if (!TextUtils.isEmpty(activationCode)) {
editText.setText(String.valueOf(activationCode));
}
};
smsListener = new SmsBroadcastReceiver(onNewMessageListener);
if (getContext() != null)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
getContext().registerReceiver(smsListener, new IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION));
}
}
@Override
public void onStop() {
super.onStop();
try {
if (getContext() != null && smsListener != null) {
getContext().unregisterReceiver(smsListener);
smsListener = null;
}
} catch (Exception ignored) {
}
}
Your sms should be like this:
<#> Use 123456 as your verification code
FC+7qAH5AZu
Message must:
- Be no longer than 140 bytes
- Begin with the prefix
<#>
- Contain a one-time code that the client sends back to your server to complete the verification flow (see Generating a one-time code)
- End with an 11-character hash string that identifies your app (see Computing your app’s hash string)
For more information see this link.
UPDATE
See this link.
EDIT
Change your activity to this:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
requestSmsPermission();
else {
smsListener = new SmsListener();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
registerReceiver(smsListener, intentFilter);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 1) {
smsListener= new SmsListener();
IntentFilter intentFilter=new IntentFilter();
intentFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
registerReceiver(smsListener, intentFilter);
}
}
Update
Change your BroadcastReceiver
to this:
public class SmsListener extends BroadcastReceiver {
private String msgBody;
private SharedPreferences preferences;
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
Toast.makeText(context, "message received", Toast.LENGTH_SHORT).show();
Bundle bundle = intent.getExtras();
try {
if (bundle != null) {
final Object[] pdus = (Object[]) bundle.get("pdus");
for (int i = 0; i < pdus.length; i++) {
SmsMessage smsMessage;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
smsMessage = SmsMessage.createFromPdu((byte[]) pdus[i], bundle.getString("format"));
else smsMessage = SmsMessage.createFromPdu((byte[]) pdus[i]);
msg_from = smsMessage.getDisplayOriginatingAddress();
msgBody = smsMessage.getMessageBody();
MainActivity.handleMessage(msgBody);
}
Toast.makeText(context, "message is:" + msgBody, Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
Log.d("Exception caught", e.getMessage());
}
}
}
}
Android - SMS Broadcast receiver
android.provider.Telephony.SMS_RECEIVED
has a capital T
, and yours in the manifest does not.
Please bear in mind that this Intent
action is not documented.
Listening to incoming texts, in the background
Yes broadcast receiver is best way for listening to incoming texts.if an incoming sms recvied use IntentService for your work what u want to do on sms recived.u can register a reciver for incoming sms as:
manifest file
<receiver class="SMSApp">
<intent-filter>
<action android:value="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.RECEIVE_SMS" />
Java File
public class SMSApp extends BroadcastReceiver{
private static final String LOG_TAG = "SMSApp";
/* package */
static final String ACTION = "android.provider.Telephony.SMS_RECEIVED";
public void onReceive(Context context, Intent intent){
if (intent.getAction().equals(ACTION)){
Bundle bundle = intent.getExtras();
if (bundle != null){
Object[] pdus = (Object[]) bundle.get("pdus");
SmsMessage[] messages = new SmsMessage[pdus.length];
for (int i = 0; i < pdus.length; i++){
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
}
for (SmsMessage message : messages){
String strFrom = message.getDisplayOriginatingAddress();
String strMsg = message.getDisplayMessageBody();
}
}
}
}
}
and second way you can register a ContentObserver for content://sms/inbox
for listening incoming sms in inbox
Listen to incoming multipart SMS message
Holy...!
After reading the Android source (this file), I realize that this is such a stupid question...
Here is my receiver:
@Override
public void onReceive(Context context, Intent intent) {
Log.d(ClassName, "received SMS");
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdus = (Object[]) bundle.get("pdus");
// here is what I need, just combine them all :-)
final SmsMessage[] messages = new SmsMessage[pdus.length];
Log.d(ClassName, String.format("message count = %s", messages.length));
for (int i = 0; i < pdus.length; i++) {
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
}
}
}// onReceive()
Oops... I was too lazy to look at my code. I already got all parts of the message at a time.
Related Topics
Passing a Bundle on Startactivity()
How to Add Dividers and Spaces Between Items in Recyclerview
Android: How to Get String from Resources Using Its Name
How to Use Recyclerview Inside Nestedscrollview
How to Use Drawerlayout to Display Over the Actionbar/Toolbar and Under the Status Bar
App Not Installed' Error on Android
Can the Android Drawable Directory Contain Subdirectories
Basic Communication Between Two Fragments
Filter Logcat to Get Only the Messages from My Application in Android
How to Use Inputfilter to Limit Characters in an Edittext in Android
Dexindexoverflowexception Only When Running Tests
What APIs Are Used to Draw Over Other Apps (Like Facebook'S Chat Heads)
Google-Services.Json For Different Productflavors
Android - Dynamically Add Views into View
How to Check Visibility of Software Keyboard in Android
How to Access My Localhost from My Android Device
How to Show Current Location on a Google Map on Android Marshmallow