Folgen Sie der Anleitung in diesem Artikel, um über Ihren Java-Code auf die Asset-Packs Ihrer App zuzugreifen.
Für Kotlin und Java entwickeln
Führen Sie die folgenden Schritte aus, um Play Asset Delivery in das Android App Bundle Ihres Projekts einzubinden. Sie müssen Android Studio nicht verwenden, um diese Schritte auszuführen.
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. Asset-Pack-Namen müssen mit einem Buchstaben beginnen und dürfen nur Buchstaben, Zahlen und Unterstriche enthalten.
Erstellen Sie im Asset-Pack-Verzeichnis eine
build.gradle
-Datei und fügen Sie den folgenden Code hinzu. Geben Sie den Namen des Asset-Packs und nur einen Bereitstellungstyp an: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 ]") } }
Fügen Sie in der Datei
build.gradle
der App des Projekts den Namen jedes Asset-Packs in Ihrem Projekt ein, wie unten gezeigt: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") }
Fügen Sie in die Datei
settings.gradle
des Projekts alle Asset-Packs ein, die in Ihrem Projekt enthalten sind, wie unten gezeigt: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")
Erstellen Sie im Asset-Pack-Verzeichnis das folgende Unterverzeichnis:
src/main/assets
.Legen Sie Assets im Verzeichnis
src/main/assets
ab. Sie können hier auch Unterverzeichnisse erstellen. Die Verzeichnisstruktur für Ihre App 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 Stammebene jetzt Folgendes:
asset-pack-name/manifest/AndroidManifest.xml
: Konfiguriert die Kennung und den Bereitstellungsmodus des Asset-Packs.asset-pack-name/assets/your-asset-directories
: Verzeichnis, das alle Assets enthält, die als Teil des Asset-Packs bereitgestellt werden
Gradle generiert das Manifest für jedes Asset-Pack und gibt das Verzeichnis
assets/
aus.Optional: Fügen Sie die Play Asset Delivery Library hinzu, wenn Sie die schnelle Bereitstellung und die Bereitstellung auf Abruf verwenden möchten.
Groovy
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")
Optional: Konfigurieren Sie Ihr App-Bundle so, dass verschiedene Texturkomprimierungsformate unterstützt werden.
Integration in die Play Asset Delivery API
Die Play Asset Delivery Java API bietet die Klasse AssetPackManager
zum Anfordern von Asset-Packs, Verwalten von Downloads und Zugreifen auf die Assets. Fügen Sie zuerst die Play Asset Delivery-Bibliothek in Ihr Projekt ein.
Sie implementieren diese API entsprechend dem Bereitstellungstyp des Asset-Packs, auf das Sie zugreifen möchten. Diese Schritte werden im folgenden Flussdiagramm dargestellt.
Abbildung 1: Flussdiagramm für den Zugriff auf Asset-Packs
Bereitstellung bei der Installation
Als install-time
konfigurierte Asset-Packs sind sofort beim Start der App verfügbar. Verwenden Sie die Java-AssetManager API, um auf Assets zuzugreifen, 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");
Fast-Follow- und On-Demand-Bereitstellung
In den folgenden Abschnitten wird beschrieben, wie Sie Informationen zu Asset-Packs abrufen, bevor Sie sie herunterladen, wie Sie die API aufrufen, um den Download zu starten, und wie Sie dann auf die heruntergeladenen Packs zugreifen. Diese Abschnitte gelten für fast-follow
- und on-demand
-Asset-Packs.
Status prüfen
Jedes Asset-Pack wird im internen Speicher der App in einem separaten Ordner 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 |
Der Stammordner des Asset-Packs ist unter assetsPath() sofort verfügbar. |
null |
Unbekanntes Asset-Pack oder Assets sind nicht verfügbar |
Downloadinformationen zu Asset-Packs abrufen
Apps müssen die Größe des Downloads angeben, bevor das Asset-Pack abgerufen wird. Verwenden Sie die Methode requestPackStates()
oder getPackStates()
, um die Größe des Downloads zu ermitteln und festzustellen, ob das Paket bereits heruntergeladen wird.
Kotlin
suspend fun requestPackStates(packNames: List<String>): AssetPackStates
Java
Task<AssetPackStates> getPackStates(List<String> packNames)
requestPackStates()
ist eine suspend-Funktion, die ein AssetPackStates
-Objekt zurückgibt, während getPackStates()
eine asynchrone Methode ist, die ein Task<AssetPackStates>
zurückgibt. Die Methode packStates()
eines AssetPackStates
-Objekts gibt einen Map<String,
AssetPackState>
zurück. Diese Map enthält den Status jedes angeforderten Asset-Packs, das nach seinem Namen indexiert wird:
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 die bereits an die App übertragene Menge zurück:
Verwenden Sie die Methode status()
, um den Status eines Asset-Packs abzurufen. Der Status wird als Ganzzahl zurückgegeben, 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
Verwenden Sie die Methode requestFetch()
oder fetch()
, um ein Asset-Pack zum ersten Mal herunterzuladen oder ein Update eines Asset-Packs anzufordern:
Kotlin
suspend fun AssetPackManager.requestFetch(packs: List<String>): AssetPackStates
Java
Task<AssetPackStates> fetch(List<String> packNames)
Diese Methode gibt ein AssetPackStates
-Objekt mit einer Liste von Packs und ihren anfänglichen Downloadstatus und -größen zurück.
Wenn ein über requestFetch()
oder fetch()
angefordertes Asset-Pack bereits heruntergeladen wird, wird der Downloadstatus zurückgegeben und kein zusätzlicher Download gestartet.
Downloadstatus überwachen
Sie sollten ein AssetPackStateUpdatedListener
implementieren, um den Installationsfortschritt von Asset-Packs zu verfolgen. Die Statusaktualisierungen werden nach Paket aufgeschlüsselt, damit 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
Wenn der Download größer als 200 MB ist und der Nutzer nicht mit einem WLAN verbunden ist, wird der Download erst gestartet, wenn der Nutzer ausdrücklich seine Einwilligung dazu gibt, den Download über eine mobile Datenverbindung fortzusetzen. Wenn der Download groß ist und der Nutzer die WLAN-Verbindung verliert, wird der Download pausiert. Für die Fortsetzung über eine mobile Datenverbindung ist eine ausdrückliche Einwilligung erforderlich. Ein pausiertes Paket hat den Status WAITING_FOR_WIFI
. Verwenden Sie die Methode showConfirmationDialog()
, um den UI-Ablauf auszulösen, in dem der Nutzer um die Einwilligung gebeten wird.
Wenn die App diese Methode nicht aufruft, wird der Download pausiert und erst dann automatisch fortgesetzt, wenn der Nutzer wieder mit einem WLAN verbunden ist.
Erforderliche Nutzerbestätigung
Wenn ein Paket den Status REQUIRES_USER_CONFIRMATION
hat, wird der Download erst fortgesetzt, wenn der Nutzer das Dialogfeld mit showConfirmationDialog()
akzeptiert.
Dieser Status kann auftreten, wenn die App von Play nicht erkannt wird, z. B. wenn sie per Sideloading installiert wurde.
Wenn Sie in diesem Fall showConfirmationDialog()
aufrufen, wird die App aktualisiert. Nach dem Update müssen Sie die Assets noch einmal anfordern.
Im Folgenden finden Sie ein Beispiel für die Implementierung 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 mit der Methode getPackStates()
den Status aktueller Downloads abrufen.
AssetPackStates
enthält den Downloadfortschritt, den Downloadstatus und alle Fehlercodes für Fehler.
Auf Asset-Packs zugreifen
Sie können nach dem Herunterladen mit Dateisystemaufrufen auf ein Asset-Pack zugreifen, sobald die Downloadanfrage den Status COMPLETED
erreicht hat. Mit der Methode getPackLocation()
können Sie den Stammordner des Asset-Packs abrufen.
Assets werden im Verzeichnis assets
im Stammverzeichnis des Asset-Packs gespeichert. Sie können den Pfad zum assets
-Verzeichnis mit der Hilfsmethode 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 Play Asset Delivery API-Methoden
Im Folgenden finden Sie einige zusätzliche API-Methoden, die Sie in Ihrer App verwenden können.
Anfrage abbrechen
Mit cancel()
können Sie eine aktive Asset-Pack-Anfrage abbrechen. Beachten Sie, dass diese Anfrage auf Best-Effort-Basis erfolgt.
Asset-Pack entfernen
Verwenden Sie requestRemovePack()
oder removePack()
, um das Entfernen eines Asset-Packs zu planen.
Standorte mehrerer Asset-Packs abrufen
Verwenden Sie getPackLocations()
, um den Status mehrerer Asset-Packs gleichzeitig abzufragen. Dadurch wird eine Karte der Asset-Packs und ihrer Speicherorte zurückgegeben. Die von getPackLocations()
zurückgegebene Karte enthält einen Eintrag für jedes Paket, das derzeit heruntergeladen und auf dem neuesten Stand ist.
Nächster Schritt
Play Asset Delivery lokal und über Google Play testen