Gunakan langkah-langkah dalam panduan ini untuk mengakses paket aset aplikasi Anda dari kode Java.
Membangun untuk Kotlin dan Java
Gunakan langkah-langkah berikut untuk mem-build Play Asset Delivery ke dalam Android App Bundle project Anda. Anda tidak perlu menggunakan Android Studio untuk melakukan langkah-langkah ini.
Update versi plugin Android Gradle di file
build.gradle
project Anda ke4.0.0
atau yang lebih baru.Di direktori level teratas project Anda, buat direktori untuk paket aset. Nama direktori ini digunakan sebagai nama paket aset. Nama paket aset harus diawali dengan huruf dan hanya boleh berisi huruf, angka, dan garis bawah.
Dalam direktori paket aset, buat file
build.gradle
dan tambahkan kode berikut. Pastikan untuk menentukan nama paket aset dan satu jenis pengiriman saja: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 ]") } }
Pada file
build.gradle
aplikasi di project, tambahkan nama setiap paket aset dalam project Anda seperti yang ditunjukkan di bawah ini: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") }
Dalam file
settings.gradle
project, sertakan semua paket aset dalam project Anda seperti yang ditunjukkan di bawah ini: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")
Dalam direktori paket aset, buat subdirektori berikut:
src/main/assets
Tempatkan aset di direktori
src/main/assets
. Anda juga dapat membuat subdirektori di sini. Struktur direktori untuk aplikasi Anda sekarang akan terlihat seperti berikut:build.gradle
settings.gradle
app/
asset-pack-name/build.gradle
asset-pack-name/src/main/assets/your-asset-directories
Buat Android App Bundle menggunakan Gradle. Dalam app bundle yang dihasilkan, direktori level root kini menyertakan hal berikut:
asset-pack-name/manifest/AndroidManifest.xml
: Mengonfigurasi mode pengiriman dan ID paket asetasset-pack-name/assets/your-asset-directories
: Direktori yang berisi semua aset yang dikirim sebagai bagian dari paket aset
Gradle menghasilkan manifes untuk setiap paket aset dan menghasilkan direktori
assets/
untuk Anda.(Opsional) Sertakan Library Play Asset Delivery jika Anda berencana menggunakan pengiriman fast-follow dan sesuai permintaan
Groovy
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")
(Opsional) Konfigurasikan app bundle Anda untuk mendukung berbagai format kompresi tekstur.
Mengintegrasikan dengan Play Asset Delivery API
Play Asset Delivery Java API
menyediakan
class AssetPackManager
untuk meminta paket aset, mengelola download, dan mengakses aset. Pastikan untuk terlebih dahulu Menambahkan Library Play Asset Delivery ke project Anda.
Anda menerapkan API ini sesuai dengan jenis pengiriman paket aset yang ingin Anda akses. Langkah-langkah ini ditampilkan dalam diagram alir berikut.
Pengiriman saat penginstalan
Paket aset yang dikonfigurasi sebagai install-time
akan segera tersedia saat aplikasi diluncurkan. Gunakan Java
AssetManager API untuk mengakses aset yang ditayangkan dalam mode ini:
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");
Pengiriman fast-follow dan sesuai permintaan
Bagian berikut menunjukkan cara memperoleh informasi tentang paket aset sebelum
didownload, cara memanggil API untuk memulai download, lalu cara
mengakses paket yang didownload. Bagian ini berlaku untuk paket aset fast-follow
dan
on-demand
.
Memeriksa status
Setiap paket aset disimpan dalam folder terpisah dalam penyimpanan internal aplikasi.
Gunakan metode
getPackLocation()
untuk menentukan folder utama paket aset. Metode ini akan menampilkan nilai berikut:
Nilai yang ditampilkan | Status |
---|---|
Objek AssetPackLocation yang valid |
Folder utama paket aset siap untuk akses langsung di assetsPath() |
null |
Paket aset tidak dikenal atau aset tidak tersedia |
Mendapatkan informasi download tentang paket aset
Aplikasi wajib mengungkapkan ukuran
download sebelum mengambil paket aset. Gunakan metode requestPackStates()
atau getPackStates()
untuk menentukan ukuran download dan mengetahui apakah paket sudah mulai didownload atau belum.
Kotlin
suspend fun requestPackStates(packNames: List<String>): AssetPackStates
Java
Task<AssetPackStates> getPackStates(List<String> packNames)
requestPackStates()
adalah fungsi penangguhan yang menampilkan
objek AssetPackStates
,
sedangkan getPackStates()
adalah metode asinkron yang menampilkan Task<AssetPackStates>
. Metode
packStates()
dari objek AssetPackStates
akan menampilkan Map<String,
AssetPackState>
. Peta ini berisi status setiap paket
aset yang diminta, yang terkunci berdasarkan namanya:
Kotlin
AssetPackStates#packStates(): Map<String, AssetPackState>
Java
Map<String, AssetPackState> AssetPackStates#packStates()
Permintaan akhir ditunjukkan oleh hal berikut:
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; })
Metode
AssetPackState
berikut memberikan ukuran paket aset, jumlah yang didownload sejauh ini (jika
diminta), dan jumlah yang telah ditransfer ke aplikasi:
Untuk mendapatkan status paket aset, gunakan metode status()
, yang menampilkan status sebagai bilangan bulat yang sesuai dengan bidang konstan di class AssetPackStatus
. Paket aset yang belum diinstal akan menampilkan status
AssetPackStatus.NOT_INSTALLED
.
Jika permintaan gagal, gunakan
metode errorCode()
,
yang nilai return-nya sesuai dengan bidang
konstan di class
AssetPackErrorCode
.
Instal
Gunakan requestFetch()
atau
fetch()
untuk mendownload paket aset untuk pertama kalinya atau meminta update
paket aset yang perlu diselesaikan:
Kotlin
suspend fun AssetPackManager.requestFetch(packs: List<String>): AssetPackStates
Java
Task<AssetPackStates> fetch(List<String> packNames)
Metode ini menampilkan objek AssetPackStates
yang berisi daftar paket serta status dan ukuran download awal.
Jika paket aset yang diminta melalui requestFetch()
atau fetch()
sudah mulai didownload, status download akan ditampilkan dan tidak ada download tambahan yang dimulai.
Memantau status download
Anda harus mengimplementasikan
AssetPackStateUpdatedListener
untuk melacak progres penginstalan paket
aset. Update status dikelompokkan per paket untuk mendukung pelacakan
status setiap paket aset. Anda dapat mulai menggunakan paket aset yang tersedia sebelum semua download permintaan Anda lainnya sudah selesai.
Kotlin
fun registerListener(listener: AssetPackStateUpdatedListener) fun unregisterListener(listener: AssetPackStateUpdatedListener)
Java
void registerListener(AssetPackStateUpdatedListener listener) void unregisterListener(AssetPackStateUpdatedListener listener)
Hasil download berukuran besar
Jika hasil download lebih besar dari 200 MB dan pengguna tidak menggunakan Wi-Fi, download tidak akan dimulai sebelum pengguna memberikan izin secara eksplisit untuk melanjutkan download dengan menggunakan koneksi data seluler. Demikian pula, jika hasil download berukuran besar dan pengguna terputus dari Wi-Fi, download akan dijeda dan izin eksplisit diperlukan untuk melanjutkan proses melalui koneksi data seluler. Paket yang dijeda akan berstatus WAITING_FOR_WIFI
. Untuk memicu alur UI yang meminta pengguna memberikan izin, gunakan metode showConfirmationDialog()
.
Perhatikan jika aplikasi tidak memanggil metode ini, download akan dijeda dan akan dilanjutkan secara otomatis hanya saat pengguna kembali berada dalam koneksi Wi-Fi.
Konfirmasi pengguna yang diperlukan
Jika paket memiliki status REQUIRES_USER_CONFIRMATION
, download tidak akan
lanjut sampai pengguna menerima dialog yang ditampilkan dengan
showConfirmationDialog()
.
Status ini dapat terjadi jika aplikasi tidak dikenali oleh Play—misalnya, jika
aplikasi di-sideload.
Perhatikan bahwa memanggil
showConfirmationDialog()
dalam hal ini akan menyebabkan aplikasi diupdate. Setelah update, Anda harus
meminta aset lagi.
Berikut adalah contoh penerapan pemroses:
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; } } }
Atau, Anda dapat menggunakan metode getPackStates()
untuk mendapatkan status download saat ini.
AssetPackStates
berisi progres download, status download, dan kode error kegagalan.
Mengakses paket aset
Anda dapat mengakses paket aset menggunakan panggilan sistem file setelah permintaan download mencapai status COMPLETED
. Gunakan metode getPackLocation()
untuk mendapatkan folder utama paket aset.
Aset disimpan di direktori assets
dalam direktori utama paket aset. Anda dapat memperoleh jalur ke direktori assets
dengan menggunakan metode praktis assetsPath()
.
Gunakan metode berikut untuk memperoleh jalur ke aset tertentu:
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; }
Metode Play Asset Delivery API lainnya
Berikut ini adalah beberapa metode API tambahan yang mungkin ingin Anda gunakan pada aplikasi.
Membatalkan permintaan
Gunakan
cancel()
untuk membatalkan permintaan paket aset aktif. Perhatikan bahwa permintaan ini adalah operasi dengan upaya terbaik.
Menghapus paket aset
Gunakan
requestRemovePack()
atau
removePack()
untuk menjadwalkan penghapusan paket aset.
Mendapatkan lokasi beberapa paket aset
Gunakan
getPackLocations()
untuk membuat kueri status beberapa paket aset sekaligus, yang menampilkan peta
paket aset dan lokasinya. Peta yang ditampilkan oleh getPackLocations()
berisi entri untuk setiap paket yang saat ini didownload dan sudah diupdate.
Langkah berikutnya
Uji Play Asset Delivery secara lokal dan dari Google Play.