Hi all I'am trying to read sms body and source from a paricular port. I can read the source number but the sms body is always null. Can someone help me to resolve this?
#Override
public void onReceive(Context ctx, Intent intent) {
Bundle extras = intent.getExtras();
if (extras != null) {
// Get received SMS Array
Object[] smsExtra = (Object[]) extras.get(SMS_EXTRA_NAME);
for (int i = 0; i < smsExtra.length; i++) {
SmsMessage sms;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
String format = intent.getExtras().getString("format");
sms = SmsMessage.createFromPdu((byte[]) smsExtra[i], format);
} else
sms = SmsMessage.createFromPdu((byte[]) smsExtra[i]);
System.out.println(sms.getOriginatingAddress());
System.out.println(sms.getMessageBody());
}
}
}
}
Related
Iam building an application that should recieve textMessage from specified number.
Is there anyway to recieve textmessage in an Edittext. here is the class for recieving sms:
class SMSReceiver extends BroadcastReceiver {
public static final String ACTION ="android.provider.Telephony.SMS_RECEIVED";
private static final String SMS_SENDER="123456789";
#Override
public void onReceive(Context context, Intent intent) {
if (intent != null && intent.getAction() != null &&
ACTION.compareToIgnoreCase(intent.getAction()) == 0) {
Object[] pduArray = (Object[]) intent.getExtras().get("pdus");
SmsMessage[] messages = new SmsMessage[pduArray.length];
for (int i = 0; i < pduArray.length; i++) {
messages[i] = SmsMessage.createFromPdu((byte[]) pduArray[i]);
}
// SMS Sender, example: 123456789
String sms_from = messages[0].getDisplayOriginatingAddress();
//Lets check if SMS sender is 123456789
if (sms_from.equalsIgnoreCase(SMS_SENDER)) {
StringBuilder bodyText = new StringBuilder();
// If SMS has several parts, lets combine it :)
for (int i = 0; i < messages.length; i++) {
bodyText.append(messages[i].getMessageBody());
}
//SMS Body
String body = bodyText.toString();
// Lets get SMS Code
String code = body.replaceAll("[^0-9]", "");
}
}
}
}
You need to understand BroadcastReceiver by Android Developer Document.
In your case, you need to get the result from BroadcastReceiver to Activity, and then you can set the value to EditText.
You can refer to here.
I'm developing an android app with Android studio that should send user location via sms but I don't know how to start the app only when the app receives a specific text.
Instructions can be found here with one extra step that i outlined below in a TODO.
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++) {
//here you will get currentMsg body phoneNmber and senderNumber
SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[i]);
String phoneNumber = currentMessage.getDisplayOriginatingAddress();
String senderNum = phoneNumber;
String message = currentMessage.getDisplayMessageBody();
//TODO launch app here!
} // end for loop
} // bundle is null
} catch (Exception e) {
Log.e("SmsReceiver", "Exception smsReceiver" +e);
}
}
}
I am creating an application in which I am sending SMS automatically on button click.When SMS is sent I get a response from server in form of SMS.I read that message and perform task on it. Now problem is that when I receive SMS I want to consider only messages received within one minute after button click. What to do.?
public class IncomingSms extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent)
{
Global mApplication = ((Global)context.getApplicationContext());
String getPPN=mApplication.getPPN();
String getStatus=mApplication.getvStatus();
String ClientId=mApplication.getvClientId();
String MobileNo=mApplication.getvStrMobile();
String LocationId=mApplication.getVstrLocation();
String IMEI=mApplication.getVstrIMEI();
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();
mApplication.setvSenderNumber(senderNum);
mApplication.setvMessageBody(message);
String IsBroadCast=mApplication.getvAuthenticatedUser();
try
{
if(IsBroadCast=="1")
{
context.sendBroadcast(new Intent("Message_Recived"));
}
}
catch(Exception e){}
}
}
} catch (Exception e)
{
}
}
}
This class is called when SMS received and take me to Arming Activity's on receive method.
But I need that..Broadcast receiver only receive message only within 1 minute after sendinf SMS
ArmingActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_arming);
registerReceiver(broadcastReceiver, new IntentFilter("Message_Recived"));}
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// internet lost alert dialog method call from here...
// if(strPPN.equals())
Global globalVariable = (Global) getApplicationContext();
String vvSenderNumber=globalVariable.getvSenderNumber();
String vvMessageBody=globalVariable.getvMessageBody();
String vvPPN=strPPN;
};
public void sendSms(String PPN, String smsBody) {
try {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(PPN, null, smsBody, null, null);
} catch (Exception e) {
e.printStackTrace();
}
}
if (strActionText.equals("1"))
{
sendSms(strPPN, MsgBody);
}
Here when send SMS start Broadcast receiver to start receiving SMS for 1 minute.
What to do?
you can do this with the Handler
for that start/register receiver and also start the Handler for the one minute
//start your broadcast here.
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// write code to stop/unregister receiver.
}
}, 60*1000);
for further display time you can use CountDownTimer class.
I'm trying to read SMS on Android. Everything's fine except when I'm trying to access some value in SmsMessage object I'm getting an error:
12-29 17:41:58.762: E/AndroidRuntime(5545): java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.android.internal.telephony.SmsMessageBase.getDisplayOriginatingAddress()' on a null object reference
12-29 17:41:58.762: E/AndroidRuntime(5545): at android.telephony.SmsMessage.getDisplayOriginatingAddress(SmsMessage.java:517)
I registered Receiver in AndroidManifest.xml, and by extending BroadcastReceiver created class SmsReceiver.
Method where I'm creating SmsMessage objects.
private final SmsMessage[] getMessagesFromIntent(Intent intent) {
Object[] messages = (Object[]) intent.getSerializableExtra("pdus");
byte[][] pduObjs = new byte[messages.length][];
for (int i = 0; i < messages.length; i++) {
pduObjs[i] = (byte[]) messages[i];
}
byte[][] pdus = new byte[pduObjs.length][];
int pduCount = pdus.length;
SmsMessage[] msgs = new SmsMessage[pduCount];
for (int i = 0; i < pduCount; i++) {
pdus[i] = pduObjs[i];
msgs[i] = SmsMessage.createFromPdu(pdus[i]);
}
return msgs;
}
Method onReceive
#Override
public void onReceive(Context context, Intent intent) {
SmsMessage[] messagesArray = getMessagesFromIntent(intent);
for (SmsMessage message : messagesArray) {
String sender = message.getDisplayOriginatingAddress(); //the application fails here
String order = message.getMessageBody().toString();
//...
}
}
I've tried method Intents.getMessagesFromIntent(intent) but with no effect
I registered Receiver in AndroidManifest.xml, and by extending BroadcastReceiver created class SmsReceiver.
Since you haven't posted your AndroidManifest.xml i am assuming you are registering your receiver like this
<receiver android:name=". SmsReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
if not please do it like this
as the Android Documentation for getMessagesFromIntent(Intent) says that it can only be used from API 19 onwards
hence ill tell you two methods to extract the sender's phone number and message from a received SMS
1. using getMessagesFromIntent(Intent) in your onRecieve method
for(SmsMessage message : Telephony.Sms.Intents.getMessagesFromIntent(intent)) {
if (message == null) {
Log.e(tag, "message is null");
break;
}
smsOriginatingAddress = message.getDisplayOriginatingAddress();
smsDisplayMessage = message.getDisplayMessageBody();
}
2. using PDU (protocol data unit) – the standard industry format for an SMS message
Object[] data = (Object[]) bundle.get("pdus");
for (Object pdu : data) {
SmsMessage message = SmsMessage.createFromPdu((byte[]) pdu);
if (message == null) {
Log.e(tag, "message is null");
break;
}
smsOriginatingAddress = message.getDisplayOriginatingAddress();
smsDisplayMessage = message.getDisplayMessageBody();
}
this should work fine
I have a broadcast receiver SMSApp which onReceive reads bundleExtras from intent. Here, How can I read phone number from bundleExtras?
if(intent.getAction().equals(SMS_RECEIVED))
{
Bundle bundleExtras = intent.getExtras();
if (bundleExtras != null)
{
}
}
Bundle bundle = intent.getExtras();
Object[] pdus = (Object[]) bundle.get("pdus");
final SmsMessage[] messages = new SmsMessage[pdus.length];
for (int i = 0; i < pdus.length; i++) {
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
}
Now, messages[0].getOriginatingAddress() is the address and messages[0].getMessageBody() is the message body.
Tutorial at http://ukitech.blogspot.com/2014/11/android-sms-app.html
OUTPUT:
SmsReceiver.processReceivedSms﹕ SMS from +1650815xxxx
SmsReceiver.processReceivedSms﹕ SMS body Test 4
/**
* Created by uki on 11/22/14.
*/
public class SmsReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
final String tag = TAG + ".onReceive";
Bundle bundle = intent.getExtras();
if (bundle == null) {
Log.w(tag, "BroadcastReceiver failed, no intent data to process.");
return;
}
if (intent.getAction().equals(SMS_RECEIVED)) {
Log.d(tag, "SMS_RECEIVED");
String smsOriginatingAddress, smsDisplayMessage;
// You have to CHOOSE which code snippet to use NEW (KitKat+), or legacy
// Please comment out the for{} you don't want to use.
// API level 19 (KitKat 4.4) getMessagesFromIntent
for (SmsMessage message : Telephony.Sms.Intents.
getMessagesFromIntent(intent)) {
Log.d(tag, "KitKat or newer");
if (message == null) {
Log.e(tag, "SMS message is null -- ABORT");
break;
}
smsOriginatingAddress = message.getDisplayOriginatingAddress();
//see getMessageBody();
smsDisplayMessage = message.getDisplayMessageBody();
processReceivedSms(smsOriginatingAddress, smsDisplayMessage);
}
// Processing SMS messages the OLD way, before KitKat,
// this WILL work on KitKat or newer Android
// PDU is a “protocol data unit”, which is the industry
// format for an SMS message
Object[] data = (Object[]) bundle.get("pdus");
for (Object pdu : data) {
Log.d(tag, "legacy SMS implementation (before KitKat)");
SmsMessage message = SmsMessage.createFromPdu((byte[]) pdu);
if (message == null) {
Log.e(tag, "SMS message is null -- ABORT");
break;
}
smsOriginatingAddress = message.getDisplayOriginatingAddress();
// see getMessageBody();
smsDisplayMessage = message.getDisplayMessageBody();
processReceivedSms(smsOriginatingAddress, smsDisplayMessage);
}
} // onReceive method
This is a link to a detailed "how to send and receive sms messages", you should check it, it is complete and full with examples:
http://mobiforge.com/developing/story/sms-messaging-android
also using this link, you can do:
if (bundle != null) {
SmsMessage[] messages = Telephony.Sms.Intents.getMessagesFromIntent(intent);
for (int i = 0; i < messages.length; i++) {
SmsMessage message = messages[i];
buf.append("Received SMS from ");
buf.append(message.getDisplayOriginatingAddress());
buf.append(" - ");
buf.append(message.getDisplayMessageBody());
}
}