Auf dieser Seite wird erläutert, wie Funk auf Hardware- und Softwareebene implementiert wird.
- Systemkomponenten veranschaulichen und beschreiben den Funktechnologie-Stack.
- Die Rundfunk-Hardware-Abstraktionsschicht (HAL) bietet OEMs Datenstrukturen und Schnittstellen, um Rundfunk wie AM/FM und Digital Audio Broadcasting (DAB) auf Hardwareebene zu implementieren.
- Die Implementierung der Radiosteuerung basiert auf
MediaSession
undMediaBrowse
, die es Medien- und Sprachassistenten-Apps ermöglichen, das Radio zu steuern. Zusätzlich zu den unten bereitgestellten Inhalten finden Sie weitere Informationen unter „Erstellen von Medien-Apps für Autos“ .
Systemkomponenten
Der Broadcast-Radio-Stack umfasst die folgenden Komponenten.
Radio-Referenz-App
Einzelheiten zur Implementierung der Funksteuerung finden Sie unter Implementierung der Funksteuerung .
Als Referenzimplementierung dient eine Beispiel-Java-Radio-App ( packages/apps/Car/Radio
). Wenn der App-Dienst startet, fordert er Radio Manager auf, einen Radio-Tuner zu öffnen. Anschließend kann die App Anfragen an den Radio-Tuner senden, z. B. die Einstellung eines bestimmten Radiosenders oder einer bestimmten Frequenz oder die Suche nach dem nächsten verfügbaren Radiosender. Die App empfängt Aktualisierungen vom Radio Manager und Radio Tuner im Radio, z. B. aktuelle Programminformationen, Radioprogrammlisten, Konfigurationen und vom Hersteller definierte Parameter. Die Referenzradio-App unterstützt nur AM- und FM-Radio. OEMs können die Radio-App nach Wunsch modifizieren oder ersetzen.
Radiomanager
Wenn die App Radio Manager auffordert, einen Tuner zu öffnen, fordert der Radio Manager ( frameworks/base/core/java/android/hardware/radio/RadioManager.java
) den Broadcast Radio Service auf, eine Tuner-Sitzung zu öffnen, und schließt die Sitzung dann in eine ein Radio-Tuner ( frameworks/base/core/java/android/hardware/radio/RadioTuner.java
), der an die App zurückgegeben wird. Der Radio-Tuner definiert APIs (wie Tune, Step und Cancel), die von Radio-Apps aufgerufen werden können und Anfragen an den Broadcast Radio Service senden. In Radio Tuner definierte Rückrufmethoden ( RadioTuner.Callback
) senden Aktualisierungen zum Rundfunk-HAL, z. B. aktuelle Programminformationen, Programmlisten und vom Hersteller definierte Parameter, vom Rundfunkdienst an Apps.
Rundfunkdienst
Der Broadcast Radio Service ( frameworks/base/services/core/java/com/android/server/broadcastradio
) ist der Client-Service für Broadcast Radio HAL. Der Broadcast Radio Service koordiniert mehrere Radiomanager mit Broadcast Radio HALs. Der Broadcast Radio Service unterstützt Rundfunk-HALs der HAL Interface Definition Language (HIDL) und der Android Interface Definition Language (AIDL) . Der Broadcast Radio Service stellt eine Verbindung zum AIDL HAL her, wenn ein AIDL HAL-Dienst vorhanden ist. Andernfalls wird der Dienst mit dem HIDL HAL verknüpft. Der Broadcast Radio Service erstellt ein Radiomodul für jede verfügbare HAL-Instanz (z. B. AM, FM und DAB).
Jeder Radiomanager kann den Broadcast Radio Service auffordern, je nach Radiotyp eine Tuner-Sitzung auf dem entsprechenden Radiomodul zu erstellen. Jede Tuner-Sitzung kann Methoden wie „tune“, „step“ und „cancel“ (definiert in HAL-Schnittstellen) aufrufen, um Vorgänge auf der entsprechenden Rundfunk-HAL-Instanz auszuführen. Wenn eine Tuner-Sitzung einen Rückruf von der HAL-Instanz zu einem HAL-Update erhält, z. B. aktuelle Programminformationen, Programmliste, Konfigurationsflags und Herstellerparameter, werden Rückrufe zum Update an alle Radio-Tuner gesendet, die mit demselben Radiomodul verbunden sind.
Rundfunkradio HAL
Weitere Informationen zu den HIDL- und AIDL-Schnittstellen des Rundfunks und den Unterschieden zwischen beiden finden Sie unter HAL-Schnittstelle für Rundfunk .
Hardware-Abstraktionsschicht für Rundfunk
In den folgenden Abschnitten wird beschrieben, wie Sie mit der Hardware-Abstraktionsschicht (HAL) arbeiten, um Rundfunk zu implementieren.
HAL-Schnittstelle für Rundfunkradio
Der Rundfunkradio-HAL stellt Datenstrukturen und Schnittstellen auf Hardwareebene zur Implementierung von Rundfunkradios wie AM/FM- und DAB-Radio bereit.
HIDL 2.0- und AIDL-Schnittstellen
Das Rundfunkradio HAL nutzt die in den folgenden Abschnitten beschriebenen Schnittstellen.
Ansage-Hörer
IAnnouncementListener
ist die Rückrufschnittstelle für den Ansage-Listener, der bei Radio HAL registriert werden kann, um Ansagen zu empfangen. Die Schnittstelle verfügt über die folgenden Methoden:
IAnnouncementListener | ||
---|---|---|
Beschreibung: Wird immer dann aufgerufen, wenn sich die Ankündigungsliste geändert hat. | ||
HIDL 2.0 | oneway onListUpdated(vec<Announcement> announcements) | |
AIDL | oneway void onListUpdated(in Announcement[] announcements) |
Griff schließen
ICloseHandle
ist das generische Schließhandle zum Entfernen eines Rückrufs, der keine aktive Schnittstelle benötigt.
ICloseHandle | ||
---|---|---|
Beschreibung: Den Griff schließen. | ||
HIDL 2.0 | close() | |
AIDL | void close() |
Rückrufschnittstelle
ITunerCallback
ist die Rückrufschnittstelle, die vom Rundfunksender HAL aufgerufen wird, um Aktualisierungen an den HAL-Clientdienst zu senden.
ITunerCallback | ||
---|---|---|
Beschreibung: Wird von der HAL aufgerufen, wenn ein Optimierungsvorgang (Abstimmen, Suchen (in AIDL) oder Scannen (in HIDL) und Schritt erfolgreich) asynchron fehlschlägt. | ||
HIDL 2.0 | oneway onCurrentProgramInfoChanged(ProgramInfo info) | |
AIDL | void onCurrentProgramInfoChanged(in ProgramInfo info) | |
Beschreibung: Wird aufgerufen, wenn die Optimierung, Suche (in AIDL) oder Suche (in HIDL) oder ein Schritt erfolgreich ist. | ||
HIDL 2.0 | oneway onTuneFailed(Result result, ProgramSelector selector) | |
AIDL | void onTuneFailed(in Result result, in ProgramSelector selector) | |
Beschreibung: Wird aufgerufen, wenn die Optimierung, Suche (in AIDL) oder Suche (in HIDL) oder ein Schritt erfolgreich ist. | ||
HIDL 2.0 | oneway onCurrentProgramInfoChanged(ProgramInfo info) | |
AIDL | void onCurrentProgramInfoChanged(in ProgramInfo info) | |
Beschreibung: Wird aufgerufen, wenn die Programmliste aktualisiert wird. Die Größe jedes Blocks sollte auf 500 KB begrenzt sein. | ||
HIDL 2.0 | oneway onProgramListUpdated(ProgramListChunk chunk) | |
AIDL | oneway onProgramListUpdated(ProgramListChunk chunk) | |
Beschreibung: Wird aufgerufen, wenn die Antenne angeschlossen oder getrennt ist. | ||
HIDL 2.0 | oneway onAntennaStateChange(bool connected) | |
AIDL | void onCurrentProgramInfoChanged(in ProgramInfo info) | |
Beschreibung: Wird aufgerufen, wenn die herstellerspezifischen Parameterwerte in HAL intern aktualisiert werden (sollte nicht nach dem Aufruf von setParameters durch den HAL-Client aufgerufen werden). | ||
HIDL 2.0 | oneway onParametersUpdated(vec<VendorKeyValue> parameters) | |
AIDL | void onParametersUpdated(in VendorKeyValue[] parameters) | |
Beschreibung: Neu in AIDL. Wird aufgerufen, wenn das Konfigurationsflag intern in der HAL aktualisiert wird (sollte nicht nach dem Aufruf von setConfigFlag durch den HAL-Client aufgerufen werden). | ||
HIDL 2.0 | Unzutreffend. | |
AIDL | void onConfigFlagUpdated(in ConfigFlag flag, in boolean value) |
Primäre Rundfunk-HAL-Schnittstelle
IBroadcastRadio
ist die primäre Schnittstelle für das Rundfunkradio HAL. Verwenden Sie im HIDL 2.0 HAL die ITunerSession
Schnittstelle zum Tuner, um Vorgänge aufzurufen. Es ist jedoch höchstens ein Tuner gleichzeitig aktiv (vorausgesetzt, jede Rundfunk-HAL-Instanz verfügt nur über einen Tuner-Chip). ITunerSession
wurde aus den AIDL-Schnittstellen entfernt und seine Schnittstellen nach IBroadcastRadio
verschoben.
IBroadcastRadio | ||
---|---|---|
Beschreibung: Rufen Sie die Beschreibung eines Moduls und seiner Funktionen ab. | ||
HIDL 2.0 | getProperties() generates (Properties properties) | |
AIDL | Properties getProperties() | |
Beschreibung: Ruft die aktuelle oder mögliche AM/FM-Regionskonfiguration ab. | ||
HIDL 2.0 | getAmFmRegionConfig(bool full) generates (Result result, AmFmRegionConfig config) | |
AIDL | AmFmRegionConfig getAmFmRegionConfig(bool full) | |
Beschreibung: Ruft die aktuelle DAB-Regionskonfiguration ab. | ||
HIDL 2.0 | getDabRegionConfig() generates (Result result, vec<DabTableEntry> config) | |
AIDL | DabTableEntry[] getDabRegionConfig() | |
Beschreibung: Ruft ein Bild aus dem Funkmodul-Cache ab. In AIDL muss die Bildgröße aufgrund einer harten Begrenzung des Binder-Transaktionspuffers weniger als 1 MB betragen. | ||
HIDL 2.0 | getImage(uint32_t id) generates (vec<uint8_t> image) | |
AIDL | byte[] getImage(in int id) | |
Beschreibung: Registriert den Ansage-Listener. | ||
HIDL 2.0 | registerAnnouncementListener(vec<AnnouncementType> enabled,IAnnouncementListener listener) generates (Result result, ICloseHandle closeHandle) | |
AIDL | ICloseHandle registerAnnouncementListener(in IAnnouncementListener listener, in AnnouncementType[] enabled) | |
Beschreibung:
| ||
HIDL 2.0 | openSession(ITunerCallback callback) generiert (Result result, ITunerSession session) | |
AIDL | void setTunerCallback(in ITunerCallback callback) | |
Beschreibung:
| ||
HIDL 2.0 | close() | |
AIDL | unsetTunerCallback() | |
Beschreibung: Stellt ein bestimmtes Programm ein. | ||
HIDL 2.0 | tune(ProgramSelector program) generates (Result result) | |
AIDL | void tune(in ProgramSelector program) | |
Beschreibung: Sucht nach dem nächsten gültigen ausgestrahlten Programm. Um Verwirrung in AIDL zu vermeiden, wird scan in seek umbenannt. | ||
HIDL 2.0 | scan(bool directionUp, bool skipSubChannel) generates (Result result) | |
AIDL | void seek(in boolean directionUp, in boolean skipSubChannel) | |
Beschreibung: Schritte zum Nachbarkanal, der von keinem Programm belegt sein darf. | ||
HIDL 2.0 | step(bool directionUp) generates (Result result) | |
AIDL | void step(in boolean directionUp) | |
Beschreibung: Bricht ausstehende Optimierungs-, Scan- (in HIDL) oder Such- (in AIDL) oder Schrittoperationen ab. | ||
HIDL 2.0 | cancel() | |
AIDL | void cancel() | |
Beschreibung: Wendet einen Filter auf die Programmliste an und beginnt mit dem Senden von Programmlistenaktualisierungen über onProgramListUpdated Rückruf. | ||
HIDL 2.0 | startProgramListUpdates(ProgramFilter filter) generates (Result result) | |
AIDL | void startProgramListUpdates(in ProgramFilter filter) | |
Beschreibung: Das Senden von Aktualisierungen der Programmliste wird gestoppt. | ||
HIDL 2.0 | stopProgramListUpdates() | |
AIDL | void stopProgramListUpdates() | |
Beschreibung: Ruft die aktuelle Einstellung eines bestimmten Konfigurationsflags ab. | ||
HIDL 2.0 | isConfigFlagSet(ConfigFlag flag) generates (Result result, bool value) | |
AIDL | boolean isConfigFlagSet(in ConfigFlag flag) | |
Beschreibung: Setzt das angegebene Konfigurationsflag. | ||
HIDL 2.0 | setConfigFlag(ConfigFlag flag, bool value) generates (Result result) | |
AIDL | void setConfigFlag(in ConfigFlag flag, boolean value) | |
Beschreibung: Legt herstellerspezifische Parameterwerte fest. | ||
HIDL 2.0 | setParameters(vec<VendorKeyValue> parameters) erzeugt , (vec<VendorKeyValue> results) | |
AIDL | VendorKeyValue[] setParameters(in VendorKeyValue[] parameters) | |
Beschreibung: Ruft herstellerspezifische Parameterwerte ab. | ||
HIDL 2.0 | getParameters(vec<string> keys) generates (vec<VendorKeyValue> parameters) | |
AIDL | VendorKeyValue[] getParameters(in String[] keys) |
Erläuterungen zur Schnittstelle
Asynchrones Verhalten
Da jeder Optimierungsvorgang (z. B. Optimierung, Scan (in HIDL) oder Suche (in AIDL) und Schritt) zeitaufwändig sein kann und der Thread nicht für längere Zeit blockiert werden sollte, sollte der Vorgang zeitaufwändige Vorgänge einplanen später auftreten und schnell einen Status oder ein Ergebnis zurückgeben. Im Einzelnen sollte jeder Vorgang:
- Brechen Sie alle ausstehenden Tuning-Vorgänge ab.
- Überprüfen Sie, ob der Vorgang basierend auf den Methodeneingaben und dem Status des Tuners verarbeitet werden kann.
- Planen Sie die Optimierungsaufgabe und geben Sie dann sofort das
Result
(in HIDL) oderstatus
(in AIDL) zurück. Wenn dasResult
oderstatus
OK
ist, muss der Tuner-RückruftuneFailed
odercurrentProgramInfoChanged
aufgerufen werden, wenn die Optimierungsaufgabe fehlgeschlagen ist (z. B. aufgrund einer Zeitüberschreitung) oder abgeschlossen ist.
In ähnlicher Weise plant startProgramListUpdates
auch die zeitaufwändige Aufgabe, die Programmliste zu einem späteren Zeitpunkt zu aktualisieren und schnell einen Status oder ein Ergebnis zurückzugeben. Die Methode bricht zunächst ausstehende Aktualisierungsanfragen ab, plant dann die Aktualisierungsaufgabe und gibt das Ergebnis schnell zurück.
Rennbedingung
Aufgrund des asynchronen Verhaltens von Optimierungsvorgängen (z. B. „Tune“, „Scan“ (in HIDL) oder „Seek“ (in AIDL) und „Step“) besteht eine Wettlaufbedingung zwischen dem Abbrechen des Vorgangs und den Optimierungsvorgängen. Wenn cancel
aufgerufen wird, nachdem HAL einen Optimierungsvorgang abgeschlossen hat und bevor der Rückruf abgeschlossen ist, kann „Cancel“ ignoriert werden und der Rückruf sollte abgeschlossen und vom HAL-Client empfangen werden.
Wenn stopProgramListUpdates
aufgerufen wird, nachdem die HAL eine Programmlistenaktualisierung abgeschlossen hat und bevor der onCurrentProgramInfoChanged
Rückruf abgeschlossen ist, kann stopProgramListUpdates
ebenfalls ignoriert werden und der Rückruf sollte abgeschlossen werden.
Beschränkung der Datengröße
Da es eine feste Grenze für den Binder-Transaktionspuffer gibt, wird die Datengrenze für einige Schnittstellenmethoden, die potenziell große Daten weitergeben, in der AIDL-HAL klargestellt.
-
getImage
ist es erforderlich, dass das zurückgegebene Bild weniger als 1 MB groß ist. -
onProgramListUpdate
erfordert, dass jederchunk
weniger als 500 KB groß ist. Größere Programmlisten müssen von der HAL-Implementierung in mehrere Blöcke aufgeteilt und über mehrere Rückrufe gesendet werden.
Änderungen in AIDL HAL-Datenstrukturen
Zusätzlich zu den Änderungen an den Schnittstellen wurden diese Änderungen auf die im Rundfunk-AIDL HAL definierten Datenstrukturen angewendet, die die Vorteile von AIDL nutzen.
- Die
Constant
Aufzählung wird in AIDL entfernt und inIBroadcastRadio
als const int definiert. In der Zwischenzeit wirdANTENNA_DISCONNECTED_TIMEOUT_MS
inANTENNA_STATE_CHANGE_TIMEOUT_MS
umbenannt. Eine neue Konstante intTUNER_TIMEOUT_MS
wird hinzugefügt. Alle Abstimmungs-, Such- und Schrittvorgänge müssen innerhalb dieser Zeit abgeschlossen sein. - Enum
RDS
undDeemphasis
werden in AIDL entfernt und als const int inAmFmRegionConfig
definiert. Dementsprechend werden sowohlfmDeemphasis
als auchfmRds
inProgramInfo
als int deklariert, ein Bitberechnungsergebnis der jeweiligen Flags. Inzwischen werdenD50
undD75
inDEEMPHASIS_D50
bzw.DEEMPHASIS_D75
umbenannt. - Enum
ProgramInfoFlags
werden in AIDL entfernt und als const int inProgramInfo
mit einem hinzugefügten PräfixFLAG_
definiert. Dementsprechend werdeninfoFlags
inProgramInfo
als int deklariert, ein Bitberechnungsergebnis von Flags.TUNED
wird außerdem inFLAG_TUNABLE
umbenannt, um die Definition, auf die der Sender eingestellt werden kann, besser zu beschreiben. - In
AmFmBandRange
wirdscanSpacing
inseekSpacing
“ umbenannt, da „scan
in AIDL in „seek
umbenannt wird. - Da das Konzept der Vereinigung in AIDL eingeführt wurde, werden
MetadataKey
undMetadata
die in HIDL HAL definiert sind, nicht mehr verwendet. AIDL-UnionMetadata
werden in AIDL HAL definiert. Jeder Enumerationswert, der zuvor inMetadataKey
enthalten war, ist jetzt ein Feld inMetadata
mit dem Typ „String“ oder „Int“, je nach Definition.
Implementierung der Funksteuerung
Die Implementierung der Radiosteuerung basiert auf MediaSession
und MediaBrowse
, die es Medien- und Sprachassistenten-Apps ermöglichen, das Radio zu steuern. Weitere Informationen finden Sie unter Erstellen von Medien-Apps für Autos auf Developer.android.com.
Eine Implementierung des Mediensuchbaums wird in der Bibliothek car-broadcastradio-support in packages/apps/Car/libs
bereitgestellt. Diese Bibliothek enthält auch Erweiterungen von ProgramSelector zum Konvertieren in und von URI. Es wird empfohlen, dass Radioimplementierungen diese Bibliothek verwenden, um den zugehörigen Suchbaum zu erstellen.
Medienquellen-Umschalter
Um einen nahtlosen Übergang zwischen Radio und anderen in Medien angezeigten Apps zu ermöglichen, enthält die car-media-common-Bibliothek Klassen, die in die Radio-App integriert werden sollen. MediaAppSelectorWidget
kann in das XML für die Radio-App eingefügt werden (das Symbol und die Dropdown-Liste, die in den Referenzmedien- und Radio-Apps verwendet werden):
<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" />
Dieses Widget startet das AppSelectionFragment
, das eine Liste der Medienquellen anzeigt, zu denen gewechselt werden kann. Wenn eine andere als die bereitgestellte Benutzeroberfläche gewünscht wird, können Sie ein benutzerdefiniertes Widget erstellen, um das AppSelectionFragment
zu starten, wenn der Umschalter angezeigt werden soll.
AppSelectionFragment newFragment = AppSelectionFragment.create(widget, packageName, fullScreen); newFragment.show(mActivity.getSupportFragmentManager(), null);
Eine Beispielimplementierung wird in der Referenz-Radio-App-Implementierung bereitgestellt, die sich unter packages/apps/Car/Radio
befindet.
Detaillierte Kontrollspezifikationen
Die MediaSession
Schnittstelle (über MediaSession.Callback
) bietet Steuerungsmechanismen für das aktuell wiedergegebene Radioprogramm:
-
onPlay
,onStop
. Stummschaltung der Radiowiedergabe aufheben. -
onPause
. Zeitversetzte Pause (sofern unterstützt). -
onPlayFromMediaId
. Spielen Sie beliebige Inhalte aus einem Ordner der obersten Ebene ab. Zum Beispiel „FM abspielen“ oder „Radio abspielen“. -
onPlayFromUri
. Spielen Sie eine bestimmte Frequenz. Beispiel: „Spielen Sie 88,5 FM.“ -
onSkipToNext
,onSkipToPrevious
. Stellen Sie einen nächsten oder vorherigen Sender ein. -
onSetRating
. Zu Favoriten hinzufügen oder daraus entfernen.
Der MediaBrowser stellt ein anpassbares MediaItem über drei Arten von Verzeichnissen der obersten Ebene bereit:
- ( Optional ) Programme (Sender). Dieser Modus wird typischerweise von Dual-Tuner-Radios verwendet, um alle verfügbaren abstimmbaren Radiosender am Standort des Benutzers anzuzeigen.
- Favoriten. Zur Favoritenliste hinzugefügte Radioprogramme, einige sind möglicherweise nicht verfügbar (außerhalb des Empfangsbereichs).
- Bandkanäle. Alle physikalisch möglichen Kanäle in der aktuellen Region (87,9, 88,1, 88,3, 88,5, 88,7, 88,9, 89,1 usw.). Jede Band verfügt über ein eigenes Top-Level-Verzeichnis.
Jedes Element in jedem dieser Ordner (AM/FM/Programme) ist ein MediaItem mit einem URI, das mit MediaSession zur Optimierung verwendet werden kann. Jeder Ordner der obersten Ebene (AM/FM/Programme) ist ein MediaItem mit einer mediaId, die mit MediaSession zum Auslösen der Wiedergabe verwendet werden kann und im Ermessen des OEM liegt. Beispielsweise sind „FM abspielen“, „AM abspielen“ und „Radio abspielen“ allesamt unspezifische Radioabfragen, die eine mediaId verwenden, um sie an die OEM-Radio-App zu senden. Es liegt an der Radio-App, anhand der generischen Anfrage und der mediaId zu bestimmen, was abgespielt werden soll.
Mediensitzung
Da es kein Konzept zum Anhalten eines Sendestreams gibt, gelten die Aktionen „Wiedergabe“, „Pause“ und „Stopp“ nicht immer für Radio. Beim Radio ist die Stop-Aktion mit dem Stummschalten des Streams verbunden, während Play mit dem Aufheben der Stummschaltung verbunden ist.
Einige Radiotuner (oder Apps) bieten die Möglichkeit, eine Pause des Sendestreams zu simulieren, indem Inhalte zwischengespeichert und später wiedergegeben werden. Verwenden Sie in solchen Fällen onPause
.
Das Abspielen von mediaId- und URI-Aktionen soll dazu dienen, einen Sender anzuhören, der von der MediaBrowser-Schnittstelle abgerufen wurde. Die mediaId ist eine beliebige Zeichenfolge, die von der Radio-App bereitgestellt wird, um einen eindeutigen (eine bestimmte ID verweist also nur auf ein Element) und einen stabilen (ein bestimmtes Element hat während der gesamten Sitzung dieselbe ID) Wert festzulegen, mit dem ein bestimmter Sender identifiziert werden kann . Der URI hat ein klar definiertes Schema. Kurz gesagt, eine URI-isierte Form von ProgramSelector. Während dadurch die Eindeutigkeitseigenschaft erhalten bleibt, muss sie nicht stabil sein, obwohl sie sich ändern kann, wenn die Station auf eine andere Frequenz wechselt.
onPlayFromSearch
wird konstruktionsbedingt nicht verwendet. Es liegt in der Verantwortung des Clients (Begleit-App), ein Suchergebnis aus der MediaBrowser-Struktur auszuwählen. Die Verlagerung dieser Verantwortung auf die Radio-App würde die Komplexität erhöhen, formelle Verträge darüber erfordern, wie Zeichenfolgenabfragen aussehen sollen, und zu einer ungleichmäßigen Benutzererfahrung auf verschiedenen Hardwareplattformen führen.
Hinweis: Die Radio-App enthält keine zusätzlichen Informationen, die für die Suche nach einem Sendernamen nützlich wären, der dem Client nicht über die MediaBrowser-Schnittstelle angezeigt wird.
Das Springen zum nächsten oder vorherigen Sender hängt vom aktuellen Kontext ab:
- Wenn eine App auf einen Sender aus der Favoritenliste eingestellt ist, kann die App zum nächsten Sender aus der Favoritenliste wechseln.
- Wenn Sie einen Sender aus der Programmliste anhören, wird möglicherweise der nächste verfügbare Sender eingestellt, sortiert nach der Kanalnummer.
- Das Anhören eines beliebigen Kanals kann dazu führen, dass auf den nächsten physischen Kanal umgeschaltet wird, selbst wenn kein Sendesignal vorhanden ist.
Die Radio-App übernimmt diese Aktionen.
Fehlerbehandlung
TransportControls
Aktionen (Wiedergabe, Stopp und Weiter) geben kein Feedback darüber, ob die Aktion erfolgreich ist oder nicht. Die einzige Möglichkeit, einen Fehler anzuzeigen, besteht darin, den MediaSession-Status mit einer Fehlermeldung auf STATE_ERROR
zu setzen.
Die Radio-App muss diese Aktionen verarbeiten und sie entweder ausführen oder einen Fehlerstatus festlegen. Wenn die Ausführung des Wiedergabebefehls nicht sofort erfolgt, sollte der Wiedergabestatus während der Ausführung des Befehls in STATE_CONNECTING
(bei direkter Abstimmung) oder STATE_SKIPPING_TO_PREVIOUS
oder NEXT
geändert werden.
Der Client sollte den PlaybackState
beobachten und überprüfen, ob die Sitzung das aktuelle Programm in den angeforderten Zustand geändert oder in den Fehlerstatus versetzt hat. STATE_CONNECTING
darf 30 Sekunden nicht überschreiten. Eine direkte Abstimmung auf eine bestimmte AM/FM-Frequenz sollte jedoch viel schneller erfolgen.
Favoriten hinzufügen und entfernen
MediaSession verfügt über eine Bewertungsunterstützung, mit der Favoriten gesteuert werden können. Der Aufruf onSetRating
mit einer Bewertung vom Typ RATING_HEART
fügt den aktuell eingestellten Sender zur Favoritenliste hinzu oder entfernt ihn daraus.
Im Gegensatz zu älteren Voreinstellungen geht dieses Modell von einer ungeordneten und unbegrenzten Favoritenliste aus, bei der jeder gespeicherte Favorit einem numerischen Feld (normalerweise 1 bis 6) zugewiesen wurde. Infolgedessen wären voreingestellte Systeme nicht mit dem onSetRating
Vorgang kompatibel.
Die Einschränkung der MediaSession-API besteht darin, dass nur der aktuell eingestellte Sender hinzugefügt oder entfernt werden kann. Beispielsweise müssen Elemente zuerst ausgewählt werden, bevor sie entfernt werden können. Dies ist lediglich eine Einschränkung des MediaBrowser-Clients, beispielsweise einer Begleit-App. Die Radio-App unterliegt keinen derartigen Einschränkungen. Dieser Teil ist optional, wenn eine App keine Favoriten unterstützt.
MediaBrowser
Um auszudrücken, welche Frequenzen oder physikalischen Kanalnamen (wenn die Abstimmung auf einen beliebigen Kanal für eine bestimmte Funktechnologie geeignet ist) für eine bestimmte Region gültig sind, werden alle gültigen Kanäle (Frequenzen) für jedes Band aufgelistet. In der US-Region sind dies 101 FM-Kanäle im Bereich von 87,8 bis 108,0 MHz (mit einem Abstand von 0,2 MHz) und 117 AM-Kanäle im Bereich von 530 bis 1700 kHz (mit einem Abstand von 10 kHz). Da HD-Radio denselben Kanalraum nutzt, wird es nicht separat dargestellt.
Die Liste der derzeit verfügbaren Radioprogramme ist flach, da Anzeigeschemata wie die Gruppierung nach DAB-Ensemble (Direct Audio Broadcast) nicht möglich sind.
Einträge in der Favoritenliste können möglicherweise nicht angepasst werden. Zum Beispiel, wenn ein bestimmtes Programm außerhalb des zulässigen Bereichs liegt. Die Radio-App erkennt möglicherweise bereits im Voraus, ob der Eintrag eingestellt werden kann. Wenn dies der Fall ist, wird der Eintrag möglicherweise nicht als spielbar markiert.
Um Ordner der obersten Ebene zu identifizieren, wird der gleiche Mechanismus wie bei Bluetooth angewendet. Das heißt, ein Extras-Bundle des MediaDescription
Objekts enthält ein Tuner-spezifisches Feld, genau wie Bluetooth es mit EXTRA_BT_FOLDER_TYPE
tut. Im Falle des Rundfunks führt dies zur Definition der folgenden neuen Felder in der öffentlichen API:
-
EXTRA_BCRADIO_FOLDER_TYPE = "android.media.extra.EXTRA_BCRADIO_FOLDER_TYPE"
. Einer der folgenden Werte:-
BCRADIO_FOLDER_TYPE_PROGRAMS = 1
. Derzeit verfügbare Programme. -
BCRADIO_FOLDER_TYPE_FAVORITES = 2
. Favoriten. -
BCRADIO_FOLDER_TYPE_BAND = 3
. Alle physischen Kanäle für ein bestimmtes Band.
Es ist nicht erforderlich, radiospezifische benutzerdefinierte Metadatenfelder zu definieren, da alle relevanten Daten in das vorhandene
MediaBrowser.MediaItem
Schema passen:- Programmname (RDS PS, DAB-Dienstname).
MediaDescription.getTitle
. - FM-Frequenz. URI (siehe ProgramSelector ) oder
MediaDescription.getTitle
(wenn sich ein Eintrag im OrdnerBROADCASTRADIO_FOLDER_TYPE_BAND
befindet). - Radiospezifische Kennungen (RDS PI, DAB SId).
MediaDescription.getMediaUri
wird in ProgramSelector analysiert.
Normalerweise ist es nicht erforderlich, die FM-Frequenz für einen Eintrag im aktuellen Programm oder in der Favoritenliste abzurufen (da der Client mit Medien-IDs arbeiten sollte). Sollte jedoch ein solcher Bedarf bestehen (z. B. zu Anzeigezwecken), ist er im URI vorhanden und kann in
ProgramSelector
analysiert werden. Es wird jedoch nicht empfohlen, den URI zum Auswählen von Elementen innerhalb der aktuellen Sitzung zu verwenden. Einzelheiten finden Sie unterProgramSelector
.Um Leistungs- oder Ordnerprobleme zu vermeiden, muss der MediaBrowser-Dienst die Paginierung unterstützen:
-
EXTRA_PAGE
-
EXTRA_PAGE_SIZE
- Zusätzliche Parameter für
subscribe()
Hinweis: Standardmäßig wird die Paginierung standardmäßig in der Variante
onLoadChildren()
ohne Optionsbehandlung implementiert.Verwandte Einträge aus allen Arten von Listen (Rohkanäle, gefundene Programme und Favoriten) können unterschiedliche Medien-IDs haben (es liegt an der Radio-App; die Support-Bibliothek wird sie unterschiedlich haben). Die URIs (in ProgramSelector-Form) unterscheiden sich in den meisten Fällen zwischen Rohkanälen und gefundenen Programmen (außer bei FM ohne RDS), sind jedoch zwischen gefundenen Programmen und Favoriten größtenteils gleich (außer beispielsweise, als AF aktualisiert wurde).
Durch unterschiedliche Medien-IDs für Einträge aus verschiedenen Listentypen ist es möglich, unterschiedliche Aktionen für diese durchzuführen. Sie können entweder die Favoritenliste oder die Liste „Alle Programme“ auf
onSkipToNext
durchsuchen, abhängig vom Ordner des zuletzt ausgewähltenMediaItem
(siehe MediaSession ).Spezielle Tune-Aktionen
Mit der Programmliste können Benutzer einen bestimmten Sender einstellen, aber keine allgemeinen Anfragen wie „FM einstellen“ stellen, was dazu führen könnte, dass ein kürzlich gehörter Sender im UKW-Band eingestellt wird.
Um solche Aktionen zu unterstützen, ist in einigen Verzeichnissen der obersten Ebene das Flag
FLAG_PLAYABLE
gesetzt (zusammen mitFLAG_BROWSABLE
für Ordner).Aktion Melodien zu So stellen Sie es aus Radio spielen Jeder Radiosender startService(ACTION_PLAY_BROADCASTRADIO)
oder
playFromMediaId(MediaBrowser. getRoot() )
Spielen Sie UKW Jeder FM-Kanal Spielen Sie von der mediaId
des FM-Bands.Die Entscheidung, welches Programm eingestellt werden soll, obliegt der App. Dies ist normalerweise der zuletzt eingestellte Kanal aus der angegebenen Liste. Einzelheiten zu
ACTION_PLAY_BROADCASTRADIO
finden Sie unter Allgemeine Spielabsichten .Discovery- und Service-Verbindung
PackageManager
kann den MediaBrowserService, der den Broadcast-Radio-Baum bereitstellt, direkt finden. Rufen Sie dazuresolveService
mit der AbsichtACTION_PLAY_BROADCASTRADIO
“ (siehe „Allgemeine Spielabsichten “) und dem Flag „MATCH_SYSTEM_ONLY
“ auf. Verwenden SiequeryIntentServices
um alle Dienste zu finden, die Radio bereitstellen (es kann mehr als einen geben, z. B. getrennte AM/FM- und Satellitendienste).Der aufgelöste Dienst verarbeitet auch die Bindungsabsicht
android.media.browse.MediaBrowserService
. Dies wird mit GTS überprüft.Um eine Verbindung zum ausgewählten MediaBrowserService herzustellen, erstellen Sie
MediaBrowser
Instanz für eine bestimmte Dienstkomponente undconnect
. Nach dem Verbindungsaufbau kann übergetSessionToken
ein Handle zu MediaSession abgerufen werden.Die Radio-App kann Client-Pakete einschränken, die in einer
onGetRoot
Implementierung ihres Dienstes eine Verbindung herstellen dürfen. Die App sollte es System-Apps ermöglichen, eine Verbindung ohne Whitelisting herzustellen. Einzelheiten zum Whitelisting finden Sie unter Akzeptieren des Assistant-App-Pakets und der Signatur .Wenn die quellenspezifische App (z. B. eine Radio-App) auf einem Gerät ohne solche Quellenunterstützung installiert wird, würde sie sich immer noch als die Absicht
ACTION_PLAY_BROADCASTRADIO
verarbeitend ankündigen, ihr MediaBrowser-Baum würde jedoch keine radiospezifischen Tags enthalten. Daher muss ein Client, der prüfen möchte, ob eine bestimmte Quelle auf einem Gerät verfügbar ist:- Entdecken Sie den Radiodienst (rufen Sie
resolveService
fürACTION_PLAY_BROADCASTRADIO
auf). - Erstellen Sie
MediaBrowser
und stellen Sie dann eine Verbindung her. - Bestimmen Sie das Vorhandensein von
MediaItem
mit dem ZusatzEXTRA_BCRADIO_FOLDER_TYPE
.
Hinweis: In den meisten Fällen muss der Client alle verfügbaren MediaBrowser-Bäume scannen, um alle verfügbaren Quellen für ein bestimmtes Gerät zu erkennen.
Bandnamen
Die Bandliste wird durch eine Reihe von Verzeichnissen der obersten Ebene dargestellt, wobei das Ordnertyp-Tag auf
BCRADIO_FOLDER_TYPE_BAND
festgelegt ist. Die Titel ihrerMediaItem
sind lokalisierte Zeichenfolgen, die Bandnamen darstellen. In den meisten Fällen handelt es sich um dasselbe wie eine englische Übersetzung, aber der Kunde kann sich nicht auf diese Annahme verlassen.Um einen stabilen Mechanismus zum Nachschlagen bestimmter Bands bereitzustellen, wird ein zusätzlicher Tag für Bandordner hinzugefügt,
EXTRA_BCRADIO_BAND_NAME_EN
. Dies ist ein nicht lokalisierter Name des Bandes und kann nur einen dieser vordefinierten Werte annehmen:-
AM
-
FM
-
DAB
Wenn die Band nicht auf dieser Liste steht, sollte das Bandnamen-Tag nicht gesetzt werden. Wenn das Band jedoch auf der Liste steht, muss ein Tag festgelegt sein. HD-Radio zählt keine separaten Bänder auf, da es dasselbe zugrunde liegende Medium wie AM/FM verwendet.
Allgemeine Spielabsichten
Jede App, die für die Wiedergabe einer bestimmten Quelle (z. B. Radio oder CD) vorgesehen ist, muss eine allgemeine Wiedergabeabsicht verarbeiten, um die Wiedergabe einiger Inhalte möglicherweise aus dem inaktiven Zustand (z. B. nach dem Booten) zu starten. Es liegt an der App, wie sie den abzuspielenden Inhalt auswählt, in der Regel handelt es sich jedoch um das zuletzt gespielte Radioprogramm oder den zuletzt gespielten CD-Titel. Für jede Audioquelle ist eine separate Absicht definiert:
-
android.car.intent.action.PLAY_BROADCASTRADIO
-
android.car.intent.action.PLAY_AUDIOCD
: CD-DA oder CD-Text -
android.car.intent.action.PLAY_DATADISC
: Optische Daten-CD wie CD/DVD, aber nicht CD-DA (möglicherweise eine Mixed-Mode-CD) -
android.car.intent.action.PLAY_AUX
: Ohne Angabe des AUX-Ports -
android.car.intent.action.PLAY_BLUETOOTH
-
android.car.intent.action.PLAY_USB
: Ohne Angabe des USB-Geräts -
android.car.intent.action.PLAY_LOCAL
: Lokaler Medienspeicher (integrierter Flash)
Absichten wurden für die Verwendung für allgemeine Spielbefehle ausgewählt, da sie zwei Probleme gleichzeitig lösen: den allgemeinen Spielbefehl selbst und die Diensterkennung. Ein zusätzlicher Vorteil einer solchen Absicht wäre die Möglichkeit, eine solche einfache Aktion auszuführen, ohne eine MediaBrowser-Sitzung zu öffnen.
Tatsächlich ist die Serviceerkennung das wichtigere Problem, das mit diesen Absichten gelöst wird. Das Verfahren zur Diensterkennung ist auf diese Weise einfach und eindeutig (siehe Erkennung und Dienstanbindung ).
Um einige Client-Implementierungen zu vereinfachen, gibt es eine alternative Möglichkeit, einen solchen Play-Befehl auszugeben (der auch von der Radio-App implementiert werden muss): Ausgabe von
playFromMediaId
mit der Root-ID des Root-Knotens (wird als mediaId verwendet). Während der Root-Knoten nicht abspielbar sein soll, ist seine Root-ID eine beliebige Zeichenfolge, die als mediaId konsumierbar gemacht werden kann. Allerdings ist es für Kunden nicht erforderlich, diese Nuance zu verstehen.Programmauswahl
Während
mediaId
ausreicht, um einen Kanal ausMediaBrowserService
auszuwählen, wird es an eine Sitzung gebunden und ist zwischen Anbietern nicht konsistent. In einigen Fällen benötigt der Client möglicherweise einen absoluten Zeiger (z. B. eine absolute Häufigkeit), um ihn zwischen Sitzungen und Geräten aufrechtzuerhalten.Im Zeitalter der digitalen Radioübertragung reicht eine bloße Frequenz nicht aus, um einen bestimmten Sender einzustellen. Verwenden Sie daher
ProgramSelector
um einen analogen oder digitalen Kanal einzustellen.ProgramSelector
besteht aus zwei Teilen:- Primärer Bezeichner. Eine eindeutige und stabile Kennung für einen bestimmten Radiosender, die sich nicht ändert, aber möglicherweise nicht ausreicht, um diesen Sender einzustellen. Zum Beispiel RDS-PI-Code, der in den USA in das Rufzeichen übersetzt werden kann.
- Sekundäre Bezeichner. Zusätzliche Kennungen, die zum Einstellen dieses Senders nützlich sind (z. B. Frequenz), möglicherweise einschließlich Kennungen anderer Radiotechnologien. Beispielsweise kann ein DAB-Sender über einen analogen Ausweichsender verfügen.
Damit
ProgramSelector
in dieMediaBrowser
oderMediaSession
-basierte Lösung passt, definieren Sie ein URI-Schema zur Serialisierung. Das Schema ist wie folgt definiert:broadcastradio://program/<primary ID type>/<primary ID>? <secondary ID type>=<secondary ID>&<secondary ID type>=<secondary ID>
In diesem Beispiel ist der sekundäre Bezeichnerteil (nach dem Fragezeichen (
?
)) optional und kann entfernt werden, um einen stabilen Bezeichner für die Verwendung alsmediaId
bereitzustellen. Zum Beispiel:-
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
Der Autoritätsteil (auch bekannt als Host) des
program
bietet Raum für zukünftige Programmerweiterungen. Die Zeichenfolgen des Bezeichnertyps werden genau als ihre Namen in der HAL 2.x-Definition vonIdentifierType
angegeben und das Wertformat ist eine dezimale oder hexadezimale Zahl (mit0x
Präfix).Alle herstellerspezifischen Kennungen werden durch das Präfix
VENDOR_
dargestellt. Zum BeispielVENDOR_0
fürVENDOR_START
undVENDOR_1
fürVENDOR_START
plus 1. Solche URIs sind spezifisch für die Funkhardware, auf der sie generiert wurden, und können nicht zwischen Geräten verschiedener OEMs übertragen werden.Diese URIs müssen jedem MediaItem in den Radioordnern der obersten Ebene zugewiesen werden. Darüber hinaus muss die MediaSession sowohl
playFromMediaId
als auchplayFromUri
unterstützen. Der URI ist jedoch in erster Linie für die Extraktion von Funkmetadaten (z. B. FM-Frequenz) und die dauerhafte Speicherung gedacht. Es gibt keine Garantie dafür, dass der URI für alle Medienelemente verfügbar ist (z. B. wenn der primäre ID-Typ noch nicht vom Framework unterstützt wird). Andererseits funktioniert Media ID immer. Es wird nicht empfohlen , dass Clients URI verwenden, um Elemente aus der aktuellen MediaBrowser-Sitzung auszuwählen. Verwenden Sie stattdessenplayFromMediaId
. Allerdings ist dies für die Serving-App nicht optional und fehlende URIs sind nur in begründeten Fällen vorbehalten.Im ursprünglichen Entwurf wurde nach dem Schemateil ein einzelner Doppelpunkt anstelle der
://
Sequenz verwendet. Ersteres wird jedoch vonandroid.net.Uri
für absolute hierarchische URI-Referenzen nicht unterstützt.Andere Quellentypen
Andere Audioquellen können ähnlich gehandhabt werden. Zum Beispiel Aux-Eingang und der Audio-CD-Player.
Eine einzelne App kann mehrere Arten von Quellen bedienen. In solchen Fällen wird empfohlen , für jeden Quelltyp einen separaten MediaBrowserService zu erstellen. Selbst in einem Setup mit mehreren bereitgestellten Quellen/MediaBrowserServices wird dringend empfohlen , eine einzige MediaSession innerhalb einer einzelnen App zu haben.
Audio-CD
Ähnlich wie bei Audio-CDs würde die App, die solche Datenträger bedient, MediaBrowser mit einem einzigen durchsuchbaren Eintrag (oder mehreren, wenn das System über einen CD-Wechsler verfügt) bereitstellen, der wiederum alle Titel einer bestimmten CD enthalten würde. Wenn das System nicht über die Titel auf jeder CD informiert ist (z. B. wenn alle Datenträger gleichzeitig in eine Kassette eingelegt sind und nicht alle gelesen werden), wäre MediaItem für den gesamten Datenträger lediglich
PLAYABLE
und nichtBROWSABLE
undPLAYABLE
. Wenn sich in einem bestimmten Steckplatz kein Datenträger befindet, wäre das Element wederPLAYABLE
nochBROWSABLE
(aber jeder Steckplatz muss immer im Baum vorhanden sein).Diese Einträge würden auf ähnliche Weise gekennzeichnet wie Rundfunkordner. Sie würden zusätzliche zusätzliche Felder enthalten, die in der MediaDescription-API definiert sind:
-
EXTRA_CD_TRACK
: Für jedesMediaItem
auf einer Audio-CD, 1-basierte Titelnummer. -
EXTRA_CD_DISK
: 1-basierte Festplattennummer.
Bei CD-Text-fähigen Systemen und kompatiblen Datenträgern hätte das MediaItem der obersten Ebene einen Titel des Datenträgers. Ebenso hätten die MediaItems für Titel einen Titel des Titels.
AUX Eingang
Die App, die Hilfseingaben bereitstellt, stellt einen MediaBrowser-Baum mit einem einzelnen Eintrag (oder mehreren, wenn mehrere Ports vorhanden sind) bereit, der den AUX-In-Port darstellt. Die jeweilige MediaSession nimmt ihre mediaId und wechselt zu dieser Quelle, nachdem sie die
playFromMediaId
-Anfrage erhalten hat.Jeder AUX MediaItem-Eintrag hätte ein zusätzliches Feld
EXTRA_AUX_PORT_NAME
das auf den nicht lokalisierten Namen des Ports ohne die Phrase „AUX“ gesetzt wäre. Beispielsweise wäre „AUX 1“ auf „1“, „AUX front“ auf „front“ und „AUX“ auf eine leere Zeichenfolge gesetzt worden. In nicht-englischen Gebietsschemas würde das Namens-Tag dieselbe englische Zeichenfolge bleiben. Es istEXTRA_BCRADIO_BAND_NAME_EN
, dass die Werte oem definiert und nicht auf eine vordefinierte Liste beschränkt sind.Wenn die Hardware Geräte erkennen kann, die mit dem Aux -Port verbunden sind, sollte die Hardware das MediaItem als
PLAYABLE
markieren, wenn die Eingabe angeschlossen ist. Die Hardware sollte immer noch aufgezählt (aber nichtPLAYABLE
), wenn nichts mit diesem Port verbunden war. Wenn die Hardware keine solche Funktion hat, muss das MediaItem immer aufPLAYABLE
eingestellt sein.Zusätzliche Felder
Definieren Sie die folgenden Felder:
-
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"
Der Client muss die Medien der obersten Ebene für Elemente mit dem zusätzlichen Feld Set
EXTRA_CD_DISK
oderEXTRA_AUX_PORT_NAME
überprüfen.Detaillierte Beispiele
Die folgenden Beispiele befassen sich mit der MediaBrowser -Baumstruktur für Quellentypen, die Teil dieses Designs sind.
Broadcast Radio MediaBrowserService (Handle
ACTION_PLAY_BROADCASTRADIO
):- Stationen (durchbr
EXTRA_BCRADIO_FOLDER_TYPE=BCRADIO_FOLDER_TYPE_PROGRAMS
durch- BBC One (spielbar) URI:
broadcastradio://program/RDS_PI/1234?AMFM_FREQUENCY=90500
- ABC 88.1 (spielbar) URI:
broadcastradio://program/RDS_PI/5678?AMFM_FREQUENCY=88100
- ABC 88.1 HD1 (spielbar) URI:
broadcastradio://program/HD_STATION_ID_EXT/158241DEADBEEF?AMFM_FREQUENCY=88100&RDS_PI=5678
- ABC 88.1 HD2 (spielbar) URI:
broadcastradio://program/HD_STATION_ID_EXT/158242DEADBEFE
- 90,5 FM (spielbar) - FM ohne RDSURI:
broadcastradio://program/AMFM_FREQUENCY/90500
- 620 Uhr (spielbar) URI:
broadcastradio://program/AMFM_FREQUENCY/620
- BBC One (spielbar) URI:
broadcastradio://program/DAB_SID_EXT/1E24102?RDS_PI=1234
- BBC One (spielbar) URI:
- Favoriten (browsable, spielbar)
EXTRA_BCRADIO_FOLDER_TYPE=BCRADIO_FOLDER_TYPE_FAVORITES
- BBC One (spielbar) URI:
broadcastradio://program/RDS_PI/1234?AMFM_FREQUENCY=101300
- BBC Two (nicht spielbar) URI:
broadcastradio://program/RDS_PI/1300?AMFM_FREQUENCY=102100
- BBC One (spielbar) URI:
- AM (Browsable, Playable):
EXTRA_BCRADIO_FOLDER_TYPE=BCRADIO_FOLDER_TYPE_BANDEXTRA_BCRADIO_BAND_NAME_EN="AM"
- 530 Uhr (spielbar) URI:
broadcastradio://program/AMFM_FREQUENCY/530
- 540 Uhr (spielbar) URI:
broadcastradio://program/AMFM_FREQUENCY/540
- 550 Uhr (spielbar) URI:
broadcastradio://program/AMFM_FREQUENCY/550
- 530 Uhr (spielbar) URI:
- Fm (browsable, spielbar):
EXTRA_BCRADIO_FOLDER_TYPE=BCRADIO_FOLDER_TYPE_BANDEXTRA_BCRADIO_BAND_NAME_EN="FM"
- 87.7 FM (spielbar) URI:
broadcastradio://program/AMFM_FREQUENCY/87700
- 87.9 FM (spielbar) URI:
broadcastradio://program/AMFM_FREQUENCY/87900
- 88.1 FM (spielbar) URI:
broadcastradio://program/AMFM_FREQUENCY/88100
- 87.7 FM (spielbar) URI:
- DAB (spielbar):
EXTRA_BCRADIO_FOLDER_TYPE=BCRADIO_FOLDER_TYPE_BANDEXTRA_BCRADIO_BAND_NAME_EN="DAB"
Audio CD MediaBrowserService (Handle
ACTION_PLAY_AUDIOCD
):- Disc 1 (spielbar)
EXTRA_CD_DISK=1
- Disc 2 (Browsable, spielbar)
EXTRA_CD_DISK=2
- Track 1 (spielbar)
EXTRA_CD_TRACK=1
- Track 2 (spielbar)
EXTRA_CD_TRACK=2
- Track 1 (spielbar)
- Meine Musik -CD (Browsable, spielbar)
EXTRA_CD_DISK=3
- Allein alleine (spielbar)
EXTRA_CD_TRACK=1
- Reise, Reise (spielbar)
EXTRA_CD_TRACK=2
- Allein alleine (spielbar)
- Leerer Steckplatz 4 (nicht spielbar)
EXTRA_CD_DISK=4
Aux MediaBrowserService (Handle
ACTION_PLAY_AUX
):- Aux Front (spielbar)
EXTRA_AUX_PORT_NAME="front"
- Aux hinten (spielbar)
EXTRA_AUX_PORT_NAME="rear"
-