Integracja dostawy zasobów (format natywny)

Aby uzyskać dostęp do pakietów zasobów aplikacji z poziomu kodu C i C++, wykonaj czynności opisane w tym przewodniku.

Przykładowy kod integracji jest dostępny na GitHubie.

Tworzenie reklam natywnych

Aby włączyć Play Asset Delivery w pakiecie Android App Bundle projektu, wykonaj te czynności. Nie musisz używać Android Studio, aby wykonać te czynności.

  1. Zaktualizuj wersję wtyczki Androida do obsługi Gradle w pliku build.gradle projektu do wersji 4.0.0 lub nowszej.

  2. W katalogu najwyższego poziomu projektu utwórz katalog pakietu zasobów. Nazwa tego katalogu jest używana jako nazwa pakietu zasobów. Nazwy pakietów zasobów muszą zaczynać się od litery i mogą zawierać tylko litery, cyfry i podkreślenia.

  3. W katalogu pakietu zasobów utwórz plik build.gradle i dodaj do niego ten kod. Pamiętaj, aby podać nazwę pakietu zasobów i tylko jeden typ dostarczania:

    // 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. W pliku build.gradle aplikacji projektu dodaj nazwę każdego pakietu zasobów w projekcie, jak pokazano poniżej:

    // In the app build.gradle file:
    android {
        ...
        assetPacks = [":asset-pack-name", ":asset-pack2-name"]
    }
  5. W pliku settings.gradle projektu uwzględnij wszystkie pakiety zasobów w projekcie, jak pokazano poniżej:

    // In the settings.gradle file:
    include ':app'
    include ':asset-pack-name'
    include ':asset-pack2-name'
  6. W katalogu pakietu zasobów utwórz podkatalog src/main/assets.

  7. Umieść zasoby w katalogu src/main/assets. Możesz tu też tworzyć podkatalogi. Struktura katalogów aplikacji powinna teraz wyglądać tak:

    • build.gradle
    • settings.gradle
    • app/
    • asset-pack-name/build.gradle
    • asset-pack-name/src/main/assets/your-asset-directories
  8. Tworzenie pakietu Android App Bundle za pomocą Gradle W wygenerowanym pakiecie aplikacji katalog na poziomie głównym zawiera teraz te elementy:

    • asset-pack-name/manifest/AndroidManifest.xml: konfiguruje identyfikator i tryb dostarczania pakietu zasobów.
    • asset-pack-name/assets/your-asset-directories: katalog zawierający wszystkie zasoby dostarczane w ramach pakietu zasobów.

    Gradle generuje plik manifestu dla każdego pakietu zasobów i tworzy katalog assets/.

  9. (Opcjonalnie) Skonfiguruj pakiet aplikacji tak, aby obsługiwał różne formaty kompresji tekstur.

Integracja z biblioteką Play Asset Delivery

Interfejs API implementuje się zgodnie z typem dostarczania pakietu zasobów, do którego chcesz uzyskać dostęp. Te kroki są przedstawione na schemacie blokowym poniżej.

Diagram przepływu pakietu zasobów w przypadku kodu natywnego

Rysunek 1. Diagram przepływu dotyczący uzyskiwania dostępu do pakietów zasobów

Pakiet SDK podstawowej biblioteki Play do aplikacji natywnych zawiera plik nagłówka C play/asset_pack.h, który umożliwia wysyłanie żądań pakietów zasobów, zarządzanie pobieraniem i uzyskiwanie dostępu do zasobów.

Konfigurowanie środowiska programistycznego pod kątem pakietu SDK podstawowej biblioteki Play do aplikacji natywnych

Pobierz Play Core Native SDK

Przed pobraniem musisz zaakceptować poniższe warunki.

Warunki korzystania z usługi

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

play-core-native-sdk-1.16.0.zip

  1. Wykonaj jedną z tych czynności:

    • Zainstaluj Android Studio w wersji 4.0 lub nowszej. Użyj interfejsu SDK Managera, aby zainstalować platformę Android SDK w wersji 10.0 (poziom interfejsu API 29).
    • Zainstaluj narzędzia wiersza poleceń Android SDK i użyj sdkmanager, aby zainstalować platformę Android SDK w wersji 10.0 (interfejs API na poziomie 29).
  2. Przygotuj Android Studio do tworzenia aplikacji natywnych, używając SDK Managera do zainstalowania najnowszej wersji CMake i pakietu Android Native Development Kit (NDK). Więcej informacji o tworzeniu i importowaniu projektów natywnych znajdziesz w artykule Pierwsze kroki z NDK.

  3. Pobierz plik ZIP i rozpakuj go w projekcie.

    Link pobierania Rozmiar Suma kontrolna SHA-256
    54,8 MiB 008b8fedc6179a6dc6ccc21af75591afc7036f78f3d5559d844f1b923934fef0
  4. Zaktualizuj plik build.gradle aplikacji w sposób pokazany poniżej:

    Dynamiczny

        // 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.3.0'
            implementation 'com.google.android.play:integrity:1.6.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.3.0")
        implementation("com.google.android.play:integrity:1.6.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. Zaktualizuj pliki CMakeLists.txt aplikacji w sposób pokazany 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 SDK podstawowej biblioteki Play do aplikacji natywnych może zbierać dane związane z wersją, aby umożliwić Google ulepszanie usługi. Dotyczy to m.in.:

  • Nazwa pakietu aplikacji
  • Wersja pakietu aplikacji
  • Wersja pakietu SDK podstawowej biblioteki Play do aplikacji natywnych

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

Pamiętaj, że zbieranie danych związanych z korzystaniem z pakietu Play Core Native SDK i wykorzystywanie ich przez Google jest niezależne od zbierania przez Google zależności bibliotek zadeklarowanych w Gradle podczas przesyłania pakietu aplikacji do Konsoli Play.

Dostarczanie w czasie instalacji

Pakiety zasobów skonfigurowane jako install-time są dostępne od razu po uruchomieniu aplikacji. Aby uzyskać dostęp do zasobów dostarczanych w tym trybie, użyj interfejsu API NDK AAssetManager:

#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);

Szybka dostawa i dostawa na żądanie

W poniższych sekcjach dowiesz się, jak zainicjować interfejs API, jak uzyskać informacje o pakietach zasobów przed ich pobraniem, jak wywołać interfejs API, aby rozpocząć pobieranie, oraz jak uzyskać dostęp do pobranych pakietów. Te sekcje dotyczą pakietów zasobów fast-follow i on-demand.

Uruchomienie aplikacji

Zawsze wywołuj AssetPackManager_init(), aby zainicjować interfejs API pakietu zasobów przed wywołaniem jakiejkolwiek innej funkcji. Sprawdź, czy nie występują kody błędów pakietu zasobów.

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

Pamiętaj też, aby wywołać te funkcje w metodach onPause() i onResume() klasy ANativeActivityCallbacks:

Uzyskiwanie informacji o pobieraniu pakietów zasobów

Aplikacje muszą ujawniać rozmiar pliku do pobrania przed pobraniem pakietu zasobów. Użyj funkcji AssetPackManager_requestInfo(), aby rozpocząć żądanie asynchroniczne dotyczące rozmiaru pobieranego pakietu i sprawdzenia, czy pakiet jest już pobierany. Następnie użyj funkcji AssetPackManager_getDownloadState(), aby sprawdzić stan pobierania (np. wywołaj tę funkcję raz na klatkę w pętli gry). Jeśli żądanie się nie powiedzie, sprawdź kody błędów pakietu zasobów.

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

Funkcja AssetPackManager_getDownloadState() zwraca nieprzezroczysty typ AssetPackDownloadState jako wskaźnik wyjściowy. Użyj tego wskaźnika, aby wywołać te funkcje:

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

Zainstaluj

Użyj AssetPackManager_requestDownload(), aby rozpocząć pobieranie pakietu zasobów po raz pierwszy lub poprosić o dokończenie aktualizacji pakietu zasobów:

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

Funkcja AssetPackManager_getDownloadState() zwraca nieprzezroczysty typ AssetPackDownloadState. Informacje o tym, jak używać tego typu, znajdziesz w artykule Pobieranie informacji.

pobierania dużych plików,

Jeśli rozmiar pobieranych danych przekracza 200 MB, a użytkownik nie jest połączony z Wi-Fi, pobieranie nie rozpocznie się, dopóki użytkownik nie wyrazi wyraźnej zgody na pobieranie przez komórkowe połączenie transmisji danych. Podobnie, jeśli pobierany plik jest duży, a użytkownik straci połączenie z Wi-Fi, pobieranie zostanie wstrzymane i będzie wymagało wyraźnej zgody na kontynuowanie przy użyciu mobilnej transmisji danych. Wstrzymany pakiet ma stan WAITING_FOR_WIFI. Aby uruchomić proces interfejsu, który prosi użytkownika o zgodę, użyj:

Wymagana zgoda użytkownika

Jeśli pakiet ma stan REQUIRES_USER_CONFIRMATION, pobieranie nie rozpocznie się, dopóki użytkownik nie zaakceptuje okna dialogowego wyświetlanego z AssetPackManager_showConfirmationDialog(). Ten stan może wystąpić, jeśli aplikacja nie jest rozpoznawana przez Google Play. Pamiętaj, że w tym przypadku wywołanie metody AssetPackManager_showConfirmationDialog() powoduje zaktualizowanie aplikacji. Po aktualizacji ponownie poproś o zasoby.

Dostęp do pakietów zasobów

Dostęp do pakietu zasobów możesz uzyskać za pomocą wywołań systemu plików, gdy żądanie pobrania osiągnie stan COMPLETED. Każdy pakiet zasobów jest przechowywany w osobnym katalogu w pamięci wewnętrznej aplikacji. Użyj AssetPackManager_getAssetPackLocation(), aby uzyskać AssetPackLocation dla określonego pakietu zasobów. Użyj AssetPackLocation_getStorageMethod() w tej lokalizacji, aby określić metodę przechowywania:

  • ASSET_PACK_STORAGE_APK: pakiet zasobów jest instalowany jako plik APK. Aby uzyskać dostęp do tych zasobów, zapoznaj się z sekcją Dostarczanie w czasie instalacji.
  • ASSET_PACK_STORAGE_FILES: użyj AssetPackLocation_getAssetsPath(), aby uzyskać ścieżkę do katalogu zawierającego zasoby, lub null, jeśli zasoby nie zostały pobrane. Nie modyfikuj pobranych plików w tej ścieżce.
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);
}

Gdy znajdziesz zasoby, użyj funkcji takich jak fopen lub ifstream, aby uzyskać dostęp do plików.

Inne metody interfejsu podstawowej biblioteki Play API

Oto kilka dodatkowych metod interfejsu API, których możesz użyć w aplikacji.

Anuluj prośbę

Użyj AssetPackManager_cancelDownload(), aby anulować aktywne żądanie pakietu zasobów. Pamiętaj, że ta prośba jest operacją wykonywaną w miarę możliwości.

Poproś o usunięcie

Użyj AssetPackManager_requestRemoval(), aby zaplanować usunięcie pakietu zasobów.

Dalsze kroki

Przetestuj Play Asset Delivery lokalnie i w Google Play.