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.
Wednesday, December 12, 2007
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:
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.]
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\TimeoutsThe 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.
Value: BattSuspendTimeout
Type: DWORD
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);
wmp.controls.playItem(media);
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.
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);
wmp.controls.playItem(media);
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.
Subscribe to:
Posts (Atom)