Wednesday, December 12, 2007

The WM6 Endless Reboot Cycle

Apparently, I became a victim of a common Windows Mobile 6 bug today. A problem with using an SD storage card can get Windows Mobile 6 into a state where it continuously reboots.

A Google search helped me determine the problem was related to the SD card and removing the card allowed the device to boot normally. However, when I powered down and reinserted the SD card, the device went back to its endless reboot cycle again. (Not all users experience this problem after reinserting the storage card, but some do.) A little more investigation was required.

I decided to boot the device without the SD card - success. Without rebooting, I inserted the SD card and opened File Explorer. I noticed the storage card was labeled as "Storage Card2" instead of the usual "Storage Card". WM6 had created a "Storage Card" folder on its own when I booted without the card to store message attachments. I deleted the "Storage Card" folder (which only contained empty folders) and rebooted. I was back in the reboot cycle. Ugh!

I removed the SD card again and booted. This time I deleted the "Storage Card" folder before inserting the SD card. I inserted the SD card and WM6 recognized it as "Storage Card". I rebooted, and... The OS booted correctly.

It's quite strange that this happened in the first place, but I offer my findings here to help anyone else who may run into the problem with WM6 and SD storage cards.

Friday, December 7, 2007

Stopping Time

As mentioned in a previous post, Mobile Stopwatch uses System.Environment.TickCount as a timer reference. If you record the TickCount value when the stopwatch starts, the elapsed time can be calculated by subtracting the initial TickCount value from the current TickCount value. The only problem with this method occurs when a Windows Mobile device goes into suspend mode and TickCount is not updated. Suspend mode effectively stops the stopwatch and it is restarted when suspend mode ends.

One solution to this problem is to prevent the device from entering suspend mode while the stopwatch is running. It turns out this is a rather simple thing to do since the Windows Mobile SDK provides us with an API for resetting the device's idle timer:
void WINAPI SystemIdleTimerReset(void);
Periodically calling this function will prevent a Windows Mobile device from suspending - we only need to determine how often this function needs to be called. Fortunately, the registry holds this information at the following key location:
Key: HKLM\SYSTEM\CurrentControlSet\Control\Power\Timeouts
Value: BattSuspendTimeout
The value stored here indicates the number of seconds that must elapse before the device enters suspend mode. As long as you call SystemIdleTimerReset() more frequently than this timeout value, the device will not suspend and TickCount will keep updating.

The down side of this solution is that your battery life will suffer if the stopwatch needs to run for long periods of time. I'll present a solution that resolves that dilemma in a future posting.

Note, it is still possible to turn off the display by pressing the device's power button, but this shouldn't be confused with the device entering a suspended state.

[As a side note, suspend mode is only an issue on Windows Mobile Professional. Windows Mobile Standard doesn't enter suspend mode, but only turns off the display.]

Wednesday, December 5, 2007

Office Mobile 6.1 Upgrade

If you need to access Office 2007 file formats on your mobile device, you can upgrade to Office Mobile 6.1 here. (An existing version of Office Mobile is required.)

Monday, December 3, 2007

Media on the Move

TV recordings, music, podcasts - with Windows Mobile 6 (WM6) you can pack it all up and take it with you on the road. Windows Media Player (WMP) is provided to handle a variety of media formats. The mobile player is very similar to the desktop player and is a suitable playback application.

I first started using WMP to take some podcasts on the road. I could sync the MP3 files to my device and enjoy them while traveling. However, this process required:

1) downloading the podcast on my PC,
2) syncing with my device,
3) listening to the podcast, and
4a) deleting the files I already played, or
4b) archiving the files on my PC if there was something I wanted to keep.

Windows Media Player is sufficient for this, but it's not really efficient. I wanted an application to streamline the whole process.

Fortunately, it's not necessary to write an entire player from the ground up. Microsoft has implemented Windows Media Player as a control that can be used in any application - WMP without the user interface. This allows anyone to write their own UI around the core media player.

I decided to use the WMP control from within a .NET CF application written in C#. Using Visual Studio, I created a C# project and added a COM reference for the WMP control. The COM control is listed as "Windows Media Player" and the path is "wmp.dll" in the \Windows\system32 directory. Because the interfaces for the mobile and desktop controls are identical, you can simply reference the desktop DLL and the Interop.WMPLib reference will be compatible with WMP on your mobile device.

Creating and using the media player simply requires:

WindowsMediaPlayerClass wmp = new WindowsMediaPlayerClass();
IWMPMedia media = wmp.newMedia(pathName);

It's that easy.

However, you will find that when you instantiate WindowsMediaPlayerClass on your mobile device your application will not shutdown properly. To confirm this all you need to do is create a new application and in the main Form's Load event call:

mWMP = new WindowsMediaPlayerClass();

Add a menu item that will call the Form's Close() method and run the application in the Windows Mobile emulator. Set a breakpoint after the application's Run loop exits in the Main() function (see Program.cs). After the Close() method is called, you'll see the run loop exits and you can step through the rest of the Main() function to see it exits cleanly, but the application will never shutdown. My guess is there is a thread created by the WMP control and WM6 is waiting for that thread to exit.

As a workaround, you can simply call:

TerminateProcess(0x42, 0);

at the end of Main(). This will force the process to shutdown. Provided you don't have any global objects that need to always shutdown cleanly, you can successfully terminate your application. The Visual Studio debugger will report that it has lost communication with the application, but your application won't run indefinitely on your mobile device.

Have you run into this same problem? Share your solution in a comment.

I'll share some of my other experiences with the WMP control in future posts.

Monday, November 26, 2007

The Missing Stopwatch and the Missing Milliseconds

While I've benefited tremendously from having my T-Mobile Wing, one of the things it's missing is a convenient stopwatch feature. My old cell phone provided a nice stopwatch, but there's nothing like this on the Wing. Even my Garmin GPS has a stopwatch feature, so I figure my cell phone should get one too.

This seems like a simple enough project and an excellent opportunity to jump into writing a C# project on the .NET Compact Framework. Well, the first thing I found out was that the DateTime object's Milliseconds property is always zero on a T-Mobile Wing. Some quick web searching revealed that this isn't a Wing peculiarity, but a lot of Windows CE devices don't provide millisecond resolution for calls to GetLocalTime() (which is ultimately beneath .NET's DateTime class).

A nice summary of alternatives can be found here. The simplest solution is to use System.Environment.TickCount to simply get the number of milliseconds that have passed since the operating system started. The only caveat is that the TickCount is suspended when the system goes into suspend mode. So if your device suspends, your stopwatch will stop ticking. However, for my needs this is sufficient for the time being. I'll look at workarounds in the future if I should need one.

Mobile Stopwatch can be found in the Mobile Tools download from this blog.

Switching to Windows Mobile

About six months ago I decided my Virgin Mobile prepaid cell phone was beginning to cost enough each month that I should look at a fixed price alternative. With the upgrade I was also hoping to add some new features to my phone.

I wanted to sync contacts and appointments with Outlook, so some kind of Palm/Blackberry/Windows Mobile device was worth investigating. Since I have a background developing software for Windows desktop operating systems, I figured with a Windows Mobile device and Microsoft Visual Studio I could learn a new development environment.

After some web searching I found I could get a pretty nice Windows Mobile 6 Professional device from T-Mobile for $99 (current offers can be found here) and my prepaid plan was history. I'll be blogging here about my experiences with Windows Mobile from both a user and developer perspective.