Over a million developers have joined DZone.

Sending text messages from a Dell Venue Pro. Directly from the app and without SmsComposerTask.

DZone's Guide to

Sending text messages from a Dell Venue Pro. Directly from the app and without SmsComposerTask.

· Mobile Zone ·
Free Resource

You probably know of the good old way to send SMS messages on a Windows Phone device. Invoking SmsComposerTask lets you pre-fill existing data and simply tell the user that the data is ready to be sent wherever he wants. This requires a system component (the messaging application) to be invoked. There is a way around the default system invocation, that allows the developer to send SMS from the application itself, even if the user did not agree to this.

To do this, I rely on AT commands – a command set that allows communicating with the phone modem on various levels. OurCOM.dll (the native connector on Dell Venue Pro) carries an implementation that allows execution of AT commands against the built-in modem directly from the phone:

state = State.INITIATING;

Result r = tm.SendCommand("EM:ATCMD_REQUEST:AT+CMGF=1;", 1, false);

tm.StartPolling("EM:ATCMD_GET;", new PollingDataHandler(this.handler), 200); 

By the way, I am still using the default COM connection implementation here that I described in the very first article on this topic.

ATCMD_REQUEST seems to be the hook here. AT+CMGF=1 will set the modem in text-only mode. Ultimately, you can enable PDU mode as well – it will work as long as you are using the PDU transmission format (with proper encoding). The handler is a parser of the results returned by the native layer:

private void handler(Result result)
string str = COMHelper.RestoreKeywords(result.Content);
if (str != "")
string[] strArray = str.Split(new char[] { '\n' });
if (strArray.Length >= 2)
if (state == State.NUMBER_SET)
state = State.SENT;
Result r = tm.SendCommand("EM:ATCMD_REQUEST:" + txtText.Text + (char)26 + ";", 1, false);
tm.StartPolling("EM:ATCMD_GET;", new PollingDataHandler(this.handler), 200);
else if ((state == State.INITIATING) || (state == State.SENT))

There is a state variable here, that defines which state the current operation is in. It is nothing else but an enum:

public enum State

For convenience purposes, whenever I am running the first AT command to set the modem in text-only mode, I am setting the state as INITIATING. After the initialization is complete, I stop the polling process – it will also stop once the message is sent.

You might be wondering – if there is a request for an AT command, why do I start polling with ATCMD_GET? The answer is simple – to get the response from the command to see whether it was successful or not. Also, as you will see next, some commands require multiple requests.

I created a simple application that has a field for the phone number as well as a field for the text message itself:


The sending process is initiated through AT+CMGS, that accepts the phone number as the first parameter. For correct processing, the number should be surrounded by double quotes. Here is how the request snippet looks like:

state = State.NUMBER_SET;

Result r = tm.SendCommand("EM:ATCMD_REQUEST:AT+CMGS=\"" + txtPhoneNumber.Text + "\"\n;", 1, false);

tm.StartPolling("EM:ATCMD_GET;", new PollingDataHandler(this.handler), 200); 

Once polling starts, if the number is set – the modem will be waiting for the message. If you’ve ever used the hyperterminal, you know that once AT+CMGS is invoked, a > character will be shown. That way, the user can type the message and once he is done, he just has to press Ctrl+Z to send it. Take a look at the handler once again – since I am not able to directly invoke keystrokes on the phone, I am passing the char value Ctrl+Z would insert at the end of the message. That way, my message will be sent.

NOTE: If Ctrl+Z is not passed, the modem will be in constant state of waiting for more message content.


Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}