라디오 구현

라디오 컨트롤 구현은 MediaSessionMediaBrowse에 기반하며 이를 통해 미디어와 음성 어시스턴트 앱에서 라디오를 제어할 수 있습니다. 자세한 내용은 developer.android.com에서 차량용 미디어 앱 빌드를 참고하세요.

미디어 탐색 트리 구현은 packages/apps/Car/libs의 car-broadcastradio-support 라이브러리에 제공됩니다. 이 라이브러리에는 URI로 변환하거나 URI에서 변환할 수 있는 확장된 ProgramSelector도 포함되어 있습니다. 라디오 구현 시 이 라이브러리를 사용하여 연결된 탐색 트리를 빌드하는 것이 좋습니다.

미디어 소스 전환

라디오와 미디어에 표시되는 다른 앱 사이에 원활하게 전환하기 위해 car-media-common 라이브러리에는 라디오 앱에 통합되어야 하는 클래스가 포함되어 있습니다. MediaAppSelectorWidget은 라디오 앱의 XML에 포함될 수 있습니다(참조 미디어와 라디오 앱에서 사용되는 아이콘과 드롭다운).

<com.android.car.media.common.MediaAppSelectorWidget
     android:id="@+id/app_switch_container"
     android:layout_width="@dimen/app_switch_widget_width"
     android:layout_height="wrap_content"
     android:background="@drawable/app_item_background"
     android:gravity="center" />

이 위젯은 전환할 수 있는 미디어 소스 목록을 표시하는 AppSelectionFragment를 실행합니다. 제공된 것 이외의 UI가 필요한 경우 맞춤 위젯을 만들어 전환이 표시되어야 할 때 AppSelectionFragment를 실행할 수 있습니다.

AppSelectionFragment newFragment = AppSelectionFragment.create(widget,
            packageName, fullScreen);
    newFragment.show(mActivity.getSupportFragmentManager(), null);

샘플 구현은 packages/apps/Car/Radio에 있는 참조 라디오 앱 구현에 제공됩니다.

세부 제어 사양

MediaSession(MediaSession.Callback을 통한) 인터페이스는 현재 재생 중인 라디오 프로그램의 제어 메커니즘을 제공합니다.

  • onPlay, onStop. 라디오 재생 음소거(음소거 해제)
  • onPause. 시간 이동 시 일시중지(지원되는 경우)
  • onPlayFromMediaId. 최상위 폴더의 모든 콘텐츠 재생. 예: "FM 재생해 줘" 또는 "라디오 재생해 줘"
  • onPlayFromUri. 특정 주파수 재생. 예: "88.5 FM 틀어 줘"
  • onSkipToNext, onSkipToPrevious. 다음 또는 이전 채널에 맞춤
  • onSetRating. 즐겨찾기에 추가 또는 즐겨찾기에서 삭제

MediaBrowser는 최상위 디렉터리의 세 가지 유형에 관해 조정 가능한 MediaItem을 노출합니다.

  • (선택사항) 프로그램(채널). 이 모드는 일반적으로 듀얼 튜너 라디오에서 사용하여 사용자 위치에서 제공되는 모든 조정 가능한 라디오 채널을 나타냅니다.
  • 즐겨찾기. 즐겨찾기 목록에 추가된 라디오 프로그램 중 일부를 사용할 수 없습니다(수신 범위 밖).
  • 대역 채널. 현재 지역에서 실제로 가능한 모든 채널(87.9, 88.1, 88.3, 88.5, 88.7, 88.9, 89.1 등). 모든 대역에는 별도의 최상위 디렉터리가 있습니다.
MediaBrowserService 트리 구조
그림 1. MediaBrowserService 트리 구조

이러한 각 폴더(AM/FM/프로그램)의 각 요소는 MediaSession과 함께 조정에 사용할 수 있는 URI가 포함된 MediaItem입니다. 각 최상위 폴더(AM/FM/Programs)는 MediaSession과 함께 재생을 트리거하는 데 사용할 수 있고 OEM의 재량권에 달려 있는 mediaId가 포함된 MediaItem입니다. 예를 들어 "FM 재생해 줘", "AM 재생해 줘", "라디오 재생해 줘"는 모두 mediaId를 사용하여 OEM 라디오 앱으로 전송하는 구체적이지 않은 라디오 쿼리입니다. 일반적인 요청과 mediaId에 따라 재생할 항목은 라디오 앱이 결정합니다.

MediaSession

방송 스트림을 일시중지하는 개념이 없으므로 재생, 일시중지, 중지 작업이 항상 라디오에 적용되지는 않습니다. 라디오에서 중지 작업은 스트림 음소거와 관련이 있고 재생은 음소거 삭제와 관련이 있습니다.

일부 라디오 튜너(또는 앱)는 콘텐츠를 캐시하고 나중에 재생하여 방송 스트림 일시중지를 시뮬레이션하는 기능을 제공합니다. 이러한 경우에는 onPause를 사용합니다.

mediaId 및 URI 작업에서 재생은 MediaBrowser 인터페이스에서 가져온 채널에 맞추기 위한 것입니다. mediaId는 라디오 앱에서 제공하는 임의 문자열로, 고유하고(주어진 ID가 항목 하나만 가리킴) 안정적인(주어진 항목의 ID가 전체 세션에 걸쳐 동일함) 값을 부과하여 주어진 채널을 식별합니다. URI는 잘 정의된 스키마입니다. 즉, URI 기반 ProgramSelector 형식입니다. 이를 통해 uniquity 속성이 보존됩니다. 이 속성은 안정적일 필요는 없지만 채널이 다른 주파수로 이동할 때 변경될 수 있습니다.

의도적으로 onPlayFromSearch는 사용되지 않습니다. MediaBrowser 트리에서 검색결과를 선택하는 것은 클라이언트(호환 앱)의 책임입니다. 이러한 책임을 라디오 앱으로 옮기면 복잡성이 증가하고 문자열 쿼리가 표시되어야 하는 방식에 관한 공식적인 계약이 필요하며 결과적으로 다양한 하드웨어 플랫폼에서 고르지 못한 사용자 환경이 발생합니다.

참고: 라디오 애플리케이션에는 MediaBrowser 인터페이스를 통해 클라이언트에 노출되지 않은 채널 이름을 검색하는 데 유용할 수 있는 추가 정보가 포함되어 있지 않습니다.

다음 또는 이전 채널로 건너뛰기는 현재 컨텍스트에 따라 다릅니다.

  • 애플리케이션이 즐겨찾기 목록의 채널에 맞춰지면 애플리케이션은 즐겨찾기 목록에서 다음 채널로 이동할 수 있습니다.
  • 프로그램 목록에서 채널을 청취하면 채널 번호에 따라 정렬된 사용 가능한 다음 채널에 맞출 수 있습니다.
  • 임의 채널을 청취하면 방송 신호가 없더라도 실제 다음 채널에 맞출 수 있습니다.

라디오 애플리케이션은 이러한 작업을 처리합니다.

오류 처리

TransportControls 작업(재생, 중지, 다음)은 작업 성공 여부에 관한 피드백을 제공하지 않습니다. 오류를 나타낼 유일한 방법은 오류 메시지와 함께 MediaSession 상태를 STATE_ERROR로 설정하는 것입니다.

라디오 앱은 이러한 작업을 처리하여 실행하거나 오류 상태를 설정해야 합니다. 재생 명령어를 즉시 실행하지 않으면 이 명령어가 실행되는 동안 재생 상태가 STATE_CONNECTING(직접 조정의 경우) 또는 STATE_SKIPPING_TO_PREVIOUS/NEXT로 변경되어야 합니다.

클라이언트는 PlaybackState를 주시하고 세션이 현재 프로그램을 요청되었거나 오류 상태로 전환된 것으로 변경했는지 확인해야 합니다. STATE_CONNECTING은 30초를 초과할 수 없습니다. 그러나 주어진 AM/FM 주파수에 직접 맞추면 훨씬 더 빠르게 실행됩니다.

즐겨찾기 추가 및 삭제

MediaSession에는 즐겨찾기를 제어하는 데 사용할 수 있는 평가 지원 기능이 있습니다. RATING_HEART 유형 평가로 호출된 onSetRating은 현재 맞춘 채널을 즐겨찾기 목록에 추가하거나 목록에서 삭제합니다.

기존 미리 설정과 달리 이 모델은 저장된 각 즐겨찾기가 숫자 슬롯(일반적으로 1~6)에 할당되었을 때 정렬되지 않은 무한한 즐겨찾기 목록을 가정합니다. 따라서 미리 설정 기반 시스템은 onSetRating 작업과 호환되지 않습니다.

MediaSession API의 제한사항은 현재 맞춰진 채널만 추가하거나 삭제할 수 있다는 점입니다. 예를 들어 항목을 먼저 선택해야 삭제할 수 있습니다. 이는 호환 앱과 같은 MediaBrowser 클라이언트의 제한사항일 뿐입니다. 라디오 앱은 이와 유사하게 제한되지 않습니다. 이 부분은 앱에서 즐겨찾기를 지원하지 않을 때 선택사항입니다.

MediaBrowser

지정된 라디오 기술에 적합한 임의 채널에 맞출 때 어떤 주파수나 실제 채널 이름이 주어진 지역에 유효한지 표시하기 위해 각 대역에 유효한 모든 채널(주파수)이 나열됩니다. 미국 지역에서는 87.8~108.0MHz 범위(0.2MHz 간격 사용)의 FM 채널 101개와 530~1700kHz 범위(10kHz 간격 사용)의 AM 채널 117개에 이릅니다. HD 라디오는 동일한 채널 공간을 사용하므로 별도로 표시되지 않습니다.

현재 사용 가능한 라디오 프로그램 목록은 직접 오디오 방송(DAB) 앙상블로 그룹화와 같은 표시 체계를 허용하지 않는다는 점에서 단조롭습니다.

즐겨찾기 목록의 항목은 조정이 불가능할 수 있습니다. 특정 프로그램의 범위를 벗어난 경우를 예로 들 수 있습니다. 라디오 앱은 항목이 미리 맞춰질 수 있는지 감지하거나 감지하지 못할 수 있습니다. 이 경우 항목을 재생 가능으로 표시하지 않을 수 있습니다.

최상위 폴더를 식별하기 위해 블루투스에서 사용하는 동일한 메커니즘이 적용됩니다. 즉, MediaDescription 객체의 Extras 번들에는 블루투스에서 EXTRA_BT_FOLDER_TYPE으로 그런 것처럼 튜너별 필드가 포함되어 있습니다. 방송 라디오의 경우에는 공개 API에서 다음과 같은 새 필드를 정의하게 됩니다.

  • EXTRA_BCRADIO_FOLDER_TYPE = "android.media.extra.EXTRA_BCRADIO_FOLDER_TYPE". 다음 값 중 하나:
    • BCRADIO_FOLDER_TYPE_PROGRAMS = 1. 현재 사용 가능한 프로그램
    • BCRADIO_FOLDER_TYPE_FAVORITES = 2. 즐겨찾기
    • BCRADIO_FOLDER_TYPE_BAND = 3. 특정 대역의 모든 실제 채널

    라디오별 맞춤 메타데이터 필드를 정의하지 않아도 됩니다. 모든 관련 데이터가 기존 MediaBrowser.MediaItem 체계에 적합하기 때문입니다.

    • 프로그램 이름(RDS PS, DAB 서비스 이름). MediaDescription.getTitle.
    • FM 주파수. URI(ProgramSelector 참고) 또는 MediaDescription.getTitle(항목이 BROADCASTRADIO_FOLDER_TYPE_BAND 폴더에 있는 경우)
    • 라디오 고유 식별자(RDS PI, DAB SId). ProgramSelector로 파싱된 MediaDescription.getMediaUri

    일반적으로 현재 프로그램이나 즐겨찾기 목록에서 항목의 FM 주파수를 가져오지 않아도 됩니다. 클라이언트가 미디어 ID에서 작동해야 하기 때문입니다. 그러나 표시 목적 등으로 가져와야 한다면 URI에 표시되고 ProgramSelector로 파싱될 수 있습니다. 하지만 현재 세션 내에서 항목을 선택하는 데 URI를 사용하지 않는 것이 좋습니다. 자세한 내용은 ProgramSelector를 참고하세요.

    성능 또는 바인더 관련 문제를 방지하기 위해 MediaBrowser 서비스는 페이지로 나누기를 지원해야 합니다.

    참고: 페이지로 나누기는 옵션 처리 없이 onLoadChildren() 변형에서 기본적으로 구현됩니다.

    모든 목록 유형(원시 채널, 찾은 프로그램, 즐겨찾기)의 관련 항목은 mediaId가 다를 수 있습니다(라디오 앱에 따라 달라짐, 지원 라이브러리마다 다름). URI(ProgramSelector 형식)는 대부분의 경우 원시 채널과 찾은 프로그램 간에 다르지만(RDS가 없는 FM은 예외) 찾은 프로그램과 즐겨찾기 간에는 대부분 동일합니다(AF를 업데이트한 경우는 예외).

    여러 목록 유형에서 항목 mediaId가 다양하면 항목에 여러 작업을 실행할 수 있습니다. 최근 선택한 MediaItem의 폴더에 따라 onSkipToNext에서 즐겨찾기 목록 또는 모든 프로그램 목록을 순회할 수 있습니다(MediaSession 참고).

    특별 미세 조정 작업

    프로그램 목록을 통해 사용자는 특정 채널에 맞출 수 있지만 "FM에 맞춰 줘" 등과 같은 일반적인 요청은 할 수 없습니다. 이와 같이 요청하면 최근에 청취한 FM 대역의 채널에 맞춰질 수 있습니다.

    이러한 작업을 지원하기 위해 일부 최상위 디렉터리에는 FLAG_PLAYABLE 플래그가 설정되어 있습니다. 폴더의 경우 FLAG_BROWSABLE도 설정되어 있습니다.

    작업 맞춤 대상 실행 방법
    라디오 재생 모든 라디오 채널 startService(ACTION_PLAY_BROADCASTRADIO)
    또는 playFromMediaId(MediaBrowser.getRoot())
    FM 재생 모든 FM 채널 FM 대역의 mediaId에서 재생

    어떤 프로그램에 맞출지는 애플리케이션에서 결정합니다. 일반적으로 지정된 목록에서 가장 최근에 맞춘 채널입니다. ACTION_PLAY_BROADCASTRADIO에 관한 자세한 내용은 일반 재생 인텐트를 참고하세요.

    탐색 및 서비스 연결

    PackageManager는 방송 라디오 트리를 제공하는 MediaBrowserService를 직접 찾을 수 있습니다. 이렇게 하려면 ACTION_PLAY_BROADCASTRADIO 인텐트(일반 재생 인텐트 참고)와 MATCH_SYSTEM_ONLY 플래그를 사용하여 resolveService를 호출합니다. 라디오를 제공하는 모든 서비스를 찾으려면(서비스가 두 개 이상 있을 수 있음. 예: 개별 AM/FM과 위성) queryIntentServices를 사용하세요.

    확인된 서비스는 android.media.browse.MediaBrowserService 바인드 인텐트도 처리합니다. GTS로 확인됩니다.

    선택한 MediaBrowserService에 연결하려면 지정된 서비스 구성요소 및 connectMediaBrowser 인스턴스를 만듭니다. 연결한 후에는 MediaSession 핸들을 getSessionToken을 통해 가져올 수 있습니다.

    라디오 앱은 서비스의 onGetRoot 구현에서 연결이 허용되는 클라이언트 패키지를 제한할 수 있습니다. 라디오 앱에서는 시스템 앱이 허용 없이 연결할 수 있도록 해야 합니다. 허용 목록에 관한 자세한 내용은 어시스턴트 앱 패키지 및 서명 수락을 참고하세요.

    소스별 애플리케이션(예: 라디오 앱)이 이러한 소스 지원이 없는 기기에 설치되면 여전히 ACTION_PLAY_BROADCASTRADIO 인텐트를 처리하는 것으로 자체를 광고하지만 MediaBrowser 트리에는 라디오별 태그가 포함되지 않습니다. 따라서 지정된 소스를 기기에서 사용할 수 있는지 확인하려는 클라이언트는 다음을 실행해야 합니다.

    1. 라디오 서비스를 탐색합니다(ACTION_PLAY_BROADCASTRADIO의 경우 resolveService 호출).
    2. 라디오 서비스용 MediaBrowser를 만들고 연결합니다.
    3. EXTRA_BCRADIO_FOLDER_TYPE extra로 MediaItem의 존재 여부를 판단합니다.

    참고: 대부분의 경우 클라이언트는 사용 가능한 모든 MediaBrowser 트리를 검사하여 지정된 기기에서 사용 가능한 모든 소스를 감지해야 합니다.

    대역 이름

    대역 목록은 폴더 유형 태그가 BCRADIO_FOLDER_TYPE_BAND로 설정된 일련의 최상위 디렉터리로 표현됩니다. MediaItem의 제목은 대역 이름을 나타내는 현지화된 문자열입니다. 대부분의 경우 영어 번역과 동일하지만 클라이언트는 이러한 가정에 의존할 수 없습니다.

    특정 대역을 찾는 데 안정적인 메커니즘을 제공하기 위해 대역 폴더에는 추가 태그 EXTRA_BCRADIO_BAND_NAME_EN이 추가됩니다. 현지화되지 않은 대역 이름으로, 다음과 같은 사전 정의된 값 중 하나만 사용할 수 있습니다.

    • AM
    • FM
    • DAB
    • SXM

    대역이 이 목록에 없으면 대역 이름 태그를 설정하면 안 됩니다. 그러나 대역이 목록에 있으면 태그 집합이 있어야 합니다. HD 라디오는 별도의 대역을 열거하지 않습니다. AM/FM과 동일한 기본 매체를 사용하기 때문입니다.

    일반 재생 인텐트

    특정 소스(예: 라디오나 CD) 재생 전용의 각 앱은 일반 재생 인텐트를 처리하여 비활성 상태(예: 부팅 후)에서 콘텐츠 재생을 시작할 수 있어야 합니다. 재생할 콘텐츠를 선택하는 방법은 앱에 따라 다르지만 일반적으로는 최근에 재생한 라디오 프로그램이나 CD 트랙입니다.
    각 오디오 소스에는 별도의 인텐트가 정의되어 있습니다.

    • android.car.intent.action.PLAY_BROADCASTRADIO
    • android.car.intent.action.PLAY_AUDIOCD: CD-DA 또는 CD-Text
    • android.car.intent.action.PLAY_DATADISC: CD/DVD와 같은 광학 데이터 디스크. CD-DA는 아님(혼합 모드 CD일 수 있음)
    • android.car.intent.action.PLAY_AUX: AUX 포트를 지정하지 않음
    • android.car.intent.action.PLAY_BLUETOOTH
    • android.car.intent.action.PLAY_USB: USB 기기를 지정하지 않음
    • android.car.intent.action.PLAY_LOCAL: 로컬 미디어 저장소(내장 플래시)

    인텐트는 일반 재생 명령어에 사용되도록 선택되었습니다. 일반 재생 명령어 자체와 서비스 검색이라는 두 가지 문제를 한 번에 해결하기 때문입니다. 이러한 인텐트가 있으면 MediaBrowser 세션을 열지 않고도 이러한 간단한 작업을 실행할 수 있다는 추가 장점이 있습니다.

    서비스 검색은 실제로 이러한 인텐트로 해결되는 더 중요한 문제입니다. 서비스 검색 절차는 이와 같은 방식으로 간단 명료합니다(검색 및 서비스 연결 참고).

    클라이언트 구현을 더 쉽게 하기 위해 이러한 재생 명령어(라디오 앱에서도 구현되어야 함)를 실행하는 대체 방법이 있습니다. mediaId로 사용되는 루트 노드의 rootId로 playFromMediaId를 실행하는 것입니다. 루트 노드는 재생할 수 없지만 그 rootId는 mediaId로 사용할 수 있는 임의 문자열입니다. 하지만 클라이언트는 이러한 미묘한 차이를 알 필요가 없습니다.

    ProgramSelector

    mediaId로 MediaBrowserService에서 채널을 충분히 선택할 수 있지만 mediaId는 세션에 바인딩되고 제공자 간에 일관되지 않습니다. 때에 따라 클라이언트는 세션과 기기 간에 mediaId를 유지하기 위해 절대 주파수와 같은 절대 포인터가 필요할 수 있습니다.

    디지털 라디오 방송 시대에 기본 주파수만으로는 특정 채널에 맞추기에 충분하지 않습니다. 따라서 ProgramSelector를 사용하여 아날로그나 디지털 채널에 맞춥니다. ProgramSelector는 두 부분으로 구성됩니다.

    • 기본 식별자. 특정 라디오 채널의 변경할 수 없는 안정적인 고유 식별자이지만 이 채널에 맞추기에는 충분하지 않을 수도 있습니다. 미국에서 호출 부호로 변환될 수 있는 RDS PI 코드를 예로 들 수 있습니다.
    • 보조 식별자. 다른 라디오 기술의 식별자를 비롯하여 채널에 맞추는 데 유용한 추가 식별자(예: 주파수)입니다. 아날로그 방송 대체가 있을 수 있는 DAB 채널을 예로 들 수 있습니다.

    MediaBrowser/MediaSession 기반 솔루션에 ProgramSelector를 적합하게 하려면 이를 직렬화하도록 URI 스키마를 정의합니다. 스키마는 다음과 같이 정의됩니다.

    broadcastradio://program/<primary ID type>/<primary ID>?
    <secondary ID type>=<secondary ID>&<secondary ID type>=<secondary ID>
    

    이 예에서 보조 식별자 부분(물음표(?) 뒤)은 선택사항이며 mediaId로 사용할 안정적인 식별자를 제공하기 위해 삭제할 수 있습니다. 예:

    • broadcastradio://program/RDS_PI/1234?
      AMFM_FREQUENCY=88500&AMFM_FREQUENCY=103300
    • broadcastradio://program/AMFM_FREQUENCY/102100
    • broadcastradio://program/DAB_SID_EXT/14895264?RDS_PI=1234

    program의 권한 부분(AKA 호스트)은 향후 체계 확장을 위한 공간을 제공합니다. 식별자 유형 문자열은 IdentifierType의 HAL 2.x 정의에 있는 이름으로 정확하게 지정되며 값 형식은 십진수 또는 16진수(0x 접두사 포함)입니다.

    모든 공급업체별 식별자는 VENDOR_ 접두사로 표시됩니다. 예: VENDOR_START의 경우 VENDOR_0, VENDOR_START + 1의 경우 VENDOR_1 이러한 URI는 URI가 생성된 무선 하드웨어에만 적용되며 다른 OEM에서 만든 기기 간에 전송할 수 없습니다.

    이러한 URI는 최상위 라디오 폴더 아래의 각 MediaItem에 할당되어야 합니다. 또한 MediaSession은 playFromMediaIdplayFromUri를 모두 지원해야 합니다. 그러나 URI는 주로 라디오 메타데이터 추출(예: FM 주파수)과 영구 스토리지에 사용됩니다. URI를 모든 미디어 항목에 사용할 수 있다는 보장은 없습니다(예: 프레임워크에서 기본 ID 유형을 아직 지원하지 않는 경우). 반면 미디어 ID는 항상 작동합니다. 클라이언트가 URI를 사용하여 현재 MediaBrowser 세션의 항목을 선택하는 것은 권장되지 않습니다. 대신 playFromMediaId를 사용하세요. 하지만 제공 앱에는 선택사항이 아니며 누락된 URI는 적절한 경우를 위해 예약됩니다.

    초기 설계에서는 체계 부분 뒤에 :// 시퀀스 대신 단일 콜론을 사용했습니다. 그러나 전자는 계층적 절대 URI 참조용으로 android.net.Uri에서 지원되지 않습니다.

    기타 소스 유형

    다른 오디오 소스는 유사하게 처리할 수 있습니다. 예를 들어 보조 입력과 오디오 CD 플레이어가 있습니다.

    단일 애플리케이션은 여러 유형의 소스를 제공할 수 있습니다. 이러한 경우에는 소스 유형마다 별도의 MediaBrowserService를 만드는 것이 좋습니다. 제공된 여러 소스/MediaBrowserServices가 있는 설정에서도 단일 애플리케이션 내에 단일 MediaSession이 있는 것이 좋습니다.

    오디오 CD

    이러한 디스크를 제공하는 애플리케이션이 탐색 가능한 단일 항목(또는 시스템에 CD 체인저가 있으면 더 많음)이 있는 MediaBrowser를 노출한다는 점에서 오디오 CD와 유사합니다. 시스템이 모든 CD의 트랙에 관해 알지 못하면(예: 모든 디스크가 카트리지에 한 번에 삽입되어 모두를 읽지 않은 경우) 전체 디스크의 MediaItem은 BROWSABLE+PLAYABLE이 아닌 PLAYABLE입니다. 지정된 슬롯에 디스크가 없다면 항목은 PLAYABLEBROWSABLE도 아니지만 각 슬롯은 항상 트리에 있어야 합니다.

    오디오 CD 트리 구조
    그림 2. 오디오 CD 트리 구조

    이러한 항목은 방송 라디오 폴더와 비슷한 방식으로 표시되는데, MediaDescription API에 정의된 추가 필드를 포함하고 있을 수 있습니다.

    • EXTRA_CD_TRACK: 오디오 CD의 모든 MediaItem의 경우 1기반 트랙 번호
    • EXTRA_CD_DISK: 1기반 디스크 번호

    CD-Text 지원 시스템 및 호환 디스크의 경우 최상위 MediaItem에는 디스크 제목이 있습니다. 마찬가지로 트랙의 MediaItems에는 트랙 제목이 있습니다.

    보조 입력

    보조 입력을 제공하는 애플리케이션은 AUX in 포트를 나타내는 단일 항목(또는 여러 포트가 있는 경우 더 많음)이 있는 MediaBrowser 트리를 노출합니다. 각 MediaSession은 mediaId를 가져와서 playFromMediaId 요청을 받은 후 그 소스로 전환합니다.

    AUX 트리 구조
    그림 3. AUX 트리 구조

    각 AUX MediaItem 항목에는 'AUX' 구문 없이 포트의 현지화되지 않은 이름으로 설정된 추가 필드 EXTRA_AUX_PORT_NAME이 있습니다. 예를 들어 'AUX 1'은 '1'로, 'AUX front'는 'front'로, 'AUX'는 빈 문자열로 설정됩니다. 영어가 아닌 언어의 경우 이름 태그는 영어 문자열과 동일하게 유지됩니다. EXTRA_BCRADIO_BAND_NAME_EN과는 달리 값은 OEM에서 정의하며 사전 정의된 목록으로 제한되지 않습니다.

    하드웨어가 AUX 포트에 연결된 기기를 감지할 수 있다면 입력이 연결된 경우에만 하드웨어가 MediaItem을 PLAYABLE로 표시해야 합니다. 이 포트에 아무것도 연결되지 않았다면 하드웨어는 여전히 열거(PLAYABLE은 아님)되어야 합니다. 하드웨어에 이러한 기능이 없으면 MediaItem은 항상 PLAYABLE로 설정되어야 합니다.

    추가 필드

    따라서 다음과 같은 추가 키를 정의해야 합니다.

    • EXTRA_CD_TRACK = "android.media.extra.CD_TRACK"
    • EXTRA_CD_DISK = "android.media.extra.CD_DISK"
    • EXTRA_AUX_PORT_NAME = "android.media.extra.AUX_PORT_NAME"

    클라이언트는 최상위 MediaItem에서 요소에 EXTRA_CD_DISK 또는 EXTRA_AUX_PORT_NAME 추가 필드가 설정되어 있는지 검토해야 합니다.

    자세한 예

    다음 예에서는 이 설계의 일부인 소스 유형의 MediaBrowser 트리 구조를 다룹니다.

    방송 라디오 MediaBrowserService(ACTION_PLAY_BROADCASTRADIO 처리)

    • 채널(탐색 가능)
      EXTRA_BCRADIO_FOLDER_TYPE=BCRADIO_FOLDER_TYPE_PROGRAMS
      • BBC One(재생 가능)
        URI: broadcastradio://program/RDS_PI/1234?AMFM_FREQUENCY=90500
      • ABC 88.1(재생 가능)
        URI: broadcastradio://program/RDS_PI/5678?AMFM_FREQUENCY=88100
      • ABC 88.1 HD1(재생 가능)
        URI: broadcastradio://program/HD_STATION_ID_EXT/158241DEADBEEF?AMFM_FREQUENCY=88100&RDS_PI=5678
      • ABC 88.1 HD2(재생 가능)
        URI: broadcastradio://program/HD_STATION_ID_EXT/158242DEADBEFE
      • 90.5 FM(재생 가능) - RDS가 없는 FM
        URI: broadcastradio://program/AMFM_FREQUENCY/90500
      • 620 AM(재생 가능)
        URI: broadcastradio://program/AMFM_FREQUENCY/620
      • BBC One(재생 가능)
        URI: broadcastradio://program/DAB_SID_EXT/1E24102?RDS_PI=1234
    • 즐겨찾기(탐색 가능, 재생 가능)
      EXTRA_BCRADIO_FOLDER_TYPE=BCRADIO_FOLDER_TYPE_FAVORITES
      • BBC One(재생 가능)
        URI: broadcastradio://program/RDS_PI/1234?AMFM_FREQUENCY=101300
      • BBC 2(재생 불가)
        URI: broadcastradio://program/RDS_PI/1300?AMFM_FREQUENCY=102100
    • AM(탐색 가능, 재생 가능)
      EXTRA_BCRADIO_FOLDER_TYPE=BCRADIO_FOLDER_TYPE_BAND
      EXTRA_BCRADIO_BAND_NAME_EN="AM"
      • 530 AM(재생 가능)
        URI: broadcastradio://program/AMFM_FREQUENCY/530
      • 540 AM(재생 가능)
        URI: broadcastradio://program/AMFM_FREQUENCY/540
      • 550 AM(재생 가능)
        URI: broadcastradio://program/AMFM_FREQUENCY/550
    • FM(탐색 가능, 재생 가능)
      EXTRA_BCRADIO_FOLDER_TYPE=BCRADIO_FOLDER_TYPE_BAND
      EXTRA_BCRADIO_BAND_NAME_EN="FM"
      • 87.7 FM(재생 가능)
        URI: broadcastradio://program/AMFM_FREQUENCY/87700
      • 87.9 FM(재생 가능)
        URI: broadcastradio://program/AMFM_FREQUENCY/87900
      • 88.1 FM(재생 가능)
        URI: broadcastradio://program/AMFM_FREQUENCY/88100
    • DAB(재생 가능)
      EXTRA_BCRADIO_FOLDER_TYPE=BCRADIO_FOLDER_TYPE_BAND
      EXTRA_BCRADIO_BAND_NAME_EN="DAB"

    오디오 CD MediaBrowserService(ACTION_PLAY_AUDIOCD 처리)

    • 디스크 1(재생 가능)
      EXTRA_CD_DISK=1
    • 디스크 2(탐색 가능, 재생 가능)
      EXTRA_CD_DISK=2
      • 트랙 1(재생 가능)
        EXTRA_CD_TRACK=1
      • 트랙 2(재생 가능)
        EXTRA_CD_TRACK=2
    • 내 음악 CD(탐색 가능, 재생 가능)
      EXTRA_CD_DISK=3
      • All By Myself(재생 가능)
        EXTRA_CD_TRACK=1
      • Reise, Reise(재생 가능)
        EXTRA_CD_TRACK=2
    • 빈 슬롯 4(재생 불가)
      EXTRA_CD_DISK=4

    AUX MediaBrowserService(ACTION_PLAY_AUX 처리)

    • AUX front(재생 가능)
      EXTRA_AUX_PORT_NAME="front"
    • AUX rear(재생 가능)
      EXTRA_AUX_PORT_NAME="rear"