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

Используйте шаги, описанные в этом руководстве, для доступа к пакетам ресурсов вашего приложения из кода 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. В файле проекта app 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

Скачать 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.15.4.zip

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

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

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

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

    Котлин

    // 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.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. Обновите файлы 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 улучшить продукт, включая:

  • Имя пакета приложения
  • Версия пакета приложения
  • Версия Play 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 Core

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

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

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

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

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

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

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