×
Namespaces

Variants
Actions

SMS Handling in Nokia X Applications

From Nokia Developer Wiki
Jump to: navigation, search

This article explains how to receive, respond to, and send SMS from within your Nokia X application.

Note.pngNote: This is an entry in the Nokia X Wiki Challenge 2014Q1

.
Article Metadata
Tested with
SDK: Nokia X 1.0 Services SDK
Devices(s): Nokia X
Article
Created: obandu (24 Mar 2014)
Last edited: BuildNokia (16 Apr 2014)

Contents

Introduction

SMS (Short messaging services) remains the one universal application available on all mobile networks. It works with both smart phones and non-smart phones, so just about everyone that has a mobile handset can use SMS.

The Nokia X smartphone provides its owners the opportunity to automate SMS handling by receiving ordinary or customised messages, and by sending ordinary or customised messages.

SMS messages can be scheduled. They can also be asynchronous; for instance,a Nokia X device can send the price of a widget to someone who sends in the widget's item code. Our "SMS Bounce" application works this way.

You could also send calendar invites via SMS from one smartphone to another. Or you could send your current location via SMS to another smartphone user. The possibilities are numerous.

In this article, we will focus on key techniques/fundamentals used by our SMS Bounce application. SMS Bounce is an application that allows the user to store key-word and response pairs. For example you could have widget SKU codes and their price. Someone who wants to know the price of a widget would send a plain SMS text from any device with the SKU code of the widget prefixed with *#. For example if we have a widget of code ACME657, they send an SMS message *#ACME657 to our Nokia X device with SMS Bounce installed. The SMS Bounce app will send back to them the price of the ACME657 widget. If they send a message without this prefix, it will be received by the built-in SMS messaging application.

AOSP or the Nokia X 1.0 Software platform provides applications with a means to listen asynchronously to incoming SMS messages. This is done using the standard Android broadcast receiver. The message received is then processed by a 'main application' (activity) which then responds to the message if it meets the preset criteria. The fundamental features we shall look at are:

1. Configuring the XML Application Manifest for receiving broadcasts and sending messages.

2. Creating a broadcast receiver and understanding its lifespan.

3. Blocking an SMS broadcast from going to the standard messaging application

4. Transferring data from a broadcast receiver to the main application.

5. Sending an SMS from within application.

Implementation

1. Configuring the XML Manifest to receive broadcasts and send messages

AOSP/Android requires that for applications to access certain features of the system, you declare permissions for these features in the manifest. See below a fragment of the manifest showing the permissions required to get receive SMS messages and send SMS messages.

    <uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
<uses-permission android:name="android.permission.SEND_SMS"></uses-permission>

The second item in the manifest is the definition of the broadcast receiver as per the code below. The key thing to note is that the android:name attribute is the name of the class. Because the name of the class is prefixed with ".", it indicates the class is part of the application package. In our case this was com.kiwavi.smsbounce and hence com.kiwavi.smsbounce.MySMSReceiver.

The second attribute is android:enabled which is set to true. In addition the specific broadcast action to be received with this receiver is shown in the action tag, in our case android.provider.Telephony.SMS_RECEIVED. The AOSP sends various broadcasts but our app is only interesting in the SMS_RECEIVED broadcast.

One other thing to note is that a broadcast receiver can be defined either in the application manifest or within the application onCreate() method. Because we expect our app to function mostly in the background, we register the receiver in the manifest so that it will always be called even if our application is not in the foreground.

Refer to the the 'DESCRIPTION' field of receiver in the Android documentation for more information.


        <receiver android:name=".MySMSReceiver" android:enabled="true">
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>

2. Creating a broadcast receiver and understanding its lifespan.

A broadcast receiver concrete class would extend the "android.content.BroadcastReceiver" class with the key method in it being 'onReceive()'. See the code below.

public class MySMSReceiver extends BroadcastReceiver 
{
 
public void onReceive(Context incontext, Intent intent)
{
.
.
code to extract sms and send it to the application processing it.
.
.
}
}

A second and very important thing to note is that the lifespan of a broadcast receiver is only limited to the {{Icode|onReceive} method. Refer to the '2. Receiver lifecycle' of BroadcastReceiver for more information.

In the onReceive() method we process the message by getting the actual SMS text, and filtering it to ensure it was meant for our application. Recall that we only want to receive messages with the prefix *#; we must allow all other messages to pass through to the normal messaging application. Once we have determined this is a message for our app, we then send it to be processed by the main application even after the broadcast receiver has finished its task and ended.

How to extract the message

Android apps and the operating system use 'Intents' for communications between apps, including sending broadcasts. An intent would contain action instructions and some data stored in a bundle. If you look at the contract for the onReceive() method of the broadcast receiver, you will see that it takes in a Context and an Intent. From this intent, we will extract the SMS Message Text and originating phone numbers. A commented method to extract the message into a two-string array containing the phone number and message body is shown below.

  private String[] getMessageFromIntent(Intent intent)
{
// array of length 2 containing originating number and message text
String mymessage[] = new String[]{"",""};
 
// the message text
String message_text = "";
 
// the originating number
String message_number = "";
 
// get the bundle containing the data (SMS Messages)
Bundle bdl = intent.getExtras();
try{
 
// collection of PDU's containing each a 160 character sms message
Object pdus[] = (Object [])bdl.get("pdus");
 
SmsMessage retMsgs[] = new SmsMessage[pdus.length];
if (retMsgs != null)
{
for(int n=0; n &lt; pdus.length; n++)
{
byte[] byteData = (byte[])pdus[n];
retMsgs[n] = SmsMessage.createFromPdu(byteData);
message_text += retMsgs[n].getMessageBody();
}
 
mymessage[0] = retMsgs[0].getOriginatingAddress();
mymessage[1] = message_text;
}
}
catch(Exception ex)
{
}
return mymessage;
}

3. Blocking an SMS broadcast from going to the standard messaging application

Considering we are not building a full-featured messaging app, we need to ensure that any messages not meant for our app do not interfere negatively with other apps in the system. To do this we use the abortBroadcast() and clearAbortBroadcast() methods of the broadcast receiver. abortBroadcast() will prevent the message from being forwarded to other SMS broadcast receivers, including the built-in messaging app, while the message is being processed. See our code fragment below in the broadcast receiver.

public class MySMSReceiver extends BroadcastReceiver 
{
 
public void onReceive(Context incontext, Intent intent)
{
abortBroadcast();
.
.
// code to extract sms and send it to the application processing it.
.
if (messagetext.startsWith("*#"))
{
//send message to main application for processing
}
else { clearAbortBroadcast(); }
.
}
}

4. Transferring data from a broadcast receiver to the main application.

As we have seen earlier, the broadcast receiver has a very short lifespan that only lasts from the beginning to the end of the onReceive() method. For processing of the SMS messages (which, in the case of our SMSBounce app, means connecting to the SQLite database, reading some data and responding to it), we have to do this in the main() activity. The broadcast receiver therefore sends the formatted message to the main() activity. The method we use is the standard inter-activity data transfer, the intent.

Our intent is very specific in that it starts up the activity, thenpasses to it the data bundle consisting of a sender number and message text. See the code fragment below.

One thing to note is the intent flag that we have set as FLAG_ACTIVITY_NEW_TASK. This is so that if the activity was not started, it would be started otherwise; it would come to the foreground.

                      // retrieve SMS body and sender number 
String msg[] = getMessageFromIntent(intent);
 
// create a new intent and add the data to it
Intent newIntent = new Intent();
newIntent.putExtra("messagetext", msg[0]);
newIntent.putExtra("sendernumber", msg[1]);
 
// choose the activity to send this intent to
newIntent.setClassName("com.kiwavi.smsbounce", "com.kiwavi.smsbounce.SMSBounceApp");
newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 
// send data to the activity, creating it if it did not exist before
getApplicationContext().startActivity(newIntent);

Receiving the data in the main activity

The main() activity is started and brought forward with the new activity request. Data sent into the activity from our broadcast receiver is received in the protected method onNewIntent(). See the code fragment below. As usual, the data added with intent.putExtras() in your broadcast receiver is extracted via a Bundle.

  public void onNewIntent(Intent intent)
{
Bundle bdl = intent.getExtras();
if (bdl != null)
{
 
String sender = ""+bdl.get("sendernumber");
String message = ""+bdl.get("messagetext");
 
// DO Anything with your message.
System.out.println("Message is surely received from " + sender + " " + message);
}
}

Finally

For the application's main activity to receive the onNewIntent(), you must modify the application tag in the manifest file to include the attribute android:launchMode as singleTop. See the code fragment below.

        <activity
android:name=".SMSBounceApp"
android:launchMode="singleTop"

5. Sending an SMS from within application.

For the SMSBounce application, we finally send back a message to the sender with their requested text. If what they request is not found, the message indicates that the feature or text requested has not been found. It is important to note here that while it costs you nothing to receive SMS messages, it may cost something to send SMS messages, depending on the users's mobile service provider. To use this version of SMSBounce, make sure you have a plan that will allow sending unlimited SMS messages.

Sending SMS messages is much simpler than receiving the messages. It actually just takes two lines of code as shown in the code fragment below. Look up the contract for the class {{Icode|android.telephony.SmsManager]] and sendTextMessage() method for further details on what each of the parameters mean. To send a standard text message using the current SMS service center address, the code shown below will work.

  synchronized void sendMessage(String address, String message)
{
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(address, null, message, null, null);
}

Summary

With these few code snippets, you should be on your way to making complex applications that use SMS for communications.

Further improvements and variations to this application template would include being able to log success/failure of messages sent, monitor and set thresholds for messages to be sent per period for billing purposes and connect to desktop computers, servers or to the web for further processing.

This could also be the basis for a full-featured replacement app for the built-in SMS messaging application.

The code for a full working application can be found in the androidsms Github project.

The code is for a full working open sourced application showing all the features described here but not all the code for the application described here (SMSBounce). You will therefore find that the class path is different but the code used is exactly the same.

This page was last modified on 16 April 2014, at 22:20.
169 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×