בעזרת השלבים במדריך הזה תוכלו לגשת לחבילות הנכסים של האפליקציה מקוד ה-Java.
פיתוח גרסאות build ל-Kotlin ול-Java
כדי להטמיע את Play Asset Delivery בחבילת האפליקציות ל-Android של הפרויקט, פועלים לפי השלבים הבאים. אין צורך להשתמש ב-Android Studio כדי לבצע את השלבים האלה.
מעדכנים את הגרסה של הפלאגין Android Gradle בקובץ
build.gradle
של הפרויקט ל-4.0.0
ואילך.בספרייה ברמה העליונה של הפרויקט, יוצרים ספרייה לחבילת הנכסים. שם הספרייה הזה משמש כשם של חבילת הנכסים. שמות של חבילות נכסים חייבים להתחיל באות ויכולים להכיל רק אותיות, מספרים וקווים תחתונים.
בספריית חבילת הנכסים, יוצרים קובץ
build.gradle
ומוסיפים את הקוד הבא. חשוב לציין את השם של חבילת הנכסים ורק סוג העברה אחד: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 ]") } }
בקובץ
build.gradle
של האפליקציה בפרויקט, מוסיפים את השם של כל חבילת נכסים בפרויקט, כפי שמתואר בהמשך: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") }
בקובץ
settings.gradle
של הפרויקט, צריך לכלול את כל חבילות הנכסים בפרויקט, כפי שמתואר בהמשך: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")
בספרייה של חבילת הנכסים, יוצרים את ספריית המשנה הבאה:
src/main/assets
.מניחים את הנכסים בספרייה
src/main/assets
. אפשר גם ליצור כאן ספריות משנה. מבנה הספריות של האפליקציה אמור להיראות כך:build.gradle
settings.gradle
app/
asset-pack-name/build.gradle
asset-pack-name/src/main/assets/your-asset-directories
פיתוח של Android App Bundle באמצעות Gradle. בחבילת האפליקציות שנוצרה, התיקייה ברמת השורש כוללת עכשיו את הפריטים הבאים:
asset-pack-name/manifest/AndroidManifest.xml
: הגדרת המזהה ושל אופן המסירה של חבילת הנכסיםasset-pack-name/assets/your-asset-directories
: הספרייה שמכילה את כל הנכסים שנשלחים כחלק מחבילת הנכסים
Gradle יוצר את המניפסט לכל חבילת נכסים ומפיק את הספרייה
assets/
בשבילכם.(אופציונלי) אם אתם מתכננים להשתמש בהעברה מסוג fast-follow ובהעברה על פי דרישה, צריך לכלול את ספריית העברת הנכסים של Play.
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")
(אופציונלי) מגדירים את חבילת האפליקציות כך שתתמוך בפורמטים שונים של דחיסת טקסטורות.
שילוב עם Play Asset Delivery API
Play Asset Delivery Java API מספק את הכיתה AssetPackManager
לשליחת בקשות לקבלת חבילות נכסים, לניהול ההורדות ולגישה לנכסים. חשוב להוסיף את ספריית Play Asset Delivery לפרויקט לפני כן.
מטמיעים את ה-API הזה בהתאם לסוג המסירה של חבילת הנכסים שאליה רוצים לגשת. השלבים האלה מוצגים בתרשים התהליך הבא.
העברה בזמן ההתקנה
חבילות נכסים שהוגדרו כ-install-time
זמינות מיידית עם השקת האפליקציה. משתמשים ב-AssetManager API של Java כדי לגשת לנכסים שמוצגים במצב הזה:
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 והפצה על פי דרישה
בקטעים הבאים מוסבר איך לקבל מידע על חבילות נכסים לפני ההורדה, איך לבצע קריאה ל-API כדי להתחיל את ההורדה ואיך לגשת לחבילות שהורדתם. הקטעים האלה חלים על חבילות נכסים מסוג fast-follow
ו-on-demand
.
בדיקת הסטטוס
כל חבילת נכסים מאוחסנת בתיקייה נפרדת באחסון הפנימי של האפליקציה.
משתמשים ב-method getPackLocation()
כדי לקבוע את תיקיית הבסיס של חבילת נכסים. השיטה הזו מחזירה את הערכים הבאים:
הערך המוחזר | סטטוס |
---|---|
אובייקט AssetPackLocation תקין |
תיקיית הבסיס של חבילת הנכסים מוכנה לגישה מיידית בכתובת assetsPath() |
null |
חבילה לא ידועה של נכסים או נכסים לא זמינים |
קבלת מידע על הורדה של חבילות נכסים
האפליקציות נדרשות לחשוף את גודל ההורדה לפני אחזור חבילת הנכסים. משתמשים ב-method requestPackStates()
או ב-method 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
מספקות את גודל חבילת הנכסים, את כמות הנתונים שהורדתם עד כה (אם ביקשת זאת) ואת הסכום שכבר הועבר לאפליקציה:
כדי לקבל את הסטטוס של חבילת נכסים, משתמשים ב-method status()
, שמחזיר את הסטטוס כמספר שלם שתואם לשדה קבוע בכיתה AssetPackStatus
. חבילת נכסים שעדיין לא הותקנה תהיה בסטטוס AssetPackStatus.NOT_INSTALLED
.
אם בקשה נכשלת, משתמשים בשיטה errorCode()
, וערך ההחזרה שלה תואם לשדה קבוע בכיתה AssetPackErrorCode
.
התקנה
משתמשים ב-method requestFetch()
או ב-method fetch()
כדי להוריד חבילת נכסים בפעם הראשונה או כדי לבצע עדכון של חבילת נכסים:
Kotlin
suspend fun AssetPackManager.requestFetch(packs: List<String>): AssetPackStates
Java
Task<AssetPackStates> fetch(List<String> packNames)
השיטה הזו מחזירה אובייקט AssetPackStates
שמכיל רשימה של חבילות, את סטטוס ההורדה הראשוני שלהן ואת הגדלים שלהן.
אם כבר מתבצעת הורדה של חבילת נכסים שהתבקשה באמצעות requestFetch()
או fetch()
, סטטוס ההורדה מוחזר ולא מתחילה הורדה נוספת.
מעקב אחרי מצבי ההורדה
מומלץ להטמיע AssetPackStateUpdatedListener
כדי לעקוב אחרי התקדמות ההתקנה של חבילות הנכסים. עדכוני הסטטוס מפורטים לפי חבילה כדי לאפשר מעקב אחרי הסטטוס של חבילות נכסים ספציפיות. אתם יכולים להתחיל להשתמש בחבילות הנכסים הזמינות לפני שההורדות האחרות של הבקשה יושלמו.
Kotlin
fun registerListener(listener: AssetPackStateUpdatedListener) fun unregisterListener(listener: AssetPackStateUpdatedListener)
Java
void registerListener(AssetPackStateUpdatedListener listener) void unregisterListener(AssetPackStateUpdatedListener listener)
הורדות גדולות
אם ההורדה גדולה מ-200MB והמשתמש לא מחובר לרשת Wi-Fi, ההורדה לא תתחיל עד שהמשתמש ייתן הסכמה מפורשת להמשיך בהורדה באמצעות חיבור לנתונים ניידים. באופן דומה, אם ההורדה גדולה והמשתמש מאבד את החיבור ל-Wi-Fi, ההורדה מושהית ונדרשת הסכמה מפורשת כדי להמשיך אותה באמצעות חיבור לחבילת גלישה. לחבילה מושהית יש את המצב WAITING_FOR_WIFI
. כדי להפעיל את תהליך ממשק המשתמש לבקשת הסכמה מהמשתמש, משתמשים ב-method showConfirmationDialog()
.
חשוב לזכור שאם האפליקציה לא קוראת לשיטה הזו, ההורדה מושהית ותתחדש באופן אוטומטי רק כשהמשתמש יחזור להתחבר לרשת Wi-Fi.
אישור נדרש מהמשתמש
אם לחבילה יש את הסטטוס REQUIRES_USER_CONFIRMATION
, ההורדה לא תמשיך עד שהמשתמש יאשר את תיבת הדו-שיח שמוצגת עם showConfirmationDialog()
.
הסטטוס הזה יכול להופיע אם האפליקציה לא מזוהה על ידי Play – לדוגמה, אם האפליקציה הותקנה ממקור לא ידוע.
לתשומת ליבכם: במקרה כזה, קריאה ל-showConfirmationDialog()
תגרום לעדכון האפליקציה. אחרי העדכון, תצטרכו לבקש שוב את הנכסים.
דוגמה להטמעה של מאזין:
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; } } }
לחלופין, אפשר להשתמש ב-method getPackStates()
כדי לקבל את הסטטוס של ההורדות הנוכחיות.
AssetPackStates
מכיל את התקדמות ההורדה, את סטטוס ההורדה ואת קודי השגיאה של הכשל.
גישה לחבילות של נכסים
אפשר לגשת לחבילת נכסים באמצעות קריאות למערכת הקבצים אחרי שבקשת ההורדה מגיעה לסטטוס COMPLETED
. משתמשים בשיטה getPackLocation()
כדי לקבל את תיקיית הבסיס של חבילת הנכסים.
הנכסים נשמרים בספרייה assets
בספריית הבסיס של חבילת הנכסים. אפשר לקבל את הנתיב לספרייה assets
באמצעות ה-method הנוחה 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()
כדי לבטל בקשה פעילה לחבילת נכסים. חשוב לזכור שהבקשה הזו היא פעולה לפי יכולת.
הסרת חבילת נכסים
אפשר להשתמש ב-requestRemovePack()
או ב-removePack()
כדי לתזמן את ההסרה של חבילת נכסים.
אחזור המיקומים של כמה חבילות נכסים
אפשר להשתמש ב-getPackLocations()
כדי לשלוח שאילתה לגבי הסטטוס של כמה חבילות נכסים בו-זמנית, וכתוצאה מכך תקבלו מפה של חבילות הנכסים והמיקומים שלהן. המפה שמוחזרת על ידי getPackLocations()
מכילה רשומה לכל חבילה שהורדתם כרגע והיא עדכנית.
השלב הבא
בודקים את Play Asset Delivery באופן מקומי ומ-Google Play.