يمكنك الاستعانة بالخطوات الواردة في هذا الدليل للوصول إلى حِزم مواد العرض لتطبيقك من خلال رمز Java.
إنشاء تطبيقات لـ Kotlin وJava
اتّبِع الخطوات التالية لإنشاء ميزة "إرسال مواد العرض في Play" في ملف APK لتطبيق Android في مشروعك. لست بحاجة إلى استخدام "استوديو Android" لتنفيذ هذه الخطوات.
عدِّل إصدار المكوّن الإضافي لنظام Gradle المتوافق مع Android في ملف
build.gradle
الخاص بمشروعك إلى4.0.0
أو إصدار أحدث.في دليل المستوى الأعلى من مشروعك، أنشئ دليلاً لحزمة مواد العرض. يُستخدَم اسم الدليل هذا كاسم لحزمة مواد العرض. يجب أن تبدأ أسماء حِزم مواد العرض بحرف، ويمكن أن تحتوي فقط على أحرف وأرقام وشرطات سفلية.
في دليل حزمة مواد العرض، أنشِئ ملف
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 ]" } }
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
الخاص بتطبيق المشروع، أضِف اسم كل حزمة مواد عرض في مشروعك على النحو الموضّح أدناه:رائع
// 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")
في دليل حِزمة مواد العرض، أنشئ الدليل الفرعي التالي:
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 باستخدام Gradle في حِزمة التطبيق التي تم إنشاؤها، يتضمّن الدليل على مستوى الجذر الآن ما يلي:
-
asset-pack-name/manifest/AndroidManifest.xml
: يضبط معرّف حزمة مواد العرض ووضع إرسالها. -
asset-pack-name/assets/your-asset-directories
: دليل يحتوي على جميع مواد العرض التي تم إرسالها كجزء من حزمة مواد العرض
ينشئ Gradle البيان لكل حزمة مواد عرض ويُخرج لك الدليل
assets/
.-
(اختياري) تضمين مكتبة إرسال مواد العرض في Play إذا كنت تخطّط لاستخدام ميزة "العرض المباشر" وميزة "العرض عند الطلب"
رائع
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
توفّر واجهة برمجة التطبيقات Java API لميزة "عرض المواد في Play"
الفئة
AssetPackManager
لطلب حِزم مواد العرض وإدارة عمليات التنزيل والوصول إلى مواد العرض. احرص على إضافة مكتبة "عرض مواد في Play" إلى مشروعك أولاً.
يتم تنفيذ واجهة برمجة التطبيقات هذه وفقًا لنوع عرض حزمة مواد العرض التي تريد الوصول إليها. يتم عرض هذه الخطوات في المخطط الانسيابي التالي.
العرض في وقت التثبيت
تتوفّر حِزم مواد العرض التي تم ضبطها لتكون install-time
على الفور
عند تشغيل التطبيق. استخدِم واجهة برمجة تطبيقات AssetManager في 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
و
on-demand
.
فحص الحالة
يتم تخزين كل حزمة مواد عرض في مجلد منفصل على وحدة التخزين الداخلية للتطبيق.
استخدِم الطريقة
getPackLocation()
لتحديد المجلد الجذر لحزمة مواد العرض. تُرجع هذه الطريقة
القيم التالية:
القيمة المعروضة | الحالة |
---|---|
عنصر AssetPackLocation صالح |
المجلد الجذر لحزمة مواد العرض جاهز للوصول إليه على الفور على الرابط assetsPath() . |
null |
لا تتوفّر حزمة مواد عرض أو مواد عرض غير معروفة. |
الحصول على معلومات حول تنزيل حِزم مواد العرض
على التطبيقات الإفصاح عن حجم الملف الذي يتم تنزيله قبل جلب حِزمة مواد العرض. استخدِم الطريقة
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
حجم حزمة مواد العرض والكمية التي تم تنزيلها حتى الآن (إذا
طُلب ذلك) والكمية التي تم نقلها إلى التطبيق:
للحصول على حالة حزمة مواد عرض، استخدِم الطريقة
status()
التي تعرض الحالة كعدد صحيح يقابل حقلاً
ثابتًا في الفئة
AssetPackStatus
. إنّ حِزمة مواد العرض غير المثبَّتة بعد تتضمّن الحالة
AssetPackStatus.NOT_INSTALLED
.
إذا تعذّر تنفيذ أحد الطلبات، استخدِم الطريقة
errorCode()
التي تتوافق قيمتها المعروضة مع حقل ثابت في الفئة
AssetPackErrorCode
.
تثبيت
استخدِم الطريقة requestFetch()
أو
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)
عمليات تنزيل كبيرة الحجم
إذا كان حجم التنزيل أكبر من 200 ميغابايت ولم يكن المستخدم متصلاً بشبكة Wi-Fi، لن يبدأ التنزيل
حتى يمنح المستخدم موافقته صراحةً على مواصلة
عملية التنزيل باستخدام اتصال بيانات الجوّال. وبالمثل، إذا كان حجم التنزيل كبيرًا وفقدان المستخدم شبكة Wi-Fi، يتم إيقاف التنزيل مؤقتًا ويجب الحصول على موافقة صريحة للمتابعة باستخدام اتصال بيانات الجوّال. تتضمّن الحزمة التي تم إيقافها مؤقتًا الحالة
WAITING_FOR_WIFI
. لبدء مسار واجهة المستخدم لطلب الموافقة من المستخدم، استخدِم 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; } } }
بدلاً من ذلك، يمكنك استخدام الوسيطة
getPackStates()
للحصول على حالة عمليات التنزيل الحالية.
AssetPackStates
تتضمّن هذه السمة مستوى تقدّم عملية التنزيل وحالتها وأي رموز خطأ متعلّقة بتعذُّر التنزيل.
الوصول إلى حِزم مواد العرض
يمكنك الوصول إلى حزمة مواد عرض باستخدام طلبات نظام الملفات بعد وصول طلب التنزيل
إلى الحالة
COMPLETED
. استخدِم الأسلوب
getPackLocation()
للحصول على المجلد الجذر لحزمة مواد العرض.
يتم تخزين مواد العرض في الدليل assets
ضمن الدليل الجذر
لحزمة مواد العرض. يمكنك الحصول على مسار دليل 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
في ما يلي بعض الطرق الإضافية لواجهة برمجة التطبيقات التي قد تريد استخدامها في تطبيقك.
إلغاء الطلب
استخدِم الرمز
cancel()
لإلغاء طلب حزمة مواد عرض نشط. يُرجى العِلم بأنّ هذا الطلب هو
أفضل عملية جهد.
إزالة حزمة مواد عرض
استخدِم
requestRemovePack()
أو
removePack()
لتحديد موعد إزالة حزمة مواد عرض.
الحصول على مواقع جغرافية لحِزم مواد عرض متعدّدة
استخدِم
getPackLocations()
للتحقّق من حالة حِزم مواد عرض متعددة بشكل مجمّع، ما يؤدي إلى عرض خريطة لمواد العرض وحِزمها ومواقعها الجغرافية. تحتوي الخريطة التي تعرضها الدالة getPackLocations()
على إدخال لكل حزمة تم تنزيلها حاليًا وتعديلها.
الخطوة التالية
اختبار ميزة "عرض المواد في Play" على الجهاز وعلى Google Play