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

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

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

Сборка для нативного

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

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

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

  3. В каталоге пакета ресурсов создайте файл build.gradle и добавьте следующий код. Обязательно укажите название пакета активов и только один тип доставки:

    // 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

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

Блок-схема пакета ресурсов для собственного кода

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

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

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

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. Выполните одно из следующих действий:

    • Установите Android Studio версии 4.0 или выше. Используйте пользовательский интерфейс SDK Manager для установки платформы Android SDK версии 10.0 (уровень API 29).
    • Установите инструменты командной строки Android SDK и используйте sdkmanager для установки платформы Android SDK версии 10.0 (уровень API 29).
  2. Подготовьте Android Studio для собственной разработки с помощью диспетчера SDK, чтобы установить последнюю версию CMake и Android Native Development Kit (NDK). Дополнительные сведения о создании или импорте собственных проектов см. в разделе «Начало работы с NDK» .

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

    Ссылка для скачивания Размер Контрольная сумма SHA-256
    36 МБ 782a8522d937848c83a715c9a258b95a3ff2879a7cd71855d137b41c00786a5e
  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.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")
            ...
        }
        

    Котлин

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

Сбор данных

Play Core Native SDK может собирать данные, связанные с версией, чтобы 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 для доступа к файлам.

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

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

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

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

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

Используйте AssetPackManager_requestRemoval() чтобы запланировать удаление пакета ресурсов.

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

Протестируйте доставку ресурсов Play локально и из Google Play.