How to display text on android when certain SMS message is received - java

I'm new to android development and java programming. i just wanted to know how to print or display certain text if this "certain" message is received.
I got this code on the web on how to receive and read SMS.
ReadIncomingSms.java
package readnewsms.adk;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;
public class IncomingSms extends BroadcastReceiver {
// Get the object of SmsManager
final SmsManager sms = SmsManager.getDefault();
public void onReceive(Context context, Intent intent) {
// Retrieves a map of extended data from the intent.
final Bundle bundle = intent.getExtras();
try {
if (bundle != null) {
final Object[] pdusObj = (Object[]) bundle.get("pdus");
for (int i = 0; i < pdusObj.length; i++) {
SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[i]);
String phoneNumber = currentMessage.getDisplayOriginatingAddress();
String senderNum = phoneNumber;
String message = currentMessage.getDisplayMessageBody();
Log.i("SmsReceiver", "senderNum: "+ senderNum + "; message: " + message);
// Show Alert
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context,
"senderNum: "+ senderNum + ", message: " + message, duration);
toast.show();
}
// end for loop
} // bundle is null
} catch (Exception e) {
Log.e("SmsReceiver", "Exception smsReceiver" +e);
}
}
}
then i added this code after toast.show(); still inside the loop
if (message.equals(("1"))){
System.out.println("user sends 1");
} else {
System.out.println("other");
}
what do i do to display those messages on the screen? or how do i evaluate the code if the message contains a certain value, then i will print a certain message depending on the message sent. for example if the INCOMING message contains 1, then the app will display user sends 1.

It looks like you want to put a Toast on the screen. This displays a little message at the bottom. The code would look like this:
if (message.equals(("1"))){
Toast toast = Toast.makeText(context, "User sent 1");
toast.show();
} else {
Toast toast = Toast.makeText(context, "Other);
toast.show();
}

Use:
if (message.contains("1")) {
//do something is message contains string '1' anywhere
Log.d("MYTAG", "user send 1");
}
or
if (message.equals("1")) {
//do something if the whole message equals to string '1'
Log.d("MYTAG", "user send 1");
}
Read here about String methods.
To update textView (assuming you have one defined in xml), find it with findViewById() and then use:
myTextView.setText("user send 1")
You can also display a message in logcat, so instead of using System.out.println(), use:
Log.d("MYTAG", "user send 1");
or whatever message you want. More on layouts here

Related

Automatically reply to Message recieved by Broadcastreciever

Good day everyone.
I would like to make an application which replies to received SMS automatically.
For example.
Jon Doe sends me - "Hi", Application gets the message body, checks it with my database where I have a potential response:
ID | Text | Potential Answer
01 | Hi | Hello how are you?
and Application sends the Potential response.
So far what I have achieved -
App receives the Message, checks it with the database ( using Like '%') and gets the correct "Potential Answer" Column and passes it as message text body, but to send it I am using a button.
My Reciever is a sperate file class
public class MyReceiver extends BroadcastReceiver {
public static String textSmsbody="";
private static final String TAG=MyReceiver.class.getSimpleName();
public static final String pdu_type="pdus";
#TargetApi(Build.VERSION_CODES.M)
#Override
public void onReceive(Context context, Intent intent) {
// Get the SMS message.
Bundle bundle = intent.getExtras();
SmsMessage[] msgs;
String strMessage = "";
String format = bundle.getString("format");
// Retrieve the SMS message received.
Object[] pdus = (Object[]) bundle.get(pdu_type);
if (pdus != null) {
// Check the Android version.
boolean isVersionM =
(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M);
// Fill the msgs array.
msgs = new SmsMessage[pdus.length];
for (int i = 0; i < msgs.length; i++) {
// Check Android version and use appropriate createFromPdu.
if (isVersionM) {
// If Android version M or newer:
msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i], format);
} else {
// If Android version L or older:
msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
}
// Build the message to show.
String a=msgs[i].getMessageBody();
textSmsbody=msgs[i].getMessageBody();
if (a.contains("?")) {
strMessage=msgs[i].getOriginatingAddress();
// strMessage += " :" + msgs[i].getMessageBody() + "\n";
}
else {
strMessage=a;
// strMessage += "SMS from" + msgs[i].getOriginatingAddress();
// strMessage += "ELSE:" + msgs[i].getMessageBody() + "\n";
}
// Log and display the SMS message.
Log.d(TAG, "onReceive: " + strMessage);
Toast.makeText(context, strMessage, Toast.LENGTH_LONG).show();
}
}
}
}
Sending method is in my MainActivity.
public void smsSendMessage(View view) {
databaseSearch();
// Set the destination phone number to the string in editText.
String destinationAddress = "2020";
// Find the sms_message view.
// Get the text of the SMS message.
String smsMessage = sendingText;
// Set the service center address if needed, otherwise null.
String scAddress = null;
// Set pending intents to broadcast
// when message sent and when delivered, or set to null.
PendingIntent sentIntent = null, deliveryIntent = null;
// Use SmsManager.
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage
(destinationAddress, scAddress, smsMessage,
sentIntent, deliveryIntent);
}
In layout I have a button which calls smsSendMessage () ;
My question is how I can make it automatically without button.
When the phone receives a message, the app shall check it with the database and send it by itself.
Please tell me if you need to see my Manifest file, or databasehelper.
Using JobService should be a suitable option in your case.
Create a JobService class like that
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class ExampleJobService extends JobService {
#Override
public boolean onStartJob(JobParameters params) {
//send a message
return true;
}
#Override
public boolean onStopJob(JobParameters params) {
return true;
}
}
Also Declare In your Manifest
<service
android:name=".ExampleJobService"
android:permission="android.permission.BIND_JOB_SERVICE" />
Now in your Receiver, you can start it like that
ComponentName componentName = new ComponentName(context, ExampleJobService.class);
PersistableBundle bundle = new PersistableBundle();
bundle.putLong("lat", lat);
bundle.putLong("lon", lon);
JobInfo jobInfo = new JobInfo.Builder(0, componentName)
.setExtras(bundle)
.build();
For more details about JobServices https://www.vogella.com/tutorials/AndroidTaskScheduling/article.html

How to Filter/Extract Code from SMS (Android)

So i'm working on a WhatsApp like verification system where user inputs the code received via sms and code is sent back to the server..yada yada ..all that basic stuff.
My dilemma is that i have received and read the sms correctly. How do i filter the body so that that it passes the number (not phone number but verification code) to the editText automatically. I'm trying to avoid users having to enter the verification code manually. Lemme show some code below.
public void processReceive(Context context, Intent intent){
Bundle bundle = intent.getExtras();
if(bundle == null){
return;
}
Object[] objectArray = (Object[])bundle.get("pdus");
for(int i = 0; i < objectArray.length; i++){
SmsMessage smsMsg = SmsMessage.createFromPdu((byte[])objectArray[i]);
String smsBody = smsMsg.getMessageBody();
Toast.makeText(context, smsBody, Toast.LENGTH_SHORT).show();
}
}
//In the code above, my broadcastReceiver receives the sms and i can display the body in a toast. The sms goes something like this: "Your verification code: 12345".
How do i get just the code from the sms and send its value to and editText programmatically like WhatsApp does.
number = (EditText) findViewById(R.id.number);
Thank you. You input is greatly appreciated
Try this it may be help to you
public static String GENERAL_OTP_TEMPLATE = "Your verification code: (.*).";
SmsMessage[] message = new SmsMessage[objectArray.length];
for (int i = 0; i < objectArray.length; i++) {
message[i] = SmsMessage.createFromPdu((byte[]) objectArray[i]);
}
Pattern generalOtpPattern = Pattern.compile(GENERAL_OTP_TEMPLATE);
Matcher generalOtpMatcher = generalOtpPattern.matcher(message[0].getMessageBody().toString());
if (generalOtpMatcher.find()) {
String otp = generalOtpMatcher.group(1);
number.setText(otp);
}
You can just use Split function to get your last 5 numbers :
String[] splited = body.split(":");
String mylastnum= splited[1];
number.settext(mylastnum);
hope it help !
register Broad cast Receiver in android manifest using below mention code.
<!-- SMS Receiver -->
<receiver android:name=".receiver.SmsReceiver">
<intent-filter android:priority="99999">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
Create Broad Cast Receiver using below mention code.
#Override
public void onReceive(Context context, Intent intent) {
final Bundle bundle = intent.getExtras();
try {
if (bundle != null) {
Object[] pdusObj = (Object[]) bundle.get("pdus");
for (Object aPdusObj : pdusObj) {
SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) aPdusObj);
String senderAddress = currentMessage.getDisplayOriginatingAddress();
String message = currentMessage.getDisplayMessageBody();
Log.e(TAG, "Received SMS: " + message + ", Sender: " + senderAddress);
// if the SMS is not from our gateway, ignore the message
if (!senderAddress.toLowerCase().contains(Config.SMS_ORIGIN.toLowerCase())) {
Log.e(TAG, "SMS is not for our app!");
return;
}
// verification code from sms
String verificationCode = getVerificationCode(message);
Log.e(TAG, "OTP received: " + verificationCode);
Intent hhtpIntent = new Intent(context, HttpService.class);
hhtpIntent.putExtra("otp", verificationCode);
context.startService(hhtpIntent);
}
}
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
}
Parse Verification Code that come through SMS.
private String getVerificationCode(String message) {
String code = null;
int index = message.indexOf(Config.OTP_DELIMITER);
if (index != -1) {
int start = index + 2;
int length = 6;
code = message.substring(start, start + length);
return code;
}
return code;
}

android sms receive and reply without user interface

i want to build a android application that first received a message from any number and after
receive message i want hold the message string and number in the variables and then reply message adding some extra string in message to same no automatically without user interface.
i am new in android so please help me.
only i have receiving message code....plese give me solution for rest of code.
thank you
My brodcost reciver class
package com.example.broadcastreceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;
public class IncomingSms extends BroadcastReceiver {
// Get the object of SmsManager
final SmsManager sms = SmsManager.getDefault();
public void onReceive(Context context, Intent intent) {
// Retrieves a map of extended data from the intent.
final Bundle bundle = intent.getExtras();
try {
if (bundle != null) {
final Object[] pdusObj = (Object[]) bundle.get("pdus");
for (int i = 0; i < pdusObj.length; i++) {
SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[i]);
String phoneNumber = currentMessage.getDisplayOriginatingAddress();
String senderNum = phoneNumber;
String message = currentMessage.getDisplayMessageBody();
System.out.println(phoneNumber);
System.out.println(currentMessage);
Log.i("SmsReceiver", "senderNum: "+ senderNum + "; message: " + message);
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context, "senderNum: "+ senderNum + ", message: " + message, duration);
toast.show();
} // end for loop
} // bundle is null
} catch (Exception e) {
Log.e("SmsReceiver", "Exception smsReceiver" +e);
}
}
}
my main activity
package com.example.broadcastreceiver;
import com.androidexample.broadcastreceiver.R;
import android.os.Bundle;
import android.app.Activity;
public class BroadcastNewSms extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.androidexample_broadcast_newsms);
Ssystem.out.println("")
}
}
Well, you now should send your message from your broadcast, you should:
PendingIntent sentIntent; // can be null
PendingIntent deliveryIntent; // can be null
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumber, null, message, sentIntent, deliveryIntent);
http://developer.android.com/reference/android/telephony/SmsManager.html
you might consider putting it into IntentService, I am not sure how long execution of sendTextMessage takes, and broadcasts should not do any heavy computations/processing. Also putting this code into IntentService, will prevent android from killing your app, this is important because you want this to work in background and android might create your app just to make it receive broadcast, and after onReceive ends it might kill your app, Service will prolong your app life.

Receiving SMS messages in my app

I am creating an app that receives SMS text messages, I have created a class that extends BroadcastReceiver to receive and display SMS messagesin a toast within the app. I have also added permissions too my manifest along with the declaration of the receiver. The problem is it still does not seem to display the message. It will only appear on the top bar as a notification. Hopefully someone will be able to see where i am going wrong. Do i have to have some code in my mainactivity in order to display the message?? or should it display in my all my activities straight from the receiver clas?? code below:
UPDATE
I ended up deleting my receiver and recreating everything, now it seems to work fine
SmsReceiver.java:
public class SmsReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
if (extras ==null)
return;
//toast
Toast.makeText(context, "Received", Toast.LENGTH_LONG).show();
Object[] pdus = (Object[]) extras.get("pdus");
for (int i = 0; i < pdus.length; i++) {
SmsMessage SMessage = SmsMessage.createFromPdu((byte[]) pdus[i]);
String sender = SMessage.getOriginatingAddress();
String body = SMessage.getMessageBody().toString();
Intent in = new Intent("SmsMessage.intent.MAIN").putExtra("get_msg", sender+":"+body);
context.sendBroadcast(in);
this.abortBroadcast();
}
}
}
The problem is it still does not seem to display the message. It will only appear on the top bar as a notification
do you know what is - Ordered Broadcast?
in case you don't know - it's a broadcast that receives synchronously (one after another) by all receivers that registered for this broadcast. you can set in the manifest receiver deceleration a priority , and each one of the receivers can control if the broadcast will pass on in the priorities chain to additional registered receivers by using the aboartBroadcast() method.
what's to this and receiving SMS? - the system sends ordered broadcast when SMS receives. if your receivers priority is lower then the "default SMS app" priority - then what usually happens is that the application that got the broadcast first will cancel the broadcast, and you'll never receives it.
to get the broadcast before the default SMS application you have to declare your receiver with high priority (providing priority = 1000 should do the trick).
without providing priority - it's automatically set to zero.
you can have a look on this example - How Can i INTERCEPT an Incoming SMS With A specific Text
also make sure you declared the permission to RECEIVE_SMS in the manifest
Try starting again and setting up your receiver like so....
public class SmsReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
if (extras ==null)
return;
//toast
Toast.makeText(context, "Received", Toast.LENGTH_LONG).show();
Object[] pdus = (Object[]) extras.get("pdus");
for (int i = 0; i < pdus.length; i++) {
SmsMessage SMessage = SmsMessage.createFromPdu((byte[]) pdus[i]);
String sender = SMessage.getOriginatingAddress();
String body = SMessage.getMessageBody().toString();
Intent in = new Intent("SmsMessage.intent.MAIN").putExtra("get_msg", sender+":"+body);
context.sendBroadcast(in);
this.abortBroadcast();
}
}
}
#Override
public void onReceive(Context context, Intent arg1) {
SmsMessage msgs[] = getMessagesFromIntent(arg1);
for (int i = 0; i < msgs.length; i++) {
SmsMessage mesg = msgs[i];
Toast toast = Toast.makeText(context, mesg.getDisplayMessageBody(), Toast.LENGTH_LONG);
toast.show();
}
}
public class SmsReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
SmsMessage[] msgs = null;
String str = "";
// retrieve the SMS message received ::
Object[] pdus = (Object[]) extras.get("pdus");
msgs = new SmsMessage[pdus.length];
for (int i = 0; i < msgs.length; i++) {
msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
str += "SMS from : " + msgs[i].getOriginatingAddress();
str += " :";
str += msgs[i].getMessageBody().toString();
str += "\n";
// Toast to display SMS ::
Toast.makeText(context, str, Toast.LENGTH_SHORT).show();
// Send SMS ::
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage("put your phoneNumber(emulatorPort)", null, str, null, null);
}
}
}
--
Have nice time !
Don't forget to add permissions !

Toast showing up twice

I have a program that sends pre-defined text messages to a group of people at a push of a button. I have it working well but the problem I have is that when it sends the messages, it pops up with 2 toasts per message sent. Code:
package com.mfd.alerter;
//imports
public class homeScreen extends Activity {
//buttons
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//vars
// Grab the time
final Date anotherCurDate = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("km");
final String formattedTime = formatter.format(anotherCurDate);
// Contacts
final String[] numbers = getResources().getStringArray(R.array.numbers);
// Start messages. Only 1 is given to shorten post
callStructureFire.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String msgText = "MFD PAGE OUT:\nStructure Fire\nTimeout:"+formattedTime;
for (int i = 0; i < numbers.length; i++) {
sendSMS(numbers[i], msgText);
}
}
});
//more call types. not important.
}
//---sends a SMS message to another device---
private void sendSMS(String numbers, String message)
{
String SENT = "SMS_SENT";
PendingIntent sentPI = PendingIntent.getBroadcast(this, 0,
new Intent(SENT), 0);
//---when the SMS has been sent---
registerReceiver(new BroadcastReceiver(){
#Override
public void onReceive(Context arg0, Intent arg1) {
switch (getResultCode())
{
case Activity.RESULT_OK:
Toast.makeText(getBaseContext(), "SMS sent",
Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
Toast.makeText(getBaseContext(), "Generic failure",
Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
Toast.makeText(getBaseContext(), "No service",
Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
Toast.makeText(getBaseContext(), "Null PDU",
Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
Toast.makeText(getBaseContext(), "Radio off",
Toast.LENGTH_SHORT).show();
break;
}
}
}, new IntentFilter(SENT));
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(numbers, null, message, sentPI, null);
}
//action bar stuff. not important.
}
More in detail: Lets say I send the text to 3 people, 6 toast messages will pop up saying "SMS Sent". How do I make it so only 3 will show up?
Also, Is there a way to maybe add a counter of the messages sent? Ex: "Message 1/10 sent", "Message 2/10 sent", etc?
I didn't really look at your code or asked myself why this happens but here's a trick to stop toasts show up twice:
Create a Toast instance using makeToast(), before showing it you call cancel(), set your text and then call show(). This will dismiss the previous toast. You won't even notice that a toast is displayed twice.
That's a stupid workaround, but it works for me ;-)
Aren't you supposed to register the receiver only once and not every time you call sendSMS.
You get 6 Toasts with three sms messages because you have 3 BroadCastReceivers. So in the first run you get 1 Toast. In the second run you get 2 Toasts (the receiver that was registered in the first run is called, and the one in the second). In the third run all three receivers are called, so you get three more toasts. All in sum - 6 Toasts...
so I guess, you have to register only one receiver before the for loop where you call sendSMS, or if you want the registration in sendSMS, then you have to unregister at the end of the method.
I hope this helps,
cheers!

Categories