SMS Messaging in Android

It would be safe to say that nearly every mobile phone sold in the past decade has SMS messaging capabilities. In fact, SMS messaging is one great killer application for the mobile phone and it has created a steady revenue stream for mobile operators. Understanding how to use SMS messaging in your application can provide you with many ideas to create the next killer application.

In this article, we take a look at how you can programmatically send and receive SMS messages in your Android applications. The good news for Android developers is that you don’t need a real device to test out SMS messaging – the free Android emulator provides the capability to do so.

Sending SMS Messages

To get started, first launch Eclipse and create a new Android project. Name the project as shown in Figure 1.

Figure 1 Creating a new Android project using Eclipse

Android uses a permission-based policy where all the permissions needed by an application need to be specified in the AndroidManifest.xml file. By doing so, when the application is installed it will be clear to the user what specific access permissions are required by the application. For example, as sending SMS messages will potentially incur additional cost on the user’s end, indicating the SMS permissions in the AndroidManifest.xml file will let the user decide whether to allow the application to install or not.

In the AndroidManifest.xml file, add the two permissions – SEND_SMS and RECEIVE_SMS:

Next, in the SMS activity, we wire up the Button view so that when the user clicks on it, we will check to see that the phone number of the recipient and the message is entered before we send the message using the sendSMS() function, which we will define shortly:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

packagenet.learn2develop.SMSMessaging;

import android.app.Activity;

import android.app.PendingIntent;

import android.content.Intent;

import android.os.Bundle;

import android.telephony.gsm.SmsManager;

import android.view.View;

import android.widget.Button;

import android.widget.EditText;

import android.widget.Toast;

publicclassSMSextendsActivity

{

Button btnSendSMS;

EditText txtPhoneNo;

EditText txtMessage;

/** Called when the activity is first created. */

@Override

publicvoidonCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

btnSendSMS=(Button)findViewById(R.id.btnSendSMS);

txtPhoneNo=(EditText)findViewById(R.id.txtPhoneNo);

txtMessage=(EditText)findViewById(R.id.txtMessage);

btnSendSMS.setOnClickListener(newView.OnClickListener()

{

publicvoidonClick(Viewv)

{

StringphoneNo=txtPhoneNo.getText().toString();

Stringmessage=txtMessage.getText().toString();

if(phoneNo.length()>0&&message.length()>0)

sendSMS(phoneNo,message);

else

Toast.makeText(getBaseContext(),

"Please enter both phone number and message.",

Toast.LENGTH_SHORT).show();

}

});

}

}

The sendSMS() function is defined as follows:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

publicclassSMSextendsActivity

{

//...

/** Called when the activity is first created. */

@Override

publicvoidonCreate(Bundle savedInstanceState)

{

//...

}

//---sends an SMS message to another device---

privatevoidsendSMS(StringphoneNumber,Stringmessage)

{

PendingIntent pi=PendingIntent.getActivity(this,0,

newIntent(this,SMS.class),0);

SmsManager sms=SmsManager.getDefault();

sms.sendTextMessage(phoneNumber,null,message,pi,null);

}

}

To send an SMS message, you use the SmsManager class. Unlike other classes, you do not directly instantiate this class; instead you will call the getDefault() static method to obtain an SmsManager object. The sendTextMessage() method sends the SMS message with a PendingIntent. The PendingIntent object is used to identify a target to invoke at a later time. For example, after sending the message, you can use a PendingIntent object to display another activity. In this case, the PendingIntent object (pi) is simply pointing to the same activity (SMS.java), so when the SMS is sent, nothing will happen.

If you need to monitor the status of the SMS message sending process, you can actually use two PendingIntent objects together with two BroadcastReceiver objects, like this:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

//---sends an SMS message to another device---

privatevoidsendSMS(StringphoneNumber,Stringmessage)

{

StringSENT="SMS_SENT";

StringDELIVERED="SMS_DELIVERED";

PendingIntent sentPI=PendingIntent.getBroadcast(this,0,

newIntent(SENT),0);

PendingIntent deliveredPI=PendingIntent.getBroadcast(this,0,

newIntent(DELIVERED),0);

//---when the SMS has been sent---

registerReceiver(newBroadcastReceiver(){

@Override

publicvoidonReceive(Context arg0,Intent arg1){

switch(getResultCode())

{

caseActivity.RESULT_OK:

Toast.makeText(getBaseContext(),"SMS sent",

Toast.LENGTH_SHORT).show();

break;

caseSmsManager.RESULT_ERROR_GENERIC_FAILURE:

Toast.makeText(getBaseContext(),"Generic failure",

Toast.LENGTH_SHORT).show();

break;

caseSmsManager.RESULT_ERROR_NO_SERVICE:

Toast.makeText(getBaseContext(),"No service",

Toast.LENGTH_SHORT).show();

break;

caseSmsManager.RESULT_ERROR_NULL_PDU:

Toast.makeText(getBaseContext(),"Null PDU",

Toast.LENGTH_SHORT).show();

break;

caseSmsManager.RESULT_ERROR_RADIO_OFF:

Toast.makeText(getBaseContext(),"Radio off",

Toast.LENGTH_SHORT).show();

break;

}

}

},newIntentFilter(SENT));

//---when the SMS has been delivered---

registerReceiver(newBroadcastReceiver(){

@Override

publicvoidonReceive(Context arg0,Intent arg1){

switch(getResultCode())

{

caseActivity.RESULT_OK:

Toast.makeText(getBaseContext(),"SMS delivered",

Toast.LENGTH_SHORT).show();

break;

caseActivity.RESULT_CANCELED:

Toast.makeText(getBaseContext(),"SMS not delivered",

Toast.LENGTH_SHORT).show();

break;

}

}

},newIntentFilter(DELIVERED));

SmsManager sms=SmsManager.getDefault();

sms.sendTextMessage(phoneNumber,null,message,sentPI,deliveredPI);

}

The above code uses a PendingIntent object (sentPI) to monitor the sending process. When an SMS message is sent, the first BroadcastReceiver‘s onReceive event will fire. This is where you check the status of the sending process. The second PendingIntent object (deliveredPI) monitors the delivery process. The second BroadcastReceiver‘s onReceive event will fire when an SMS is successfully delivered.

You can now test the application by pressing F11 in Eclipse. To send an SMS message from one emulator instance to another, simply launch another instance of the Android emulator by going to the Tools folder of the SDK and running Emulator.exe.

Figure 3 Sending an SMS message

Figure 3 shows how you can send an SMS message from one emulator to another; simply use the target emulator’s port number (shown in the top left corner of the window) as its phone number. When an SMS is sent successfully, it will display a “SMS sent” message. When it is successfully delivered, it will display a “SMS delivered” message. Note that for testing using the emulator, when an SMS is successfully delivered, the “SMS delivered” message does not appear; this only works for real devices.

Figure 4 shows the SMS message received on the recipient emulator. The message first appeared in the notification bar (top of the screen). Dragging down the notification bar reveals the message received. To view the entire message, click on the message.

Figure 4 The SMS message received by the Android emulator

If you do not want to go through all the trouble of sending the SMS message yourself, you can use an Intent object to help you send an SMS message. The following code shows how you can invoke the built-in SMS application to help you send an SMS message:

Receiving SMS Messages

Besides programmatically sending SMS messages, you can also intercept incoming SMS messages using a BroadcastReceiver object.

To see how to receive SMS messages from within your Android application, in the AndroidManifest.xml file add the <receiver> element so that incoming SMS messages can be intercepted by the SmsReceiver class:

Add a new class file to your project and name it as SmsReceiver.java (see Figure 6).

Figure 6Adding the SmsReceiver.java file to the project

In the SmsReceiver class, extend the BroadcastReceiver class and override the onReceive() method:

1

2

3

4

5

6

7

8

9

10

11

12

13

packagenet.learn2develop.SMSMessaging;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

publicclassSmsReceiverextendsBroadcastReceiver

{

@Override

publicvoidonReceive(Context context,Intent intent)

{

}

}

When SMS messages are received, the onCreate() method will be invoked. The SMS message is contained and attached to the Intent object (intent – the second parameter in the onReceive() method) via a Bundle object. The messages are stored in an Object array in the PDU format. To extract each message, you use the static createFromPdu() method from the SmsMessage class. The SMS message is then displayed using the Toast class:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

packagenet.learn2develop.SMSMessaging;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.os.Bundle;

import android.telephony.gsm.SmsMessage;

import android.widget.Toast;

publicclassSmsReceiverextendsBroadcastReceiver

{

@Override

publicvoidonReceive(Context context,Intent intent)

{

//---get the SMS message passed in---

Bundle bundle=intent.getExtras();

SmsMessage[]msgs=null;

Stringstr="";

if(bundle!=null)

{

//---retrieve the SMS message received---

Object[]pdus=(Object[])bundle.get("pdus");

msgs=newSmsMessage[pdus.length];

for(inti=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";

}

//---display the new SMS message---

Toast.makeText(context,str,Toast.LENGTH_SHORT).show();

}

}

}

That’s it! To test the application, press F11 in Eclipse. Deploy the application to each Android emulator. Figure 7 shows Eclipse showing the emulators currently running. All you need to do is to select each emulator and deploy the application onto each one.

Figure 7 Selecting an emulator/device to deploy the application onto

Figure 8 shows that when you send an SMS message to another emulator instance (port number 5556), the message is received by the target emulator and displayed via the Toast class.

Summary

In this article, you have seen how you can send and receive SMS messages programmatically from within your Android application. The capability to send and receive SMS messages is very useful as you can build very compelling applications. As an example, you can build a location tracker application where you can send a secret-coded SMS message to a device and when the device receives the secret SMS message it will reply with another SMS message containing its current geographical location using its built-in GPS receiver. How cool is that?!

i use sdk_window_1.5, run app the emulator run normal, but my problem is i can’t run emulator.exe in tools folder in sdk 1.5, may its have problem with emulator? so i used the emulator.exe of sdk_1.0 and it run, =)), very interested!!

Great article bro! When would (should) you *not* use the built-in Apps via Intents? Isn’t that what they are there for? I see many places where developers are rolling their own solutions and this seems like recreating the wheel to me. If the issue is to change the L&F, this sort of goes against the grain of a common UI too.

is it possible to start a new activity on receive of sms?means i want to startActivity(intent) in SmsReceiver class.but as this class is not a Activity class how to pass context to start new activity?
Please let me know this will be great help for me.Kapnkore@gmail.com

Hi, congratulation for the tutorial, it’s very easy to understand. I am trying to make a little hack to your code. I would like to realize an sms application:
when an sms is received a new thread is lunched, it’s an UDP client that should talk whit an UDP Java server (running on a desktop pc) via socket.
The code is attached, please rename the file to .tar.gz.
All the class compiles well and also runs on the emulator, but the client seems to be unable to connect to the server. We tried to install the application on the terminal (htc hero with android 1.5) .
Could you please have a look to say if something is not ok?

[quote=kapnkore]is it possible to start a new activity on receive of sms?means i want to startActivity(intent) in SmsReceiver class.but as this class is not a Activity class how to pass context to start new activity?
Please let me know this will be great help for me.Kapnkore@gmail.com[/quote]
Please help me. jindoman87@yahoo.com. Thanks

Hello Everyone,
This is a very good tutorial site.
Can i anyone tell me, can i call in android automatically without opening its default calling interface. I want to show my application while calling is running in the backgroud.
Sorry for bad english.

Hi. I tried to use this code and i have this kind of porblem:
I create their own files for this BroadcastReceiver. Maybe what’s why it is work different, but i am sure it is not important.
So. First we register new receivers every time we send a Sms. So if i send 3 sms i will have 6 broadcast receivers in memory. (I noticed it, using log) We need register recievers in onCreate function (or onStart)

And Second. I tried this code on 2 emulators. Sms sends fine, but broadcast receiver, what responsible for delievery is never called. So i don’t get delievery toast.
Is this emulator problem? This code work correct on phone?
Also i read something in android developers, what this delivery broadcast use some raw pdu, i don’t get how to use it. Someone can explain me pls?

[quote]
Hi,I want use the Mobile set to send the sms,but where I must put the code?Can you help me?
[/quote]
You should have some soft – eclipse + android sdk+ adt.The first qustetion is do you have them?

This is a website of Afilias Technologies Ltd, a private company limited by shares, incorporated and registered in the Republic of Ireland with registered number 398040 and registered office at 6th Floor, 2 Grand Canal Square, Dublin 2, Ireland