オンデバイス AI のための Google Play 早期アクセス プログラム(EAP)

はじめに

Play for On-device AI は、Android App Bundle と Google Play 配信のメリットをカスタム ML モデルの配信に活かします。これにより、追加費用なしでエコシステムの複雑さを軽減し、モデルのパフォーマンスを向上させることができます。これにより、コード、アセット、ML モデルを含む単一のアーティファクトを Play に公開し、さまざまな配信モードとターゲティング オプションから選択できます。

利点

  • 単一の公開アーティファクトを Google Play にアップロードし、ホスティング、配信、更新、ターゲティングを追加料金なしで Google Play に委任します。
  • ML モデルをインストール時、高速フォロー、オンデマンドで配信します。
    • インストール時の配信では、アプリの起動時に非常に大きなモデルが存在することを保証できます。モデルは APK としてインストールされます。
    • 高速フォロー配信は、アプリのインストール後にバックグラウンドで自動的に実行されます。モデルが完全にダウンロードされる前に、ユーザーがアプリを開く可能性があります。モデルはアプリの内部ストレージにダウンロードされます。
    • オンデマンド配信では、実行時にモデルをリクエストできます。これは、特定のユーザーフローに対してのみモデルが必要な場合に便利です。モデルはアプリの内部ストレージにダウンロードされます。
  • デバイスモデル、システム プロパティ、RAM に基づいて特定のデバイスをターゲットとする ML モデルのバリエーションを配信します。
  • Google Play の自動パッチ適用により、アプリのアップデートを小さくして最適化できます。つまり、ダウンロードする必要があるのはファイルの差分のみです。

考慮事項

  • Play for On-device AI を使用すると、Google Play デベロッパー販売 / 配布契約および Play Core ソフトウェア開発キット利用規約の各条項に同意したことになります。
  • 早期アクセス プログラムに参加するデベロッパーには、Play for On-device AI を評価し、Google Play にフィードバックを提供する責任があります。
  • Play for On-device AI によってダウンロードされたモデルは、モデルをダウンロードしたアプリでのみ使用できます。モデルは、サービス接続などを通じて他のアプリに提供しないでください。
  • 個々の AI パックのサイズは、圧縮後のダウンロード サイズに基づいて最大 1.5 GB です。App Bundle から生成されるアプリのバージョンの最大累積アプリサイズは 4 GB です。
  • サイズが 1 GB を超えるアプリの場合、最小 SDK レベルを 21 以上に設定する必要があります。
  • 早期アクセス プログラムの間に、オンデバイス AI 向け Play は変更される可能性があります。

オンデバイス AI のための Google Play の使用方法

オンデバイス AI のための Google Play は AI パックを使用します。配布可能なカスタムモデルは、アプリ バンドルの AI パック内にパッケージ化します。AI パックをインストール時、高速フォロー、オンデマンドで配信するかどうかを選択できます。

AI パックをアプリバンドルにパッケージ化することで、テストトラックやステージ別のロールアウトなど、Google Play の既存のテストツールとリリースツールをすべて使用して、カスタムモデルを使用してアプリの配信を管理できます。

AI パックは、アプリのバイナリとともに更新されます。新しいアプリのリリースで AI パックが変更されていない場合、Play の自動パッチ適用プロセスにより、ユーザーが AI パックを再ダウンロードする必要がなくなります。Google Play は、アプリの更新時に変更された部分のみをダウンロードします。

AI パックにはモデルのみが含まれます。Java/Kotlin とネイティブ ライブラリは使用できません。ML モデルを実行するためのライブラリやコードを配布する必要がある場合は、ベース モジュールまたは機能モジュールに移動します。AI パックと同じダウンロード設定とターゲティング設定になるように、機能モジュールを構成できます。

AI パックで LiteRT と MediaPipe を使用する

LiteRT と MediaPipe は AI パックで使用できます。モデルを AI パックとしてパッケージ化し、インストール時パックまたは高速フォロー パックとオンデマンド パックの手順に沿ってアクセスします。

関連情報:

AI パックを使ってみる

オンデバイス AI のための Google Play の使用を開始する方法の概要は次のとおりです。

  1. EAP に参加するには、Google Play に Google Play デベロッパー アカウント ID を提供してください。
  2. モデルを AI パックとして Android App Bundle にパッケージ化し、AI パックの配信方法を指定します。
  3. [省略可] デバイスごとに異なるモデルを配信する場合は、AI パックのデバイス ターゲティングを構成できます。たとえば、AI パック A を特定のデバイスモデルに配信し、AI パック B を 6 GB 以上の RAM を搭載したデバイスに配信し、他のすべてのデバイスには配信しないというように設定できます。
  4. [省略可] on-demand 配信または fast-follow 配信を使用している場合は、Play AI Delivery Library をアプリに統合して、必要に応じて AI パックをダウンロードします。
  5. App Bundle をテストして Google Play にリリースします。

Google Play デベロッパー アカウント ID を入力してください

この機能は早期アクセス版であるため、デバイス上の AI 向け Play にアクセスするには、デベロッパー アカウントが許可リストに登録されている必要があります。Google Play デベロッパー アカウント ID とアプリのパッケージ名を Google Play パートナー マネージャーまたは Play for On-device AI チームのメンバーに確認します。モデルを特定のデバイスにターゲティングするかどうかを指定します(これは前のセクションの手順 3 です)。現在、この機能をテストしていただくには、一部の Play パートナー様にご案内しています。

Android Gradle プラグインのバージョンを確認する

AI パックを使用するには、Android Gradle プラグイン(AGP)のバージョンが 8.8 以降であることを確認してください。このバージョンは Android Studio Ladybug 2 にパッケージ化されています。

モデルを AI パックとして抽出する

次の手順では Android Studio は必要ありません。

  1. プロジェクトの最上位ディレクトリに、AI パックのディレクトリを作成します。このディレクトリ名は AI パック名として使用されます。AI パック名の先頭は英字にする必要があります。名前に含められるのは文字、数字、アンダースコアのみです。
  2. AI パックのディレクトリに build.gradle ファイルを作成し、次のコードを追加します。AI パックの名前と、配信タイプを 1 つだけ指定します。

    // In the AI pack's build.gradle file:
    plugins {
      id 'com.android.ai-pack'
    }
    
    aiPack {
        packName = "ai-pack-name" // Directory name for the AI pack
        dynamicDelivery {
            deliveryType = "[ install-time | fast-follow | on-demand ]"
        }
    }
    
  3. プロジェクトのアプリの build.gradle ファイルで、下記のように、プロジェクト内の各 AI パックの名前を追加します。

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

    // In the settings.gradle file:
    include ':app'
    include ':ai-pack-name'
    include ':ai-pack2-name'
    
  5. AI パック内に src/main/assets/ ディレクトリを作成します。

  6. モデルを src/main/assets ディレクトリに配置します。ここでもサブディレクトリを作成できます。アプリのディレクトリ構造は次のようになります。

    • build.gradle
    • settings.gradle
    • app/
    • ai-pack-name/build.gradle
    • ai-pack-name/src/main/assets/your-model-directories
  7. モデルを読み込んで実行するコードを追加します。方法は、AI パックの配信モードによって異なります。インストール時ファスト フォロー/オンデマンドの手順については、下記をご覧ください。

  8. [省略可] デバイス ターゲティングを構成して、さまざまなデバイスにさまざまなモデルを配信します。

  9. Gradle を使用して Android App Bundle をビルドします。生成された App Bundle のルートレベルのディレクトリには、以下が含まれるようになりました。

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

    Gradle は各 AI パックのマニフェストを生成し、assets/ ディレクトリを出力します。

インストール時配信の設定

インストール時として設定された AI パックは、アプリの起動時にすぐに使用できます。このモードで配信される AI パックにアクセスするには、Java AssetManager API を使用します。

import android.content.res.AssetManager;
...
Context context = createPackageContext("com.example.app", 0);
AssetManager assetManager = context.getAssets();
InputStream is = assetManager.open("model-name");

fast-follow 配信と on-demand 配信を設定する

fast-follow 配信またはオンデマンド配信で AI パックをダウンロードするには、Play AI Delivery ライブラリを使用します。

Play AI Delivery Library の依存関係を宣言する

アプリの build.gradle ファイルで、Play AI Delivery Library への依存関係を宣言します。

dependencies {
  ...
  implementation "com.google.android.play:ai-delivery:0.1.1-alpha01"
}

ステータスを確認する

各 AI パックは、アプリの内部ストレージ内の個別のフォルダに保存されます。AI パックのルートフォルダを確認するには、getPackLocation() メソッドを使用します。このメソッドは以下の値を返します。

戻り値 ステータス
有効な AiPackLocation オブジェクト AI パックのルートフォルダは assetsPath() ですぐにアクセスできます
null 不明な AI パックまたは AI パックは利用できません

AI パックのダウンロード情報を取得する

ダウンロードのサイズを確認し、パックがすでにダウンロード中かどうかを判別するには、
getPackStates() メソッドを使用します。

Task<AiPackStates> getPackStates(List<String> packNames)

getPackStates() は、Task<AiPackStates> を返す非同期メソッドです。AiPackStates オブジェクトの packStates() メソッドは Map<String, AiPackState> を返します。このマップには、リクエストされた各 AI パックの状態(名前がキーになっています)が含まれます。

Map<String, AiPackState> AiPackStates#packStates()

最終リクエストは次のように表示されます。

final String aiPackName = "myAiPackName";

aiPackManager
    .getPackStates(Collections.singletonList(aiPackName))
    .addOnCompleteListener(new OnCompleteListener<AiPackStates>() {
        @Override
        public void onComplete(Task<AiPackStates> task) {
            AiPackStates aiPackStates;
            try {
                aiPackStates = task.getResult();
                AiPackState aiPackState =
                    aiPackStates.packStates().get(aiPackName);
            } catch (RuntimeExecutionException e) {
                Log.d("MainActivity", e.getMessage());
                return;
            });

次の AiPackState メソッドは、AI パックのサイズ、これまでにダウンロードされた量(リクエストされた場合)、すでにアプリに転送された量を提供します。

AI パックのステータスを取得するには、status() メソッドを使用します。このメソッドは、AiPackStatus クラスの定数フィールドに対応する整数としてステータスを返します。まだインストールされていない AI パックのステータスは AiPackStatus.NOT_INSTALLED です。

リクエストが失敗した場合は、errorCode() メソッドを使用します。このメソッドは、AiPackErrorCode クラスの定数フィールドに対応する戻り値を返します。

インストール

fetch() メソッドを使用して、AI パックの初回ダウンロードを行うか、AI パックの更新の完了を要求します。

Task<AiPackStates> fetch(List<String> packNames)

このメソッドは、パックのリストと初回ダウンロードの状態およびサイズを含む AiPackStates オブジェクトを返します。fetch() でリクエストされた AI パックがすでにダウンロード中の場合は、ダウンロード ステータスが返され、追加のダウンロードは開始されません。

ダウンロード状態をモニタリングする

AI パックのインストールの進行状況をトラッキングするには、AiPackStateUpdateListener を実装する必要があります。個々の AI パックのステータスをトラッキングできるように、ステータスの更新はパックごとに分類されます。リクエストしたすべてのダウンロードが完了する前に、利用可能な AI パックの使用を開始できます。

void registerListener(AiPackStateUpdateListener listener)
void unregisterListener(AiPackStateUpdateListener listener)
大規模なダウンロード

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

アプリがこのメソッドを呼び出さなかった場合、ダウンロードは一時停止され、ユーザーの Wi-Fi 接続が回復したときに限り、自動的に再開されます。

ユーザー確認が必要

パックのステータスが REQUIRES_USER_CONFIRMATION の場合、ユーザーが showConfirmationDialog() で表示されるダイアログを承認するまで、ダウンロードは開始されません。このステータスは、アプリが Play で認識されていない場合に発生することがあります(アプリがサイドローディングされた場合など)。この場合、showConfirmationDialog() を呼び出すとアプリが更新されます。更新後、AI パックを再度リクエストする必要があります。

リスナーの実装例を次に示します。

AiPackStateUpdateListener aiPackStateUpdateListener = new AiPackStateUpdateListener() {
    private final ActivityResultLauncher<IntentSenderRequest> activityResultLauncher =
      registerForActivityResult(
          new ActivityResultContracts.StartIntentSenderForResult(),
          new ActivityResultCallback<ActivityResult>() {
            @Override
            public void onActivityResult(ActivityResult result) {
              if (result.getResultCode() == RESULT_OK) {
                Log.d(TAG, "Confirmation dialog has been accepted.");
              } else if (result.getResultCode() == RESULT_CANCELED) {
                Log.d(TAG, "Confirmation dialog has been denied by the user.");
              }
            }
          });

    @Override
    public void onStateUpdate(AiPackState aiPackState) {
      switch (aiPackState.status()) {
        case AiPackStatus.PENDING:
          Log.i(TAG, "Pending");
          break;

        case AiPackStatus.DOWNLOADING:
          long downloaded = aiPackState.bytesDownloaded();
          long totalSize = aiPackState.totalBytesToDownload();
          double percent = 100.0 * downloaded / totalSize;

          Log.i(TAG, "PercentDone=" + String.format("%.2f", percent));
          break;

        case AiPackStatus.TRANSFERRING:
          // 100% downloaded and assets are being transferred.
          // Notify user to wait until transfer is complete.
          break;

        case AiPackStatus.COMPLETED:
          // AI pack is ready to use. Run the model.
          break;

        case AiPackStatus.FAILED:
          // Request failed. Notify user.
          Log.e(TAG, aiPackState.errorCode());
          break;

        case AiPackStatus.CANCELED:
          // Request canceled. Notify user.
          break;

        case AiPackStatus.WAITING_FOR_WIFI:
        case AiPackStatus.REQUIRES_USER_CONFIRMATION:
          if (!confirmationDialogShown) {
            aiPackManager.showConfirmationDialog(activityResultLauncher);
            confirmationDialogShown = true;
          }
          break;

        case AiPackStatus.NOT_INSTALLED:
          // AI pack is not downloaded yet.
          break;
        case AiPackStatus.UNKNOWN:
          Log.wtf(TAG, "AI pack status unknown")
          break;
      }
    }
}

または、getPackStates() メソッドを使用して、現在のダウンロードのステータスを取得できます。AiPackStates には、ダウンロードの進行状況、ダウンロードのステータス、失敗のエラーコードが含まれます。

AI パックへのアクセス

ダウンロード リクエストが COMPLETED 状態になったら、ファイル システム呼び出しを使用して AI パックにアクセスできます。AI パックのルートフォルダを取得するには、getPackLocation() メソッドを使用します。

AI パックは、AI パックのルート ディレクトリ内の assets ディレクトリに保存されます。assetsPath() コンビニエンス メソッドを使用して、assets ディレクトリへのパスを取得できます。特定のアセットへのパスを取得するには、次のメソッドを使用します。

private String getAbsoluteAiAssetPath(String aiPack, String relativeAiAssetPath) {
    AiPackLocation aiPackPath = aiPackManager.getPackLocation(aiPack);

    if (aiPackPath == null) {
        // AI pack is not ready
        return null;
    }

    String aiAssetsFolderPath = aiPackPath.assetsPath();
    // equivalent to: FilenameUtils.concat(aiPackPath.path(), "assets");
    String aiAssetPath = FilenameUtils.concat(aiAssetsFolderPath, relativeAiAssetPath);
    return aiAssetPath;
}

デバイス ターゲティングを設定する

デバイス ターゲティングの手順に沿って、AI パックを配信するデバイスまたはデバイス グループを指定します。

その他の Play AI Delivery API メソッド

ここでは、アプリで使用できるその他の API メソッドを紹介します。

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

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

AI パックを削除する

AI パックの削除をスケジュールするには、removePack() を使用します。

複数の AI パックの場所を取得する

複数の AI パックのステータスをまとめてクエリするには、AI パックとその場所のマップを返す getPackLocations() を使用します。getPackLocations() によって返されるマップのエントリは、現在ダウンロードされている最新のパックです。

デバイス ターゲティング

デバイス ターゲティングを使用すると、特定のデバイスに配信する App Bundle の部分をより細かく制御できます。たとえば、大規模なモデルを RAM 容量の大きいデバイスにのみ配信したり、モデルの異なるバージョンを異なるデバイスに配信したりできます。

ターゲットに設定できるデバイスのプロパティは次のとおりです。

  • システム オン チップ
  • デバイスのモデル
  • デバイス RAM
  • システム機能

必要な手順の概要

デバイス ターゲティングを有効にするには、次の手順が必要です。

  1. デバイス グループを XML ファイルで定義します。
  2. バンドルのどの部分をどのデバイス グループに送信するかを指定します。
  3. [省略可] 構成をローカルでテストします。
  4. バンドル(XML ファイルを含む)を Google Play にアップロードします。

Android Gradle プラグインのバージョンを確認する

デバイス ターゲティングを使用するには、Android Gradle プラグイン(AGP)のバージョンが 8.10.0-alpha01 以降であることを確認してください。これは、カナリア版の Android Studio Meerkat 2 にパッケージ化されています。

Android Gradle プラグインでこの機能を有効にする

デバイス ターゲティングは、gradle.properties ファイルで明示的に有効にする必要があります。

android.experimental.enableDeviceTargetingConfigApi=true

デバイス ターゲティング構成の XML ファイルを作成する

デバイス ターゲティング構成ファイルは、カスタム デバイス グループを定義する XML ファイルです。たとえば、Qualcomm SM8750 システム オン チップ搭載のすべてのデバイスを含む qti_v79 というデバイス グループを定義できます。

<config:device-targeting-config
    xmlns:config="http://schemas.android.com/apk/config">

    <config:device-group name="qti_v79">
        <config:device-selector>
            <config:system-on-chip manufacturer="QTI" model="SM8750"/>
        </config:device-selector>
    </config:device-group>

</config:device-targeting-config>

デバイス グループは、最大 5 つのデバイス セレクタで構成されます。デバイス グループに含まれるデバイスは、デバイス グループのデバイス セレクタのいずれかに一致するデバイスです。

デバイス セレクタには、1 つ以上のデバイス プロパティを設定できます。デバイスがセレクタのデバイス プロパティのすべてに一致する場合、そのデバイスが選択されます。

デバイスが複数のグループに一致する場合、XML ファイルで最初に定義されたグループのコンテンツが配信されます。XML ファイルでグループを定義する順序が優先順位の順序になります。

デバイスがどのグループにも一致しない場合、デフォルトの「other」グループが割り当てられます。このグループは自動的に生成されるため、明示的に定義する必要はありません。

使用可能なデバイスのプロパティ

  • device_ram: デバイスの RAM の要件
    • min_bytes(包含的): 必要な最小 RAM(バイト単位)。
    • max_bytes(排他的): 必要な最大 RAM(バイト単位)。
  • included_device_ids: このセレクタに含めるデバイスモデル(グループあたり最大 10,000 個の device_ids)。このプロパティは、デバイスがリスト内のいずれかの device_id と一致する場合に満たされます。
    • build_brand: デバイスのメーカー
    • build_device: デバイスのモデルコード
  • excluded_device_ids: このセレクタで除外するデバイスモデル(グループあたり最大 10,000 個の device_ids)。このプロパティは、デバイスがリスト内のどの device_id とも一致しない場合、満たされます。
    • build_brand: デバイスのメーカー
    • build_device: デバイスのモデルコード
  • required_system_features: デバイスがこのセレクタに含まれるために搭載している必要がある機能(グループあたり最大 100 個の機能)。このプロパティを満たすには、デバイスがこのリストにあるすべてのシステム機能を搭載している必要があります。

    システム機能リファレンス

    • name: システム機能
  • forbidden_system_features: このセレクタに含まれるために、デバイスが搭載してはいけない機能(グループあたり最大 100 個の機能)。デバイスがこのリスト内にあるシステム機能を搭載している場合、このプロパティを満たしていません。

    システム機能リファレンス

    • name: システム機能
  • system-on-chip: このセレクタに含めるシステム オン チップ。このプロパティを満たすには、デバイスにこのリストのいずれかのチップが搭載されている必要があります。

以下に、考えられるすべてのデバイス プロパティを示します。

<config:device-targeting-config
    xmlns:config="http://schemas.android.com/apk/config">

    <config:device-group name="myCustomGroup1">
      <config:device-selector ram-min-bytes="8000000000">
        <config:included-device-id brand="google" device="redfin"/>
        <config:included-device-id brand="google" device="sailfish"/>
        <config:included-device-id brand="good-brand"/>
        <config:excluded-device-id brand="google" device="caiman"/>
        <config:system-on-chip manufacturer="Sinclair" model="ZX80"/>
        <config:system-on-chip manufacturer="Commodore" model="C64"/>
      </config:device-selector>
      <config:device-selector ram-min-bytes="16000000000"/>
    </config:device-group>

    <config:device-group name="myCustomGroup2">
      <config:device-selector ram-min-bytes="4000000000" ram-max-bytes="8000000000">
        <config:required-system-feature name="android.hardware.bluetooth"/>
        <config:required-system-feature name="android.hardware.location"/>
        <config:forbidden-system-feature name="android.hardware.camera"/>
        <config:forbidden-system-feature name="mindcontrol.laser"/>
      </config:device-selector>
    </config:device-group>

</config:device-targeting-config>

デバイスのメーカーとデバイスモデルの公式コード

デバイスのメーカーとモデルコードの正しい形式を見つけるには、Google Play Console のデバイス カタログを使用して、次のいずれかを行います。

  • 下記の例のように、デバイス カタログを使用して個々のデバイスを調べ、メーカーとモデルコードを見つけます(Google Pixel 4a の場合、メーカーは「Google」、モデルコードは「sunfish」となります)。

    デバイス カタログの Pixel 4a のページ

    デバイス カタログの Pixel 4a のページ

  • サポートされているデバイスの CSV をダウンロードし、build_brandbuild_device にそれぞれメーカーとモデルコードを使用します。

デバイス ターゲティング構成ファイルをアプリバンドルに含める

メイン モジュールの build.gradle ファイルに次の行を追加します。

android {
  ...
  bundle {
    deviceTargetingConfig = file('device_targeting_config.xml')
    deviceGroup {
      enableSplit = true   // split bundle by #group
      defaultGroup = "other"  // group used for standalone APKs
    }
  }
  ...
}

device_targeting_config.xml は、メイン モジュールを基準とした構成ファイルのパスです。これにより、構成ファイルがアプリバンドルにパッケージ化されます。

deviceGroup 句により、Bundle から生成された APK がデバイス グループごとに分割されます。

AI パックでデバイス ターゲティングを使用する

サイズを最適化したままデバイスに配信するには、大規模なモデルを実行できるデバイスにのみ配信します。

前の手順で作成した既存の AI パック ディレクトリを取得し、適切なフォルダに(後述のように)#group_myCustomGroup1、#group_myCustomGroup2 などの接尾辞を追加して、デバイス グループごとに AI パックを分割します。アプリで AI パックを使用する場合は、接尾辞でフォルダを参照する必要はありません(つまり、接尾辞はビルドプロセス中に自動的に削除されます)。

前のステップを実施すると、次のようになります。

...
.../ai-pack-name/src/main/assets/image-classifier#group_myCustomGroup1/
.../ai-pack-name/src/main/assets/image-classifier#group_myCustomGroup2/
...

この例では、接尾辞なしで ai-pack-name/assets/image-classifier/ を参照します。

myCustomGroup1 のデバイスは image-classifier#group_myCustomGroup1/ のすべてのアセットを受信し、myCustomGroup2 のデバイスは image-classifier#group_myCustomGroup2/ のすべてのアセットを受信します。

myCustomGroup1 または myCustomGroup2 に属していないデバイスには、空の ai-pack-name パッケージが送信されます。

これは、どのデバイス グループにも一致しないデバイスには、AI パックのデフォルト バリアントが表示されるためです。これには、#group_suffix を含むディレクトリにないすべてのものが含まれます。

AI パックをダウンロードしたら、インストール時パックの場合は AssetManager、高速フォロー パックとオンデマンド パックの場合は AiPackManager を使用して、モデルが存在するかどうかを確認できます。サンプルアプリでは、すべての配信モードでこの方法の例を示しています。

機能モジュールでデバイス ターゲティングを使用する

機能モジュールにはデバイス ターゲティングを使用することもできます。機能モジュールをデバイス グループごとに細分化するのではなく、デバイス グループ メンバーシップに基づいてモジュール全体を配信するかどうかを指定します。

myCustomGroup1 または myCustomGroup2 に属するデバイスに機能モジュールを配信するには、その AndroidManifest.xml を変更します。

<manifest ...>
  ...
  <dist:module dist:title="...">
    <dist:delivery>
      <dist:install-time>
        <dist:conditions>
          <dist:device-groups>
            <dist:device-group dist:name="myCustomGroup1"/>
            <dist:device-group dist:name="myCustomGroup2"/>
          </dist:device-groups>
          ...
        </dist:conditions>
      </dist:install-time>
    </dist:delivery>
  </dist:module>
  ...
</manifest>

ローカルでテストする

新しいバンドルのリリースを作成する前に、内部アプリ共有または Bundletool を使用してローカルでテストできます。

内部アプリ共有

内部アプリ共有を使用すると、App Bundle を使用して URL をすばやく生成できます。この URL をローカル デバイスでタップすると、そのバージョンのアプリがテストトラックまたは製品トラックで公開されている場合、Google Play がそのデバイスにインストールする内容を正確にインストールできます。

内部アプリ共有の手順をご覧ください。

bundletool

または、bundletool(1.18.0 以降)を使用して APK を生成し、デバイスにサイドロードすることもできます。bundletool を使用してローカルでアプリをテストする手順は次のとおりです。

  1. Android Studio または bundletool を使用して App Bundle をビルドします。

  2. --local-testing フラグを使用して APK を生成します。

    java -jar bundletool-all.jar build-apks --bundle=path/to/your/bundle.aab \
      --output=output.apks --local-testing
    
  3. デバイスを接続し、bundletool を実行して APK をサイドローディングします。

    # Example without Device Targeting Configuration
    java -jar bundletool.jar install-apks --apks=output.apks
    
    # Example with Device Targeting Configuration (you must specify which groups the connected device belongs to)
    java -jar bundletool.jar install-apks --apks=output.apks --device-groups=myCustomGroup1,myCustomGroup2
    

bundletool を使用したローカルテストの制限事項

bundletool を使用したローカルテストには次の制限があります。

  • fast-follow パックは、on-demand パックのように動作します。つまり、アプリがサイドローディングされたときに自動的に取得されることはありません。デベロッパーがアプリの開始時に手動でリクエストする必要があります。アプリのコードを変更する必要はありません。
  • パックは Play ではなく外部ストレージから取得するため、ネットワーク エラーの場合のコードの動作はテストできません。
  • Wi-Fi 接続を待つシナリオはローカルテストの対象外です。
  • アップデートはサポートされません。新しいバージョンのビルドをインストールする前に、前のバージョンを手動でアンインストールしてください。

正しい APK がインストールされていることを確認する

正しい APK のみがデバイスにインストールされるようにするには、次のメソッドを使用します。

adb shell pm path {packageName}

次のような出力が表示されます。

package:{...}/base.apk
package:{...}/split_config.en.apk
package:{...}/split_config.xxhdpi.apk
package:{...}/split_main_ai-pack-name.apk
package:{...}/split_main_ai-pack-name.config.group_myCustomGroup1.apk

このリストには、機能モジュールとインストール時の AI パックから作成された APK のみが表示されます。オンデマンド AI パックと fast-follow AI パックは APK としてインストールされません。

Google Play でのテストとリリース

内部テストトラックを使用して、Google Play でアプリのエンドツーエンド テストを行うことをおすすめします。

その後、段階的な公開を使用して、アプリのアップデートを段階的に本番環境にリリースできます。

オンデバイス AI のための Google Play を使用するサンプルアプリ

サンプルアプリにアクセスするには、Google Play パートナー マネージャーにお問い合わせください。

各配信モードとデバイス ターゲティングの設定方法について説明します。始めるにあたっては、ローカル テストのセクションをご覧ください。

フィードバックを送信

早期アクセス プログラムの参加者は、問題の報告やフィードバックの提供を行う必要があります。Google Play パートナー マネージャーまたは Play for On-device AI チームにお問い合わせください。

詳しくは、Android App Bundle の詳細と AI Delivery SDK のリファレンスをご覧ください。