Integrare la pubblicazione degli asset (nativa)

Segui i passaggi descritti in questa guida per accedere ai pacchetti di asset della tua app dal codice C e C++.

Il codice di integrazione di esempio è disponibile su GitHub.

Creare per i formati nativi

Segui questa procedura per integrare Play Asset Delivery nell'app bundle Android del tuo progetto. Non è necessario utilizzare Android Studio per eseguire questi passaggi.

  1. Aggiorna la versione del plug-in Android per Gradle nel file build.gradle del progetto alla versione 4.0.0 o successiva.

  2. Nella directory di primo livello del progetto, crea una directory per il pacchetto di asset. Questo nome di directory viene utilizzato come nome del pacchetto di asset. I nomi dei pacchetti di asset devono iniziare con una lettera e possono contenere solo lettere, numeri e trattini bassi.

  3. Nella directory del pacchetto di asset, crea un file build.gradle e aggiungi il seguente codice. Assicurati di specificare il nome del pacchetto di asset e un solo tipo di caricamento:

    // In the asset pack’s build.gradle file:
    plugins {
        id 'com.android.asset-pack'
    }
    
    assetPack {
        packName = "asset-pack-name" // Directory name for the asset pack
        dynamicDelivery {
            deliveryType = "[ install-time | fast-follow | on-demand ]"
        }
    }
  4. Nel file build.gradle dell'app del progetto, aggiungi il nome di ogni asset pack nel progetto, come mostrato di seguito:

    // In the app build.gradle file:
    android {
        ...
        assetPacks = [":asset-pack-name", ":asset-pack2-name"]
    }
  5. Nel file settings.gradle del progetto, includi tutti i pacchetti di asset come mostrato di seguito:

    // In the settings.gradle file:
    include ':app'
    include ':asset-pack-name'
    include ':asset-pack2-name'
  6. Nella directory del pacchetto di asset, crea la seguente sottodirectory: src/main/assets.

  7. Inserisci gli asset nella directory src/main/assets. Puoi anche creare sottodirectory qui. La struttura di directory della tua app dovrebbe ora avere il seguente aspetto:

    • build.gradle
    • settings.gradle
    • app/
    • asset-pack-name/build.gradle
    • asset-pack-name/src/main/assets/your-asset-directories
  8. Crea l'app bundle Android con Gradle. Nell'app bundle generato, la directory di primo livello ora include quanto segue:

    • asset-pack-name/manifest/AndroidManifest.xml: configura l'identificatore e la modalità di caricamento del pacchetto di asset
    • asset-pack-name/assets/your-asset-directories: directory contenente tutte le risorse caricate nell'asset pack

    Gradle genera il manifest per ogni asset pack e genera la directory assets/ per te.

  9. (Facoltativo) Configura l'app bundle in modo da supportare diversi formati di compressione delle texture.

Integrazione con la raccolta di Play Asset Delivery

Implementa questa API in base al tipo di caricamento del pacchetto di asset a cui vuoi accedere. Questi passaggi sono illustrati nel seguente diagramma di flusso.

Diagramma di flusso del pacchetto di asset per il codice nativo

Figura 1. Diagramma di flusso per accedere ai pacchetti di asset

L'SDK nativo della libreria di base Play fornisce il file di intestazione Cplay/asset_pack.h per richiedere pacchetti di asset, gestire i download e accedere agli asset.

Configurare l'ambiente di sviluppo per l'SDK nativo della libreria di base Play

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

play-core-native-sdk-1.15.3.zip

  1. Procedi in uno dei seguenti modi:

    • Installa Android Studio versione 4.0 o successive. Utilizza l'interfaccia utente di SDK Manager per installare la versione 10.0 della piattaforma SDK per Android (livello API 29).
    • Installa gli strumenti a riga di comando dell'SDK Android e utilizza sdkmanager per installare la versione 10.0 della piattaforma SDK Android (livello API 29).
  2. Prepara Android Studio per lo sviluppo nativo utilizzando SDK Manager per installare le ultime versioni di CMake e del Native Development Kit (NDK) per Android. Per ulteriori informazioni sulla creazione o sull'importazione di progetti nativi, consulta la sezione Guida introduttiva all'NDK.

  3. Scarica il file ZIP ed estrailo insieme al progetto.

    Link di download Dimensioni Checksum SHA-256
    37,8 MiB 9db60185185342f28d2c278b60222333608c67bc022e458a25224eaea8c4c4b7
  4. Aggiorna il file build.gradle dell'app come mostrato di seguito:

    Groovy

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

    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.2")
    
        // Import these common dependencies.
        implementation("com.google.android.gms:play-services-tasks:18.0.2")
        implementation(files("$playcoreDir/playcore-native-metadata.jar"))
        ...
    }
  5. 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 della libreria di base Play potrebbe raccogliere dati relativi alla versione per consentire a Google di migliorare il prodotto, tra cui:

  • Nome del pacchetto dell'app
  • Versione del pacchetto dell'app
  • Versione dell'SDK nativo della libreria di base Play

Questi dati verranno raccolti quando carichi il pacchetto dell'app su Play Console. Per disattivare questa procedura di raccolta dei dati, rimuovi l'importazione di $playcoreDir/playcore-native-metadata.jar nel file build.gradle.

Tieni presente che questa raccolta di dati relativa al tuo utilizzo dell'SDK nativo Play Core e all'utilizzo da parte di Google dei dati raccolti è separata e indipendente dalla raccolta di dipendenze di libreria dichiarate in Gradle quando carichi il pacchetto dell'app su Play Console.

Pubblicazione al momento dell'installazione

I pacchetti di asset configurati come install-time sono disponibili immediatamente al lancio dell'app. Utilizza l'API NDK AAssetManager per accedere agli asset pubblicati in questa modalità:

#include <android/asset_manager.h>
#include <android_native_app_glue.h>
...
AAssetManager* assetManager = app->activity->assetManager;
AAsset* asset = AAssetManager_open(assetManager, "asset-name", AASSET_MODE_BUFFER);
size_t assetLength = AAsset_getLength(asset);
char* buffer = (char*) malloc(assetLength + 1);
AAsset_read(asset, buffer, assetLength);

Fast-follow e distribuzione on demand

Le sezioni seguenti mostrano come inizializzare l'API, come ottenere informazioni sui pacchetti di asset prima di scaricarli, come chiamare l'API per avviare il download e come accedere ai pacchetti scaricati. Queste sezioni si applicano ai pacchetti di asset fast-follow e on-demand.

Avvio app

Chiama sempre AssetPackManager_init() per inizializzare l'API asset pack prima di chiamare qualsiasi altra funzione. Controlla la presenza di codici di errore del pacchetto di asset.

#include "play/asset_pack.h"
...
AssetPackErrorCode AssetPackManager_init(JavaVM* jvm, jobject android_context);

Assicurati inoltre di chiamare le seguenti funzioni in onPause() e onResume() di ANativeActivityCallbacks:

Visualizzare le informazioni di download dei pacchetti di asset

Le app sono tenute a indicare le dimensioni del download prima di recuperare il pacchetto di asset. Utilizza la funzione AssetPackManager_requestInfo() per avviare una richiesta asincrona per le dimensioni del download e per verificare se il pacchetto è già in download. Quindi, utilizza AssetPackManager_getDownloadState() per eseguire il polling dello stato del download (ad esempio, chiama questa funzione una volta per frame nel loop di gioco). Se una richiesta non va a buon fine, controlla i codici di errore dei pacchetti di asset.

AssetPackErrorCode AssetPackManager_requestInfo();      // Call once
AssetPackErrorCode AssetPackManager_getDownloadState(); // Call once per frame in your game loop

La funzione AssetPackManager_getDownloadState() restituisce il tipo opaco AssetPackDownloadState come un puntatore di output. Utilizza questo puntatore per chiamare le seguenti funzioni:

AssetPackDownloadState* state;
AssetPackErrorCode error_code = AssetPackManager_getDownloadState(asset-pack-name, &state);
AssetPackDownloadStatus status = AssetPackDownloadState_getStatus(state);
uint64_t downloadedBytes = AssetPackDownloadState_getBytesDownloaded(state);
uint64_t totalBytes = AssetPackDownloadState_getTotalBytesToDownload(state));
AssetPackDownloadState_destroy(state);

Installa

Utilizza AssetPackManager_requestDownload() per avviare il download di un asset pack per la prima volta o per richiedere il completamento di un aggiornamento dell'asset pack:

AssetPackErrorCode AssetPackManager_requestDownload();  // Call once
AssetPackErrorCode AssetPackManager_getDownloadState(); // Call once per frame in your game loop

La funzione AssetPackManager_getDownloadState() restituisce il tipo opaco AssetPackDownloadState. Per informazioni su come utilizzare questo tipo, consulta Ottenere informazioni sul download.

Download di grandi dimensioni

Se il download è superiore a 200 MB e l'utente non è connesso al Wi-Fi, il download non viene avviato finché l'utente non dà il consenso esplicito a procedere con il download utilizzando una connessione dati mobili. Analogamente, se il download è di grandi dimensioni e l'utente perde la connessione Wi-Fi, il download viene messo in pausa e per procedere utilizzando una connessione dati mobili è necessario il consenso esplicito. Un pacchetto in pausa ha lo stato WAITING_FOR_WIFI. Per attivare il flusso dell'interfaccia utente che richiede il consenso dell'utente, utilizza quanto segue:

Conferma dell'utente richiesta

Se un pacchetto ha lo stato REQUIRES_USER_CONFIRMATION, il download non procede finché l'utente non accetta la finestra di dialogo visualizzata con AssetPackManager_showConfirmationDialog(). Questo stato può verificarsi se l'app non è riconosciuta da Google Play. Tieni presente che in questo caso la chiamata a AssetPackManager_showConfirmationDialog() provoca l'aggiornamento dell'app. Dopo l'aggiornamento, richiedi di nuovo gli asset.

Accedere ai pacchetti di asset

Puoi accedere a un pacchetto di asset utilizzando le chiamate al file system dopo che la richiesta di download ha raggiunto lo stato COMPLETED. Ogni pacchetto di asset viene archiviato in una directory distinta nella memoria interna dell'app. Utilizza AssetPackManager_getAssetPackLocation() per ottenere un AssetPackLocation per il pacchetto di asset specificato. Utilizza AssetPackLocation_getStorageMethod() nella posizione in questione per determinare il metodo di archiviazione:

  • ASSET_PACK_STORAGE_APK: il pacchetto di asset viene installato come APK. Consulta Importazione al momento dell'installazione per accedere a questi asset.
  • ASSET_PACK_STORAGE_FILES: utilizza AssetPackLocation_getAssetsPath() per ottenere il percorso del file della directory contenente gli asset o null se gli asset non sono stati scaricati. Non modificare i file scaricati in questo percorso.
AssetPackLocation* location;

AssetPackErrorCode error_code = AssetPackManager_getAssetPackLocation(asset-pack-name, &location);

if (error_code == ASSET_PACK_NO_ERROR) {
    AssetPackStorageMethod storage_method = AssetPackLocation_getStorageMethod(location);
    const char* assets_path = AssetPackLocation_getAssetsPath(location);
    AssetPackLocation_destroy(location);
}

Una volta individuati gli asset, utilizza funzioni come fopen o ifstream per accedere ai file.

Altri metodi dell'API Play Core

Di seguito sono riportati alcuni metodi API aggiuntivi che potresti voler utilizzare nella tua app.

Annulla richiesta

Utilizza AssetPackManager_cancelDownload() per annullare una richiesta di pacchetti di asset attivi. Tieni presente che questa richiesta è un'operazione di tipo "best effort".

Richiedi rimozione

Utilizza AssetPackManager_requestRemoval() per pianificare la rimozione di un pacchetto di asset.

Passaggi successivi

Eseguire il test di Play Asset Delivery localmente e da Google Play.