Power-Efficient applications on Windows Mobile
Sometimes it happens that a developer asks for suggestions about how to design an application from the very beginning so that it'll be power-efficient, and therefore I now have a list of links\suggestions that may be interesting to share...
- First of all, if you want to see some code in action you should start from the SDK sample "PowerManager": it "[...] Demonstrates how an application can use the Power Manager APIs to register for power notifications, set minimum device power requirements, and get and set the system power state. "
- Read section "Writing a Power-Efficient Application" of the MSDN article Effective Memory, Storage, and Power Management in Windows Mobile 5.0 (and in general the whole article is a must for mobile developers and architects)
- If you like videos:
- MSDN Webcast: Writing Power-Efficient Applications for Windows Mobile (yes, it's 200 - but it's worth as introduction)
- How Do I: Programmatically Monitor for a Specific Time of Day Without Draining a Device Battery? ("[...] The technique shown in this video is power-efficient and avoids the rapid battery drain created by commonly used techniques.")
- From Windows Mobile Dev Team, there have been some interesting posts in the past -- and asnwers to some comments as well! -- about power-management:
- Section "Application Interface to the Power Manager" of An In-Depth Look at the Power Manager in Windows CE .NET 4.1 (note that the Power Manager component was firstly introduced on Windows CE 4.1, and the same concepts still apply to every version of Windows Mobile)
- Sections "Basic Power—Applications" and "Enhanced Power Management—Applications" of Power Management Features of Windows CE .NET
- In some cases you may want to perform an action only if the display is turned on (for example refresh a smartphone's home plugin). You can use GetSystemPowerState():
DWORD PwrFlag, NameLength; TCHAR StateName[64] = { 0 }; GetSystemPowerState(StateName, NameLength, &PwrFlag); if(POWER_STATE_ON != PwrFlag) //perform action only if display is on. //for example, in case of Home plugins: InvalidateRect(hPlugInWnd, NULL, TRUE);
- Or the application may listen on Activity Timers through the State&Notification Broker to perform tasks only when necessary.
- In some cases you may want to turn off only the display when performing some actions - I knew a solution based on ExtEscape API (see old Alex Feinmain's managed sample) and thought that this was supported for OEMs only, however looking at the official doc it's for ISV Application Developers as well (in any case, note that "[...] The device capabilities this function accesses must be implemented by an OEM. ", thus meaning that you can see different behaviors on different devices):
HDC gdc = ::GetDC(NULL); VIDEO_POWER_MANAGEMENT vpm; vpm.Length = sizeof(VIDEO_POWER_MANAGEMENT); vpm.DPMSVersion = 0x0001; vpm.PowerState = VideoPowerOff; // Power off the display ExtEscape(gdc, SETPOWERMANAGEMENT, vpm.Length, (LPCSTR) &vpm, 0, NULL); Sleep(5000); //just for demonstration purposes vpm.PowerState = VideoPowerOn; // Power on the display ExtEscape(gdc, SETPOWERMANAGEMENT, vpm.Length, (LPCSTR) &vpm, 0, NULL); ::ReleaseDC(NULL, gdc);
- You may want to have applications continue running when the device is suspended. This is simply not possible, as the processor is in idle state and doesn't offer any CPU cycle to be used by applications. Moreover, an application can't detect entering suspend state: "[...] While an application cannot detect the transition into SUSPEND mode, it is able to detect the transition from SUSPEND mode. It does this by calling the CeRunAppAtEvent function, which takes two parameters: a path and an event code" (from Power Management Features of Windows CE .NET). So if you really want to continue having the application running you can use CeRunAppAtTime() invoking SystemIdleTimerReset() every minute to prevent the device to suspend. You may turn the display off to save battery tough, at least. In such cases, I would encourage revisiting the architecture of the application. In many cases you can simply use CeAppRunAtTime() to perform a task: consider that the API will wake the device up if it's suspended. Note that if the device was suspended and waken up by CeRunAppAtTime it will be in a state between Power On and Suspend: you need to call SetSystemPowerState API to really turn the device on:
SetSystemPowerState(NULL, POWER_STATE_ON, POWER_FORCE)
I imagine there are many other techniques out there to save devices to drain battery... feel free to add whatever link or suggestions in a comment!
Cheers,
~raffaele
Comments
Anonymous
July 22, 2008
Power-Efficient applications on Windows MobileAnonymous
July 22, 2008
Interessante post relativo alla gestione dell’alimentazione su dispositivi con Windows Mobile: SometimesAnonymous
January 04, 2009
" My NETCF application takes long to start, on both devices and emulators... is there any way to