Cómo configurar la entrega condicional

La entrega condicional te permite establecer ciertos requisitos de configuración del dispositivo para que los módulos de funciones se descarguen automáticamente durante la instalación de la app. Por ejemplo, puedes configurar un módulo de funciones que incluya la funcionalidad de realidad aumentada (RA) para que esté disponible desde la instalación de la app solo en los dispositivos compatibles con RA.

Actualmente, este mecanismo de entrega admite el control de la descarga de un módulo durante la instalación de la app, en función de las siguientes configuraciones del dispositivo:

Si un dispositivo no cumple con todos los requisitos que especificaste, no se descargará el módulo durante la instalación de la app. Sin embargo, tu app puede solicitar más tarde que se descargue el módulo on demand con el SDK de Play Core.

Antes de comenzar, asegúrate de estar usando Android Studio 3.5 o una versión posterior. En las siguientes secciones, se muestra cómo agregar compatibilidad con la entrega condicional a tus módulos de funciones.

Cómo agregar un nuevo módulo con opciones de entrega condicional

La manera más fácil de crear un nuevo módulo de funciones con entrega condicional es mediante el asistente New Module, de la siguiente manera:

  1. Para abrir el diálogo New Module, selecciona File > New > New Module en la barra de menú.
  2. En el diálogo New Module, selecciona Dynamic Feature Module y haz clic en Next.
  3. Configura tu módulo como lo harías normalmente y haz clic en Next.
  4. En la sección Module Download Options, haz lo siguiente:

    1. Especifica el título del módulo en un máximo de 50 caracteres. La plataforma usa ese título para identificar el módulo ante los usuarios cuando, por ejemplo, confirma si el usuario desea descargar el módulo. Por esta razón, el módulo básico de la app debe incluir el título del módulo como un recurso de cadenas, que se puede traducir. Cuando se crea el módulo con Android Studio, el IDE agrega el recurso de cadenas al módulo básico y, luego, inserta la siguiente entrada en el manifiesto del módulo de funciones:

      <dist:module
          ...
          dist:title="@string/feature_title">
      </dist:module>
      
    2. En el menú desplegable, en Install-time inclusion, selecciona Only include module at app install for devices with specified features. De esta manera, se crea un módulo que se incluye con tu app durante la instalación solo en dispositivos con determinados parámetros de configuración que puedes especificar, como las funciones del dispositivo o el país. Android Studio inserta el siguiente código en el manifiesto del módulo para reflejar tu elección:

      <dist:module ... >
        <dist:delivery>
            <dist:install-time>
                <dist:conditions>
                    <!-- If you specify conditions, as described in the steps
                         below, the IDE includes them here. -->
                </dist:conditions>
            </dist:install-time>
        </dist:delivery>
      </dist:module>
      
    3. Si deseas limitar la descarga automática del módulo a ciertos países o un nivel mínimo de API, haz clic en Finish para completar la creación del módulo y, luego, lee la sección sobre cómo especificar las condiciones según el país o el nivel mínimo de API. De lo contrario, haz clic en + device feature y agrega una función necesaria para que un dispositivo descargue el módulo en el momento de la instalación.

    4. Junto a device-feature, selecciona una de las siguientes opciones del menú desplegable y especifica su valor:

      • Name: Te permite especificar una función de hardware o software que el dispositivo necesita para descargar el módulo en el momento de la instalación. Las funciones que admite la entrega condicional son las mismas que las que PackageManager especifica como constantes de FEATURE_*. Si seleccionas esta opción, comienza a escribir cualquier parte del valor constante de la función, como "bluetooth", en el campo junto al menú desplegable, y selecciona una de las sugerencias que aparecen.
      • OpenGL ES Version: te permite especificar la versión de OpenGL ES que necesita el dispositivo para descargar el módulo durante la instalación. Si seleccionas esta opción, comienza a escribir la versión, como "0x00030001", en el campo junto al menú desplegable, y selecciona una de las sugerencias que aparecen.
    5. Si deseas agregar varias condiciones según las funciones disponibles del dispositivo, haz clic en + device feature para cada condición de función del dispositivo que quieras especificar.

    6. Marca la casilla junto a Fusing si deseas que ese módulo esté disponible para los dispositivos que ejecutan Android 4.4 (nivel de API 20) y versiones anteriores, y se lo incluya en APK múltiples. Eso significa que puedes habilitar el comportamiento a pedido para este módulo e inhabilitar la fusión para omitirlo en dispositivos que no admiten la descarga e instalación de APK divididos. Android Studio inserta el siguiente código en el manifiesto del módulo para reflejar tu elección:

      <dist:module ...>
          <dist:fusing dist:include="true | false" />
      </dist:module>
      
  5. Cuando hayas terminado de configurar las opciones de descarga del módulo, haz clic en Finish.

Ten en cuenta que el complemento de Android para Gradle no admite la ejecución de lint desde módulos de funciones dinámicos. Cuando se ejecute lint desde el módulo de aplicaciones correspondiente, se ejecutará en sus módulos de funciones dinámicas y se incluirán todos los errores en el informe de lint de la app.

Cómo agregar opciones de entrega condicional a un módulo de funciones existente

Puedes agregar opciones de entrega condicional a un módulo de funciones existente con facilidad a través del manifiesto del módulo. Sin embargo, primero debes leer sobre la compatibilidad de las opciones de entrega condicional con otras opciones de entrega que posiblemente ya hayas habilitado.

Para comenzar, primero debes migrar tu manifiesto al nuevo elemento <dist:delivery>. En el siguiente fragmento de código, se muestra un ejemplo de la sintaxis anterior:

<!-- This is the old syntax. -->
<dist:module
  dist:title="@string/feature_title" dist:onDemand="true">
  <dist:fusing dist:include="true"/>
</dist:module>

Las opciones de entrega anteriores ahora se especifican de la siguiente manera:

<dist:module
  dist:title="@string/feature_title">
  <dist:delivery>
      <dist:on-demand/>
  </dist:delivery>
  <dist:fusing dist:include="true"/>
</dist:module>

Luego, puedes incluir opciones de entrega condicional basadas en las funciones del dispositivo de la siguiente manera:

<dist:module
    dist:title="@string/feature_title">
    <dist:delivery>
      <dist:on-demand/>
      <dist:install-time>
        <dist:conditions>
          <!-- Requires that the device support AR to download the module at
          app install-time.  -->
          <dist:device-feature dist:name="android.hardware.camera.ar"/>
        </dist:conditions>
      </dist:install-time>
    </dist:delivery>
    <dist:fusing dist:include="true"/>
</dist:module>

En las siguientes secciones, se analizan otras opciones para la entrega condicional, por ejemplo, por país o nivel mínimo de API.

Compatibilidad con otras opciones de descarga de módulos

Debido a que los módulos de funciones ofrecen varias opciones para configurar cómo se entrega cada función al dispositivo de un usuario, es importante comprender cómo otras configuraciones afectan las opciones de entrega condicional. En la siguiente tabla, se resume la compatibilidad de la entrega condicional con otras opciones de descarga de módulos.

Opción de descarga de módulos Compatibilidad con entrega condicional
Fusión (<dist:fusing dist:include="true"/>) Si un módulo configura esta opción como verdadera, Google Play no respeta las opciones de entrega condicional que especificas cuando implementas tu app en dispositivos que ejecutan el nivel de API 19 o uno inferior. Es decir, los módulos de funciones que permiten la fusión siempre se incluyen en el momento de la instalación para los dispositivos que ejecutan el nivel de API 19 o uno inferior.
Habilitado instantáneamente (<dist:module dist:instant="true"/>) Las opciones de entrega condicional no son compatibles con los módulos de funciones habilitados instantáneamente.
A pedido (<dist:on-demand/>) De forma predeterminada, si especificas opciones de entrega condicional, el módulo también está disponible a pedido.

Cómo especificar condiciones según el país

La entrega condicional también te permite especificar qué países deseas excluir de la descarga de tu módulo (o incluir en ella) en el momento de la instalación de la app. Especificar esta condición podría ser útil si, por ejemplo, tu módulo implementa una forma de pago que no está disponible en ciertas regiones.

En este contexto, el país del dispositivo generalmente está determinado por la dirección de facturación del usuario registrada en su cuenta de Google Play.

Si deseas especificar países para tu módulo, incluye lo siguiente en el manifiesto del módulo de funciones:

<dist:conditions>
   <!-- Set to "true" to specify countries to exclude from downloading
   this module at app install-time. By default, modules are available
   for download to all user countries. -->
  <dist:user-countries dist:exclude="true">
    <!-- Specifies the two-letter  CLDR country code for regions that should
    not download the module at app install-time. -->
    <dist:country dist:code="CN"/>
    <dist:country dist:code="HK"/>
  </dist:user-countries>
</dist:conditions>

Cómo especificar condiciones para el nivel de API

Especificar una condición basada en el nivel de API de un dispositivo puede ser útil si un módulo de funciones depende de las API que estén disponibles solo en ciertas versiones de la plataforma de Android.

Para establecer una condición basada en un nivel de API del dispositivo mínimo o máximo, incluye lo siguiente en el manifiesto del módulo de funciones:

<dist:conditions>
    <!-- Specifies the minimum API level that the device must satisfy
         in order to download your module at app install-time. The API level you
         specify must be greater or equal to the module's own minSdkVersion. -->
   <dist:min-sdk dist:value="21"/>
    <!-- Specifies the maximum API level that the device cannot exceed
         in order to download your module at app install-time. The API level you
         specify must be less than or equal to the module's own maxSdkVersion. -->
   <dist:max-sdk dist:value="24"/>
</dist:conditions>