دمج عرض المواد (الأصلي)

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

يتوفّر نموذج لرمز الدمج على GitHub.

Build for Native

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

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

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

  3. في دليل حِزمة مواد العرض، أنشئ ملف 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 ]"
        }
    }
  4. في ملف build.gradle لتطبيق المشروع، أضِف اسم كل حزمة مواد عرض في مشروعك كما هو موضّح أدناه:

    // In the app build.gradle file:
    android {
        ...
        assetPacks = [":asset-pack-name", ":asset-pack2-name"]
    }
  5. في ملف settings.gradle الخاص بالمشروع، أدرِج جميع حِزم مواد العرض في مشروعك كما هو موضّح أدناه:

    // In the settings.gradle 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"

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

مخطّط تدفّق حِزم مواد العرض للرمز البرمجي الأصلي

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

توفّر حزمة تطوير البرامج (SDK) الأصلية لمكتبة Play الأساسية ملف رأس C ‏(play/asset_pack.h) لطلب حِزم مواد العرض وإدارة عمليات التنزيل والوصول إلى مواد العرض.

إعداد بيئة التطوير لحزمة تطوير البرامج (SDK) الأصلية لمكتبة Play Core

تنزيل Play Core Native SDK

قبل تنزيل التطبيق، عليك الموافقة على الأحكام والشروط التالية.

الأحكام والشروط

Last modified: September 24, 2020
  1. By using the Play Core Software Development Kit, you agree to these terms in addition to the Google APIs Terms of Service ("API ToS"). If these terms are ever in conflict, these terms will take precedence over the API ToS. Please read these terms and the API ToS carefully.
  2. For purposes of these terms, "APIs" means Google's APIs, other developer services, and associated software, including any Redistributable Code.
  3. “Redistributable Code” means Google-provided object code or header files that call the APIs.
  4. Subject to these terms and the terms of the API ToS, you may copy and distribute Redistributable Code solely for inclusion as part of your API Client. Google and its licensors own all right, title and interest, including any and all intellectual property and other proprietary rights, in and to Redistributable Code. You will not modify, translate, or create derivative works of Redistributable Code.
  5. Google may make changes to these terms at any time with notice and the opportunity to decline further use of the Play Core Software Development Kit. Google will post notice of modifications to the terms at https://developer.android.com/guide/playcore/license. Changes will not be retroactive.
.
تنزيل Play Core Native SDK

play-core-native-sdk-1.15.3.zip

  1. عليك القيام بأي مما يلي:

    • ثبِّت الإصدار 4.0 من Android Studio أو إصدارًا أحدث. استخدِم واجهة مستخدم "مدير حزمة تطوير البرامج (SDK)" لتثبيت الإصدار 10.0 من "منصّة حزمة تطوير البرامج (SDK) لنظام التشغيل Android" (المستوى 29 من واجهة برمجة التطبيقات).
    • ثبِّت أدوات سطر الأوامر لحزمة تطوير البرامج (SDK) لنظام التشغيل Android واستخدِم sdkmanager لتثبيت الإصدار 10.0 من حزمة تطوير البرامج (SDK) لنظام التشغيل Android (المستوى 29 من واجهة برمجة التطبيقات).
  2. جهِّز "استوديو Android" للتطوير بلغة C/C++ من خلال استخدام مدير SDK لتثبيت أحدث إصدار من CMake و"حزمة تطوير البرامج الأصلية لنظام التشغيل Android" (NDK). لمزيد من المعلومات حول إنشاء المشاريع الأصلية أو استيرادها، يُرجى الاطّلاع على البدء في استخدام NDK.

  3. نزِّل ملف ZIP واستخرِجه بجانب مشروعك.

    رابط التنزيل الحجم المجموع الاختباري SHA-256
    ‫37.8 MiB 9db60185185342f28d2c278b60222333608c67bc022e458a25224eaea8c4c4b7
  4. عدِّل ملف build.gradle الخاص بتطبيقك كما هو موضّح أدناه:

    Groovy

        // App build.gradle
    
        plugins {
          id 'com.android.application'
        }
    
        // Define a path to the extracted Play Core SDK files.
        // If using a relative path, wrap it with file() since CMake requires absolute paths.
        def playcoreDir = file('../path/to/playcore-native-sdk')
    
        android {
            defaultConfig {
                ...
                externalNativeBuild {
                    cmake {
                        // Define the PLAYCORE_LOCATION directive.
                        arguments "-DANDROID_STL=c++_static",
                                  "-DPLAYCORE_LOCATION=$playcoreDir"
                    }
                }
                ndk {
                    // Skip deprecated ABIs. Only required when using NDK 16 or earlier.
                    abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
                }
            }
            buildTypes {
                release {
                    // Include Play Core Library proguard config files to strip unused code while retaining the Java symbols needed for JNI.
                    proguardFile '$playcoreDir/proguard/common.pgcfg'
                    proguardFile '$playcoreDir/proguard/gms_task.pgcfg'
                    proguardFile '$playcoreDir/proguard/per-feature-proguard-files'
                    ...
                }
                debug {
                    ...
                }
            }
            externalNativeBuild {
                cmake {
                    path 'src/main/CMakeLists.txt'
                }
            }
        }
    
        dependencies {
            // Import these feature-specific AARs for each Google Play Core library.
            implementation 'com.google.android.play:app-update:2.1.0'
            implementation 'com.google.android.play:asset-delivery:2.3.0'
            implementation 'com.google.android.play:integrity:1.4.0'
            implementation 'com.google.android.play:review:2.0.2'
    
            // Import these common dependencies.
            implementation 'com.google.android.gms:play-services-tasks:18.0.2'
            implementation files("$playcoreDir/playcore-native-metadata.jar")
            ...
        }
        

    Kotlin

    // App build.gradle
    
    plugins {
        id("com.android.application")
    }
    
    // Define a path to the extracted Play Core SDK files.
    // If using a relative path, wrap it with file() since CMake requires absolute paths.
    val playcoreDir = file("../path/to/playcore-native-sdk")
    
    android {
        defaultConfig {
            ...
            externalNativeBuild {
                cmake {
                    // Define the PLAYCORE_LOCATION directive.
                    arguments += listOf("-DANDROID_STL=c++_static", "-DPLAYCORE_LOCATION=$playcoreDir")
                }
            }
            ndk {
                // Skip deprecated ABIs. Only required when using NDK 16 or earlier.
                abiFilters.clear()
                abiFilters += listOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")
            }
        }
        buildTypes {
            release {
                // Include Play Core Library proguard config files to strip unused code while retaining the Java symbols needed for JNI.
                proguardFile("$playcoreDir/proguard/common.pgcfg")
                proguardFile("$playcoreDir/proguard/gms_task.pgcfg")
                proguardFile("$playcoreDir/proguard/per-feature-proguard-files")
                ...
            }
            debug {
                ...
            }
        }
        externalNativeBuild {
            cmake {
                path = "src/main/CMakeLists.txt"
            }
        }
    }
    
    dependencies {
        // Import these feature-specific AARs for each Google Play Core library.
        implementation("com.google.android.play:app-update:2.1.0")
        implementation("com.google.android.play:asset-delivery:2.3.0")
        implementation("com.google.android.play:integrity:1.4.0")
        implementation("com.google.android.play:review:2.0.2")
    
        // Import these common dependencies.
        implementation("com.google.android.gms:play-services-tasks:18.0.2")
        implementation(files("$playcoreDir/playcore-native-metadata.jar"))
        ...
    }
  5. عدِّل ملفات CMakeLists.txt في تطبيقك كما هو موضّح أدناه:

    cmake_minimum_required(VERSION 3.6)
    
    ...
    
    # Add a static library called “playcore” built with the c++_static STL.
    include(${PLAYCORE_LOCATION}/playcore.cmake)
    add_playcore_static_library()
    
    // In this example “main” is your native code library, i.e. libmain.so.
    add_library(main SHARED
            ...)
    
    target_include_directories(main PRIVATE
            ${PLAYCORE_LOCATION}/include
            ...)
    
    target_link_libraries(main
            android
            playcore
            ...)
    

جمع البيانات

قد تجمع حزمة تطوير البرامج (SDK) الأصلية لمكتبة Play الأساسية بيانات متعلقة بالإصدار للسماح لشركة Google بتحسين المنتج، بما في ذلك:

  • اسم حزمة التطبيق
  • إصدار حزمة التطبيق
  • إصدار حزمة تطوير البرامج (SDK) الأصلية لمكتبة Play Core

سيتم جمع هذه البيانات عند تحميل حزمة تطبيقك إلى Play Console. لإيقاف عملية جمع البيانات هذه، عليك إزالة عبارة الاستيراد $playcoreDir/playcore-native-metadata.jar في ملف build.gradle.

يُرجى العِلم أنّ عملية جمع البيانات هذه المتعلقة باستخدامك لحزمة تطوير البرامج (SDK) الأصلية في Play Core واستخدام Google للبيانات التي يتم جمعها هي عملية منفصلة ومستقلة عن عملية جمع Google لبيانات البرامج الاعتمادية للمكتبة التي تم الإفصاح عنها في Gradle عند تحميل حزمة تطبيقك إلى Play Console.

العرض في وقت التثبيت

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

#include <android/asset_manager.h>
#include <android_native_app_glue.h>
...
AAssetManager* assetManager = app->activity->assetManager;
AAsset* asset = AAssetManager_open(assetManager, "asset-name", AASSET_MODE_BUFFER);
size_t assetLength = AAsset_getLength(asset);
char* buffer = (char*) malloc(assetLength + 1);
AAsset_read(asset, buffer, assetLength);

العرض الانسيابي السريع والعرض عند الطلب

توضّح الأقسام التالية كيفية تهيئة واجهة برمجة التطبيقات، وكيفية الحصول على معلومات حول حِزم مواد العرض قبل تنزيلها، وكيفية طلب البيانات من واجهة برمجة التطبيقات لبدء التنزيل، وكيفية الوصول إلى الحِزم التي تم تنزيلها. تنطبق هذه الأقسام على حِزم مواد العرض fast-follow وon-demand.

تشغيل التطبيق

يجب دائمًا استدعاء AssetPackManager_init() لإعداد واجهة برمجة التطبيقات لحِزم مواد العرض قبل استدعاء أي دالة أخرى. ابحث عن أي رموز أخطاء لحِزم مواد العرض.

#include "play/asset_pack.h"
...
AssetPackErrorCode AssetPackManager_init(JavaVM* jvm, jobject android_context);

يُرجى أيضًا التأكّد من استدعاء الدالتين التاليتين في onPause() وonResume() من ANativeActivityCallbacks:

الحصول على معلومات التنزيل حول حِزم مواد العرض

يجب أن تفصح التطبيقات عن حجم التنزيل قبل جلب حِزمة مواد العرض. استخدِم الدالة AssetPackManager_requestInfo() لبدء طلب غير متزامن لمعرفة حجم التنزيل وما إذا كانت الحزمة قيد التنزيل حاليًا. بعد ذلك، استخدِم AssetPackManager_getDownloadState() للاستعلام عن حالة التنزيل (على سبيل المثال، استدعِ هذه الدالة مرة واحدة لكل إطار في حلقة اللعبة). إذا تعذّر تنفيذ طلب، راجِع رموز الخطأ في حِزم مواد العرض.

AssetPackErrorCode AssetPackManager_requestInfo();      // Call once
AssetPackErrorCode AssetPackManager_getDownloadState(); // Call once per frame in your game loop

تعرض الدالة AssetPackManager_getDownloadState() النوع غير الشفاف AssetPackDownloadState كمؤشر إخراج. استخدِم هذا المؤشر لاستدعاء الوظائف التالية:

AssetPackDownloadState* state;
AssetPackErrorCode error_code = AssetPackManager_getDownloadState(asset-pack-name, &state);
AssetPackDownloadStatus status = AssetPackDownloadState_getStatus(state);
uint64_t downloadedBytes = AssetPackDownloadState_getBytesDownloaded(state);
uint64_t totalBytes = AssetPackDownloadState_getTotalBytesToDownload(state));
AssetPackDownloadState_destroy(state);

تثبيت

استخدِم AssetPackManager_requestDownload() لبدء تنزيل حِزمة مواد عرض للمرة الأولى أو لطلب تحديث حِزمة مواد عرض لإكمال ما يلي:

AssetPackErrorCode AssetPackManager_requestDownload();  // Call once
AssetPackErrorCode AssetPackManager_getDownloadState(); // Call once per frame in your game loop

تعرض الدالة AssetPackManager_getDownloadState() النوع غير الشفاف AssetPackDownloadState. للحصول على معلومات حول كيفية استخدام هذا النوع، يُرجى الاطّلاع على الحصول على معلومات التنزيل.

عمليات التنزيل الكبيرة

إذا كان حجم التنزيل أكبر من 200 ميغابايت ولم يكن المستخدم متصلاً بشبكة Wi-Fi، لن يبدأ التنزيل إلا بعد أن يمنح المستخدم موافقته الصريحة على المتابعة باستخدام اتصال بيانات الجوّال. وبالمثل، إذا كان حجم التنزيل كبيرًا وانقطع اتصال المستخدم بشبكة Wi-Fi، سيتوقف التنزيل مؤقتًا وسيكون من الضروري الحصول على موافقة صريحة للمتابعة باستخدام اتصال بيانات الجوّال. تحتوي الحزمة المتوقّفة مؤقتًا على الحالة WAITING_FOR_WIFI. لتفعيل تدفّق واجهة المستخدِم من أجل مطالبة المستخدِم بالموافقة، استخدِم ما يلي:

تأكيد المستخدم مطلوب

إذا كانت الحزمة تحمل الحالة REQUIRES_USER_CONFIRMATION، لن يتم تنزيلها إلا بعد أن يوافق المستخدم على مربّع الحوار الذي يظهر مع AssetPackManager_showConfirmationDialog(). يمكن أن تظهر هذه الحالة إذا لم يتعرّف Play على التطبيق. يُرجى العِلم أنّ طلب AssetPackManager_showConfirmationDialog() في هذه الحالة يؤدي إلى تحديث التطبيق. بعد التحديث، اطلب مواد العرض مرة أخرى.

الوصول إلى حِزم مواد العرض

يمكنك الوصول إلى حِزمة مواد العرض باستخدام طلبات نظام الملفات بعد أن يصل طلب التنزيل إلى الحالة COMPLETED. يتم تخزين كل حزمة مواد عرض في دليل منفصل في وحدة التخزين الداخلية للتطبيق. استخدِم AssetPackManager_getAssetPackLocation() للحصول على AssetPackLocation لحزمة مواد العرض المحدّدة. استخدِم AssetPackLocation_getStorageMethod() في ذلك الموقع الجغرافي لتحديد طريقة التخزين:

  • ASSET_PACK_STORAGE_APK: يتم تثبيت حزمة مواد العرض كحزمة APK. يمكنك الاطّلاع على العرض في وقت التثبيت للوصول إلى مواد العرض هذه.
  • ASSET_PACK_STORAGE_FILES: استخدِم AssetPackLocation_getAssetsPath() للحصول على مسار ملف إلى الدليل الذي يحتوي على مواد العرض، أو القيمة null إذا لم يتم تنزيل مواد العرض. لا تعدِّل الملفات التي تم تنزيلها في مسار الملف هذا.
AssetPackLocation* location;

AssetPackErrorCode error_code = AssetPackManager_getAssetPackLocation(asset-pack-name, &location);

if (error_code == ASSET_PACK_NO_ERROR) {
    AssetPackStorageMethod storage_method = AssetPackLocation_getStorageMethod(location);
    const char* assets_path = AssetPackLocation_getAssetsPath(location);
    AssetPackLocation_destroy(location);
}

بعد تحديد موقع الأصول، استخدِم دوال مثل fopen أو ifstream للوصول إلى الملفات.

طُرق أخرى في Play Core API

في ما يلي بعض طرق واجهة برمجة التطبيقات الإضافية التي قد تحتاج إلى استخدامها في تطبيقك.

إلغاء الطلب

استخدِم AssetPackManager_cancelDownload() لإلغاء طلب حزمة مواد عرض نشط. يُرجى العِلم أنّ هذا الطلب هو عملية بأفضل جهد.

طلب الإزالة

استخدِم AssetPackManager_requestRemoval() لتحديد موعد لإزالة حِزمة مواد عرض.

الخطوات التالية

اختبار ميزة "عرض المواد في Play" على الجهاز ومن Google Play