این راهنما نحوه پشتیبانی از بهروزرسانیهای درونبرنامه در برنامه بااستفاده از کد بومی (C یا C++) را شرح میدهد. راهنماهای جداگانهای برای مواردی که پیادهسازی شما از زبان برنامهنویسی Kotlin یا زبان برنامهنویسی Java استفاده میکند و مواردی که پیادهسازی شما از Unity یا Unreal Engine استفاده میکند وجود دارد.
نمای کلی کیت توسعه نرمافزار بومی
«کیت توسعه نرمافزار بومی Play Core» بخشی از خانواده کیت توسعه نرمافزار Play Core است. «کیت توسعه نرمافزار بومی» شامل فایل سرصفحه C، app_update.h، است که AppUpdateManager
را از «کتابخانه بهروزرسانی درونبرنامه Java Play» میپیچد. این فایل سرصفحه به برنامه شما اجازه میدهد
میانای برنامهسازی کاربردی بهروزرسانیهای درونبرنامهای را مستقیماً از کد بومیتان فراخوانی کند.
راهاندازی محیط توسعه
دانلود کنید Play Core Native SDK
قبل از دانلود، باید با شرایط و ضوابط زیر موافقت کنید.
شرایط و ضوابط
Last modified: September 24, 2020- 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.
- For purposes of these terms, "APIs" means Google's APIs, other developer services, and associated software, including any Redistributable Code.
- “Redistributable Code” means Google-provided object code or header files that call the APIs.
- 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.
- 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.
یکی از کارهای زیر را انجام دهید:
- نسخه ۴.۰ یا بالاتر Android Studio را نصب کنید. از «مدیر کیت توسعه نرمافزار» واسط کاربر برای نصب Android SDK Platform نسخه ۱۰.۰ (سطح میانای برنامه کاربردی ۲۹) استفاده کنید.
- ابزارهای خط فرمان کیت توسعه نرمافزار Android را نصب کنید
و از
sdkmanagerبرای نصب نسخه پلاتفرم کیت توسعه نرمافزار Android 10.0 (سطح میانای برنامه کاربردی ۲۹) استفاده کنید.
بااستفاده از مدیر کیت توسعه نرمافزار برای نصب جدیدترین CMake و Android Native Development Kit (NDK)، «استودیو Android» را برای توسعه بومی آماده کنید. برای اطلاعات بیشتر درباره ایجاد یا وارد کردن پروژههای بومی، به شروع به کار با NDK مراجعه کنید.
فایل zip را بارگیری کنید و آن را در کنار پروژهتان استخراج کنید.
بارگیری پیوند اندازه کنترلجمع SHA-256 ۵۴٫۸ مگابایت 008b8fedc6179a6dc6ccc21af75591afc7036f78f3d5559d844f1b923934fef0 فایل
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")) ... }
فایلهای
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» ممکن است دادههای مربوط به نسخه را جمعآوری کند تا به Google اجازه دهد محصول را بهبود دهد، ازجمله:
- نام بسته برنامه
- نسخه بسته برنامه
- نسخه «کیت توسعه نرمافزار بومی Play Core»
این دادهها هنگام بارگذاری بسته برنامه در «کنسول Play» جمعآوری میشود. برای انصراف دادن از این فرایند جمعآوری داده،
$playcoreDir/playcore-native-metadata.jar وارد کردن را در فایل build.gradle بردارید.
توجه داشته باشید که این جمعآوری داده مربوط به استفاده شما از «کیت توسعه نرمافزار بومی هسته Play» است و استفاده Google از دادههای جمعآوریشده جدا از جمعآوری وابستگیهای کتابخانه اعلامشده در Gradle توسط Google هنگام بارگذاری بسته برنامه در «کنسول Play» است و مستقل از آن است.
پساز ادغام کردن «کیت توسعه نرمافزار بومی Play Core» در پروژهتان، خط زیر را در فایلهایی که حاوی فراخوانیهای میانای برنامهسازی کاربردی هستند اضافه کنید:
#include "play/app_update.h"
میانای برنامهسازی کاربردی بهروزرسانی درونبرنامه را مقداردهی اولیه کنید
هرگاه از «میانای برنامهسازی کاربردی بهروزرسانی درونبرنامه» استفاده میکنید، ابتدا آن را با فراخواندن تابع
AppUpdateManager_init() مقداردهی اولیه کنید، همانطور که در مثال زیر که با android_native_app_glue.h ساخته شده است نشان داده شده است:
void android_main(android_app* app) {
app->onInputEvent = HandleInputEvent;
AppUpdateErrorCode error_code =
AppUpdateManager_init(app->activity->vm, app->activity->clazz);
if (error_code == APP_UPDATE_NO_ERROR) {
// You can use the API.
}
}
بررسی دردسترس بودن بهروزرسانی
قبلاز درخواست بهروزرسانی، بررسی کنید که آیا بهروزرسانی برای برنامهتان دردسترس است یا نه. AppUpdateManager_requestInfo() درخواست ناهمزمانی را شروع میکند که اطلاعات لازم برای راهاندازی جریان بهروزرسانی درونبرنامهای را در آینده جمعآوری میکند. اگر درخواست باموفقیت شروع شود، تابع APP_UPDATE_NO_ERROR را برمیگرداند.
AppUpdateErrorCode error_code = AppUpdateManager_requestInfo()
if (error_code == APP_UPDATE_NO_ERROR) {
// The request has successfully started, check the result using
// AppUpdateManager_getInfo.
}
میتوانید فرایند جاری و نتیجه درخواست را بااستفاده از
AppUpdateManager_getInfo() پیگیری کنید. علاوهبر کد خطا، این تابع یک ساختار
AppUpdateInfo مبهم برمیگرداند که میتوانید از آن برای بازیابی
اطلاعات مربوط به درخواست بهروزرسانی استفاده کنید. برای مثال، ممکن است بخواهید این تابع را در هر حلقه بازی فراخوانی کنید تا زمانی که نتیجه غیرتهی برای info برگرداند:
AppUpdateInfo* info;
GameUpdate() {
// Keep calling this in every game loop until info != nullptr
AppUpdateErrorCode error_code = AppUpdateManager_getInfo(&info);
if (error_code == APP_UPDATE_NO_ERROR && info != nullptr) {
// Successfully started, check the result in the following functions
}
...
}
بررسی قدیمی بودن بهروزرسانی
علاوهبر بررسی اینکه آیا بهروزرسانی دردسترس است یا نه، ممکن است بخواهید بررسی کنید چه مدت از آخرین باری که کاربر ازطریق «فروشگاه Play» از بهروزرسانی مطلع شده است گذشته است. این کار میتواند به شما کمک کند تصمیم بگیرید که آیا باید بهروزرسانی انعطافپذیر یا بهروزرسانی فوری را شروع کنید. برای مثال، ممکن است چند روز صبر کنید و سپس با بهروزرسانی انعطافپذیر به کاربر اطلاع دهید، و چند روز بعد بهروزرسانی فوری را الزامی کنید.
از AppUpdateInfo_getClientVersionStalenessDays() برای بررسی تعداد روزهایی که از زمان دردسترس قرار گرفتن بهروزرسانی ازطریق «فروشگاه Play» میگذرد استفاده کنید:
int32_t staleness_days = AppUpdateInfo_getClientVersionStalenessDays(info);
بررسی اولویت بهروزرسانی
Google Play Developer API به شما اجازه میدهد اولویت هر بهروزرسانی را تنظیم کنید. این به برنامه شما اجازه میدهد تصمیم بگیرد که بهروزرسانی را با چه شدتی به کاربر توصیه کند. برای مثال، استراتژی زیر را برای تنظیم اولویت بهروزرسانی درنظر بگیرید:
- بهبودهای جزئی در واسط کاربر: بهروزرسانی اولویت پایین؛ نه بهروزرسانی انعطافپذیر و نه بهروزرسانی فوری درخواست کنید. فقط زمانی بهروزرسانی شود که کاربر با برنامهتان تعامل ندارد.
- بهبود عملکرد: بهروزرسانی اولویت متوسط؛ درخواست بهروزرسانی انعطافپذیر.
- بهروزرسانی امنیتی مهم: بهروزرسانی اولویت بالا؛ درخواست بهروزرسانی فوری.
برای تعیین اولویت، Google Play از مقدار صحیح بین ۰ و ۵ استفاده میکند، که در آن ۰
پیشفرض و ۵ بالاترین اولویت است. برای تنظیم اولویت بهروزرسانی، از فیلد inAppUpdatePriority در بخش Edits.tracks.releases
در Google Play Developer API استفاده کنید. همه نسخههای جدیداً اضافهشده در نسخهٔ پخش
هماولویت با نسخهٔ پخش درنظر گرفته میشوند. اولویت فقط هنگام عرضه نسخه جدید قابل تنظیم است و بعداً نمیتوان آن را تغییر داد.
اولویت را بااستفاده از Google Play Developer API، همانطور که در سند Play
Developer API توضیح داده شده است، تنظیم کنید. اولویت بهروزرسانی درونبرنامه را در منبع
Edit.tracks ارسالشده در روش Edit.tracks: update مشخص کنید.
مثال زیر انتشار برنامه با کد نسخه ۸۸ و
inAppUpdatePriority ۵ را نشان میدهد:
{ "releases": [{ "versionCodes": ["88"], "inAppUpdatePriority": 5, "status": "completed" }] }
در کد برنامهتان، میتوانید سطح اولویت بهروزرسانی موردنظر را بااستفاده از
AppUpdateInfo_getPriority() بررسی کنید:
int32_t priority = AppUpdateInfo_getPriority(info);
شروع بهروزرسانی
پساز اینکه تأیید کردید بهروزرسانی دردسترس است، میتوانید بااستفاده از
AppUpdateManager_requestStartUpdate() درخواست بهروزرسانی کنید. پیشاز درخواست بهروزرسانی،
شیء AppUpdateInfo بهروزی دریافت کنید و شیء AppUpdateOptions
ایجاد کنید تا جریان بهروزرسانی را پیکربندی کنید. شیء AppUpdateOptions گزینههایی را برای جریان بهروزرسانی درونبرنامه تعریف میکند، ازجمله اینکه آیا بهروزرسانی باید انعطافپذیر یا فوری باشد.
مثال زیر یک شیء AppUpdateOptions برای جریان بهروزرسانی انعطافپذیر ایجاد میکند:
// Creates an AppUpdateOptions configuring a flexible in-app update flow.
AppUpdateOptions* options;
AppUpdateErrorCode error_code = AppUpdateOptions_createOptions(APP_UPDATE_TYPE_FLEXIBLE, &options);
مثال زیر یک شیء AppUpdateOptions برای جریان بهروزرسانی فوری ایجاد میکند:
// Creates an AppUpdateOptions configuring an immediate in-app update flow.
AppUpdateOptions* options;
AppUpdateErrorCode error_code = AppUpdateOptions_createOptions(APP_UPDATE_TYPE_IMMEDIATE, &options);
شیء AppUpdateOptions همچنین حاوی فیلد AllowAssetPackDeletion است که مشخص میکند آیا بهروزرسانی مجاز است درصورت محدود بودن فضای ذخیرهسازی دستگاه، بستههای دارایی را پاک کند یا نه. این فیلد بهطور پیشفرض روی false تنظیم شده است، اما میتوانید از روش AppUpdateOptions_setAssetPackDeletionAllowed() برای تنظیم آن روی true استفاده کنید:
bool allow = true;
AppUpdateErrorCode error_code = AppUpdateOptions_setAssetPackDeletionAllowed(options, allow);
پساز اینکه شیء AppUpdateInfo بهروزی داشتید و شیء AppUpdateOptions بهدرستی پیکربندی شد، AppUpdateManager_requestStartUpdate() را فراخوانی کنید تا
جریان بهروزرسانی را بهصورت ناهمزمان درخواست کنید و «فعالیت Android» jobject را
برای پارامتر نهایی ارسال کنید.
AppUpdateErrorCode request_error_code =
AppUpdateManager_requestStartUpdate(info, options, app->activity->clazz);
برای آزاد کردن منابع، نمونههای AppUpdateInfo و
AppUpdateOptions را که دیگر به آنها نیاز ندارید با فراخوانی
AppUpdateInfo_destroy() و AppUpdateOptions_destroy()،
بهترتیب، آزاد کنید.
AppUpdateInfo_destroy(info);
AppUpdateOptions_destroy(options);
برای جریان بهروزرسانی فوری، Google Play صفحه تأیید کاربر را نمایش میدهد. وقتی کاربر درخواست را میپذیرد، Google Play بهطور خودکار بهروزرسانی را در پیشزمینه بارگیری و نصب میکند، سپس اگر نصب موفقیتآمیز باشد، برنامه را به نسخه بهروزرسانیشده بازراهاندازی میکند.
برای جریان بهروزرسانی انعطافپذیر، میتوانید درخواست اشیای AppUpdateInfo
بهروز را ادامه دهید تا وضعیت بهروزرسانی فعلی را پیگیری کنید و کاربر همچنان با برنامه
تعامل داشته باشد. پساز اینکه بارگیری با موفقیت تکمیل شد، باید
تکمیل بهروزرسانی را با فراخوانی
AppUpdateManager_requestCompleteUpdate() راهاندازی کنید، همانطور که در مثال زیر نشان داده شده است:
AppUpdateStatus status = AppUpdateInfo_getStatus(info);
if (status == APP_UPDATE_DOWNLOADED) {
AppUpdateErrorCode error_code = AppUpdateManager_requestCompleteUpdate();
if (error_code != APP_UPDATE_NO_ERROR)
{
// There was an error while completing the update flow.
}
}
پساز اینکه برنامهتان استفاده از API را تمام کرد، با فراخوانی تابع AppUpdateManager_destroy() منابع را آزاد کنید.
مدیریت کردن خطا
این بخش راهحلهای خطاهای رایج را که با مقادیر خاص AppUpdateErrorCode نشان داده میشوند توضیح میدهد:
- کد خطای
-110, APP_UPDATE_INITIALIZATION_NEEDEDنشان میدهد که API با موفقیت مقداردهی اولیه نشده است. برای مقداردهی اولیه API،AppUpdateManager_init()را فراخوانی کنید. - کد خطای
-4, APP_UPDATE_INVALID_REQUESTنشان میدهد که برخیاز پارامترهای درخواست جاریسازی بهروزرسانی بدشکل هستند. بررسی کنید و مطمئن شوید که اشیاءAppUpdateInfoوAppUpdateOptionsتهی نباشند و قالببندی درستی داشته باشند. - کد خطای
-5, APP_UPDATE_UNAVAILABLEنشان میدهد که بهروزرسانی قابلاجرایی دردسترس نیست. مطمئن شوید که نسخه هدف دارای همان نام بسته، شناسه برنامه، و کلید امضا است. اگر بهروزرسانی دردسترس است، حافظه نهان برنامه را پاک کنید و دوباره باAppUpdateManager_requestAppUpdateInfo()تماس بگیرید تاAppUpdateInfoبازآوری شود. - کد خطای
-6, APP_UPDATE_NOT_ALLOWEDنشان میدهد که نوع بهروزرسانی نشاندادهشده توسط شیءAppUpdateOptionمجاز نیست. قبلاز شروع جریان بهروزرسانی، بررسی کنید آیاAppUpdateInfoشیء نشان میدهد که نوع بهروزرسانی مجاز است یا نه.
مراحل بعدی
برای تأیید اینکه یکپارچهسازی شما بهدرستی کار میکند، بهروزرسانیهای درونبرنامه برنامهتان را آزمایش کنید.