State Notification in Windows Mobile 5.0

author-image
PCQ Bureau
New Update

In the earlier issues of PCQuest, we have already discussed SMS Interception
support in Windows Mobile 5.0 and how we can build applications that can
intercept the incoming SMS and perform some custom tasks. Now, there are also
scenarios where in you would like your mobile application to perform some task
when a system condition is true. For eg, if you get a missed call, you would
like an application to automatically send an SMS to the caller with a preset
message. Another scenario could be if the battery power levels go low, you may
want to hibernate your application state until the device is charged.

Direct
Hit!
Applies
to:
Windows Mobile 5.0 developers
USP:
Use the State and Notification Broker for custom application behavior when system state changes
Links:
http://msdn.microsoft.com/mobility/
Google
keywords:
state notifcation, Win Mobile 5.0
On PCQ Professional CD: systems\cdrom\developers\2006-08 source code

Windows Mobile 5.0 has introduced a new component called the State and
Notification Broker that allows your applications to be registered with it for a
given state change and when the state change happens, your code will be
automatically invoked. In this article, we introduce the State and Notification
Broker, how it works and what goes into writing an application that leverages it
to do something useful.

Introducing the State Notification Broker

Different Windows Mobile applications store their state information at different
locations, including the core system state details such as number of missed
calls, number of unread e-mail, etc. The problem with this approach is that if
another application wishes to leverage this information to perform a custom
task, it would not know where to look for the information and what all kinds of
information would be available for it.

To solve this problem, Windows Mobile 5.0 has introduced the State and
Notification Broker. According to this:

  • There will be documented locations in the Windows CE registry where the
    information can be published by the source of state change.
  • Windows Mobile 5.0 will provide a set APIs that will monitor the changes
    published in the registry locations.
  • Applications that wish to know about a state change will register with the
    OS using the APIs and will be invoked (or have their code called) when the
    state change takes place.
The
architecture of the State Notification Broker lets the Windows Mobile
developer use its API in eVC++ or .NET (compact) applications

These APIs are available in the native form (for development using eVC++) and
also in managed form (when writing applications for the .NET Compact Framework).
Architecturally, the State and Notification Broker looks as shown in the
adjoining figure.

The entire functionality is based on the Microsoft.WindowsMobile.Status
assembly that contains a namespace with the same name which needs to be
referenced in your application. There are a whole lot of states about which the
application can be notified.

The SystemProperty class encapsulates most of these states, ranging from new
incoming e-mail or SMS to missed phone calls to signal strenght and so on. The
best way to understand this would be to write an application that leverages this
functionality.

Understanding AutoReply

AutoReply is an application that is invoked by Windows Mobile 5.0 in a case
someone calls you on your phone and you miss the call. It sends an SMS to the
caller informing about your unavailability. You can also customize the message
to be sent. We start off by building a Windows Mobile 5.0 PocketPC application.

You will need VS 2005 and the PocketPC 5.0 SDK installed. You can download
the SDK from http://www.microsoft.com/downloads/details.aspx?FamilyID=83a52af2-f524-4ec5-9155-717cbe5d25ed&DisplayLang=en.
Once everything is installed, we design the UI as shown in the figure above.

The textbox will contain the custom message to be sent and the 'SaveAutoReply
Message' button implementation will be used to persist the custom message on
the device. The code for this implementation looks like this.

Clicking on
the Activate button will let the app receive notifications when new
messages/calls arrive

private bool SaveAutoReplyMessage()

{

TextWriter fsAutoReply = null;

string strCurPath = GetCurrentPath();

try

{

fsAutoReply = File.CreateText(strCurPath+"AutoReply.txt");

}

catch (Exception ex)

{

return false;

}

// Save the message to the file

fsAutoReply.Write(txtAutoReplyMessage.Text);

strAutoReplyMessage = txtAutoReplyMessage.Text;

fsAutoReply.Close();

fsAutoReply = null;

return true;

}

The 'GetCurrentPath' method is the crucial one as it helps calculate the
path to application's folder on the device. The code for that is:

// Returns the executing assembly path

private string GetCurrentPath()

{

System.Reflection.Module curMod = (System.Reflection.Assembly.GetExecutingAssembly().GetModules())<0>;

int iLastSlashPos = curMod.FullyQualifiedName.LastIndexOf("\\");

return curMod.FullyQualifiedName.Substring(0, iLastSlashPos+1);

}

Activating the notification

The real crux lies in the Activate button implementation. Since we want to be
notified when there's a missed call , we use the

'SystemProperty' class to inform the 'State and Notification Broker'
about it, as shown below.

if (btnActivate.Text.IndexOf("Activate")
!= -1)

{

// Setup the missed call handler

stateMissedCall = new SystemState(SystemProperty.PhoneMissedCall);

stateMissedCall.Changed += new
ChangeEventHandler(stateMissedCall_Changed);

stateMissedCall.EnableApplicationLauncher(strAppID);

btnActivate.Text = "&Deactivate";

MessageBox.Show("Autoreply activated!");

}

else

{

// Deactivate the missed call handler..

SystemState.DisableApplicationLauncher(strAppID);

btnActivate.Text = "&Activate";

MessageBox.Show("Autoreply deactivated!");

}

The 'SystemState' class is the managed API that informs the State and
Notification Broker about what state we want to be notified about. The
SystemProperty representing the state (we are interested in getting notified
about) is passed as an argument to the SystemState constructor. Next, we wire up
to the 'ChangeEventHandler' that will be invoked whenever the state changes.

We also invoke 'EnableApplicationLauncher' method against the SystemState
instance. This registers our application with the State and Notification Broker
such that even if your application is not running, it will be invoked whenever
the state change is detected and your event handler invoked.

To disable this registration, we invoke the 'DisableApplicationLauncher'
method.

The ChangeEventHandler checks whether there is a missed call and if so, we
attempt to send them an SMS, with the custom message that was saved by the user.
The code for this application looks like:

// When a missed call happens, this code gets
invoked

void stateMissedCall_Changed(object sender, ChangeEventArgs args)

{

// Did we miss a call?

object objMissed = args.NewValue;

bool bMissed = ((int)objMissed == 0) ? false : true;

if (bMissed == false)

return;

Contact cntCaller = SystemState.PhoneLastIncomingCallerContact;

string strCallerNumber = SystemState.PhoneLastIncomingCallerNumber;

// Send an SMS to them

SmsMessage sms = new SmsMessage();

// If we got the contact details from POOM, then use cell

// from there, else use the incoming caller number

if ((cntCaller != null) && (cntCaller.MobileTelephoneNumber != null))

sms.To.Add(new Recipient(cntCaller.MobileTelephoneNumber));

else if (strCallerNumber != null)

sms.To.Add(new Recipient(strCallerNumber));

else

return;

sms.Body = strAutoReplyMessage;

sms.Send();

}

The ChangeEventHandler gets an argument of the type 'ChangeEventArgs'
that has a 'NewValue' property. In case of true/false checks (eg, our
scenario where we want to check if there was a missed call or not), it will
contain a 0 (zero) for false and 1 (one) for true.

If there is a missed call, we use the SystemState class's 'PhoneLastIncomingCallerContact'
property to extract POOM (Pocket Outlook Object Model) Contact object for the
caller and then extract his cellphone number. If the Contact object is not
available, we use SystemState class's 'PhoneLastIncomingCallerNumber'
property to get the phone number from which the missed call was received.

Once we have the phone number, we use the 'SmsMessage' class (based on
Microsoft.WindowsMobile.PocketOutlook) to create a SMS and send it to the number
from which the call came. And we have AutoReply working for us!

To sum up

State and Notification Broker enables scenarios for conditional application
development that were not possible before.

Not only that, you can author your own custom states to which applications
can subscribe to and be notified when those states change. This article is
accompanied with the source code of AutoReply application to help you understand
the concept better.

Stay connected with us through our social media channels for the latest updates and news!

Follow us: