Zwiększanie bezpieczeństwa dźwięku w tle

Począwszy od Androida 17, platforma audio wymusza ograniczenia dotyczące interakcji z dźwiękiem w tle, w tym odtwarzania dźwięku, żądań fokusu audio i interfejsów API zmiany głośności, aby mieć pewność, że te zmiany są wprowadzane celowo przez użytkownika.

Wszystkie aplikacje działające na Androidzie 17, które mają te interakcje z dźwiękiem w tle, muszą mieć widoczną aktywność lub uruchamiać usługę na pierwszym planie, która nie jest typu SHORT_SERVICE. Dotyczy to aplikacji kierowanych na interfejs API na poziomie 37 i tych, które nie są na niego kierowane.

Jeśli aplikacja jest kierowana na Androida 17 (API na poziomie 37), obowiązuje dodatkowe ograniczenie. Jeśli aplikacja działa w tle, musi uruchomić usługę na pierwszym planie, która ma uprawnienia podczas używania. (Usługa działająca na pierwszym planie otrzymuje uprawnienia WIU, jeśli zostanie uruchomiona w odpowiedzi na operację zainicjowaną przez użytkownika lub gdy aplikacja jest widoczna dla użytkownika). Wymóg dotyczący funkcji WIU jest jednak zniesiony, jeśli aplikacja ma uprawnienia do alarmu precyzyjnego i wprowadza zmiany w strumieniach audio z atrybutem USAGE_ALARM.

Jeśli aplikacja próbuje wywołać interfejsy API audio, gdy nie jest w prawidłowym cyklu życia, interfejsy API odtwarzania dźwięku i zmiany głośności nie działają, ale nie zgłaszają wyjątku ani nie wyświetlają komunikatu o błędzie. Interfejs API fokusu audio nie działa i zwraca kod wyniku AUDIOFOCUS_REQUEST_FAILED.

Dlaczego wprowadzamy tę zmianę

Wprowadziliśmy te ograniczenia, aby zmniejszyć liczbę niezamierzonych błędów związanych z dźwiękiem w tle. Oto kilka przykładów:

  • Aplikacje odtwarzające dźwięk bez usługi działającej na pierwszym planie mogą zostać zamrożone. Gdy aplikacja zostanie ostatecznie odmrożona, nieoczekiwanie wznowi odtwarzanie dźwięku, potencjalnie po kilku godzinach.
  • Aplikacje odtwarzające dźwięk bez usługi na pierwszym planie podlegały różnym ograniczeniom, co powodowało przerywanie dźwięku.
  • Odtwarzanie odłączone od cyklu życia działania, co może skutkować wyciekiem sesji odtwarzania lub zdarzeń zaznaczenia, które będą kontynuowane bez możliwości zatrzymania odtwarzania przez użytkownika.

Zachęcamy deweloperów do przetestowania aplikacji i przekazania opinii na temat zmiany zachowania, jeśli ma ona negatywny wpływ na zamierzone przypadki użycia dźwięku. Wszelkie problemy zgłaszaj za pomocą tego narzędzia do śledzenia problemów ze zgodnością aplikacji na Androidzie 17.

Identyfikowanie przypadków użycia dźwięku w tle, których dotyczy problem

Sprawdź implementację odtwarzania dźwięku i ustal, czy aplikacja ma zapewniać funkcję interakcji z dźwiękiem w tle nawet w określonych okolicznościach.

Jeśli Twoja aplikacja ma odtwarzać dźwięk lub korzystać z interfejsów API audio tylko wtedy, gdy wyświetla aktywność widoczną dla użytkownika, w tym w trybie obrazu w obrazie, te zmiany nie będą miały na nią wpływu.

Jeśli aplikacja zapewnia funkcje VOIP, w tym rozmowy wideo, musi już spełniać wymagania wprowadzane w przypadku odtwarzania (zwykle przez korzystanie z zalecanych interfejsów API do obsługi połączeń), aby pomyślnie nagrywać dźwięk. Dlatego jest mało prawdopodobne, że ta zmiana będzie miała na nią wpływ.

Jeśli Twoja aplikacja ma kontynuować odtwarzanie dźwięku, gdy ekran jest wyłączony lub gdy aktywność nie jest widoczna (co najczęściej ma miejsce w przypadku aplikacji do odtwarzania strumieniowego muzyki lub aplikacji do podcastów), uznaje się, że zapewnia ona funkcję odtwarzania dźwięku w tle i musi spełniać nowe wymagania.

Scenariusze dotyczące dźwięku w tle, które mogą ulec zmianie

Jeśli Twoja aplikacja nie działa według modelu kontynuowania interakcji audio rozpoczętej, gdy aplikacja była otwarta, lub w odpowiedzi na wyraźne działanie użytkownika, jej funkcje zostaną prawdopodobnie wyciszone.

Jeśli na przykład aplikacja uruchomi usługę na pierwszym planie w odpowiedzi na BOOT_COMPLETE i spróbuje wejść w interakcję z dźwiękiem, zostanie to zablokowane.

Sprawdzone metody dotyczące dźwięku w tle, które pomagają ograniczyć wpływ na skuteczność

  • Użyj komponentu MediaSessionService biblioteki Jetpack media3, aby zarządzać odtwarzaniem dźwięku w tle.

    Jeśli to zrobisz, wzmocnienie zabezpieczeń w tle prawdopodobnie nie będzie miało wpływu na Twoją aplikację, ponieważ biblioteka pomaga w zarządzaniu cyklem życia odtwarzania.

  • Jeśli nie korzystasz z biblioteki media3, musisz ręcznie uruchomić usługę na pierwszym planie mediaPlayback. Zawsze uruchamiaj usługę na pierwszym planie, gdy aplikacja działa na pierwszym planie, jeśli może wystąpić odtwarzanie dźwięku w tle.

    Jeśli na przykład Twoja aplikacja służy do odtwarzania strumieniowego filmów i zwykle działa tylko na pierwszym planie, ale zawiera funkcję umożliwiającą użytkownikowi kontynuowanie odtwarzania przy wyłączonym ekranie, to gdy użytkownik uruchomi odtwarzanie, aplikacja powinna nadal uruchamiać usługę na pierwszym planie.

    Dzięki temu usługa działająca na pierwszym planie zostanie uruchomiona z możliwościami WIU.

  • Utrzymuj aktywność mediaPlayback FGS podczas przejściowych awarii trwających krócej niż 10 minut.

    Jeśli w aplikacji wystąpi przejściowy błąd, np. problem z buforowaniem z powodu aktywności sieciowej, lub spodziewana jest przejściowa przerwa, np. AUDIOFOCUS_LOSS_TRANSIENT, intencja odtwarzania powinna być kontynuowana. Dlatego Twoja usługa FGS powinna pozostać aktywna.

  • Zatrzymaj usługę na pierwszym planie po zakończeniu odtwarzania i wznów odtwarzanie tylko wtedy, gdy użytkownik wyraźnie to zrobi.

    W przypadku stałego sygnału zakończenia odtwarzania (np. zakończenie treści bez autoodtwarzania, AUDIOFOCUS_LOSS, zdarzenie wstrzymania z UMO lub zdarzenie klawisza multimedialnego) lub nieodwracalnego błędu aplikacja powinna przerwać interakcję audio, zatrzymać usługę na pierwszym planie i zakończyć sesję multimedialną. Wykonanie wszystkich tych czynności odpowiada koncepcji użytkownika dotyczącej „zakończenia” pożądanej interakcji z dźwiękiem w tle. Po wykonaniu tej czynności aplikacja nie będzie już mogła odtwarzać dźwięku w tle.

    Jeśli następnie użytkownik wyraźnie wznowi odtwarzanie, na przykład za pomocą interfejsu aplikacji lub przycisku odtwarzania uniwersalnego obiektu multimedialnego, intencja rozpoczęcia odtwarzania dźwięku powinna zostać zwrócona, co spowoduje uruchomienie nowej usługi na pierwszym planie.

  • Przetestuj działanie odtwarzania dźwięku za pomocą poleceń powłoki adb.

Testowanie zmian

Możesz przetestować zgodność aplikacji na urządzeniach z Androidem 17 lub nowszym (począwszy od wersji beta 3), uruchamiając to polecenie ADB:

adb shell cmd audio set-enable-hardening <enable|disable|throw>

To polecenie ma te opcje:

  • enable: włącza wszystkie ograniczenia dotyczące wzmocnienia dźwięku we wszystkich aplikacjach. Wymaganie dotyczące usług WIU działających na pierwszym planie obowiązuje niezależnie od tego, czy aplikacja jest kierowana na Androida 17 (interfejs API na poziomie 37). Ponadto wymóg ten jest egzekwowany nawet wtedy, gdy aplikacja wprowadza zmiany w strumieniach alarmów i ma uprawnienia do alarmów precyzyjnych.

  • disable: wyłącza wszystkie ograniczenia dotyczące wzmocnienia dźwięku.

  • throw: włącza wszystkie ograniczenia dotyczące wzmocnienia dźwięku we wszystkich aplikacjach, takich jak enable. Dodatkowo ta flaga umożliwia głośne błędy, wywołując IllegalStateException w przypadku interakcji związanych z głośnością i fokusem. W przypadku odtwarzania dźwięku metoda zapisu stale zwraca kod błędu. W trybach odtwarzania bez jawnych zapisów aplikacja ulega awarii.

Użyj adb dumpsys audio lub logcat, aby sprawdzić, czy aplikacja napotkała błędy bez powiadomienia z powodu wymuszenia wzmocnienia dźwięku. Jeśli tak, pojawi się wpis z prefiksem AudioHardening i nazwą pakietu. Jeśli komunikat zawiera ciąg level: full, aplikacja uruchamia usługę na pierwszym planie, ale usługa nie ma funkcji „podczas używania”. Jeśli komunikat zawiera level: partial, aplikacja w ogóle nie uruchamia usługi na pierwszym planie.

Informacje o usłudze działającej na pierwszym planie z możliwością działania podczas używania aplikacji

Zasadniczo usługi działające na pierwszym planie muszą być uruchamiane, gdy aplikacja działa na pierwszym planie, aby rozszerzyć operacje inicjowane przez użytkownika. W niektórych przypadkach aplikacje mogą uruchamiać usługę na pierwszym planie, gdy działają w tle. Jednak te usługi na pierwszym planie zwykle nie mają uprawnień do działania podczas używania aplikacji.

WIU działa jako zabezpieczenie – uniemożliwia usłudze działającej na pierwszym planie, która została uruchomiona w tle, wykonywanie pewnych działań związanych z danymi wrażliwymi, gdy użytkownik może nie być świadomy aktywności aplikacji. Uniemożliwia aplikacji dostęp do danych wrażliwych, takich jak lokalizacja, aparat czy mikrofon, a od Androida 17 blokuje też interfejsy API audio, które zwykle wymagają widocznego kontekstu interfejsu.

Oto przydatne informacje:

  • Standardowa usługa działająca na pierwszym planie: usługi uruchamiane, gdy aplikacja jest widoczna lub ma przyznane uprawnienia do uruchamiania aktywności w tle, mają dostęp do WIU.
  • Usługi na pierwszym planie uruchamiane w tle (BFSL): większość nie przyznaje dostępu do WIU. Główne wyjątki, które przyznają WIU, to interakcje obejmujące wyraźną intencję użytkownika, np. kliknięcia powiadomień, interakcje z widżetami lub zdarzenia klawiszy multimedialnych z urządzenia zewnętrznego.
  • Usługa na pierwszym planie uruchomiona przez system: usługi na pierwszym planie mają dostęp do WIU, jeśli zostały uruchomione przez delegowanie serwera systemowego (np. z biblioteki Jetpack Telecom) lub przez powiązania systemowe reprezentujące podwyższony stan na pierwszym planie w celu wykonywania dedykowanych funkcji (np. VoiceInteractionService).

Więcej informacji znajdziesz w artykule Ograniczenia dotyczące uruchamiania usługi na pierwszym planie podczas działania w tle.

Pełna lista interfejsów Audio API, których dotyczy problem

Funkcja audio

Wynik

Interfejsy API, których dotyczy problem

Odtwarzanie dźwięku

Odtwarzanie jest wyciszone

Brak wyjątków, brak komunikatu o błędzie z interfejsu API

AudioTrack.write()

(NDK) AAudioStream_write

OpenSL ES na Androida

Może to też mieć wpływ na biblioteki multimediów po stronie klienta, które zarządzają odtwarzaniem, takie jak media3, Exoplayer i Oboe.

Prośba o aktywność audio

Zwraca AUDIOFOCUS_REQUEST_FAILED

Brak wpływu na odtwarzanie dźwięku w innych aplikacjach, brak fokusu

AudioManager.requestAudioFocus()

Interfejsy API głośności i trybu dzwonka

Brak wpływu na tryb dzwonka lub głośność (wywołanie metody jest ignorowane bez powiadomienia)

Brak wyjątków, brak komunikatu o błędzie z interfejsu API

AudioManager.setStreamVolume()

AudioManager.setStreamMute()

AudioManager.adjustStreamVolume()

AudioManager.adjustVolume()

AudioManager.adjustSuggestedStreamVolume()

AudioManager.setRingerMode()