Sigue los pasos que se indican en esta guía para acceder a los paquetes de elementos de tu app desde el código de Java.
Cómo compilar para Kotlin y Java
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.
Actualiza la versión del complemento de Android para Gradle en el archivo
build.gradle
de tu proyecto a4.0.0
o a una versión posterior.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.
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:Groovy
// 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 ]" } }
Kotlin
// In the asset pack’s build.gradle.kts file: plugins { id("com.android.asset-pack") } assetPack { packName.set("asset-pack-name") // Directory name for the asset pack dynamicDelivery { deliveryType.set("[ install-time | fast-follow | on-demand ]") } }
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:Groovy
// In the app build.gradle file: android { ... assetPacks = [":asset-pack-name", ":asset-pack2-name"] }
Kotlin
// In the app build.gradle.kts file: android { ... assetPacks += listOf(":asset-pack-name", ":asset-pack2-name") }
En el archivo
settings.gradle
del proyecto, incluye todos los paquetes de elementos de tu proyecto, como se muestra a continuación:Groovy
// In the settings.gradle file: include ':app' include ':asset-pack-name' include ':asset-pack2-name'
Kotlin
// In the settings.gradle.kts file: include(":app") include(":asset-pack-name") include(":asset-pack2-name")
En el directorio del paquete de elementos, crea el siguiente subdirectorio:
src/main/assets
.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
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 recursos y genera el directorio
assets/
por ti.Opcional: Incluye la biblioteca de Play Asset Delivery si planeas usar la entrega de seguimiento rápido y on demand.
Groovy
implementation "com.google.android.play:asset-delivery:2.0.2" // For Kotlin use asset-delivery-ktx implementation "com.google.android.play:asset-delivery-ktx:2.0.1"
Kotlin
implementation("com.google.android.play:asset-delivery:2.0.2") // For Kotlin use core-ktx implementation("com.google.android.play:asset-delivery-ktx:2.0.1")
Opcional: Configura el paquete de aplicación para que sea compatible con diferentes formatos de compresión de texturas.
Integra la API de Play Asset Delivery
La API de Java de Play Asset Delivery proporciona la clase AssetPackManager
para solicitar paquetes de recursos, administrar descargas y acceder a los recursos. Primero, asegúrate de agregar la biblioteca de Play Asset Delivery a tu proyecto.
Esta API se implementa de acuerdo con el tipo de entrega del paquete de recursos al que deseas acceder. Estos pasos se muestran en el siguiente diagrama de flujo.
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 AssetManager de Java para acceder a los elementos que se entregan en este modo:
Kotlin
import android.content.res.AssetManager ... val context: Context = createPackageContext("com.example.app", 0) val assetManager: AssetManager = context.assets val stream: InputStream = assetManager.open("asset-name")
Java
import android.content.res.AssetManager; ... Context context = createPackageContext("com.example.app", 0); AssetManager assetManager = context.getAssets(); InputStream is = assetManager.open("asset-name");
Cómo realizar entregas rápidas y a pedido
En las siguientes secciones, se muestra cómo obtener información sobre los paquetes de elementos antes de descargarlos, cómo llamar a la API para comenzar la descarga y cómo acceder a los paquetes descargados. Estas secciones se aplican a los paquetes de elementos fast-follow
y on-demand
.
Comprueba el estado
Cada paquete de elementos se almacena en una carpeta independiente del almacenamiento interno de la app.
Usa el método getPackLocation()
para determinar la carpeta raíz de un paquete de elementos. Este método muestra los siguientes valores:
Valor que se muestra | Estado |
---|---|
Un objeto AssetPackLocation válido |
La carpeta raíz del paquete de elementos está lista para acceder de inmediato a assetsPath() |
null |
Los paquetes de elementos o los elementos desconocidos no están disponibles |
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 el método requestPackStates()
o getPackStates()
para determinar el tamaño de la descarga y si ya se está descargando el paquete.
Kotlin
suspend fun requestPackStates(packNames: List<String>): AssetPackStates
Java
Task<AssetPackStates> getPackStates(List<String> packNames)
requestPackStates()
es una función de suspensión que muestra un objeto AssetPackStates
, mientras que getPackStates()
es un método asíncrono que muestra un elemento Task<AssetPackStates>
. El método packStates()
de un objeto AssetPackStates
muestra un elemento Map<String,
AssetPackState>
. Este mapa contiene el estado de cada paquete de elementos solicitado, codificado por su nombre:
Kotlin
AssetPackStates#packStates(): Map<String, AssetPackState>
Java
Map<String, AssetPackState> AssetPackStates#packStates()
La solicitud final se muestra mediante lo siguiente:
Kotlin
const val assetPackName = "assetPackName" coroutineScope.launch { try { val assetPackStates: AssetPackStates = manager.requestPackStates(listOf(assetPackName)) val assetPackState: AssetPackState = assetPackStates.packStates()[assetPackName] } catch (e: RuntimeExecutionException) { Log.d("MainActivity", e.message) } }
Java
final String assetPackName = "myasset"; assetPackManager .getPackStates(Collections.singletonList(assetPackName)) .addOnCompleteListener(new OnCompleteListener<AssetPackStates>() { @Override public void onComplete(Task<AssetPackStates> task) { AssetPackStates assetPackStates; try { assetPackStates = task.getResult(); AssetPackState assetPackState = assetPackStates.packStates().get(assetPackName); } catch (RuntimeExecutionException e) { Log.d("MainActivity", e.getMessage()); return; })
Los siguientes métodos AssetPackState
proporcionan el tamaño del paquete de elementos, la cantidad descargada hasta el momento (si se solicita) y la cantidad que ya se transfirió a la app:
Para obtener el estado de un paquete de elementos, usa el status()
que muestra el estado como un número entero que corresponde a un campo constante en la clase AssetPackStatus
. Un paquete de elementos que aún no está instalado aún tiene el estado AssetPackStatus.NOT_INSTALLED
.
Si falla una solicitud, usa el método errorCode()
, cuyo valor que se muestra corresponde a un campo constante en la clase AssetPackErrorCode
.
Instalar
Usa el método requestFetch()
o fetch()
para descargar un paquete de recursos por primera vez o realiza la llamada a fin de que se complete la actualización de un paquete:
Kotlin
suspend fun AssetPackManager.requestFetch(packs: List<String>): AssetPackStates
Java
Task<AssetPackStates> fetch(List<String> packNames)
Este método muestra un objeto AssetPackStates
que contiene una lista de paquetes y sus estados y tamaños de descarga iniciales.
Si ya se está descargando un paquete de recursos solicitado a través de requestFetch()
o fetch()
, se mostrará el estado de descarga y no se iniciará ninguna descarga adicional.
Supervisa los estados de descarga
Debes implementar un objeto AssetPackStateUpdatedListener
para realizar un seguimiento del progreso de la instalación de paquetes de recursos. Las actualizaciones de estado se desglosan por paquete para admitir el seguimiento del estado de paquetes de elementos individuales. Puedes comenzar a usar los paquetes de elementos disponibles antes de que se completen todas las demás descargas de la solicitud.
Kotlin
fun registerListener(listener: AssetPackStateUpdatedListener) fun unregisterListener(listener: AssetPackStateUpdatedListener)
Java
void registerListener(AssetPackStateUpdatedListener listener) void unregisterListener(AssetPackStateUpdatedListener listener)
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 continuar 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, esta se detiene y se necesita el consentimiento explícito para 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 a fin de solicitar el consentimiento del usuario, usa el método requestCellularDataConfirmation()
o showCellularDataConfirmation()
.
Ten en cuenta que si la app no llama a este método, la descarga se detiene y se reanudará automáticamente cuando el usuario vuelva a una conexión Wi-Fi.
A continuación, se muestra un ejemplo de implementación de un objeto de escucha:
Kotlin
assetPackManager.registerListener { assetPackState -> when(assetPackState.status()) { AssetPackStatus.PENDING -> { Log.i(TAG, "Pending") } AssetPackStatus.DOWNLOADING -> { val downloaded = assetPackState.bytesDownloaded() val totalSize = assetPackState.totalBytesToDownload() val percent = 100.0 * downloaded / totalSize Log.i(TAG, "PercentDone=" + String.format("%.2f", percent)) } AssetPackStatus.TRANSFERRING -> { // 100% downloaded and assets are being transferred. // Notify user to wait until transfer is complete. } AssetPackStatus.COMPLETED -> { // Asset pack is ready to use. Start the game. } AssetPackStatus.FAILED -> { // Request failed. Notify user. Log.e(TAG, assetPackState.errorCode()) } AssetPackStatus.CANCELED -> { // Request canceled. Notify user. } AssetPackStatus.WAITING_FOR_WIFI -> { if (!waitForWifiConfirmationShown) { coroutineScope.launch { val resultCode = assetPackManager.requestCellularDataConfirmation(this@MainActivity) if (resultCode == RESULT_OK) { Log.d(TAG, "Confirmation dialog has been accepted.") } else if (resultCode == RESULT_CANCELED) { Log.d(TAG, "Confirmation dialog has been denied by the user.") } } waitForWifiConfirmationShown = true } } AssetPackStatus.NOT_INSTALLED -> { // Asset pack is not downloaded yet. } AssetPackStatus.UNKNOWN -> { Log.wtf(TAG, "Asset pack status unknown") } } }
Java
assetPackStateUpdateListener = new AssetPackStateUpdateListener() { @Override public void onStateUpdate(AssetPackState assetPackState) { switch (assetPackState.status()) { case AssetPackStatus.PENDING: Log.i(TAG, "Pending"); break; case AssetPackStatus.DOWNLOADING: long downloaded = assetPackState.bytesDownloaded(); long totalSize = assetPackState.totalBytesToDownload(); double percent = 100.0 * downloaded / totalSize; Log.i(TAG, "PercentDone=" + String.format("%.2f", percent)); break; case AssetPackStatus.TRANSFERRING: // 100% downloaded and assets are being transferred. // Notify user to wait until transfer is complete. break; case AssetPackStatus.COMPLETED: // Asset pack is ready to use. Start the game. break; case AssetPackStatus.FAILED: // Request failed. Notify user. Log.e(TAG, assetPackState.errorCode()); break; case AssetPackStatus.CANCELED: // Request canceled. Notify user. break; case AssetPackStatus.WAITING_FOR_WIFI: if (!waitForWifiConfirmationShown) { assetPackManager.showCellularDataConfirmation(MainActivity.this) .addOnSuccessListener(new OnSuccessListener<Integer> () { @Override public void onSuccess(Integer resultCode) { if (resultCode == RESULT_OK) { Log.d(TAG, "Confirmation dialog has been accepted."); } else if (resultCode == RESULT_CANCELED) { Log.d(TAG, "Confirmation dialog has been denied by the user."); } } }); waitForWifiConfirmationShown = true; } break; case AssetPackStatus.NOT_INSTALLED: // Asset pack is not downloaded yet. break; case AssetPackStatus.UNKNOWN: Log.wtf(TAG, "Asset pack status unknown") break; } } }
También puedes usar el método getPackStates()
para obtener el estado de las descargas actuales.
AssetPackStates
contiene el progreso de descarga, el estado de descarga y los códigos de error con fallas.
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 alcanza el estado COMPLETED
. Usa el método getPackLocation()
para obtener la carpeta raíz del paquete de elementos.
Los elementos se almacenan en el directorio assets
dentro del directorio raíz del paquete de elementos. Puedes obtener la ruta al directorio assets
con el método útil assetsPath()
.
Usa el siguiente método para obtener la ruta a un elemento específico:
Kotlin
private fun getAbsoluteAssetPath(assetPack: String, relativeAssetPath: String): String? { val assetPackPath: AssetPackLocation = assetPackManager.getPackLocation(assetPack) // asset pack is not ready ?: return null val assetsFolderPath = assetPackPath.assetsPath() // equivalent to: FilenameUtils.concat(assetPackPath.path(), "assets") return FilenameUtils.concat(assetsFolderPath, relativeAssetPath) }
Java
private String getAbsoluteAssetPath(String assetPack, String relativeAssetPath) { AssetPackLocation assetPackPath = assetPackManager.getPackLocation(assetPack); if (assetPackPath == null) { // asset pack is not ready return null; } String assetsFolderPath = assetPackPath.assetsPath(); // equivalent to: FilenameUtils.concat(assetPackPath.path(), "assets"); String assetPath = FilenameUtils.concat(assetsFolderPath, relativeAssetPath); return assetPath; }
Otros métodos de la API de Play Asset Delivery
Estos son algunos métodos de API adicionales que te recomendamos que uses en tu app.
Cancelar solicitud
Usa cancel()
para cancelar una solicitud activa de paquete de elementos. Ten en cuenta que esta solicitud es una operación de mejor esfuerzo.
Quita un paquete de elementos
Usa el método requestRemovePack()
o removePack()
para programar la eliminación de un paquete de recursos.
Obtén las ubicaciones de varios paquetes de elementos
Usa getPackLocations()
para consultar el estado de varios paquetes de elementos de forma masiva, lo que muestra un mapa de los paquetes de elementos y sus ubicaciones. El mapa que muestra getPackLocations()
contiene una entrada para cada paquete que se descarga y está actualizado.
Siguiente paso
Prueba Play Asset Delivery de forma local y desde Google Play.