Google Play에서 온디바이스 AI 사전 체험 프로그램 (EAP)

소개

온디바이스 AI용 Play는 Android App Bundle 및 Google Play 전송의 이점을 맞춤 ML 모델 배포에 제공하므로 추가 비용 없이 생태계 복잡성을 줄여 모델 성능을 개선할 수 있습니다. 이를 통해 코드, 애셋, ML 모델이 포함된 단일 아티팩트를 Play에 게시하고 여러 전송 모드와 타겟팅 옵션 중에서 선택할 수 있습니다.

이점

  • 단일 게시 아티팩트를 Google Play에 업로드하고 추가 비용 없이 호스팅, 전송, 업데이트, 타겟팅을 Play에 위임하세요.
  • 설치 시, 빠른 추적 또는 주문형으로 ML 모델을 배포합니다.
    • 설치 시간 전송을 사용하면 앱이 열릴 때 매우 큰 모델이 있는지 확인할 수 있습니다. 모델이 APK로 설치됩니다.
    • 빠른 추적 전송은 앱이 설치된 후 백그라운드에서 자동으로 실행됩니다. 모델이 완전히 다운로드되기 전에 사용자가 앱을 열 수 있습니다. 모델이 앱의 내부 저장공간에 다운로드됩니다.
    • 주문형 전송을 사용하면 런타임에 모델을 요청할 수 있습니다. 이는 특정 사용자 흐름에만 모델이 필요한 경우에 유용합니다. 모델이 앱의 내부 저장소 공간에 다운로드됩니다.
  • 기기 모델, 시스템 속성 또는 RAM을 기반으로 특정 기기를 타겟팅하는 ML 모델의 변형을 제공합니다.
  • Play의 자동 패치를 사용하여 앱 업데이트를 작고 최적화된 상태로 유지합니다. 즉, 파일의 차이점만 다운로드하면 됩니다.

고려사항

  • 기기 내 AI용 Play를 사용하면 Google Play 개발자 배포 계약Play Core 소프트웨어 개발 키트 서비스 약관의 약관에 동의하는 것으로 간주됩니다.
  • 사전 체험 프로그램에 참여하는 개발자는 기기 내 AI용 Play를 평가하고 Google Play에 의견을 제공해야 합니다.
  • 기기 내 AI용 Play에서 다운로드한 모델은 모델을 다운로드한 앱에서만 사용할 수 있습니다. 모델은 서비스 연결을 통해 다른 앱에 제공되어서는 안 됩니다.
  • 개별 AI 팩은 압축된 다운로드 크기에 따라 최대 1.5GB까지 가능합니다. App Bundle에서 생성된 앱 버전의 최대 누적 앱 크기는 4GB입니다.
  • 크기가 1GB를 초과하는 앱은 최소 SDK 수준을 21 이상으로 설정해야 합니다.
  • 사전 체험 프로그램 중에는 기기 내 AI용 Play가 변경될 수 있습니다.

온디바이스 AI용 Play 사용 방법

온디바이스 AI용 Play는 AI 팩을 사용합니다. 앱 번들의 AI 팩에 배포할 준비가 된 맞춤 모델을 패키징합니다. AI 팩을 설치 시, 빠른 추적 시 또는 주문형으로 전송할지 선택할 수 있습니다.

앱 번들과 함께 AI 팩을 패키징하면 테스트 트랙, 단계적 출시와 같은 Play의 기존 테스트 및 출시 도구를 모두 사용하여 맞춤 모델로 앱의 배포를 관리할 수 있습니다.

AI 팩은 앱 바이너리와 함께 업데이트됩니다. 새 앱 버전에서 AI 팩을 변경하지 않으면 Play의 자동 패치 프로세스를 통해 사용자가 AI 팩을 다시 다운로드하지 않아도 됩니다. Play에서는 앱을 업데이트할 때 변경된 사항만 다운로드합니다.

AI 팩에는 모델만 포함됩니다. Java/Kotlin 및 네이티브 라이브러리는 허용되지 않습니다. ML 모델을 실행하기 위해 라이브러리 또는 코드를 제공해야 하는 경우 기본 모듈 또는 기능 모듈로 옮깁니다. AI 팩과 동일한 다운로드 및 타겟팅 설정을 갖도록 기능 모듈을 구성할 수 있습니다.

AI 팩으로 LiteRT 및 MediaPipe 사용

AI 팩과 함께 LiteRT 및 MediaPipe를 사용할 수 있습니다. AI 팩에 모델을 패키징한 다음 설치 시 패키지 또는 빠른 추적 및 주문형 패키지의 안내에 따라 액세스합니다.

추가 자료:

AI 팩 시작하기

온디바이스 AI용 Play를 사용하기 시작하는 방법은 대략 다음과 같습니다.

  1. EAP에 참여하려면 Google Play에 Play 개발자 계정 ID를 제공하세요.
  2. Android App Bundle에 모델을 AI 팩으로 패키징하고 AI 팩을 전송하는 방법을 지정합니다.
  3. [선택사항] 기기마다 다른 모델을 제공하려면 AI 팩에 기기 타겟팅을 구성하면 됩니다. 예를 들어 특정 기기 모델에는 AI 팩 A를, RAM이 6GB 이상인 기기에는 AI 팩 B를 전송하고 다른 모든 기기에는 모델을 전송하지 않을 수 있습니다.
  4. [선택사항] 주문형 또는 빠른 추적 전송을 사용하는 경우 Play AI Delivery Library를 앱에 통합하여 필요에 따라 AI 팩을 다운로드합니다.
  5. App Bundle을 테스트하고 Google Play에 출시합니다.

Play 개발자 계정 ID 제공

이 기능은 사전 체험판이므로 기기 내 AI용 Play에 액세스하려면 개발자 계정이 허용 목록에 있어야 합니다. Google Play 파트너 관리자 또는 기기 내 AI팀의 Play 담당자에게 Play 개발자 계정 ID 및 앱 패키지 이름을 확인합니다. 특정 기기에 모델을 타겟팅할지 지정합니다 (이전 섹션의 3단계). 현재 일부 Play 파트너를 대상으로 이 기능을 테스트하고 있습니다.

Android Gradle 플러그인 버전 확인

AI 팩을 사용하려면 Android Gradle 플러그인 (AGP) 버전이 8.8 이상인지 확인하세요. 이 버전은 Android 스튜디오 Ladybug 2와 함께 패키징됩니다.

모델을 AI 팩으로 추출

다음 단계에는 Android 스튜디오가 필요하지 않습니다.

  1. 프로젝트의 최상위 디렉터리에 AI 팩용 디렉터리를 만듭니다. 이 디렉터리 이름은 AI 팩 이름으로 사용됩니다. AI 팩 이름은 문자로 시작해야 하며 문자, 숫자, 밑줄만 포함할 수 있습니다.
  2. AI 팩 디렉터리에서 build.gradle 파일을 만들고 다음 코드를 추가합니다. AI 팩 이름과 하나의 전송 유형만 지정해야 합니다.

    // 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 팩의 식별자 및 전송 모드를 구성합니다.
    • 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");

빠른 추적 및 주문형 전송 구성

빠른 추적 또는 주문형 제공으로 AI 팩을 다운로드하려면 Play AI Delivery Library를 사용하세요.

Play AI Delivery 라이브러리에 대한 종속 항목 선언

앱의 build.gradle 파일에서 Play AI 전송 라이브러리의 종속 항목을 선언합니다.

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

상태 확인

각 AI 팩은 앱의 내부 저장소에 있는 별도의 폴더에 저장됩니다. getPackLocation() 메서드를 사용하여 AI 팩의 루트 폴더를 확인합니다. 이 메서드는 다음 값을 반환합니다.

반환 값 상태
유효한 AiPackLocation 객체 AI 팩 루트 폴더는 assetsPath()에서 즉시 액세스할 수 있도록 준비되어 있습니다.
null 알 수 없는 AI 팩 또는 AI 팩을 사용할 수 없음

AI 팩 다운로드 정보 확인


getPackStates() 메서드를 사용하여 다운로드 크기와 팩이 이미 다운로드 중인지 여부를 확인할 수 있습니다.

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

getPackStates()Task<AiPackStates>를 반환하는 비동기 메서드입니다. AiPackStates 객체의 packStates() 메서드는 Map<String, AiPackState>를 반환합니다. 다음과 같이 이 맵에는 요청된 각 AI 팩의 상태가 포함되며 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입니다.

요청이 실패하면 반환 값이 AiPackErrorCode 클래스의 상수 필드에 상응하는 errorCode() 메서드를 사용해야 합니다.

설치

다음과 같이 fetch() 메서드를 사용하여 AI 팩을 처음 다운로드하거나 AI 팩 업데이트를 호출하여 완료할 수 있습니다.

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

이 메서드는 팩 목록과 최초 다운로드 상태 및 크기가 포함된 AiPackStates 객체를 반환합니다. fetch()를 통해 요청된 AI 팩을 이미 다운로드 중이면 다운로드 상태가 반환되고 추가 다운로드가 시작되지 않습니다.

다운로드 상태 모니터링

AI 팩의 설치 진행률을 추적하려면 AiPackStateUpdateListener를 구현해야 합니다. 상태 업데이트는 팩별로 분류되어 개별 AI 팩의 상태 추적을 지원합니다. 요청과 관련된 다른 모든 다운로드가 완료되기 전에 사용 가능한 AI 팩을 사용할 수 있습니다.

void registerListener(AiPackStateUpdateListener listener)
void unregisterListener(AiPackStateUpdateListener listener)
대용량 다운로드

다운로드 용량이 200MB보다 크고 사용자가 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 팩에 액세스할 수 있습니다. getPackLocation() 메서드를 사용하여 AI 팩의 루트 폴더를 가져옵니다.

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 메서드입니다.

요청 취소

cancel()를 사용하여 활성 상태의 AI 팩 요청을 취소할 수 있습니다. 이 요청이 최선의 작업입니다.

AI 팩 삭제

removePack()을 사용하여 AI 팩 삭제를 예약합니다.

여러 AI 팩의 위치 가져오기

getPackLocations()를 사용하여 여러 AI 팩의 상태를 일괄적으로 쿼리하면 AI 팩 및 그 위치 맵이 반환됩니다. getPackLocations()에서 반환한 맵에는 현재 다운로드되고 최신 상태인 각 팩의 항목이 포함되어 있습니다.

기기 타겟팅

기기 타겟팅을 사용하면 특정 기기에 전송되는 App Bundle의 부분을 더 세부적으로 제어할 수 있습니다. 예를 들어 대용량 모델을 RAM이 많은 기기에만 전송하거나 기기에 따라 모델의 다른 버전을 전송할 수 있습니다.

다음과 같은 기기 속성을 타겟팅할 수 있습니다.

필수 단계 개요

기기 타겟팅을 사용 설정하려면 다음 단계를 따르세요.

  1. XML 파일에서 기기 그룹을 정의합니다.
  2. 번들의 어떤 부분이 어떤 기기 그룹으로 이동해야 하는지 지정합니다.
  3. [선택사항] 로컬에서 구성을 테스트합니다.
  4. XML 파일이 포함된 번들을 Google Play에 업로드합니다.

Android Gradle 플러그인 버전 확인

기기 타겟팅을 사용하려면 Android Gradle 플러그인 (AGP) 버전이 8.10.0-alpha01 이상인지 확인하세요. 이는 canary의 Android 스튜디오 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개의 기기 선택기로 구성됩니다. 기기가 기기 선택기 중 하나를 충족하는 경우 기기 그룹에 포함됩니다.

기기 선택기에는 하나 이상의 기기 속성이 있을 수 있습니다. 기기가 선택기의 모든 기기 속성과 일치하면 선택됩니다.

기기가 여러 그룹과 일치하는 경우 XML 파일에서 먼저 정의된 그룹의 콘텐츠가 제공됩니다. XML 파일에서 그룹을 정의하는 순서가 우선순위 순서입니다.

기기가 어떤 그룹과도 일치하지 않으면 기본 '기타' 그룹이 수신됩니다. 이 그룹은 자동으로 생성되며 명시적으로 정의해서는 안 됩니다.

사용 가능한 기기 속성

  • device_ram: 기기 RAM 요구사항
    • min_bytes (양 끝값 포함): 필요한 최소 RAM (바이트)
    • max_bytes (제외): 필요한 최대 RAM (바이트)
  • included_device_ids: 이 선택기에 포함할 기기 모델(그룹당 최대 1만 개 device_ids). 기기가 목록의 device_id와 일치하면 이 속성이 충족됩니다.
    • build_brand: 기기 제조업체
    • build_device: 기기 모델 코드
  • excluded_device_ids: 이 선택기에서 제외할 기기 모델(그룹당 최대 1만 개 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_brand 필드와 build_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 절은 번들에서 생성된 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을 사용하여 로컬 기기에서 탭하여 Google Play가 해당 기기에 설치할 항목을 정확하게 설치할 수 있는 URL을 빠르게 생성할 수 있습니다. 이 URL은 해당 앱 버전이 테스트 또는 프로덕션 트랙에 게시된 경우에도 사용할 수 있습니다.

내부 앱 공유 안내를 참고하세요.

bundletool

또는 bundletool (1.18.0 이상)를 사용하여 APK를 생성하고 기기에 사이드로드할 수 있습니다. bundletool을 사용하여 로컬에서 앱을 테스트하려면 다음 단계를 따르세요.

  1. Android 스튜디오 또는 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 팩으로 동작합니다. 즉, 앱이 사이드로드될 때 자동으로 가져오지는 않습니다. 개발자는 앱이 시작될 때 수동으로 fast-follow 팩을 요청해야 합니다. 이를 위해 앱에서 코드를 변경할 필요는 없습니다.
  • 팩은 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 팩은 APK로 설치되지 않습니다.

Google Play에서 테스트 및 출시

내부 테스트 트랙을 사용하여 Google Play에서 앱을 엔드 투 엔드로 테스트하는 것이 좋습니다.

이 작업이 완료되면 단계적 출시를 사용하여 앱 업데이트를 프로덕션으로 점진적으로 출시할 수 있습니다.

온디바이스 AI용 Play를 사용하는 샘플 앱

Google Play 파트너 관리자에게 문의하여 샘플 앱에 액세스하세요.

각 게재 모드와 기기 타겟팅 구성을 사용하는 방법을 보여줍니다. 시작하려면 로컬 테스트 섹션을 참고하세요.

의견 보내기

사전 체험 프로그램 참여자는 문제를 신고하고 의견을 제공해야 합니다. Google Play 파트너 관리자에게 문의하거나 기기 내 AI용 Play팀에 문의할 수 있습니다.

Android App Bundle에 관해 자세히 알아보고 AI Delivery SDK 참조를 읽어보세요.