Obsługa aktualizacji w aplikacji (natywna)

W tym przewodniku opisujemy, jak obsługiwać reklamy w aplikacjach aktualizacje aplikacji przy użyciu kodu natywnego (C lub C++). Istnieją osobne przewodniki dla przypadków, w których implementacja wykorzystuje język programowania Kotlin lub język Java oraz przypadki, w których implementacja korzysta z Unity.

Omówienie natywnego pakietu SDK

Podstawowy natywny pakiet SDK Google Play jest częścią Play Core pakietu SDK. Natywny Pakiet SDK zawiera plik nagłówka C (app_update.h), który jest opakowany AppUpdateManager. z biblioteki aktualizacji Javy w aplikacji Play. Ten plik nagłówka umożliwia aplikacji wywołuje interfejs API pod kątem aktualizacji w aplikacji bezpośrednio z kodu natywnego.

Konfigurowanie środowiska programistycznego

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. Wykonaj jedną z tych czynności:

    • Zainstaluj Android Studio w wersji 4.0 lub nowszej. Korzystanie z pakietu SDK Interfejs menedżera przedstawiający instalowanie pakietu Android SDK Platform w wersji 10.0 (poziom interfejsu API 29).
    • zainstalować narzędzia wiersza poleceń pakietu Android SDK, i użyj sdkmanager do instalacji Platforma Android SDK w wersji 10.0 (poziom interfejsu API 29).
  2. Przygotowanie Android Studio do natywnego programowania przy użyciu Menedżer SDK, aby zainstalować najnowszą wersję CMake i Android Native Development Kit (NDK). Więcej informacji na temat: tworzenia lub importowania projektów natywnych, patrz Pierwsze kroki z NDK

  3. Pobierz plik ZIP i rozpakuj go razem z projektem.

    Link do pobierania Rozmiar Suma kontrolna SHA-256
    36 MiB 782a8522d937848c83a715c9a258b95a3ff2879a7cd71855d137b41c00786a5e
  4. Zaktualizuj plik build.gradle aplikacji, jak pokazano poniżej:

    Odlotowe

        // 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. Zaktualizuj pliki CMakeLists.txt aplikacji, jak pokazano poniżej:

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

Zbieranie danych

Pakiet Play Core Native SDK może gromadzić dane dotyczące wersji, aby umożliwić Google: ulepszania usługi, w tym:

  • Nazwa pakietu aplikacji
  • Wersja pakietu aplikacji
  • Wersja Core Native SDK w Google Play

Te dane będą zbierane, gdy prześlesz pakiet aplikacji. w Konsoli Play. Aby zrezygnować z tego procesu zbierania danych, usuń Import $playcoreDir/playcore-native-metadata.jar w pliku build.gradle.

Uwaga: te zbieranie danych jest związane z korzystaniem przez Ciebie z podstawowego natywnego pakietu SDK Google Play oraz Google będzie korzystać z zebranych danych oddzielnie i niezależnie od zbiór zależności bibliotek zadeklarowanych w Gradle podczas przesyłania aplikacji do Konsoli Play.

Po zintegrowaniu z projektem natywnego pakietu Play Core dołącz do projektu następujący wiersz w plikach zawierających wywołania interfejsu API:

#include "play/app_update.h"

Inicjowanie interfejsu API aktualizacji w aplikacji

Za każdym razem, gdy używasz interfejsu API aktualizacji w aplikacji, najpierw go zainicjuj, wywołując AppUpdateManager_init() jak w przykładzie poniżej utworzonym przy użyciu funkcji 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.
  }
}

Sprawdź dostępność aktualizacji

Zanim poprosisz o aktualizację, sprawdź, czy jest dostępna aktualizacja . AppUpdateManager_requestInfo() uruchamia asynchroniczne żądanie, które zbiera informacje wymagane do uruchomienia. proces aktualizacji w aplikacji. Funkcja zwraca APP_UPDATE_NO_ERROR, jeśli

AppUpdateErrorCode error_code = AppUpdateManager_requestInfo()

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

Trwający proces i jego wynik możesz śledzić za pomocą AppUpdateManager_getInfo() Oprócz kodu błędu ta funkcja zwraca AppUpdateInfo opaque struct, którego można używać do pobierania informacji o aktualizacji. użytkownika. Możesz na przykład wywoływać tę funkcję w każdej pętli gry dopóki nie zwróci niezerowego wyniku dla funkcji 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
   }
...
}

Sprawdź aktualność aktualizacji

Oprócz sprawdzenia, czy jest dostępna aktualizacja, możesz też sprawdzanie, ile czasu upłynęło od ostatniego powiadomienia użytkownika o aktualizacji; w Sklepie Play. Pomoże Ci to podjąć decyzję o zainicjowaniu lub natychmiastową aktualizację. Na przykład możesz odczekać kilka dni, przed powiadomieniem użytkownika o elastycznej aktualizacji i kilka dni później bez natychmiastowej aktualizacji.

Używaj AppUpdateInfo_getClientVersionStalenessDays() aby sprawdzić liczbę dni od udostępnienia aktualizacji w Google Play Magazyn:

int32_t staleness_days = AppUpdateInfo_getClientVersionStalenessDays(info);

Sprawdź priorytet aktualizacji

Interfejs Google Play Developer API pozwala określić priorytet każdej aktualizacji. Dzięki temu aplikacja może zdecydować, jak zdecydowanie zalecić aktualizację użytkownikowi. Rozważ na przykład tę strategię ustalania priorytetu aktualizacji:

  • Drobne ulepszenia interfejsu: aktualizacja Niskiego priorytetu. nie żądają też elastycznego ani natychmiastowej aktualizacji. Aktualizuj tylko wtedy, gdy użytkownik nie wchodzi w interakcję z Twoją aplikacją.
  • Ulepszenia wydajności: aktualizacja o średnim priorytecie; poproś o elastyczną formę płatności .
  • Krytyczna aktualizacja zabezpieczeń: aktualizacja o wysokim priorytecie; poproś o natychmiastową prośbę .

Aby określić priorytet, Google Play używa liczby całkowitej z zakresu od 0 do 5, przy czym 0 to wartość domyślna, a 5 to najwyższy priorytet. Aby ustawić priorytet aktualizacji, użyj pola inAppUpdatePriority w sekcji Edits.tracks.releases. w interfejsie Google Play Developer API. Wszystkie nowo dodane wersje są uważane za taki sam priorytet co wydanie. Priorytet można ustawić tylko wtedy, gdy podczas publikowania nowej wersji, której nie można później zmienić.

Ustaw priorytet przy użyciu interfejsu Google Play Developer API, zgodnie z opisem na stronie Google Play. Interfejs API dla programistów dokumentacji. Określ priorytet aktualizacji w aplikacji w Edit.tracks zasób przekazany w Edit.tracks: update . Poniższy przykład pokazuje publikowanie aplikacji z kodem wersji 88 i inAppUpdatePriority 5:

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

W kodzie aplikacji możesz sprawdzić priorytet danej aktualizacji, AppUpdateInfo_getPriority():

int32_t priority = AppUpdateInfo_getPriority(info);

Rozpocznij aktualizację

Po potwierdzeniu, że aktualizacja jest dostępna, możesz poprosić o jej przywrócenie przy użyciu: AppUpdateManager_requestStartUpdate() Zanim poprosisz o aktualizację, pobierz aktualny obiekt AppUpdateInfo i utwórz AppUpdateOptions. aby skonfigurować przepływ aktualizacji. Obiekt AppUpdateOptions określa definicję opcje procesu aktualizacji w aplikacji, w tym czy aktualizacja powinna lub natychmiastowych informacji.

Poniższy przykład tworzy obiekt AppUpdateOptions na potrzeby elastycznej aktualizacji przepływ:

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

Ten przykład pozwala utworzyć obiekt AppUpdateOptions dla funkcji natychmiastowej proces aktualizacji:

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

Obiekt AppUpdateOptions zawiera też pole AllowAssetPackDeletion. który określa, czy aktualizacja może wyczyścić zasób w przypadku ograniczonej pamięci urządzenia. Ten jest domyślnie ustawione na false, ale możesz użyć AppUpdateOptions_setAssetPackDeletionAllowed(). ustaw ją na true:

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

Gdy już będziesz mieć aktualny obiekt AppUpdateInfo i poprawnie skonfigurowany obiekt AppUpdateOptions obiekt, wywołaj AppUpdateManager_requestStartUpdate() do asynchronicznie żądania procesu aktualizacji, przekazując aktywność Androida jobject dla końcowego parametru.

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

Aby zwolnić zasoby, zwolnij instancje AppUpdateInfo i AppUpdateOptions, których już nie potrzebujesz, dzwoniąc do AppUpdateInfo_destroy(). oraz AppUpdateOptions_destroy(), .

AppUpdateInfo_destroy(info);
AppUpdateOptions_destroy(options);

Aby natychmiast przeprowadzić aktualizację, Google Play wyświetla stronę potwierdzenia użytkownika. Gdy użytkownik zaakceptuje prośbę, Google Play automatycznie pobierze instaluje aktualizację na pierwszym planie, a następnie uruchamia aplikację ponownie jeśli instalacja się powiedzie.

Aby korzystać z elastycznego procesu aktualizacji, możesz nadal przesyłać prośby o aktualność AppUpdateInfo śledzić bieżący stan aktualizacji, gdy użytkownik wchodzą w interakcję z aplikacją. Po zakończeniu pobierania musisz wywołaj zakończenie aktualizacji, wywołując AppUpdateManager_requestCompleteUpdate(), jak w tym przykładzie:

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

Zwolnij zasoby, wywołując metodę AppUpdateManager_destroy() .

Obsługa błędów

W tej sekcji znajdziesz rozwiązania typowych błędów wskazywanych przez określone AppUpdateErrorCode wartości:

  • Kod błędu -110, APP_UPDATE_INITIALIZATION_NEEDED oznacza, że Nie udało się zainicjować interfejsu API. Zadzwoń pod numer AppUpdateManager_init() do zainicjować interfejs API.
  • Kod błędu -4, APP_UPDATE_INVALID_REQUEST oznacza, że niektóre parametry żądania przepływu aktualizacji mają nieprawidłowy format. Upewnij się, że obiekty AppUpdateInfo i AppUpdateOptions nie mają wartości null i są prawidłowo sformatowanego.
  • Kod błędu -5, APP_UPDATE_UNAVAILABLE oznacza, że nie występują dostępna jest odpowiednia aktualizacja. Upewnij się, że wersja docelowa ma taką samą nazwa pakietu, identyfikator aplikacji, i klucz podpisywania. Jeśli aktualizacja jest dostępna, wyczyść pamięć podręczną aplikacji i wywołaj AppUpdateManager_requestAppUpdateInfo() ponownie, aby odśwież AppUpdateInfo.
  • Kod błędu -6, APP_UPDATE_NOT_ALLOWED oznacza, że typ aktualizacji wskazywana przez obiekt AppUpdateOption jest niedozwolone. Sprawdź, czy Obiekt AppUpdateInfo wskazuje, że typ aktualizacji jest dozwolony przed rozpoczyna się proces aktualizacji.

Dalsze kroki

Przetestuj aktualizacje aplikacji w sprawdź, czy integracja działa poprawnie.