7 days of WordPress plugins, themes & templates - for free!* Unlimited asset downloads! Start 7-Day Free Trial
Advertisement
  1. Code
  2. Android SDK

Hintergrundaudio in Android mit MediaSessionCompat

Read Time: 13 mins

German (Deutsch) translation by Federicco Ancie (you can also view the original English article)

Eine der beliebtesten Anwendungen für mobile Geräte ist die Wiedergabe von Audio über Musik-Streaming-Dienste, heruntergeladene Podcasts oder eine beliebige andere Anzahl von Audioquellen. Dies ist zwar eine ziemlich häufige Funktion, ist jedoch schwer zu implementieren, da viele verschiedene Teile korrekt erstellt werden müssen, um Ihrem Benutzer das volle Android-Erlebnis zu bieten.

In diesem Tutorial erfahren Sie mehr über MediaSessionCompat aus der Android-Supportbibliothek und wie Sie damit einen geeigneten Hintergrundaudiodienst für Ihre Benutzer erstellen können.

Einrichten

Als erstes müssen Sie die Android-Supportbibliothek in Ihr Projekt aufnehmen. Dies können Sie tun, indem Sie die folgende Zeile in die Datei build.gradle Ihres Moduls unter dem Knoten Abhängigkeiten einfügen.

Nachdem Sie Ihr Projekt synchronisiert haben, erstellen Sie eine neue Java-Klasse. Für dieses Beispiel nenne ich die Klasse BackgroundAudioService. Diese Klasse muss MediaBrowserServiceCompat erweitern. Außerdem werden wir folgende Schnittstellen implementieren: MediaPlayer.OnCompletionListener und AudioManager.OnAudioFocusChangeListener.

Nachdem Ihre MediaBrowserServiceCompat-Implementierung jetzt erstellt wurde, nehmen wir uns einen Moment Zeit, um AndroidManifest.xml zu aktualisieren, bevor wir zu dieser Klasse zurückkehren. Oben in der Klasse müssen Sie die WAKE_LOCK-Berechtigung anfordern.

Deklarieren Sie als Nächstes innerhalb des application-Knotens Ihren neuen Dienst mit den folgenden intent-filter-Elementen. Dadurch kann Ihr Dienst Steuertasten, Kopfhörerereignisse und das Durchsuchen von Medien für Geräte wie Android Auto abfangen (obwohl wir in diesem Tutorial nichts mit Android Auto tun werden, wird von MediaBrowserServiceCompat dennoch einige grundlegende Unterstützung dafür benötigt).

Schließlich müssen Sie die Verwendung des MediaButtonReceiver aus der Android-Supportbibliothek deklarieren. Auf diese Weise können Sie Interaktionen mit Mediensteuerungstasten und Kopfhörerereignisse auf Geräten abfangen, auf denen KitKat und früher ausgeführt wird.

Nachdem Ihre AndroidManifest.xml-Datei fertig ist, können Sie sie schließen. Wir werden auch eine weitere Klasse namens MediaStyleHelper erstellen, die von Ian Lake, Developer Advocate bei Google, geschrieben wurde, um die Erstellung von Medienstilbenachrichtigungen zu bereinigen.

Sobald das erstellt wurde, fahren Sie fort und schließen Sie die Datei. Wir werden uns im nächsten Abschnitt auf den Hintergrundaudiodienst konzentrieren.

Aufbau des Hintergrundaudiodienstes

Jetzt ist es an der Zeit, sich mit dem Kern der Erstellung Ihrer Medien-App zu befassen. Es gibt einige Membervariablen, die Sie zuerst für diese Beispiel-App deklarieren möchten: einen MediaPlayer für die eigentliche Wiedergabe und ein MediaSessionCompat-Objekt, das Metadaten und Wiedergabesteuerelemente/-zustände verwaltet.

Außerdem benötigen Sie einen BroadcastReceiver, der auf Änderungen des Kopfhörerstatus lauscht. Der Einfachheit halber hält dieser Receiver den MediaPlayer an, wenn er abgespielt wird.

Für die letzte Membervariable erstellen Sie ein MediaSessionCompat.Callback-Objekt, das zum Behandeln des Wiedergabestatus verwendet wird, wenn Mediensitzungsaktionen auftreten.

Wir werden jede der oben genannten Methoden später in diesem Tutorial wiederholen, da sie verwendet werden, um Vorgänge in unserer Medien-App zu steuern.

Es gibt zwei Methoden, die wir ebenfalls deklarieren müssen, obwohl sie für die Zwecke dieses Tutorials nichts tun müssen: onGetRoot() und onLoadChildren(). Sie können den folgenden Code für Ihre Standardeinstellungen verwenden.

Schließlich möchten Sie die Methode onStartCommand() überschreiben, die den Einstiegspunkt in Ihren Service darstellt. Diese Methode nimmt den an den Service übergebenen Intent und sendet ihn an die MediaButtonReceiver-Klasse.

Alle Dinge initialisieren

Nachdem Ihre Basiselementvariablen erstellt wurden, ist es an der Zeit, alles zu initialisieren. Dazu rufen wir verschiedene Hilfsmethoden in onCreate() auf.

Die erste Methode, initMediaPlayer(), initialisiert das MediaPlayer-Objekt, das wir oben in der Klasse erstellt haben, fordert einen teilweisen Wakelock an (weshalb wir diese Berechtigung in AndroidManifest.xml benötigt haben) und legt die Lautstärke des Players fest.

Mit der nächsten Methode, initMediaSession(), initialisieren wir das MediaSessionCompat-Objekt und verbinden es mit den Medienschaltflächen und Steuermethoden, die es uns ermöglichen, Wiedergabe und Benutzereingaben zu verarbeiten. Diese Methode beginnt mit dem Erstellen eines ComponentName-Objekts, das auf die MediaButtonReceiver-Klasse der Android-Supportbibliothek verweist, und verwendet diese zum Erstellen eines neuen MediaSessionCompat. Anschließend übergeben wir das zuvor erstellte MediaSession.Callback-Objekt und setzen die erforderlichen Flags zum Empfangen von Medientasteneingaben und Steuersignalen. Als Nächstes erstellen wir einen neuen Intent für die Verarbeitung von Medientasteneingaben auf Pre-Lollipop-Geräten und legen das Mediensitzungstoken für unseren Dienst fest.

Schließlich registrieren wir den BroadcastReceiver, den wir oben in der Klasse erstellt haben, damit wir auf Kopfhörerwechselereignisse lauschen können.

Umgang mit Audiofokus

Nachdem Sie die Initialisierung der BroadcastReceiver-, MediaSessionCompat- und MediaPlayer-Objekte abgeschlossen haben, ist es an der Zeit, sich mit der Handhabung des Audiofokus zu befassen.

Während wir vielleicht denken, dass unsere eigenen Audio-Apps derzeit die wichtigsten sind, konkurrieren andere Apps auf dem Gerät darum, ihre eigenen Sounds zu erzeugen, z. B. eine E-Mail-Benachrichtigung oder ein Handyspiel. Um mit diesen verschiedenen Situationen zu arbeiten, verwendet das Android-System den Audiofokus, um zu bestimmen, wie Audio behandelt werden soll.

Der erste Fall, den wir behandeln möchten, ist das Starten der Wiedergabe und der Versuch, den Fokus des Geräts zu erhalten. Gehen Sie in Ihrem MediaSessionCompat.Callback-Objekt in die Methode onPlay() und fügen Sie die folgende Bedingungsprüfung hinzu.

Der obige Code ruft eine Hilfsmethode auf, die versucht, den Fokus abzurufen, und wenn dies nicht möglich ist, wird einfach zurückgegeben. In einer echten App möchten Sie die fehlgeschlagene Audiowiedergabe eleganter behandeln. successfullyRetrievedAudioFocus() ruft einen Verweis auf den AudioManager des Systems ab und versucht, den Audiofokus für das Streamen von Musik anzufordern. Es gibt dann einen boolean Wert zurück, der angibt, ob die Anforderung erfolgreich war oder nicht.

Sie werden feststellen, dass wir this auch an die Methode requestAudioFocus() übergeben, die den OnAudioFocusChangeListener mit unserem Dienst verknüpft. Es gibt ein paar verschiedene Zustände, auf die Sie achten sollten, um ein "guter Bürger" im App-Ökosystem des Geräts zu sein.

  • AudioManager.AUDIOFOCUS_LOSS: Dies tritt auf, wenn eine andere App den Audiofokus angefordert hat. In diesem Fall sollten Sie die Audiowiedergabe in Ihrer App stoppen.
  • AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: Dieser Zustand wird erreicht, wenn eine andere App Audio abspielen möchte, aber erwartet, dass sie nur für kurze Zeit fokussiert werden muss. Sie können diesen Status verwenden, um Ihre Audiowiedergabe zu unterbrechen.
  • AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: Wenn der Audio-Fokus angefordert wird, aber den Status "kann sich ducken" auslöst, bedeutet dies, dass Sie Ihre Wiedergabe fortsetzen können, die Lautstärke jedoch etwas verringern sollten. Dies kann auftreten, wenn ein Benachrichtigungston vom Gerät abgespielt wird.
  • AudioManager.AUDIOFOCUS_GAIN: Der letzte Zustand, den wir besprechen werden, ist AUDIOFOCUS_GAIN. Dies ist der Zustand, wenn eine Duckable-Audiowiedergabe abgeschlossen ist und Ihre App auf den vorherigen Ebenen fortgesetzt werden kann.

Ein vereinfachter onAudioFocusChange()-Callback kann wie folgt aussehen:

Den MediaSessionCompat.Callback verstehen

Nachdem Sie nun eine allgemeine Struktur für Ihren Service erstellt haben, ist es an der Zeit, in den MediaSessionCompat.Callback einzutauchen. Im letzten Abschnitt haben Sie onPlay() ein wenig hinzugefügt, um zu überprüfen, ob der Audiofokus gewährt wurde. Unterhalb der bedingten Anweisung möchten Sie das MediaSessionCompat-Objekt auf aktiv setzen, ihm den Status STATE_PLAYING geben und die richtigen Aktionen zuweisen, die zum Erstellen von Pausenschaltflächen für Sperrbildschirm-Steuerelemente vor dem Lollipop, Telefon- und Android Wear-Benachrichtigungen erforderlich sind.

Die obige Methode setMediaPlaybackState() ist eine Hilfsmethode, die ein PlaybackStateCompat.Builder-Objekt erstellt und ihm die richtigen Aktionen und den richtigen Zustand zuweist und dann ein PlaybackStateCompat erstellt und Ihrem MediaSessionCompat-Objekt zuordnet.

Beachten Sie, dass Sie in Ihren Aktionen sowohl das ACTION_PLAY_PAUSE- als auch das ACTION_PAUSE- oder ACTION_PLAY-Flag benötigen, um die richtige Steuerung auf Android Wear zu erhalten.

Media notification on Android WearMedia notification on Android WearMedia notification on Android Wear

Zurück in onPlay() möchten Sie eine Wiedergabebenachrichtigung anzeigen, die Ihrem MediaSessionCompat-Objekt zugeordnet ist, indem Sie die zuvor definierte MediaStyleHelper-Klasse verwenden, und dann diese Benachrichtigung anzeigen.

Schließlich starten Sie den MediaPlayer am Ende von onPlay().

Media control notification on an Android Nougat deviceMedia control notification on an Android Nougat deviceMedia control notification on an Android Nougat device

Wenn der Callback einen Pause-Befehl erhält, wird onPause() aufgerufen. Hier pausieren Sie den MediaPlayer, setzen den Status auf STATE_PAUSED und zeigen eine pausierte Benachrichtigung an.

Unsere showPausedNotification()-Hilfsmethode sieht ähnlich aus wie die showPlayNotification()-Methode.

Die nächste Methode im Callback, die wir besprechen werden, onPlayFromMediaId(), verwendet einen String und ein Bundle als Parameter. Dies ist die Rückrufmethode, die Sie zum Ändern von Audiospuren/Inhalten in Ihrer App verwenden können.

Für dieses Tutorial akzeptieren wir einfach eine Rohressourcen-ID und versuchen, diese abzuspielen, und initialisieren dann die Metadaten der Sitzung neu. Da Sie ein Bundle an diese Methode übergeben dürfen, können Sie damit andere Aspekte Ihrer Medienwiedergabe anpassen, z. B. das Einrichten eines benutzerdefinierten Hintergrundsounds für einen Track.

Nachdem wir nun die beiden Hauptmethoden in diesem Rückruf besprochen haben, die Sie in Ihren Apps verwenden werden, ist es wichtig zu wissen, dass es andere optionale Methoden gibt, mit denen Sie Ihren Dienst anpassen können. Einige Methoden umfassen onSeekTo(), mit dem Sie die Wiedergabeposition Ihres Inhalts ändern können, und onCommand(), das einen String akzeptiert, der den Befehlstyp angibt, ein Bundle für zusätzliche Informationen zum Befehl und einen ResultReceiver-Rückruf, der ermöglicht es Ihnen, benutzerdefinierte Befehle an Ihren Service zu senden.

Abreißen

Wenn unsere Audiodatei fertig ist, möchten wir entscheiden, was unsere nächste Aktion sein wird. Während Sie vielleicht den nächsten Titel in Ihrer App abspielen möchten, halten wir die Dinge einfach und veröffentlichen den MediaPlayer.

Schließlich möchten wir noch ein paar Dinge in der onDestroy()-Methode unseres Service tun. Rufen Sie zunächst einen Verweis auf den AudioManager des Systemdienstes ab und rufen Sie AbandonAudioFocus() mit unserem AudioFocusChangeListener als Parameter auf, der andere Apps auf dem Gerät benachrichtigt, dass Sie den Audiofokus aufgeben. Heben Sie als Nächstes die Registrierung des BroadcastReceivers auf, der für die Überwachung von Kopfhöreränderungen eingerichtet wurde, und geben Sie das MediaSessionCompat-Objekt frei. Schließlich möchten Sie die Benachrichtigung zur Wiedergabesteuerung abbrechen.

An dieser Stelle sollten Sie über einen funktionierenden grundlegenden Hintergrundaudio Service verfügen, der MediaSessionCompat für die Wiedergabesteuerung auf allen Geräten verwendet. Während es bereits viel getan hat, um den Dienst zu erstellen, sollten Sie in der Lage sein, die Wiedergabe von Ihrer App, einer Benachrichtigung, einer Sperrbildschirmsteuerung auf Pre-Lollipop-Geräten (Lollipop und höher verwenden die Benachrichtigung auf dem Sperrbildschirm) zu steuern. und von Peripheriegeräten wie Android Wear, sobald der Service gestartet wurde.

Media lock screen controls on Android Kit KatMedia lock screen controls on Android Kit KatMedia lock screen controls on Android Kit Kat

Starten und Steuern von Inhalten aus einer Aktivität

Während die meisten Steuerelemente automatisch erfolgen, haben Sie noch ein wenig Arbeit, um eine Mediensitzung über Ihre In-App-Steuerelemente zu starten und zu steuern. Zumindest möchten Sie, dass in Ihrer App ein MediaBrowserCompat.ConnectionCallback-, MediaControllerCompat.Callback-, MediaBrowserCompat- und MediaControllerCompat-Objekt erstellt wird.

MediaControllerCompat.Callback verfügt über eine Methode namens onPlaybackStateChanged(), die Änderungen im Wiedergabestatus empfängt und verwendet werden kann, um Ihre Benutzeroberfläche synchron zu halten.

MediaBrowserCompat.ConnectionCallback verfügt über eine onConnected()-Methode, die aufgerufen wird, wenn ein neues MediaBrowserCompat-Objekt erstellt und verbunden wird. Sie können dies verwenden, um Ihr MediaControllerCompat-Objekt zu initialisieren, es mit Ihrem MediaControllerCompat.Callback zu verknüpfen und es mit MediaSessionCompat von Ihrem Service zu verknüpfen. Sobald dies abgeschlossen ist, können Sie die Audiowiedergabe mit dieser Methode starten.

Sie werden feststellen, dass der obige Codeausschnitt getSupportMediaController().getTransportControls() verwendet, um mit der Mediensitzung zu kommunizieren. Mit derselben Technik können Sie onPlay() und onPause() im MediaSessionCompat.Callback-Objekt Ihres Audiodienstes aufrufen.

Wenn Sie mit der Audiowiedergabe fertig sind, können Sie den Audiodienst anhalten und Ihr MediaBrowserCompat-Objekt trennen, was wir in diesem Tutorial tun werden, wenn diese Activity zerstört wird.

Einpacken

Wütend! Wie Sie sehen können, gibt es viele bewegliche Teile, die mit der korrekten Erstellung und Verwendung eines Hintergrundaudiodienstes verbunden sind.

In diesem Tutorial haben Sie einen Dienst erstellt, der eine einfache Audiodatei abspielt, auf Änderungen des Audiofokus wartet und eine Verknüpfung zu MediaSessionCompat erstellt, um eine universelle Wiedergabesteuerung auf Android-Geräten, einschließlich Mobilteilen und Android Wear, bereitzustellen. Wenn Sie beim Durcharbeiten dieses Tutorials auf Hindernisse stoßen, empfehle ich dringend, den zugehörigen Android-Projektcode auf dem GitHub von Envato Tuts+ zu überprüfen.

Schauen Sie sich auch einige unserer anderen Android-Kurse und -Tutorials hier auf Envato Tuts+ an!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Scroll to top
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.