Интегрированная доставка активов (родная)

Следуйте инструкциям в этом руководстве, чтобы получить доступ к пакетам ресурсов вашего приложения из кода на C и C++.

Пример кода интеграции доступен на GitHub.

Создано для нативных приложений

Выполните следующие шаги, чтобы интегрировать Play Asset Delivery в пакет Android-приложения вашего проекта. Для выполнения этих шагов вам не потребуется Android Studio.

  1. Обновите версию плагина Android Gradle в файле build.gradle вашего проекта до 4.0.0 или более поздней.

  2. В корневом каталоге вашего проекта создайте каталог для пакета ресурсов. Имя этого каталога будет использоваться в качестве имени пакета ресурсов. Имена пакетов ресурсов должны начинаться с буквы и могут содержать только буквы, цифры и подчеркивания.

  3. В каталоге asset pack создайте файл build.gradle и добавьте следующий код. Убедитесь, что указано имя asset pack и только один тип доставки:

    // 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. В файле build.gradle вашего проекта добавьте имена всех пакетов ресурсов, как показано ниже:

    // In the app build.gradle file:
    android {
        ...
        assetPacks = [":asset-pack-name", ":asset-pack2-name"]
    }
  5. В файле settings.gradle проекта добавьте все пакеты ресурсов, как показано ниже:

    // In the settings.gradle file:
    include ':app'
    include ':asset-pack-name'
    include ':asset-pack2-name'
  6. В каталоге пакета ресурсов создайте следующую подпапку: src/main/assets .

  7. Разместите ресурсы в каталоге src/main/assets . Здесь также можно создавать подкаталоги. Структура каталогов вашего приложения теперь должна выглядеть следующим образом:

    • build.gradle
    • settings.gradle
    • app/
    • asset-pack-name /build.gradle
    • asset-pack-name /src/main/assets/ your-asset-directories
  8. Создайте пакет Android-приложения с помощью Gradle . В сгенерированном пакете приложения корневой каталог теперь содержит следующее:

    • asset-pack-name /manifest/AndroidManifest.xml : Настраивает идентификатор пакета ресурсов и режим доставки.
    • asset-pack-name /assets/ your-asset-directories : Каталог, содержащий все ресурсы, входящие в состав пакета ресурсов.

    Gradle генерирует манифест для каждого пакета ресурсов и выводит путь к каталогу assets/ .

  9. (Необязательно) Настройте пакет приложения для поддержки различных форматов сжатия текстур .

Интеграция с библиотекой доставки игровых ресурсов (Play Asset Delivery Library).

Реализация этого API осуществляется в соответствии с типом доставки пакета ресурсов, к которому вы хотите получить доступ. Эти шаги показаны на следующей блок-схеме.

Диаграмма потока загрузки ресурсов для нативного кода

Рисунок 1. Блок-схема доступа к пакетам активов.

В состав Play Core Native SDK входит заголовочный файл на языке C play/asset_pack.h предназначенный для запроса пакетов ресурсов, управления загрузками и доступа к ресурсам.

Настройте среду разработки для Play Core Native SDK.

Скачать Play Core Native SDK

Перед загрузкой вы должны согласиться со следующими условиями.

Условия и положения

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.
Скачать Play Core Native SDK

play-core-native-sdk-1.16.0.zip

  1. Выполните одно из следующих действий:

  2. Подготовьте Android Studio к разработке нативных приложений, используя SDK Manager для установки последних версий CMake и Android Native Development Kit (NDK). Дополнительную информацию о создании или импорте нативных проектов см. в разделе «Начало работы с NDK» .

  3. Скачайте zip-файл и распакуйте его вместе с вашим проектом.

    Ссылка для скачивания Размер Контрольная сумма SHA-256
    54,8 МиБ 008b8fedc6179a6dc6ccc21af75591afc7036f78f3d5559d844f1b923934fef0
  4. Обновите файл build.gradle вашего приложения, как показано ниже:

    Классный

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

    Котлин

    // 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. Обновите файлы CMakeLists.txt вашего приложения, как показано ниже:

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

Сбор данных

SDK Play Core Native может собирать данные, связанные с версией, чтобы позволить Google улучшить продукт, в том числе:

  • Название пакета приложения
  • Версия пакета приложения
  • Играйте в версию Core Native SDK

Эти данные будут собираться при загрузке пакета вашего приложения в Play Console. Чтобы отказаться от сбора этих данных, удалите импорт $playcoreDir/playcore-native-metadata.jar в файле build.gradle.

Обратите внимание, что сбор данных, связанный с использованием вами Play Core Native SDK, и использование собранных данных компанией Google осуществляется отдельно и независимо от сбора Google зависимостей библиотек, объявленных в Gradle при загрузке пакета вашего приложения в Play Console.

Доставка в момент установки

Пакеты ресурсов, настроенные как install-time становятся доступны сразу после запуска приложения. Используйте 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);

Быстрая доставка по запросу.

В следующих разделах описано, как инициализировать API, как получить информацию о пакетах ресурсов перед их загрузкой, как вызвать API для начала загрузки и как получить доступ к загруженным пакетам. Эти разделы относятся к пакетам ресурсов fast-follow и on-demand .

Запуск приложения

Перед вызовом любой другой функции всегда вызывайте функцию AssetPackManager_init() для инициализации API пакета ресурсов. Проверяйте наличие кодов ошибок пакета ресурсов .

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

Также обязательно вызовите следующие функции в методах onPause() и onResume() класса ANativeActivityCallbacks :

Получите информацию о загрузке пакетов ресурсов.

Приложения обязаны сообщать размер загружаемого файла перед загрузкой пакета ресурсов. Используйте функцию AssetPackManager_requestInfo() для запуска асинхронного запроса размера загружаемого файла и проверки, загружается ли пакет уже. Затем используйте AssetPackManager_getDownloadState() для проверки состояния загрузки (например, вызывайте эту функцию один раз за кадр в игровом цикле). Если запрос не удался, проверьте коды ошибок пакета ресурсов .

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

Функция AssetPackManager_getDownloadState() возвращает непрозрачный тип AssetPackDownloadState в виде указателя на выходной объект. Используйте этот указатель для вызова следующих функций:

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

Установить

Используйте AssetPackManager_requestDownload() , чтобы начать загрузку пакета ресурсов в первый раз или запросить завершение обновления пакета ресурсов:

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

Функция AssetPackManager_getDownloadState() возвращает непрозрачный тип AssetPackDownloadState . Информацию об использовании этого типа см. в разделе «Получение информации о загрузке» .

Большие файлы для скачивания

Если размер загружаемого файла превышает 200 МБ, и пользователь не подключен к Wi-Fi, загрузка не начнётся до тех пор, пока пользователь явно не даст своё согласие на продолжение загрузки с использованием мобильного интернет-соединения. Аналогично, если размер загружаемого файла велик и пользователь теряет Wi-Fi, загрузка приостанавливается, и для продолжения загрузки с использованием мобильного интернет-соединения требуется явное согласие. Приостановленный файл имеет состояние WAITING_FOR_WIFI . Чтобы запустить процесс пользовательского интерфейса для запроса согласия пользователя, используйте следующее:

Требуется подтверждение пользователя.

Если пакет имеет статус REQUIRES_USER_CONFIRMATION , загрузка не продолжится, пока пользователь не подтвердит диалоговое окно, отображаемое с помощью AssetPackManager_showConfirmationDialog() . Этот статус может возникнуть, если приложение не распознается Play. Обратите внимание, что вызов AssetPackManager_showConfirmationDialog() в этом случае приводит к обновлению приложения. После обновления запросите ресурсы снова.

Доступ к пакетам ресурсов

После завершения загрузки и достижения состояния COMPLETED вы можете получить доступ к пакету ресурсов с помощью вызовов файловой системы. Каждый пакет ресурсов хранится в отдельном каталоге во внутренней памяти приложения. Используйте AssetPackManager_getAssetPackLocation() , чтобы получить AssetPackLocation для указанного пакета ресурсов. Используйте AssetPackLocation_getStorageMethod() для этого местоположения, чтобы определить метод хранения:

  • ASSET_PACK_STORAGE_APK : Пакет ресурсов устанавливается как APK-файл. Для доступа к этим ресурсам см. раздел «Доставка во время установки» .
  • ASSET_PACK_STORAGE_FILES : Используйте AssetPackLocation_getAssetsPath() для получения пути к файлу в каталоге, содержащем ресурсы, или null, если ресурсы еще не были загружены. Не изменяйте загруженные файлы по указанному пути.
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);
}

После того как вы найдете нужные ресурсы, используйте такие функции, как fopen или ifstream для доступа к файлам.

Другие методы API ядра Play

Ниже приведены некоторые дополнительные методы API, которые вы можете использовать в своем приложении.

Отменить запрос

Используйте функцию AssetPackManager_cancelDownload() для отмены активного запроса на создание пакета ресурсов. Обратите внимание, что этот запрос выполняется с максимальными усилиями.

Запрос на удаление

Используйте функцию AssetPackManager_requestRemoval() для планирования удаления пакета ресурсов.

Следующие шаги

Тестирование доставки игровых ресурсов локально и из Google Play.