Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development Knowledge Base

BlackBerry 10 Developer’s Guide to SMS and MMS

by BlackBerry Development Advisor (Retired) ‎07-26-2013 10:30 AM - edited ‎10-29-2013 06:02 AM (6,439 Views)

Introduction

 

This article is intended to help developers wishing to incorporate SMS (Short Messaging Service) and MMS (Multimedia Messaging Service) messaging features in their BlackBerry® 10 applications. Note that SMS is also known as Text Messaging.

 

Most of this KB article is about SMS. A section on MMS was added in a second release of the article. The BlackBerry 10 APIs are very similar for both SMS and MMS and the section on MMS highlights the differences when working with MMS rather than SMS so even if you're only interested in MMS, it's recommended that you read the whole of this article as much of the SMS information applies equally to MMS.

 

Readers of this article should be familiar with BlackBerry 10 Native development, including Qt® and QML, and should be familiar with C++ in order to appreciate the sample applications that are used to demonstrate the concepts. It is also assumed that the reader is familiar with at least the basic concepts surrounding SMS.

 

Two open source applications, “SmsMessageService” and “SmsPortDirected”, which incorporate the features discussed in this article, have been published on GitHub® as Open Source. Code fragments from these applications are used in this article to illustrate important points.

 

sms_apps.png

 

You’ll find screenshots from both applications in the article too. The screenshots may include patches of red, obscuring parts of the user interface. The user interface doesn’t actually have these red patches. For the article I thought it best to obscure the mobile phone numbers I used for testing and did so by hiding them behind a red rectangle.

 

The Author

This article was written by Martin Woolley who works in the BlackBerry Developer Relations team. 

 

SMS Application Use Cases

In simple terms, developers will want to do one or both of two things with SMS from a BlackBerry 10 application: send SMS messages or receive them. However, there are two distinct scenarios for each of these simple use cases; either the application works with SMS messages in much the same way that a user would using the BlackBerry 10 text messaging application, creating or receiving text messages that are intended to be “consumed” by a human recipient; or, the application uses SMS as a transport for binary data, to be sent or received to or from another device, or server-resident messaging service. We’ll refer to the first scenario as “user directed SMS”, and the second as “port directed SMS” for reasons that will become clear.

 

User Directed SMS

The BlackBerry 10 native APIs include the Message API and the Account API. These APIs are both used when we wish to send or receive user directed SMS messages.

 

A BlackBerry 10 device may be configured to allow  the use of a series of different messaging accounts, including SMS, MMS, email, Twitter® and so on. The Account API relates to this. The Message API provides an abstraction of the world of messages for the many types that are supported by these various account types on BlackBerry 10.

 

Accounts have an internal ID, which is a numeric identifier used by BlackBerry 10. They also have a provider ID. This is a human readable string value which acts as an alternate identifier. The provider ID value is something that we can rely upon as having a known and predictable value. The numeric account ID, on the other hand, should not be assumed to always contain the same value. For SMS, the provider ID has a value of “sms-mms”.

 

To send a user directed SMS message and to identify the account from which we’re receiving messages, we need to know the ID of the account associated with SMS messaging in API calls. Therefore, one of our first jobs is to ascertain this value. The AccountService class makes this possible. 

 

Let’s take our first look at some code. You’ll find all that follows in this section in the SmsMessageService application.

 

bb::pim::account::AccountService* _account_service;
bb::pim::message::MessageService* _message_service;
int _sms_account_id;

Figure 1 - SmsMessageService.hpp declarations 

 

 

_account_service = new AccountService();

.....

// obtain the Account responsible for SMS
QList<Account> account_list = 
    _account_service->accounts(Service::Messages, "sms-mms");

// save its internal ID value for future API calls
_sms_account_id = account_list.first().id();

Figure 2 - Obtaining the sms-mms account ID

 

Now that we know the ID of the account providing SMS services, we can send user directed SMS messages from our application and recognise messages as being SMS messages when we receive them.  Let’s start by examining how we go about sending an SMS message.

 


 

Sending a user directed SMS message

The code that implements sending of user directed SMS messages in the SmsMessageService app is shown in Figure 3. Cast your eye over it first and then we’ll discuss the details.

 

void SmsMessageService::sendMessage(const QString & text, 
                                    const QString & destination_addr) {

// First create a Conversation object 
// User directed SMS messages are always part of a “conversation”

   ConversationBuilder* conversation_builder = ConversationBuilder::create();
   conversation_builder->accountId(_sms_account_id);
   QList<MessageContact> participants;

// Create a MessageContact object for the message recipient

   MessageContact recipient = MessageContact(-1, 
                                             MessageContact::To, 
                                             destination_addr, 
                                             destination_addr);

// and add it to the list of conversation participants
   participants.append(recipient);
   conversation_builder->participants(participants);

// Obtain the conversation and save it using the MessageService, specifying the sms-mms 
// account ID
	Conversation conversation = *conversation_builder;
	ConversationKey conversation_id = 
         _message_service->save(_sms_account_id, conversation);

// Make a Message object for the sms-mms account
	MessageBuilder* msg_builder = MessageBuilder::create(_sms_account_id);

// Set the message body (message text) as an Attachment to the Message object
	msg_builder->addAttachment(Attachment("text/plain", "", text));

// Specify the recipient of the message (i.e. the destination address/MSISDN)
	msg_builder->addRecipient(recipient);

// Set the message’s conversation ID
	msg_builder->conversationId(conversation_id);


// 
	Message message;
	message = *msg_builder;

// Send it using the SMS MMS account
	qDebug() << "XXXX sendMessage: sending via account id " << _sms_account_id << " : " << message.recipientAt(0).address();
	MessageKey msg_id = _message_service->send(_sms_account_id, message);
	log("Sent... message ID:" + msg_id);

}

Figure 3 - Sending a user directed SMS message

 

There are a number of classes involved in our code. Let’s a say a word or two about each of them. Hopefully this, together with the code and its comments, will make things clear:

 

Conversation and ConversationBuilder

When sending a user directed SMS message, you’re required to work with the same data structures and concepts that the standard BlackBrry 10 text messaging application uses. Amongst those is the concept of a “conversation”. All messages sent in this way, must be part of a conversation even if ultimately, it’s the only message that is ever part of that conversation and there’s only one person participating in it. Whether you make more extensive use of Conversations depends on your application requirements, but, for a simple “send an SMS” use case, generally each message will be the sole member of a Conversation and you’ll be creating a new Conversation for each Message you send. That’s what the code in Figure 3 does.

 

As you can see, we use a class called ConversationBuilder to create our Conversation object and then set its attributes. This includes the list of MessageContact objects that represent participants in the conversation. In our case, as we’ve already noted, our one-and-only participant is the recipient of our SMS message. Let’s look at MessageContact next.

 

MessageContact

Recipients of SMS messages sent via the Message API are represented by MessageContact objects. It’s designed to work with messages of various types, so you’ll see defined in the class various constants, such as MessageContact::Cc, that don’t really have any role with an SMS message. You should use the MessageContact::To constant when building a MessageContact.

 

In our code, you can see that we appear to provide the destination address (i.e. the phone number or MSISDN of the destination to which we’re sending the SMS message) twice. In fact the first of those two parameters, which is called “name” in the API documentation, is a text value which you designate to be used for display purposes in the Text Messages application. Why? Well, because when you send an SMS using this API, it will be saved automatically in the user’s SMS folder. During testing I sent a message with “name” set to “CONTACT NAME” and you can see the way this manifests itself in figures 4 and 5 below.

 

sms_contact_name.png

Figure 4 - The name parameter value as it appears in my text message folder

 

 

 

And also....

 

sms_compose_message.png

 

Figure 5 - the name parameter value as it appears when replying to my text

 

MessageBuilder

The MessageBuilder class provides the mechanism, by which, you can easily create a Message object and set its attributes. In our application, we first create a Message that “belongs to” the “sms-mms” account using MessageBuilder, and then proceed to set its attributes. With one exception, the meaning of all of these attributes should be clear from the code above and the associated comments. The attribute whose purpose will not necessarily be completely clear is set using the call to addAttachment using an Attachment object as the argument. Let’s examine this next.

 

Attachment

The rule for SMS messages is that the message body (that is, the text that you wish to send) is supplied to the Message object as an Attachment object and associated with it by calling addAttachment on the MessageBuilder object you originally used to created your Message object. It’s as simple as that. As you can see, when creating an Attachment, you can specify a MIME type. This is because, as we’ve already noted, the Message API is designed to handle messages, and therefore also attachments to messages, of a variety of types. For a standard SMS text message make sure you specify a MIME type of “text/plain”. If you use any other value you will probably find that your message is sent as an MMS (Multimedia Messaging Service) and this may have cost implications for your user.

 

MessageService

As the API documentation states, MessageService is an interface to the BlackBerry 10 messaging service. It provides a number of functions, including the ability to send, save and remove (delete) messages from specified accounts. We’re using it to send our message. Note that when sending a message in this way, it will be automatically saved and be visible in the user’s SMS folder.

 


  

Receiving user directed SMS messages

Receiving user directed SMS messages is very straightforward. The MessageService defines a number of signals, including messageAdded. This signal is emitted by a MessageService object whenever a new Message is saved into one of the MessageService folders. You can connect this signal to your own slot method and so receive keys to the Message, Account and Conversation relating to the message. An example should make this clear:

 

connect(_message_service, SIGNAL(
			messageAdded(bb::pim::account::AccountKey, bb::pim::message::ConversationKey, bb::pim::message::MessageKey)), SLOT(
			messageReceived(bb::pim::account::AccountKey, bb::pim::message::ConversationKey, bb::pim::message::MessageKey)));

Figure 6 - connecting to the MessageService messageAdded signal

 

In figure 6, we connect the messageAdded signal associated with an instance of MessageService to a slot, a method that we implement, called messageReceived. Signals and Slots are a feature of Qt by the way, if the terms are new to you. Qt is a key part of the native development environment for BlackBerry 10 too so it’s well worth reading more about these features.

 

Here’s what our messageReceived slot looks like: 

 

void SmsMessageService::messageReceived(
  bb::pim::account::AccountKey account_key, 
  bb::pim::message::ConversationKey conv, 
  bb::pim::message::MessageKey message_key) {

  Message message = _message_service->message(_sms_account_id, message_key);

  if (message.mimeType() == MimeTypes::Sms) {
		qDebug() << "XXXX messageReceived: It's an SMS!!!";
		if (message.isInbound()) {
			qDebug() << "XXXX sender:" << message.sender().displayableName();
			if (message.attachmentCount() > 0) {
				showToast("SMS received");
				bb::pim::message::Attachment attachment = message.attachmentAt(0);
				log(QString("RCVD: SMS\n").append("RCVD: from " + message.sender().displayableName()).append("\nRCVD: ").append(QString(attachment.data())));
			} else {
				qDebug() << "XXXX messageReceived: no attachments";
			}
		} else {
			qDebug() << "XXXX messageReceived: not inbound";
		}
	}  else {
		qDebug() << "XXXX messageReceived: not an SMS";
	}
}

Figure 7 - messageReceived slot handling “received” messages

 

The first, and perhaps most important, thing to appreciate about this signal/slot arrangement is that the slot method will be called for any and all messages that the MessageService adds to the user’s inbox, regardless of the folder it is stored in or the Account that it relates to. So, if you only want to process SMS messages you need to do some filtering in your code.

 

In the SmsMessageService app, we want to process only SMS messages. Luckily, the Message object has a MIME type and there’s a MIME type that specifically identifies a Message as an SMS message. 

 

You can see the check we’ve made:

 

message.mimeType() == MimeTypes::Sms

in the code fragment in Figure 7. 

 

Furthermore, we want to process only “inbound” messages, so we have a test for that too. For example, this ensures we do not process draft SMS messages that may have been composed by the user and saved without having been sent.

 

The SMS message body itself is in the first Attachment owned by the Message object. You can use the Attachment::data() method to extract the message payload as a byte array. You may have to do further processing against the payload to refine your selection  if you’re only interested in specific messages. I’ll leave that to you.

 


Delivery Receipts

SMS messages can be tracked once they’ve been submitted to the cellular network for delivery. This uses a capability known as “delivery receipts”. Not all networks support delivery receipts but certainly in the EMEA region, it’s unusual to find one that doesn’t. A delivery receipt is a special type of SMS message that is returned by the network to the device from which an SMS was sent. It indicates the current or final status of that message. For example, the simplest status that a delivery receipt can indicate is that the message was successfully delivered. 

 

Now, it may be that the person to whom you’re sending your SMS has their phone switched off and they’ve gone on holiday for 2 weeks. In this case your SMS message will not be delivered to them until they switch their phone back on, and you will not receive a delivery receipt until that happens. 

 

The point here is that delivery receipts do not get returned in real time. SMS is a “store and forward” system and the time that elapses between stages in the delivery of your message may sometimes be very substantial. That said, SMS messages are not stored forever by the network. They have a “validity period”. This represents the maximum time the network will store, and periodically attempt to deliver it. Once that validity period has expired, your message will be deleted. You may or may not receive a delivery receipt at this point, indicating that the message was not delivered. This behaviour may vary across networks. 

 

It’s also possible to receive more than one delivery receipt for a particular message. A delivery receipt can indicate a status that is temporary, whilst others are permanent and final. So it’s possible to receive one or more temporary, interim status indications followed by a final status delivery receipt.

 

It’s important to be aware of these various permutations of delivery receipts so that you can design your application to deal with them.

 

The BlackBerry 10 APIs allow your application to receive delivery receipts. The formal telecommunications specifications that cover SMS, calls delivery receipts “Status Reports” and this is the term used in the BlackBerry 10 APIs. In fact you’ll see that we have a class called StatusReport:

 

http://developer.blackberry.com/cascades/reference/bb__pim__message__statusreport.html

 

The network will not return delivery receipts for a message unless the message has a flag set, requesting this. Access to the setting of this flag is not currently available via the BlackBerry 10 APIs, however. Instead, this is controlled via a global Text Messages setting which you can access from Hub Settings. Either, all SMS messages are sent with the flag set to request delivery receipts or none are.

 

To receive StatusReport objects in an application you must connect a slot method to the messageUpdated signal as shown in Figure 8.

 

connect(_message_service, 
  SIGNAL(
    messageUpdated(bb::pim::account::AccountKey, 
                   bb::pim::message::ConversationKey, 
                   bb::pim::message::MessageKey, 
                   bb::pim::message::MessageUpdate)), 
  SLOT(
    messageUpdated(bb::pim::account::AccountKey, 
                   bb::pim::message::ConversationKey, 
                   bb::pim::message::MessageKey, 
                   bb::pim::message::MessageUpdate)));

Figure 8 - messageUpdated signal and slot connection

 

The messageUpdated signal is emitted whenever a Message changes. When a delivery receipt is received by the BlackBerry 10 device, it gets turned into a StatusReport object and added to the original Message object, which has a QList of these objects. Finally the signal is emitted. There are many types of message updates that could cause this signal to be emitted. The addition of a StatusReport object is not the only reason this may happen so your application is responsible for tracking the these changes and recognising whether a particular change is significant or not.

 

Here’s the messageUpdated slot from the SmsMessageService application, showing how we respond to messageUpdated signals:

 

void SmsMessageService::messageUpdated(bb::pim::account::AccountKey accountId, bb::pim::message::ConversationKey conversationId, bb::pim::message::MessageKey message_key,
		bb::pim::message::MessageUpdate data) {

// retrieve the Message object identfied by the MessageKey
	Message message = _message_service->message(_sms_account_id, message_key);

	if (message.mimeType() == MimeTypes::Sms) {
		qDebug() << "XXXX messageUpdated: It's an SMS!!!";
		if (message.attachmentCount() > 0) {
			QList<StatusReport> status_reports = message.statusReports();
			QList<StatusReport>::iterator i;
			if (status_reports.size() > 0) {
				showToast("Delivery receipt received");
				for (i = status_reports.begin(); i != status_reports.end(); ++i) {
					log(statusReportTypeName(i->type()));
					if (i->type() ==
                                        bb::pim::message::StatusReportType::DeliveryReport) {
						log(QString("Delivery Receipt --------"));
						log(i->address());
						log(i->date().toString("dd.MM.yyyy hh:mm:ss"));
						log(QString::number(i->status()).append(":").append(statusDescription(i->status())));
						log(QString("Delivery Receipt ++++++++"));
					}
				}
			}
		} else {
			qDebug() << "XXXX messageUpdated: no SMS body; no attachments";
		}
	} else {
		qDebug() << "XXXX messageUpdated: not an SMS message, no Attachments";
	}
}

 Figure 9 - messageUpdated slot

 

StatusReport objects have a status() method that returns an int value which identifies the meaning of the status report. For example a value of zero means your messages was successfully delivered whereas a value of 1 means that the message was forwarded to the destination device but there was no confirmation that it was delivered. 

 

sms_message_service.png

Figure 10 - SmsMessageService sending and receiving messages and delivery receipts

 

OK, so that’s quick look at the world of user directed SMS on BlackBerry 10. Now let’s turn our attention to “port directed SMS”.

 


 

Port Directed SMS

SMS messages can be associated with a numeric port number and applications can register to receive messages addressed to a given port. This is of course, analagous to the way TCP/IP servers listen on a particular port. When sending an SMS message, it is also possible to specify a destination port number. So when we use the term “port directed” we’re talking about SMS messages that are addressed to non-zero port numbers.

 

Port directed SMS messages are typically used only in special situations and, generally, would not involve interaction with the user. Port directed SMS messages will not appear in the user’s SMS folder. A common use for port directed SMS is as a means of delivering binary data to an application, over the air. For example, some applications use SMS as a mechanism for delivering provisioning or personalisation data In these cases, the message is usually constructed and submitted to the mobile network by a server application rather than another mobile device.

 

Port numbers are integer values. The range of available values are defined in specification ETSI TS 123 040 and there are addressing schemes for both 8 bits and 16 bits. You can use 8 bit values in the range 240 - 255 and 16 bit values in the range 16000 - 16999.

 

As you’ll see shortly, much of what’s involved in working with port directed SMS is exactly the same as when we work with user directed SMS. Let’s take a look at the differences.

 

Receiving port directed SMS messages

To accompany this part of the article, I wrote a sample application called SmsPortDirected and you’ll find a link to its location in GitHub at the end of this article. Code fragments used below come from that application.

 

When we’re working with port direct SMS, we use a class we didn’t use with user directed SMS. The class I’m referring to is:

 

bb::pim::message::SmsTransport

 

Typically, you’ll create an instance of SmsTransport in the constructor of your main class and then call its registerPort(<port number>) method to register your interest in receiving messages addressed to that port.

 

SmsPortDirected::SmsPortDirected(bb::cascades::Application *app) :
		QObject(app), _initialised_ok(false), 
               _sms_transport(new bb::pim::message::SmsTransport(this)) {

	QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this);

....
....
	connect(_sms_transport, 
                 SIGNAL(registerResultReceived(
                          unsigned int, 
                          bb::pim::message::SmsTransportRegistrationResult::Type)), 
               this,
		  SLOT(onRegisterResultReceived(
                        unsigned int,
                        bb::pim::message::SmsTransportRegistrationResult::Type)));

	connect(_sms_transport, 
                  SIGNAL(messageSendResultReceived(
                           bb::pim::message::MessageKey)), 
               this, 
                  SLOT(onMessageSendResultReceived(bb::pim::message::MessageKey)));

	connect(_sms_transport, 
                  SIGNAL(messageReceived (
                           unsigned int, 
                           const Message &)), 
               this, 
                  SLOT(onMessageReceived(
                         unsigned int, 
                         const Message &)));

....
	_sms_transport->registerPort(16000);

}

 Figure 11 - SmsTransport and port registration

   

SmsTransport has some signals that it can emit. The first one that SmsPortDirected uses is registerResultReceived. This signal is emitted when the call to registerPort(..) has been processed and the result is available. All we do in our connected slot is check that the registration was successful. Figure 12 shows how to do this. If your registration fails, it’s most likely that another application is already using this port. Registration is granted on a first come, first served basis.

 

The second signal of interest is messageReceived. By connecting this signal to a slot in our application we will receive messages addressed to the port in which we registered an interest. Figure 13 shows the code from SmsPortDirected that handles this event. 

 

void SmsPortDirected::onRegisterResultReceived(
         unsigned int port,
         bb::pim::message::SmsTransportRegistrationResult::Type status) 
{

	if (status == SmsTransportRegistrationResult::PortRegistered) {
		log(QString("Port %1 registered OK").arg(port));
	} else {
		log("Failed to register port:" + status);
		log("<b>Error:</b>" + getRegisterResultReceivedName(status));
	}
}

Figure 12 - slot method which handles port registration results

 

void SmsPortDirected::onMessageReceived(unsigned int port, const Message& message) {
	bb::pim::message::Attachment attachment = message.attachmentAt(0);
	hexlog(attachment.data());
}

 Figure 13 - the onMessageReived slot

 

Since Port directed SMS is often used for delivering binary data to an application I’ve just logged the received message payload in hex format in the SmsPortDirected application. Your application will need to be aware of the format of the messages it receives in order to be able to decode them. You should be aware that you will have no API access to the user data header indicator and so will not be able to use this in your decoding algorithm.

 


 

Decoding bytes received

 

In general, you should be aware of the following two rules for working with the ByteArray returned by SmsTransport.data():

 

1. Pure binary SMS messages (those whose Data Coding Scheme (DCS) attribute designate them as being binary) will be passed to your application, with any user data header (UDH) removed, but otherwise with the original byte values unchanged. So for example, the following Wireshark trace shows a message that was submitted from a desktop application using the SMPP protocol to my BlackBerry Q10. The DCS is 4, meaning “binary” and the message has a UDH indicating the message is addressed to application port 16,000 and a message payload of 0x01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F:

 

smpp_binary_port_16000_phone_number_hidden.jpg

 

The data() ByteArray contents are logged by SmsPortDirected as a hex string and we can see that the rule has been obeyed:

 

bb_app_received_binary.png

 

2. Text messages (i.e. those that are not designated as being binary via their Data Coding Scheme) will have any UDH removed and then the short message payload converted to UTF-8. The UTF-8 encoded bytes are passed to your application in the ByteArray returned by SmsTransport.data(). Here’s an example, again using a desktop application to submit a message via SMPP. The DCS is 8, meaning “Unicode”. SMPP requires that Unicode text be encoded using UCS2 by the way. And once again the message has a UDH indicating the message is addressed to application port 16,000. The payload is a mix of 4 Latin characters and Arabic characters; “ABCDלق” which has a UCS2 encoding of 0x 00 41 00 42 00 43 00 44 05 DC 06 42:

 

smpp_ucs2_port_16000_phone_number_hidden.jpg

 

Received by SmsPortDirected:

 

bb_app_received_ucs2_payload.png

 

Let’s check the result here:

 

I sent UCS-2 encoded text:

 

0x00 41 00 42 00 43 00 44 05 DC 06 42

 

The same text UTF-8 encoded is: 

 

0x41 42 43 44 D7 9C D9 82

 

SmsPortDirected received: 

 

0x41 42 43 44 D7 9C D9 82

 

Which is precisely what we expect given the stated rules :-)

  


 

Sending port directed SMS messages

Sending a port directed SMS message is very easy. The SmsTransport class has a send(...,...) method that takes a Message object and port number as parameters. Figure 14 shows this. 

 

 

void SmsPortDirected::sendMessage(const QString & text, const QString & destination_addr, const int port) {

	MessageBuilder* msg_builder = _sms_transport->createMessageBuilder();
	msg_builder->addAttachment(Attachment("text/plain", "", text));
	MessageContact recipient = MessageContact(-1, 
                                                  MessageContact::To, 
                                                  destination_addr, 
                                                  destination_addr);
	msg_builder->addRecipient(recipient);

	Message message;
	message = *msg_builder;

	_sms_transport->send(port, message);

}

 

Figure 14 - Sending a port directed SMS 

 

Port 0 indicates user directed!

You can use SmsTransport to send user directed SMS messages to. Specifying port 0 will send a message that *will* be received by the user and stored in their standard SMS folder as opposed to being routed to an application that has registered for that port. You may find this a convenient short cut of all you want to do is “fire and forget”.

 

port_directed_screen_shots.png

 

Figure 15 - SmsPortDirected screen shots

 

Receiving SMS Messages requires your application to be running

At the time of writing, for an application to be able to receive SMS messages, it must be running. In version 10.2 of the BlackBerry 10 OS, we expect to offer a new feature known as “Headless Applications” and so, this may change things in this respect.

  

 

http://developer.blackberry.com/native/downloads/roadmap/

 

 

  


Long or “concatenated” messages

 

You may be aware that SMS supports something known as “concatenation”. This is a mechanism which allows the user to send and receive messages whose payload is longer than 160 x 7 bit characters (or 70 x Unicode characters). This magic is achieved through the sending device splitting the “long” message text that the user enterer into a number of separate but linked message segments, each with its own sequence number and a reference number that indicates that they are all part of the same larger, logical message. On receipt of a series of these “concatenated message segments”, the receiving device’s SMS stack reassembles these segments, in the correct order of sequence number, into the long message that was originally formulated by the sender, for proper presentation to the recipient.

 

When sending longer than 140 byte messages, you don’t need to worry about concatenation. The APIs take care of the segmentation and concatenation process behind the scenes, so you are free to supply text that is longer than the expected maximum length for a single SMS message.

 

When receiving messages using the SmsTransport API, once again, the payload returned by Attachment.data() will contain the full payload derived by concatenating the complete set of individual message segments.

 

When receiving messages using the MessageService and Message APIs as described in the user directed SMS section of this article, the messageAdded signal will be emitted when the first segment is received by the stack and then messageUpdated will be emitted for each subsequent segment received. At each call to the slot you connected to messageUpdated, the Message object will have been updated to contain the full payload received so far.

 

 

MMS

 

The BlackBerry 10 APIs used to send and receive MMS messages are fundamentally the same APIs that you use for SMS and which we explored above. You work with the MessageService, create Message objects and address them to MessageContacts in exactly the same way as we have already seen. Message content is provided using the Attachment class.

 

And better still, the API will automatically decide whether to send a message as an MMS or an SMS without you needing to explicitly state this. So how does the API decide to send an MMS rather than an MMS?

 

Here are the key "triggers" which will cause a message to be sent as an MMS instead of an SMS:

 

1. If you add more than one Attachment object to your Message object it will be sent as an MMS. Note that adding two Attachment objects, each of which contains plain text will still result in an MMS being sent and not an SMS.

 

2. If you add a single, non-text Attachment to your Message it will be sent as an MMS.

 

3. if you address your message to an email address it will be sent as an MMS. Don't forget that you've selected the sms-mms account for use with the MessageBuilder so you're effectively saying "send to this email address using either SMS or MMS". Of course you'd have to ask yourself whether using MMS was the best and indeed most cost-effective way to send an email on a BlackBerry!

 

That's it. Simple.

 

Note that MMS messages can have a Subject which SMS messages cannot. The API lets you set a Subject value. 

 

 

	msg_builder->subject("This is the subject");

 

 

The messageAdded and messageUpdated signals both play the same part as they do for SMS. We check a different MIME type for MMS messages however:

 

 

	if (message.mimeType() == MimeTypes::Mms) {


 

 

It's worth noting that whereas SMS messages support delivery receipts, indicating the delivery (or otherwise) of an SMS, MMS messages support delivery *and* read reports. In each case they must be enabled by the user in the Settings application.

 

Finally, there's a subtle difference between SMS and MMS with respect to the messageAdded and messageUpdated signals which relate to the underlying way in which MMS actually works. MMS makes use of a special binary SMS message, usually invisible to the user, to indicate to the handset that an MMS has been addressed to it. At this point the multimedia content still resides on a server in the carrier's network. The SMS triggers the downloading of the multimedia content, automatically if the carrier thinks your handset type can process it, or you may simply receive a standard user directed SMS with a link the user can invoke to manually download the multimedia content if the carrier for some reason thinks you have a legacy handset that is not capable of automatically processing the content. The arrival of the initial SMS that signals the availability of multmedia content causes the messageAdded signal to be emitted. messageUpdated is emitted when the multimedia content has been automatically downloaded in response to the initial binary SMS.

 

The sample application MmsSample illustrates much of what has been described here.

 

 

The MmsSample Application

 

mms_sample_600.png 

Sending an MMS using the MmsSample application - numbers obfuscated

 

mms_received_from_app.png

 

What the MMS sent from the sample application looks like when received in the standard Text Messaging application on a BlackBerry Z10

 

 

 

 

Application Descriptor Issues

 

To use the Message and Account APIs in your application you need to indicate that permission to access SMS API functions will be required and that the user must grant this. To do so you must include the following line in your application’s bar-descriptor.xml file:

 

    <permission>access_sms_mms</permission>

Figure 16 - Permissions required for SML API use

 

Build Issues

Build Issues
To use the APIs featured in this article, you’ll also need to include the following in your project’s .pro file:

 

LIBS += -lbbpim

Figure 17 - Library referenced in .pro file

  

API References

You’ll find the APIs we’ve been exploring in the Cascades API reference:

 

http://developer.blackberry.com/cascades/reference/ 

 

Entering “Message” in the Filter box will help you navigate to the Message API quickly. 

 

Other sample applications

The “messages” application in the Cascades-Samples repository provides a further example of use of the Message and Account APIs. It is not specifically focused on SMS but you may still find it useful.

 

https://github.com/blackberry/Cascades-Samples/tree/master/messages

 


 

Summary

 I hope that this article helps you make use of SMS in your BlackBerry 10 applications.

 

You can download MmsSample, SmsMessageService and SmsPortDirected, including full source code from:

 

https://github.com/blackberry/Cascades-Community-Samples 

 

All applications were written for the BlackBerry 10 Z10 and Q10 devices and the following versions of the NDK and device software should be used to build and run them:

 

  • BlackBerry 10 Native SDK version 10.2.0 and above
  • BlackBerry 10 Software version 10.2.0 and above

A video presentation covering the same topics and including demonstrations of both the SmsMessageService and the SmsPortDirected applications is available in the YouTube BlackBerry Developer channel:

 

http://youtu.be/XNGDLiHw-HE 

  

You can contact Martin either through the BlackBerry support forums or through Twitter®:

 

 

  Support Forum ID Twitter
Martin mwoolley @mdwrim

 

 

 

Contributors
Comments
by New Developer on ‎09-03-2013 01:35 PM

Good post :Clap:. Keep sharing like this.