پشتیبانی از به روز رسانی های درون برنامه ای (بومی)

این راهنما نحوه پشتیبانی از به‌روزرسانی‌های درون برنامه‌ای در برنامه خود را با استفاده از کد بومی (C یا C++) توضیح می‌دهد. راهنماهای جداگانه ای برای مواردی وجود دارد که پیاده سازی شما از زبان برنامه نویسی Kotlin یا زبان برنامه نویسی جاوا استفاده می کند و مواردی که پیاده سازی شما از Unity استفاده می کند.

نمای کلی SDK بومی

Play Core Native SDK بخشی از خانواده Play Core SDK است. Native SDK شامل یک فایل هدر C به app_update.h است که AppUpdateManager از کتابخانه به‌روزرسانی درون برنامه Java Play می‌پیچد. این فایل هدر به برنامه شما اجازه می‌دهد تا مستقیماً از کد اصلی شما، API را برای به‌روزرسانی‌های درون‌برنامه فراخوانی کند.

محیط توسعه خود را تنظیم کنید

Download Play Core Native SDK

Before downloading, you must agree to the following terms and conditions.

Terms and Conditions

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.
Download Play Core Native SDK

play-core-native-sdk-1.15.3.zip

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

    • Android Studio نسخه 4.0 یا بالاتر را نصب کنید. از رابط کاربری SDK Manager برای نصب Android SDK Platform نسخه 10.0 (سطح API 29) استفاده کنید.
    • ابزارهای خط فرمان Android SDK را نصب کنید و از sdkmanager برای نصب Android SDK Platform نسخه 10.0 (سطح API 29) استفاده کنید.
  2. Android Studio را برای توسعه بومی با استفاده از مدیر SDK برای نصب جدیدترین کیت توسعه CMake و Android Native (NDK) آماده کنید. برای اطلاعات بیشتر در مورد ایجاد یا وارد کردن پروژه های بومی، به شروع با NDK مراجعه کنید.

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

    لینک دانلود اندازه SHA-256 Checksum
    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")
            ...
        }
        

    کاتلین

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

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

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

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

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

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

پس از اینکه Play Core Native SDK را در پروژه خود ادغام کردید، خط زیر را در فایل‌هایی که حاوی فراخوان‌های API هستند قرار دهید:

#include "play/app_update.h"

API به‌روزرسانی درون‌برنامه را راه‌اندازی کنید

همانطور که در مثال زیر که با android_native_app_glue.h ساخته شده است، هر زمان که از API به‌روزرسانی درون‌برنامه استفاده می‌کنید، ابتدا با فراخوانی تابع AppUpdateManager_init() آن را مقداردهی اولیه کنید:

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 به شما امکان می دهد اولویت هر به روز رسانی را تعیین کنید. این به برنامه شما اجازه می‌دهد تصمیم بگیرد که چقدر به‌روزرسانی به‌طور جدی به کاربر توصیه کند. برای مثال، استراتژی زیر را برای تنظیم اولویت به‌روزرسانی در نظر بگیرید:

  • بهبودهای جزئی رابط کاربری: به روز رسانی با اولویت پایین . نه به‌روزرسانی انعطاف‌پذیر و نه به‌روزرسانی فوری را درخواست کنید. فقط زمانی به‌روزرسانی کنید که کاربر با برنامه شما تعامل نداشته باشد.
  • بهبود عملکرد: به روز رسانی با اولویت متوسط . درخواست به روز رسانی انعطاف پذیر
  • به روز رسانی امنیتی حیاتی: به روز رسانی با اولویت بالا . درخواست به روز رسانی فوری

برای تعیین اولویت، گوگل پلی از یک عدد صحیح بین 0 تا 5 استفاده می کند که 0 به عنوان پیش فرض و 5 بالاترین اولویت است. برای تنظیم اولویت برای به‌روزرسانی، از فیلد inAppUpdatePriority زیر Edits.tracks.releases در Google Play Developer API استفاده کنید. تمام نسخه های جدید اضافه شده در نسخه دارای اولویت مشابه نسخه در نظر گرفته می شوند. اولویت را فقط می توان در هنگام عرضه نسخه جدید تنظیم کرد و بعداً نمی توان آن را تغییر داد.

همانطور که در مستندات Play Developer API توضیح داده شده است، اولویت را با استفاده از Google Play Developer 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() را فراخوانی کنید تا به طور ناهمزمان یک جریان به روز رسانی را درخواست کنید و پارامتر نهایی را در یک jobject Activity Android ارسال کنید.

AppUpdateErrorCode request_error_code =
AppUpdateManager_requestStartUpdate(info, options, app->activity->clazz);

برای آزاد کردن منابع، به ترتیب با فراخوانی AppUpdateInfo_destroy() و AppUpdateOptions_destroy() نمونه هایی از AppUpdateInfo و AppUpdateOptions را منتشر کنید که دیگر به آنها نیاز ندارید.

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 نشان می دهد که نوع به روز رسانی قبل از شروع جریان به روز رسانی مجاز است یا خیر.

مراحل بعدی

به‌روزرسانی‌های درون‌برنامه‌ای را آزمایش کنید تا مطمئن شوید که ادغام شما به درستی کار می‌کند.