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
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.
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());
}
}
}
}
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 want to open my application when I get notification message "abc". I can do this with SMSReceiver but only get sms message. I want do this whatsapp message. sory for bad English.
#Override
public void onReceive(Context context, Intent intent) {
String hangiNumaradan = "";
String neYazmis = "";
Bundle bundle = intent.getExtras();
SmsMessage[] msgs = null;
if (bundle != null) {
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]);
hangiNumaradan += msgs[i].getOriginatingAddress();
neYazmis += msgs[i].getMessageBody().toString();
}
Toast.makeText(context, hangiNumaradan + " gelen mesaj " + neYazmis, Toast.LENGTH_LONG).show();
}
}
This code is smsreceiver and toast message.
After doing some investigation I realized that since Facebook bought Whatsapp, they closed all public Whatsapp API and right now it's impossible to create Whatsapp message receiver, BUT there is one thing that you can do.
Create AccessibilityService:
public class MyAccessibilityService extends AccessibilityService {
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
//here you can implement your reaction for incoming notification
//here you can find some tags that could be helpful for you
String helpful = event.getContentDescription();
//In code below you could also retrieve some helpful info from Notification
AccessibilityNodeInfo source = event.getSource();
if (source == null) {
return;
}
// Grab the parent of the view that fired the event.
AccessibilityNodeInfo rowNode = getListItemNodeInfo(source);
if (rowNode == null) {
return;
}
// Using this parent, get references to both child nodes, the label and the checkbox.
AccessibilityNodeInfo labelNode = rowNode.getChild(0);
if (labelNode == null) {
rowNode.recycle();
return;
}
AccessibilityNodeInfo completeNode = rowNode.getChild(1);
if (completeNode == null) {
rowNode.recycle();
return;
}
// Determine what the task is and whether or not it's complete, based on
// the text inside the label, and the state of the check-box.
if (rowNode.getChildCount() < 2 || !rowNode.getChild(1).isCheckable()) {
rowNode.recycle();
return;
}
CharSequence anotherInfoFromNotification = labelNode.getText();
}
#Override
public void onInterrupt() {
}
}
Create serviceconfig.xml file:
<accessibility-service
android:accessibilityEventTypes="typeViewClicked|typeViewFocused"
android:packageNames="com.whatsapp"
android:accessibilityFeedbackType="feedbackSpoken"
android:notificationTimeout="100"
android:settingsActivity="com.example.android.your.way.to.activity"
android:canRetrieveWindowContent="true"/>
Register service in manifest:
<service android:name=".MyAccessibilityService">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data android:name="android.accessibilityservice"
android:resource="#xml/serviceconfig" />
</service>
So to summ it up: you will be able to get listener to all incoming whatsapp messages, you have to try little bit more with code in onAccessibilityEvent method to retrive info from message.
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());
}
}