martes, 17 de julio de 2012

Aplicación en modo kiosko para Android: lo que no se puede hacer

Generalmente solemos hablar de lo que se puede hacer y cómo se hace; pero para evitar quebraderos de cabeza a veces es bueno saber qué es lo que no se puede hacer y así no perdemos el tiempo intentándolo. Debido a que ya he pasado por eso (intentar infructuosamente hacer ciertas cosas con Android) pongo aquí algunas cosas que he verificado que no es posible hacer o que no son recomendables hacer.

Nota: Antes de comenzar debo aclarar que lo que aquí se comenta está relacionado con el desarrollo de aplicaciones usando la SDK de Android que serán ejecutadas en un dispositivo con su ROM original, sin rootear. Ninguna conclusión de las siguientes deberá aplicarse al desarrollo con otras plataformas como la NDK, Mono Droid o cualquier otro medio utilizado para desarrollar aplicaciones para Android, ni para el caso de la ejecución de aplicaciones en un entorno con privilengios de súper usuario.

Las cosas que intenté hacer y ahora describo, estaban relacionadas con el desarrollo de una aplicación en modo kiosko (ver post anterior Aplicación en modo kiosko para Android). Una aplicación en modo kiosko, por definición, debería limitar toda la interacción del usuario con el dispositivo a los elementos que se quieran y definan en la aplicación. En nuestro caso, se suponía que todos los botones del hardware estarían bloqueados, incluso el botón para bloquear o apagar el móvil. Sin embargo, aquí nos encontramos con la primera limitación en Android: 

No es posible inhabilitar o desactivar el comportamiento del botón de encendido del móvil. 

Si bien es cierto que podemos interceptar algunos eventos relacionados con dicho botón, no hay nada que hacer al respecto salvo procesamientos al margen del proceso iniciado (apagado de la pantalla, reinicio o apagado del terminal). De modo que si queremos que una aplicación en modo kiosko en Android no sea interrumpida por la pulsación del botón de encendido, tendremos que inhabilitar físicamente dicho botón, lo cual es "poco" factible en la mayoría de los casos.


No obstante, supongamos que logramos inhabilitar el botón de encendido, digamos, porque empotramos un teléfono o un tablet con Android en una carcasa que limita su utilización a la interfaz táctil. Nos encontramos entonces con la necesidad de poder reiniciar o apagar el dispositivo, ya sea mediante algún elemento en la interfaz o de manera remota, reaccionando a un SMS, un código recibido por NFC, un patrón leído a través de la cámara o la estrategia que mejor nos convenga. 


Para reiniciar y apagar el dipositivo disponemos de los métodos reboot() y goToSleep(). Sin embargo, a pesar de que parece que podemos reiniciar y apagar el dispositivo con dichos métodos, la ejecución de los mismos requiere del permiso android.permission.DEVICE_POWER que, aunque no lo dice en la documentación de la SDK, está restringido a las aplicaciones que se ejecutan con permisos del sistema y, por tanto, nuestra aplicación no podrá apagar ni reiniciar el dispositivo ejecutándose como una aplicación corriente. De modo que:

No es posible reiniciar o apagar el móvil, por programación.

Finalmente, el último problema está relacionado con la intercepción de llamadas entrantes. En nuestra aplicación, deberíamos interceptar las llamadas entrantes y colgarlas para no interrumpir el funcionamiento de la aplicación. Sin embargo, aunque hay varias aplicaciones que logran hacer esto, lo hacen accediendo a una API no oficial que, desde la versión 2.3 de Android a quedado limitada a las aplicaciones que se ejecutan con permisos del sistema. De modo que, si nuestra aplicación se ejecutará en Android 2.2 o una versión anterior, podríamos usar la estrategia que se ilustra claramente este post: Blocking Incoming call - Android. Sin embargo, deberá tenerse en cuenta que ese código no funcionará en versiones de Android posteriores a la 2.2 pues desde la 2.3 el permiso necesario para manipular una llamada (android.permission.MODIFY_PHONE_STATE) se ha limitado a las aplicaciones del sistema. En Stakoverflow este tema se ha tratado extensamente (como en este hilo) y queda claro que no es posible hacerlo, y aunque hay quien propone diferentes estrategias para paliar el problema, ninguna es la solución definitiva a éste problema que pueda aplicarse a cualquier versión del sistema y en cualquier terminal. De modo que:

No es posible colgar una llamada entrante, por programación, en Android 2.3 o superior.

Hasta aquí las limitaciones con las que me he topado en el desarrollo de aplicaciones para Android. Seguramente haya muchas más, pero de momento, estas están verificadas como problemas, hasta el momento, irresolubles. A lo mejor alguien encuentra una solución universal y la comparte; pero por ahora:

  • No es posible inhabilitar o desactivar el comportamiento del botón de encendido del móvil.
  • No es posible reiniciar o apagar el móvil, por programación.
  • No es posible colgar una llamada entrante, por programación, en Android 2.3 o superior.

2 comentarios:

  1. Bueno bueno mi socio...así ya se donde no romperme la cabeza cuando empieze a colarme al android.Saludos

    ResponderEliminar