Folgen Sie den Schritten in diesem Leitfaden, um über Ihren Java-Code auf die Asset-Packs Ihrer App zuzugreifen.
Build für Kotlin und Java
Führe die folgenden Schritte aus, um Play Asset Delivery im Android App Bundle deines Projekts zu integrieren. Sie müssen für diese Schritte nicht Android Studio verwenden.
Aktualisieren Sie die Version des Android-Gradle-Plug-ins in der Datei
build.gradle
Ihres Projekts auf4.0.0
oder höher.Erstellen Sie im obersten Verzeichnis Ihres Projekts ein Verzeichnis für das Asset-Pack. Dieser Verzeichnisname wird als Name des Asset-Packs verwendet. Namen von Asset-Packs müssen mit einem Buchstaben beginnen und dürfen nur Buchstaben, Ziffern und Unterstriche enthalten.
Erstellen Sie im Verzeichnis des Asset-Packs eine
build.gradle
-Datei und fügen Sie den folgenden Code hinzu. Gib den Namen des Asset-Packs und nur einen Übermittlungstyp an:Cool
// 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 ]") } }
Fügen Sie in der App-Datei
build.gradle
des Projekts die Namen aller Asset-Packs in Ihrem Projekt hinzu, wie unten gezeigt:Cool
// 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") }
Fügen Sie in der Datei
settings.gradle
des Projekts alle Asset-Packs wie unten gezeigt in Ihr Projekt ein:Cool
// 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")
Erstellen Sie im Verzeichnis des Asset-Packs das folgende Unterverzeichnis:
src/main/assets
.Platzieren Sie Assets im Verzeichnis
src/main/assets
. Hier können Sie auch Unterverzeichnisse erstellen. Die Verzeichnisstruktur für Ihre Anwendung sollte jetzt so aussehen:build.gradle
settings.gradle
app/
asset-pack-name/build.gradle
asset-pack-name/src/main/assets/your-asset-directories
Android App Bundle mit Gradle erstellen Im generierten App-Bundle enthält das Verzeichnis auf Stammverzeichnisebene jetzt Folgendes:
asset-pack-name/manifest/AndroidManifest.xml
: Konfiguriert die Kennung und den Übermittlungsmodus des Asset-Packsasset-pack-name/assets/your-asset-directories
: Verzeichnis, das alle Assets enthält, die als Teil des Asset-Packs übermittelt wurden
Gradle generiert das Manifest für jedes Asset-Pack und gibt das Verzeichnis
assets/
für Sie aus.Optional: Fügen Sie die Play Asset Delivery Library hinzu, wenn Sie die Fast-Follow- und On-Demand-Übermittlung verwenden möchten.
Cool
implementation "com.google.android.play:asset-delivery:2.2.2" // For Kotlin use asset-delivery-ktx implementation "com.google.android.play:asset-delivery-ktx:2.2.2"
Kotlin
implementation("com.google.android.play:asset-delivery:2.2.2") // For Kotlin use core-ktx implementation("com.google.android.play:asset-delivery-ktx:2.2.2")
(Optional) Konfiguriere dein App Bundle so, dass es verschiedene Texturkomprimierungsformate unterstützt.
In die Play Asset Delivery API einbinden
Die Play Asset Delivery Java API bietet die AssetPackManager
-Klasse zum Anfordern von Asset-Packs, zum Verwalten von Downloads und zum Zugriff auf Assets. Sie müssen Ihrem Projekt zuerst die Asset Delivery-Bibliothek von Google Play hinzufügen.
Die Implementierung dieser API richtet sich nach der Art der Übermittlung des Asset-Packs, auf das du zugreifen möchtest. Diese Schritte sind im folgenden Flussdiagramm dargestellt.
Installationszeitpunkt
Als install-time
konfigurierte Asset-Packs sind sofort beim Start der App verfügbar. Mit der Java AssetManager API kannst du auf Assets zugreifen, die in diesem Modus bereitgestellt werden:
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");
Schnelle Folgen- und On-Demand-Bereitstellung
In den folgenden Abschnitten erfahren Sie, wie Sie vor dem Herunterladen Informationen zu Asset-Packs abrufen, die API aufrufen, um den Download zu starten, und wie Sie auf die heruntergeladenen Pakete zugreifen. Diese Abschnitte gelten für Asset-Packs fast-follow
und on-demand
.
Status prüfen
Jedes Asset-Pack wird in einem separaten Ordner im internen Speicher der App gespeichert.
Verwenden Sie die Methode getPackLocation()
, um den Stammordner eines Asset-Packs zu ermitteln. Diese Methode gibt die folgenden Werte zurück:
Rückgabewert | Status |
---|---|
Ein gültiges AssetPackLocation -Objekt |
Stammordner des Asset-Packs ist bereit für sofortigen Zugriff unter assetsPath() |
null |
Unbekanntes Asset-Pack oder unbekannte Assets sind nicht verfügbar |
Downloadinformationen zu Asset-Packs
Apps müssen die Größe des Downloads angeben, bevor das Asset-Pack abgerufen werden kann. Mit der Methode requestPackStates()
oder getPackStates()
kannst du die Größe des Downloads ermitteln und feststellen, ob das Paket bereits heruntergeladen wird.
Kotlin
suspend fun requestPackStates(packNames: List<String>): AssetPackStates
Java
Task<AssetPackStates> getPackStates(List<String> packNames)
requestPackStates()
ist eine Sperrfunktion, die ein AssetPackStates
-Objekt zurückgibt, während getPackStates()
eine asynchrone Methode ist, die einen Task<AssetPackStates>
zurückgibt. Die Methode packStates()
eines AssetPackStates
-Objekts gibt ein Map<String,
AssetPackState>
zurück. Diese Zuordnung enthält den Status jedes angeforderten Asset-Packs, aufgeschlüsselt nach seinem Namen:
Kotlin
AssetPackStates#packStates(): Map<String, AssetPackState>
Java
Map<String, AssetPackState> AssetPackStates#packStates()
Die endgültige Anfrage sieht so aus:
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; })
Die folgenden AssetPackState
-Methoden geben die Größe des Asset-Packs, die bisher heruntergeladene Menge (falls angefordert) und den bereits an die App übertragenen Betrag an:
Verwenden Sie zum Abrufen des Status eines Asset-Packs die Methode status()
, die den Status als Ganzzahl zurückgibt, die einem konstanten Feld in der Klasse AssetPackStatus
entspricht. Ein Asset-Pack, das noch nicht installiert ist, hat den Status AssetPackStatus.NOT_INSTALLED
.
Wenn eine Anfrage fehlschlägt, verwenden Sie die Methode errorCode()
, deren Rückgabewert einem konstanten Feld in der Klasse AssetPackErrorCode
entspricht.
Installieren
Verwende die Methode requestFetch()
oder fetch()
, um ein Asset-Pack zum ersten Mal herunterzuladen oder die Aktualisierung eines Asset-Packs aufzurufen, um die Aktualisierung abzuschließen:
Kotlin
suspend fun AssetPackManager.requestFetch(packs: List<String>): AssetPackStates
Java
Task<AssetPackStates> fetch(List<String> packNames)
Diese Methode gibt ein AssetPackStates
-Objekt zurück, das eine Liste der Pakete sowie deren anfängliche Downloadstatus und -größe enthält.
Wenn ein über requestFetch()
oder fetch()
angefordertes Asset-Pack bereits heruntergeladen wird, wird der Downloadstatus zurückgegeben und kein weiterer Download gestartet.
Downloadstatus überwachen
Sie sollten eine AssetPackStateUpdatedListener
implementieren, um den Installationsfortschritt von Asset-Packs zu verfolgen. Die Statusaktualisierungen sind nach Paket aufgeschlüsselt, sodass Sie den Status einzelner Asset-Packs verfolgen können. Sie können die verfügbaren Asset-Packs verwenden, bevor alle anderen Downloads für Ihre Anfrage abgeschlossen sind.
Kotlin
fun registerListener(listener: AssetPackStateUpdatedListener) fun unregisterListener(listener: AssetPackStateUpdatedListener)
Java
void registerListener(AssetPackStateUpdatedListener listener) void unregisterListener(AssetPackStateUpdatedListener listener)
Große Downloads
Ist der Download größer als 200 MB und der Nutzer ist nicht mit einem WLAN verbunden, wird der Download erst gestartet, wenn der Nutzer dem Download über eine mobile Datenverbindung ausdrücklich zugestimmt hat. Gleichermaßen wird der Download angehalten, wenn der Download groß ist und der Nutzer die WLAN-Verbindung verliert. In diesem Fall ist eine ausdrückliche Zustimmung erforderlich, um über eine mobile Datenverbindung fortzufahren. Ein pausiertes Paket hat den Status WAITING_FOR_WIFI
. Verwenden Sie die Methode showConfirmationDialog()
, um den UI-Ablauf auszulösen, mit dem der Nutzer um Einwilligung gebeten wird.
Wenn die App diese Methode nicht aufruft, wird der Download angehalten und erst dann automatisch fortgesetzt, wenn der Nutzer wieder eine WLAN-Verbindung hat.
Erforderliche Nutzerbestätigung
Wenn ein Paket den Status REQUIRES_USER_CONFIRMATION
hat, wird der Download erst fortgesetzt, wenn der Nutzer das mit showConfirmationDialog()
angezeigte Dialogfeld akzeptiert.
Dieser Status kann auftreten, wenn die App von Google Play nicht erkannt wird, z. B. wenn sie per Sideload geladen wurde.
Hinweis: Wenn in diesem Fall showConfirmationDialog()
aufgerufen wird, wird die Anwendung aktualisiert. Nach der Aktualisierung müssen
die Assets noch einmal angefordert werden.
Im Folgenden sehen Sie eine Beispielimplementierung eines Listeners:
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; } } }
Alternativ können Sie die Methode getPackStates()
verwenden, um den Status der aktuellen Downloads abzurufen.
AssetPackStates
enthält den Downloadfortschritt, den Downloadstatus und etwaige Fehlercodes.
Auf Asset-Packs zugreifen
Sobald die Downloadanfrage den Status COMPLETED
erreicht hat, können Sie mit Dateisystemaufrufen auf ein Asset-Pack zugreifen. Verwenden Sie die Methode getPackLocation()
, um den Stammordner des Asset-Packs abzurufen.
Assets werden im Verzeichnis assets
des Stammverzeichnisses des Asset-Packs gespeichert. Den Pfad zum Verzeichnis assets
können Sie mit der einfachen Methode assetsPath()
abrufen.
Verwenden Sie die folgende Methode, um den Pfad zu einem bestimmten Asset abzurufen:
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; }
Andere Methoden der Play Asset Delivery API
Im Folgenden finden Sie einige zusätzliche API-Methoden, die Sie in Ihrer App verwenden können.
Anfrage abbrechen
Verwenden Sie cancel()
, um eine aktive Asset-Pack-Anfrage abzubrechen. Bei dieser Anfrage handelt es sich um einen Best-Effort-Vorgang.
Asset-Pack entfernen
Verwenden Sie requestRemovePack()
oder removePack()
, um das Entfernen eines Asset-Packs zu planen.
Standorte mehrerer Asset-Packs abrufen
Mit getPackLocations()
kannst du den Status mehrerer Asset-Packs im Bulk-Verfahren abfragen. Dadurch wird eine Karte mit Asset-Packs und ihren Standorten zurückgegeben. Die von getPackLocations()
zurückgegebene Karte enthält einen Eintrag für jedes Paket, das derzeit heruntergeladen wird und auf dem neuesten Stand ist.
Nächster Schritt
Teste Play Asset Delivery lokal und bei Google Play.