Introduction
Using Android programming, you can integrate SMS capabilities into your own Android applications. This allows you to create Android applications which can send and
receive SMS messages from your Android device. In this article I am explaining how you can send SMS messages programmatically. Also I am showing how you can monitor
the status of the SMS message, for example, when the message is sent and when it is delivered to the receiver.
Here, I am assuming that the reader has a basic knowledge of creating Android apps using the Eclipse IDE.
Background
Android requires permissions needed by an application to be specified in the
AndroidManifest.xml file. This ensures that when the application is installed,
the user knows which permissions are required by it. Also it gives an option to the user to decide whether or not to install the SMS application because such
an application requires a user to incur the cost of sending SMS messages.
Using the Code
The following line is required in the AndroidManifest.xml file to allow the application to send SMS messages:
<uses-permission android:name="android.permission.SEND_SMS"/>
The following is the full code of the AndroidManifest.xml file:
="1.0"="utf-8"
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.azim"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.SEND_SMS"/>
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".SMSSenderActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
The user interface of the SMS application consists of two EditText
fields for accepting the message text and the phone number, respectively and a
Button
control to send the message.
The following is the content of the main.xml file:
="1.0"="utf-8"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<TextView android:text="Enter SMS Text: " android:id="@+id/textView1"
android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
<EditText android:layout_width="match_parent" android:layout_height="wrap_content"
android:id="@+id/editText1"></EditText>
<TextView android:text="Enter Phone Number: " android:id="@+id/textView2"
android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
<EditText android:layout_width="match_parent" android:layout_height="wrap_content"
android:id="@+id/editText2"></EditText>
<Button android:text="Send SMS" android:id="@+id/button1" android:layout_width="wrap_content"
android:layout_height="wrap_content"></Button>
</LinearLayout>
The SmsManager
class is used to programmatically send an SMS message. This class is instantiated by using the
static getDefault()
method as follows:
SmsManager sms=SmsManager.getDefault();
The sendTextMessage()
method of the SmsManager
class is used to send a text message as follows:
sms.sendTextMessage(phone, null, message, piSent, piDelivered);
The sendTextMessage()
method accepts five parameters, as follows:
phone
- Recipient's phone numberaddress
- Service Center Address (null for default)message
- SMS message to be sentpiSent
- Pending intent to be invoked when the message is sentpiDelivered
- Pending intent to be invoked when the message is delivered to the recipient
The pending intents piSent
and piDelivered
are created as follows before calling the
sendTextMessage()
method:
PendingIntent piSent=PendingIntent.getBroadcast(this, 0, new Intent("SMS_SENT"), 0);
PendingIntent piDelivered=PendingIntent.getBroadcast(this, 0, new Intent("SMS_DELIVERED"), 0);
The PendingIntent
object piSent
is used to notify the sender that the message has been sent and the
PendingIntent
object piDelivered
is used to notify the sender that
the message has been delivered to the recipient when the recipient actually
receives the message.
Note: The piDelivered PendingIntent
does not fire in the Android emulator. You have to test the application on a real device to view it.
However, the piSent PendingIntent
works on both, the emulator as well as on a real device.
Two BroadcastReceiver
objects, smsSentReceiver
and
smsDeliveredReceiver
, are created in the onResume()
method. These are registered using the registerReceiver()
method as follows:
registerReceiver(smsSentReceiver, new IntentFilter("SMS_SENT"));
registerReceiver(smsDeliveredReceiver, new IntentFilter("SMS_DELIVERED"));
Inside each BroadcastReceiver
object, the onReceive()
method is overridden to check the result code using the
getResultCode()
method and display the appropriate message.
The two BroadcastReceiver
objects are unregistered in the onPause()
method as follows:
unregisterReceiver(smsSentReceiver);
unregisterReceiver(smsDeliveredReceiver);
Following is the full source code of the application:
package com.azim;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class SMSSenderActivity extends Activity implements View.OnClickListener {
EditText txtMessage,txtPhone;
Button btnSend;
BroadcastReceiver smsSentReceiver, smsDeliveredReceiver;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txtMessage=(EditText)findViewById(R.id.editText1);
txtPhone=(EditText)findViewById(R.id.editText2);
btnSend=(Button)findViewById(R.id.button1);
btnSend.setOnClickListener(this);
}
public void onClick(View arg0) {
SmsManager sms=SmsManager.getDefault();
String phone=txtPhone.getText().toString();
String message=txtMessage.getText().toString();
PendingIntent piSent=PendingIntent.getBroadcast(this, 0, new Intent("SMS_SENT"), 0);
PendingIntent piDelivered=PendingIntent.getBroadcast(this, 0, new Intent("SMS_DELIVERED"), 0);
sms.sendTextMessage(phone, null, message, piSent, piDelivered);
}
public void onResume() {
super.onResume();
smsSentReceiver=new BroadcastReceiver() {
@Override
public void onReceive(Context arg0, Intent arg1) {
switch (getResultCode()) {
case Activity.RESULT_OK:
Toast.makeText(getBaseContext(), "SMS has been 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;
default:
break;
}
}
};
smsDeliveredReceiver=new BroadcastReceiver() {
@Override
public void onReceive(Context arg0, Intent arg1) {
switch(getResultCode()) {
case Activity.RESULT_OK:
Toast.makeText(getBaseContext(), "SMS Delivered", Toast.LENGTH_SHORT).show();
break;
case Activity.RESULT_CANCELED:
Toast.makeText(getBaseContext(), "SMS not delivered", Toast.LENGTH_SHORT).show();
break;
}
}
};
registerReceiver(smsSentReceiver, new IntentFilter("SMS_SENT"));
registerReceiver(smsDeliveredReceiver, new IntentFilter("SMS_DELIVERED"));
}
public void onPause() {
super.onPause();
unregisterReceiver(smsSentReceiver);
unregisterReceiver(smsDeliveredReceiver);
}
}
Execute the application on the Android emulator. This will start the default AVD. Using the Android SDK and AVD Manager option, launch another AVD as follows:
On the first emulator (5554), type the message and number of the second emulator (5556) and click on the Send SMS button. This will show the message on the second emulator
and the sent notification on the first emulator.
Points of Interest
The advantage of sending SMS programmatically is that you can send dynamically generated messages through your applications. Also you don't need a real device to test this feature.
You can test the application on the emulator before transferring it to the real device.