Wednesday, June 13, 2012

Application to send SMS on Android Platform

I have been playing around with Android application in past. I thought of writing a simple application which can send a SMS.
Android has provided android.telephony.SmsManager class which has exposed different methods for sending SMS. If the message size is less than 160 character then we can use the the following method.
sendTextMessage(String destinationAddress, String scAddress,
        String text, PendingIntent sentIntent, PendingIntent deliveryIntent)
If you just want to send the message and not bothered about the send result then just pass the destinalAddress(MDN) and text(Message). 

Here is the code snippet for main Activity class.
package com.rakesh.simpleSms;

import com.rakesh.broadcastreceiver.DeliverSMSBroadcastReceiver;
import com.rakesh.broadcastreceiver.OutgoingSMSBroadcastReceiver;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class SimpleSMSAppActivity extends Activity {
 private EditText etNumber;
 private EditText etMessage;
 private SmsManager manager;
 public static final int  MAX_MESSAGE_SIZE = 160;
 public static final String SMS_SENT = "SMS_SENT";
 public static final String SMS_DELIVERED = "SMS_DELIVERED";
 private final BroadcastReceiver outgoingSMSBR = new OutgoingSMSBroadcastReceiver();
 private final BroadcastReceiver deliverSMSBR = new DeliverSMSBroadcastReceiver();
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  //  btSendMessage = (Button)findViewById(R.id.btSendMessage);
  etNumber = (EditText)findViewById(R.id.etNumber);
  etMessage = (EditText)findViewById(R.id.etMessage);
  manager =  SmsManager.getDefault();
 }

 public void sendMessage(View view){
  String number = etNumber.getText().toString();
  String message = etMessage.getText().toString();
  Log.d("RK","number : "+number+", message : " + message  );

  if(!isNullOrEmpty(number) && !isNullOrEmpty(message)){
   if(message.length() > MAX_MESSAGE_SIZE){

    Toast.makeText(this,"Message is longer then allowed in SMS",Toast.LENGTH_LONG).show();
   } else{
    PendingIntent piSend = PendingIntent.getBroadcast(this, 0, new Intent(SMS_SENT),0);
    PendingIntent piDelivered = PendingIntent.getBroadcast(this, 0, new Intent(SMS_DELIVERED), 0);

    manager.sendTextMessage(number, null, message, piSend, piDelivered);
    etMessage.setText("");
   }
  }
 }

 @Override
 protected void onResume() {
  registerReceiver(outgoingSMSBR, new IntentFilter(SMS_SENT));

  registerReceiver(deliverSMSBR, new IntentFilter(SMS_DELIVERED));

  super.onResume();
 }

 @Override
 protected void onPause() {
  unregisterReceiver(outgoingSMSBR);
  unregisterReceiver(deliverSMSBR);
  super.onPause();
 }

 private boolean isNullOrEmpty(String string){
  return string == null || string.isEmpty();
 }
}

and two broadcast receiver classes are as following.

OutgoingSMSBroadcastReceiver.java
 
public class OutgoingSMSBroadcastReceiver extends BroadcastReceiver {

 @Override
 public void onReceive(Context context, Intent intent) {
  
  switch(getResultCode()){
  
   case Activity.RESULT_OK:
      Toast.makeText(context, "SMS sent", 
                 Toast.LENGTH_SHORT).show();
      Log.d("RK","RESULT_OK");
         break;
      case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
          Toast.makeText(context, "Generic failure", 
                  Toast.LENGTH_SHORT).show();
          Log.d("RK","RESULT_ERROR_GENERIC_FAILURE");
          break;
      case SmsManager.RESULT_ERROR_NO_SERVICE:
          Toast.makeText(context, "No service", 
                  Toast.LENGTH_SHORT).show();
          Log.d("RK","RESULT_ERROR_NO_SERVICE");
          break;
      case SmsManager.RESULT_ERROR_NULL_PDU:
          Toast.makeText(context, "Null PDU", 
                  Toast.LENGTH_SHORT).show();
          Log.d("RK","RESULT_ERROR_NULL_PDU");
          break;
      case SmsManager.RESULT_ERROR_RADIO_OFF:
          Toast.makeText(context, "Radio off", 
                  Toast.LENGTH_SHORT).show();
          Log.d("RK","RESULT_ERROR_RADIO_OFF");
          break;
  }
 }
}
DeliverSMSBroadcastReceiver.java
package com.rakesh.broadcastreceiver;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;

public class DeliverSMSBroadcastReceiver extends BroadcastReceiver {

 @Override
 public void onReceive(Context context, Intent intent) {
 
          switch (getResultCode())
            {
             case Activity.RESULT_OK:
                Toast.makeText(context, "SMS delivered", 
                        Toast.LENGTH_SHORT).show();
                Log.d("RK","RESULT_OK=> DELIVER");
                break;
             case Activity.RESULT_CANCELED:
                Toast.makeText(context, "SMS not delivered", 
                        Toast.LENGTH_SHORT).show();
                Log.d("RK","RESULT_CANCELED");
                break;                        
            }
 }
}
Make sure you have provided the right permission to application in manifest file.

<manifest android:versioncode="1"   
 android:versionname="1.0" package="com.rakesh.simpleSms" 
 xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-sdk android:minsdkversion="10">
    
 <uses-permission android:name="android.permission.SEND_SMS">
 
    <application android:debuggable="true" android:icon="@drawable/ic_launcher" 
         android:label="@string/app_name">
        
        <activity android:label="@string/app_name" android:name=".SimpleSMSAppActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN">
                <category android:name="android.intent.category.LAUNCHER">
            </category></action></intent-filter>
        </activity>
    </application>
 
</uses-permission></uses-sdk>
You can find the source code here.

Please provide your valuable comments to improve this blog.

"By three methods we may learn wisdom: First, by reflection, which is noblest; Second, by imitation, which is easiest; and third by experience, which is the bitterest."
By : Confucius