Unterstützung von In-App-Updates (nativ)

In diesem Leitfaden wird beschrieben, wie Sie In-App- Updates in Ihrer App mithilfe von nativem Code (C oder C++). Es gibt separate Anleitungen für Fälle, in denen die Programmiersprache Kotlin oder die Java-Programmierung, Sprache und Fälle, in denen Ihre -Implementierung verwendet Unity.

Native SDK – Übersicht

Das Play Core Native SDK ist Teil des Play Core SDK-Familie. Die Ureinwohner SDK enthält die C-Header-Datei app_update.h, die AppUpdateManager aus der Java Play In-App Update Library. Mit dieser Headerdatei kann Ihre App können Sie die API für In-App-Updates direkt aus Ihrem nativen Code aufrufen.

Entwicklungsumgebung einrichten

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. Sie haben folgende Möglichkeiten:

    • Installieren Sie Android Studio Version 4.0 oder höher. SDK verwenden Manager-UI zur Installation der Android SDK Platform Version 10.0 (API-Level 29)
    • Installieren Sie die Android SDK-Befehlszeilentools. und verwende sdkmanager zum Installieren Android SDK Platform Version 10.0 (API-Level 29):
  2. Bereiten Sie Android Studio für die native Entwicklung mit der SDK-Manager, um die neueste CMake und Android Native Development Kit (NDK) Weitere Informationen zu native Projekte erstellen oder importieren, finden Sie unter Erste Schritte mit dem NDK

  3. Lade die ZIP-Datei herunter und entpacke sie zusammen mit deinem Projekt.

    Downloadlink Größe SHA-256-Prüfsumme
    36 MiB 782a8522d937848c83a715c9a258b95a3ff2879a7cd71855d137b41c00786a5e
  4. Aktualisieren Sie die Datei build.gradle Ihrer App wie unten gezeigt:

    Cool

        // 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. Aktualisieren Sie die CMakeLists.txt-Dateien Ihrer App wie unten gezeigt:

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

Datenerhebung

Das Play Core Native SDK kann versionsbezogene Daten erheben, damit Google Folgendes tun kann: das Produkt zu verbessern, einschließlich:

  • Paketname der App
  • Paketversion der App
  • Version des Core Native SDK

Diese Daten werden erhoben, wenn Sie Ihr App-Paket hochladen in der Play Console. Wenn Sie die Datenerhebung deaktivieren möchten, entfernen Sie die $playcoreDir/playcore-native-metadata.jar-Import in der build.gradle-Datei.

Die Datenerhebung bezieht sich auf deine Nutzung des Play Core Native SDK und Die Verwendung der erhobenen Daten durch Google erfolgt getrennt und unabhängig vom Sammlung von Bibliotheksabhängigkeiten, die beim Hochladen Ihrer App in Gradle deklariert wurden an die Play Console zu senden.

Nachdem Sie das Play Core Native SDK in Ihr Projekt integriert haben, fügen Sie den folgende Zeile in Dateien mit API-Aufrufen:

#include "play/app_update.h"

In-App Update API initialisieren

Immer wenn Sie die In-App Update API verwenden, initialisieren Sie diese zuerst, indem Sie die Methode AppUpdateManager_init() aus, wie im folgenden Beispiel mit 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.
  }
}

Verfügbarkeit von Updates prüfen

Bevor Sie ein Update anfordern, prüfen Sie, ob ein Update für Ihr AppUpdateManager_requestInfo() eine asynchrone Anfrage startet, die die erforderlichen Informationen zum Starten mit dem In-App-Update beginnen. Die Funktion gibt APP_UPDATE_NO_ERROR zurück, wenn die -Anforderung wird gestartet.

AppUpdateErrorCode error_code = AppUpdateManager_requestInfo()

if (error_code == APP_UPDATE_NO_ERROR) {
    // The request has successfully started, check the result using
    // AppUpdateManager_getInfo.
}

Sie können den laufenden Prozess und das Ergebnis der Anfrage über AppUpdateManager_getInfo() Zusätzlich zum Fehlercode gibt diese Funktion ein AppUpdateInfo opaque Struct, mit der Sie Informationen über die Aktualisierung abrufen können. Diese Funktion kann z. B. in jeder Spielschleife aufgerufen werden. bis sie ein Ergebnis ungleich null für info zurückgibt:

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
   }
...
}

Veraltete Updates prüfen

Neben der Prüfung, ob ein Update verfügbar ist, Prüfen, wie viel Zeit seit der letzten Benachrichtigung des Nutzers über ein Update vergangen ist über den Play Store. So können Sie besser entscheiden, ob Sie ein flexibles Update oder ein sofortiges Update. Warten Sie z. B. einige Tage bevor der Nutzer mit einem flexiblen Update benachrichtigt wird, und einige Tage später bevor eine sofortige Aktualisierung erforderlich ist.

Verwenden Sie AppUpdateInfo_getClientVersionStalenessDays() um zu sehen, wie viele Tage seit dem Update über Google Play Geschäft:

int32_t staleness_days = AppUpdateInfo_getClientVersionStalenessDays(info);

Updatepriorität prüfen

Mit der Google Play Developer API können Sie die Priorität jedes Updates festlegen. So kann Ihre App entscheiden, wie dringend ein Update dem Nutzer empfohlen wird. Betrachten Sie beispielsweise die folgende Strategie zum Festlegen der Aktualisierungspriorität:

  • Kleinere Verbesserungen der Benutzeroberfläche: Aktualisierung mit niedriger Priorität. weder eine flexible noch ein sofortiges Update. Nur aktualisieren, wenn der Nutzer nicht interagiert mit Ihrer App.
  • Leistungsverbesserungen: Update mit mittlerer Priorität flexibles aktualisieren.
  • Kritisches Sicherheitsupdate: Update mit hoher Priorität Sofortige Anforderung aktualisieren.

Zur Bestimmung der Priorität verwendet Google Play einen ganzzahligen Wert zwischen 0 und 5 mit 0 Standardeinstellung und 5 die höchste Priorität. Zum Festlegen der Priorität für eine aktualisieren, verwenden Sie das Feld inAppUpdatePriority unter Edits.tracks.releases in der Google Play Developer API. Alle neu hinzugefügten Versionen im Release dieselbe Priorität wie die Veröffentlichung haben. Die Priorität kann nur festgelegt werden, wenn wenn ein neuer Release eingeführt wird, der später nicht mehr geändert werden kann.

Legen Sie die Priorität mithilfe der Google Play Developer API fest, wie in der Google Play Developer API Entwickler-API Dokumentation. Legen Sie die Priorität für In-App-Updates fest in der Edit.tracks im Feld Edit.tracks: update . Das folgende Beispiel zeigt die Veröffentlichung einer App mit Versionscode 88 und inAppUpdatePriority 5:

{
  "releases": [{
      "versionCodes": ["88"],
      "inAppUpdatePriority": 5,
      "status": "completed"
  }]
}

Im Code Ihrer App können Sie die Prioritätsstufe für ein bestimmtes Update mit AppUpdateInfo_getPriority():

int32_t priority = AppUpdateInfo_getPriority(info);

Update starten

Nachdem Sie bestätigt haben, dass ein Update verfügbar ist, können Sie es mit AppUpdateManager_requestStartUpdate() Bevor Sie eine Aktualisierung anfordern, rufen Sie ein aktuelles AppUpdateInfo-Objekt ab und erstelle ein AppUpdateOptions -Objekt, um den Aktualisierungsablauf zu konfigurieren. Ein AppUpdateOptions-Objekt definiert Optionen für einen In-App-Update-Ablauf, einschließlich der Frage, ob das Update flexibel oder unmittelbar sind.

Im folgenden Beispiel wird ein AppUpdateOptions-Objekt für eine flexible Aktualisierung erstellt. Ablauf:

// Creates an AppUpdateOptions configuring a flexible in-app update flow.
AppUpdateOptions* options;
AppUpdateErrorCode error_code = AppUpdateOptions_createOptions(APP_UPDATE_TYPE_FLEXIBLE, &options);

Im folgenden Beispiel wird ein AppUpdateOptions-Objekt für eine sofortige Ablauf aktualisieren:

// Creates an AppUpdateOptions configuring an immediate in-app update flow.
AppUpdateOptions* options;
AppUpdateErrorCode error_code = AppUpdateOptions_createOptions(APP_UPDATE_TYPE_IMMEDIATE, &options);

Das AppUpdateOptions-Objekt enthält auch ein AllowAssetPackDeletion-Feld der definiert, ob das Update das Asset löschen darf Paketen bei begrenztem Speicherplatz auf dem Gerät. Dieses ist standardmäßig auf false gesetzt, aber Sie können den Parameter AppUpdateOptions_setAssetPackDeletionAllowed() , um sie stattdessen auf true festzulegen:

bool allow = true;
AppUpdateErrorCode error_code = AppUpdateOptions_setAssetPackDeletionAllowed(options, allow);

Wenn Sie ein aktuelles AppUpdateInfo-Objekt und ein korrekt konfiguriertes AppUpdateOptions-Objekt enthält, rufen Sie AppUpdateManager_requestStartUpdate() auf, um asynchron einen Aktualisierungsablauf anfordern und eine Android-Aktivität jobject übergeben. für den letzten Parameter.

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

Wenn Sie Ressourcen freigeben möchten, geben Sie Instanzen von AppUpdateInfo und AppUpdateOptions, die Sie nicht mehr benötigen, indem Sie AppUpdateInfo_destroy() und AppUpdateOptions_destroy(), .

AppUpdateInfo_destroy(info);
AppUpdateOptions_destroy(options);

Damit ein Update sofort durchgeführt werden kann, wird in Google Play eine Bestätigungsseite des Nutzers angezeigt. Wenn der Nutzer die Anfrage annimmt, lädt Google Play automatisch installiert das Update im Vordergrund und startet die App dann neu Version, wenn die Installation erfolgreich war.

Für einen flexiblen Aktualisierungsablauf können Sie weiterhin aktuelle AppUpdateInfo anfordern Objekte, um den aktuellen Update-Status zu verfolgen, während der Nutzer mit der App interagieren können. Nach erfolgreichem Abschluss des Downloads müssen Sie lösen den Abschluss des Updates aus, indem wir AppUpdateManager_requestCompleteUpdate(), Dies wird im folgenden Beispiel gezeigt:

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.
    }
}

Geben Sie Ressourcen kostenlos, indem Sie die Methode AppUpdateManager_destroy() nachdem Ihre App die API nicht mehr verwendet hat.

Fehlerbehandlung

In diesem Abschnitt werden Lösungen für häufige Fehler beschrieben, die durch spezifische AppUpdateErrorCode Werte:

  • Der Fehlercode -110, APP_UPDATE_INITIALIZATION_NEEDED gibt an, dass der API wurde nicht erfolgreich initialisiert. AppUpdateManager_init() anrufen, um die API initialisieren.
  • Der Fehlercode -4, APP_UPDATE_INVALID_REQUEST gibt an, dass einige Parameter der Anfrage für den Aktualisierungsvorgang sind fehlerhaft. Prüfen Sie, ob Die Objekte AppUpdateInfo und AppUpdateOptions sind nicht null und werden richtig formatiert sind.
  • Der Fehlercode -5, APP_UPDATE_UNAVAILABLE gibt an, dass keine entsprechendes Update verfügbar. Stellen Sie sicher, dass die Zielversion Paketname application ID, und den Signaturschlüssel. Wenn ein Update verfügbar ist, leeren Sie den Cache der App und rufen Sie noch einmal AppUpdateManager_requestAppUpdateInfo() auf, um AppUpdateInfo aktualisieren
  • Der Fehlercode -6, APP_UPDATE_NOT_ALLOWED gibt an, dass der Aktualisierungstyp AppUpdateOption angegeben ist, ist nicht zulässig. Prüfen Sie, ob die Das Objekt AppUpdateInfo gibt an, dass der Aktualisierungstyp vor dem den Aktualisierungsablauf zu starten.

Nächste Schritte

Teste die In-App-Updates, um prüfen, ob die Integration korrekt funktioniert.