Cómo integrar Asset Delivery (código nativo)

Sigue los pasos que se indican en esta guía para acceder a los paquetes de elementos de tu app desde código de C y C++.

El código de integración de ejemplo está disponible en GitHub.

Crea contenido nativo

Usa los siguientes pasos para compilar Play Asset Delivery en el Android App Bundle de tu proyecto. No es necesario que uses Android Studio para seguir estos pasos.

  1. Actualiza la versión del complemento de Android para Gradle en el archivo build.gradle de tu proyecto a 4.0.0 o a una versión posterior.

  2. En el directorio de nivel superior de tu proyecto, crea un directorio para el paquete de elementos. Se usa el nombre de ese directorio como el nombre del paquete de elementos. Los nombres de los paquetes de elementos deben comenzar con una letra y solo pueden contener letras, números y guiones bajos.

  3. En el directorio del paquete de recursos, crea un archivo build.gradle y agrega el siguiente código. Asegúrate de especificar el nombre del paquete de elementos y solo un tipo de entrega:

    // In the asset pack’s build.gradle file:
    plugins {
        id 'com.android.asset-pack'
    }
    
    assetPack {
        packName = "asset-pack-name" // Directory name for the asset pack
        dynamicDelivery {
            deliveryType = "[ install-time | fast-follow | on-demand ]"
        }
    }
    
  4. En el archivo build.gradle de la app del proyecto, agrega el nombre de cada paquete de elementos de tu proyecto, como se muestra a continuación:

    // In the app build.gradle file:
    android {
        ...
        assetPacks = [":asset-pack-name", ":asset-pack2-name"]
    }
    
  5. En el archivo settings.gradle del proyecto, incluye todos los paquetes de elementos de tu proyecto, como se muestra a continuación:

    // In the settings.gradle file:
    include ':app'
    include ':asset-pack-name'
    include ':asset-pack2-name'
    
  6. En el directorio del paquete de elementos, crea el siguiente subdirectorio: src/main/assets.

  7. Coloca los recursos en el directorio src/main/assets. Aquí también puedes crear subdirectorios. Ahora la estructura del directorio de tu app debería verse de la siguiente manera:

    • build.gradle
    • settings.gradle
    • app/
    • asset-pack-name/build.gradle
    • asset-pack-name/src/main/assets/your-asset-directories
  8. Compila el Android App Bundle con Gradle. En el paquete de aplicación que se generó, el directorio raíz ahora incluye lo siguiente:

    • asset-pack-name/manifest/AndroidManifest.xml: configura el identificador y el modo de entrega del paquete de elementos.
    • asset-pack-name/assets/your-asset-directories: es el directorio que contiene todos los elementos entregados como parte del paquete de elementos.

    Gradle genera el manifiesto para cada paquete de elementos y da como resultado el directorio assets/ por ti.

  9. Opcional: Configura el paquete de aplicación para que sea compatible con diferentes formatos de compresión de texturas.

Integración con el SDK de Play Core

El SDK nativo de Play Core proporciona el archivo de encabezado de C de play/asset_pack.h para solicitar paquetes de elementos, administrar descargas y acceder a los elementos. Primero, asegúrate de agregar la biblioteca de Play Core a tu proyecto.

Debes implementar esa API según el tipo de entrega del paquete de elementos al que deseas acceder. Estos pasos se muestran en el siguiente diagrama de flujo.

Diagrama de flujo del paquete de elementos para el código nativo

Figura 1: Diagrama de flujo para acceder a paquetes de elementos

Entrega durante la instalación

Los paquetes de elementos configurados como install-time están disponibles apenas se inicia la app. Usa la API de NDK de AAssetManager a fin de acceder a los elementos que se entregan en este modo:

#include <android/asset_manager.h>
#include <android_native_app_glue.h>
...
AAssetManager* assetManager = app->activity->assetManager;
AAsset* asset = AAssetManager_open(assetManager, "asset-name", AASSET_MODE_BUFFER);
size_t assetLength = AAsset_getLength(asset);
char* buffer = (char*) malloc(assetLength + 1);
AAsset_read(asset, buffer, assetLength);

Entrega rápida y a pedido

En las siguientes secciones, se muestra cómo inicializar la API, obtener información sobre los paquetes de elementos antes de descargarlos, llamar a la API para iniciar la descarga y acceder a los paquetes descargados. Estas secciones se aplican a los paquetes de elementos fast-follow y on-demand.

Inicio de la app

Siempre llama a AssetPackManager_init() para inicializar la API del paquete de elementos antes de llamar a cualquier otra función. Comprueba si hay códigos de error del paquete de elementos.

#include "play/asset_pack.h"
...
AssetPackErrorCode AssetPackManager_init(JavaVM* jvm, jobject android_context);

Además, asegúrate de llamar a las siguientes funciones en onPause() y onResume() de ANativeActivityCallbacks:

Obtén información de descarga sobre paquetes de elementos

Las apps deben divulgar el tamaño de la descarga antes de recuperar el paquete de elementos. Usa la función AssetPackManager_requestInfo() a fin de iniciar una solicitud asíncrona para el tamaño de la descarga y aunque el paquete ya se esté descargando. Luego, usa AssetPackManager_getDownloadState() para sondear el estado de descarga (por ejemplo, llama a esta función una vez por fotograma en el bucle de juego). Si falla una solicitud, consulta los códigos de error del paquete de recursos.

AssetPackErrorCode AssetPackManager_requestInfo();      // Call once
AssetPackErrorCode AssetPackManager_getDownloadState(); // Call once per frame in your game loop

La función AssetPackManager_getDownloadState() muestra el tipo opaco AssetPackDownloadState como un puntero de salida. Usa ese puntero a fin de llamar a las siguientes funciones:

AssetPackDownloadState* state;
AssetPackErrorCode error_code = AssetPackManager_getDownloadState(asset-pack-name, &state);
AssetPackDownloadStatus status = AssetPackDownloadState_getStatus(state);
uint64_t downloadedBytes = AssetPackDownloadState_getBytesDownloaded(state);
uint64_t totalBytes = AssetPackDownloadState_getTotalBytesToDownload(state));
AssetPackDownloadState_destroy(state);

Instalar

Usa AssetPackManager_requestDownload() para comenzar a descargar un paquete de elementos por primera vez o solicitar que se complete la actualización de un paquete:

AssetPackErrorCode AssetPackManager_requestDownload();  // Call once
AssetPackErrorCode AssetPackManager_getDownloadState(); // Call once per frame in your game loop

La función AssetPackManager_getDownloadState() muestra el tipo opaco AssetPackDownloadState. A fin de obtener información para usar este tipo, consulta Obtén información de descarga.

Descargas grandes

Si la descarga supera los 150 MB y el usuario no está conectado a una red Wi-Fi, no se iniciará la descarga hasta que el usuario otorgue explícitamente su consentimiento para proceder con la descarga mediante una conexión de datos móviles. Del mismo modo, si la descarga es grande y el usuario pierde la conexión Wi-Fi, se detendrá el proceso y se necesitará el consentimiento explícito a fin de continuar usando una conexión de datos móviles. Un paquete detenido tiene el estado WAITING_FOR_WIFI. Para activar el flujo de la IU y solicitar el consentimiento del usuario, usa lo siguiente:

Accede a los paquetes de elementos

Puedes acceder a un paquete de elementos mediante llamadas al sistema de archivos después de que la solicitud de descarga alcance el estado COMPLETED. Cada paquete de elementos se almacena en un directorio independiente, en el almacenamiento interno de la app. Usa AssetPackManager_getAssetPackLocation() a los efectos de obtener un AssetPackLocation para el paquete de elementos especificado. Usa AssetPackLocation_getStorageMethod() en esa ubicación para determinar el método de almacenamiento:

  • ASSET_PACK_STORAGE_APK: el paquete de elementos se instala como un APK. Consulta Entrega durante la instalación a fin de acceder a estos elementos.
  • ASSET_PACK_STORAGE_FILES: usa AssetPackLocation_getAssetsPath() para obtener una ruta de acceso del archivo al directorio que contiene los elementos, o valores nulos si estos no se descargaron. No modifiques los archivos descargados en esta ruta de acceso del archivo.
AssetPackLocation* location;

AssetPackErrorCode error_code = AssetPackManager_getAssetPackLocation(asset-pack-name, &location);

if (error_code == ASSET_PACK_NO_ERROR) {
    AssetPackStorageMethod storage_method = AssetPackLocation_getStorageMethod(location);
    const char* assets_path = AssetPackLocation_getAssetsPath(location);
    AssetPackLocation_destroy(location);
}

Una vez que encuentres los elementos, usa funciones como fopen o ifstream para acceder a los archivos.

Otros métodos de la API de Play Core

Estos son algunos métodos de API adicionales que recomendamos que uses en tu app.

Cancelar solicitud

Usa AssetPackManager_cancelDownload() para cancelar una solicitud activa de paquete de elementos. Ten en cuenta que esta solicitud es una operación de mejor esfuerzo.

Solicitar eliminación

Usa AssetPackManager_requestRemoval() para programar la eliminación de un paquete de elementos.

Siguiente paso

Prueba Play Asset Delivery de forma local y desde Google Play.