Skupienie na dźwięku

Przed rozpoczęciem strumienia logicznego aplikacja powinna poprosić o skupienie dźwięku, używając tych samych atrybutów dźwięku, które są używane w przypadku strumienia logicznego. Przesyłanie takiej prośby o uwagę jest zalecane, ale nie jest wymagane przez system. Niektóre aplikacje mogą pomijać wysyłanie żądania, aby uzyskać określone działanie (np. aby celowo odtworzyć dźwięk podczas rozmowy telefonicznej).

Z tego powodu należy traktować system sterowania jako sposób pośredniego sterowania odtwarzaniem i rozwiązywania konfliktów, a nie jako podstawowy mechanizm sterowania dźwiękiem. Samochód nie powinien polegać na systemie sterowania w celu obsługi podsystemu audio.

Interakcje z elementem

Aby spełnić wymagania AAOS, żądania dotyczące fokusa audio są obsługiwane na podstawie zdefiniowanych wcześniej interakcji CarAudioContext żądania z interakcjami bieżących posiadaczy fokusa. Wyróżniamy 3 typy interakcji: wyłączne, odrzucające i jednoczesne.

Interakcja wykluczająca

W przypadku interakcji wyłącznych w danym momencie może być aktywna tylko 1 aplikacja. W związku z tym przychodzące żądanie fokusu powoduje przeniesienie fokusu, a obecny obiekt traci fokus. Przykładem może być sytuacja, w której użytkownik uruchamia nową aplikację muzyczną, gdy muzyka jest już odtwarzana w dotychczasowej aplikacji. Ponieważ obie aplikacje odtwarzają multimedia, tylko jedna z nich może być aktywna w danym momencie. W efekcie żądanie dotyczące stanu skupienia nowo uruchomionej aplikacji zwraca wartość AUDIOFOCUS_REQUEST_GRANTED, a aplikacja, która obecnie odtwarza muzykę, otrzymuje zdarzenie zmiany stanu skupienia z stanem „loss” (utrata) odpowiadającym rodzajowi wysłanego żądania. Jest to model interakcji najczęściej używany w przypadku Androida.

Odrzuć interakcję

W przypadku interakcji odrzucenia przychodzące żądanie jest zawsze odrzucane. Próba odtworzenia muzyki podczas trwającej rozmowy jest przykładem odrzuconej interakcji. W takim przypadku, jeśli dialer ma obecnie fokus audio w przypadku połączenia, a druga aplikacja poprosi o fokus audio w celu odtworzenia muzyki, aplikacja muzyczna otrzyma w odpowiedzi AUDIOFOCUS_REQUEST_FAILED. Ponieważ prośba o fokus została odrzucona, do obecnego posiadacza fokusu nie zostanie wysłana żadna prośba o utratę fokusu.

Równoległa interakcja

Najbardziej charakterystyczne dla AAOS są równoczesne interakcje. Dzięki temu aplikacje, które proszą o skupienie się na dźwięku w samochodzie, mogą zachować skupienie równolegle z innymi aplikacjami. Aby interakcja mogła się odbywać równocześnie, muszą być spełnione te warunki. The:

Jeśli te kryteria są spełnione, żądanie focus zwraca wartość AUDIOFOCUS_REQUEST_GRANTED, a obecny element nie zmienia stanu. Jeśli jednak bieżący element skupienia zdecyduje się na otrzymywanie zdarzeń duck lub na wstrzymanie działania po wciśnięciu przycisku Duck, straci on skupienie, tak jak w przypadku interakcji wyłącznej.

Obsługa równoczesnych strumieni

Chociaż równoczesna interakcja ma wiele przydatnych zastosowań, producenci sprzętu muszą zadbać o miksowanie i przytłumienie na poziomie sprzętowym na urządzeniach wyjściowych. Dlatego zalecamy, aby CarAudioContext były kierowane tylko do tego samego urządzenia wyjściowego co CarAudioContext, z którym nie mogą być odtwarzane jednocześnie. Dzięki temu, że urządzenia wyjściowe są oddzielne dla poszczególnych strumieni, HAL może wyciszyć jeden ze strumieni przed zmiksowaniem go z innymi lub przekierować fizyczne strumienie do różnych głośników w pojeździe. Jeśli strumienie logiczne są miksowane w Androidzie, ich wzmocnienia nie ulegają zmianie i są dostarczane w ramach tego samego fizycznego strumienia.

Jeśli na przykład nawigacja i multimedia są dostarczane jednocześnie, wzmocnienie strumienia multimediów może zostać tymczasowo zmniejszone (zmniejszone), aby instrukcje nawigacji były lepiej słyszalne. Można też przesłać strumień nawigacji do głośników po stronie kierowcy, a multimedia odtwarzać w pozostałych głośnikach w samochodzie.

Interakcja

Tabela poniżej przedstawia macierz interakcji zdefiniowaną przez CarAudioService. Wiersze reprezentują CarAudioContext bieżącego właściciela fokusa, a kolumny – CarAudioContext przychodzącego żądania.

Jeśli np. aplikacja muzyczna ma obecnie fokus, a aplikacja do nawigacji – fokus żądania, z tabeli wynika, że te 2 interakcje mogą działać jednocześnie, o ile spełnione są inne kryteria dotyczące interakcji równoczesnych.

Ze względu na jednoczesne interakcje może istnieć więcej niż 1 element fokusowy. W takiej sytuacji przychodzące żądanie jest porównywane z każdym z obecnych żądań, aby określić, jakiego rodzaju interakcję zastosować. W tym przypadku zwycięża najbardziej konserwatywna interakcja (najpierw odrzucenie, potem wyłączność, a na końcu równoczesność).

W tabeli poniżej przedstawiono interakcje fokusu między CarAudioContext dla przychodzącego żądania fokusu (kolumny) a kontekstem istniejących elementów fokusu (wiersze). Każda komórka reprezentuje oczekiwany typ interakcji w danych 2 kontekstach.

Interakcje z aktywną aktywnością audio

Rysunek 1. Interakcje z aktywizacją audio

W Androidzie 11 wprowadzono nowe ustawienie, które pozwala użytkownikom zmieniać sposób interakcji między nawigacją a połączeniami telefonicznymi. Gdy parametr android.car.KEY_AUDIO_FOCUS_NAVIGATION_REJECTED_DURING_CALL jest ustawiony, zmienia interakcję między przychodzącymi NAVIGATION prośbami o skupienie a obecnymi CALL posiadaczami prośby z równoległego na odrzucenia. Jeśli użytkownik nie chce, aby instrukcje nawigacji przerywały połączenie, może włączyć to ustawienie. Użytkownik może zapisać te ustawienia i zmieniać je dynamicznie, aby kolejne żądania dotyczące skupienia uwzględniały nową wartość ustawienia.

Możliwość opóźnienia aktywacji trybu pełnej koncentracji

W Androidzie 11 dodano obsługę prośby o opóźnienie skupienia na dźwięku. Dzięki temu można opóźnić nieprzechodnie prośby o uwagę, gdy ich interakcja z obecnymi posiadaczami prośby o uwagę spowodowałaby ich odrzucenie. Gdy zmiana stanu spowoduje, że opóźnione żądanie może zostać wykonane, żądanie zostanie zaakceptowane.

Zasady dotyczące opóźnionych żądań dostępu do mikrofonu

  • Tylko żądania nieprzelotne – jak już wspomnieliśmy, opóźnione żądanie można wysłać tylko w przypadku źródeł nieprzelotnych. Pozwala to uniknąć odtwarzania dźwięku przejściowego przez długi czas po tym, jak przestał być istotny.
  • Tylko jedno żądanie może być opóźnione naraz – jeśli opóźnione żądanie zostanie wysłane, gdy już jest opóźnione żądanie, pierwotne opóźnione żądanie otrzyma zdarzenie zmiany AUDIOFOCUS_LOSS, a nowe żądanie otrzyma synchroniczną odpowiedź AUDIOFOCUS_REQUEST_DELAYED.
  • Prośby o opóźnienie muszą mieć OnAudioFocusChangeListener. Gdy prośba zostanie opóźniona, listener służy do powiadamiania osoby, która ją wysłała, gdy prośba zostanie ostatecznie zaakceptowana (AUDIOFOCUS_GAIN) lub odrzucona (AUDIOFOCUS_LOSS).

Prośba o opóźnienie fokusa

Aby utworzyć prośbę, która może zostać opóźniona, użyj: AudioFocusRequest.Builder#setAcceptsDelayedFocusGain

mMediaWithDelayedFocusListener = new MediaWithDelayedFocusListener();

mDelayedFocusRequest = new AudioFocusRequest
     .Builder(AudioManager.AUDIOFOCUS_GAIN)
     .setAudioAttributes(mMusicAudioAttrib)
     .setOnAudioFocusChangeListener(mMediaWithDelayedFocusListener)
     .setForceDucking(false)
     .setWillPauseWhenDucked(false)
     .setAcceptsDelayedFocusGain(true)
     .build();

Następnie, gdy przesyłasz prośbę, postępuj zgodnie z instrukcjami podanymi w odpowiedzi AUDIOFOCUS_REQUEST_DELAYED:

int delayedFocusRequestResults = mAudioManager.requestAudioFocus(mDelayedFocusRequest);
if (delayedFocusRequestResults == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
// start audio playback
return;
}
if (delayedFocusRequestResults == AudioManager.AUDIOFOCUS_REQUEST_DELAYED) {
     // audio playback delayed to audio focus listener
     return;
}

Gdy żądanie jest opóźnione, słuchacz fokusa jest odpowiedzialny za obsługę zmian w fokusie:

private final class MediaWithDelayedFocusListener implements
OnAudioFocusChangeListener {
       @Override
       public void onAudioFocusChange(int focusChange) {
           synchronized (mLock) {
               switch (focusChange) {
                   case AudioManager.AUDIOFOCUS_GAIN:
                        // Start focus playback
                   case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                        // Pause media transiently
                   case AudioManager.AUDIOFOCUS_LOSS:
                        // Stop media

Zarządzanie strefami fokusowymi

W pojazdach z wieloma strefami dźwiękowymi można niezależnie zarządzać dźwiękiem w każdej strefie. W związku z tym żądanie wysłane do jednej strefy nie uwzględnia tego, co ma fokus w innych strefach, ani nie powoduje utraty fokusu w innych strefach. Dzięki temu można zarządzać punktem skupienia w głównej kabinie osobno od systemu rozrywki na tylnym siedzeniu, co pozwala uniknąć przerw w odtwarzaniu dźwięku w jednej strefie spowodowanych zmianami punktu skupienia w innej.

W przypadku wszystkich aplikacji zarządzanie nawigacją odbywa się automatycznie.CarAudioService Strefa audio żądania fokusowego jest określana na podstawie powiązanego z nim UserId lub UID. Więcej informacji znajdziesz w artykule Routing dźwięku.

Prośba o dźwięk z wielu stref jednocześnie

Jeśli aplikacja chce odtwarzać dźwięk w kilku strefach jednocześnie, musi poprosić o skupienie się na każdej strefie, dodając AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID do pakietu:

// Create attribute with bundle and AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID
Bundle bundle = new Bundle();
bundle.putInt(CarAudioManager.AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID,
               zoneId);

AudioAttributes attributesWithZone = new AudioAttributes.Builder()
     .setUsage(AudioAttributes.USAGE_MEDIA)
     .addBundle(bundle)
     .build();

// Create focus request using built attributesWithZone

Ten parametr pakietu umożliwia zastąpienie automatycznych mapowania stref dźwięku, aby zamiast tego używać określonego identyfikatora strefy. Aplikacja może więc wysyłać oddzielne żądania dotyczące różnych stref dźwiękowych.

HAL Audio Focus

Od Androida 11 interfejs HAL może prosić o skupienie uwagi w imieniu zewnętrznych strumieni. Te interfejsy API są opcjonalne, ale zdecydowanie zalecamy ich używanie, aby umożliwić dźwiękom zewnętrznym lepsze funkcjonowanie w ekosystemie Androida i zapewnienie większą wygodę użytkownikom.

Pamiętaj, że HAL jest nadal odpowiedzialny za podejmowanie ostatecznej decyzji, które dźwięki mają być priorytetowe. W tym zakresie dźwięki alarmowe i dźwięki związane z bezpieczeństwem powinny być odtwarzane niezależnie od tego, czy HAL ma przypisane skupienie dźwiękowe, i powinny być odtwarzane w odpowiednich momentach nawet wtedy, gdy HAL utraci to skupienie. To samo dotyczy dźwięków wymaganych przez przepisy.

W tym samym duchu HAL powinien nadal proaktywnie wyciszać strumienie Androida, gdy odtwarzane są dźwięki alarmowe lub dźwięki mające kluczowe znaczenie dla bezpieczeństwa, aby były wyraźnie słyszalne.

AudioControl@2.0

Wersja 2.0 interfejsu AudioControl HAL wprowadza kilka nowych interfejsów API:

Interfejs API Cel
IAudioControl#registerFocusListener Rejestruje wystąpienie IFocusListener w interfejsie AudioControl HAL. Ten odbiornik umożliwia HAL żądanie i rezygnację z koncentracji na dźwięku. HAl powinien udostępnić instancję ICloseHandle, której Android będzie używać do wyrejestrowania listenera.
IAudioControl#onAudioFocusChange Informuje HAL o zmianach stanu żądań skupienia uwagi, które HAL wysyła za pomocą interfejsu IFocusListener. Obejmuje to odpowiedzi na początkowe żądania dotyczące tematu.
IFocusListener#requestAudioFocus Prośby o wyostrzanie w imieniu HAL dla określonego użycia, identyfikatora strefy i typu wzmocnienia ostrości.
IFocusListener#abandonAudioFocus powoduje porzucenie istniejących żądań skupienia HAL dla określonego użycia i identyfikatora strefy.

HAL może mieć wiele żądań fokusu w tym samym czasie, ale jest ograniczony do jednego żądania na parę identyfikatorów użytkowania i strefy. Pamiętaj, że Android zakłada, że HAL natychmiast zaczyna odtwarzać dźwięki po wysłaniu żądania i kontynuuje to do momentu utraty fokusu.

Poza registerFocusListener wszystkie te żądania są oneway, aby Android nie opóźniał HAL podczas przetwarzania żądania focus. HAL nie powinien czekać na uzyskanie fokusu przed odtworzeniem dźwięków istotnych dla bezpieczeństwa. HAL może opcjonalnie słuchać i reagować na zmiany w fokusie dźwięku za pomocą IAudioControl#onAudioFocusChange, ale nie jest to wymagane.