Przyciski multimediów to przyciski sprzętowe dostępne na urządzeniach z Androidem i innych urządzeniach peryferyjnych, np. przycisk wstrzymania/odtwarzania na słuchawkach Bluetooth. Gdy użytkownik naciśnie przycisk multimediów, Android wygeneruje KeyEvent
, który zawiera kod klucza identyfikujący przycisk. Kody klucza w przypadku przycisku mediów są stałymi, które zaczynają się od KEYCODE_MEDIA
(np. KEYCODE_MEDIA_PLAY
).
Aplikacje powinny obsługiwać zdarzenia przycisku multimediów w 3 przypadkach, w tej kolejności priorytet:
- Gdy aktywność w interfejsie aplikacji jest widoczna
- Gdy aktywność w interfejsie jest ukryta, a sesja multimediów w aplikacji jest aktywna
- Gdy aktywność w interfejsie jest ukryta, a sesja multimediów w aplikacji jest nieaktywna i trzeba ją ponownie uruchomić
Obsługa przycisków multimediów w aktywności na pierwszym planie
Aktywność na pierwszym planie odbiera kluczowe zdarzenie przycisku multimediów w elemencie onKeyDown()
. W zależności od uruchomionej wersji Androida system może kierować zdarzenie na 2 sposoby.
za pomocą kontrolera multimediów:
- Jeśli używasz Androida 5.0 (poziom interfejsu API 21) lub nowszego, wywołaj
FLAG_HANDLES_MEDIA_BUTTONS
MediaBrowserCompat.ConnectionCallback.onConnected
Dzięki temu automatycznie wywołujedispatchMediaButtonEvent()
, co przekłada kod klucza na wywołanie zwrotne sesji multimediów. - Przed Androidem 5.0 (poziom interfejsu API 21) trzeba zmodyfikować
onKeyDown()
, aby obsługiwały samemu utworzyć wydarzenie. Więcej informacji znajdziesz w artykule Obsługa przycisków multimediów w aktywnej sesji multimediów. Poniższy fragment kodu pokazuje, jak przechwycić i wywołaj dispatchMediaButtonEvent(). Pamiętaj, aby zwrócić adrestrue
do wskazują, że zdarzenie zostało obsługiwane:Kotlin
fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { return super.onKeyDown(keyCode, event) } when (keyCode) { KeyEvent.KEYCODE_MEDIA_PLAY -> { yourMediaController.dispatchMediaButtonEvent(event) return true } } return super.onKeyDown(keyCode, event) }
Java
@Override boolean onKeyDown(int keyCode, KeyEvent event) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { return super.onKeyDown(keyCode, event); } switch (keyCode) { case KeyEvent.KEYCODE_MEDIA_PLAY: yourMediaController.dispatchMediaButtonEvent(event); return true; } return super.onKeyDown(keyCode, event); }
Znajdowanie sesji multimedialnej
Jeśli działanie na pierwszym planie nie obsługuje zdarzenia, Android próbuje znaleźć która potrafi ją obsłużyć. W zależności od działającej wersji Na Androidzie dostępne są 2 sposoby wyszukiwania sesji multimediów:
Jeśli korzystasz z Androida 8.0 (poziom interfejsu API 26) lub nowszego, system próbuje znaleźć ostatnią aplikację za pomocą sesji MediaSession, która odtwarzała dźwięk lokalnie. Jeśli podczas sesji jest nadal aktywny. Android wysyła wydarzenie bezpośrednio do niego. W przeciwnym razie, jeśli sesja nie jest aktywna i ma odbiornik przycisku multimedialnego, Android wysyła zdarzenie do odbiorcy, co spowoduje ponowne uruchomienie sesji i umożliwi odebranie zdarzenia. Więcej informacji znajdziesz w artykule Ponowne uruchamianie nieaktywnej sesji multimediów przy użyciu przycisków multimediów. Jeśli sesja nie ma modułu obsługującego przycisk multimediów, system odrzuca multimedia. i nic się nie wydarzy. Logika ukazuje się w ten sposób: schemat:
W wersjach starszych niż Android 8.0 (poziom interfejsu API 26) system próbuje wysyłać zdarzenie do podczas sesji multimedialnej. Jeśli jest wiele aktywnych sesji multimediów, Android spróbuje aby wybrać sesję multimediów, która przygotowuje się do odtwarzania (buforowanie/łączenie), odtwarzania lub wstrzymania, a nie takiego, który został wstrzymany. (Zobacz Obsługa przycisków multimediów w aktywnej sesji multimediów ). Jeśli nie ma aktywnych Android próbuje wysłać zdarzenie do ostatnio aktywnej sesji. Więcej informacji znajdziesz w artykule Ponowne uruchamianie nieaktywnej sesji multimediów przy użyciu przycisków multimediów. Logikę pokazano na tym diagramie:
Obsługa przycisków multimediów w aktywnej sesji multimediów
W Androidzie 5.0 (poziom interfejsu API 21) i nowszych Android automatycznie wysyła zdarzenia przycisku multimediów do aktywnej sesji multimediów przez wywołanie
onMediaButtonEvent()
Domyślnie to wywołanie zwrotne przekształca zdarzenie KeyEvent na odpowiednią metodę wywołania zwrotnego sesji multimedialnej, która pasuje do kodu klucza.
Przed Androidem 5.0 (poziom interfejsu API 21) Android obsługuje zdarzenia przycisków multimediów przez transmitowanie intencji
z działaniem ACTION_MEDIA_BUTTON
. Aplikacja musi zarejestrować
Odbiornik BroadcastReceiver na przechwytywanie tych intencji.
MediaButtonReceiver
została opracowana specjalnie
w tym celu. Jest to klasa udogodnienia dla osób, które
Androida
biblioteki kompatybilnej z multimediami,
obsługuje intencję ACTION_MEDIA_BUTTON
i przekształca przychodzące intencje na
odpowiednie wywołania metody MediaSessionCompat.Callback
.
MediaButtonReceiver
to krótkotrwały BroadcastReceiver. Przekazuje ona wiadomości przychodzące
z intencjami do usługi, która zarządza Twoją sesją multimediów. Jeśli chcesz korzystać z usługi
w systemach Android 5.0 starszych niż 5.0 należy dodać parametr
MediaButtonReceiver
w pliku manifestu z filtrem intencji MEDIA_BUTTON
.
<receiver android:name="android.support.v4.media.session.MediaButtonReceiver" >
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
Interfejs BroadcastReceiver
przekazuje intencję do Twojej usługi. Aby przeanalizować intencję
i wygeneruj wywołanie zwrotne do sesji multimediów, umieść metodę MediaButtonReceiver.handleIntent()
w tagu onStartCommand()
usługi.
Konwertuje to kod klucza na odpowiednią metodę wywołania zwrotnego sesji.
Kotlin
private val mediaSessionCompat: MediaSessionCompat = ... override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { MediaButtonReceiver.handleIntent(mediaSessionCompat, intent) return super.onStartCommand(intent, flags, startId) }
Java
private MediaSessionCompat mediaSessionCompat = ...; public int onStartCommand(Intent intent, int flags, int startId) { MediaButtonReceiver.handleIntent(mediaSessionCompat, intent); return super.onStartCommand(intent, flags, startId); }
Używanie przycisków multimediów do ponownego uruchomienia nieaktywnej sesji multimediów
Jeśli Android rozpozna ostatnią aktywną sesję multimediów, próbuje ponownie uruchomić sesję, wysyłając intencję ACTION_MEDIA_BUTTON
do komponentu zarejestrowanego w pliku manifestu (np. usługi lub BroadcastReceiver
).
Dzięki temu aplikacja może ponownie uruchomić odtwarzanie, gdy jej interfejs jest niewidoczny (dotyczy to większości aplikacji audio).
To zachowanie jest automatycznie włączane, gdy używasz MediaSessionCompat
. Jeśli
korzysta z MediaSession
platformy Androida lub biblioteki pomocy w wersji od 24.0.0 do
25.1.1 należy wywołać setMediaButtonReceiver
, aby umożliwić ponowne uruchomienie przycisku multimediów
nieaktywna sesja multimediów.
Tę funkcję możesz wyłączyć w Androidzie 5.0 (poziom interfejsu API 21) lub nowszym przez jak ustawić odbiornik przycisku multimedialnego z pustym ekranem:
Kotlin
// Create a MediaSessionCompat mediaSession = MediaSessionCompat(context, LOG_TAG) mediaSession.setMediaButtonReceiver(null)
Java
// Create a MediaSessionCompat mediaSession = new MediaSessionCompat(context, LOG_TAG); mediaSession.setMediaButtonReceiver(null);
Dostosowywanie modułów obsługi przycisków multimediów
Domyślne działanie funkcji onMediaButtonEvent()
powoduje wyodrębnienie kodu klucza i określenie, którą metodę należy wywołać, na podstawie bieżącego stanu sesji multimediów oraz listy obsługiwanych działań. Na przykład KEYCODE_MEDIA_PLAY
wywołuje onPlay()
.
Aby przycisk multimediów był spójny we wszystkich aplikacjach, użyj
zachowanie domyślne i odbiegają tylko w konkretnym celu. Jeśli przycisk multimediów
wymaga niestandardowej obsługi, zastąp wywołanie zwrotne
onMediaButtonEvent()
wyodrębnij KeyEvent
za pomocą
intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT)
,
samodzielnie obsługuje zdarzenie i zwróci wartość true
.
Podsumowanie
Aby zapewnić prawidłową obsługę zdarzeń przycisków multimediów we wszystkich wersjach Androida, musisz:
podaj FLAG_HANDLES_MEDIA_BUTTONS
podczas tworzenia sesji multimediów.
Poza tym w zależności od tego, jakie wersje Androida chcesz obsługiwać, musisz też spełnić te wymagania:
W Androidzie 5.0 lub nowszym:
- Wywołaj funkcję
MediaControllerCompat.setMediaController()
z poziomu wywołania zwrotnego kontrolera multimediówonConnected()
- Aby umożliwić przyciskowi multimediów ponowne uruchomienie nieaktywnej sesji, dynamicznie utwórz
MediaButtonReceiver
, wywołującsetMediaButtonReceiver()
z wynikiem pozytywnymPendingIntent
W systemach starszych niż Android 5.0:
- Zastąp
onKeyDown()
aktywności, aby obsługiwać przyciski multimediów - Statycznie utwórz element
MediaButtonReceiver
, dodając go do pliku manifestu aplikacji.