アセット配信を統合する(ネイティブ)

このガイドの手順に沿って、C / C++ コードでアプリのアセットパックにアクセスします。

統合コードのサンプルは GitHub で入手できます。

ネイティブ向けのビルド

プロジェクトの Android App Bundle に Play Asset Delivery を組み込む手順は次のとおりです。この手順で Android Studio を使用する必要はありません。

  1. プロジェクトの build.gradle ファイル内の Android Gradle プラグインのバージョンを 4.0.0 以降に更新します。

  2. プロジェクトの最上位ディレクトリに、Asset Pack のディレクトリを作成します。このディレクトリ名は Asset Pack 名として使用されます。Asset Pack 名の先頭は英字にしてください。その後には、英字、数字、アンダースコアのみ使用できます。

  3. Asset Pack のディレクトリに build.gradle ファイルを作成し、下記のコードを入力します。Asset Pack の名前と配信タイプを 1 つだけ指定します。

    // 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 ファイルで、下記のように、プロジェクト内の各 Asset Pack の名前を追加します。

    // In the app build.gradle file:
    android {
        ...
        assetPacks = [":asset-pack-name", ":asset-pack2-name"]
    }
    
  5. プロジェクトの settings.gradle ファイルに、下記のように、プロジェクト内のすべての Asset Pack をインクルードします。

    // In the settings.gradle file:
    include ':app'
    include ':asset-pack-name'
    include ':asset-pack2-name'
    
  6. Asset Pack のディレクトリにサブディレクトリ 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. Gradle を使用して Android App Bundle をビルドします。生成された App Bundle のルートレベルのディレクトリには、以下が含まれるようになりました。

    • asset-pack-name/manifest/AndroidManifest.xml: Asset Pack の識別子と配信モードを設定します
    • asset-pack-name/assets/your-asset-directories: Asset Pack の一部として配信されるすべてのアセットを含むディレクトリです

    Gradle は各 Asset Pack のマニフェストを生成し、assets/ ディレクトリを出力してくれます。

  9. (省略可)さまざまなテクスチャ圧縮形式をサポートするように App Bundle を構成します。

Play Core SDK との統合

Play Core Native SDK には、アセットパックのリクエスト、ダウンロードの管理、アセットへのアクセスのための C ヘッダー ファイル play/asset_pack.h が用意されています。まず、プロジェクトに Play Core Library を追加します。

アクセスするアセットパックの配信タイプに応じて、この API を実装します。Asset Pack にアクセスする手順を次のフローチャートに示します。

Asset Pack のネイティブ コードのフロー図

図 1:Asset Pack へのアクセスのフロー図

インストール時の配信

install-time として設定された Asset Pack は、アプリの起動時にすぐに利用できます。このモードで配信されるアセットにアクセスするには、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);

fast-follow 配信と on-demand 配信

以下のセクションでは、API を初期化する方法、Asset Pack に関する情報をダウンロード前に取得する方法、API を呼び出してダウンロードを開始する方法、ダウンロードしたパックにアクセスする方法について説明します。このセクションは、fast-followon-demand の Asset Pack を対象としています。

アプリを起動

他の関数を呼び出す前に、必ず AssetPackManager_init() を呼び出して Asset Pack API を初期化します。Asset Pack のエラーコードがないか確認します。

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

また、次の関数は必ず ANativeActivityCallbacksonPause()onResume() で呼び出してください。

Asset Pack のダウンロード情報を取得

アプリは、Asset Pack を取得する前に、ダウンロード サイズを開示する必要があります。ダウンロードのサイズを確認し、パックがすでにダウンロード中かどうかを判別するための非同期リクエストを開始するには、AssetPackManager_requestInfo() 関数を使用します。次に、AssetPackManager_getDownloadState() を使用してダウンロード状態をポーリングします(たとえば、ゲームループ内のフレームごとにこの関数を 1 回呼び出します)。リクエストが失敗した場合、Asset Pack のエラーコードを確認します。

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

インストール

Asset Pack の最初のダウンロードや、Asset Pack を更新して完了するためのリクエストを行うには、AssetPackManager_requestDownload() を使用します。

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

AssetPackManager_getDownloadState() 関数は、不透明型の AssetPackDownloadState を返します。この型の使用方法については、ダウンロード情報を取得をご覧ください。

大規模なダウンロード

ダウンロードのサイズが 150 MB を超えていて、ユーザーが Wi-Fi に接続していない場合、モバイルデータ通信を介してダウンロードを続行することにユーザーが明示的に同意するまで、ダウンロードは開始されません。同様に、ダウンロードのサイズが大きく、ユーザーの Wi-Fi 接続が切断された場合は、ダウンロードが一時停止され、モバイルデータ接続を使用してダウンロードを続行するにはユーザーの明示的な同意が必要になります。一時停止されたパックは WAITING_FOR_WIFI の状態になります。ユーザーに同意を求める UI フローをトリガーするには、次の関数を使用します。

Asset Pack にアクセス

ダウンロード リクエストが COMPLETED 状態になった後、ファイル システム呼び出しを使用して Asset Pack にアクセスできます。各 Asset Pack は、アプリの内部ストレージ内の個別のディレクトリに保存されます。AssetPackManager_getAssetPackLocation() を使用して、指定した Asset Pack の AssetPackLocation を取得します。その場所で AssetPackLocation_getStorageMethod() を使用して格納方法を確認します。

  • ASSET_PACK_STORAGE_APK: Asset Pack は APK としてインストールされます。これらのアセットにアクセスするには、install-time 配信をご覧ください。
  • 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);
}

アセットが見つかったら、fopenifstream などの関数を使用してファイルにアクセスします。

その他の Play Core API メソッド

アプリで使用できるその他の API メソッドを次にいくつか示します。

リクエストをキャンセルする

アクティブなアセットパック リクエストをキャンセルするには、AssetPackManager_cancelDownload() を使用します。このリクエストはベスト エフォート型のオペレーションです。

削除をリクエスト

Asset Pack の削除をスケジュールするには、AssetPackManager_requestRemoval() を使用します。

次のステップ

ローカルおよび Google Play で Play Asset Delivery をテストします。