Questa guida descrive come supportare gli annunci in-app aggiornamenti dell'app usando il codice nativo (C C++). Esistono guide separate per i casi in cui l'implementazione utilizza il linguaggio di programmazione Kotlin o la programmazione Java lingua e i casi in cui le tue utilizza Unity.
Panoramica di Native SDK
L'SDK nativo di Play Core fa parte del programma Play Core
SDK. Nativo
L'SDK include un file di intestazione C, app_update.h
, che aggrega
AppUpdateManager
dalla libreria di aggiornamento in-app di Java Play. Questo file di intestazione consente all'app
chiama l'API per gli aggiornamenti in-app direttamente dal codice nativo.
Configura l'ambiente di sviluppo
Scarica Play Core Native SDK
Prima di eseguire il download, devi accettare i seguenti termini e condizioni.
Termini e condizioni
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.
Esegui una delle seguenti operazioni:
- Installa Android Studio versione 4.0 o successive. Utilizza l'SDK UI di Manager per installare Android SDK Platform versione 10.0 (livello API 29).
- Installare gli strumenti a riga di comando dell'SDK per Android
e usa
sdkmanager
per installare Android SDK Platform versione 10.0 (livello API 29).
Prepara Android Studio per lo sviluppo nativo utilizzando Gestore SDK per installare la versione più recente CMake e Android Native Development Kit (NDK). Per ulteriori informazioni creazione o importazione di progetti nativi, consulta Introduzione all'NDK.
Scarica il file ZIP ed estrailo insieme al tuo progetto.
Link di download Dimensioni Checksum SHA-256 36 MiB 782a8522d937848c83a715c9a258b95a3ff2879a7cd71855d137b41c00786a5e Aggiorna il file
build.gradle
dell'app come mostrato di seguito:Alla moda
// 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")) ... }
Aggiorna i file
CMakeLists.txt
dell'app come mostrato di seguito: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 ...)
Raccolta dei dati
L'SDK nativo principale di Play potrebbe raccogliere dati relativi alla versione per consentire a Google di migliorare il prodotto, ad esempio:
- Nome pacchetto dell'app
- Versione pacchetto dell'app
- Versione di Core Native SDK di Play
Questi dati verranno raccolti al momento del caricamento del pacchetto dell'app
a Play Console. Per disattivare questa procedura di raccolta dei dati, rimuovi il
Importazione di $playcoreDir/playcore-native-metadata.jar
nel file build.gradle.
Tieni presente che questa raccolta di dati riguarda l'utilizzo dell'SDK nativo di base di Play e L'utilizzo da parte di Google dei dati raccolti è separato e indipendente dai suoi raccolta di dipendenze di libreria dichiarate in Gradle quando carichi la tua app alla Play Console.
Dopo aver integrato l'SDK nativo di base di Play nel progetto, includi il parametro seguente nei file che contengono chiamate API:
#include "play/app_update.h"
Inizializzare l'API In-app Update
Ogni volta che utilizzi l'API in-app Update, inizializzala chiamandola
AppUpdateManager_init()
, come mostrato nell'esempio seguente, creata con
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.
}
}
Verificare la disponibilità degli aggiornamenti
Prima di richiedere un aggiornamento, controlla se è disponibile un aggiornamento per il tuo
dell'app.
AppUpdateManager_requestInfo()
avvia una richiesta asincrona che raccoglie le informazioni richieste per avviare
il flusso di aggiornamento in-app in un secondo momento. La funzione restituisce APP_UPDATE_NO_ERROR
se la funzione
richiesta avviata correttamente.
AppUpdateErrorCode error_code = AppUpdateManager_requestInfo()
if (error_code == APP_UPDATE_NO_ERROR) {
// The request has successfully started, check the result using
// AppUpdateManager_getInfo.
}
Puoi monitorare il processo in corso e il risultato della richiesta utilizzando
AppUpdateManager_getInfo()
Oltre al codice di errore, questa funzione restituisce un
AppUpdateInfo
struct opaco, che puoi usare per recuperare informazioni sull'aggiornamento
richiesta. Ad esempio, potresti voler chiamare questa funzione in ogni ciclo di gioco
finché non restituisce un risultato non nullo per 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
}
...
}
Controlla lo stato di inattività degli aggiornamenti
Oltre a verificare la disponibilità di un aggiornamento, controlla quanto tempo è trascorso dall'ultima notifica di un aggiornamento all'utente tramite il Play Store. Questo può aiutarti a decidere se devi avviare o meno flessibile o immediato. Ad esempio, potresti attendere alcuni giorni prima di informare l'utente con un aggiornamento flessibile e alcuni giorni dopo prima di richiedere un aggiornamento immediato.
Utilizza le funzionalità di
AppUpdateInfo_getClientVersionStalenessDays()
per controllare il numero di giorni da quando l'aggiornamento è diventato disponibile tramite Google Play
Negozio:
int32_t staleness_days = AppUpdateInfo_getClientVersionStalenessDays(info);
Controlla la priorità degli aggiornamenti
L'API Google Play Developer ti consente di impostare la priorità di ogni aggiornamento. In questo modo la tua app può decidere in che misura consigliare un aggiornamento all'utente. Ad esempio, considera la seguente strategia per impostare la priorità degli aggiornamenti:
- Miglioramenti di minore entità all'interfaccia utente: aggiornamento a priorità bassa; non richiede uno spazio né un aggiornamento immediato. Aggiorna solo quando l'utente non interagisce con la tua app.
- Miglioramenti delle prestazioni: aggiornamento a priorità media; richiedere un piano flessibile aggiornamento.
- Aggiornamento critico della sicurezza: aggiornamento ad alta priorità; richiedi un accesso immediato aggiornamento.
Per determinare la priorità, Google Play utilizza un valore intero compreso tra 0 e 5, con 0
il valore predefinito e 5 la priorità massima. Per impostare la priorità di un
aggiorna, usa il campo inAppUpdatePriority
sotto
Edits.tracks.releases
nell'API Google Play Developer. Tutte le versioni appena aggiunte nella release
con la stessa priorità dell'uscita. La priorità può essere impostata solo quando
una nuova release e non può essere modificata in un secondo momento.
Imposta la priorità utilizzando l'API Google Play Developer, come descritto nella sezione
API per sviluppatori
documentazione.
Specifica la priorità degli aggiornamenti in-app nel campo
Edit.tracks
passata nella
Edit.tracks: update
. L'esempio seguente mostra il rilascio di un'app con codice di versione
88 e inAppUpdatePriority
5:
{ "releases": [{ "versionCodes": ["88"], "inAppUpdatePriority": 5, "status": "completed" }] }
Nel codice dell'app puoi controllare il livello di priorità di un determinato aggiornamento utilizzando
AppUpdateInfo_getPriority()
:
int32_t priority = AppUpdateInfo_getPriority(info);
Avvia un aggiornamento
Dopo aver confermato la disponibilità di un aggiornamento, puoi richiederne uno utilizzando
AppUpdateManager_requestStartUpdate()
Prima di richiedere un aggiornamento, ottieni un oggetto AppUpdateInfo
aggiornato e
crea un
AppUpdateOptions
per configurare il flusso di aggiornamento. Un oggetto AppUpdateOptions
definisce
per un flusso di aggiornamento in-app, ad esempio se l'aggiornamento deve essere
flessibile o immediato.
Nell'esempio seguente viene creato un oggetto AppUpdateOptions
per un aggiornamento flessibile
:
// Creates an AppUpdateOptions configuring a flexible in-app update flow.
AppUpdateOptions* options;
AppUpdateErrorCode error_code = AppUpdateOptions_createOptions(APP_UPDATE_TYPE_FLEXIBLE, &options);
L'esempio seguente crea un oggetto AppUpdateOptions
per una richiesta immediata
flusso di aggiornamento:
// Creates an AppUpdateOptions configuring an immediate in-app update flow.
AppUpdateOptions* options;
AppUpdateErrorCode error_code = AppUpdateOptions_createOptions(APP_UPDATE_TYPE_IMMEDIATE, &options);
L'oggetto AppUpdateOptions
contiene anche un campo AllowAssetPackDeletion
che definisce se l'aggiornamento può cancellare asset
pacchetti se lo spazio di archiviazione sul dispositivo è limitato. Questo
il campo è impostato su false
per impostazione predefinita, ma puoi utilizzare il
AppUpdateOptions_setAssetPackDeletionAllowed()
per impostarlo su true
:
bool allow = true;
AppUpdateErrorCode error_code = AppUpdateOptions_setAssetPackDeletionAllowed(options, allow);
Dopo che hai un oggetto AppUpdateInfo
aggiornato e un oggetto configurato correttamente
Oggetto AppUpdateOptions
, chiama AppUpdateManager_requestStartUpdate()
a
richiedere in modo asincrono un flusso di aggiornamento, trasmettendo un'attività Android jobject
per il parametro finale.
AppUpdateErrorCode request_error_code =
AppUpdateManager_requestStartUpdate(info, options, app->activity->clazz);
Per liberare risorse, rilascia le istanze di AppUpdateInfo
e
AppUpdateOptions
che non ti servono più chiamando
AppUpdateInfo_destroy()
:
e
AppUpdateOptions_destroy()
,
rispettivamente.
AppUpdateInfo_destroy(info);
AppUpdateOptions_destroy(options);
Per un flusso di aggiornamento immediato, Google Play mostra una pagina di conferma dell'utente. Quando l'utente accetta la richiesta, Google Play scarica automaticamente e installa l'aggiornamento in primo piano, quindi riavvia l'app se l'installazione è avvenuta correttamente.
Per un flusso di aggiornamento flessibile, puoi continuare a richiedere AppUpdateInfo
per tenere traccia dello stato di aggiornamento corrente mentre l'utente continua
interagire con l'app. Al termine del download, devi
attivare il completamento dell'aggiornamento richiamando
AppUpdateManager_requestCompleteUpdate()
,
come mostrato nell'esempio seguente:
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.
}
}
Libera risorse chiamando il metodo
AppUpdateManager_destroy()
quando l'app ha finito di usare l'API.
Gestione degli errori
Questa sezione descrive le soluzioni agli errori comuni indicati da errori
AppUpdateErrorCode
valori:
- Un codice di errore
-110, APP_UPDATE_INITIALIZATION_NEEDED
indica che L'API non è stata inizializzata correttamente. ChiamaAppUpdateManager_init()
per inizializzare l'API. - Il codice di errore
-4, APP_UPDATE_INVALID_REQUEST
indica che alcune i parametri della richiesta del flusso di aggiornamento non sono nel formato corretto. Verifica che gli oggettiAppUpdateInfo
eAppUpdateOptions
non sono nulli e il formato corretto. - Un codice di errore
-5, APP_UPDATE_UNAVAILABLE
indica che non sono presenti l'aggiornamento applicabile. Assicurati che la versione di destinazione abbia lo stesso package name, ID applicazione, e la chiave di firma. Se è disponibile un aggiornamento, svuota la cache dell'app e chiama di nuovoAppUpdateManager_requestAppUpdateInfo()
a aggiornaAppUpdateInfo
. - Un codice di errore
-6, APP_UPDATE_NOT_ALLOWED
indica che il tipo di aggiornamento indicato dall'oggettoAppUpdateOption
non è consentito. Controlla se L'oggettoAppUpdateInfo
indica che il tipo di aggiornamento è consentito prima avviando il flusso di aggiornamento.
Passaggi successivi
Testare gli aggiornamenti in-app dell'app per verificare il corretto funzionamento dell'integrazione.