دمج عرض مواد العرض (Kotlin وJava)

استخدِم الخطوات الواردة في هذا الدليل للوصول إلى حِزم مواد العرض في تطبيقك من خلال Java. الرمز.

إنشاء تطبيقات لـ Kotlin وJava

اتّبِع الخطوات التالية لإضافة ميزة "عرض المواد في Play" إلى نظام Android الخاص بمشروعك مجموعة حزمات التطبيق. لست بحاجة إلى استخدام "استوديو Android" لتنفيذ هذه الخطوات.

  1. تحديث إصدار المكوّن الإضافي لنظام Gradle المتوافق مع Android في مخطط مشروعك ملف build.gradle إلى 4.0.0 أو لاحقًا.

  2. إنشاء دليل للأصل في دليل المستوى الأعلى لمشروعك كُمة. يُستخدَم اسم الدليل هذا كاسم لحزمة مواد العرض. أسماء حِزم مواد العرض يجب أن يبدأ بحرف ويمكن أن يحتوي فقط على أحرف وأرقام الشرطات السفلية.

  3. في دليل حِزم مواد العرض، أنشِئ ملف 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 ]")
      }
    }
    
  4. أضِف اسم كل حزمة مواد عرض في ملف 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")
    }
    
  5. في ملف 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")
    
  6. في دليل حزمة مواد العرض، أنشِئ الدليل الفرعي التالي: src/main/assets

  7. ضَع مواد العرض في دليل src/main/assets. يمكنك إنشاء الأدلة الفرعية هنا أيضًا. ينبغي أن تتضمن بنية الدليل لتطبيقك على النحو التالي:

    • build.gradle
    • settings.gradle
    • app/
    • asset-pack-name/build.gradle
    • asset-pack-name/src/main/assets/your-asset-directories
  8. إنشاء "مجموعة حزمات تطبيق Android" باستخدام Gradle في حِزمة التطبيق التي تم إنشاؤها، يشتمل دليل المستوى الجذر الآن على التالي:

    • asset-pack-name/manifest/AndroidManifest.xml: تتيح هذه السياسة ضبط معرّف حزمة مواد العرض ووضع العرض.
    • asset-pack-name/assets/your-asset-directories: الدليل الذي يحتوي على كل مواد العرض المرسَلة كجزء من حزمة مواد العرض

    تُنشئ Gradle البيان لكل حزمة مواد عرض وتُخرج assets/. الدليل.

  9. (اختياري) يمكنك تضمين مكتبة عرض المواد في 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")
    

  10. (اختياري) يمكنك ضبط حِزمة التطبيق للتوافق مع زخارف مختلفة بتنسيقات الضغط

الدمج مع واجهة برمجة التطبيقات Play Asset Delivery API

واجهة برمجة تطبيقات Java لعرض المواد في Play توفير AssetPackManager فئة طلب حِزم مواد العرض وإدارة عمليات التنزيل والوصول إلى مواد العرض. احرص على إضافة مكتبة عرض المواد في Play إلى مشروعك أولاً.

أنت تنفّذ واجهة برمجة التطبيقات هذه وفقًا لنوع إرسال حزمة مواد العرض التي تريدها الوصول إليه. يتم عرض هذه الخطوات في المخطط الانسيابي التالي.

مخطط تدفق حزمة مواد العرض للغة البرمجة Java

الشكل 1. مخطط انسيابي للوصول إلى حِزم مواد العرض

التسليم في وقت التثبيت

تتوفّر على الفور في التطبيق حِزم مواد العرض التي تم ضبطها لتكون install-time. إطلاقه. استخدام جافا AssetManager API للوصول إلى مواد العرض يتم عرضها في هذا الوضع:

Kotlin

import android.content.res.AssetManager
...
val context: Context = createPackageContext("com.example.app", 0)
val assetManager: AssetManager = context.assets
val stream: InputStream = assetManager.open("asset-name")

Java

import android.content.res.AssetManager;
...
Context context = createPackageContext("com.example.app", 0);
AssetManager assetManager = context.getAssets();
InputStream is = assetManager.open("asset-name");

متابعة سريعة وتوصيل عند الطلب

توضّح الأقسام التالية كيفية الحصول على معلومات حول حِزم مواد العرض قبل وتنزيلها، وكيفية طلب بيانات من واجهة برمجة التطبيقات لبدء التنزيل، ثم كيفية الوصول إلى الحزم التي تم تنزيلها. تنطبق هذه الأقسام على 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.