Integrowanie dostarczania zasobów (reklamy natywne)

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

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

Tworzenie na potrzeby reklam natywnych

Wykonaj poniższe czynności, aby dodać funkcję Play Asset Delivery do pakietu Android App Bundle swojego projektu. Nie musisz używać Android Studio do wykonania tych 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 dla pakietu zasobów. Ta nazwa 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 oraz podkreślenia.

  3. W katalogu pakietu zasobów utwórz plik build.gradle i dodaj ten kod. Podaj nazwę pakietu zasobów i tylko jeden typ przesyłania:

    // 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 w projekcie 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 umieść wszystkie pakiety zasobów w podany niżej sposób:

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

  7. Umieść zasoby w katalogu src/main/assets. Tutaj możesz 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. Utwórz pakiet Android App Bundle za pomocą Gradle W wygenerowanym pakiecie aplikacji katalog główny zawiera teraz:

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

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

  9. (Opcjonalnie) Skonfiguruj pakiet aplikacji pod kątem obsługi różnych formatów kompresji tekstur.

Integracja z biblioteką Play Asset Delivery

Ten interfejs API implementujesz zgodnie z typem przesyłania pakietu zasobów, do którego chcesz uzyskać dostęp. Kroki te są pokazane poniżej.

Diagram przepływu pakietu zasobów dla kodu natywnego

Rysunek 1. Schemat blokowy dostępu do pakietów zasobów

Play Core Native SDK udostępnia plik nagłówka C play/asset_pack.h, który służy do wysyłania żądań pakietów zasobów, zarządzania pobieraniem i uzyskiwania dostępu do zasobów.

Konfigurowanie środowiska programistycznego pod kątem podstawowego pakietu SDK Play

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:

  2. Przygotuj Android Studio do tworzenia aplikacji natywnych, korzystając z Menedżera SDK, aby zainstalować najnowszy pakiet NDK (CMake i Android Native Development Kit). Więcej informacji o tworzeniu i importowaniu projektów natywnych znajdziesz w artykule Wprowadzenie do pakietu NDK.

  3. Pobierz plik ZIP i rozpakuj go wraz ze swoim projektem.

    Link do pobrania Rozmiar Suma kontrolna SHA-256
    36 MiB 782a8522d937848c83a715c9a258b95a3ff2879a7cd71855d137b41c00786a5e
  4. Zaktualizuj plik build.gradle aplikacji w ten sposób:

    Odlotowy

        // 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.0.0'
            implementation 'com.google.android.play:asset-delivery:2.0.0'
            implementation 'com.google.android.play:integrity:1.0.1'
            implementation 'com.google.android.play:review:2.0.0'
    
            // 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.0.0")
        implementation("com.google.android.play:asset-delivery:2.0.0")
        implementation("com.google.android.play:integrity:1.0.1")
        implementation("com.google.android.play:review:2.0.0")
    
        // 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 ten sposób:

    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

Podstawowy pakiet SDK w Google Play może gromadzić dane związane z wersją, aby umożliwić Google ulepszanie tej usługi. Obejmuje to:

  • Nazwa pakietu aplikacji
  • Wersja pakietu aplikacji
  • Wersja pakietu SDK podstawowego natywnego pakietu SDK

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

Pamiętaj, że zbieranie danych związanych z korzystaniem przez Ciebie z podstawowego pakietu SDK Play oraz przez Google jest niezależne od zbioru zależności bibliotek zadeklarowanych przez Google w Gradle podczas przesyłania pakietu aplikacji do Konsoli Play.

Dostawa podczas instalacji

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

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

Szybkie śledzenie i na żądanie

Z sekcji poniżej dowiesz się, jak zainicjować interfejs API, uzyskać informacje o pakietach zasobów przed ich pobraniem, jak wywołać interfejs API w celu rozpoczęcia pobierania i 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 metodę AssetPackManager_init(), aby zainicjować interfejs Asset pack API przed wywołaniem jakiejkolwiek innej funkcji. Sprawdź, czy nie ma kodów 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 onPause() i onResume() w ANativeActivityCallbacks:

Pobieranie informacji o pakietach zasobów do pobrania

Przed pobraniem pakietu zasobów aplikacje muszą ujawniać rozmiar pobieranego pliku. Użyj funkcji AssetPackManager_requestInfo(), aby rozpocząć asynchroniczne żądanie dotyczące rozmiaru pobieranego pliku i sprawdzić, czy pakiet jest już pobierany. Następnie użyj metody AssetPackManager_getDownloadState() do odpytywania stanu pobierania (np. wywołaj tę funkcję raz na klatkę w pętli gry). Jeśli żądanie nie powiedzie się, 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 jako wskaźnik wyjściowy typ nieprzezroczysty AssetPackDownloadState. Ten wskaźnik pozwala wywoływać następujące 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 operatora AssetPackManager_requestDownload(), aby po raz pierwszy pobrać pakiet zasobów lub poprosić o jego aktualizację:

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

Funkcja AssetPackManager_getDownloadState() zwraca typ nieprzezroczysty AssetPackDownloadState. Aby dowiedzieć się, jak korzystać z tego typu plików, przeczytaj artykuł Pobieranie informacji o pobieraniu.

Duże pliki do pobrania

Jeśli rozmiar pliku przekracza 200 MB, a użytkownik nie korzysta z Wi-Fi, pobieranie rozpocznie się dopiero wtedy, gdy użytkownik wyraźnie wyrazi zgodę na pobieranie przy użyciu komórkowego połączenia danych. I podobnie, jeśli pobierany jest dużo danych i użytkownik utraci połączenie z Wi-Fi, pobieranie zostanie wstrzymane, a kontynuacja korzystania z mobilnego połączenia transmisji danych będzie wymagać wyraźnej zgody użytkownika. Wstrzymany pakiet ma stan WAITING_FOR_WIFI. Aby wywołać w interfejsie prośbę o zgodę na wykorzystanie danych, użyj tych poleceń:

Wymagane potwierdzenie użytkownika

Jeśli pakiet ma stan REQUIRES_USER_CONFIRMATION, pobieranie nie zostanie ukończone, dopóki użytkownik nie zaakceptuje okna ze stanem AssetPackManager_showConfirmationDialog(). Ten stan może pojawić się, gdy aplikacja nie zostanie rozpoznana przez Google Play. Pamiętaj, że wywołanie metody AssetPackManager_showConfirmationDialog() w tym przypadku spowoduje zaktualizowanie aplikacji. Po aktualizacji ponownie poproś o zasoby.

Dostęp do pakietów zasobów

Gdy żądanie pobierania osiągnie stan COMPLETED, możesz uzyskać dostęp do pakietu zasobów za pomocą wywołań systemu plików. 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 zainstalowany jako plik APK. Informacje o tym, jak uzyskać dostęp do tych zasobów, znajdziesz w sekcji Dostawa w czasie instalacji.
  • ASSET_PACK_STORAGE_FILES: użyj wartości AssetPackLocation_getAssetsPath(), aby uzyskać ścieżkę pliku do katalogu zawierającego zasoby. Wartość 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 Play Core API

Poniżej znajdziesz kilka dodatkowych metod interfejsu API, których możesz używać w swojej aplikacji.

Anuluj prośbę

Użyj operatora AssetPackManager_cancelDownload(), aby anulować żądanie aktywnego pakietu zasobów. Pamiętaj, że jest to działanie z możliwością najlepszej obsługi.

Poproś o usunięcie

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

Dalsze kroki

Przetestuj przesyłanie zasobów Play lokalnie i z Google Play.