W serii „Twoja aplikacja” będę pokazywał, w jaki sposób stworzyć aplikację kompletną wraz z najważniejszymi komponentami. Taka aplikacja będzie posiadać wszystkie podstawowe rzeczy, która powinna mieć. Seria będzie podzielona na części, a każda część będzie zawierać poszczególne zagadnienie.

 

W tej serii stworzymy aplikację o odtwarzania muzyki wraz z najważniejszymi komponentami.

  1. Część 1: MediaSession i MediaController
  2. Cześć 2: AudioFocus

W artykule omówimy architekturę i interfejs API do tworzenia aplikacji odtwarzających muzykę. Napiszemy prostą aplikację, która będzie odtwarzać utwór za pomocą oficjalnie zalecanych praktyk. Będziemy używać MediaSessionMediaController do zorganizowania jednego punktu dostępu do odtwarzacza multimedialnego. Ponadto określę kilka kroków, które są obowiązkowe, jeśli nie chcesz robić problemów użytkownikowi.

Zadanie wygląda na proste, tworzymy MediaPlayer, po naciśnięciu przycisku Play, zaczyna odtwarzanie, Stop – zatrzymuje. Wszystko działa dobrze, dopóki użytkownik nie zamknie aplikacji. Oczywistym rozwiązaniem jest przeniesienie MediaPlayer’a do usługi. Tutaj pojawia się dylemat dotyczący organizacji dostępu do odtwarzacza z interfejsu użytkownika. Będziemy musieli wdrożyć bindservice i stworzyć dla niej API, które pozwoli nam kontrolować odtwarzacz i odbierać z niego zdarzenia. Ale to tylko połowa drogi, nikt poza nami nie zna API usługi. Użytkownik będzie musiał wejść do aplikacji i nacisnąć Pause, jeśli chce zadzwonić. Dlatego potrzebujemy sposobu aby poinformowania system Android, że ​​nasza aplikacja jest odtwarzaczem, może być kontrolowana i że w tej chwili gramy taki i taki utwór z takiego i tego albumu. W tym momencie właśnie pojawia się MediaSession i MediaController wprowadzony w wersji Lollipop (API 21). Nieco później w bibliotece wsparcia pojawili się ich bliźniacy MediaSessionCompat i MediaControllerCompat.

1. Czym jest MediaSession?

MediaSession – to interfejs pośredniczące między Twoją aplikacją a innymi urządzeniami (Android TV, Android Wear, Android Auto, przyciski multimedialne itp.), które mogą kontrolować aplikacje multimedialnie. Czyli to oprogramowanie, które pozwala na kontrolowanie multimediów w Twojej aplikacji poza interfejsem użytkownika aplikacji. MediaSession to nie odtwarzacz multimedialny taki jak MediaPlayer, Aby dokładniej to zrozumieć, spójrz na poniższy diagram:

Jeżeli użytkownik naciśnie przycisk pauzy na słuchawkach to system wyszukuje, która aplikacja ostatnio miała aktywną sesję multimedialną, Następnie ta aplikacja za pomocą MediaSession odbiera to działanie i wywołuje metodą onPause(), a ta metoda przesyła sygnał do Twojego odtwarzacza, który zatrzymuje dźwięk. Warto też poinformować z powrotem MediaSession, że zatrzymałeś dźwięk. wywołując setPlaybackState() z nowym stanem odtwarzania (w tym przypadku, utwór jest spauzowany), a jednocześnie też informujesz systemu Android. Interfejs użytkownika Twojej aplikacji powinien również łączyć się z MediaSession w celu wywołania onPlaybackStateChanged() w celu poinformowania UI aplikacji, że stan odtwarzania się zmienił – zmiana ikonki z Play na Pause.

2. Do czego służy MediaSession?

MediaSession najczęściej jest używana w aplikacjach do odtwarzania muzyki, a interfejs nie zawsze znajduje się na pierwszym planie. Możesz też użyć to w aplikacjach, które wyświetlają wideo. MediaSession wykonuje następujące czynności:

  • sterowaniem odtwarzaniem -  zapewnia pojedynczy interfejs do sterowania odtwarzaniem. Możesz korzystać z wielu podmiotów aby kontrolować stan odtwarzania, np.pauza, zatrzymanie, przejście do następnego utworu. Nie musisz tworzyć dla każdego urządzenia specjalnego kodu, który będzie kontrolował ten stan.
  • synchronizacja stanu  - nadaje bieżący stan odtwarzania (odtwarzanie, wstrzymanie, zatrzymanie itp.). Dodatkowo możesz uzyskać metadane mediów (okładka albumu, czas trwania utworu, tytuł utworu itp.). Dzięki temu zabiegowi wszystkie urządzenia które są połączone z Twoją aplikacją mogą dostawać takie informacje.

3. Jak tego używać?

Poniżej przedstawię kod, dzięki któremu będziesz mógł kontrolować MediaPlayer za pomocą telefonu + dodatkowego urządzenia podłączonego do sesji medialnej (w moim przypadku będzie to zegarek Garmin).

Na samym początku s stworzymy usługę z MediaSession i MediaPlayer. W AndroidManifest.xml dodajemy wpis:

Wpis intent-filter informuje system, że potrzebujemy odbierać zdarzenia z przycisków multimedialnych. Tworzony naszą klasę i rozszerzamy o Service. Metoda onCreate() może wyglądać tak:

Metoda initMediaSession():

Tworzymy instancję MediaSession i nadajemy odpowiednie flagi. Przypisujemy callbacka, a on może wyglądać tak:

W metodzie onPlay() aktywujemy MediaSession (tymczasowo komentarz), a w metodzie onStop() dezaktywujemy. Tutaj podałem Ci tylko 3 przykładowe przyciski. Jeżeli będziesz robił aplikację pamiętaj aby zaimplementować więcej przycisków takich jak, następny/poprzedni utwór, zmiana głośności. Zastanawiasz się też pewnie jak obsłużyć długie przyciśnięcie przycisku oraz podwójny klik. W tym celu musisz nadpisać metodę MediaSession.Callback.onMediaButtonEvent() Przykładowy kod możesz znaleźć tutaj.

Wracając do naszego kodu, również informujemy system o stanie odtwarzania – setPlaybackState() i aktualizujemy metadane o utworze – updateMetadata(). A ta metoda może wyglądać tak:

Jeszcze została nam metoda initMediaPlayer():

Pomijam tutaj pełną implementację tego odtwarzacza, ponieważ do przykładu nie jest to nam potrzebne. Czyli brakuje tutaj onError(), onPrepared() itd. Pamiętaj, że musisz też napisać kod, który będzie informował sesję medialną  o zakończeniu utworu czy przejściu na następny utwór.

Jeszcze zostało nam wystartowanie usługi w aktywności:

Działa? Na pewno. Podłącz słuchawki i sprawdź. A jak sterować za pomocą innego urządzenia, np.: zegarka? Wystarczy dostać uprawnienia do powiadomień systemu Android. W aktywności dodajmy i wywołujemy metodę:

Jak już masz dostęp do powiadomień, możemy również odczytywać dane z sesji multimedialnej (niekoniecznie stworzoną przez Twoją aplikację):

Jak widzisz, możesz odczytać dane o utworze i sterować też odtwarzaniem obcej aplikacji. Tak dobrze rozumiesz podłączysz się do innej aplikacji, która korzysta z MediaSession. Uważaj! Może być kilka sesji aktywnych i musisz wybrać z której chcesz korzystać.

Pamiętaj dodać wpis do AndroidMenifest.xml:

oraz utworzeniu klasy:

4. Sterowanie za pomocą przycisków UI.

Ok, mamy już aktywną usługę, która sobie gra. Zmodyfikujmy naszą aktywność w taki sposób, aby muzyka odtwarzała się po naciśnięciu play, a nie zaraz po uruchomieniu aktywności. Nasza aktywność może wyglądać tak:

W klasie PlayerService dodajemy:

Teraz gdy naciśniemy na telefonie przycisk play, muzyka zacznie grać. W zależności od stanu odtwarzania, poszczególne przyciski będą aktywne. Jeśli odtwarzana jest muzyka to przycisk play jest nieaktywny, a przyciski pause i stop są aktywne.

Jeszcze została nam mała modyfikacja. Usuń z metody initMediaPlayer ten wpis:

A w metodzie onPlay() odkomentuj aktywowanie sesji medialnej. Teraz masz sterowanie za pomocą UI oraz innego urządzenia.

5. Wparcie dla APi <21.

Jeżeli Twoja aplikacja ma działać na API<21 musisz dodać wsparcie. W AndroidManifest.xml dodaj taki wpis:

Jeśli odpowiednia usługa, która odpowiada za odbieranie sygnałów z przycisków nie zostanie znaleziona lub jest ich kilka, zostanie zgłoszony wyjątek IllegalStateException. Teraz dodaj do usługi taki wpis:

Metoda handleIntent() analizuje kody przycisków z intencji i wywołuje odpowiednie wywołania zwrotne w MediaSession.

W systemach z API>=21, system uzyskuje bezpośrednio dostęp do MediaSession, nie używa rozgłaszaczy do zdarzeń odbieranych z przycisków. Jeśli jednak nasza sesja multimedialna jest nieaktywna – setActive(false), i chcesz ją aktywować skorzystaj z poniższego kodu. W klasie z usługą, w metodzie onCreate() dodaj:

W systemach z API<21, metoda setMediaButtonReceiver nie robi nic.

6. Podsumowanie

MediaSession to interfejs, który łączy z jednej strony Twój odtwarzacz audio lub video, z drugiej strony mamy urządzenia lub kontrolki, za pomocą których możemy kontrolować i odczytywać dane o sesji medialnej oraz informujemy system co aktualnie aplikacja robi. Pamiętaj  że MediaSession nie ma nic wspólnego z reprodukcją dźwięku, chodzi tylko o kontrolowanie odtwarzacza i jego metadanych. Po przeczytaniu tego wpisu wiesz w jaki sposób stworzyć sesję medialną oraz jak do niej się podłączyć i nią zarządzać.

Dzięki za poświęcony czas 🙂 Jeżeli podobał Ci się wpis udostępnij go dalej. Będę Ci za to bardzo wdzięczny. Dzięki!

Miłego kodowania 🙂

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *