รองรับการอัปเดตในแอป (เนทีฟ)

คู่มือนี้จะอธิบายวิธีการสนับสนุนในแอป อัปเดตในแอปของคุณโดยใช้โค้ดแบบเนทีฟ (C หรือ C++) เรามีคำแนะนำแยกต่างหากสำหรับกรณีที่การติดตั้งใช้งานของคุณใช้ ภาษาโปรแกรม Kotlin หรือการเขียนโปรแกรม Java ภาษา และกรณีต่างๆ ที่ จะใช้ Unity

ภาพรวมของ SDK เนทีฟ

Play Core Native SDK เป็นส่วนหนึ่งของ Play Core SDK เจ้าของภาษา 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.14.0.zip

  1. เลือกดำเนินการอย่างหนึ่งดังต่อไปนี้

    • ติดตั้ง Android Studio เวอร์ชัน 4.0 ขึ้นไป ใช้ SDK UI ของ Manager เพื่อติดตั้งแพลตฟอร์ม Android SDK เวอร์ชัน 10.0 (API ระดับ 29)
    • ติดตั้งเครื่องมือบรรทัดคำสั่ง Android SDK และใช้ sdkmanager เพื่อติดตั้ง แพลตฟอร์ม Android SDK เวอร์ชัน 10.0 (API ระดับ 29)
  2. เตรียม Android Studio สำหรับการพัฒนาในตัวโดยใช้ SDK Manager เพื่อติดตั้งเวอร์ชันล่าสุด CMake และ Android Native Development Kit (NDK) สำหรับข้อมูลเพิ่มเติมเกี่ยวกับ การสร้างหรือการนำเข้าโปรเจ็กต์เนทีฟ โปรดดู เริ่มต้นใช้งาน NDK

  3. ดาวน์โหลดไฟล์ ZIP และแตกข้อมูลควบคู่ไปกับโปรเจ็กต์ของคุณ

    ลิงก์ดาวน์โหลด ขนาด ผลรวมตรวจสอบ SHA-256
    36 MiB 782a8522d937848c83a715c9a258b95a3ff2879a7cd71855d137b41c00786a5e
  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.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"))
        ...
    }
    
  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 ดำเนินการต่อไปนี้ได้ เพื่อปรับปรุงผลิตภัณฑ์ รวมถึง

  • ชื่อแพ็กเกจของแอป
  • เวอร์ชันแพ็กเกจของแอป
  • เวอร์ชันของ Play Core Native SDK

ข้อมูลนี้จะรวบรวมเมื่อคุณอัปโหลดแพ็กเกจแอป ไปยัง Play Console หากต้องการเลือกไม่ใช้กระบวนการเก็บรวบรวมข้อมูลนี้ ให้นำ นำเข้า $playcoreDir/playcore-native-metadata.jar ในไฟล์build.gradle

โปรดทราบว่าการรวบรวมข้อมูลนี้เกี่ยวข้องกับการใช้ Play Core Native SDK และ การใช้ข้อมูลที่เก็บรวบรวมของ Google แยกต่างหาก และเป็นอิสระจาก คอลเล็กชันของทรัพยากร Dependency ของไลบรารีที่ประกาศใน Gradle เมื่อคุณอัปโหลดแอป ลงใน Play Console ได้

หลังจากที่คุณผสานรวม Play Core Native SDK เข้ากับโปรเจ็กต์แล้ว ให้ใส่ บรรทัดต่อไปนี้ในไฟล์ที่มีการเรียก API

#include "play/app_update.h"

เริ่มต้น API อัปเดตในแอป

เมื่อใดก็ตามที่คุณใช้ 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 โครงสร้างที่คลุมเครือ ซึ่งคุณสามารถใช้เพื่อเรียกข้อมูลเกี่ยวกับการอัปเดต อีกครั้ง เช่น คุณอาจต้องการเรียกใช้ฟังก์ชันนี้ในทุก Game Loop จนกว่าจะแสดงผลลัพธ์ที่ไม่เป็นค่าว่างสำหรับ 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 Store ซึ่งจะช่วยให้ตัดสินใจได้ว่าคุณควรริเริ่ม การอัปเดตที่ยืดหยุ่น หรือการอัปเดตในทันที ตัวอย่างเช่น คุณอาจต้องรอ 2-3 วัน ก่อนที่จะแจ้งให้ผู้ใช้ทราบถึงการอัปเดตที่ยืดหยุ่น และไม่กี่วันหลังจากนั้น ก่อนที่จะต้องอัปเดตทันที

ใช้ AppUpdateInfo_getClientVersionStalenessDays() เพื่อตรวจสอบจำนวนวันนับตั้งแต่ที่การอัปเดตพร้อมให้บริการผ่าน Play ร้านค้า:

int32_t staleness_days = AppUpdateInfo_getClientVersionStalenessDays(info);

ตรวจสอบลำดับความสำคัญของการอัปเดต

API สำหรับนักพัฒนาซอฟต์แวร์ Google Play ช่วยให้คุณสามารถกำหนดลำดับความสำคัญของการอัปเดตแต่ละครั้งได้ วิธีนี้ช่วยให้แอปของคุณตัดสินใจได้ว่าจะแนะนำการอัปเดตให้กับผู้ใช้มากแค่ไหน ตัวอย่างเช่น ลองพิจารณากลยุทธ์ต่อไปนี้ในการตั้งค่าลำดับความสำคัญของการอัปเดต

  • การปรับปรุง UI เล็กน้อย: การอัปเดตลำดับความสำคัญต่ำ ไม่ใช่คำขอที่ยืดหยุ่น หรือการอัปเดตทันที อัปเดตเฉพาะเมื่อผู้ใช้ไม่ได้โต้ตอบ กับแอปของคุณ
  • การปรับปรุงประสิทธิภาพ: การอัปเดตลำดับความสำคัญปานกลาง ขอใบอนุญาตที่ยืดหยุ่น อัปเดต
  • การอัปเดตความปลอดภัยที่สำคัญ: การอัปเดตลำดับความสำคัญสูง ขอทันที อัปเดต

ในการกำหนดลำดับความสำคัญ Google Play จะใช้ค่าจำนวนเต็มระหว่าง 0 ถึง 5 โดยมี 0 คือค่าเริ่มต้น และ 5 คือลำดับความสำคัญสูงสุด วิธีกำหนดลำดับความสำคัญสำหรับ อัปเดต ให้ใช้ช่อง inAppUpdatePriority ในส่วน Edits.tracks.releases ใน Google Play Developer API เวอร์ชันที่เพิ่มเข้ามาใหม่ทั้งหมดในรุ่นนี้ ถือได้ว่ามีความสำคัญ เท่ากับการเปิดตัว จะกำหนดลำดับความสำคัญได้ก็ต่อเมื่อ เปิดตัวรุ่นใหม่และไม่สามารถเปลี่ยนแปลงในภายหลังได้

กำหนดลำดับความสำคัญโดยใช้ 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 ระบุว่าไม่มี มีการอัปเดตที่เกี่ยวข้อง ตรวจสอบว่าเวอร์ชันเป้าหมายมีเวอร์ชันเดียวกัน ชื่อแพ็กเกจ รหัสแอปพลิเคชัน และคีย์การลงชื่อเข้าใช้ หากมีการอัปเดต ล้างแคชของแอปและเรียกใช้ AppUpdateManager_requestAppUpdateInfo() อีกครั้งเพื่อ รีเฟรช AppUpdateInfo
  • รหัสข้อผิดพลาด -6, APP_UPDATE_NOT_ALLOWED บ่งชี้ว่าประเภทการอัปเดต ไม่อนุญาตให้ใช้ออบเจ็กต์ AppUpdateOption ที่ระบุ ตรวจสอบว่า ออบเจ็กต์ AppUpdateInfo บ่งชี้ว่าประเภทการอัปเดตได้รับอนุญาตก่อน เริ่มขั้นตอนการอัปเดต

ขั้นตอนถัดไป

ทดสอบการอัปเดตในแอปของแอปเพื่อ ตรวจสอบว่าการผสานรวมทำงานได้อย่างถูกต้อง