Cómo encender el teléfono en Windows Mobile con C#

encender-telefono

Recientemente un cliente me pidió, como parte de los requerimientos del proyecto, que para realizar ciertas acciones en su aplicación de Windows Mobile se encendiera y apagara el teléfono automáticamente, sin que el usuario tuviera que intervenir. Concretamente, la aplicación tiene que abrir una conexión de datos GPRS, conectarse a un webservice situado en un servidor de Internet, e intercambiar cierta información con éste. El teléfono no se utiliza para comunicaciones de voz, sólo de datos.

Como era una tarea que nunca antes había realizado, tuve que recurrir a Google para intentar encontrar la solución, alguna solución cercana o alguna pista que me llevara hacia ella. Pronto la decepción se apropió de mí. Por más que buscaba y buscaba cómo encender el teléfono en Windows Mobile con C#, no encontraba nada, a pesar de que la búsqueda la realizaba en Inglés, el idioma más difundido en la red.

Sin embargo, aunque lentamente, poco a poco me fui acercando a la solución. La causa de la falta de respuestas era que no estaba escribiendo la pregunta correcta. Para un usuario común puede que la frase «encender el teléfono» le resultara natural, pero en términos más técnicos el enfoque correcto es «encender la radio del dispositivo móvil». Y en Inglés. Algo así como: turn radio on and off windows mobile c#. Aunque en este contexto existen otros posibles sinónimos de turn, como switch o toggle.

Resulta que en la ROM del dispositivo existe una dll no documentada llamada ossvcs.dll, que exporta funciones para controlar los Dispositivos de Radio (Radio Devices). Es decir, los módulos de Bluetooth, Teléfono y Red Inalámbrica (WiFi). Ossvcs.dll exporta las funciones por un número de orden y no por su nombre. Estas funciones pertenecen a una API no administrada, por lo que para invocarlas desde nuestro código C# necesitaremos declarar los prototipos mediante p/Invoke. Las funciones que necesitamos son las siguientes:

[DllImport(«ossvcs.dll», EntryPoint = «#276», CharSet = CharSet.Unicode)]
private static extern uint GetWirelessDevice(ref IntPtr pDevice, int pDevVal);

[DllImport(«ossvcs.dll», EntryPoint = «#273», CharSet = CharSet.Unicode)]
private static extern uint ChangeRadioState(ref RDD pDevice, int dwState, int saveAction);

[DllImport(«ossvcs.dll», EntryPoint = «#280», CharSet = CharSet.Unicode)]
private static extern uint FreeDeviceList(IntPtr pDevice);

Nótese cómo EntryPoint contiene el número de orden que identifica a la función invocada.

De las tres funciones, la que realmente nos interesa es ChangeRadioState(), porque justamente es la que nos permite cambiar el estado de la radio. Es decir, encenderla o apagarla. O dicho de forma llana, encender o apagar el teléfono.

He creado una clase llamada MobileRadio, que expone un único método público estático: SetDeviceState(). Este método acepta dos argumentos de tipo entero. El primero indica el tipo de dispositivo, y el segundo informa el estado al que se desea cambiar. El tipo de dispositivo puede ser uno de los siguientes: Bluetooth, el Teléfono o la Red Inalámbrica (WiFi). No necesitas conocer de memoria los valores enteros que se pueden traspasar. La clase MobileRadio exporta también dos estructuras (RADIODEVTYPE y RADIODEVSTATE) que contienen las constantes necesarias.

Para encender el teléfono basta la siguiente línea de código:

MobileRadio.SetDeviceState(MobileRadio.RADIODEVTYPE.PHONE, MobileRadio.RADIODEVSTATE.ON);

Y para apagarlo, ¿lo adivinas? 😉

Para conocer el estado actual del teléfono, si está encendido o apagado, utilizamos la propiedad booleana PhoneRadioOff de la clase SystemState, situada en el espacio de nombres Microsoft.WindowsMobile.Status:

Microsoft.WindowsMobile.Status.SystemState.PhoneRadioOff

Esta propiedad es verdadera (true) si la radio del dispositivo está apagada, y falsa (false) en caso contrario.

Puedes descargar el proyecto completo desde aquí.

Enlaces de interés:

Cómo encender el teléfono en Windows Mobile con C#
El código fuente del proyecto

Turn radio on and off as needed
http://community.intermec.com/t5/General-Development-Developer/Turn-radio-on-and-off-as-needed/m-p/138

Controlling the Radio Devices
http://www.teksoftco.com/articles/article%20007/radiodevices.htm

Toggle WiFi/BT/Phone using .NET code only!!!
http://forum.xda-developers.com/showthread.php?t=413159

PInvoke.net: A wiki for .NET developers
http://www.pinvoke.net/