I am currently writing and application, that is sending/receiving SMS messages.
For unit-testing purposes I need to create PDU programmatically. Decoding is quite easy:
Bundle bundle = intent.getExtras();
if (bundle != null) {
/* Get all messages contained in the Intent*/
Object[] pdusObj = (Object[]) bundle.get("pdus");
for (int i = 0; i < pdusObj.length; i++) {
SmsMessage msg = SmsMessage.createFromPdu((byte[])pdusObj[i]);
}
}
Is there any appropriate way to create PDU programamtically?
Typically PDUs are hardcoded in the code. Similar to this:
String pdu = "07914151551512f2040B916105551511f100006060605130308A04D4F29C0E";
SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
Here's a complete example on how to do this.
Now, you're gonna ask me "where can I find a PDU for testing?" You generate it. For example, you can use this online service.
I hope this helps!!
Related
I have written a SMSReceiver for Android and all works fine on real devices and when I test the App over Telnet.
But how can I create a unit test for the following onReceive Method in Android Studio?
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if (bundle!=null){
Object[] smsExtras = (Object[]) bundle.get("pdus");
String format = (String)bundle.get("format");
String strMessage = "";
for (Object smsExtra : smsExtras) {
SmsMessage smsMessage;
if (Build.VERSION.SDK_INT < 23){
smsMessage = SmsMessage.createFromPdu((byte[]) smsExtra);
}else {
smsMessage = SmsMessage.createFromPdu((byte[]) smsExtra, format);
}
String messageBody = smsMessage.getMessageBody();
String messageSource = smsMessage.getOriginatingAddress();
strMessage += "SMS from " + messageSource + " : " + messageBody;
Log.i(AppConstants.DEBUG_TAG, strMessage);
}
}
}
It depends on what you want to test, but it looks like you want to check that the message body and address is correctly parsed and has the expected contents. In that case you can break out that logic into a separate method and unit test it, by passing in a PDU and checking the return value.
If you want to test onReceive, it should be possible to use Mockito, pass in a MockContext and mock Intent's getExtra to return your own test Bundle object. Still, you'll need to verify something in the end. Perhaps you're planning to store the parsed data somewhere later? If so you can use that as your verification point - either by capturing and checking the argument, or verifying that the data was stored (though that's stretching the boundaries of the unit test quite a bit).
I develop an SMS Application in which when a SMS is received it is saved in the listview of my application. Now the problem is that if the message contains inverted commas then it is not saving in the database and thus not showing in listview. However i tried different methods available on net but none of them work. I then use Log.e to determine whether the incoming message is replacing the inverted comma or not but it doesnot replacing the inverted comma. My code for receiving sms is:
if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
Bundle bundle = intent.getExtras();
SmsMessage[] msgs = null;
String msg_from="";
String msgBody = "";
String msgDate="";
String title="";
if (bundle != null) {
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();
msgBody += msgs[i].getDisplayMessageBody();
msgBody.replace("\"","");
Log.e("answer", msgBody);
I check in the last line but if I write "Hello and send it to my self then following error shown in logcat:
near "HELLO": syntax error (code 1):
while compiling: insert into smss(contactnumber,contactname,message,date)
values ("03329234863", "03329234863",""HELLO ","1464940881000")
I also tried to replace msgBody with these solutions but none of them work:
msgBody.replaceAll("\"","");
msgBody.replace("\"","\\\\\"");
Please Help
Removing double quotes from a String works like this in Java:
String replaced = original.replaceAll("\"", "");
So your first attempt will work as expected. If it did not work for you, you likely have an issue somewhere else, ie are not passing the replaced string to the database. You did not post that code, but I guess there's an issue somewhere.
Use this
String first = second.replaceAll("\"", "");
i saw duplicates of this question. In all the questions, they specified to read all the sms from inbox.
What i want is just to read the latest received sms.
Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsMessage[pdus.length];
for (int i=0; i < msgs.length; i++) {
// Convert Object array
msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
// Sender's phone number
str += "SMS from " + msgs[i].getOriginatingAddress() + " : ";
// Fetch the text message
str += msgs[i].getMessageBody().toString();
str += "\n";
}
It is extracting all the messages, So which one of the below codes do i need to use to fetch latest sms, ( I removed 'for' loop in below code )
1
msgs[0] = SmsMessage.createFromPdu((byte[]) pdus[0]);
2
msgs[0] = SmsMessage.createFromPdu((byte[]) pdus[msgs.length-1]);
Question 1 : In above two codes, which one will give me latest message, fetching pdus[0] (1) or pdus[msg.length-1] ) (2)
Quetion 2 : In my code, i am going to read latest sms and search for particular key word and do corresponding action.
When i receive 2 sms at the same time (Say SMS1 & SMS2) . My keyword is present in SMS1 .
First, SMS1 receiving and after one or two second SMS2 is receiving, so what my doubt is whether my code will read SMS1 fastly and move to read SMS2 or it will skip SMS1 when SMS2 received ?
Forgive me and do a comment if i provided anything unclear, Hope you can solve my problem . Thanks in advance. :)
Your question is weird.
The code you gave first will actually fetch only one message .
Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsMessage[pdus.length];
for (int i=0; i < msgs.length; i++) {
// Convert Object array
msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
// Sender's phone number
str += "SMS from " + msgs[i].getOriginatingAddress() + " : ";
// Fetch the text message
str += msgs[i].getMessageBody().toString();
str += "\n";
}
Question 1 - You must use the above code . It will fetch only one message not all the messages in inbox.
Question 2 - It will not skip
I'm just done my lock screen application in Android. Now I want to improve it a bit with a notification on the lock screen when a sms received.
I got the content of the sms but I want to get the contact info of the sender. Anybody can help me to do that? Thanks in advance.
Start by getting the PDUs (Program Data Unit). From this, extract the information you desire. Search google for code examples to extract and read the data:
final Object[] pdusObj = (Object[]) bundle.get("pdus");
String who = new String();
String what = new String();
for (int i = 0; i < pdusObj.length; i++) {
SmsMessage received = SmsMessage.createFromPdu((byte[]) pdusObj[i]);
who = received.getDisplayOriginatingAddress();
what = received.getDisplayMessageBody();
Toast toast = Toast.makeText(contexto, "Who: " + who + "\n, What: " + what, Toast.LENGTH_LONG);
toast.show();
}
I can start another activity when i receive a sms. what I want to know is how to compare the text message with the content in my resources(xml string) and also the textview, editText. Is it possible to get reference from textview and edittext value in broadcast receiver class? Below is the code starting an activity without comparing any value.
public class SMSReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
//---get the SMS message passed in---
Bundle bundle = intent.getExtras();
SmsMessage[] msgs = null;
String str = "";
String phonenumber = "";
if (bundle != null)
{
//---retrieve the SMS message received---
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]);
phonenumber=msgs[i].getOriginatingAddress();
str += msgs[i].getMessageBody().toString();
str += "\n";
}
//=======launch the ShowMap1 when recieve SMS==============//
Intent mainActivityIntent = new Intent(context, ShowMap2.class);
mainActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mainActivityIntent.putExtra("phn", phonenumber);
mainActivityIntent.putExtra("sms", str);
context.startActivity(mainActivityIntent);
//========================END=============================//
}
}
}
as far as I understood that will be a global receiver that will get SMS.
So it means that the device can be on sleep, on the home screen, on the some game, on the gmail, or any other app; so that means that the Activity and the EditText do not exist at the moment that this receiver is being fired.
You can save a previously entered value from the activity on the SharedPreferences for example, and compare from those values.
To compare from an XML resource is very simple, you're receiving a reference to your application context with this receiver, just use it to get the value with this code:
String compare = context.getString(R.string.___);