از مراحل این راهنما برای دسترسی به بستههای دارایی برنامه خود از کد جاوا استفاده کنید.
ساخت برای کاتلین و جاوا
از مراحل زیر برای ایجاد 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 آزمایش کنید .