Cómo crear varios APK para diferentes tamaños de pantallas

Para publicar tu app en Google Play, debes compilar y subir un Android App Bundle. Cuando lo hagas, Google Play generará y publicará automáticamente los APK optimizados de la configuración del dispositivo de cada usuario, de manera que solo tengan que descargar el código y los recursos que necesiten para ejecutar tu app. La publicación de varios APK resulta útil cuando no publicas tu app en Google Play, pero deberás compilar, firmar y administrar cada APK tú mismo.

Cuando desarrolles tu app para Android con el objetivo de aprovechar múltiples 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 APK 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 app que funcione en varios tamaños de dispositivos Android, es natural que busques que la app aproveche todo el espacio disponible en dispositivos más grandes, sin sacrificar la compatibilidad o la usabilidad en las pantallas más pequeñas. 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, incluso sobre el uso de nuestra biblioteca de compatibilidad. También debes leer la guía sobre cómo admitir varias pantallas. Incluso puedes descargar una biblioteca de compatibilidad con el SDK de Android, que te permite usar fragmentos en dispositivos anteriores a Honeycomb (lo que facilita mucho la compatibilidad con varias pantallas en un solo APK).

Si puedes administrarla, limitar tu app 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.

Para 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 app.

Cómo organizar tus requisitos

Comienza creando un gráfico simple para determinar rápidamente cuántos APK necesitas y qué tamaño de pantalla cubre cada APK. Por suerte, es fácil organizar tus requisitos de manera rápida y sencilla, y tener una referencia para más adelante. Comienza con una fila de celdas que represente los diversos tamaños de pantalla disponibles en la plataforma Android.

Pequeño Normal Grande Extragrande

Ahora solo debes colorear el gráfico de manera que cada color represente un APK. Este es un ejemplo de cómo puedes aplicar cada APK a un determinado rango de tamaños de pantalla.

Pequeño Normal Grande Extragrande

Según tus necesidades, también podrías tener dos APK, "Pequeño y todo lo demás" o "Extragrande y todo lo demás". Los colores del cuadro también son una forma de facilitar la comunicación dentro del equipo. Ahora puedes referirte a cada APK como "azul", "verde" o "rojo", sin importar cuántos tipos de pantalla diferentes cubra.

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

Si vas a modificar una app para Android existente o comenzar una desde cero, esto es lo primero, y lo más importante, que deberías hacer con la base de código base. Solo se necesita actualizar una vez todo lo que entra en el proyecto de la biblioteca (piensa en strings localizadas para diferentes idiomas, temas de color, errores corregidos en el código compartido), lo que mejora tu tiempo de desarrollo y reduce la probabilidad de errores que podrían haberse 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 app existente para usar la compatibilidad con varios APK, examina tu base de código en busca de todos los archivos de strings localizadas, listas de valores, colores de tema, íconos de menú y diseños que no vas a cambiar entre los APK, y pon todo en el proyecto de la biblioteca. También debes incluir en este proyecto el código que no sufrirá demasiados cambios. Es posible que debas extender estas clases para agregar un método o dos de un APK a otro.

Si, en cambio, estás creando la app 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 agregar código a uno, luego a otro y a otro, y meses más tarde intentas averiguar si se puede transferir este BLOB a 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 un organizarte de manera sencilla, coloca el proyecto de la biblioteca y todos los proyectos de APK relacionados en la misma carpeta principal. También recuerda que cada APK debe tener el mismo nombre de paquete, aunque no necesariamente deben compartir el nombre del paquete con la biblioteca. Si tuvieras 3 APK siguiendo el esquema que se describió arriba, el directorio raíz podría tener el siguiente formato:

    alexlucas:~/code/multi-apks-root$ ls
    foo-blue
    foo-green
    foo-lib
    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 la biblioteca y extiende esa actividad en tu proyecto de APK. Tener una actividad inicial definida en el proyecto de la biblioteca te permite colocar todas las inicializaciones de tu app en un solo lugar, de modo que los APK no tengan que volver a implementar trabajos "universales", como inicializar Analytics, ejecutar verificaciones de licencia y otros procedimientos de inicialización que no difieren mucho entre los diferentes APK.

Cómo ajustar los manifiestos

Cuando un usuario descarga una app que usa varios APK 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 no establecimos un nivel de API máximo para ninguno de los APK. Tomado de forma individual, el rango posible de cada APK tendría el siguiente aspecto:

Pequeño Normal Grande Extragrande
Pequeño Normal Grande Extragrande
Pequeño Normal Grande Extragrande

Sin embargo, cuando usamos la regla por la que se da prioridad al que tiene el número de versión más alto, si establecemos el atributo versionCode en cada APK, por ejemplo, rojo ≥ verde ≥ azul, el gráfico se contrae de la siguiente manera:

Pequeño Normal Grande Extragrande

Ahora, supongamos que el APK rojo tiene algunos requisitos 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 rojo requiere una cámara frontal. De hecho, el objetivo del APK rojo es usar funciones entretenidas de la cámara frontal. Pero resulta que no todos los dispositivos extragrandes TIENEN cámaras frontales. ¡Qué mal!

Por suerte, si un usuario está navegando en Google Play desde uno de esos dispositivos, Google Play mirará el manifiesto, verá que Rojo indica la cámara frontal como un requisito y la ignorará en silencio, después de determinar que Rojo y ese dispositivo no son una combinación perfecta en el cielo digital. Verá que Rojo no solo es compatible con los dispositivos extragrandes, sino que también no importa si hay una cámara frontal. El usuario aún puede descargar la app de Google Play, porque a pesar del contratiempo de la cámara frontal, todavía había un APK que admitía ese tamaño de pantalla en particular.

Para mantener todos tus APK 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. Como el conjunto de ejemplos de APK solo abarca una de 3 dimensiones posibles, basta con separar cada APK por 1,000 y comenzar a sumar desde allí. El aspecto podría ser el siguiente:

Azul: 1,001, 1,002, 1,003, 1,004…
Verde: 2,001, 2,002, 2,003, 2,004…
Rojo: 3,001, 3,002, 3,003, 3,004…

Tras juntar todo esto, es posible que los manifiestos de Android tengan el siguiente aspecto:

Azul:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        android:versionCode="1001" android:versionName="1.0" package="com.example.foo">
        <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="2001" android:versionName="1.0" package="com.example.foo">
        <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="3001" android:versionName="1.0" package="com.example.foo">
        <supports-screens android:smallScreens="false"
            android:normalScreens="false"
            android:largeScreens="false"
            android:xlargeScreens="true" />
        ...
    

Ten en cuenta que, técnicamente, varios APK funcionarán con la etiqueta de supports-screens o con la etiqueta compatible-screens. Por lo general, se prefiere la etiqueta supports-screens y no se considera una buena idea usar ambas en el mismo manifiesto, ya que complica el proceso y aumenta la posibilidad de errores. También 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 de cada tamaño de pantalla. Esto puede ahorrarte dolores de cabeza en el futuro. Por ejemplo, un manifiesto con un SDK de destino de < 9 tendrá xlarge configurado automáticamente como falso, dado que ese tamaño aún no existía. Por lo tanto, 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 solo pertinentes para varios APK, y de ninguna manera representan una lista de tareas completa para todas las apps 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.
  • 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 configura como falso.
  • Comprueba que los filtros de manifiesto no tengan información contradictoria (a un APK que solo admita 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 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 app en Google Play. Esto es bastante simple con la herramienta "aapt". Aapt (Android Asset Packaging Tool) puede ayudarte durante el proceso de compilación para crear y empaquetar tus apps 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 comprobar que no hay valores en conflicto para supports-screens y compatible-screens, y que no tengas valores "uses-feature" no intencionales que se hayan agregado como resultado de los permisos que estableciste en el manifiesto. En el ejemplo anterior, el APK no será visible en la mayoría de los dispositivos, si no en 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 agregando lo siguiente en tu manifiesto:

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

También se agrega de manera implícita el requisito de android.hardware.touchscreen. Si quieres que tu APK sea visible en TVs que no tienen con 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.

Para obtener más información sobre la publicación de varios APK en Google Play, consulta Compatibilidad con varios APK.