미디어 앱에 Android Automotive OS 지원 추가

Android Automotive OS를 통해 사용자는 자동차에 앱을 설치할 수 있습니다. 이 플랫폼의 사용자에게 다가가려면 Android Automotive OS와 호환되며 운전자에 최적화된 앱을 배포해야 합니다. Android Auto 앱의 거의 모든 코드와 리소스를 재사용할 수 있지만, 이 페이지의 요구사항을 충족하는 별도의 빌드를 만들어야 합니다.

개발 개요

Android Automotive OS 지원을 추가하려면 다음 섹션에 설명된 대로 몇 단계만 거치면 됩니다.

  1. Android 스튜디오에서 자동차 기능 사용 설정
  2. 자동차 모듈 만들기
  3. Gradle 종속 항목 업데이트
  4. 설정 및 로그인 활동 구현(선택사항)
  5. 미디어 호스트 힌트 읽기(선택사항)

설계 고려사항

Android Automotive OS는 앱의 미디어 브라우저 서비스에서 수신한 미디어 콘텐츠를 배치합니다. 즉, 사용자가 미디어 재생을 트리거할 때 앱에서 UI를 그리지 않고 활동을 시작하지 않습니다.

설정 또는 로그인 활동을 구현하고 있다면 이러한 활동은 차량에 최적화되어야 합니다. 앱의 이러한 영역을 디자인하면서 Android Automotive OS용 디자인 가이드라인을 참고하세요.

프로젝트 설정

Android Automotive OS 지원을 사용하려면 앱 프로젝트의 여러 부분을 설정해야 합니다.

Android 스튜디오에서 자동차 기능 사용 설정

Android 스튜디오 4.0 이상을 사용하여 모든 Automotive OS 기능이 사용 설정되어 있는지 확인합니다.

자동차 모듈 만들기

매니페스트와 같은 Android Automotive OS의 일부 구성요소에는 플랫폼별 요구사항이 있습니다. 이러한 구성요소의 코드를 프로젝트의 다른 코드(예: 휴대전화 앱에 사용된 코드)와 별도로 유지할 수 있는 모듈을 만드세요.

프로젝트에 자동차 모듈을 추가하려면 다음 단계를 따르세요.

  1. Android 스튜디오에서 File > New > New Module을 클릭합니다.
  2. Automotive Module을 선택하고 Next를 클릭합니다.
  3. Application/Library name을 입력합니다. 이것은 Android Automotive OS에서 사용자에게 표시되는 앱의 이름입니다.
  4. Module name을 입력합니다.
  5. Package name이 앱과 일치하도록 조정합니다.
  6. Minimum SDK에서 API 28: Android 9.0 (Pie)을 선택하고 Next를 클릭합니다.

    Android Automotive OS를 지원하는 모든 자동차는 Android 9(API 수준 28) 이상에서 실행되므로 이 값을 선택하면 호환되는 모든 자동차가 타겟팅됩니다.

  7. No Activity를 선택하고 Finish를 클릭합니다.

Android 스튜디오에서 모듈을 만든 후 새 자동차 모듈에서 AndroidManifest.xml을 엽니다.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.media">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" />

    <uses-feature
        android:name="android.hardware.type.automotive"
        android:required="true" />

</manifest>

application 요소에는 일부 표준 앱 정보와 Android Automotive OS 지원을 선언하는 uses-feature 요소가 있습니다. 매니페스트에 선언된 활동은 없습니다.

설정 또는 로그인 활동을 구현한다면 여기에 추가합니다. 이러한 활동은 명시적 인텐트를 사용하여 시스템에서 트리거하며 Android Automotive OS 앱의 매니페스트 내에서 선언하는 유일한 활동입니다.

설정 또는 로그인 활동을 추가한 후 application 요소에서 android:appCategory="audio" 속성을 설정하고 다음 uses-feature 요소를 추가하여 매니페스트 파일을 완성합니다.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.media">

    <application
        android:allowBackup="true"
        android:appCategory="audio"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" />

    <uses-feature
        android:name="android.hardware.type.automotive"
        android:required="true" />

    <uses-feature
        android:name="android.hardware.wifi"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.screen.portrait"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.screen.landscape"
        android:required="false" />

</manifest>

이러한 기능을 required="false"로 명시적으로 설정하면 앱이 Automotive OS 기기에서 사용할 수 있는 하드웨어 기능과 충돌하지 않습니다.

Android Automotive OS 미디어 지원 선언

다음 매니페스트 항목을 사용하여 앱에서 Android Automotive OS를 지원한다고 선언합니다.

<application>
    ...
    <meta-data android:name="com.android.automotive"
        android:resource="@xml/automotive_app_desc"/>
    ...
</application>

이 매니페스트 항목은 앱에서 지원하는 자동차 기능을 선언하는 XML 파일을 참조합니다.

미디어 앱이 있음을 나타내려면 automotive_app_desc.xml이라는 XML 파일을 프로젝트의 res/xml/ 디렉터리에 추가합니다. 이 파일에 다음 콘텐츠를 포함합니다.

<automotiveApp>
    <uses name="media"/>
</automotiveApp>

인텐트 필터

Android Automotive OS는 명시적 인텐트를 사용하여 미디어 앱에서 활동을 트리거합니다. CATEGORY_LAUNCHER 또는 ACTION_MAIN 인텐트 필터가 있는 활동은 매니페스트 파일에 포함하지 마세요.

다음 예와 같은 활동은 일반적으로 휴대전화 또는 다른 일부 휴대기기를 타겟팅합니다. 이러한 활동은 Android Automotive OS 앱을 빌드하는 모듈이 아니라 휴대전화 앱을 빌드하는 모듈에서 선언합니다.

<activity android:name=".MyActivity">
    <intent-filter>
        <!-- You can't use either of these intents for Android Automotive OS -->
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <!--
        In their place, you can include other intent filters for any activities
        that your app needs for Android Automotive OS, such as settings or
        sign-in activities.
        -->
    </intent-filter>
</activity>

Gradle 종속 항목 업데이트

휴대전화 앱과 자동차 모듈 간에 공유하는 별도의 모듈에 미디어 브라우저 서비스를 유지하는 것이 좋습니다. 이 방법을 사용한다면 다음 스니펫에 표시된 대로 자동차 모듈을 업데이트하여 공유 모듈을 포함해야 합니다.

my-auto-module/build.gradle

Groovy

buildscript {
    ...
    dependencies {
        ...
        implementation project(':shared_module_name')
    }
}

Kotlin

buildscript {
    ...
    dependencies {
        ...
        implementation(project(":shared_module_name"))
    }
}

설정 및 로그인 활동 구현

미디어 브라우저 서비스 외에도 Android Automotive OS 앱에 차량에 최적화된 설정 및 로그인 활동을 제공할 수 있습니다. 이러한 활동을 통해 Android Media API에 포함되지 않은 앱 기능을 제공할 수 있습니다.

Android Automotive OS 앱에서 사용자가 로그인하거나 앱 설정을 지정하도록 해야 하는 경우에만 이러한 활동을 구현합니다. Android Auto에서는 이 활동을 사용하지 않습니다.

활동 워크플로

다음 다이어그램은 사용자가 Android Automotive OS를 사용하여 설정 및 로그인 활동과 상호작용하는 방법을 보여줍니다.

설정 및 로그인 활동 워크플로

그림 1. 설정 및 로그인 활동 워크플로

설정 및 로그인 활동에 집중하기

사용자의 차량이 주차된 동안에만 설정 또는 로그인 활동을 사용할 수 있도록 하려면 <activity> 요소에 다음 <meta-data> 요소가 포함되어 있지 않은지 확인합니다. 이러한 요소가 있으면 검토 중에 앱이 거부됩니다.

<!-- NOT ALLOWED -->
<meta-data
  android:name="distractionOptimized"
  android:value="true"/>

설정 활동 추가

사용자가 자동차에서 앱의 설정을 구성할 수 있도록 차량에 최적화된 설정 활동을 추가할 수 있습니다. 설정 활동에서는 사용자 계정 로그인 또는 로그아웃, 사용자 계정 전환과 같은 다른 워크플로를 제공할 수도 있습니다. 이 활동은 Android Automotive OS에서 실행되는 앱에서만 트리거한다는 점에 유의하세요. Android Auto에 연결된 휴대전화 앱은 이 활동을 사용하지 않습니다.

설정 활동 선언

다음 코드 스니펫에 표시된 대로 앱의 매니페스트 파일에서 설정 활동을 선언해야 합니다.

<application>
    ...
    <activity android:name=".AppSettingsActivity"
              android:exported="true"
              android:theme="@style/SettingsActivity"
              android:label="@string/app_settings_activity_title">
        <intent-filter>
            <action android:name="android.intent.action.APPLICATION_PREFERENCES"/>
        </intent-filter>
    </activity>
    ...
</application>

설정 활동 구현

사용자가 앱을 실행하면 Android Automotive OS는 선언된 설정 활동을 감지하고 아이콘과 같은 어포던스를 표시합니다. 사용자는 자동차의 디스플레이에서 이 어포던스를 탭하거나 선택하여 활동으로 이동할 수 있습니다. Android Automotive OS에서는 설정 활동을 시작하도록 앱에 지시하는 ACTION_APPLICATION_PREFERENCES 인텐트를 전송합니다.

이 섹션의 나머지 부분에서는 범용 Android 뮤직 플레이어(UAMP) 샘플 앱에서 코드를 조정하여 앱의 설정 활동을 구현하는 방법을 보여줍니다.

시작하려면 샘플 코드를 다운로드합니다.

# Clone the UAMP repository
git clone https://github.com/android/uamp.git

# Fetch the appropriate pull request to your local repository
git fetch origin pull/323/head:NEW_LOCAL_BRANCH_NAME

# Switch to the new branch
git checkout NEW_LOCAL_BRANCH_NAME

활동을 구현하려면 다음 단계를 따르세요.

  1. automotive/automotive-lib 폴더를 자동차 모듈에 복사합니다.
  2. automotive/src/main/res/xml/preferences.xml에서처럼 환경설정 트리를 정의합니다.
  3. 설정 활동이 표시하는 PreferenceFragmentCompat를 구현합니다. 자세한 내용은 UAMP의 SettingsFragment.ktSettingsActivity.kt 파일과 Android 설정 가이드를 참고하세요.

설정 활동을 구현할 때 환경설정 라이브러리의 일부 구성요소 사용에 관한 다음 권장사항을 고려하세요.

  • 설정 활동의 기본 뷰 아래에 두 수준 이상의 깊이를 두지 않도록 합니다.
  • DropDownPreference를 사용하지 않습니다. 대신 ListPreference를 사용하세요.
  • 조직 구성요소는 다음과 같습니다.
    • PreferenceScreen
      • 환경설정 트리의 최상위 레벨이어야 합니다.
    • PreferenceCategory
      • Preference 객체를 그룹화하는 데 사용됩니다.
      • title을 포함합니다.
  • 다음 모든 구성요소에 keytitle을 포함합니다. summary, icon 또는 둘 다를 포함할 수도 있습니다.
    • Preference
      • PreferenceFragmentCompat 구현의 onPreferenceTreeClick() 콜백에서 로직을 맞춤설정합니다.
    • CheckBoxPreference
      • 조건부 텍스트의 경우 summary 대신 summaryOn 또는 summaryOff를 사용할 수 있습니다.
    • SwitchPreference
      • 조건부 텍스트의 경우 summary 대신 summaryOn 또는 summaryOff를 사용할 수 있습니다.
      • switchTextOn 또는 switchTextOff를 보유할 수 있습니다.
    • SeekBarPreference
      • min, max, defaultValue를 포함합니다.
    • EditTextPreference
      • dialogTitle, positiveButtonText, negativeButtonText를 포함합니다.
      • dialogMessage 또는 dialogLayoutResource를 보유할 수 있습니다.
    • com.example.android.uamp.automotive.lib.ListPreference
      • 대부분 ListPreference에서 파생됩니다.
      • Preference 객체의 단일 선택 목록을 표시하는 데 사용됩니다.
      • entries 배열과 상응하는 entryValues가 있어야 합니다.
    • com.example.android.uamp.automotive.lib.MultiSelectListPreference
      • 대부분 MultiSelectListPreference에서 파생됩니다.
      • Preference 객체의 다중 선택 목록을 표시하는 데 사용됩니다.
      • entries 배열과 상응하는 entryValues가 있어야 합니다.

로그인 활동 추가

사용자가 로그인해야 사용할 수 있는 앱이라면 앱의 로그인과 로그아웃을 처리할 수 있도록 차량에 최적화된 로그인 활동을 추가할 수 있습니다. 설정 활동에 로그인과 로그아웃 워크플로를 추가할 수도 있지만, 사용자가 로그인할 때까지 앱을 사용할 수 없다면 전용 로그인 활동을 사용합니다. 이 활동은 Android Automotive OS에서 실행되는 앱에서만 트리거한다는 점에 유의하세요. Android Auto에 연결된 스마트폰 앱은 이 활동을 사용하지 않습니다.

앱 시작 시 로그인 요구

사용자가 로그인해야 앱을 사용할 수 있게 하려면 미디어 브라우저 서비스에서 다음을 실행해야 합니다.

  1. 서비스의 onLoadChildren() 메서드에서 sendResult() 메서드를 사용하여 null 결과를 전송합니다.
  2. setState() 메서드를 사용하여 미디어 세션의 PlaybackStateCompatSTATE_ERROR로 설정합니다. 이는 오류가 해결될 때까지 다른 작업을 할 수 없다고 Android Automotive OS에 알리는 것입니다.
  3. 미디어 세션의 PlaybackStateCompat 오류 코드를 ERROR_CODE_AUTHENTICATION_EXPIRED로 설정합니다. 이는 사용자가 인증해야 한다는 것을 Android Automotive OS에 알리는 것입니다.
  4. setErrorMessage() 메서드를 사용하여 미디어 세션의 PlaybackStateCompat 오류 메시지를 설정합니다. 이 오류 메시지는 사용자 대상이므로 사용자의 현재 언어에 맞게 현지화합니다.
  5. setExtras() 메서드를 사용하여 미디어 세션의 PlaybackStateCompat 추가 항목을 설정합니다. 다음 두 키를 포함합니다.

다음 코드 스니펫은 앱을 사용할 수 있도록 사용자에게 로그인을 요청하는 방법을 보여줍니다.

Kotlin

import androidx.media.utils.MediaConstants

val signInIntent = Intent(this, SignInActivity::class.java)
val signInActivityPendingIntent = PendingIntent.getActivity(this, 0,
    signInIntent, 0)
val extras = Bundle().apply {
    putString(
        MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_LABEL,
        "Sign in"
    )
    putParcelable(
        MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_INTENT,
        signInActivityPendingIntent
    )
}

val playbackState = PlaybackStateCompat.Builder()
        .setState(PlaybackStateCompat.STATE_ERROR, 0, 0f)
        .setErrorMessage(
            PlaybackStateCompat.ERROR_CODE_AUTHENTICATION_EXPIRED,
            "Authentication required"
        )
        .setExtras(extras)
        .build()
mediaSession.setPlaybackState(playbackState)

자바

import androidx.media.utils.MediaConstants;

Intent signInIntent = new Intent(this, SignInActivity.class);
PendingIntent signInActivityPendingIntent = PendingIntent.getActivity(this, 0,
    signInIntent, 0);
Bundle extras = new Bundle();
extras.putString(
    MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_LABEL,
    "Sign in");
extras.putParcelable(
    MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_INTENT,
    signInActivityPendingIntent);

PlaybackStateCompat playbackState = new PlaybackStateCompat.Builder()
    .setState(PlaybackStateCompat.STATE_ERROR, 0, 0f)
    .setErrorMessage(
            PlaybackStateCompat.ERROR_CODE_AUTHENTICATION_EXPIRED,
            "Authentication required"
    )
    .setExtras(extras)
    .build();
mediaSession.setPlaybackState(playbackState);

사용자가 성공적으로 인증된 후 PlaybackStateCompatSTATE_ERROR가 아닌 상태로 다시 설정하고, 활동의 finish() 메서드를 호출하여 사용자를 다시 Android Automotive OS로 안내합니다.

로그인 활동 구현

Google에서는 사용자가 자동차에서 앱에 로그인하는 과정을 지원하는 데 사용할 수 있는 다양한 ID 도구를 제공합니다. Firebase 인증과 같은 도구에서는 맞춤설정 인증 환경을 빌드하는 데 도움이 되는 풀스택 도구를 제공합니다. 또한 사용자의 기존 사용자 인증 정보 또는 기타 기술을 활용하여 사용자가 원활하게 로그인할 수 있는 환경을 빌드할 수 있게 지원하는 도구도 있습니다.

다음 도구를 사용하면 이전에 다른 기기에서 로그인한 적이 있는 사용자를 위한 더 간단한 로그인 환경을 빌드할 수 있습니다.

  • 원탭 로그인 및 가입: 다른 기기(예: 휴대전화 앱)에 이미 원탭을 구현했다면 Android Automotive OS 앱에도 구현하여 기존 원탭 사용자를 지원합니다.
  • Google 로그인: 다른 기기(예: 휴대전화 앱)에 Google 로그인을 이미 구현했다면 Android Automotive OS 앱에도 Google 로그인을 구현하여 기존 Google 로그인 사용자를 지원합니다.
  • Google 자동 완성: 사용자가 다른 Android 기기에서 Google 자동 완성을 선택했다면 사용자 인증 정보가 Google 비밀번호 관리자에 저장됩니다. 이러한 사용자가 Android Automotive OS 앱에 로그인하면 Google 자동 완성은 저장된 관련 사용자 인증 정보를 제안합니다. Google 자동 완성을 사용하면 애플리케이션을 개발할 필요가 없습니다. 하지만 애플리케이션 개발자는 품질을 개선하기 위해 앱을 최적화할 수 있습니다. Google 자동 완성은 Android 8.0(API 수준 26) 이상(Android Automotive OS 포함)을 실행하는 모든 기기에서 지원됩니다.

AccountManager 사용

인증이 포함된 Android Automotive OS 앱은 다음과 같은 이유로 AccountManager를 사용해야 합니다.

  • 더 나은 UX 및 간편한 계정 관리: 사용자는 로그인 및 로그아웃을 비롯하여 시스템 설정의 계정 메뉴에서 모든 계정을 쉽게 관리할 수 있습니다.
  • '게스트' 환경: 자동차는 공유 기기이므로 OEM이 차량에서 '게스트' 환경을 사용 설정할 수 있지만 이 차량에는 계정을 추가할 수 없습니다. 이 제한사항은 AccountManagerDISALLOW_MODIFY_ACCOUNTS를 사용하면 됩니다.

권한

사용자에게 권한을 요청해야 하는 경우 이전 섹션의 활동 워크플로 다이어그램에서 보여준 인증 활동 또는 설정 활동과 동일한 흐름을 사용합니다.

미디어 호스트 힌트 읽기

네트워크에 연결되는 시스템 애플리케이션 (버전 포함)에 따라 미디어 브라우저 서비스를 사용하는 경우 애플리케이션이 다음과 같은 추가 항목을 수신할 수 있습니다.

오류 처리

Android Automotive OS의 미디어 앱 오류는 미디어 세션의 PlaybackStateCompat를 통해 전달됩니다. 모든 오류의 경우 PlaybackStateCompat에서 적절한 오류 코드와 오류 메시지를 설정합니다. 그러면 Toast가 UI에 표시됩니다.

오류가 발생하지만 재생이 계속될 수 있는 경우 심각하지 않은 오류를 실행합니다. 예를 들어, 사용자가 로그인하지 않아도 앱에서 음악을 재생할 수 있지만, 노래를 건너뛰려면 로그인해야 합니다. 심각하지 않은 오류를 사용하면 시스템은 사용자가 현재 미디어 항목의 재생을 중단하지 않고 로그인하도록 제안할 수 있습니다.

심각하지 않은 오류를 실행하면 오류 코드와 오류 메시지를 제외하고 PlaybackStateCompat의 나머지 부분을 그대로 유지합니다. 이 접근 방식을 사용하면 사용자가 로그인할지 결정하는 동안 현재 미디어 항목을 계속 재생할 수 있습니다.

인터넷 연결이 불가능하고 오프라인 콘텐츠도 없는 등 재생이 불가능한 경우 PlaybackStateCompat 상태를 STATE_ERROR로 설정합니다.

이후에 PlaybackStateCompat를 업데이트할 때 오류 코드와 오류 메시지를 삭제하여 동일한 오류에 여러 경고가 표시되지 않도록 하세요.

인증이 필요한데 사용자가 로그인하지 않은 경우 등 언제라도 탐색 트리를 로드할 수 없다면 빈 탐색 트리를 전송합니다. 이를 나타내기 위해 루트 미디어 노드에 관해 onLoadChildren()에서 null 결과를 반환합니다. 이 경우 시스템에서는 PlaybackStateCompat에 설정된 오류 메시지와 함께 전체 화면 오류를 표시합니다.

조치 가능한 오류

오류가 조치 가능하다면 추가로 다음 두 extras를 PlaybackStateCompat에 설정합니다.

조치 가능한 오류는 Dialog로 표시되고 자동차가 정지된 때만 사용자가 해결할 수 있습니다.

오류 사례 테스트

앱이 다음을 포함한 모든 시나리오에서 오류를 적절하게 처리하는지 확인합니다.

  • 제품의 다양한 등급: 무료 제품과 프리미엄 제품 또는 로그인 상태와 로그아웃 상태를 예로 들 수 있습니다.
  • 다양한 운전 상태: 주차 상태와 운전 상태를 예로 들 수 있습니다.
  • 다양한 연결 상태: 온라인 상태와 오프라인 상태를 예로 들 수 있습니다.

기타 고려사항

Android Automotive OS 앱을 개발할 때 다음과 같은 기타 고려사항에 유의하세요.

오프라인 콘텐츠

적용되는 경우 오프라인 재생 지원을 구현합니다. Android Automotive OS를 사용하는 자동차에는 자체 데이터 연결이 있을 것으로 예상됩니다. 즉, 데이터 요금제가 차량 비용에 포함되어 있거나 사용자가 데이터 요금제를 지불합니다. 그러나 자동차는 휴대기기보다 연결성이 더 다양할 것으로 예상됩니다.

다음은 오프라인 작동 전략을 고려할 때 유의해야 할 사항입니다.

  • 콘텐츠를 다운로드할 가장 좋은 때는 앱을 사용하고 있는 동안입니다.
  • Wi-Fi를 사용할 수 있다고 가정하지 않습니다. 자동차가 Wi-Fi 범위로 들어오지 않거나 OEM에서 셀룰러 네트워크를 위해 Wi-Fi를 사용 중지했을 수 있습니다.
  • 사용자가 사용할 것으로 예상되는 콘텐츠를 스마트하게 캐시하는 것도 괜찮지만 사용자가 설정 활동을 통해 이 동작을 변경하도록 허용하는 것이 좋습니다.
  • 자동차의 디스크 공간은 다양하므로 사용자에게 오프라인 콘텐츠를 삭제하는 방법(예: 설정 활동의 옵션을 통해)을 제공합니다.

WebView 지원

WebView는 Android Automotive OS에서 지원되지만 설정 및 로그인 활동에만 허용됩니다. WebView를 사용하는 활동은 WebView 외부에 '닫기' 또는 '뒤로' 어포던스를 보유해야 합니다.

다음은 허용되는 WebView 사용 사례의 예입니다.

  • 설정 활동에서 개인정보처리방침이나 서비스 약관, 기타 법률 관련 링크 표시
  • 로그인 활동의 웹 기반 흐름

WebView를 사용할 때 자바스크립트를 사용 설정할 수 있습니다.

WebView 보안

WebView가 더 큰 인터넷의 진입점이 되지 않도록 가능한 모든 예방 조치를 취합니다. WebView를 loadUrl() 호출에서 사용되는 URL에 잠그고 리디렉션을 방지하는 방법에 관한 예는 아래 코드 스니펫을 참고하세요. 가능하다면(예: 법률 관련 링크를 표시할 때) 이와 같은 보호 장치를 구현하는 것이 좋습니다.

Kotlin

override fun shouldOverrideUrlLoading(webView: WebView,
                             webResourceRequest: WebResourceRequest): Boolean {
  val originalUri: Uri = Uri.parse(webView.originalUrl)
  // Check for allowed URLs
  if (originalUri.equals(Uri.parse(BLANK_URL))
      || originalUri.equals(webResourceRequest.url)) {
    return false
  }
  if (webResourceRequest.isRedirect) {
    logger.w("Redirect detected, not following")
    return true
  }
  setupWizardWebViewClientListener.onUriBlocked(webResourceRequest.url)
  logger.w(
    String.format(
      "Navigation prevented to %s original is %s", webResourceRequest.url, originalUri))
  return true
}

Java

@Override
public boolean shouldOverrideUrlLoading(WebView webView, WebResourceRequest webResourceRequest) {
  Uri originalUri = Uri.parse(webView.getOriginalUrl());
  // Check for allowed URLs
  if (originalUri.equals(Uri.parse(BLANK_URL))
      || originalUri.equals(webResourceRequest.getUrl())) {
    return false;
  }
  if (webResourceRequest.isRedirect()) {
    logger.w("Redirect detected, not following");
    return true;
  }
  setupWizardWebViewClientListener.onUriBlocked(webResourceRequest.getUrl());
  logger.w(
      String.format(
          "Navigation prevented to %s original is %s", webResourceRequest.getUrl(), originalUri));
  return true;
}

패키지 이름

Android Automotive OS용 Android Package Kit(APK)가 별도로 배포되므로 모바일 앱의 패키지 이름을 재사용하거나 새 패키지 이름을 만들 수 있습니다. 다른 패키지 이름을 사용하면 앱은 서로 다른 두 개의 Play 스토어 등록정보를 갖게 되며, 현재 패키지 이름을 재사용하면 앱은 두 플랫폼에서 하나의 등록정보를 갖게 됩니다.

이는 주로 비즈니스를 고려해 결정하게 되는 사항입니다. 예를 들어 한 팀에서 모바일 앱을 담당하고 다른 팀에서 Android Automotive OS 앱을 담당한다면 서로 다른 패키지 이름을 만들어 각 팀에서 자체 Play 스토어 등록정보를 관리하도록 하는 것이 좋을 수 있습니다. 두 접근 방식을 사용하는 데 필요한 기술적 작업에는 큰 차이가 없습니다.

다음 표는 현재 패키지 이름을 유지하는 것과 새 패키지 이름을 사용하는 것의 주요 차이점을 요약하여 보여줍니다.

기능 동일한 패키지 이름 새 패키지 이름
스토어 등록정보 한 개 여러 개
미러링 설치 예: 설정 마법사에서 '빠른 앱 재설치' 아니요
Play 스토어 검토 절차 검토 차단: 하나의 APK에 관한 검토가 실패하면 동일한 버전에 제출된 다른 APK가 차단됨 개별 검토
통계, 측정항목, vitals 결합됨: 자동차 관련 데이터를 필터링할 수 있습니다. 별도
색인 생성 및 검색 순위 현재 순위에서 빌드 이월 없음
다른 앱과 통합 두 APK 간에 미디어 코드가 공유된다고 가정하면 대부분 변경이 필요하지 않음 Google 어시스턴트로 URI를 재생하는 경우와 같이 상응하는 앱을 업데이트해야 할 수 있음

자주 묻는 질문(FAQ)

Android Automotive OS에 관한 자주 묻는 질문(FAQ)의 답변은 다음 섹션을 참고하세요.

하드웨어

앱에서 마이크에 액세스할 수 있나요?

Android 10(API 수준 29) 이상을 타겟팅하는 앱은 오디오 입력 공유 문서를 참고하세요. API 수준 29 이전에는 이 기능을 사용할 수 없습니다.

액세스할 수 있는 자동차 API와 액세스 방법은 무엇인가요?

OEM에서 노출하는 API로 제한됩니다. 이러한 API에 액세스하는 방법을 표준화하는 프로세스가 개발되고 있습니다.

앱은 CarPropertyManager에서 SetProperty()GetProperty()를 사용하여 자동차 API에 액세스할 수 있습니다. 사용 가능한 모든 속성 목록은 소스 코드참조 문서를 참고하세요. 속성이 @SystemApi주석 처리된 경우 미리 로드된 시스템 앱으로 제한됩니다.

지원되는 오디오 코덱 유형은 무엇인가요?

Android CDD의 오디오 코덱 세부정보를 참고하세요.

Widevine DRM은 지원되나요?

예. Widevine DRM은 지원됩니다.

개발 및 테스트

서드 파티 SDK 및 라이브러리 사용에 관한 제한사항이나 권장사항이 있나요?

서드 파티 SDK 및 라이브러리 사용에 관한 특정 가이드라인은 없습니다. 서드 파티 SDK 및 라이브러리를 사용하기로 한 경우에도 모든 자동차 앱 품질 요구사항을 준수해야 합니다.

포그라운드 서비스를 사용할 수 있나요?

유일하게 허용된 포그라운드 서비스 사용 사례는 오프라인에서 사용할 콘텐츠를 다운로드하는 것입니다. 지원받고자 하는 다른 포그라운드 서비스 사용 사례가 있다면 Android Automotive OS 토론방을 통해 문의해 주세요.

Android Automotive OS 앱 게시

Google Play Console을 사용하여 Android Automotive OS 앱을 게시하려면 어떻게 해야 하나요?

앱 게시 프로세스는 휴대전화 앱을 게시하는 것과 비슷하지만 다른 폼 팩터를 사용합니다. 앱이 Android Automotive OS 폼 팩터를 사용하도록 선택하려면 다음 단계를 따르세요.

  1. Play Console을 엽니다.
  2. 앱을 선택합니다.
  3. 왼쪽 메뉴에서 출시 > 설정 > 고급 설정 > 폼 팩터를 클릭합니다.
  4. 폼 팩터 추가 > Android Automotive OS를 클릭한 후 Play Console의 안내를 따릅니다.

추가 리소스

Android Automotive OS에 관한 자세한 내용은 다음 추가 리소스를 참고하세요.

샘플

가이드

블로그

동영상

Android Automotive OS 미디어 문제 신고

Android Automotive OS용 미디어 앱을 개발하는 중에 문제가 발생하면 Google Issue Tracker를 사용하여 신고할 수 있습니다. 문제 템플릿에 요청된 모든 정보를 작성해야 합니다.

새로운 문제 제출하기

새로운 문제를 신고하기 전에 그 문제가 문제 목록에 이미 보고되었는지 확인합니다. Tracker에서 문제에 있는 별표를 클릭하여 문제를 구독하고 투표를 할 수 있습니다. 자세한 내용은 문제 구독을 참고하세요.