11.2 SMS and MMS in Android

Hello readers!!! Hope you enjoyed the last sub-section. Let us start a new section which would deal with SMS and MMS technology. We would learn about SMS with respect to android framework. Let us not waste any more time and start introduction with this new guy.

11.2.1 Introduction to SMS and MMS

Short Message Service is one of the killer applications which are one of the most prominent communication tools. Even a kid knows how to use SMS application. Android comes with a built-in SMS application that enables us to send and receive SMS messages. However, it is possible that we would want to integrate SMS application. SMS technology can be used to send/receive text messages or data messages. Android supports full SMS functionality within our applications through the SmsManager class. We can use this SMS Manager to replace the native SMS application to send text messages, respond to incoming texts, or use SMS as a data transport layer.

Multimedia messaging service (MMS) messages allow users to send and receive messages which includes multimedia attachments such as videos, photos and audio.

SMSManager manages SMS operations such as sending data, text, and SMS messages. This object is get by calling the static method getDefault(). The default SMS app is the one which is selected b the user in system settings. The default SMS app is able to write to the SMS Provider. SMSProvider are the tables defined within the Telephony class. Only the default SMS app receives the SMS_DELIVER_ACTION broadcast when the user receives an SMS or the WAP_PUSH_DELIVER_ACTION broadcast when the user receives an MMS.

Application which wants to behave as the user's default SMS app must be able to handle the following intents:

  • In a broadcast receiver we have to include an intent filter for SMS_DELIVER_ACTION. The broadcast receiver would require the BROADCAST_SMS permission as well. This will allow our app to directly receive incoming SMS messages.
  • In a broadcast receiver it has to include an intent filter for WAP_PUSH_DELIVER_ACTION and it has to include the "MIME type". The broadcast receiver would also require the BROADCAST_WAP_PUSH permission. This will allow our app to directly receive incoming MMS messages.
  • In our activity that would deliver new message should include an intent filter for ACTION_SENDTO with schemas like sms:, smsto:, mms:, and mmsto:. This will allow our app to receive intents from other apps that would want to deliver a message.
  • In a service it must include an intent filter for ACTION_RESPOND_VIA_MESSAGE with schemas like sms:, smsto:, mms:, and mmsto:. This service would also require the SEND_RESPOND_VIA_MESSAGE permission. This will allow users to respond to incoming phone calls with an immediate text message using your app.

11.2.3 Example

Create a project and name it as you like. I am naming it SMSExample App. In this example we shall create a small text application. This would send SMS to another device. For that open the activity_main.xml file and code it as shown in the following listing:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Enter the phone number of recipient" />
    <EditText
        android:id="@+id/txtPhoneNo"
        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/txtMessage"
        android:layout_width="fill_parent"
        android:layout_height="150px"
        android:gravity="top" />
    <Button
        android:id="@+id/btnSendSMS"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Send SMS" />
</LinearLayout>

Figure activity_main.xml file

Open the activity file and code it as shown in the following listing:

package com.android.tution.SMSExample;
import android.os.Bundle;
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.telephony.SmsManager;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity {
    Button btnSendSMS;
    EditText txtPhoneNo;
    EditText txtMessage;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btnSendSMS = (Button) findViewById(R.id.btnSendSMS);
        txtPhoneNo = (EditText) findViewById(R.id.txtPhoneNo);
        txtMessage = (EditText) findViewById(R.id.txtMessage);
        btnSendSMS.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                String phoneNo = txtPhoneNo.getText().toString();
                String message = 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();
            }
        });
    }
    private void sendSMS(String phoneNumber, String message) {
        String SENT = "SMS_SENT";
        String DELIVERED = "SMS_DELIVERED";
        PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, new Intent(
                SENT), 0);
        PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0,
                new Intent(DELIVERED), 0);

Figure First half of code

Second half of class is as shown in the following listing:

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(SENT));
        // ---when the SMS has been delivered---
        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(DELIVERED));
        SmsManager sms = SmsManager.getDefault();
        sms.sendTextMessage(phoneNumber, null, message, sentPI, deliveredPI);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}

Figure Second half of class

Our last task is to work out the manifest. Please cross check manifest file with the following listing:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.tution.SMSExample"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.SEND_SMS" />
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.android.tution.SMSExample.MainActivity"
            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>

Figure manifest file

Create a suitable to run the application. In this project we need to emulator instances to check whether SMS send is received or not. Run two emulators. Run application in any one of them and you should receive SMS in another emulator. So output should look similar to the following snapshot:

Figure First instance of app

SMS sent from emulator 5554 will be received in 5556. So output should look similar to the following snapshot:

Figure Output of SMSExample app

 We have successfully completed this section. See you in the next section with something new. Till then keep practicing. Happy App Developing!!!