Cómo crear varios APK con distintas dimensiones

Para publicar tu app en Google Play, debes compilar y subir un Android App Bundle. Cuando lo haces, Google Play genera y publica automáticamente APK optimizados para la configuración del dispositivo de cada usuario, por lo que este solo debe descargar el código y los recursos que necesita para ejecutar tu app. Publicar varios APK es útil si no publicas en Google Play, pero debes compilar, firmar y administrar cada APK por tu cuenta.

Cuando desarrolles tu aplicación para Android con el objetivo de aprovechar varios APK en Google Play, es importante que adoptes algunas buenas prácticas desde el principio y evites dolores de cabeza innecesarios en el proceso de desarrollo. En esta lección, se muestra cómo crear varios APKs para tu app, de modo que cada uno cubra una clase diferente de tamaño de pantalla. También obtendrás algunas herramientas necesarias para que el mantenimiento de una base de código APK múltiple sea lo más sencillo posible.

Cómo confirmar que necesitas varios APK

Cuando intentas crear una aplicación que funcione en la gran variedad de dispositivos Android disponibles, es natural que quieras que esta se vea lo mejor posible en cada dispositivo individual. Te recomendamos aprovechar el espacio de las pantallas grandes, pero que aún trabajes en las pequeñas, para usar las nuevas funciones de la API de Android o las texturas visuales disponibles en dispositivos de vanguardia, pero no abandonar los antiguos. Al principio, puede parecer que la compatibilidad con varios APK es la mejor solución, pero a menudo este no es el caso. La sección Cómo usar un solo APK de la guía para desarrolladores de varios APK contiene información útil sobre cómo lograrlo con un solo APK, incluido el uso de nuestra biblioteca de compatibilidad, además de vínculos a recursos de la Guía para desarrolladores de Android.

Si puedes administrarla, limitar tu aplicación a un solo APK tiene varias ventajas, entre las que se incluyen las siguientes:

  • Es más fácil realizar publicaciones y pruebas.
  • Solo hay que mantener una base de código.
  • Tu app se puede adaptar a los cambios de configuración del dispositivo.
  • Funciona el restablecimiento de apps en dispositivos.
  • No tienes que preocuparte por la preferencia del mercado, por el comportamiento de las "actualizaciones" de un APK al siguiente, o por el APK adecuado para cada clase de dispositivos.

En el resto de esta lección, se supone que investigaste el tema, estudiaste detenidamente el material de los recursos vinculados y determinaste que varios APK son la ruta correcta para tu aplicación.

Cómo organizar tus requisitos

Para comenzar, crea un gráfico simple para determinar rápidamente cuántos APKs necesitas y qué tamaños de pantalla cubre cada APK. Afortunadamente, es fácil organizar tus requisitos de forma rápida y sencilla, y tener una referencia fácil para más adelante. Supongamos que quieres dividir tus APKs en dos dimensiones, API y tamaño de pantalla. Crea una tabla con una fila y una columna para cada par de valores posible y colorea algunos "BLOB", cada color que represente un APK.

3 4 5 6 7 8 9 10 11 12 +
Pequeño
Normal
Grande
Extragrande

Arriba se muestra un ejemplo con cuatro APK. El azul es para todos los dispositivos de pantalla pequeña o normal, el verde es para dispositivos de pantalla grande y el rojo es para dispositivos de pantalla extragrande, todos con un rango de API de 3 a 10. El morado es un caso especial, ya que se aplica a todos los tamaños de pantalla, pero solo para el nivel de API 11 y versiones posteriores. Lo que es más importante, con solo mirar este gráfico, sabrás inmediatamente qué APK cubre cualquier combinación de API/tamaño de pantalla. Para iniciar, también tienes nombres internos elegantes para cada uno, ya que “¿Ya probamos el rojo en el ?” es mucho más fácil preguntarle a tu cubie que “¿Ya probamos el APK extragrande de 3 a 10 en el Xoom?” Imprime este gráfico y entrégalo a cada persona que trabaje en tu base de código. Ahora la vida es mucho más simple.

Cómo colocar todos los recursos y el código común en un proyecto de biblioteca

Ya sea que estés modificando una aplicación para Android existente o iniciando una desde cero, esto es lo primero que debes hacer en la base de código y, por lejos, lo más importante. Todo lo que entra en el proyecto de biblioteca solo se debe actualizar una vez (piensa en strings localizadas para idiomas, temas de color, errores corregidos en el código compartido), lo que mejora el tiempo de desarrollo y reduce la probabilidad de errores que se podrían haber evitado fácilmente.

Nota: Si bien los detalles de la implementación sobre cómo crear e incluir proyectos de biblioteca están fuera del alcance de esta lección, lee Cómo crear una biblioteca de Android.

Si estás convirtiendo una aplicación existente para que use compatibilidad con varios APK, analiza tu base de código en busca de todos los archivos de cadenas localizadas, las listas de valores, los colores de temas, los íconos de menú y el diseño que no cambiará entre los APKs, y colócalo todo en el proyecto de biblioteca. El código que no va a cambiar mucho también debe incluirse en el proyecto de biblioteca. Es probable que debas extender estas clases para agregar uno o dos métodos de un APK a otro.

Si, por el contrario, estás creando la aplicación desde cero, primero intenta escribir el código en el proyecto de la biblioteca y, luego, transfiérelo a un APK individual, si es necesario. Esto es mucho más fácil de administrar a largo plazo que agregarlo a uno, luego otro, luego otro y, meses después, intentar averiguar si la BLOB se puede mover a la sección de la biblioteca sin arruinar nada.

Cómo crear nuevos proyectos de APK

Debe haber un proyecto de Android por separado para cada APK que vas a publicar. Para facilitar la organización, coloca el proyecto de biblioteca y todos los proyectos de APK relacionados en la misma carpeta superior. Además, recuerda que cada APK debe tener el mismo nombre de paquete, aunque no es necesario que compartan el nombre del paquete con la biblioteca. Si tuvieras 3 APK que sigan el esquema descrito anteriormente, tu directorio raíz podría verse así:

alexlucas:~/code/multi-apks-root$ ls
foo-blue
foo-green
foo-lib
foo-purple
foo-red

Una vez que se creen los proyectos, agrega el proyecto de la biblioteca como referencia para cada proyecto de APK. Si es posible, define tu actividad inicial en el proyecto de biblioteca y extiende esa actividad en tu proyecto de APK. Tener una actividad inicial definida en el proyecto de la biblioteca te permite colocar toda la inicialización de tu aplicación en un solo lugar, de modo que cada APK individual no tenga que volver a implementar tareas "universales", como inicializar Analytics, ejecutar verificaciones de licencias y cualquier otro procedimiento de inicialización que no cambie mucho de un APK a otro.

Cómo ajustar los manifiestos

Cuando un usuario descarga una aplicación que usa varios APKs mediante Google Play, el APK correcto que se usará se elige según dos reglas simples:

  • El manifiesto tiene que mostrar que un APK en particular es apto.
  • De los APK aptos, se da prioridad al que tiene el número de versión más alto.

A modo de ejemplo, tomemos el conjunto de varios APK descritos anteriormente y supongamos que cada APK se configuró para admitir todos los tamaños de pantalla más grandes que su tamaño de pantalla "objetivo". Veamos el gráfico de muestra anterior:

3 4 5 6 7 8 9 10 11 12 +
Pequeño
Normal
Grande
Extragrande

Debido a que no es problema que la cobertura se superponga, podemos describir el área que abarca cada APK de la siguiente manera:

  • El azul cubre todas las pantallas, minSDK 3.
  • El verde cubre pantallas Grandes y Extragrandes, minSDK 3.
  • El rojo cubre pantallas Extragrandes (generalmente tabletas), minSDK de 9.
  • El morado cubre todas las pantallas, minSDK de 11.

Ten en cuenta que hay muchas superposiciones en estas reglas. Por ejemplo, un dispositivo extragrande con API 11 puede ejecutar cualquiera de los 4 APK especificados. Sin embargo, si usamos la regla por la que se da prioridad al que tiene el número de versión más alto, podemos establecer un orden de preferencia de la siguiente manera:

Morado ≥ Rojo ≥ Verde ≥ Azul

¿Por qué permitir todas las superposiciones? Supongamos que el APK morado tiene algún requisito que los otros dos no tienen. En la página Filtros en Google Play de la guía para desarrolladores de Android, se incluye una lista completa de posibles culpables. A modo de ejemplo, supongamos que el morado requiere una cámara frontal. De hecho, el objetivo del color morado es usar la cámara frontal para entretenernos. Pero resulta que no todos los dispositivos con API 11 o superior TIENEN cámaras frontales. ¡Qué mal!

Afortunadamente, si un usuario está navegando en Google Play desde uno de esos dispositivos, Google Play analizará el manifiesto, verá que Morado indica la cámara frontal como requisito y la ignorará en silencio, después de determinar que Morado y ese dispositivo no son una coincidencia perfecta en el cielo digital. Luego, verá que Rojo no solo es compatible con dispositivos extragrandes, sino que tampoco le importa si hay una cámara frontal. El usuario aún puede descargar la app de Google Play, ya que, a pesar del contratiempo de la cámara frontal, todavía había un APK que admitía ese nivel de API en particular.

Para mantener todos tus APKs en "segmentos" separados, es importante tener un buen esquema de código de versión. Se recomienda usar el que se encuentra en el área Códigos de versión de nuestra guía para desarrolladores. Vale la pena leer toda la sección, pero el punto básico es que, para este conjunto de APK, usaríamos dos dígitos para representar el minSDK, dos para representar el tamaño mínimo y máximo de la pantalla y 3 para representar el número de compilación. De esta manera, cuando el dispositivo se actualice a una nueva versión de Android (por ejemplo, de 10 a 11), el dispositivo considerará cualquier APK que sea apto y preferido por sobre el que está instalado actualmente como una "actualización". El esquema de número de versión, cuando se aplica al conjunto de ejemplos de APKs, podría tener el siguiente aspecto:

Azul: 0304001, 0304002, 0304003…
Verde: 0334001, 0334002, 0334003
Rojo: 0344001, 0344002, 0344003...
Púrpura: 1104001, 1104002, 1104003...

Con todo esto, es probable que los manifiestos de Android se vean de la siguiente manera:

Azul:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="0304001" android:versionName="1.0" package="com.example.foo">
    <uses-sdk android:minSdkVersion="3" />
    <supports-screens android:smallScreens="true"
        android:normalScreens="true"
        android:largeScreens="true"
        android:xlargeScreens="true" />
    ...

Verde:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="0334001" android:versionName="1.0" package="com.example.foo">
    <uses-sdk android:minSdkVersion="3" />
    <supports-screens android:smallScreens="false"
        android:normalScreens="false"
        android:largeScreens="true"
        android:xlargeScreens="true" />
    ...

Rojo:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="0344001" android:versionName="1.0" package="com.example.foo">
    <uses-sdk android:minSdkVersion="3" />
    <supports-screens android:smallScreens="false"
        android:normalScreens="false"
        android:largeScreens="false"
        android:xlargeScreens="true" />
    ...

Morado:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="1104001" android:versionName="1.0" package="com.example.foo">
    <uses-sdk android:minSdkVersion="11" />
    <supports-screens android:smallScreens="true"
        android:normalScreens="true"
        android:largeScreens="true"
        android:xlargeScreens="true" />
    ...

Ten en cuenta que, técnicamente, varios APK funcionarán con la etiqueta supported-screens o con la etiqueta compatible-screens. Por lo general, se prefiere el formato compatible con pantallas y, en general, no es una buena idea usar ambos, ya que complica el proceso y aumenta las posibilidades de errores. Además, ten en cuenta que, en lugar de aprovechar los valores predeterminados (los valores pequeño y normal siempre son verdaderos de forma predeterminada), los manifiestos establecen de manera explícita el valor para cada tamaño de pantalla. Esto puede ahorrarte dolores de cabeza en el futuro. A modo de ejemplo, un manifiesto con un SDK de destino de < 9 tendrá xlarge configurado automáticamente como falso, ya que ese tamaño aún no existía. ¡Así que debes ser explícito!

Cómo revisar tu lista de tareas previa al lanzamiento

Antes de subir tu proyecto a Google Play, verifica los siguientes elementos. Recuerda que estos son específicamente relevantes para varios APK y de ninguna manera representan una lista de tareas completa para todas las aplicaciones que se suben a Google Play.

  • Todos los APK deben tener el mismo nombre de paquete.
  • Todos los APK deben estar firmados con el mismo certificado.
  • Si los APK se superponen en la versión de la plataforma, el que tenga la minSdkVersion más alta debe tener un código de versión más alto.
  • Cada tamaño de pantalla que deseas que sea compatible con tu APK se establece como verdadero en el manifiesto. Cada tamaño de pantalla que deseas evitar se establece en falso.
  • Vuelve a verificar que los filtros de manifiesto no tengan información contradictoria (a un APK que solo sea compatible con Cupcake en las pantallas extragrandes no lo verá nadie).
  • El manifiesto de cada APK debe ser único en al menos una de las pantallas, texturas de OpenGL o versiones de la plataforma compatibles.
  • Intenta probar cada APK en al menos un dispositivo. Salvo eso, tienes uno de los emuladores de dispositivos más personalizables de la industria en tu máquina de desarrollo. ¡Disfruta a lo grande!

También vale la pena inspeccionar el APK compilado antes de lanzarlo al mercado, para asegurarte de que no haya sorpresas que puedan ocultar tu aplicación en Google Play. Esto es bastante simple con la herramienta "aapt". Aapt (Android Asset Packaging Tool) forma parte del proceso de compilación a fin de crear y empaquetar tus aplicaciones para Android, y también es una herramienta muy útil para inspeccionarlas.

>aapt dump badging
package: name='com.example.hello' versionCode='1' versionName='1.0'
sdkVersion:'11'
uses-permission:'android.permission.SEND_SMS'
application-label:'Hello'
application-icon-120:'res/drawable-ldpi/icon.png'
application-icon-160:'res/drawable-mdpi/icon.png'
application-icon-240:'res/drawable-hdpi/icon.png'
application: label='Hello' icon='res/drawable-mdpi/icon.png'
launchable-activity: name='com.example.hello.HelloActivity'  label='Hello' icon=''
uses-feature:'android.hardware.telephony'
uses-feature:'android.hardware.touchscreen'
main
supports-screens: 'xlarge'
supports-any-density: 'true'
locales: '--_--'
densities: '120' '160' '240'

Cuando examines un resultado de aapt, asegúrate de verificar que no haya valores en conflicto para supports-screens y compatible-screens, y que no tengas valores "uses-feature" no deseados que se hayan agregado como resultado de los permisos que estableciste en el manifiesto. En el ejemplo anterior, el APK será invisible para la mayoría de los dispositivos, si no todos.

¿Por qué? Cuando agregas el permiso necesario SEND_SMS, se agregó de manera implícita el requisito de función de android.hardware.telephony. Como la mayoría de los dispositivos extragrandes (si no todos) son tabletas sin hardware de telefonía, Google Play filtrará este APK en estos casos, hasta que aparezcan dispositivos futuros que tengan el tamaño suficiente para ser tratado como tamaño de pantalla extragrande y cuenten con hardware de telefonía.

Por suerte, esto se soluciona fácilmente si agregas lo siguiente en el manifiesto:

<uses-feature android:name="android.hardware.telephony" android:required="false" />

También se agrega de forma implícita el requisito android.hardware.touchscreen. Si quieres que el APK sea visible en TVs sin pantalla táctil, debes agregar lo siguiente en el manifiesto:

<uses-feature android:name="android.hardware.touchscreen" android:required="false" />

Cuando completes la lista de tareas previa al lanzamiento, sube los APK a Google Play. Es posible que la app demore un poco en aparecer cuando navegas por Google Play. Cuando aparezca, realiza una última comprobación. Descarga la app en cualquier dispositivo de prueba para asegurarte de que los APK estén orientados a los dispositivos previstos. ¡Felicitaciones! Eso es todo.