دمج عرض مواد العرض (الإعلانات المدمجة مع المحتوى)

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

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

تطوير الإعلانات المدمجة مع المحتوى

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

  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 الأساسية ملف العنوان play/asset_pack.h لطلب حِزم مواد العرض وإدارة عمليات التنزيل والوصول إلى مواد العرض.

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

تنزيل 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.14.0.zip

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

  2. يمكنك إعداد "استوديو Android" لتطوير البرامج الأصلية باستخدام مدير SDK لتثبيت أحدث إصدار من CMake وAndroid Native Development Kit (NDK). لمزيد من المعلومات حول إنشاء مشاريع أصلية أو استيرادها، راجع بدء استخدام NDK.

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

    رابط التنزيل حجم الملف المجموع الاختباري لخوارزمية SHA-256
    36 ميبيبايت 782a8522d937848c83a715c9a258b95a3ff2879a7cd71855d137b41c00786a5e
  4. عدِّل ملف build.gradle الخاص بتطبيقك على النحو الموضّح أدناه:

    رائع

        // 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.2.2'
            implementation 'com.google.android.play:integrity:1.3.0'
            implementation 'com.google.android.play:review:2.0.1'
    
            // 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.2.2")
        implementation("com.google.android.play:integrity:1.3.0")
        implementation("com.google.android.play:review:2.0.1")
    
        // 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 بتحسين المنتج، بما في ذلك:

  • اسم حزمة التطبيق
  • إصدار حزمة التطبيق
  • إصدار Play Core Native SDK

سيتم جمع هذه البيانات عند تحميل حزمة تطبيقك على Play Console. لإيقاف عملية جمع البيانات هذه، عليك إزالة عملية استيراد $playcoreDir/playcore-native-metadata.jar في ملف create.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() لإعداد واجهة برمجة التطبيقات asset pack API قبل استدعاء أي دالة أخرى. ابحث عن أيّ رموز خطأ في حِزمة مواد العرض.

#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() للحصول على مسار ملف يؤدي إلى الدليل الذي يحتوي على مواد العرض، أو فارغًا إذا لم يتم تنزيل مواد العرض. لا تعدِّل الملفات التي تم تنزيلها في مسار الملف هذا.
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.