390 likes | 558 Views
New Managed Messaging, State, And Notification APIs In Windows Mobile 5.0. Robert Levy (rlevy@microsoft.com) Program Manager Windows Mobile Developer Experience. Here’s What We’ll Cover. Lots of Brand New Managed APIs Only for Windows Mobile 5.0 .NET Compact Framework 1.0 or 2.0
E N D
New Managed Messaging, State, And Notification APIs In Windows Mobile 5.0 Robert Levy (rlevy@microsoft.com)Program Manager Windows Mobile Developer Experience
Here’s What We’ll Cover • Lots of Brand New Managed APIs • Only for Windows Mobile 5.0 • .NET Compact Framework 1.0 or 2.0 • Capabilities • Usage • Common mistakes • Lots of code snippets
Successful mobile applications are designed for mobile users
Initiate Calls With Phone.Talk • Get properties and events through theState & Notification Broker Dim phone As New Phone phone.Talk( “425-555-1212” )
It All Starts At OutlookSession OutlookSession outlook = new OutlookSession(); int contactCount = outlook.Contacts.Items.Count;
Folders And Collections • One folder per type • Each has a collection • Enumerate items • Check capabilities • Sort & Filter • Add & Remove • ListChanged event
Appointments, Contacts, And Tasks • Lots of properties and events • Don’t forget Update() OutlookSession outlook = new OutlookSession(); Contact me = new Contact(); me.FullName = “Robert Levy”; outlook.Contacts.Items.Add( me ); // <-- Saved me.JobTitle = “Program Manager”; me.Update(); // <-- Saved
Items Can Be Shown In Outlook Mobile With ShowDialog Appointment appt = new Appointment(); appt.Subject = "Launch Windows Mobile 5.0!"; appt.AllDayEvent = true; appt.Start = new DateTime(2005, 5, 10); outlook.Appointments.Items.Add(appt); appt.ShowDialog();
Add Your Own Properties To PIM Items • See if the property has been defined • If not, define it • Use it Contact myCustomer; // ... if(!myCustomer.Properties.Contains(“Employee ID”)) { myCustomer.Properties.Add("Employee ID", typeof(string)); } myCustomer.Properties["Employee ID"] = "ABC1234";
Working With Item IDs • Store references to items by their ID • Retrieve items by their ID Contact c; // … string idString = c.ItemID.ToString(); string idString; // … Read idString from a file, registry, or database int idNumber = Int32.Parse( idString ); ItemID id = new ItemID( idNumber ); Contact c = new Contact( id );
Sending E-Mail And SMS SmsMessage msg = new SmsMessage(); msg.To.Add( new Recipient(“555-1212")); msg.Body = “Hello World!"; msg.Send();
Attach Files to E-mail Messages EmailMessage msg = new EmailMessage(); msg.Attachments.Add(new Attachment(@“\Stuff.doc") );
Contacts Are Not Recipients Contact myCustomer; // ... EmailMessage msg = new EmailMessage(); msg.To.Add( myCustomer );// Won’t compile! msg.To.Add( new Recipient( myCustomer.Email2Address ) ); // OK
Control The Messaging Application • Display the compose form • Display the inbox • Initiate synchronization
Intercept SMS Messages In Managed Code MessageInterceptor sms; void Form_Load( ... ) { sms = new MessageInterceptor(); //... Set optional properties here sms.MessageReceived += new EventHandler(sms_MessageReceived); } void sms_MessageReceived(...) { //... Handle incoming message }
Specify What Happens to Intercepted Messages MessageInterceptor sms; void Form_Load( ... ) { sms = new MessageInterceptor(); sms.InterceptionAction = InterceptionAction.NotifyAndDelete; sms.MessageReceived += new EventHandler(sms_MessageReceived); } void sms_MessageReceived(...) { //... Handle incoming message }
Intercept SMS Messages In Native Code //================================================================= // MonitorThread - Monitors event for timer notification // DWORD WINAPI MonitorThread (PVOID pArg) { TEXT_PROVIDER_SPECIFIC_DATA tpsd; SMS_HANDLE smshHandle = (SMS_HANDLE)pArg; PMYMSG_STRUCT pNextMsg; BYTE bBuffer[MAXMESSAGELEN]; PBYTE pIn; SYSTEMTIME st; HANDLE hWait[2]; HRESULT hr; int rc; DWORD dwInSize, dwSize, dwRead = 0; hWait[0] = g_hReadEvent; // Need two events since it isn't hWait[1] = g_hQuitEvent; // allowed for us to signal SMS event. while (g_fContinue) { rc = WaitForMultipleObjects (2, hWait, FALSE, INFINITE); if (!g_fContinue || (rc != WAIT_OBJECT_0)) break; // Point to the next free entry in the array pNextMsg = &g_pMsgDB->pMsgs[g_pMsgDB->nMsgCnt]; // Get the message size hr = SmsGetMessageSize (smshHandle, &dwSize); if (hr != ERROR_SUCCESS) continue; // Check for message larger than std buffer if (dwSize > sizeof (pNextMsg->wcMessage)) { if (dwSize > MAXMESSAGELEN) continue; pIn = bBuffer; dwInSize = MAXMESSAGELEN; } else { pIn = (PBYTE)pNextMsg->wcMessage; dwInSize = sizeof (pNextMsg->wcMessage); } // Set up provider specific data tpsd.dwMessageOptions = PS_MESSAGE_OPTION_NONE; tpsd.psMessageClass = PS_MESSAGE_CLASS0; tpsd.psReplaceOption = PSRO_NONE; tpsd.dwHeaderDataSize = 0; // Read the message hr = SmsReadMessage (smshHandle, NULL, &pNextMsg->smsAddr, &st, (PBYTE)pIn, dwInSize, (PBYTE)&tpsd, sizeof(TEXT_PROVIDER_SPECIFIC_DATA), &dwRead); if (hr == ERROR_SUCCESS) { // Convert GMT message time to local time FILETIME ft, ftLocal; SystemTimeToFileTime (&st, &ft); FileTimeToLocalFileTime (&ft, &ftLocal); FileTimeToSystemTime (&ftLocal, &pNextMsg->stMsg); // If using alt buffer, copy to std buff if ((DWORD)pIn == (DWORD)pNextMsg->wcMessage) { pNextMsg->nSize = (int) dwRead; } else { memset (pNextMsg->wcMessage, 0, sizeof(pNextMsg->wcMessage)); memcpy (pNextMsg->wcMessage, pIn, sizeof(pNextMsg->wcMessage)-2); pNextMsg->nSize = sizeof(pNextMsg->wcMessage); } // Increment message count if (g_pMsgDB->nMsgCnt < MAX_MSGS-1) { if (g_hMain) PostMessage (g_hMain, MYMSG_TELLNOTIFY, 1, g_pMsgDB->nMsgCnt); g_pMsgDB->nMsgCnt++; } } else { ErrorBox (g_hMain, TEXT("Error %x (%d) reading msg"), hr, GetLastError()); break; } } SmsClose (smshHandle); return 0; }
Create smart mobile apps with the State & Notification Broker
Why Is This So Hard? • Problems • Different APIs for querying different properties • Different change notification mechanisms for different properties • Many properties not exposed (especially in .NET CF) • No standard way for OEMs and ISVs to expose their own properties
State And Notification Broker Strategy • Placement of useful information in documented registry locations • Native APIs to get notified of changes to any registry value • Managed wrapper around native APIs
State And Notification Broker Design Microsoft.WindowsMobile.Status RegExt.h SNAPI.h Interesting Values Registry
There Are Over 100 System Properties • Power & Battery • Appointments • Media Player • Connectivity • ActiveSync • Messaging • Telephony • Hardware • Tasks • Shell
Get Change Notifications • Create a SystemState object • Attach an event handler SystemState callerId = new SystemState( SystemProperty.PhoneIncomingCallerContact); callerId.Changed += new EventHandler(callerId_Changed); void callerId_Changed(object sender, ChangeEventArgs e) { Contact caller = (Contact)callerId.CurrentValue; // ... }
Two Ways To Query For Current Values • Static Strongly typed, quick and easy • Dynamic Contact c = SystemState.PhoneIncomingCallerContact; SystemState callerId = new SystemState( SystemProperty.PhoneIncomingCallerContact); Contact c = (Contact)callerId.CurrentValue;
The State And Notification Broker Is Extensible • Publish your own state • Get notified of changes to any registry value
Get Notified While Your Application Is Not Running • Can be used for • SMS Interception • State and Notification Broker • When a change occurs • Windows Mobile launches the application • Application hooks up an event hander • Event is fired
App Launching With The State & Notification Broker SystemState missedCall; void Form_Load( … ) { if(!SystemState.IsApplicationLauncherEnabled(“MyApp.MissedCall”)) { missedCall = new SystemState( SystemProperty.PhoneMissedCall ); missedCall.EnableApplicationLauncher( “MyApp.MissedCall” ); } else { missedCall = new SystemState(“MyApp.MissedCall”); } missedCall.Changed += new EventHandler( missedCall_Changed ); }
App Launching With The SMS Interception MessageInterceptor sms; void Form_Load( … ) { if(!MessageInterceptor.IsApplicationLauncherEnabled(“MyApp.SMS”)) { sms = new MessageInterceptor(); sms.EnableApplicationLauncher( “MyApp.SMS” ); } else { sms = new SystemState(“MyApp.SMS”); } sms.MessageReceived += new EventHandler( sms_MessageReceived ); }
Conditions Prevent Unnecessary Notifications • Very important for app-launching notifications! • Comparison Types:
Setting Conditions With The State & Notification Broker SystemState missedCall; void Form_Load( … ) { // … missedCall = new SystemState( SystemProperty.PhoneMissedCall ); missedCall.ComparisonType = StatusComparisonType.Equal; missedCall.ComparisonValue = true; missedCall.Changed += new EventHandler( missedCall_Changed ); }
Setting Conditions WithSMS Message Interception MessageInterceptor sms; void Form_Load( ... ) { sms = new MessageInterceptor(); sms.MessageCondition.Property = MessageProperty.Body; sms.MessageCondition.ComparisonType = MessagePropertyComparisonType.Equal; sms.MessageCondition.ComparisonValue = “1234"; sms.MessageReceived += new EventHandler(sms_MessageReceived); }
Volatile Registry KeysPrevent Invalid Data • Problem: • IM client publishes a “number of online contacts” value in the registry. User logs in and this gets set to 15. Device is reset so user is no longer logged in. Value in the registry (15) is no longer accurate. • Solution: Volatile Registry Keys • Just like regular registry keys except they die when the device turns off • Better performance • Always in RAM • Never flushed to persistent storage
WindowsMobile.Telephony Initiate phone calls WindowsMobile.PocketOutlook Edit Contacts, Appointments, and Tasks Control the Messaging application Send SMS & email messages WindowsMobile.PocketOutlook.MessageInterception Intercept incoming SMS messages WindowsMobile.Status Query 100+ system properties Get notified of changes Namespace Summary
Other Managed APIs in WindowsMobile 5.0 WindowsMobile.Configuration • Configuration Manager WindowsMobile.Forms • Contact Picker Dialog • Picture Picker Dialog • Camera Capture Dialog
Other Resources • Windows Mobile 5.0 SDK • http://msdn.microsoft.com/mobility/ • Windows Mobile Team Blog • http://blogs.msdn.com/windowsmobile • Migration FAQ for Developers • http://msdn.microsoft.com/library/en-us/dnppcgen/html/migration_developers_faq.asp • Newsgroups • microsoft.public.pocketpc.developer smartphone.developer dotnet.framework.compactframework
© 2005 Microsoft Corporation. All rights reserved. MICROSOFT CONFIDENTIAL. INTERNAL USE ONLY.