במדריך הזה מוסבר איך לתמוך בבתוך האפליקציה עדכונים באפליקציה באמצעות קוד נייטיב (C או C++). יש מדריכים נפרדים למקרים שבהם ההטמעה משתמשת שפת התכנות Kotlin או תכנות Java שפה ומקרים שבהם מוטמעת באמצעות Unity.
סקירה כללית על Native SDK
Play Core Native SDK הוא חלק מ-Play Core
משפחת ה-SDK. השפה המקומית
ב-SDK יש קובץ כותרת C, app_update.h
, שעוטף
AppUpdateManager
מספריית העדכונים בתוך האפליקציה של Java Play. קובץ הכותרת הזה מאפשר לאפליקציה
מפעילים את ה-API כדי לבצע עדכונים בתוך האפליקציה ישירות מקוד ה-Native.
הגדרת סביבת הפיתוח
Download Play Core Native SDK
Before downloading, you must agree to the following terms and conditions.
Terms and Conditions
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 בגרסה 4.0 ואילך. שימוש ב-SDK ממשק משתמש של מנהל להתקנת פלטפורמת Android SDK גרסה 10.0 (רמת API 29).
- להתקין את כלי שורת הפקודה של Android SDK.
ולהשתמש ב-
sdkmanager
כדי להתקין פלטפורמת Android SDK גרסה 10.0 (רמת API 29).
כדי להכין את Android Studio לפיתוח מקורי באמצעות מנהל ה-SDK כדי להתקין את הגרסה העדכנית ביותר CMake ו-Android Native Development Kit (NDK). מידע נוסף על ליצירה או לייבוא של פרויקטים מקוריים, תחילת העבודה עם NDK.
מורידים את קובץ ה-ZIP ומחלצים אותו לצד הפרויקט.
קישור להורדה גודל סיכום ביקורת (checksum) SHA-256 36MiB 782a8522d937848c83a715c9a258b95a3ff2879a7cd71855d137b41c00786a5e מעדכנים את קובץ
build.gradle
של האפליקציה באופן הבא:Groovy
// 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.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.4.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")) ... }
מעדכנים את קובצי
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 SDK יאסוף נתונים שקשורים לגרסאות כדי לאפשר ל-Google: לשפר את המוצר, כולל:
- שם החבילה של האפליקציה
- גרסת החבילה של האפליקציה
- גרסת ה-SDK של Play Core Native
הנתונים האלה ייאספו כשתעלו את חבילת האפליקציה
אל Play Console. כדי לבטל את ההסכמה לתהליך איסוף הנתונים הזה, צריך להסיר את
ייבוא של $playcoreDir/playcore-native-metadata.jar
בקובץ build.gradle.
לתשומת ליבך, איסוף הנתונים הזה שקשור לשימוש שלך ב-Play Core Native SDK השימוש של Google בנתונים שנאספו הוא נפרד ובלתי תלוי אוסף יחסי התלות של ספריות שהוצהרו ב-Gradle כשמעלים את האפליקציה חבילה ל-Play Console.
אחרי שמשלבים את Play Core Native SDK בפרויקט, צריך לכלול את את השורה הבאה בקבצים שמכילים קריאות ל-API:
#include "play/app_update.h"
הפעלת ה-API לעדכון בתוך האפליקציה
בכל פעם שמשתמשים ב-API לעדכון בתוך האפליקציה, צריך לאתחל אותו קודם על ידי שליחת קריאה
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);
בדיקת עדיפות העדכון
ממשק ה-API של Google Play למפתחים מאפשר להגדיר את העדיפות של כל עדכון. כך האפליקציה שלך יכולה להחליט באיזו מידה להמליץ למשתמש על עדכון. לדוגמה, שימוש באסטרטגיה הבאה להגדרת עדיפות העדכון:
- שיפורים קטנים בממשק המשתמש: עדכון עדיפות נמוכה; לא בקשה או עדכון מיידי. עדכון רק כשהמשתמש אין אינטראקציה באפליקציה שלכם.
- שיפורי ביצועים: עדכון לעדיפות בינונית; לבקש
- עדכון אבטחה קריטי: עדכון בעדיפות גבוהה; בקשה מיידית
כדי לקבוע עדיפות, Google Play משתמשת בערך שלם בין 0 ל-5, עם 0
להיות ברירת המחדל ו-5 היא העדיפות הגבוהה ביותר. כדי להגדיר עדיפות של
משתמשים בשדה inAppUpdatePriority
שמתחת
Edits.tracks.releases
בממשק API של Google Play למפתחים. כל הגרסאות החדשות שנוספו בגרסה הן
נחשבת לאותה עדיפות כמו של פריט התוכן. ניתן להגדיר עדיפות רק כאשר
בתהליך השקה של גרסה חדשה, ואי אפשר לשנות אותה מאוחר יותר.
הגדרת העדיפות באמצעות ממשק API של Google Play למפתחים, כפי שמתואר ב-Play
ממשק API למפתחים
תיעוד.
לציין את העדיפות של העדכונים בתוך האפליקציה בעמודה
Edit.tracks
שהמשאב הועבר
Edit.tracks: update
. בדוגמה הבאה מוצגת השקה של אפליקציה עם קוד גרסה
88 ו-inAppUpdatePriority
5:
{ "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.
}
}
כדי לפנות משאבים, אפשר להפעיל
AppUpdateManager_destroy()
אחרי שהאפליקציה סיימה להשתמש ב-API.
טיפול בשגיאות
בקטע הזה מתוארים פתרונות לשגיאות נפוצות שמצביעות על
AppUpdateErrorCode
ערכים:
- קוד שגיאה של
-110, APP_UPDATE_INITIALIZATION_NEEDED
מציין ה-API לא הופעל. חיוג למספרAppUpdateManager_init()
אל מתחילה לאתחל את ה-API. - קוד שגיאה של
-4, APP_UPDATE_INVALID_REQUEST
מציין של בקשת העדכון בפורמט שגוי. צריך לוודא האובייקטיםAppUpdateInfo
ו-AppUpdateOptions
אינם ריקים בפורמט הנכון. - קוד השגיאה
-5, APP_UPDATE_UNAVAILABLE
מציין שאין יש עדכון זמין. צריך לוודא שגרסת היעד זהה package name, מזהה בקשה, ומפתח החתימה. אם יש עדכון זמין, מנקים את המטמון של האפליקציה וקוראים שוב אלAppUpdateManager_requestAppUpdateInfo()
כדי רענוןAppUpdateInfo
. - קוד שגיאה של
-6, APP_UPDATE_NOT_ALLOWED
מציין שסוג העדכון שמצוין על ידי האובייקטAppUpdateOption
. יש לבדוק אם האובייקטAppUpdateInfo
מציין שסוג העדכון מותר לפני להתחיל את תהליך העדכון.
השלבים הבאים
בודקים את העדכונים בתוך האפליקציה כדי לוודא שהשילוב פועל כראוי.