sábado, 30 de agosto de 2014

Compatibilidad y dispositivos

Android ha sido diseñado para ser ejecutado en múltiples tipos de dispositivos, desde teléfonos móviles a tabletas y televisores inteligentes (smart TV). Como desarrollador, esta amplia gama de dispositivos te ofrece la oportunidad de llegar a un alto número de usuarios desde tu aplicación. Para que tu aplicación tenga éxito, ésta deberá ser lo suficientemente flexible y contar con una interfaz de usuario que sea capaz de adaptarse a cada una de las configuraciones de pantalla existentes.

Para facilitarnos el camino y conseguir dicho objetivo, Android nos ofrece la posibilidad de poder especificar diferentes diseños y recursos de manera estática para cada configuración específica de dispositivo. Por ejemplo, podremos especificar diferentes diseños usando varios archivos XML, atendiendo al tamaño de pantalla. En este caso, Android cargará el diseño más adecuado en función de las características del dispositivo en el que se esté ejecutando nuestra aplicación.

¿Qué significa compatibilidad?

Podemos hablar de dos tipos de compatibilidad: compatibilidad desde el punto de vista del dispositivo y compatibilidad desde el punto de vista de la aplicación.

Al ser Android un proyecto de fuentes abiertas (open source), cualquier fabricante de hardware puede construir un dispositivo capaz de ejecutar el sistema operativo Android. Aún así, un dispositivo es compatible con Android solo si puede ejecutar de manera correcta aplicaciones escritas para el entorno de ejecución de Android. Los detalles concretos de dicho entorno, se encuentran definidos por el programa de compatibilidad de Android y cada dispositivo deberá pasar los tests de compatibilidad (CTS - Compatibility Test Suite) para ser considerado como compatible.

Como desarrolladores de aplicaciones, no necesitamos preocuparnos sobre si un dispositivo es compatible con Android o no porque solo los dispositivos compatibles incluyen la tienda de Google Play. Puedes estar seguro de que los usuarios que instalen tu aplicación desde la tienda de Google, estarán usando un dispositivo compatible con Android.

Sin embargo, sí que tendrás que preocuparte de que tu aplicación sea compatible con la configuración de cada dispositivo. Debido a que Android se ejecuta en un amplio abanico de configuraciones de dispositivos, algunas funcionalidades no estarán disponibles en todos ellos. Por ejemplo, algunos dispositivos  no contarán con brújula. Si el núcleo de tu aplicación hace uso de la brújula, entonces tu aplicación solo será compatible con aquellos dispositivos que la incluyan.

Controlando la disponibilidad de tu aplicación por dispositivo.

Android cuenta con una serie de funcionalidades que podremos utilizar enlazando las APIs de la plataforma a nuestra aplicación. Algunas de esas funcionalidades se basan en el hardware (la brújula, por ejemplo), otras se basan en el software (los widgets, por ejemplo) y otras dependerán de la versión de la plataforma. No todos los dispositivos soportan todas las funcionalidades y es por ello que tendremos que restringir la disponibilidad de nuestro desarrollo a los dispositivos que cumplan con sus requisitos.

Para llegar al máximo número de usuarios posible, tendremos que hacer un esfuerzo para que nuestra aplicación de soporte al mayor número de configuraciones posible usando un único APK. En la mayoría de los casos, podremos conseguirlo mediante la desactivación de funcionalidades opcionales en tiempo de ejecución y proporcionando recursos alternativos para las diferentes configuraciones (definir varios diseños para diferentes tamaños de pantalla, por ejemplo). Si es necesario, tendremos que restringir la disponibilidad a través de la tienda Google Play basándonos en alguno de los siguientes criterios:
  • Funcionalidades de dispositivo.
  • Versión de la plataforma.
  • Configuración de la pantalla.

Funcionalidades de dispositivo.

Android define una serie de identificadores para cada una de las posibles funcionalidades software o hardware disponibles en un dispositivo. Por ejemplo, para la brújula contamos con la constante FEATURE_SENSOR_COMPASS y para los widgets contamos con la constante FEATURE_APP_WIDGETS.

Si fuera necesario, podríamos prevenir que un usuario instalara nuestra aplicación si su dispositivo no provee alguna de las funcionalidades que declaramos en el archivo de declaraciones de Android a través de elementos <uses-feature>:
<manifest ... >
    <uses-feature android:name="android.hardware.sensor.compass"
                  android:required="true" />
    ...
</manifest>
Google Play comparará las funcionalidades de nuestra aplicación con las funcionalidades del dispositivo del usuario para comprobar si son compatibles. Si el dispositivo no da soporte a todas las funcionalidades, el usuario no podrá instalar la aplicación.

Sin embargo, si para el funcionamiento de la aplicación no es imprescindible dicha funcionalidad, podríamos establecer el valor del atributo android:required a false y preguntar en tiempo de ejecución sobre su disponibilidad:
PackageManager pm = getPackageManager();
if (!pm.hasSystemFeature(PackageManager.FEATURE_SENSOR_COMPASS)) {
    // Este dispositivo no cuenta con brújula y la desactivamos
    disableCompassFeature();
}

Nota. Ciertos permisos del sistema requieren implícitamente que una funcionalidad concreta se encuentre disponible. Por ejemplo, si nuestra aplicación necesita permisos para acceder al bluetooth, esto implica que el dispositivo deberá contar obligatoriamente con bluetooth. Puedes cambiar este comportamiento haciendo que la aplicación esté disponible también para dispositivos sin bluetooth estableciendo el valor del atributo android:required a false.
<manifest ...>
    <uses-feature android:name="android.hardware.bluetooth" android:required="false" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    ...
</manifest>

Versión de la plataforma.

Los dispositivos Android ejecutan versiones distintas del sistema. Cada una de estas versiones cuenta con su propia API que no se encontrará disponible en versiones anteriores. Por ejemplo, en Android 1.0 contamos con la versión 1 de la API, mientras que en Android 4.4 contamos con la versión 19.

Supongamos que desarrollamos una aplicación donde utilizamos la agenda y que para ellos vamos a echar mano de la clase CalendarProvider. Puesto que esta funcionalidad fue añadida con Android 4.0 (versión 14 de la API), a la hora de crear nuestro proyecto tendremos que especificar como versión mínima soportada (minSdkVersion), 14.

Por otro lado, existe también un targetSdkVersion asociado a nuestro proyecto. Se trata de la versión de la API para el que nuestra aplicación ha sido optimizada. Por defecto, cuando creamos el proyecto, ésta se corresponde con la última versión de la API disponible, aunque podríamos elegir una inferior.

Cada versión de Android es compatible con aplicaciones que fueron desarrolladas con las APIs de versiones anteriores. De esta manera, nuestra aplicación debería ser compatible con versiones futuras de Android.

Nota. El atributo targetSdkVersion no evita que nuestra aplicación pueda ser instalada en dispositivos que ejecuten versiones posteriores del sistema. Este atributo si servirá para garantizar que el comportamiento de la API sea el esperado y que no se hereden comportamientos de APIs posteriores a la indicada.

Si nuestra aplicación utiliza una versión reciente de API pero queremos que ésta se ejecute en dispositivos con versiones anteriores, siempre podremos comprobar en tiempo de ejecución por la versión de la plataforma en la que se está ejecutando nuestra aplicación y en caso de ser demasiado baja, pasaremos a desactivar la funcionalidad no soportada:

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
    // Si se ejecuta en una versión de API anterior a la 11
    // no usaremos características de pulsar/arrastrar en el ClipboardManager
    disableDragAndDrop();
}

Configuración de la pantalla.

Android se ejecuta en todo tipo de dispositivos: teléfonos móviles, relojes, televisiones, etc. Una manera de clasificar los dispositivos es a través de su pantalla. Para ello, Android define dos características por cada dispositivo: tamaño de pantalla (tamaño físico de la pantalla) y la densidad de la pantalla (densidad física de los pixeles en pantalla, aka DPI). Para simplificar las diferentes configuraciones, Android generaliza estas variaciones dentro de grupos que hacen más fácil su tratamiento:
  • Cuatro tamaños de pantalla genéricos: small, normal, large y xlarge.
  • Varias densidades genéricas: mdpi (media), hdpi (alta), xhdpi (extra alta), xxhdpi (extra extra alta).
Por defecto, una aplicación será compatible con todos los tamaños y densidades de pantalla. Será el sistema el encargado de hacer todos los ajustes necesarios para ello. Sin embargo, deberíamos de proporcionar una mejor experiencia al usuario, optimizando nuestras aplicaciones y desarrollando diferentes diseños dependiendo del tamaño de pantalla o proporcionando imágenes de mayor o menor calidad en función de las densidades de pantalla.

Controlando la disponibilidad de tu aplicación por razones de negocio.

Existe otro tipo de razones por las que podemos estar interesados en restringir el acceso a nuestra aplicación a ciertos usuarios. Por ejemplo, supongamos que nuestra aplicación muestra los horarios para los trenes de cercanías de Madrid. Es evidente que se trata de un tema que no interesa a usuarios que no se encuentren en Madrid. Para este tipo de situaciones, la tienda Google Play nos proporciona una serie de filtros a través de la consola del programador que nos permitirán controlar la disponibilidad de nuestra aplicación atendiendo a razones no técnicas, tales como, la localización del usuario o el proveedor de servicio.

Los filtros asociados a razones técnicas como un requerimiento hardware determinado, siempre estarán basadas en información contenida dentro del APK. Pero los filtros debidos a razones no técnicas como la localización geográfica, siempre se gestionarán a través de la consola del desarrollador de Google Play. 

No hay comentarios:

Publicar un comentario