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 te aplikacje chcą otrzymywać dane wejściowe 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 opisujemy, jak system Android udostępnia dane audio różnym aplikacjom, które rejestrują dźwięk.
Zachowanie w wersjach Androida starszych niż 10
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 nagranie nie rozpocznie się.
Wyjątkiem od tej reguły było posiadanie uprawnieńandroid.permission.CAPTURE_AUDIO_HOTWORD
przez aplikację uprzywilejowaną (np. Asystenta Google lub usługę ułatwień dostępu) korzystającą ze źródła dźwięku typuHOTWORD
. 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 wprowadziliśmy jeszcze jedną zmianę: tylko aplikacje działające na pierwszym planie (lub usługa na pierwszym planie) mogły przechwytywać dane dźwiękowe. Gdy aplikacja bez usługi na pierwszym planie lub komponentu interfejsu 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.
Działanie Androida 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 opisany tu schemat przełączania metod wprowadzania danych 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. Obejmują one 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, które przechwytują dźwięk ze źródła zapewniającego ochronę prywatności, mają wyższy priorytet niż aplikacje, które nim nie są.
- 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ą przechwycić dźwięk, obie mogą odbierać sygnał wejściowy, a jedna może być wyciszona.
Istnieją 4 główne scenariusze:
- Asystent + zwykła aplikacja
- Usługa ułatwień dostępu + zwykła aplikacja
- 2 zwykłe aplikacje
- Rozmowa głosowa + 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 planie czy w tle), chyba że inna aplikacja korzystająca ze źródła dźwięku chroniącego prywatność nagrywa już dźwięk.
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
AccessibilityService
wymaga ścisłej deklaracji.
Android udostępnia wejściowy dźwięk 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 odbiera dźwięk, a druga słyszy 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 otrzymuje dźwięk w tej, która jako ostatnia zaczęła rejestrować dźwięk.
- 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ę.
Rozmowa głosowa + zwykła aplikacja
Rozmowa głosowa jest aktywna, jeśli tryb „Tylko dźwięk” zwrócony przez użytkownika
AudioManager.getMode()
to
MODE_IN_CALL
lub
MODE_IN_COMMUNICATION
.
Android udostępnia wejściowy dźwięk zgodnie z tymi regułami:
- Podczas połączenia zawsze jest odbierany dźwięk.
- Aplikacja może rejestrować dźwięk, jeśli jest usługą ułatwień dostępu.
Aplikacja może rejestrować rozmowy głosowe, jeśli jest to aplikacja uprzywilejowana (zainstalowana fabrycznie) z uprawnieniami
CAPTURE_AUDIO_OUTPUT
.Aby rejestrować połączenia głosowe w trybie uplink (TX), downlink (RX) lub w obu trybach, aplikacja musi określić źródła dźwięku
MediaRecorder.AudioSource.VOICE_UPLINK
lubMediaRecorder.AudioSource.VOICE_DOWNLINK
, a także urządzenieAudioDeviceInfo.TYPE_TELEPHONY
.
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
, MediaRecorder
i AAudioStream
, które umożliwiają jednoczesne przechwytywanie dźwięku niezależnie od wybranego przypadku użycia.
Nowe metody to:
AudioRecord.Builder.setPrivacySensitive()
AudioRecord.isPrivacySensitive()
MediaRecorder.setPrivacySensitive()
MediaRecorder.isPrivacySensitive()
AAudioStreamBuilder_setPrivacySensitive()
AAudioStream_isPrivacySensitive()
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 zmienią się aktywne aplikacje, platforma 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.
Ponieważ aktywna aplikacja może być wyciszona, gdy aplikacja o wyższym priorytecie stanie się aktywna, możesz zarejestrować funkcję AudioManager.AudioRecordingCallback
w obiekcie AudioRecord
lub MediaRecorder
, aby otrzymywać powiadomienia o zmianie konfiguracji.
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” (prawda), 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 się różnić od efektu zwracanego przez metodę
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, kanał i konwersję formatu z formatu używanego w interfejsie sprzętowym na format określony przez klienta. AudioRecord.getActiveRecordingConfiguration()
.- Zwraca aktywną konfigurację nagrywania.
Możesz uzyskać ogólny widok wszystkich aktywnych nagrań na urządzeniu, dzwoniąc pod numer AudioManager.getActiveRecordingConfigurations()
.