Segui i passaggi descritti in questa guida per accedere ai pacchetti di asset della tua app dal codice Java.
Creare per Kotlin e Java
Segui questi passaggi per creare Play Asset Delivery nell'Android App Bundle del tuo progetto. Non è necessario utilizzare Android Studio per eseguire questi passaggi.
Aggiorna la versione del plug-in Android per Gradle nel file
build.gradledel tuo progetto alla versione4.0.0o successive.Nella directory di primo livello del progetto, crea una directory per il pacchetto di asset. Questo nome di directory viene utilizzato come nome del pacchetto di asset. I nomi dei pacchetti di asset devono iniziare con una lettera e possono contenere solo lettere, numeri e trattini bassi.
Nella directory del pacchetto di asset, crea un file
build.gradlee aggiungi il seguente codice. Assicurati di specificare il nome del pacchetto di asset e un solo tipo di pubblicazione:Alla moda
// 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 ]") } }
Nel file
build.gradledell'app del progetto, aggiungi il nome di ogni pacchetto di asset nel progetto come mostrato di seguito:Alla moda
// 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") }
Nel file
settings.gradledel progetto, includi tutti i pacchetti di asset nel progetto come mostrato di seguito:Alla moda
// 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")
Nella directory del pacchetto di asset, crea la seguente sottodirectory:
src/main/assets.Inserisci gli asset nella directory
src/main/assets. Puoi anche creare sottodirectory qui. La struttura di directory della tua app dovrebbe ora essere simile alla seguente:build.gradlesettings.gradleapp/asset-pack-name/build.gradleasset-pack-name/src/main/assets/your-asset-directories
Crea l'Android App Bundle con Gradle. Nell'app bundle generato, la directory di primo livello ora include quanto segue:
asset-pack-name/manifest/AndroidManifest.xml: configura l'identificatore e la modalità di invio del pacchetto di assetasset-pack-name/assets/your-asset-directories: directory che contiene tutti gli asset pubblicati come parte del pacchetto di asset
Gradle genera il manifest per ogni pacchetto di asset e restituisce la directory
assets/.(Facoltativo) Includi la libreria Play Asset Delivery se prevedi di utilizzare la pubblicazione fast-follow e on demand
Alla moda
implementation "com.google.android.play:asset-delivery:2.3.0" // For Kotlin use asset-delivery-ktx implementation "com.google.android.play:asset-delivery-ktx:2.3.0"
Kotlin
implementation("com.google.android.play:asset-delivery:2.3.0") // For Kotlin use core-ktx implementation("com.google.android.play:asset-delivery-ktx:2.3.0")
(Facoltativo) Configura l'app bundle in modo che supporti diversi formati di compressione delle texture.
Integrare l'API Play Asset Delivery
L'API Java Play Asset Delivery
fornisce la
AssetPackManager
classe per richiedere pacchetti di asset, gestire i download e accedere agli asset. Assicurati di aggiungere prima la libreria Play Asset Delivery al tuo progetto.
Implementa questa API in base al tipo di pubblicazione del pacchetto di asset a cui vuoi accedere. Questi passaggi sono mostrati nel seguente diagramma di flusso.
Figura 1. Diagramma di flusso per l'accesso ai pacchetti di asset
Pubblicazione in fase di installazione
I pacchetti di asset configurati come install-time sono immediatamente disponibili all'avvio dell'app. Utilizza l'API Java
AssetManager per accedere agli asset
pubblicati in questa modalità:
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");
Fast-follow e on demand
Le sezioni seguenti mostrano come ottenere informazioni sui pacchetti di asset prima di scaricarli, come chiamare l'API per avviare il download e come accedere ai pacchetti scaricati. Queste sezioni si applicano ai pacchetti di asset fast-follow e on-demand.
Verifica lo stato
Ogni pacchetto di asset è archiviato in una cartella separata nella memoria interna dell'app.
Utilizza il
getPackLocation()
metodo per determinare la cartella principale di un pacchetto di asset. Questo metodo restituisce i seguenti valori:
| Valore restituito | Stato |
|---|---|
Un oggetto AssetPackLocation valido |
La cartella principale del pacchetto di asset è pronta per l'accesso immediato in assetsPath() |
null |
Pacchetto di asset sconosciuto o asset non disponibili |
Ottenere informazioni sul download dei pacchetti di asset
Le app sono tenute a comunicare le dimensioni del download prima di recuperare il pacchetto di asset. Utilizza il
requestPackStates()
o il getPackStates()
metodo per determinare le dimensioni del download e se il pacchetto è già in fase di
download.
Kotlin
suspend fun requestPackStates(packNames: List<String>): AssetPackStates
Java
Task<AssetPackStates> getPackStates(List<String> packNames)
requestPackStates() è una funzione di sospensione che restituisce un
AssetPackStates
oggetto, mentre getPackStates() è un metodo asincrono che restituisce un Task<AssetPackStates>. Il
packStates()
metodo di un AssetPackStates oggetto restituisce un Map<String,
AssetPackState>. Questa mappa contiene lo stato di ogni pacchetto di asset richiesto, con chiave in base al nome:
Kotlin
AssetPackStates#packStates(): Map<String, AssetPackState>
Java
Map<String, AssetPackState> AssetPackStates#packStates()
La richiesta finale è mostrata di seguito:
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; })
I seguenti
AssetPackState
metodi forniscono le dimensioni del pacchetto di asset, la quantità scaricata finora (se
richiesta) e la quantità già trasferita all'app:
Per ottenere lo stato di un pacchetto di asset, utilizza il
status()
metodo, che restituisce lo stato come numero intero corrispondente a un campo
costante nella classe
AssetPackStatus. Un pacchetto di asset non ancora installato ha lo stato AssetPackStatus.NOT_INSTALLED.
Se una richiesta non va a buon fine, utilizza il
errorCode()
metodo, il cui valore restituito corrisponde a un campo costante nella
AssetPackErrorCode
classe.
Installa
Utilizza il requestFetch() o
fetch()
metodo per scaricare un pacchetto di asset per la prima volta o per richiedere il completamento dell'aggiornamento di un
pacchetto di asset:
Kotlin
suspend fun AssetPackManager.requestFetch(packs: List<String>): AssetPackStates
Java
Task<AssetPackStates> fetch(List<String> packNames)
Questo metodo restituisce un
AssetPackStates
oggetto contenente un elenco di pacchetti e i relativi stati e dimensioni di download iniziali.
Se un pacchetto di asset richiesto tramite requestFetch() o fetch() è già in fase di download, viene restituito lo stato del download e non viene avviato alcun download aggiuntivo.
Monitorare gli stati di download
Devi implementare un
AssetPackStateUpdatedListener
per monitorare l'avanzamento dell'installazione dei pacchetti di asset. Gli aggiornamenti dello stato sono suddivisi per pacchetto per supportare il monitoraggio dello stato dei singoli pacchetti di asset. Puoi iniziare a utilizzare i pacchetti di asset disponibili prima che tutti gli altri download per la tua richiesta siano completati.
Kotlin
fun registerListener(listener: AssetPackStateUpdatedListener) fun unregisterListener(listener: AssetPackStateUpdatedListener)
Java
void registerListener(AssetPackStateUpdatedListener listener) void unregisterListener(AssetPackStateUpdatedListener listener)
Download di grandi dimensioni
Se il download supera i 200 MB e l'utente non è connesso al Wi-Fi, il download non viene avviato finché l'utente non fornisce esplicitamente il consenso a procedere con il download utilizzando una connessione dati mobile. Allo stesso modo, se il download è di grandi dimensioni e l'utente perde la connessione Wi-Fi, il download viene messo in pausa e per procedere utilizzando una connessione dati mobile è necessario il consenso esplicito. Un pacchetto in pausa ha lo stato WAITING_FOR_WIFI. Per attivare il flusso dell'interfaccia utente per richiedere il consenso all'utente, utilizza
il showConfirmationDialog()
metodo.
Tieni presente che se l'app non chiama questo metodo, il download viene messo in pausa e riprenderà automaticamente solo quando l'utente sarà di nuovo connesso al Wi-Fi.
Conferma utente obbligatoria
Se un pacchetto ha lo stato REQUIRES_USER_CONFIRMATION, il download non verrà
eseguito finché l'utente non accetta la finestra di dialogo visualizzata con
showConfirmationDialog().
Questo stato può verificarsi quando l'app non viene riconosciuta da Play, ad esempio se è stata installata tramite sideload.
Tieni presente che la chiamata a
showConfirmationDialog()
in questo caso causerà l'aggiornamento dell'app. Dopo l'aggiornamento, dovrai richiedere di nuovo gli asset.
Di seguito è riportato un esempio di implementazione di un listener:
Kotlin
private val activityResultLauncher = registerForActivityResult( ActivityResultContracts.StartIntentSenderForResult() ) { result -> if (result.resultCode == RESULT_OK) { Log.d(TAG, "Confirmation dialog has been accepted.") } else if (result.resultCode == RESULT_CANCELED) { Log.d(TAG, "Confirmation dialog has been denied by the user.") } } 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, AssetPackStatus.REQUIRES_USER_CONFIRMATION -> { if (!confirmationDialogShown) { assetPackManager.showConfirmationDialog(activityResultLauncher); confirmationDialogShown = true } } AssetPackStatus.NOT_INSTALLED -> { // Asset pack is not downloaded yet. } AssetPackStatus.UNKNOWN -> { Log.wtf(TAG, "Asset pack status unknown") } } }
Java
assetPackStateUpdateListener = new AssetPackStateUpdateListener() { private final ActivityResultLauncher<IntentSenderRequest> activityResultLauncher = registerForActivityResult( new ActivityResultContracts.StartIntentSenderForResult(), new ActivityResultCallback<ActivityResult>() { @Override public void onActivityResult(ActivityResult result) { if (result.getResultCode() == RESULT_OK) { Log.d(TAG, "Confirmation dialog has been accepted."); } else if (result.getResultCode() == RESULT_CANCELED) { Log.d(TAG, "Confirmation dialog has been denied by the user."); } } }); @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: case AssetPackStatus.REQUIRES_USER_CONFIRMATION: if (!confirmationDialogShown) { assetPackManager.showConfirmationDialog(activityResultLauncher); confirmationDialogShown = true; } break; case AssetPackStatus.NOT_INSTALLED: // Asset pack is not downloaded yet. break; case AssetPackStatus.UNKNOWN: Log.wtf(TAG, "Asset pack status unknown") break; } } }
In alternativa, puoi utilizzare il
getPackStates()
metodo per ottenere lo stato dei download in corso.
AssetPackStates
contiene l'avanzamento del download, lo stato del download e tutti i codici di errore in caso di errore.
Accedere ai pacchetti di asset
Puoi accedere a un pacchetto di asset utilizzando le chiamate al file system dopo che la richiesta di download
raggiunge lo
COMPLETED
stato. Utilizza il
getPackLocation()
metodo per ottenere la cartella principale del pacchetto di asset.
Gli asset sono archiviati nella directory assets all'interno della directory principale del pacchetto di asset. Puoi ottenere il percorso della directory assets utilizzando il
metodo pratico
assetsPath().
Utilizza il seguente metodo per ottenere il percorso di un asset specifico:
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; }
Altri metodi dell'API Play Asset Delivery
Di seguito sono riportati alcuni metodi API aggiuntivi che potresti voler utilizzare nella tua app.
Annulla richiesta
Utilizza
cancel()
per annullare una richiesta di pacchetto di asset attiva. Tieni presente che questa richiesta è un'operazione "best effort".
Rimuovere un pacchetto di asset
Utilizza
requestRemovePack()
o
removePack()
per pianificare la rimozione di un pacchetto di asset.
Ottenere le posizioni di più pacchetti di asset
Utilizza
getPackLocations()
per eseguire una query sullo stato di più pacchetti di asset in blocco, che restituisce una mappa dei
pacchetti di asset e delle relative posizioni. La mappa restituita da getPackLocations() contiene una voce per ogni pacchetto attualmente scaricato e aggiornato.
Passaggio successivo
Testa Play Asset Delivery localmente e da Google Play.