How to use Broadcast Receiver in Android – Send and Receive SMS
Sending SMS is one of the basic features every phone has. In this tutorial we’ll create a SMS Sending Application for Android. You app can also Intercept any incoming SMS and perform task based on pre-defined rules, we’ll use Broadcast receiver for the listening purpose.
Project Name: HelloSMS Android Level: Android 2.3.3 Application Name: HelloSMS Package Name: com.vineetdhanawat.hellosms Create Activity: HelloSMS Min SDK Version: 10Layout
We’ll start with creating a layout for our main screen.
Components
- 2 Text Strings
- 2 Editable Text Box
- Character Counter in Message
- Send Button
<?xml version="1.0" encoding="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="Enter the phone number of the recipient" /> <EditText android:id="@+id/phoneNo" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Message" /> <EditText android:id="@+id/textMessage" android:layout_width="fill_parent" android:layout_height="160px" android:gravity="top" /> <TextView android:id="@+id/counter" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="160/0" /> <Button android:id="@+id/sendSMS" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Send SMS" /> </LinearLayout>
HelloSMS Main Activity
In the Main HelloSMS Activity, we’ll do 2 things.
- Bind the Send SMS button to a OnClickListener() for sending sms.
- Bind the Message Text box to addTextChangedListener() for counter.
package com.vineetdhanawat.hellosms;
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.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class HelloSMS extends Activity {
// Called when the activity is first created.
Button sendSMS;
EditText phoneNo;
EditText textMessage;
TextView mCounter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
sendSMS = (Button) findViewById(R.id.sendSMS);
phoneNo = (EditText) findViewById(R.id.phoneNo);
textMessage = (EditText) findViewById(R.id.textMessage);
mCounter = (TextView) findViewById(R.id.counter);
textMessage.addTextChangedListener(mTextEditorWatcher);
// On Click Listener on the sendSMS Button.
sendSMS.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String mobNo = phoneNo.getText().toString();
String message = textMessage.getText().toString();
if (mobNo.length()>0 && message.length()>0)
sendSMS(mobNo, message);
else
Toast.makeText(getBaseContext(),
"Please enter both phone number and message.",
Toast.LENGTH_SHORT).show();
}
});
}
}
The sendSMS() is defined as follows: We do not need to instantiate this class directly, Instead we can call getdefault() to obtain the SmsManager Object. sendTextMessage() send the sms with a PendingIntent. In this case it does nothing, but it can be used to monitor the status of sent SMS.
// Method to send SMS.
private void sendSMS(String phoneNumber, String message)
{
PendingIntent pi = PendingIntent.getActivity(this, 0,
new Intent(this, SMS.class), 0);
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumber, null, message, pi, null);
}
Let us modify the code to monitor the Sent / Delivered status of the SMS. We’ll need to use BroadcastReceiver object for the purpose.
// Method to send SMS.
private void sendSMS(String mobNo, String message) {
String smsSent = "SMS_SENT";
String smsDelivered = "SMS_DELIVERED";
PendingIntent sentPI = PendingIntent.getBroadcast(this, 0,
new Intent(smsSent), 0);
PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0,
new Intent(smsDelivered), 0);
// Receiver for Sent SMS.
registerReceiver(new BroadcastReceiver(){
@Override
public void onReceive(Context arg0, Intent arg1) {
switch (getResultCode())
{
case Activity.RESULT_OK:
Toast.makeText(getBaseContext(), "SMS 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;
}
}
}, new IntentFilter(smsSent));
// Receiver for Delivered SMS.
registerReceiver(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;
}
}
}, new IntentFilter(smsDelivered));
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(mobNo, null, message, sentPI, deliveredPI);
}
Let us now implement the addTextChangedListener() as Counter.
private final TextWatcher mTextEditorWatcher = new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
public void onTextChanged(CharSequence s, int start,
int before, int count) {
//This sets a textview to the current length
String smsNo;
if(s.length() == 0)
smsNo = "0";
else
smsNo = String.valueOf(s.length()/160 + 1);
String smsLength = String.valueOf(160-(s.length()%160));
mCounter.setText(smsLength+"/"+smsNo);
}
@Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
}
};
Permissions
In the AndroidManifest.xml file, we need to add the two permissions SEND_SMS and RECEIVE_SMS
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.vineetdhanawat.hellosms"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="10" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".HelloSMS"
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>
<uses-permission android:name="android.permission.SEND_SMS">
</uses-permission>
<uses-permission android:name="android.permission.RECEIVE_SMS">
</uses-permission>
</manifest>
Broadcast Receiver (Intercepting SMS)
Applications can intercept Incoming SMS as well. To do so, you need to add <receiver> element inside AndroidManifest.xml . Make sure it is included inside element.
<receiver android:name="com.vineetdhanawat.hellosms.SMSReceiver" android:enabled="true"> <intent-filter> <action android:name="android.provider.Telephony.SMS_RECEIVED" /> </intent-filter> </receiver>
Add a new Class file SMSReceiver.java. Here we’ll be parsing the intercepted sms and displaying as Toast. But this will Toast all the incoming sms. In case you want to Toast particular senders, use getOriginatingAddress();
package com.vineetdhanawat.hellosms;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.widget.Toast;
public class SMSReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Parse the SMS.
Bundle bundle = intent.getExtras();
SmsMessage[] msgs = null;
String str = "";
if (bundle != null)
{
// Retrieve the SMS.
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]);
// In case of a particular App / Service.
//if(msgs[i].getOriginatingAddress().equals("+91XXX"))
//{
str += "SMS from " + msgs[i].getOriginatingAddress();
str += " :";
str += msgs[i].getMessageBody().toString();
str += "\n";
//}
}
// Display the SMS as Toast.
Toast.makeText(context, str, Toast.LENGTH_SHORT).show();
}
}
}
That’s it. You can also use two emulators, By default they will have device names as emulator-5554 and emulator-5556. You can test it by sending sms from one of them to another giving emulator-5556 or just 5556 as the number.
App Ideas?
Using the Location Sensing (GPS) post which i posted a while before, and Broadcast Receiver above, It opens up a whole lot possibility of Apps.
Apps like JustDial. Where you have a lot of options like Theatres, Restaurant etc. All you need to do is choose an option. The app detects your location and sends your location to a pre-defined no. The server responds with list of available results (Say nearest Restaurants).
Want to learn more about Android Service and Broadcast Receiver? Check out Vogel’s Blog
Do you have any other Interesting App Ideas? Do share with us in the comments!








Pingback: Counter display code in SMS « NIKSHITS