ทำตามขั้นตอนในคู่มือนี้เพื่อเข้าถึง Asset Pack ของแอปจากโค้ด Java
สร้างสำหรับ Kotlin และ Java
ทำตามขั้นตอนต่อไปนี้เพื่อสร้างการนำส่งเนื้อหา Play ลงใน Android App Bundle ของโปรเจ็กต์ คุณไม่จำเป็นต้องใช้ Android Studio เพื่อทำตามขั้นตอนเหล่านี้
อัปเดตเวอร์ชันของปลั๊กอิน Android Gradle ในไฟล์
build.gradleของโปรเจ็กต์เป็น4.0.0ขึ้นไปสร้างไดเรกทอรีสำหรับ Asset Pack ในไดเรกทอรีระดับบนสุดของโปรเจ็กต์ ระบบจะใช้ชื่อไดเรกทอรีนี้เป็นชื่อ Asset Pack ชื่อ Asset Pack ต้องขึ้นต้นด้วยตัวอักษรและมีได้เฉพาะตัวอักษร ตัวเลข และ ขีดล่างเท่านั้น
สร้างไฟล์
build.gradleในไดเรกทอรี Asset Pack แล้วเพิ่มโค้ดต่อไปนี้ โปรดระบุชื่อของ Asset Pack และประเภทการนำส่งเพียงประเภทเดียวดึงดูด
// 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 ]") } }
ในไฟล์แอปของโปรเจ็กต์
build.gradleให้เพิ่มชื่อของทุกๆ Asset Pack ในโปรเจ็กต์ตามที่แสดงด้านล่างดึงดูด
// 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") }
ในไฟล์
settings.gradleของโปรเจ็กต์ ให้รวมแพ็กชิ้นงานทั้งหมดไว้ใน โปรเจ็กต์ตามที่แสดงด้านล่างดึงดูด
// 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")
ในไดเรกทอรี Asset Pack ให้สร้างไดเรกทอรีย่อยต่อไปนี้
src/main/assetsวางชิ้นงานในไดเรกทอรี
src/main/assetsคุณยังสร้าง ไดเรกทอรีย่อยในนี้ได้ด้วย ตอนนี้โครงสร้างไดเรกทอรีของแอปควรมีลักษณะดังนี้build.gradlesettings.gradleapp/asset-pack-name/build.gradleasset-pack-name/src/main/assets/your-asset-directories
สร้าง Android App Bundle ด้วย Gradle ใน App Bundle ที่สร้างขึ้น ไดเรกทอรีระดับรูทจะมีรายการต่อไปนี้
asset-pack-name/manifest/AndroidManifest.xml: กำหนดค่าตัวระบุและวิธีการส่งข้อมูลราคาของ Asset Packasset-pack-name/assets/your-asset-directories: ไดเรกทอรีที่มีชิ้นงานทั้งหมดที่ส่งเป็นส่วนหนึ่งของ Asset Pack
Gradle จะสร้างไฟล์ Manifest สำหรับแต่ละ Asset Pack และเอาต์พุต
assets/ไดเรกทอรีให้คุณ(ไม่บังคับ) ใส่ไลบรารีการนำส่งเนื้อหา Play หากวางแผนที่จะใช้การนำส่งแบบดาวน์โหลดอัตโนมัติและแบบออนดีมานด์
ดึงดูด
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")
(ไม่บังคับ) กำหนดค่า App Bundle เพื่อรองรับรูปแบบการบีบอัด พื้นผิวที่แตกต่างกัน
ผสานรวมกับการนำส่งเนื้อหา Play API
การนำส่งเนื้อหา Play Java API มีคลาส AssetPackManager สำหรับการขอ Asset Pack, การจัดการการดาวน์โหลด และการเข้าถึงเนื้อหา อย่าลืมเพิ่มไลบรารีการนำส่งเนื้อหา Play ลงในโปรเจ็กต์ก่อน
คุณจะใช้ API นี้ตามประเภทการนำส่งของ Asset Pack ที่ต้องการเข้าถึง ขั้นตอนเหล่านี้แสดงในโฟลว์ชาร์ตต่อไปนี้
รูปที่ 1 แผนภาพโฟลว์สำหรับการเข้าถึงแพ็กเกจเนื้อหา
การนำส่งเมื่อติดตั้ง
แพ็กเกจชิ้นงานที่กำหนดค่าเป็น install-time จะพร้อมใช้งานทันทีเมื่อเปิดแอป
ใช้ Java
AssetManager API เพื่อเข้าถึงชิ้นงาน
ที่แสดงในโหมดนี้
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");
การดาวน์โหลดอัตโนมัติและการนำส่งแบบออนดีมานด์
ส่วนต่อไปนี้จะแสดงวิธีรับข้อมูลเกี่ยวกับ Asset Pack ก่อนดาวน์โหลด วิธีเรียก API เพื่อเริ่มดาวน์โหลด และวิธีเข้าถึงแพ็กที่ดาวน์โหลด ส่วนเหล่านี้มีผลกับ Asset Pack fast-follow และ on-demand
ตรวจสอบสถานะ
ระบบจะจัดเก็บ Asset Pack แต่ละรายการไว้ในโฟลเดอร์แยกต่างหากในที่จัดเก็บข้อมูลภายในของแอป
ใช้เมธอด
getPackLocation()
เพื่อกำหนดโฟลเดอร์รูทของ Asset Pack เมธอดนี้จะแสดงค่าต่อไปนี้
| แสดงผลค่า | สถานะ |
|---|---|
ออบเจ็กต์ AssetPackLocation ที่ถูกต้อง |
โฟลเดอร์รูทของ Asset Pack พร้อมให้เข้าถึงได้ทันทีที่ assetsPath() |
null |
ไม่รู้จัก Asset Pack หรือชิ้นงานไม่พร้อมใช้งาน |
ดูข้อมูลการดาวน์โหลดเกี่ยวกับ Asset Pack
แอปต้องเปิดเผยขนาดของการดาวน์โหลดก่อนที่จะดึงข้อมูลแพ็กเกจเนื้อหา
ใช้เมธอด
requestPackStates()
หรือ getPackStates()
เพื่อกำหนดขนาดของการดาวน์โหลดและดูว่าแพ็กกำลังดาวน์โหลดอยู่หรือไม่
Kotlin
suspend fun requestPackStates(packNames: List<String>): AssetPackStates
Java
Task<AssetPackStates> getPackStates(List<String> packNames)
requestPackStates() เป็นฟังก์ชันระงับที่แสดงผลออบเจ็กต์
AssetPackStates
ส่วน getPackStates() เป็นเมธอดแบบอะซิงโครนัสที่แสดงผล Task<AssetPackStates> เมธอด
packStates()
ของออบเจ็กต์ AssetPackStates จะแสดงผล Map<String,
AssetPackState> แผนที่นี้มีสถานะของแพ็กเนื้อหาที่ขอแต่ละรายการ โดยมีชื่อเป็นคีย์
Kotlin
AssetPackStates#packStates(): Map<String, AssetPackState>
Java
Map<String, AssetPackState> AssetPackStates#packStates()
คำขอสุดท้ายจะแสดงโดยข้อมูลต่อไปนี้
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; })
เมธอดต่อไปนี้
AssetPackState
จะระบุขนาดของ Asset Pack, จำนวนที่ดาวน์โหลดไปแล้ว (หาก
มีการขอ) และจำนวนที่โอนไปยังแอปแล้ว
หากต้องการดูสถานะของ Asset Pack ให้ใช้เมธอด
status()
ซึ่งจะแสดงผลสถานะเป็นจำนวนเต็มที่สอดคล้องกับฟิลด์ค่าคงที่
ในคลาส
AssetPackStatus Asset Pack ที่ยังไม่ได้ติดตั้งจะมีสถานะเป็น
AssetPackStatus.NOT_INSTALLED
หากคำขอไม่สำเร็จ ให้ใช้เมธอด
errorCode()
ซึ่งค่าที่ส่งคืนจะสอดคล้องกับฟิลด์ค่าคงที่ในคลาส
AssetPackErrorCode
ติดตั้ง
ใช้วิธี requestFetch() หรือ
fetch()
เพื่อดาวน์โหลด Asset Pack เป็นครั้งแรก หรือเรียกการอัปเดต Asset Pack ให้เสร็จสมบูรณ์
Kotlin
suspend fun AssetPackManager.requestFetch(packs: List<String>): AssetPackStates
Java
Task<AssetPackStates> fetch(List<String> packNames)
เมธอดนี้จะแสดงออบเจ็กต์
AssetPackStates
ที่มีรายการแพ็ก สถานะการดาวน์โหลดเริ่มต้น และขนาดของแพ็ก
หากมีการดาวน์โหลด Asset Pack ที่ขอผ่าน requestFetch() หรือ fetch() อยู่แล้ว ระบบจะแสดงสถานะการดาวน์โหลดและจะไม่เริ่มการดาวน์โหลดเพิ่มเติม
ตรวจสอบสถานะการดาวน์โหลด
คุณควรใช้
AssetPackStateUpdatedListener
เพื่อติดตามความคืบหน้าในการติดตั้งแพ็กเกจเนื้อหา การอัปเดตสถานะจะแบ่งตามแพ็กเพื่อรองรับการติดตามสถานะของ Asset Pack แต่ละรายการ คุณเริ่มใช้แพ็กเกจชิ้นงานที่มีอยู่ได้
ก่อนที่การดาวน์โหลดอื่นๆ ทั้งหมดสำหรับคำขอจะเสร็จสมบูรณ์
Kotlin
fun registerListener(listener: AssetPackStateUpdatedListener) fun unregisterListener(listener: AssetPackStateUpdatedListener)
Java
void registerListener(AssetPackStateUpdatedListener listener) void unregisterListener(AssetPackStateUpdatedListener listener)
การดาวน์โหลดขนาดใหญ่
หากการดาวน์โหลดมีขนาดใหญ่กว่า 200 MB และผู้ใช้ไม่ได้ใช้ Wi-Fi การดาวน์โหลดจะไม่เริ่มจนกว่าผู้ใช้จะให้ความยินยอมอย่างชัดแจ้งเพื่อดำเนินการดาวน์โหลดต่อโดยใช้การเชื่อมต่ออินเทอร์เน็ตมือถือ ในทำนองเดียวกัน หากการดาวน์โหลดมีขนาดใหญ่และ
ผู้ใช้ไม่ได้เชื่อมต่อ Wi-Fi ระบบจะหยุดการดาวน์โหลดชั่วคราวและต้องได้รับความยินยอมอย่างชัดแจ้งเพื่อ
ดำเนินการต่อโดยใช้การเชื่อมต่ออินเทอร์เน็ตมือถือ แพ็กที่หยุดชั่วคราวจะมีสถานะ
WAITING_FOR_WIFI หากต้องการทริกเกอร์โฟลว์ UI เพื่อแจ้งให้ผู้ใช้ขอความยินยอม ให้ใช้เมธอด showConfirmationDialog()
โปรดทราบว่าหากแอปไม่เรียกใช้เมธอดนี้ ระบบจะหยุดการดาวน์โหลดชั่วคราวและจะ กลับมาดำเนินการต่อโดยอัตโนมัติเมื่อผู้ใช้กลับมาเชื่อมต่อ Wi-Fi เท่านั้น
การยืนยันผู้ใช้ที่จำเป็น
หากแพ็กมีสถานะ REQUIRES_USER_CONFIRMATION การดาวน์โหลดจะไม่
ดำเนินการต่อจนกว่าผู้ใช้จะยอมรับกล่องโต้ตอบที่แสดงพร้อมกับ
showConfirmationDialog()
สถานะนี้อาจเกิดขึ้นเมื่อ Play ไม่รู้จักแอป เช่น หากมีการโหลดแอปจากแหล่งที่ไม่รู้จัก
โปรดทราบว่าการเรียกใช้
showConfirmationDialog()
ในกรณีนี้จะทําให้แอปได้รับการอัปเดต หลังจากอัปเดตแล้ว คุณจะต้องขอชิ้นงานอีกครั้ง
ตัวอย่างการใช้งาน 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; } } }
หรือจะใช้วิธี
getPackStates()
เพื่อดูสถานะของการดาวน์โหลดปัจจุบันก็ได้
AssetPackStates
มีข้อมูลความคืบหน้าในการดาวน์โหลด สถานะการดาวน์โหลด และรหัสข้อผิดพลาดที่เกิดจากความล้มเหลว
เข้าถึง Asset Pack
คุณเข้าถึง Asset Pack ได้โดยใช้การเรียก ระบบไฟล์ หลังจากคำขอดาวน์โหลด ไปถึงสถานะ COMPLETED ใช้เมธอด
getPackLocation()
เพื่อรับโฟลเดอร์รูทของ Asset Pack
ชิ้นงานจะถูกจัดเก็บไว้ในไดเรกทอรี assets ภายในไดเรกทอรีรูทของ Asset Pack คุณรับเส้นทางไปยังไดเรกทอรี assets ได้โดยใช้วิธี
ที่สะดวก
assetsPath()
ใช้วิธีการต่อไปนี้เพื่อรับเส้นทางไปยังชิ้นงานที่เฉพาะเจาะจง
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; }
เมธอดอื่นๆ ของ Play Asset Delivery API
ต่อไปนี้คือเมธอด API เพิ่มเติมบางส่วนที่คุณอาจต้องการใช้ในแอป
ยกเลิกคำขอ
ใช้
cancel()
เพื่อยกเลิกคำขอ Asset Pack ที่ใช้งานอยู่ โปรดทราบว่าคำขอนี้เป็นการดำเนินการ
ตามความสามารถที่ดีที่สุด
นำ Asset Pack ออก
ใช้
requestRemovePack()
หรือ
removePack()
เพื่อกำหนดเวลาการนำ Asset Pack ออก
รับตำแหน่งของแพ็กชิ้นงานหลายรายการ
ใช้
getPackLocations()
เพื่อค้นหาสถานะของ Asset Pack หลายรายการพร้อมกัน ซึ่งจะแสดงแผนที่ของ
Asset Pack และตำแหน่งของ Asset Pack แผนที่ที่ getPackLocations()
ส่งคืนจะมีรายการสำหรับแต่ละแพ็กที่ดาวน์โหลดและเป็นเวอร์ชันล่าสุดในขณะนั้น
ขั้นตอนถัดไป
ทดสอบการนำส่งเนื้อหา Play ในเครื่องและจาก Google Play