Audio de fundal în Android Cu MediaSessionCompat

Una dintre cele mai populare utilizări pentru dispozitive mobile este redarea audio prin servicii de streaming muzical, podcasturi descărcate sau orice alt număr de surse audio. În timp ce aceasta este o caracteristică destul de comună, este greu de implementat, cu o mulțime de piese diferite care trebuie construite corect, pentru a oferi utilizatorilor dvs. experiența Android completă. 

În acest tutorial veți afla despre MediaSessionCompat din biblioteca de asistență Android și cum poate fi utilizată pentru a crea un serviciu audio de fundal adecvat pentru utilizatorii dvs..

Înființat

Primul lucru pe care trebuie să-l faceți este să includeți biblioteca de asistență Android în proiectul dvs. Acest lucru se poate face adăugând următoarea linie în modulul dvs. build.gradle fișier în cadrul nodului dependențelor.

compile 'com.android.support:support-v13:24.2.1'

După ce ați sincronizat proiectul, creați o nouă clasă Java. Pentru acest exemplu voi numi clasa BackgroundAudioService. Această clasă va trebui să se extindă MediaBrowserServiceCompat. Vom implementa, de asemenea, următoarele interfețe: MediaPlayer.OnCompletionListener și AudioManager.OnAudioFocusChangeListener.

Acum, că dvs. MediaBrowserServiceCompat implementarea este creată, să facem un moment de actualizare AndroidManifest.xml înainte de a reveni la această clasă. În partea de sus a clasei, va trebui să solicitați WAKE_LOCK permisiune.

Apoi, în cadrul cerere nod, declarați noul dvs. serviciu cu următoarele intenție-filtru articole. Acestea vor permite serviciului dvs. să intercepteze butoanele de control, evenimentele căștilor și navigarea în mass-media pentru dispozitive, cum ar fi Android Auto (deși nu vom face nimic cu Android Auto pentru acest tutorial, MediaBrowserServiceCompat).

      

În cele din urmă, va trebui să declarați utilizarea MediaButtonReceiver din biblioteca de asistență Android. Acest lucru vă va permite să interceptați interacțiunile butoanelor de control media și evenimentele pentru căști pe dispozitivele care rulează KitKat și mai devreme.

     

Acum, că dvs. AndroidManifest.xml fișierul este terminat, îl puteți închide. De asemenea, vom crea o altă clasă numită MediaStyleHelper, care a fost scris de Ian Lake, Avocat dezvoltator la Google, pentru a curăța crearea de notificări de stil media.

public class MediaStyleHelper / ** * Creați o notificare utilizând informațiile din sesiunea media dată. Utilizează grele * din @link MediaMetadataCompat # getDescription () pentru a extrage informațiile corespunzătoare. * @ context param Contextul folosit pentru a construi notificarea. * @param mediaSession Media sesiune pentru a obține informații. * @ return O notificare pre-construită cu informații din sesiunea media dată. * / public Static NotificareCompat.Builder din (Context context, MediaSessionCompat mediaSession) MediaControllerCompact controller = mediaSession.getController (); MediaMetadataCompat mediaMetadata = controller.getMetadata (); MediaDescriptionCompat descriere = mediaMetadata.getDescription (); NotificareCompat.Builder builder = Notificare nouăCompat.Builder (context); constructor .setContentTitle (description.getTitle ()) .setContentText (description.getSubtitle ()) .setSubText (descriere.getDescription ()) .setLargeIcon (descriere.getIconBitmap ()) .setContentIntent (controller.getSessionActivity ()) .setDeleteIntent (MediaButtonReceiver .buildMediaButtonPendingIntent (context, PlaybackStateCompat.ACTION_STOP)) .setVisibility (NotificareCompat.VISIBILITY_PUBLIC); constructor de returnari; 

După ce a fost creat, continuați și închideți fișierul. Ne vom concentra pe serviciul audio de fundal în secțiunea următoare.

Construirea serviciului audio de fundal

Acum este timpul să vă grăbiți să creați aplicația media. Există câteva variabile membre pe care doriți să le declarați mai întâi pentru această aplicație probă: a Media Player pentru redarea reală și a MediaSessionCompat obiect care va gestiona metadatele și controalele / stările de redare.

private MediaPlayer mMediaPlayer; private MediaSessionCompat mMediaSessionCompat;

În plus, veți avea nevoie de a BroadcastReceiver care ascultă schimbările în starea căștilor. Pentru a menține lucrurile simple, acest receptor va întrerupe Media Player, dacă se joacă.

privat BroadcastReceiver mNoisyReceiver = nou BroadcastReceiver () @Override public void onReceive (Context context, Intent intent) if (mMediaPlayer! = null && mMediaPlayer.isPlaying ()) mMediaPlayer.pause (); ;

Pentru variabila finală membru, veți crea o MediaSessionCompat.Callback obiect, care este utilizat pentru a gestiona starea redării când apar acțiuni de sesiune media.

privat MediaSessionCompat.Callback mMediaSessionCallback = nou MediaSessionCompat.Callback () @Override public void onPlay () super.onPlay ();  @Override public void pePause () super.onPause ();  @Override public void pePlayFromMediaId (String mediaId, Extras pachet) super.onPlayFromMediaId (mediaId, extras); ;

Vom revizui fiecare dintre metodele de mai sus mai târziu în acest tutorial, deoarece acestea vor fi folosite pentru a conduce operațiile în aplicația noastră media.

Există două metode pe care va trebui să le declarăm, deși nu vor trebui să facă nimic în scopul acestui tutorial: onGetRoot () și onLoadChildren (). Puteți utiliza codul următor pentru setările prestabilite.

@Nullable @Override public BrowserRoot onGetRoot (@NonNull String clientPackageName, int clientUid, @Nullable Bundle rootHints) if (TextUtils.equals (clientPackageName, getPackageName ())) returnează noul BrowserRoot (getString (R.string.app_name), null );  return null;  // Nu este important pentru serviciul audio general, necesar pentru clasa @Override public void onLoadChildren (@NonNull String parentId, @NonNull Result> rezultat) result.sendResult (null); 

În cele din urmă, veți dori să suprascrieți onStartCommand () metoda, care este punctul de intrare în dvs. Serviciu. Această metodă va lua intenția care va fi trecută la Serviciu și trimiteți-l la MediaButtonReceiver clasă.

@Override public int peStartCommand (Intent intent, int flags, int startId) MediaButtonReceiver.handleIntent (mMediaSessionCompat, intent); returnează super.onStartCommand (intenție, steaguri, startId); 

Inițializarea tuturor lucrurilor

Acum, când variabilele dvs. de bază sunt create, este timpul să inițializați totul. Vom face asta prin apelarea diferitelor metode de ajutor onCreate ().

@Override publice void onCreate () super.onCreate (); initMediaPlayer (); initMediaSession (); initNoisyReceiver (); 

Prima metodă, initMediaPlayer (), va inițializa Media Player obiect pe care l-am creat la vârful clasei, cereți blocarea parțială a treptelor (motiv pentru care am solicitat permisiunea AndroidManifest.xml) și setați volumul playerului.

void privat initMediaPlayer () mMediaPlayer = nou MediaPlayer (); mMediaPlayer.setWakeMode (getApplicationContext (), PowerManager.PARTIAL_WAKE_LOCK); mMediaPlayer.setAudioStreamType (AudioManager.STREAM_MUSIC); mMediaPlayer.setVolume (1.0f, 1.0f); 

Următoarea metodă, initMediaSession (), este locul unde inițializăm MediaSessionCompat obiecte și conectați-le la butoanele media și metodele de control care ne permit să gestionăm redarea și intrarea utilizatorilor. Această metodă începe prin crearea unui ComponentName obiect care indică biblioteca de suport Android MediaButtonReceiver clasă și utilizează pentru a crea un nou MediaSessionCompat. Apoi vom trece MediaSession.Callback obiect pe care l-am creat mai devreme și setând steagurile necesare pentru recepționarea intrărilor de butoane media și a semnalelor de control. Apoi, vom crea un nou scop pentru a manipula intrările butoanelor media pe dispozitivele pre-Lollipop și pentru a seta jetonul sesiunii media pentru serviciul nostru.

void privat initMediaSession () ComponentName mediaButtonReceiver = nume Component nou (getApplicationContext (), MediaButtonReceiver.class); mMediaSessionCompat = nou MediaSessionCompat (getApplicationContext (), "Tag", mediaButtonReceiver, null); mMediaSessionCompat.setCallback (mMediaSessionCallback); mMediaSessionCompat.setFlags (MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); Intenția mediaButtonIntent = intenția nouă (Intent.ACTION_MEDIA_BUTTON); mediaButtonIntent.setClass (aceasta, MediaButtonReceiver.class); PendingIntent pendingIntent = PendingIntent.getBroadcast (aceasta, 0, mediaButtonIntent, 0); mMediaSessionCompat.setMediaButtonReceiver (pendingIntent); setSessionToken (mMediaSessionCompat.getSessionToken ()); 

În cele din urmă, vom înregistra BroadcastReceiver pe care am creat-o la vârful clasei, astfel încât să putem asculta evenimentele de schimbare a căștilor.

private void initNoisyReceiver () // Mânerele căștilor care au fost deconectate. nu se poate face printr-un receptor manifest IntentFilter filter = new IntentFilter (AudioManager.ACTION_AUDIO_BECOMING_NOISY); registerReceiver (mNoisyReceiver, filtru); 

Manipularea focalizării audio

Acum că ați terminat inițializarea BroadcastReceiver, MediaSessionCompat și Media Player obiecte, este timpul să te uiți în manevrarea focalizării audio. 

În timp ce ne putem gândi că aplicațiile audio proprii sunt cele mai importante momentan, alte aplicații de pe dispozitiv vor concura pentru a-și face propriile sunete, cum ar fi o notificare prin e-mail sau un joc mobil. Pentru a lucra cu aceste situații diferite, sistemul Android folosește focalizarea audio pentru a determina modul în care ar trebui să fie tratată audio. 

Primul caz pe care vom dori să-l rezolvăm este începerea redării și încercarea de a primi focalizarea dispozitivului. În tine MediaSessionCompat.Callback obiect, intră în onPlay () și adăugați următoarea verificare a condițiilor.

@Override public void pePlay () super.onPlay (); dacă (! successfullyRetrievedAudioFocus ()) return; 

Codul de mai sus va apela o metodă de ajutor care încearcă să recupereze focalizarea și dacă nu poate, va reveni pur și simplu. Într-o aplicație reală, ați dori să vă ocupați de redarea eșuată a sunetului mai grațios. successfullyRetrievedAudioFocus () va primi o referință la sistem AudioManager, și încercați să solicitați focalizarea audio pentru streaming muzică. Acesta va reveni apoi a boolean reprezentând dacă cererea a fost sau nu reușită.

boolean privat cu succesRetrievedAudioFocus () AudioManager audioManager = (AudioManager) getSystemService (Context.AUDIO_SERVICE); int rezultat = audioManager.requestAudioFocus (aceasta, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); return rezultat == AudioManager.AUDIOFOCUS_GAIN; 

Veți observa că și noi trecem acest în requestAudioFocus () , care asociază OnAudioFocusChangeListener cu serviciul nostru. Există câteva stări diferite pe care le veți dori să le ascultați pentru a fi un "bun cetățean" în ecosistemul de aplicații al dispozitivului.

  • AudioManager.AUDIOFOCUS_LOSS: Apare atunci când o altă aplicație a solicitat focalizare audio. Când se întâmplă acest lucru, ar trebui să opriți redarea audio în aplicația dvs..
  • AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: Această stare este introdusă atunci când o altă aplicație dorește să redea audio, dar doar anticipează necesitatea focalizării pentru o perioadă scurtă de timp. Puteți utiliza această stare pentru a întrerupe redarea audio.
  • AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: Când se solicită focalizarea audio, dar aruncă o stare "poate rață", înseamnă că puteți continua redarea, dar ar trebui să aducem puțin volumul. Acest lucru poate apărea atunci când dispozitivul emite un sunet de notificare.
  • AudioManager.AUDIOFOCUS_GAIN: Starea finală pe care o vom discuta este AUDIOFOCUS_GAIN. Aceasta este starea în care a fost finalizată o redare audio duckable, iar aplicația dvs. poate relua la nivelurile anterioare.

O simplificată onAudioFocusChange () inversarea apelului poate să arate astfel:

@Override public void peAudioFocusChange (int focusChange) comutare (focusChange) caz AudioManager.AUDIOFOCUS_LOSS: if (mMediaPlayer.isPlaying ()) mMediaPlayer.stop ();  pauză;  caz AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: mMediaPlayer.pause (); pauză;  caz AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: if (mMediaPlayer! = null) mMediaPlayer.setVolume (0.3f, 0.3f);  pauză;  caz AudioManager.AUDIOFOCUS_GAIN: if (mMediaPlayer! = null) if (! mMediaPlayer.isPlaying ()) mMediaPlayer.start ();  mMediaPlayer.setVolume (1.0f, 1.0f);  pauză; 

Înțelegerea MediaSessionCompat.Callback

Acum că aveți o structură generală împreună pentru dvs. Serviciu, este timpul să se scufunde în MediaSessionCompat.Callback. În ultima secțiune ați adăugat un pic la onPlay () pentru a verifica dacă sa acordat focalizarea audio. Sub instrucțiunea condiționată, veți dori să setați MediaSessionCompat obiect la activ, da-i o stare de STATE_PLAYING, și să atribuiți acțiunile potrivite necesare pentru a crea butoane de pauză în comenzile de pe ecranul de blocare pre-Lollipop, în notificările telefonului și în Android Wear.

@Override public void pePlay () super.onPlay (); dacă (! successfullyRetrievedAudioFocus ()) return;  mMediaSessionCompat.setActive (adevărat); setMediaPlaybackState (PlaybackStateCompat.STATE_PLAYING); ...

setMediaPlaybackState () Metoda de mai sus este o metodă de ajutor care creează o PlaybackStateCompat.Builder obiect și îi dă acțiunile și starea adecvată, apoi construiește și asociază a PlaybackStateCompat cu tine MediaSessionCompat obiect.

void privat setMediaPlaybackState (stare int) PlaybackStateCompat.Builder playbackstateBuilder = nou PlaybackStateCompat.Builder (); dacă (state == PlaybackStateCompat.STATE_PLAYING) playbackstateBuilder.setActions (PlaybackStateCompat.ACTION_PLAY_PAUSE | PlaybackStateCompat.ACTION_PAUSE);  altceva playbackstateBuilder.setActions (PlaybackStateCompat.ACTION_PLAY_PAUSE | PlaybackStateCompat.ACTION_PLAY);  playstateBuilder.setState (starea, PlaybackStateCompat.PLAYBACK_POSITION_UNKNOWN, 0); mMediaSessionCompat.setPlaybackState (playbackstateBuilder.build ()); 

Este important să rețineți că veți avea nevoie de ambele ACTION_PLAY_PAUSE si nici ACTION_PAUSE sau ACTION_PLAY steaguri în acțiunile dvs. pentru a obține controale adecvate pentru Android Wear.

Înapoi în onPlay (), veți dori să afișați o notificare de joc asociată cu dvs. MediaSessionCompat obiect folosind MediaStyleHelper clasa pe care am definit-o mai devreme, și apoi să afișăm această notificare.

private void showPlayingNotificare () NotificareCompat.Builder builder = MediaStyleHelper.from (BackgroundAudioService.this, mMediaSessionCompat); dacă (constructor == null) return;  builder.addAction (noua NotificareCompat.Action (android.R.drawable.ic_media_pause, "Pause", MediaButtonReceiver.buildMediaButtonPendingIntent (aceasta, PlaybackStateCompat.ACTION_PLAY_PAUSE)); builder.setStyle (noua NotificareCompat.MediaStyle (). setShowActionsInCompactView (0) .setMediaSession (mMediaSessionCompat.getSessionToken ())); builder.setSmallIcon (R.mipmap.ic_launcher); NotificareaManagerCompat.from (BackgroundAudioService.this) .notify (1, builder.build ()); 

În cele din urmă, veți începe Media Player la sfârșitul onPlay ().

@Override public void onPlay () super.onPlay (); ... showPlayingNotification (); mMediaPlayer.start (); 

Când apelul de apel primește o comandă de pauză, onPause () va fi numit. Aici veți întrerupe Media Player, setați starea la STATE_PAUSED, și să afișați o notificare în pauză.

@Override publice void onPause () super.onPause (); dacă (mMediaPlayer.isPlaying ()) mMediaPlayer.pause (); setMediaPlaybackState (PlaybackStateCompat.STATE_PAUSED); showPausedNotification (); 

Al nostru showPausedNotification () metoda de ajutor va arata similar cu showPlayNotification () metodă.

private void showPausedNotification () NotificareCompat.Builder builder = MediaStyleHelper.from (aceasta, mMediaSessionCompat); dacă (constructor == null) return;  builder.addAction (noua NotificareCompat.Action (android.R.drawable.ic_media_play, "Play", MediaButtonReceiver.buildMediaButtonPendingIntent (aceasta, PlaybackStateCompat.ACTION_PLAY_PAUSE)); builder.setStyle (noua NotificareCompat.MediaStyle (). setShowActionsInCompactView (0) .setMediaSession (mMediaSessionCompat.getSessionToken ())); builder.setSmallIcon (R.mipmap.ic_launcher); NotificationManagerCompat.from (acest) .notify (1, builder.build ()); 

Următoarea metodă din callback pe care o vom discuta, onPlayFromMediaId (), ia a Şir și a Pachet ca parametri. Aceasta este metoda de apel inversă pe care o puteți utiliza pentru a schimba piste audio / conținut din aplicația dvs.. 

Pentru acest tutorial, vom accepta pur și simplu un ID de resursă brut și vom încerca să jucăm acest lucru și apoi vom reinitializa metadatele sesiunii. După cum vi se permite să treci a Pachet în această metodă, o puteți folosi pentru a personaliza alte aspecte ale redării media, cum ar fi configurarea unui sunet de fundal personalizat pentru o piesă.

@Override publice void pePlayFromMediaId (String mediaId, Extras pachet) super.onPlayFromMediaId (mediaId, extras); încercați AssetFileDescriptor afd = getResources () openRawResourceFd (Integer.valueOf (mediaId)); dacă (afd == null) return;  încercați mMediaPlayer.setDataSource (afd.getFileDescriptor (), afd.getStartOffset (), afd.getLength ());  captură (IllegalStateException e) mMediaPlayer.release (); initMediaPlayer (); mMediaPlayer.setDataSource (afd.getFileDescriptor (), afd.getStartOffset (), afd.getLength ());  afd.close (); initMediaSessionMetadata ();  captură (IOException e) retur;  încercați mMediaPlayer.prepare ();  catch (IOException e)  // Lucrează cu extras aici dacă vrei

Acum, când am discutat cele două metode principale din acest apel invers pe care îl veți folosi în aplicațiile dvs., este important să știți că există și alte metode opționale pe care le puteți utiliza pentru a vă personaliza serviciul. Unele metode includ onSeekTo (), care vă permite să modificați poziția de redare a conținutului dvs. și la comandă(), care va accepta a Şir indicând tipul de comandă, a Pachet pentru informații suplimentare despre comandă și a ResultReceiver apel invers, care vă va permite să trimiteți comenzi personalizate către dvs. Serviciu.

@Override publice void onCommand (comanda String, extras Bundle, ResultReceiver cb) super.onCommand (comanda, extras, cb); dacă (COMMAND_EXAMPLE.equalsIgnoreCase (comanda)) // Comanda personalizată aici @Override public void onSeekTo (long pos) super.onSeekTo (pos); 

Înlăturați-vă

Când fișierul nostru audio va fi finalizat, vom dori să decidem ce va fi următoarea noastră acțiune. În timp ce poate doriți să redați piesa următoare în aplicația dvs., vom păstra lucrurile simple și vom elibera Media Player.

@Override publice void onCompletion (MediaPlayer mediaPlayer) dacă (mMediaPlayer! = Null) mMediaPlayer.release (); 

În cele din urmă, vom dori să facem câteva lucruri în onDestroy () metoda noastră Serviciu. Mai întâi, obțineți o referință la serviciul de sistem AudioManager, și sunați abandonAudioFocus () cu a noastră AudioFocusChangeListener ca parametru, care va notifica alte aplicații de pe dispozitiv că renunțați la focalizarea audio. Apoi, anulați înregistrarea BroadcastReceiver care a fost configurat pentru a asculta schimbările căștilor și eliberați-l MediaSessionCompat obiect. În cele din urmă, veți dori să anulați notificarea privind controlul redării.

@Override public void peDestroy () super.onDestroy (); AudioManager audioManager = (AudioManager) getSystemService (Context.AUDIO_SERVICE); audioManager.abandonAudioFocus (aceasta); unregisterReceiver (mNoisyReceiver); mMediaSessionCompat.release (); NotificationManagerCompat.from (aceasta) .cancel (1); 

În acest moment, ar trebui să aveți un sunet de fundal de lucru Serviciu utilizând MediaSessionCompat pentru controlul redării pe toate dispozitivele. Deși a fost deja mult implicat doar în crearea serviciului, ar trebui să puteți controla redarea din aplicație, o notificare, comenzile de blocare a ecranului pe dispozitivele pre-Lollipop (Lollipop și mai sus vor folosi notificarea pe ecranul de blocare), și de la dispozitivele periferice, cum ar fi Android Wear, o dată Serviciu a început.

Pornirea și controlul conținutului dintr-o activitate

În timp ce cele mai multe controale vor fi automate, veți avea încă un pic de lucru pentru a începe și controla o sesiune media din controalele în aplicație. Cel puțin, veți dori a MediaBrowserCompat.ConnectionCallback, MediaControllerCompat.CallbackMediaBrowserCompat, și MediaControllerCompat obiecte create în aplicația dvs..

MediaControllerCompat.Callback va avea o metodă numită onPlaybackStateChanged () care primește modificări în starea de redare și poate fi utilizat pentru a păstra sincronizarea interfeței utile.

private MediaControllerCompat.Callback mMediaControllerCompatCallback = nou MediaControllerCompat.Callback () @Override public void pePlaybackStateChanged (starea PlaybackStateCompat) super.onPlaybackStateChanged (state); dacă (state == null) return;  comutare (state.getState ()) case PlaybackStateCompat.STATE_PLAYING: mCurrentState = STATE_PLAYING; pauză;  caz PlaybackStateCompat.STATE_PAUSED: mCurrentState = STATE_PAUSED; pauză; ;

MediaBrowserCompat.ConnectionCallback are un onConnected () care va fi numită atunci când este nouă MediaBrowserCompat obiect este creat și conectat. Puteți folosi acest lucru pentru a vă inițializa MediaControllerCompat obiect, conectați-l la dvs. MediaControllerCompat.Callback, și asociați-o cu MediaSessionCompat de la tine Serviciu. Odată terminată, puteți porni redarea audio de la această metodă.

private MediaBrowserCompat.ConnectionCallback mMediaBrowserCompatConnectionCallback = nou MediaBrowserCompat.ConnectionCallback () @Override public void onConnected () super.onConnected (); încercați mMediaControllerCompat = nou MediaControllerCompat (MainActivity.this, mMediaBrowserCompat.getSessionToken ()); mMediaControllerCompat.registerCallback (mMediaControllerCompatCallback); setSupportMediaController (mMediaControllerCompat); getFormMediaId (String.valueOf (R.raw.warner_tautz_off_broadway), null);  captură (RemoteException e) ;

Veți observa că fragmentul de cod de mai sus utilizează getSupportMediaController (). getTransportControls () pentru a comunica cu sesiunea media. Folosind aceeași tehnică, puteți apela onPlay () și onPause () în serviciile dvs. audio MediaSessionCompat.Callback obiect.

dacă (mCurrentState == STATE_PAUSED) getSupportMediaController (). getTransportControls () play (); mCurrentState = STATE_PLAYING;  altceva if (getSupportMediaController () getPlaybackState () getState () == PlaybackStateCompat.STATE_PLAYING) getSupportMediaController () getTransportControls () pauză ();  mCurrentState = STATE_PAUSED; 

Când ați terminat redarea audio, puteți întrerupe serviciul audio și vă puteți deconecta MediaBrowserCompat obiect, pe care îl vom face în acest tutorial atunci când aceasta Activitate este distrusă.

@Override protejate void onDestroy () super.onDestroy (); dacă getStateMediaController () getPlaybackState () getState () == PlaybackStateCompat.STATE_PLAYING) getSupportMediaController () getTransportControls () pauză ();  mMediaBrowserCompat.disconnect (); 

Înfășurarea în sus

Uau! După cum puteți vedea, există o mulțime de piese în mișcare implicate în crearea și utilizarea unui serviciu audio de fundal corect. 

În acest tutorial, ați creat un serviciu care redă un fișier audio simplu, ascultă schimbările în focalizarea audio și link-urile MediaSessionCompat pentru a oferi control universal al redării pe dispozitive Android, inclusiv pe telefoane mobile și Android Wear. Dacă vă confruntați cu blocaje în timp ce lucrați prin acest tutorial, vă recomandăm insistent să verificați codul de proiect Android asociat pe GitHub al Envato Tuts +.

Și verificați câteva dintre celelalte cursuri și tutoriale Android de aici, pe Envato Tuts+!


Cod