از مراحل این راهنما برای دسترسی به بستههای دارایی برنامه خود از کد جاوا استفاده کنید.
ساخت برای کاتلین و جاوا
از مراحل زیر برای ایجاد Play Asset Delivery در بسته نرم افزار Android پروژه خود استفاده کنید. برای انجام این مراحل نیازی به استفاده از اندروید استودیو نیست.
نسخه پلاگین Android Gradle را در فایل
build.gradle
پروژه خود به4.0.0
یا بالاتر به روز کنید.در دایرکتوری سطح بالای پروژه خود، یک دایرکتوری برای بسته دارایی ایجاد کنید. این نام دایرکتوری به عنوان نام بسته دارایی استفاده می شود. نام بسته دارایی باید با یک حرف شروع شود و فقط شامل حروف، اعداد و زیرخط باشد.
در پوشه asset pack یک فایل
build.gradle
ایجاد کنید و کد زیر را اضافه کنید. مطمئن شوید که نام بسته دارایی و فقط یک نوع تحویل را مشخص کنید:شیار
// 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 ]" } }
کاتلین
// 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
برنامه پروژه، نام هر بسته دارایی در پروژه خود را مانند شکل زیر اضافه کنید:شیار
// In the app build.gradle file: android { ... assetPacks = [":asset-pack-name", ":asset-pack2-name"] }
کاتلین
// 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'
کاتلین
// 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
-
بسته نرم افزاری اندروید را با Gradle بسازید . در بسته نرم افزاری تولید شده، دایرکتوری سطح ریشه اکنون شامل موارد زیر است:
-
asset-pack-name /manifest/AndroidManifest.xml
: شناسه بسته دارایی و حالت تحویل را پیکربندی می کند -
asset-pack-name /assets/ your-asset-directories
: فهرستی که شامل تمام دارایی های تحویل شده به عنوان بخشی از بسته دارایی است.
Gradle مانیفست را برای هر بسته دارایی تولید می کند و فهرست
assets/
را برای شما خروجی می دهد.-
(اختیاری) اگر میخواهید از تحویل سریع و درخواستی استفاده کنید ، کتابخانه Play Asset Delivery را اضافه کنید
شیار
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"
کاتلین
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 را به پروژه خود اضافه کنید .
شما این API را با توجه به نوع تحویل بسته دارایی که می خواهید به آن دسترسی داشته باشید پیاده سازی می کنید. این مراحل در فلوچارت زیر نشان داده شده است.
تحویل در زمان نصب
بستههای دارایی که بهعنوان install-time
پیکربندی شدهاند، بلافاصله با راهاندازی برنامه در دسترس هستند. از Java AssetManager API برای دسترسی به دارایی های ارائه شده در این حالت استفاده کنید:
کاتلین
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")
جاوا
import android.content.res.AssetManager; ... Context context = createPackageContext("com.example.app", 0); AssetManager assetManager = context.getAssets(); InputStream is = assetManager.open("asset-name");
تحویل سریع و درخواستی
بخشهای زیر نحوه دریافت اطلاعات بستههای دارایی را قبل از دانلود، نحوه تماس با API برای شروع دانلود و سپس نحوه دسترسی به بستههای دانلود شده نشان میدهد. این بخشها برای بستههای دارایی fast-follow
و on-demand
اعمال میشود.
وضعیت را بررسی کنید
هر بسته دارایی در یک پوشه جداگانه در حافظه داخلی برنامه ذخیره می شود. از متد getPackLocation()
برای تعیین پوشه ریشه یک بسته دارایی استفاده کنید. این متد مقادیر زیر را برمی گرداند:
ارزش برگشتی | وضعیت |
---|---|
یک شیء معتبر AssetPackLocation | پوشه ریشه بسته دارایی برای دسترسی فوری در assetsPath() آماده است. |
null | بسته یا دارایی های ناشناخته در دسترس نیست |
دریافت اطلاعات دانلود در مورد بسته های دارایی
برنامهها باید قبل از واکشی بسته دارایی، اندازه دانلود را فاش کنند. از روش requestPackStates()
یا getPackStates()
برای تعیین اندازه دانلود و اینکه آیا بسته در حال بارگیری است استفاده کنید.
کاتلین
suspend fun requestPackStates(packNames: List<String>): AssetPackStates
جاوا
Task<AssetPackStates> getPackStates(List<String> packNames)
requestPackStates()
یک تابع suspend است که یک شی AssetPackStates
را برمی گرداند در حالی که getPackStates()
یک روش ناهمزمان است که Task<AssetPackStates>
را برمی گرداند. متد packStates()
یک شی AssetPackStates
یک Map<String, AssetPackState>
را برمی گرداند. این نقشه شامل وضعیت هر بسته دارایی درخواستی است که با نام آن کلید زده شده است:
کاتلین
AssetPackStates#packStates(): Map<String, AssetPackState>
جاوا
Map<String, AssetPackState> AssetPackStates#packStates()
درخواست نهایی با موارد زیر نشان داده می شود:
کاتلین
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) } }
جاوا
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
زیر اندازه بسته دارایی، مقدار دانلود شده تا کنون (در صورت درخواست) و مبلغی که قبلاً به برنامه منتقل شده است را ارائه میکند:
برای بدست آوردن وضعیت بسته دارایی، از متد status()
استفاده کنید که وضعیت را به عنوان یک عدد صحیح که مربوط به یک فیلد ثابت در کلاس AssetPackStatus
است، برمی گرداند. بسته دارایی که هنوز نصب نشده است وضعیت AssetPackStatus.NOT_INSTALLED
را دارد.
اگر درخواستی با شکست مواجه شد، از روش errorCode()
استفاده کنید که مقدار بازگشتی آن مربوط به یک فیلد ثابت در کلاس AssetPackErrorCode
است.
نصب کنید
از روش requestFetch()
یا fetch()
برای دانلود یک بسته دارایی برای اولین بار استفاده کنید یا برای تکمیل به روز رسانی یک بسته دارایی تماس بگیرید:
کاتلین
suspend fun AssetPackManager.requestFetch(packs: List<String>): AssetPackStates
جاوا
Task<AssetPackStates> fetch(List<String> packNames)
این روش یک شی AssetPackStates
حاوی لیستی از بسته ها و حالت ها و اندازه های دانلود اولیه آنها را برمی گرداند. اگر بسته دارایی درخواست شده از طریق requestFetch()
یا fetch()
در حال دانلود باشد، وضعیت دانلود برگردانده می شود و دانلود اضافی شروع نمی شود.
وضعیت های دانلود را مانیتور کنید
شما باید یک AssetPackStateUpdatedListener
را برای ردیابی پیشرفت نصب بسته های دارایی پیاده سازی کنید. بهروزرسانیهای وضعیت در هر بسته برای پشتیبانی از ردیابی وضعیت بستههای دارایی جداگانه تجزیه میشوند. میتوانید قبل از تکمیل همه دانلودهای دیگر برای درخواستتان، استفاده از بستههای دارایی موجود را شروع کنید.
کاتلین
fun registerListener(listener: AssetPackStateUpdatedListener) fun unregisterListener(listener: AssetPackStateUpdatedListener)
جاوا
void registerListener(AssetPackStateUpdatedListener listener) void unregisterListener(AssetPackStateUpdatedListener listener)
دانلودهای بزرگ
اگر دانلود بزرگتر از 200 مگابایت باشد و کاربر از Wi-Fi استفاده نکند، دانلود شروع نمی شود تا زمانی که کاربر صریحاً رضایت خود را برای ادامه دانلود با استفاده از اتصال داده تلفن همراه اعلام کند. به همین ترتیب، اگر بارگیری زیاد باشد و کاربر Wi-Fi را از دست بدهد، دانلود متوقف میشود و برای ادامه با استفاده از اتصال داده تلفن همراه، رضایت صریح لازم است. یک بسته متوقف شده دارای وضعیت WAITING_FOR_WIFI
است. برای راه اندازی جریان UI برای درخواست رضایت از کاربر، از متد showConfirmationDialog()
استفاده کنید.
توجه داشته باشید که اگر برنامه این روش را فراخوانی نکند، دانلود متوقف میشود و تنها زمانی که کاربر به اتصال Wi-Fi بازگشته است، بهطور خودکار از سر گرفته میشود.
تایید کاربر مورد نیاز است
اگر بسته ای دارای وضعیت REQUIRES_USER_CONFIRMATION
باشد، دانلود ادامه نمی یابد تا زمانی که کاربر گفتگوی نشان داده شده با showConfirmationDialog()
نپذیرد. این وضعیت زمانی رخ میدهد که برنامه توسط Play شناسایی نشود—مثلاً اگر برنامه از جانبی بارگذاری شده باشد. توجه داشته باشید که فراخوانی showConfirmationDialog()
در این حالت باعث بهروزرسانی برنامه میشود. پس از به روز رسانی، باید دوباره دارایی ها را درخواست کنید.
در زیر نمونه ای از اجرای شنونده است:
کاتلین
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") } } }
جاوا
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
شامل پیشرفت دانلود، وضعیت دانلود و هر گونه کد خطای خطا است.
دسترسی به بسته های دارایی
پس از اینکه درخواست دانلود به حالت COMPLETED
رسید، می توانید با استفاده از تماس های سیستم فایل به بسته دارایی دسترسی داشته باشید. از متد getPackLocation()
برای دریافت پوشه ریشه بسته دارایی استفاده کنید.
دارایی ها در فهرست assets
در دایرکتوری ریشه بسته دارایی ذخیره می شوند. با استفاده از روش راحتی assetsPath()
می توانید مسیر دایرکتوری assets
را دریافت کنید. برای رسیدن به یک دارایی خاص از روش زیر استفاده کنید:
کاتلین
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) }
جاوا
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 را به صورت محلی و از Google Play آزمایش کنید .
،از مراحل این راهنما برای دسترسی به بستههای دارایی برنامه خود از کد جاوا استفاده کنید.
ساخت برای کاتلین و جاوا
از مراحل زیر برای ایجاد Play Asset Delivery در بسته نرم افزار Android پروژه خود استفاده کنید. برای انجام این مراحل نیازی به استفاده از اندروید استودیو نیست.
نسخه پلاگین Android Gradle را در فایل
build.gradle
پروژه خود به4.0.0
یا بالاتر به روز کنید.در دایرکتوری سطح بالای پروژه خود، یک دایرکتوری برای بسته دارایی ایجاد کنید. این نام دایرکتوری به عنوان نام بسته دارایی استفاده می شود. نام بسته دارایی باید با یک حرف شروع شود و فقط شامل حروف، اعداد و زیرخط باشد.
در پوشه asset pack یک فایل
build.gradle
ایجاد کنید و کد زیر را اضافه کنید. مطمئن شوید که نام بسته دارایی و فقط یک نوع تحویل را مشخص کنید:شیار
// 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 ]" } }
کاتلین
// 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
برنامه پروژه، نام هر بسته دارایی در پروژه خود را مانند شکل زیر اضافه کنید:شیار
// In the app build.gradle file: android { ... assetPacks = [":asset-pack-name", ":asset-pack2-name"] }
کاتلین
// 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'
کاتلین
// 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
-
بسته نرم افزاری اندروید را با Gradle بسازید . در بسته نرم افزاری تولید شده، دایرکتوری سطح ریشه اکنون شامل موارد زیر است:
-
asset-pack-name /manifest/AndroidManifest.xml
: شناسه بسته دارایی و حالت تحویل را پیکربندی می کند -
asset-pack-name /assets/ your-asset-directories
: فهرستی که شامل تمام دارایی های تحویل شده به عنوان بخشی از بسته دارایی است.
Gradle مانیفست را برای هر بسته دارایی تولید می کند و فهرست
assets/
را برای شما خروجی می دهد.-
(اختیاری) اگر میخواهید از تحویل سریع و درخواستی استفاده کنید ، کتابخانه Play Asset Delivery را اضافه کنید
شیار
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"
کاتلین
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 را به پروژه خود اضافه کنید .
شما این API را با توجه به نوع تحویل بسته دارایی که می خواهید به آن دسترسی داشته باشید پیاده سازی می کنید. این مراحل در فلوچارت زیر نشان داده شده است.
تحویل در زمان نصب
بستههای دارایی که بهعنوان install-time
پیکربندی شدهاند، بلافاصله با راهاندازی برنامه در دسترس هستند. از Java AssetManager API برای دسترسی به دارایی های ارائه شده در این حالت استفاده کنید:
کاتلین
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")
جاوا
import android.content.res.AssetManager; ... Context context = createPackageContext("com.example.app", 0); AssetManager assetManager = context.getAssets(); InputStream is = assetManager.open("asset-name");
تحویل سریع و درخواستی
بخشهای زیر نحوه دریافت اطلاعات بستههای دارایی را قبل از دانلود، نحوه تماس با API برای شروع دانلود و سپس نحوه دسترسی به بستههای دانلود شده نشان میدهد. این بخشها برای بستههای دارایی fast-follow
و on-demand
اعمال میشود.
وضعیت را بررسی کنید
هر بسته دارایی در یک پوشه جداگانه در حافظه داخلی برنامه ذخیره می شود. از متد getPackLocation()
برای تعیین پوشه ریشه یک بسته دارایی استفاده کنید. این متد مقادیر زیر را برمی گرداند:
ارزش برگشتی | وضعیت |
---|---|
یک شیء معتبر AssetPackLocation | پوشه ریشه بسته دارایی برای دسترسی فوری در assetsPath() آماده است. |
null | بسته یا دارایی های ناشناخته در دسترس نیست |
دریافت اطلاعات دانلود در مورد بسته های دارایی
برنامهها باید قبل از واکشی بسته دارایی، اندازه دانلود را فاش کنند. از روش requestPackStates()
یا getPackStates()
برای تعیین اندازه دانلود و اینکه آیا بسته در حال بارگیری است استفاده کنید.
کاتلین
suspend fun requestPackStates(packNames: List<String>): AssetPackStates
جاوا
Task<AssetPackStates> getPackStates(List<String> packNames)
requestPackStates()
یک تابع suspend است که یک شی AssetPackStates
را برمی گرداند در حالی که getPackStates()
یک روش ناهمزمان است که Task<AssetPackStates>
را برمی گرداند. متد packStates()
یک شی AssetPackStates
یک Map<String, AssetPackState>
را برمی گرداند. این نقشه شامل وضعیت هر بسته دارایی درخواستی است که با نام آن کلید زده شده است:
کاتلین
AssetPackStates#packStates(): Map<String, AssetPackState>
جاوا
Map<String, AssetPackState> AssetPackStates#packStates()
درخواست نهایی با موارد زیر نشان داده می شود:
کاتلین
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) } }
جاوا
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
زیر اندازه بسته دارایی، مقدار دانلود شده تا کنون (در صورت درخواست) و مبلغی که قبلاً به برنامه منتقل شده است را ارائه میکند:
برای بدست آوردن وضعیت بسته دارایی، از متد status()
استفاده کنید که وضعیت را به عنوان یک عدد صحیح که مربوط به یک فیلد ثابت در کلاس AssetPackStatus
است، برمی گرداند. بسته دارایی که هنوز نصب نشده است وضعیت AssetPackStatus.NOT_INSTALLED
را دارد.
اگر درخواستی با شکست مواجه شد، از روش errorCode()
استفاده کنید که مقدار بازگشتی آن مربوط به یک فیلد ثابت در کلاس AssetPackErrorCode
است.
نصب کنید
از روش requestFetch()
یا fetch()
برای دانلود یک بسته دارایی برای اولین بار استفاده کنید یا برای تکمیل به روز رسانی یک بسته دارایی تماس بگیرید:
کاتلین
suspend fun AssetPackManager.requestFetch(packs: List<String>): AssetPackStates
جاوا
Task<AssetPackStates> fetch(List<String> packNames)
این روش یک شی AssetPackStates
حاوی لیستی از بسته ها و حالت ها و اندازه های دانلود اولیه آنها را برمی گرداند. اگر بسته دارایی درخواست شده از طریق requestFetch()
یا fetch()
در حال دانلود باشد، وضعیت دانلود برگردانده می شود و دانلود اضافی شروع نمی شود.
وضعیت های دانلود را مانیتور کنید
شما باید یک AssetPackStateUpdatedListener
را برای ردیابی پیشرفت نصب بسته های دارایی پیاده سازی کنید. بهروزرسانیهای وضعیت در هر بسته برای پشتیبانی از ردیابی وضعیت بستههای دارایی جداگانه تجزیه میشوند. میتوانید قبل از تکمیل همه دانلودهای دیگر برای درخواستتان، استفاده از بستههای دارایی موجود را شروع کنید.
کاتلین
fun registerListener(listener: AssetPackStateUpdatedListener) fun unregisterListener(listener: AssetPackStateUpdatedListener)
جاوا
void registerListener(AssetPackStateUpdatedListener listener) void unregisterListener(AssetPackStateUpdatedListener listener)
دانلودهای بزرگ
اگر دانلود بزرگتر از 200 مگابایت باشد و کاربر از Wi-Fi استفاده نکند، دانلود شروع نمی شود تا زمانی که کاربر صریحاً رضایت خود را برای ادامه دانلود با استفاده از اتصال داده تلفن همراه اعلام کند. به همین ترتیب، اگر بارگیری زیاد باشد و کاربر Wi-Fi را از دست بدهد، دانلود متوقف میشود و برای ادامه با استفاده از اتصال داده تلفن همراه، رضایت صریح لازم است. یک بسته متوقف شده دارای وضعیت WAITING_FOR_WIFI
است. برای راه اندازی جریان UI برای درخواست رضایت از کاربر، از متد showConfirmationDialog()
استفاده کنید.
توجه داشته باشید که اگر برنامه این روش را فراخوانی نکند، دانلود متوقف میشود و تنها زمانی که کاربر به اتصال Wi-Fi بازگشته است، بهطور خودکار از سر گرفته میشود.
تایید کاربر مورد نیاز است
اگر بسته ای دارای وضعیت REQUIRES_USER_CONFIRMATION
باشد، دانلود ادامه نمی یابد تا زمانی که کاربر گفتگوی نشان داده شده با showConfirmationDialog()
نپذیرد. این وضعیت زمانی رخ میدهد که برنامه توسط Play شناسایی نشود—مثلاً اگر برنامه از جانبی بارگذاری شده باشد. توجه داشته باشید که فراخوانی showConfirmationDialog()
در این حالت باعث بهروزرسانی برنامه میشود. پس از به روز رسانی، باید دوباره دارایی ها را درخواست کنید.
در زیر نمونه ای از اجرای شنونده است:
کاتلین
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") } } }
جاوا
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
شامل پیشرفت دانلود، وضعیت دانلود و هر گونه کد خطای خطا است.
دسترسی به بسته های دارایی
پس از اینکه درخواست دانلود به حالت COMPLETED
رسید، می توانید با استفاده از تماس های سیستم فایل به بسته دارایی دسترسی داشته باشید. از متد getPackLocation()
برای دریافت پوشه ریشه بسته دارایی استفاده کنید.
دارایی ها در فهرست assets
در دایرکتوری ریشه بسته دارایی ذخیره می شوند. با استفاده از روش راحتی assetsPath()
می توانید مسیر دایرکتوری assets
را دریافت کنید. برای رسیدن به یک دارایی خاص از روش زیر استفاده کنید:
کاتلین
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) }
جاوا
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 را به صورت محلی و از Google Play آزمایش کنید .
،از مراحل این راهنما برای دسترسی به بستههای دارایی برنامه خود از کد جاوا استفاده کنید.
ساخت برای کاتلین و جاوا
از مراحل زیر برای ایجاد Play Asset Delivery در بسته نرم افزار Android پروژه خود استفاده کنید. برای انجام این مراحل نیازی به استفاده از اندروید استودیو نیست.
نسخه پلاگین Android Gradle را در فایل
build.gradle
پروژه خود به4.0.0
یا بالاتر به روز کنید.در دایرکتوری سطح بالای پروژه خود، یک دایرکتوری برای بسته دارایی ایجاد کنید. این نام دایرکتوری به عنوان نام بسته دارایی استفاده می شود. نام بسته دارایی باید با یک حرف شروع شود و فقط شامل حروف، اعداد و زیرخط باشد.
در پوشه asset pack یک فایل
build.gradle
ایجاد کنید و کد زیر را اضافه کنید. مطمئن شوید که نام بسته دارایی و فقط یک نوع تحویل را مشخص کنید:شیار
// 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 ]" } }
کاتلین
// 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
برنامه پروژه، نام هر بسته دارایی در پروژه خود را مانند شکل زیر اضافه کنید:شیار
// In the app build.gradle file: android { ... assetPacks = [":asset-pack-name", ":asset-pack2-name"] }
کاتلین
// 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'
کاتلین
// 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
-
بسته نرم افزاری اندروید را با Gradle بسازید . در بسته نرم افزاری تولید شده، دایرکتوری سطح ریشه اکنون شامل موارد زیر است:
-
asset-pack-name /manifest/AndroidManifest.xml
: شناسه بسته دارایی و حالت تحویل را پیکربندی می کند -
asset-pack-name /assets/ your-asset-directories
: فهرستی که شامل تمام دارایی های تحویل شده به عنوان بخشی از بسته دارایی است.
Gradle مانیفست را برای هر بسته دارایی تولید می کند و فهرست
assets/
را برای شما خروجی می دهد.-
(اختیاری) اگر میخواهید از تحویل سریع و درخواستی استفاده کنید ، کتابخانه Play Asset Delivery را اضافه کنید
شیار
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"
کاتلین
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 را به پروژه خود اضافه کنید .
شما این API را با توجه به نوع تحویل بسته دارایی که می خواهید به آن دسترسی داشته باشید پیاده سازی می کنید. این مراحل در فلوچارت زیر نشان داده شده است.
تحویل در زمان نصب
بستههای دارایی که بهعنوان install-time
پیکربندی شدهاند، بلافاصله با راهاندازی برنامه در دسترس هستند. از Java AssetManager API برای دسترسی به دارایی های ارائه شده در این حالت استفاده کنید:
کاتلین
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")
جاوا
import android.content.res.AssetManager; ... Context context = createPackageContext("com.example.app", 0); AssetManager assetManager = context.getAssets(); InputStream is = assetManager.open("asset-name");
تحویل سریع و درخواستی
بخشهای زیر نحوه دریافت اطلاعات بستههای دارایی را قبل از دانلود، نحوه تماس با API برای شروع دانلود و سپس نحوه دسترسی به بستههای دانلود شده نشان میدهد. این بخشها برای بستههای دارایی fast-follow
و on-demand
اعمال میشود.
وضعیت را بررسی کنید
هر بسته دارایی در یک پوشه جداگانه در حافظه داخلی برنامه ذخیره می شود. از متد getPackLocation()
برای تعیین پوشه ریشه یک بسته دارایی استفاده کنید. این متد مقادیر زیر را برمی گرداند:
ارزش برگشتی | وضعیت |
---|---|
یک شیء معتبر AssetPackLocation | پوشه ریشه بسته دارایی برای دسترسی فوری در assetsPath() آماده است. |
null | بسته یا دارایی های ناشناخته در دسترس نیست |
دریافت اطلاعات دانلود در مورد بسته های دارایی
برنامهها باید قبل از واکشی بسته دارایی، اندازه دانلود را فاش کنند. از روش requestPackStates()
یا getPackStates()
برای تعیین اندازه دانلود و اینکه آیا بسته در حال بارگیری است استفاده کنید.
کاتلین
suspend fun requestPackStates(packNames: List<String>): AssetPackStates
جاوا
Task<AssetPackStates> getPackStates(List<String> packNames)
requestPackStates()
یک تابع suspend است که یک شی AssetPackStates
را برمی گرداند در حالی که getPackStates()
یک روش ناهمزمان است که Task<AssetPackStates>
را برمی گرداند. متد packStates()
یک شی AssetPackStates
یک Map<String, AssetPackState>
را برمی گرداند. این نقشه شامل وضعیت هر بسته دارایی درخواستی است که با نام آن کلید زده شده است:
کاتلین
AssetPackStates#packStates(): Map<String, AssetPackState>
جاوا
Map<String, AssetPackState> AssetPackStates#packStates()
درخواست نهایی با موارد زیر نشان داده می شود:
کاتلین
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) } }
جاوا
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
زیر اندازه بسته دارایی، مقدار دانلود شده تا کنون (در صورت درخواست) و مبلغی که قبلاً به برنامه منتقل شده است را ارائه میکند:
برای بدست آوردن وضعیت بسته دارایی، از متد status()
استفاده کنید که وضعیت را به عنوان یک عدد صحیح که مربوط به یک فیلد ثابت در کلاس AssetPackStatus
است، برمی گرداند. بسته دارایی که هنوز نصب نشده است وضعیت AssetPackStatus.NOT_INSTALLED
را دارد.
اگر درخواستی با شکست مواجه شد، از روش errorCode()
استفاده کنید که مقدار بازگشتی آن مربوط به یک فیلد ثابت در کلاس AssetPackErrorCode
است.
نصب کنید
از روش requestFetch()
یا fetch()
برای دانلود یک بسته دارایی برای اولین بار استفاده کنید یا برای تکمیل به روز رسانی یک بسته دارایی تماس بگیرید:
کاتلین
suspend fun AssetPackManager.requestFetch(packs: List<String>): AssetPackStates
جاوا
Task<AssetPackStates> fetch(List<String> packNames)
این روش یک شی AssetPackStates
حاوی لیستی از بسته ها و حالت ها و اندازه های دانلود اولیه آنها را برمی گرداند. اگر بسته دارایی درخواست شده از طریق requestFetch()
یا fetch()
در حال دانلود باشد، وضعیت دانلود برگردانده می شود و دانلود اضافی شروع نمی شود.
وضعیت های دانلود را مانیتور کنید
شما باید یک AssetPackStateUpdatedListener
را برای ردیابی پیشرفت نصب بسته های دارایی پیاده سازی کنید. بهروزرسانیهای وضعیت در هر بسته برای پشتیبانی از ردیابی وضعیت بستههای دارایی جداگانه تجزیه میشوند. میتوانید قبل از تکمیل همه دانلودهای دیگر برای درخواستتان، استفاده از بستههای دارایی موجود را شروع کنید.
کاتلین
fun registerListener(listener: AssetPackStateUpdatedListener) fun unregisterListener(listener: AssetPackStateUpdatedListener)
جاوا
void registerListener(AssetPackStateUpdatedListener listener) void unregisterListener(AssetPackStateUpdatedListener listener)
دانلودهای بزرگ
اگر دانلود بزرگتر از 200 مگابایت باشد و کاربر از Wi-Fi استفاده نکند، دانلود شروع نمی شود تا زمانی که کاربر صریحاً رضایت خود را برای ادامه دانلود با استفاده از اتصال داده تلفن همراه اعلام کند. به همین ترتیب، اگر بارگیری زیاد باشد و کاربر Wi-Fi را از دست بدهد، دانلود متوقف میشود و برای ادامه با استفاده از اتصال داده تلفن همراه، رضایت صریح لازم است. یک بسته متوقف شده دارای وضعیت WAITING_FOR_WIFI
است. برای راه اندازی جریان UI برای درخواست رضایت از کاربر، از متد showConfirmationDialog()
استفاده کنید.
توجه داشته باشید که اگر برنامه این روش را فراخوانی نکند، دانلود متوقف میشود و تنها زمانی که کاربر به اتصال Wi-Fi بازگشته است، بهطور خودکار از سر گرفته میشود.
تایید کاربر مورد نیاز است
اگر بسته ای دارای وضعیت REQUIRES_USER_CONFIRMATION
باشد، دانلود ادامه نمی یابد تا زمانی که کاربر گفتگوی نشان داده شده با showConfirmationDialog()
نپذیرد. این وضعیت زمانی رخ میدهد که برنامه توسط Play شناسایی نشود—مثلاً اگر برنامه از جانبی بارگذاری شده باشد. توجه داشته باشید که فراخوانی showConfirmationDialog()
در این حالت باعث بهروزرسانی برنامه میشود. پس از به روز رسانی، باید دوباره دارایی ها را درخواست کنید.
در زیر نمونه ای از اجرای شنونده است:
کاتلین
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") } } }
جاوا
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
شامل پیشرفت دانلود، وضعیت دانلود و هر گونه کد خطای خطا است.
دسترسی به بسته های دارایی
پس از اینکه درخواست دانلود به حالت COMPLETED
رسید، می توانید با استفاده از تماس های سیستم فایل به بسته دارایی دسترسی داشته باشید. از متد getPackLocation()
برای دریافت پوشه ریشه بسته دارایی استفاده کنید.
دارایی ها در فهرست assets
در دایرکتوری ریشه بسته دارایی ذخیره می شوند. با استفاده از روش راحتی assetsPath()
می توانید مسیر دایرکتوری assets
را دریافت کنید. برای رسیدن به یک دارایی خاص از روش زیر استفاده کنید:
کاتلین
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) }
جاوا
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 را به صورت محلی و از Google Play آزمایش کنید .
،از مراحل این راهنما برای دسترسی به بستههای دارایی برنامه خود از کد جاوا استفاده کنید.
ساخت برای کاتلین و جاوا
از مراحل زیر برای ایجاد Play Asset Delivery در بسته نرم افزار Android پروژه خود استفاده کنید. برای انجام این مراحل نیازی به استفاده از اندروید استودیو نیست.
نسخه پلاگین Android Gradle را در فایل
build.gradle
پروژه خود به4.0.0
یا بالاتر به روز کنید.در دایرکتوری سطح بالای پروژه خود، یک دایرکتوری برای بسته دارایی ایجاد کنید. این نام دایرکتوری به عنوان نام بسته دارایی استفاده می شود. نام بسته دارایی باید با یک حرف شروع شود و فقط شامل حروف، اعداد و زیرخط باشد.
در پوشه asset pack یک فایل
build.gradle
ایجاد کنید و کد زیر را اضافه کنید. مطمئن شوید که نام بسته دارایی و فقط یک نوع تحویل را مشخص کنید:شیار
// 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 ]" } }
کاتلین
// 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
برنامه پروژه، نام هر بسته دارایی در پروژه خود را مانند شکل زیر اضافه کنید:شیار
// In the app build.gradle file: android { ... assetPacks = [":asset-pack-name", ":asset-pack2-name"] }
کاتلین
// 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'
کاتلین
// 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
-
بسته نرم افزاری اندروید را با Gradle بسازید . در بسته نرم افزاری تولید شده، دایرکتوری سطح ریشه اکنون شامل موارد زیر است:
-
asset-pack-name /manifest/AndroidManifest.xml
: شناسه بسته دارایی و حالت تحویل را پیکربندی می کند -
asset-pack-name /assets/ your-asset-directories
: فهرستی که شامل تمام دارایی های تحویل شده به عنوان بخشی از بسته دارایی است.
Gradle مانیفست را برای هر بسته دارایی تولید می کند و فهرست
assets/
را برای شما خروجی می دهد.-
(اختیاری) اگر میخواهید از تحویل سریع و درخواستی استفاده کنید ، کتابخانه Play Asset Delivery را اضافه کنید
شیار
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"
کاتلین
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 را به پروژه خود اضافه کنید .
شما این API را با توجه به نوع تحویل بسته دارایی که می خواهید به آن دسترسی داشته باشید پیاده سازی می کنید. این مراحل در فلوچارت زیر نشان داده شده است.
تحویل در زمان نصب
بستههای دارایی که بهعنوان install-time
پیکربندی شدهاند، بلافاصله با راهاندازی برنامه در دسترس هستند. از Java AssetManager API برای دسترسی به دارایی های ارائه شده در این حالت استفاده کنید:
کاتلین
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")
جاوا
import android.content.res.AssetManager; ... Context context = createPackageContext("com.example.app", 0); AssetManager assetManager = context.getAssets(); InputStream is = assetManager.open("asset-name");
تحویل سریع و درخواستی
بخشهای زیر نحوه دریافت اطلاعات بستههای دارایی را قبل از دانلود، نحوه تماس با API برای شروع دانلود و سپس نحوه دسترسی به بستههای دانلود شده نشان میدهد. این بخشها برای بستههای دارایی fast-follow
و on-demand
اعمال میشود.
وضعیت را بررسی کنید
هر بسته دارایی در یک پوشه جداگانه در حافظه داخلی برنامه ذخیره می شود. از متد getPackLocation()
برای تعیین پوشه ریشه یک بسته دارایی استفاده کنید. این متد مقادیر زیر را برمی گرداند:
ارزش برگشتی | وضعیت |
---|---|
یک شیء معتبر AssetPackLocation | پوشه ریشه بسته دارایی برای دسترسی فوری در assetsPath() آماده است. |
null | بسته یا دارایی های ناشناخته در دسترس نیست |
دریافت اطلاعات دانلود در مورد بسته های دارایی
برنامهها باید قبل از واکشی بسته دارایی، اندازه دانلود را فاش کنند. از روش requestPackStates()
یا getPackStates()
برای تعیین اندازه دانلود و اینکه آیا بسته در حال بارگیری است استفاده کنید.
کاتلین
suspend fun requestPackStates(packNames: List<String>): AssetPackStates
جاوا
Task<AssetPackStates> getPackStates(List<String> packNames)
requestPackStates()
یک تابع suspend است که یک شی AssetPackStates
را برمی گرداند در حالی که getPackStates()
یک روش ناهمزمان است که Task<AssetPackStates>
را برمی گرداند. متد packStates()
یک شی AssetPackStates
یک Map<String, AssetPackState>
را برمی گرداند. این نقشه شامل وضعیت هر بسته دارایی درخواستی است که با نام آن کلید زده شده است:
کاتلین
AssetPackStates#packStates(): Map<String, AssetPackState>
جاوا
Map<String, AssetPackState> AssetPackStates#packStates()
درخواست نهایی با موارد زیر نشان داده می شود:
کاتلین
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) } }
جاوا
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
اندازه بسته دارایی ، مبلغ بارگیری شده تاکنون (در صورت درخواست) و مبلغی را که قبلاً به برنامه منتقل شده است ، ارائه می دهد:
برای به دست آوردن وضعیت یک بسته دارایی ، از روش status()
استفاده کنید ، که وضعیت را به عنوان یک عدد صحیح که مربوط به یک قسمت ثابت در کلاس AssetPackStatus
است ، برمی گرداند. یک بسته دارایی که هنوز نصب نشده است دارای وضعیت AssetPackStatus.NOT_INSTALLED
است.
در صورت عدم موفقیت یک درخواست ، از روش errorCode()
استفاده کنید ، که مقدار بازگشت آن با یک قسمت ثابت در کلاس AssetPackErrorCode
مطابقت دارد.
نصب کنید
برای بارگیری یک بسته دارایی برای اولین بار از روش requestFetch()
یا fetch()
استفاده کنید یا برای تکمیل به روزرسانی یک بسته دارایی تماس بگیرید:
کاتلین
suspend fun AssetPackManager.requestFetch(packs: List<String>): AssetPackStates
جاوا
Task<AssetPackStates> fetch(List<String> packNames)
این روش یک شیء AssetPackStates
را شامل می شود که شامل لیستی از بسته ها و حالت های بارگیری اولیه آنها است. اگر یک بسته دارایی که از طریق requestFetch()
یا fetch()
درخواست می شود ، در حال بارگیری است ، وضعیت بارگیری بازگردانده می شود و هیچ بارگیری اضافی شروع نمی شود.
نظارت بر حالتهای بارگیری
برای ردیابی پیشرفت نصب بسته های دارایی ، باید یک AssetPackStateUpdatedListener
را پیاده سازی کنید. به روزرسانی های وضعیت در هر بسته برای پشتیبانی از ردیابی وضعیت بسته های دارایی فردی تقسیم می شوند. می توانید قبل از اتمام همه بارگیری های دیگر برای درخواست خود ، استفاده از بسته های دارایی موجود را شروع کنید.
کاتلین
fun registerListener(listener: AssetPackStateUpdatedListener) fun unregisterListener(listener: AssetPackStateUpdatedListener)
جاوا
void registerListener(AssetPackStateUpdatedListener listener) void unregisterListener(AssetPackStateUpdatedListener listener)
بارگیری های بزرگ
اگر بارگیری از 200 مگابایت بزرگتر باشد و کاربر در Wi-Fi نباشد ، بارگیری شروع نمی شود تا زمانی که کاربر صریحاً رضایت خود را برای انجام بارگیری با استفاده از اتصال داده های موبایل انجام دهد. به همین ترتیب ، اگر بارگیری بزرگ باشد و کاربر Wi-Fi را از دست بدهد ، بارگیری متوقف می شود و رضایت صریح برای استفاده از اتصال داده های تلفن همراه لازم است. یک بسته مکث دارای حالت WAITING_FOR_WIFI
است. برای تحریک جریان UI برای درخواست کاربر برای رضایت ، از روش showConfirmationDialog()
استفاده کنید.
توجه داشته باشید که اگر برنامه با این روش تماس نگیرد ، بارگیری متوقف می شود و فقط در صورت بازگشت کاربر در اتصال Wi-Fi به طور خودکار از سر می گیرد.
تأیید کاربر مورد نیاز
اگر یک بسته وضعیت REQUIRES_USER_CONFIRMATION
را داشته باشد ، بارگیری تا زمانی که کاربر گفت و گو را که با showConfirmationDialog()
ادامه نمی دهد. این وضعیت می تواند زمانی رخ دهد که برنامه توسط PLAY تشخیص داده نشود-برای مثال ، اگر برنامه بار جانبی باشد. توجه داشته باشید که تماس با showConfirmationDialog()
در این حالت باعث به روزرسانی برنامه می شود. پس از بروزرسانی ، باید دوباره دارایی ها را درخواست کنید.
در زیر یک نمونه اجرای شنونده است:
کاتلین
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") } } }
جاوا
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
شامل پیشرفت بارگیری ، وضعیت بارگیری و هرگونه خطای خطای خرابی است.
دسترسی به بسته های دارایی
پس از رسیدن درخواست بارگیری به حالت COMPLETED
، می توانید با استفاده از تماس های سیستم فایل به یک بسته دارایی دسترسی پیدا کنید. برای به دست آوردن پوشه ریشه بسته دارایی از روش getPackLocation()
استفاده کنید.
دارایی ها در فهرست assets
در فهرست ریشه Asset Pack ذخیره می شوند. می توانید با استفاده از روش راحتی assetsPath()
مسیر دایرکتوری assets
را دریافت کنید. از روش زیر استفاده کنید تا مسیر یک دارایی خاص را بدست آورید:
کاتلین
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) }
جاوا
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; }
سایر روشهای API تحویل دارایی بازی
در زیر برخی از روشهای API اضافی که ممکن است بخواهید در برنامه خود استفاده کنید.
لغو درخواست
برای لغو درخواست بسته دارایی فعال از cancel()
استفاده کنید. توجه داشته باشید که این درخواست یک عملیات بهترین تلاش است.
یک بسته دارایی را حذف کنید
برای برنامه ریزی حذف یک بسته دارایی requestRemovePack()
یا removePack()
استفاده کنید.
مکان های چند دارایی را دریافت کنید
برای پرس و جو از وضعیت چندین دارایی به صورت عمده ، از getPackLocations()
استفاده کنید ، که نقشه ای از بسته های دارایی و مکان های آنها را برمی گرداند. نقشه برگشتی توسط getPackLocations()
حاوی ورودی برای هر بسته است که در حال حاضر بارگیری و به روز است.
مرحله بعدی
تست تحویل دارایی را به صورت محلی و از Google Play تست کنید .