Udostępnianie wejścia audio

Wejście audio pochodzi zwykle z wbudowanego mikrofonu, mikrofonu zewnętrznego lub interfejsu audio podłączonego do urządzenia. Dane wejściowe w postaci dźwięku mogą też pochodzić z rozmowy telefonicznej.

Czasami 2 lub więcej aplikacji może chcieć „przechwycić” ten sam sygnał audio. Mogą wykonywać różne zadania. Na przykład niektóre aplikacje, które otrzymują dźwięk, mogą „nagrywać”, tak jak prosty rejestrator dźwięku, podczas gdy inne mogą „słuchać”, tak jak Asystent Google czy usługa ułatwień dostępu, która reaguje na polecenia głosowe.

W obu przypadkach aplikacje chcą otrzymywać dane audio. Na tej stronie używamy terminu „przechwytywanie” niezależnie od tego, czy aplikacja nagrywa czy tylko nasłuchuje.

Jeśli 2 lub więcej aplikacji chce jednocześnie rejestrować dźwięk, może wystąpić problem z przekazaniem sygnału dźwiękowego z tego samego źródła do wszystkich aplikacji. Na tej stronie opisano, jak system Android udostępnia dane wejściowe dotyczące dźwięku wielu aplikacjom, które rejestrują dźwięk.

Zachowanie w wersji Android 10 i starszych

Przed Androidem 10 strumień audio wejściowego mógł być przechwytywany tylko przez jedną aplikację naraz. Jeśli jakaś aplikacja już nagrywała lub odtwarzała dźwięk, Twoja aplikacja mogła utworzyć obiekt AudioRecord, ale po wywołaniu metody AudioRecord.startRecording() zwróci błąd, a nagrywanie się nie rozpocznie.

Wyjątkiem od tej reguły było, gdy aplikacja uprzywilejowana (np. Asystent Google lub usługa ułatwień dostępu) miała uprawnienie android.permission.CAPTURE_AUDIO_HOTWORD i używała źródła dźwięku typu HOTWORD. W takim przypadku nagrywanie może rozpocząć inna aplikacja. Gdy to nastąpiło, aplikacja uprzywilejowana została zamknięta, a nowa aplikacja przechwyciła dane wejściowe.

W Androidzie 9 wprowadzono jeszcze jedną zmianę: tylko aplikacje działające na pierwszym planie (lub usługa na pierwszym planie) mogły rejestrować dane wejściowe audio. Gdy aplikacja bez usługi na pierwszym planie lub interfejsu użytkownika na pierwszym planie zaczęła rejestrować, aplikacja nadal działała, ale nie rejestrowała dźwięku, nawet jeśli była jedyną aplikacją rejestrującą dźwięk w danym momencie.

Zachowanie w Androidzie 10

Zachowanie przed Androidem 10 to „pierwsze lepszych”. Gdy aplikacja zacznie przechwytywać dźwięk, żadne inne aplikacje nie będą mogły uzyskać dostępu do wejścia audio, dopóki aplikacja, która przechwytuje dźwięk, nie przestanie tego robić.

Android 10 narzuca schemat priorytetów, który może przełączać strumień wejściowy między aplikacjami podczas ich działania. W większości przypadków, gdy nowa aplikacja przechwytuje dane audio, aplikacja, która wcześniej przechwytywała dane, nadal działa, ale nie rejestruje dźwięku. W niektórych przypadkach system może nadal przesyłać dźwięk do obu aplikacji. Poniżej opisujemy różne scenariusze udostępniania.

Schemat ten jest podobny do sposobu, w jaki funkcja skupienia dźwięku obsługuje wiele aplikacji rywalizujących o możliwość korzystania z wyjścia audio. Jednak skupienie na dźwięku jest zarządzane przez automatyczne prośby o uzyskanie i zwolnienie skupienia, a schemat przełączania danych wejściowych opisany tutaj opiera się na zasadach priorytetów stosowanych automatycznie, gdy nowa aplikacja zaczyna rejestrować dźwięk.

W celu rejestrowania dźwięku Android rozróżnia 2 rodzaje aplikacji:

  • „Zwykłe” aplikacje są instalowane przez użytkownika.
  • „Uprzywilejowane” aplikacje są wstępnie zainstalowane na urządzeniu. Obejmuje to Asystenta Google i wszystkie usługi ułatwień dostępu.

Aplikacja jest też traktowana inaczej, jeśli używa źródła dźwięku, które wymaga ochrony prywatności: CAMCORDER lub VOICE_COMMUNICATION.

Reguły ustalania priorytetów dotyczące korzystania z danych wejściowych dźwięku i ich udostępniania:

  • Aplikacje z przywilejami mają wyższy priorytet niż zwykłe aplikacje.
  • Aplikacje z widocznym interfejsem użytkownika na pierwszym planie mają wyższy priorytet niż aplikacje działające w tle.
  • Aplikacje rejestrujące dźwięk z źródła chronionego przed wyciekiem danych mają wyższy priorytet niż aplikacje, które nie mają takich właściwości.
  • Dwie zwykłe aplikacje nigdy nie mogą rejestrować dźwięku w tym samym czasie.
  • W niektórych sytuacjach aplikacja z przywilejami może udostępniać dane wejściowe dotyczące dźwięku innej aplikacji.
  • Jeśli 2 aplikacje w tle o tym samym priorytecie rejestrują dźwięk, wyższą wartość priorytetu ma ta, która została uruchomiona jako ostatnia.

Scenariusze udostępniania

Gdy 2 aplikacje próbują rejestrować dźwięk, obie mogą odbierać sygnał wejściowy, ale jedna z nich może nie odbierać żadnych dźwięków.

Istnieją 4 główne scenariusze:

  • Asystent + zwykła aplikacja
  • Usługa ułatwień dostępu + zwykła aplikacja
  • 2 zwykłe aplikacje
  • Połączenie głosowe + zwykła aplikacja

Asystent + zwykła aplikacja

Asystent jest aplikacją uprzywilejowaną, ponieważ jest wstępnie zainstalowany i ma rolę RoleManager.ROLE_ASSISTANT. Inne wstępnie zainstalowane aplikacje z tą rolą są traktowane podobnie.

Android udostępnia dane audio zgodnie z tymi regułami:

  • Asystent może odbierać dźwięk (niezależnie od tego, czy jest na pierwszym czy drugim planie), chyba że inna aplikacja korzystająca z źródła dźwięku wrażliwego na naruszenie prywatności już to robi.

  • Aplikacja odbiera dźwięk, chyba że Asystent ma widoczny element UI u góry ekranu.

Pamiętaj, że obie aplikacje otrzymują dźwięk tylko wtedy, gdy Asystent jest uruchomiony w tle, a druga aplikacja nie rejestruje dźwięku z źródła dźwięku wrażliwego na prywatność.

Usługa ułatwień dostępu + zwykła aplikacja

AccessibilityServicewymaga ścisłej deklaracji.

Android udostępnia dane audio zgodnie z tymi regułami:

  • Jeśli interfejs usługi jest na górze, zarówno usługa, jak i aplikacja otrzymują dane wejściowe audio. Dzięki temu możesz sterować połączeniem głosowym lub nagrywać filmy za pomocą poleceń głosowych.

  • Jeśli usługa nie znajduje się na górze, jest traktowana jak zwykła aplikacja.

2 zwykłe aplikacje

Gdy 2 aplikacje nagrywają jednocześnie, tylko jedna z nich otrzymuje dźwięk, a druga – ciszę.

Android udostępnia dane audio zgodnie z tymi regułami:

  • Jeśli żadna z aplikacji nie jest aplikacją chroniącą prywatność, dźwięk jest odtwarzany przez aplikację z interfejsem na górze. Jeśli żadna z aplikacji nie ma interfejsu, dźwięk zostanie odebrany przez aplikację, która ostatnio rozpoczęła nagrywanie.
  • Jeśli jedna z aplikacji jest szczególnie wrażliwa na prywatność, to właśnie ona będzie rejestrować dźwięk, a druga aplikacja będzie milczeć, nawet jeśli ma interfejs na górze lub zaczęła nagrywać później.
  • Jeśli obie aplikacje są chronione przed wyciekiem danych, aplikacja, która rozpoczęła ostatnio nagrywanie, otrzyma dźwięk, a druga – ciszę.

Połączenie głosowe + zwykła aplikacja

Połączenie głosowe jest aktywne, jeśli tryb audio zwracany przez AudioManager.getMode() to MODE_IN_CALL lub MODE_IN_COMMUNICATION.

Android udostępnia dane audio zgodnie z tymi regułami:

Zachowanie w Androidzie 11

Android 11 (poziom API 30) stosuje schemat priorytetów Androida 10, o którym mowa powyżej. Udostępnia też nowe metody w metodach AudioRecord, MediaRecorderAAudioStream, które umożliwiają jednoczesne przechwytywanie dźwięku niezależnie od wybranego przypadku użycia.

Nowe metody to:

Gdy setPrivacySensitive() ma wartość true, użycie funkcji rejestrowania jest prywatne i nawet uprzywilejowany Asystent nie może równocześnie rejestrować. To ustawienie zastępuje domyślne zachowanie, które zależy od źródła dźwięku. Na przykład VOICE_COMMUNICATION jest domyślnie prywatny, ale UNPROCESSED nie jest.

Zmiany konfiguracji

Gdy kilka aplikacji jednocześnie rejestruje dźwięk, tylko jedna lub dwie z nich są „aktywne” (odbiory dźwięku); pozostałe są wyciszone (odbiory ciszy). Gdy aktywne aplikacje się zmieniają, framework audio może zmienić konfigurację ścieżek audio zgodnie z tymi regułami:

  • Urządzenie wejścia audio dla każdej aktywnej aplikacji może się zmieniać (np. z wbudowanego mikrofonu na podłączony zestaw słuchawkowy Bluetooth).
  • Włączone jest wstępne przetwarzanie powiązane z aktywną aplikacją o najwyższym priorytecie. Wszystkie inne przetwarzanie wstępne jest ignorowane.

Aktywna aplikacja może zostać wyciszona, gdy aktywuje się aplikacja o wyższym priorytecie. Aby otrzymywać powiadomienia o zmianach konfiguracji, możesz zarejestrować funkcję AudioManager.AudioRecordingCallback w obiekcie AudioRecord lub MediaRecorder. Możliwe zmiany:

  • Nagrywanie z wyciszeniem lub bez wyciszenia
  • Zmieniono urządzenie
  • Zmieniono przetwarzanie wstępne
  • Zmiana właściwości strumienia (częstotliwość próbkowania, maska kanału, format próbki)

Przed rozpoczęciem rejestrowania musisz wywołać funkcję AudioRecord.registerAudioRecordingCallback(). Funkcja wywołania zwrotnego jest wykonywana tylko wtedy, gdy aplikacja odbiera dźwięk i występuje zmiana.

Metoda onRecordingConfigChanged() zwraca obiekt AudioRecordingConfiguration zawierający bieżący stan przechwytywania dźwięku. Aby dowiedzieć się więcej o tej zmianie, skorzystaj z tych metod:

isClientSilenced()
Zwraca wartość „true”, jeśli dźwięk zwrócony do klienta jest obecnie wyciszony z powodu zasad dotyczących rejestrowania.
getAudioDevice()
Zwraca aktywne urządzenie audio.
getEffects()
Zwraca aktywny efekt wstępnego przetwarzania. Pamiętaj, że aktywny efekt może być inny niż zwracany przez funkcję getClientEffects(), jeśli klient nie jest aktywną aplikacją o najwyższym priorytecie.
getFormat()
Zwraca właściwości strumienia. Pamiętaj, że rzeczywiste dane audio otrzymane przez klienta zawsze są zgodne z wymaganym formatem zwracanym przez getClientFormat(). Framework automatycznie wykonuje niezbędne przepróbkowanie, konwersję kanału i formatu z formatu używanego w interfejsie sprzętowym na format określony przez klienta.
AudioRecord.getActiveRecordingConfiguration().
Zwraca aktywną konfigurację nagrywania.

Możesz wyświetlić ogólny widok wszystkich aktywnych nagrań na urządzeniu, wywołując AudioManager.getActiveRecordingConfigurations().