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

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

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

الإنشاء للإعلانات الصورية

اتّبِع الخطوات التالية لإنشاء أداة "إرسال مواد عرض Play" في ملف APK لتطبيق 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 الأساسية ملف play/asset_pack.h لرأس لغة C لطلب حِزم مواد العرض وإدارة عمليات التنزيل والوصول إلى مواد العرض.

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

تنزيل 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. عليك القيام بأي مما يلي:

  2. حضِّر "استوديو Android" للتطوير المتوافق مع الأجهزة فقط باستخدام مدير حِزم SDK لتثبيت أحدث إصدار من CMake ومجموعة تطوير البرامج الأصلية لنظام التشغيل Android ‏(NDK). لمزيد من المعلومات عن إنشاء مشاريع أصلية أو استيرادها، يُرجى الاطّلاع على البدء في استخدام حِزم NDK.

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

    رابط التنزيل الحجم المجموع الاختباري لخوارزمية SHA-256
    ‫37.8 ميغابايت 9db60185185342f28d2c278b60222333608c67bc022e458a25224eaea8c4c4b7
  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.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.2.2")
        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 الأساسية

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

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

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

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

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