یکپارچه سازی تحویل دارایی (بومی)، یکپارچه سازی تحویل دارایی (بومی)

از مراحل این راهنما برای دسترسی به بسته‌های دارایی برنامه خود از طریق کد C و C++ خود استفاده کنید.

نمونه کد ادغام در گیت‌هاب موجود است.

ساخت برای بومیان

برای ساخت Play Asset Delivery در Android App Bundle پروژه خود، از مراحل زیر استفاده کنید. برای انجام این مراحل نیازی به استفاده از اندروید استودیو ندارید.

  1. نسخه افزونه Android Gradle را در فایل build.gradle پروژه خود به 4.0.0 یا بالاتر ارتقا دهید.

  2. در دایرکتوری سطح بالای پروژه خود، یک دایرکتوری برای بسته دارایی ایجاد کنید. نام این دایرکتوری به عنوان نام بسته دارایی استفاده می‌شود. نام بسته‌های دارایی باید با یک حرف شروع شود و فقط می‌تواند شامل حروف، اعداد و زیرخط باشد.

  3. در پوشه‌ی asset pack، یک فایل build.gradle ایجاد کنید و کد زیر را به آن اضافه کنید. حتماً نام asset pack و فقط یک نوع تحویل را مشخص کنید:

    // 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 برنامه پروژه، نام هر بسته دارایی (assets pack) را مطابق شکل زیر اضافه کنید:

    // In the app build.gradle file:
    android {
        ...
        assetPacks = [":asset-pack-name", ":asset-pack2-name"]
    }
  5. در فایل settings.gradle پروژه، تمام بسته‌های دارایی (assets pack) را مطابق شکل زیر در پروژه خود وارد کنید:

    // In the settings.gradle file:
    include ':app'
    include ':asset-pack-name'
    include ':asset-pack2-name'
  6. در دایرکتوری بسته‌ی دارایی‌ها، زیردایرکتوری زیر را ایجاد کنید: src/main/assets .

  7. فایل assets را در دایرکتوری src/main/assets قرار دهید. می‌توانید زیرشاخه‌ها را نیز در اینجا ایجاد کنید. ساختار دایرکتوری برنامه شما اکنون باید به شکل زیر باشد:

    • build.gradle
    • settings.gradle
    • app/
    • asset-pack-name /build.gradle
    • asset-pack-name /src/main/assets/ your-asset-directories
  8. ساخت بسته نرم‌افزاری اندروید با Gradle . در بسته نرم‌افزاری تولید شده، دایرکتوری سطح ریشه اکنون شامل موارد زیر است:

    • asset-pack-name /manifest/AndroidManifest.xml : شناسه و نحوه‌ی تحویل بسته‌ی دارایی را پیکربندی می‌کند.
    • asset-pack-name /assets/ your-asset-directories : دایرکتوری که شامل تمام دارایی‌های ارائه شده به عنوان بخشی از بسته دارایی است.

    Gradle برای هر بسته دارایی، فایل manifest را تولید می‌کند و دایرکتوری assets/ را برای شما خروجی می‌دهد.

  9. (اختیاری) بسته برنامه خود را برای پشتیبانی از قالب‌های مختلف فشرده‌سازی بافت پیکربندی کنید.

ادغام با کتابخانه تحویل دارایی‌های بازی

شما این API را بر اساس نوع تحویل بسته‌ی دارایی که می‌خواهید به آن دسترسی داشته باشید، پیاده‌سازی می‌کنید. این مراحل در فلوچارت زیر نشان داده شده است.

نمودار جریان بسته دارایی برای کد بومی

شکل ۱. نمودار جریان دسترسی به بسته‌های دارایی

کیت توسعه نرم‌افزار بومی Play Core، فایل هدر C play/asset_pack.h را برای درخواست بسته‌های دارایی، مدیریت دانلودها و دسترسی به دارایی‌ها ارائه می‌دهد.

محیط توسعه خود را برای Play Core Native SDK تنظیم کنید

دانلود کنید 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.4.zip

  1. هر یک از موارد زیر را انجام دهید:

  2. با استفاده از SDK Manager و نصب آخرین نسخه CMake و Android Native Development Kit (NDK)، اندروید استودیو را برای توسعه بومی آماده کنید. برای اطلاعات بیشتر در مورد ایجاد یا وارد کردن پروژه‌های بومی، به بخش «شروع کار با NDK» مراجعه کنید.

  3. فایل زیپ را دانلود کنید و آن را در کنار پروژه خود استخراج کنید.

    لینک دانلود اندازه بررسی SHA-256
    ۳۹.۶ مگابایت 92b43246860d4ce4772a3a0786212d9b4781920e112d81b93ca1c5ebd8da89cb
  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.3.0'
            implementation 'com.google.android.play:integrity:1.5.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")
            ...
        }
        

    کاتلین

    // 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.5.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
            ...)
    

جمع‌آوری داده‌ها

کیت توسعه نرم‌افزار Play Core Native ممکن است داده‌های مربوط به نسخه را جمع‌آوری کند تا به گوگل امکان بهبود محصول را بدهد، از جمله:

  • نام بسته برنامه
  • نسخه بسته برنامه
  • نسخه Core Native SDK را اجرا کنید

این داده‌ها هنگام آپلود بسته برنامه خود در کنسول Play جمع‌آوری می‌شوند. برای انصراف از این فرآیند جمع‌آوری داده‌ها، دستور $playcoreDir/playcore-native-metadata.jar در فایل build.gradle حذف کنید.

توجه داشته باشید، این جمع‌آوری داده‌ها که مربوط به استفاده شما از Play Core Native SDK و استفاده گوگل از داده‌های جمع‌آوری‌شده است، جدا و مستقل از مجموعه وابستگی‌های کتابخانه‌ای گوگل است که هنگام آپلود بسته برنامه خود در کنسول Play در Gradle اعلام شده‌اند.

تحویل زمان نصب

بسته‌های دارایی پیکربندی‌شده به عنوان install-time بلافاصله در هنگام راه‌اندازی برنامه در دسترس هستند. برای دسترسی به دارایی‌های ارائه شده در این حالت ، از API NDK AAssetManager استفاده کنید:

#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);

تحویل سریع و بر اساس تقاضا

بخش‌های بعدی نحوه‌ی مقداردهی اولیه‌ی API، نحوه‌ی دریافت اطلاعات در مورد بسته‌های دارایی قبل از دانلود آنها، نحوه‌ی فراخوانی API برای شروع دانلود و نحوه‌ی دسترسی به بسته‌های دانلود شده را نشان می‌دهد. این بخش‌ها برای بسته‌های دارایی fast-follow و بسته‌های دارایی on-demand اعمال می‌شوند.

راه‌اندازی برنامه

قبل از فراخوانی هر تابع دیگری، همیشه AssetPackManager_init() را برای مقداردهی اولیه 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 را برمی‌گرداند. برای اطلاعات بیشتر در مورد نحوه استفاده از این نوع، به Get download information مراجعه کنید.

دانلودهای بزرگ

اگر حجم دانلود بیش از ۲۰۰ مگابایت باشد و کاربر به وای‌فای متصل نباشد، دانلود تا زمانی که کاربر صراحتاً رضایت خود را برای ادامه دانلود با استفاده از اتصال داده تلفن همراه اعلام نکند، شروع نمی‌شود. به طور مشابه، اگر حجم دانلود زیاد باشد و کاربر وای‌فای خود را از دست بدهد، دانلود متوقف می‌شود و برای ادامه دانلود با استفاده از اتصال داده تلفن همراه، رضایت صریح لازم است. یک بسته متوقف شده دارای وضعیت 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

در ادامه چند متد API اضافی که ممکن است بخواهید در برنامه خود استفاده کنید، آورده شده است.

لغو درخواست

برای لغو درخواست فعال بسته‌ی دارایی از AssetPackManager_cancelDownload() استفاده کنید. توجه داشته باشید که این درخواست یک عملیات با بهترین تلاش است.

درخواست حذف

برای زمان‌بندی حذف یک بسته‌ی دارایی از AssetPackManager_requestRemoval() استفاده کنید.

مراحل بعدی

تحویل دارایی‌های بازی را به صورت محلی و از Google Play آزمایش کنید .