ادغام کردن ارائه دارایی (بومی)

برای دسترسی به بسته‌های دارایی برنامه‌تان از کد C و C++‎، مراحل این راهنما را دنبال کنید.

کد ادغام نمونه در GitHub دردسترس است.

ساختن برای Native

از مراحل زیر برای ساختن «ارائه دارایی‌های Play» در Android App Bundle پروژه‌تان استفاده کنید. برای انجام این مراحل، نیازی به استفاده از Android Studio ندارید.

  1. نسخه افزایه Android Gradle را در فایل 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»

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

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

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

کیت توسعه نرم‌افزار Play Core Native فایل سرایند 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.16.0.zip

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

    • Android Studio نسخه ۴.۰ یا بالاتر را نصب کنید. از میانای کاربر «مدیر کیت توسعه نرم‌افزار» برای نصب نسخه ۱۰.۰ پلاتفرم کیت توسعه نرم‌افزار Android (سطح میانای برنامه‌سازی کاربردی ۲۹) استفاده کنید.
    • ابزارهای خط فرمان کیت توسعه نرم‌افزار Android را نصب کنید و از sdkmanager برای نصب نسخه ۱۰.۰ پلاتفرم کیت توسعه نرم‌افزار Android (سطح میانای برنامه‌سازی کاربردی ۲۹) استفاده کنید.
  2. بااستفاده از مدیر SDK، «استودیو Android» را برای توسعه بومی آماده کنید تا جدیدترین نسخه‌های CMake و «کیت توسعه بومی Android»‏ (NDK) را نصب کنید. برای اطلاعات بیشتر درباره ایجاد یا وارد کردن پروژه‌های بومی، به شروع به کار با NDK مراجعه کنید.

  3. فایل zip را بارگیری کنید و آن را در کنار پروژه‌تان از حالت فشرده خارج کنید.

    بارگیری پیوند اندازه جمع‌آزمای SHA-256
    ‫۵۴٫۸ مبی‌بایت 008b8fedc6179a6dc6ccc21af75591afc7036f78f3d5559d844f1b923934fef0
  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.6.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.6.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» ممکن است داده‌های مربوط به نسخه را جمع‌آوری کند تا به Google اجازه دهد محصول را بهبود بخشد، ازجمله:

  • نام بسته برنامه
  • نسخه بسته برنامه
  • نسخه Play Core Native SDK

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

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

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

بسته‌های دارایی پیکربندی‌شده به‌عنوان 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);

تحویل سریع و تحویل درخواستی

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

بارگیری‌های بزرگ

اگر حجم بارگیری بیشتر از ۲۰۰ مگابایت باشد و کاربر به 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 آزمایش کنید.