Cyber Monday Sale Save up to 40% off unlimited courses, tutorials and creative assets. Cyber Monday Sale! Save Now
Advertisement
  1. Code
  2. Android SDK

Ang Background Audio sa Android gamit ang MediaSessionCompat

by
Difficulty:BeginnerLength:LongLanguages:

Tagalog (Wikang Tagalog) translation by Anna Nelson (you can also view the original English article)

Isa sa mga sikat na gamit ng mga mobile na mga kagamitan ay ang pagpapatugtog sa pamamagitan ng mga music streaming services, mga nadownload na podcast, o anumang iba pang mga pinagkukunan ng audio.  Habang ito ay isang pangkaraniwang tampok, ito ay mahirap isagawa, may maraming magkaibang mga bahagi na kailangang buuin ng tama para magbigay sa gumagamit ng buong Android na karanasan.

Sa pagtuturo na ito iyong matututunan ang tungkol sa MediaSessionCompat na mula sa Android support library, at kung paano ito magagamit para lumikha ng angkop na background audio service para sa mga gumagamit.

Ang Setup

Ang unang bagay na kailangan mong gawin ay isama ang Android support library sa iyong proyekto. Nagagawa ito sa pamamagitan ng pagdagdag ng linyang ito sa loob ng build.gradle na file sa iyong module sa ibaba ng dependencies node.

Pagkatapos mong ma-sync ang iyong proyekto, gumawa ng isang bagong Java class. Para sa halimbawang ito tatawagin ko ang class na BackgroundAudioService. Ang class na ito ay kailangang ma-extend ang MediaBrowserServiceCompat. Ipapatupad din natin ang mga interfaces na ito: MediaPlayer.OnCompletionListener at AudioManager.OnAudioFocusChangeListener.

Ngayon na ang iyong implementasyon sa MediaBrowserServiceCompat ay natapos na, tayo’y maglaan ng isang saglit para i-update ang AndroidManifest.xml bago ito bumalik sa class na ito. Sa itaas ng class, kakailanganin mong humingi ng WAKE_LOCK na pahintulot.

Sunod, sa loob ng application node, ideklara ang iyong bagong service sa pamamagitan ng mga intent-filter items na ito: Ang mga ito ay magpapahintulot sa iyong service na maharangan ang mga control buttons, mga headphone events at ang pagbrowse ng media sa mga kagamitan, tulad ng Android Auto (bagamat wala tayong gagawin na anumang bagay sa Android Auto sa pagtuturo na ito, ilan sa mga mahahalagang suporta para dito ay kailangan ng MediaBrowserServiceCompat).

At sa huli, kakailanganin mong ideklara ang paggamit ng MediaButtonReceiver mula sa Android support library. Ito ay magpapahintulot sa’yo na maharangan ang mga interaksyon ng media control button at mga headphone events sa mga kagamitang tumatakbo ng KitKat at ang mga nauna.

Ngayon na ang iyong AndroidManifest.xml na file ay tapos na, maaari mo na itong isara. Tayo ay gagawa din ng isa pang class na tinatawag na MediaStyleHelper, na isinulat ni Ian Lake, Developer Advocate sa Google, para linisin ang pagbuo ng mga media style na notipikasyon.

Kapag iyon ay nabuo na, pwede ng isara ang file. Itutuon natin sa background audio service ang susunod na bahagi.

Ang Paggawa ng Background Audio Service

Ngayon ay panahon na para suriing mabuti ang paggawa nga iyong media app. May iilang mga member variables na gugustuhin mong ideklara ng una para sa halimbawang app na ito: isang MediaPlayer para sa aktwal na pagpapatugtog, at isang MediaSessionCompat na object na mamamahala ng metadata at mga kontrols / mga kalagayan ng pagpapatugtog.

Sa karagdagan, kakailanganin mo ng isang BroadcastReceiver na nakikinig sa mga pagbabago sa kalagayan ng headphone. Para manatiling simple ang mga bagay, ang tagatanggap na ito ay nagpapahinto sa MediaPlayer, kung ito ay tumugtog.

Para sa huling member variable, ikaw ay gagawa ng isang MediaSessionCompat.Callback na object, na ginagamit para sa paghawak sa kalagayan ng pagpapatugtog kung kalian nangyayari ang mga aksyon ng media session. 

Bibisitahin natin ulit ang bawat paraan na nasa itaas mamaya sa pagtuturo na ito, sapagkat sila’y gagamitin para sa pagpapatakbo ng ating media app.

May dalawang paraan na kakailanganin din nating ideklara, bagamat sila’y walang kailangang gawin para sa mga layunin ng pagtuturo na ito: onGetRoot() at onLoadChildren(). Pwede mong gamitin ang code na ito para sa iyong defaults.

Sa pagtatapos, gugustuhin mong ipawalang bisa ang onStartCommand() na paraan, kung saan ito ang pasukan sa iyong Service. Ang paraang ito ay kukuha sa Intent na ipapasa naman sa Service at ipapadala ito sa MediaButtonReceiver class.

Ang Pag-Initialize sa Lahat ng Bagay

Ngayon na ang iyong base member na mga variables are nagawa na, panahon na para i-initialize ang lahat. Gagawin natin ito sa pamamagitan ng pagtawag ng iba’t ibang helper na paraan sa onCreate().

Ang unang paraan, initMediaPlayer(), ay mag-i-initialize sa MediaPlayer na object na ginawa natin sa itaas ng class, hihingi ng bahagyang wake lock (ito ang dahilan kung bakit natin kinailangan ng pahintulot sa  AndroidManifest.xml), at itakda ang volume ng player.

Ang susunod na paraan, initMediaSession(), ay saan natin i-initialize ang MediaSessionCompat na object at ikakabit ito sa mga media buttons at mga control na paraan na magpapahintulot sa atin na mapangasiwaan ang pagpapatugtog at input ng gumagamit. Ang paraan na ito ay nagsisimula sa pamamagitan ng pagbuo ng isang ComponentName na object na nagtuturo patungo sa MediaButtonReceiver class ng Android support library, at gagamitin ito para bumuo ng isang bagong MediaSessionCompat. Ipapasa ngayon natin ang MediaSession.Callback object na ating binuo kanina patungo dito, at itatakda ang mga flags na kinakailangan para tumanggap ng mga input sa media button at mga senyas ng control. Sunod, tayo at gagawa ng isang bagong Intent para paghawak ng mga input ng media button sa mga kagamitang nauna pa sa Lollipop, at itatakda ang media session na token para sa ating service.

At sa huli, ipaparehistro natin ang BroadcastReceiver na ating ginawa sa itaas ng class para sa gayon ay marinig natin ang pagbabago sa mga headphone event.

Ang Paghawak sa Audio Focus

Ngayong natapos mo na ang pag-i-initialize sa BroadcastReceiver, sa MediaSessionCompat at sa MediaPlayer na mga objects, panahon na para tingnan ang paghawak sa audio focus.

Habang iniisip natin na ang ating audio apps ay ang pinakamahalaga sa sandaling ito, ang ibang apps na nasa kagamitan ay makikipagcompetensiya para gumawa ng kani-kanilang tunog, tulad ng notipikasyon sa email o sa laro sa mobile. Para makagawa batay sa mga iba’t ibang sitwasyon na ito, ang sisteam ng Android ay gumagamit ng audio focus para matukoy kung paano mapapangasiwaan ang audio.

Ang unang kalagayan na gusto nating mapangasiwaan ay ang pagsisimula ng pagpapatugtog at ang pagsubok na matanggap ang focus ng kagamitan. Sa iyong MediaSessionCompat.Callback na object, pumunta sa onPlay() na paraan and idagdag ang pangcheck sa condisyon na ito.

Ang code na nasa itaas ay tatawag sa isang helper na paraan na susubukan na kunin ang focus, at kung hindi, ito ay babalik lamang. Sa isang totoong app, gusto mong mapangasiwaan ang nabigong pagpapatugtog sa audio ng mas banayad. Ang successfullyRetrievedAudioFocus() ay kukuha ng kaugnayan sa AudioManager na sistema, at susubukan na humingi ng audio focus para makapagstream ng musika. Ito ngayon ay babalik sa isang boolean na kumakatawan kung ang hinihingi ay nagtagumpay o hindi.

Iyong mapapansin na pinapasa din natin ito sa requestAudioFocus() na paraan, kung saan inuugnay ang OnAudioFocusChangeListener sa ating service. May iilan na magkaibang kalagayan na gusto mong pakinggan upang maging “mabuting mamamayan” sa   ecosystem ng app sa loob ng kagamitan. 

  • AudioManager.AUDIOFOCUS_LOSS: Ito ay nangyayari kapag isa pang app ay humihingi ng audio focus. Kapag ito ay nangyari, dapat mong itigil ang pagpapatugtog ng audio sa iyong app.
  • AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: Ang kalagayan na ito ay nangyayari kapag ang isa pang app ay gustong tumugtog ng audio, pero inaasahan nito na sa maikling panahon lamang kailangan ang focus.  Maaari mong gamitin ang kalagayan na ito para mapatigil ang pagpapatugtog ng audio.
  • AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: Kapag ang audio focus ay hiningi, pero nagbibigay ng “pwedeng bumaba” na kalagayan, ito ay nangangahulugan na maaari kang magpatulay sa iyong pagpapatugtog, pero dapat babaan ang volume ng kaunti. Ito ay maaaring mangyari sa tuwing isang tunog ng notipikasyon ay pinatugtog ng isang kagamitan.
  • AudioManager.AUDIOFOCUS_GAIN: Ang huling kalagayan na ating paguusapan ay ang AUDIOFOCUS_GAIN. Ito ang kalagayan kapag ang isang maaaring bumaba na pagpapatugtog ng audio ay nakumpleto, at ang iyong app ay maaaring magpatuloy sa dati nitong mga antas.

Ang isang pinapayak na onAudioFocusChange() callback ay maaaring magmukha ng tulad nito:

Ang Pag – unawa sa MediaSessionCompat.Callback

Ngayon na ikaw ay may kalahatang estruktura na nasama-sama para sa iyong Service, panahon na para simulang pagusupan ang MediaSessionCompat.Callback. Sa nakaraang bahagi iyong dinagdagan ng kaunti ang onPlay() para tiyakin kung ang audio focus ay ipinagkaloob. Sa ibaba ng kondisyonal na pahayag, gugustuhin mong itakda ang MediaSessionCompat na object na aktibo, bigyan ito ng kalagayan na STATE_PLAYING, at italaga ang wastong mga gawaing kinakailan para makabuo ng mga pause button sa mga nauna-pa-sa Lollipop na mga controls sa lock screen, telepono at mga notipikasyon ng Android Wear.

Ang setMediaPlaybackState() na paraan na nasa itaas ay isang helper na paraan na gumagawa ng isang PlaybackStateCompat.Builder na object at nagbibigay ito ng wastong mga gawain at kalagayan, at binubuo at iniuugnay nito ang isang PlaybackStateCompat sa iyong MediaSessionCompat na object.

Mahalagang tandaan na kakailanganin mo ang dalawa ang ACTION_PLAY_PAUSE at kahit alin sa ACTION_PAUSE o ACTION_PLAY na mga flags sa iyong gawain upang makuha ang wastong mga control sa Android Wear.

Media notification on Android Wear

Balik sa onPlay(), gugustuhin mong ipakita ang isang tumutugtog na notipikasyon na iniugnay sa iyong MediaSessionCompat na object sa pamamagitan ng paggamit ng MediaStyleHelper na class na ating tinukoy kanina, at saka ipakita ang notipikasyon na iyon.

Sa pagtatapos, iyong sisimulan ang MediaPlayer sa huli ng onPlay().

Media control notification on an Android Nougat device

Tuwing ang callback ay tumatanggap ng pagtigil na command, ang onPause() ay tatawagin. Dito mo ititigil ang MediaPlayer, itakda ang kalagayan na STATE_PAUSED, at ipakita ang itinigil na notipikasyon.

Ang ating showPausedNotification() helper na paraan ay magmumukhang tulad sa showPlayNotification() na paraan.

Ang susunod na paraan sa callback na ating paguusapan, onPlayFromMediaId(), ay kumukuha ng isang String at ng isang Bundle bilang mga parametro. Ito ang callback na paraan na maaari mong gamitin para baguhin ang mga track / mga nilalaman ng audio sa loob ng iyong app.

Para sa pagtuturo na ito, tatanggap lamang tayo ng isang raw resource na ID at susubukan na ipatugtog iyon, at saka i-initialize ulit ang metadata ng sesyon. Samantalang ikaw ay pinahihintulutang ipasa ang isang Bundle tungo sa paraang ito, maaari mong gamitin ito para mabago ang ibang mga aspekto ng iyong pagpapatugtog ng media, tulad ng pagtatakda ng isang pasadyang background na tunog para sa isang track.

Ngayon na napagusapan na natin ang dalawang pangunahing mga paraan sa callback na iyong gagamitin sa iyong mga apps, mahalagang malaman na may ibang mga opsyonal na mga paraang maaari mong gamitin para mabago ang iyong service. Kasama sa mga paraan ay onSeekTo(), na nagpapahintulot sa’yo na mabago ang posisyon ng pagpapatugtog ng iyong nilalaman, at onCommand(), na tatanggap ng isang String na tumutukoy sa uri ng command, isang Bundle para sa dagdag na impormasyon tungkol sa command, at isang ResultReceiver na callback, na nagpapahintulot sa’yo na magpadala ng pasadya na mga command tungo sa iyong Service.

Ang Tearing Down

Kapag ang ating audio na file ay nakumpleto na, gugustuhin natin na magpasya kung ano ang ating susunod na gagawin. Habang gusto mong ipatugtog and susunod na track sa iyong app, papanatilihin nating simple ang mga bagay at isasara ang MediaPlayer.

Sa pagtatapos, gugustuhin nating gumawa ng iilang mga bagay sa onDestroy() na paraan sa ating Service. Una, kumuha ng kaugnayan sa AudioManager sa sistema ng service, at tawagin ang abandonAudioFocus() kasama ang ating AudioFocusChangeListener bilang isang parametro, na mag aabiso sa iba pang mga apps sa kagamitan na binibitawan mo na ang audio focus. Sunod, ipatanggal sa pagkakarehistro ang BroadcastReceiver na naitakda para pakinggan ang mga pagbabago sa headphone, at isara ang MediaSessionCompat na object. At sa wakas, gugustuhin mong kanselahin ang notipikasyon sa control sa pagpapatugtog. At sa wakas, gugustuhin mong kanselahin ang notipikasyon sa control sa pagpapatugtog.

Sa puntong ito, ikaw dapat ay may gumagana na basic background audio Service gamit ang MediaSessionCompat para makontrol ang pagpapatugtog sa lahat ng mga kagamitan. Habang maraming nang napaloob sa pagbuo lamang ng service, dapat ikaw ay may kontrol sa pagpapatugtog na galing sa iyong app, isang notipikasyon, mga control sa lock screen sa mga kagamitan na nauna pa sa Lollilop ( ang Lollipop at pataas ay ginagamit ang notipikasyon na nasa lock screen), at galing sa mga kagamitang periperal, tulad ng Android Wear, nang magsimula ang Service.

Media lock screen controls on Android Kit Kat

Pagsisimula at Pagkokontrol ng Nilalaman mula sa isang Gawain

Habang karamihan ng mga kontrol ay nagkukusa, kinakailangan pa rin na ikaw ay magtrabaho ng kaunti para magsimula at makontrol ang isang media session galing sa iyong mga in-app controls. Sa pinakamababa, gugustuhin mong may MediaBrowserCompat.ConnectionCallbackMediaControllerCompat.CallbackMediaBrowserCompat at MediaControllerCompat na mga objects na nabuo sa iyong app.

Ang MediaControllerCompat.Callback ay may paraan na tinatawag na onPlaybackStateChanged() na tumatanggap ng mga pagbabago sa kalagayan ng pagpapatugtog, at maaaring gamitin para panatilihing sync ang iyong UI.

MediaBrowserCompat.ConnectionCallback ay may onConnected() na paraan na tatawagin tuwing may isang bagong MediaBrowserCompat na object na nabuo at naiugnay. Maaari mo itong gamitin para i-initialize ang iyong MediaControllerCompat na object, ikabit ito sa iyong MediaControllerCompat.Callback, at iugnay ito sa MediaSessionCompat na galing sa iyong Service. Kapag ito ay nakumpleto, maaari mo ng simulan ang pagpapatugtog ng audio mula sa paraan na ito.

Iyong mapapansin na ang piraso ng code na nasa itaas ay gumagamit ng getSupportMediaController().getTransportControls() para makipagugnayan sa media session. Gamit ang parehong pamamaraan, maaari mong tawagin ang onPlay() at ang onPause() mula sa MediaSessionCompat.Callback na object sa iyong audio service.

Kapag ika’y tapos na sa iyong pagpapatugtog ng audio, maaaring mong ihinto ang audio service at alisin ang iyong MediaBrowserCompat na object, na ating gagawin sa pagtuturo na ito kapag sinira na ang Activity na ito.

Ang Pagtatapos

Whew!  Gaya ng iyong nakikita, may maraming mga gumagalaw na mga piraso ang napapaloob sa pagbuo at paggamit ng isang wasto na background audio service.

Sa pagtuturo na ito, ikaw ay nakabuo ng isang service na tumutugtog ng isang simpleng audio na file, nakarinig ng mga pagbabago sa audio focus, at ang mga koneksyon sa MediaSessionCompat para magbigay ng pangkalahatang kontrol sa pagpapatugtog sa mga Android na mga kagamitan, kasama na ang mga telepono at Android Wear. Kung ikaw ay makadaan sa mga balakid habang nagtratrabaho sa pagtuturo na ito, aking matinding maipapayo na tingnan ang nakaugnay na code ng proyekto ng Android sa Envato Tuts+'s GitHub.

At tingnan din ang ilan sa mga iba pa naming mga kurso sa Android at mga pagtuturo dito sa Envato Tuts+!


Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.