ȸ¿ø°¡ÀԡžÆÀ̵ð/ºñ¹øã±â
ȨÀ¸·Î

ANDROID(¾Èµå·ÎÀ̵å) ¾Û °³¹ß ±âÃÊ] MEDIAPLAYER À½¾Ç Àç»ýÇϱâ
7³â Àü
* ¹Ìµð¾î Àç»ýÇϱâ
: ¾Èµå·ÎÀÌµå ¸ÖƼ¹Ìµð¾î ÇÁ·¹ÀÓ¿öÅ©´Â ´Ù¾çÇÑ ¹Ìµð¾î ÇüŸ¦ Àç»ýÇÒ ¼ö ÀÖµµ·Ï Áö¿øÇØÁØ´Ù. µû¶ó¼­, ¿Àµð¿À, ºñµð¿À³ª À̹ÌÁö¸¦ ¾Û¿¡¼­ È°¿ëÇÏ´Â °ÍÀº ¾ÆÁÖ ½±°Ô ±¸ÇöÀÌ °¡´ÉÇÏ´Ù. ¾ÛÀÇ resource¿¡ ¹Ù·Î ÀúÀåÀ» ÇÑ ¼ø¼öÇÑ resource¸¦ Àç»ýÇÒ ¼öµµ ÀÖ°í, ÆÄÀÏ ½Ã½ºÅÛ¿¡ ÀÖ´Â ÆÄÀϵéÀ» Àç»ýÇÒ¼öµµ ÀÖÀ¸¸ç, ³×Æ®¿öÅ© ¿¬°áÀ» ÅëÇؼ­ µ¥ÀÌÅÍ ½ºÆ®¸®¹ÖÀ¸·Îµµ È°¿ëÇÒ ¼ö ÀÖ´Ù. ÀÌ ¸ðµç °ÍÀº MediaPlayer API¸¦ ÅëÇؼ­ ±¸ÇöÀÌ °¡´ÉÇÏ´Ù.

: ÀÌ ±Û¿¡¼­´Â ¸ÖƼ¹Ìµð¾î¸¦ Àç»ýÇÏ´Â ¾ÛÀ» °³¹ßÇÏ´Â ¹æ¹ý°ú »ç¿ëÀÚ¿Í ½Ã½ºÅÛ°£ ¾î¶»°Ô »óÈ£ÀÛ¿ëÀ» ÇØ¾ß Á¦´ë·ÎµÈ ÆÛÆ÷¸Õ½º¿Í UX°¡ ³ª¿À°Ô µÉÁö ´Ù·ç°Ô µÈ´Ù.

* Âü°í: ¿Àµð¿À µ¥ÀÌÅÍ´Â ±âº» Ãâ·Â Àåºñ¸¦ ÅëÇؼ­¸¸ Àç»ýÀÌ °¡´ÉÇÏ´Ù. ÇöÀç¿¡´Â Àåºñ ½ºÇÇÄ¿³ª ºí·çÅõ½º Çìµå¼Â µîÀÇ ÀåºñÀÌ°í, ÅëÈ­ Áß¿¡´Â ¿Àµð¿À Àç»ýÀÌ ºÒ°¡´ÉÇÏ´Ù.

* ±âº» »çÇ×
: ¾Æ·¡ÀÇ Å¬·¡½ºµéÀº À½¾Ç°ú ºñµð¿À¸¦ Àç»ýÇϴµ¥ »ç¿ëµÇ¾îÁö´Â ÇÁ·¹ÀÓ¿öÅ©ÀÌ´Ù.

- MediaPlayer: ÀÌ Å¬·¡½º´Â ¿Àµð¿À¿Í ºñµð¿À¸¦ Àç»ýÇϴµ¥ À־ °¡Àå ±âº»ÀûÀΠŬ·¡½ºÀÌ´Ù.
- AudioManager: ÀÌ Å¬·¡½º´Â ¿Àµð¿À ¼Ò½º¿Í Ãâ·Â Àåºñ¸¦ °ü¸®Çϴ Ŭ·¡½ºÀÌ´Ù.

* Manifest Á¤ÀÇ
: MediaPlayer¸¦ »ç¿ëÇÏ´Â ¾ÛÀ» °³¹ßÇϱâ Àü¿¡ Manifest ÆÄÀÏÀ» ÅëÇؼ­ ¾Æ·¡ÀÇ ±ÇÇѵéÀÌ Á¦´ë·Î Á¤ÀÇ µÇ¾ú´ÂÁö È®ÀÎÇغ¸ÀÚ.

- Internet Permission: MediaPlayer¸¦ ÅëÇØ ³×Æ®¿öÅ© »ó¿¡ ÀÖ´Â ¹Ìµð¾î¸¦ ½ºÆ®¸®¹ÖÀ¸·Î ¿¬µ¿ÇÏ´Â °æ¿ì ³×Æ®¿öÅ© ¿¬µ¿ÀÌ ÇÊ¿äÇÏ´Ù.
<uses-permission android:name="android.permission.INTERNET" />
- Wake Lock Permission: ¸¸¾à ¿Àµð¿À Àç»ý ¾ÛÀÌ È­¸éÀÌ ÀÚµ¿À¸·Î ¾îµÎ¿öÁö°Å³ª Àá±Ý¸ðµå·Î °¡´Â °ÍÀ» ¹æÁö ÇØ¾ß Çϰųª, MediaPlayer.setScreenOnWhilePlaying()À̳ª MediaPlayer.setWakeMode()¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù¸é ¾Æ·¡ÀÇ ±ÇÇÑÀ» ¿äûÇØ¾ß ÇÑ´Ù.
<uses-permission android:name="android.permission.WAKE_LOCK" />

* MediaPlayer »ç¿ëÇϱâ
: MediaPlayer Ŭ·¡½º´Â ¾Èµå·ÎÀÌµå ¹Ìµð¾î ÇÁ·¹ÀÓ¿öÅ©¿¡¼­ °¡Àå Áß¿äÇÑ ÄÄÆ÷³ÍÆ® Áß ÇϳªÀÌ´Ù. ÀÌ °´Ã¼´Â ¿Àµð¿À¿Í ºñµð¿À¸¦ °¡Á®¿À°í µðÄÚµùÇÏ°í Àç»ýÇÏ´Â °ÍÀ» ÃÖ¼ÒÇÑÀÇ ¼³Á¤À¸·Î °¡´ÉÇÏ°Ô ÇØÁØ´Ù. ¸î °¡Áö ¼­·Î ´Ù¸¥ ¹Ìµð¾î Á¦°ø ¹æ½ÄÀº ¾Æ·¡¿Í °°´Ù.

- ·ÎÄÃ resource
- ContentResolverµîÀ» È°¿ëÇÒ ³»ºÎ URI
- ¿ÜºÎ URL(½ºÆ®¸®¹Ö)

: ¾Èµå·ÎÀ̵忡¼­ Áö¿ø °¡´ÉÇÑ Æ÷¸ËÀº ¾Æ·¡ÀÇ »çÀÌÆ®¸¦ Âü°íÇÏ¸é µÈ´Ù.

http://developer.android.com/guide/appendix/media-formats.html

: ¾Æ·¡´Â ¹Ìµð¾î°¡ ·ÎÄÃÀÇ resource¿¡ ¼ø¼öÇÏ°Ô ÀúÀåµÈ °æ¿ì Àç»ýÇÏ´Â ¹æ¹ýÀÌ´Ù.
MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.sound_file_1);
mediaPlayer.start(); // prepare(); ³ª create() ¸¦ È£ÃâÇÒ ÇÊ¿ä ¾øÀ½
: ÀÌ °æ¿ì¿¡´Â "raw" ¸®¼Ò½º´Â½Ã½ºÅÛ¿¡ ÀúÀåµÇ¾îÀ־ º°´Ù¸¥ ó¸® ¾øÀÌ ¹Ù·Î Á¢±ÙÀÌ °¡´ÉÇÏ´Ù. ¾î·µç, ÀÌ·¯ÇÑ ÆÄÀϵµ ¼ø¼öÇÑ ¿Àµð¿À ÆÄÀÏÀÌ ¾Æ´Ï¶ó, Áö¿ø °¡´ÉÇÑ ÇÑ°¡ÁöÀÇ ¹Ìµð¾î ŸÀÔÀ¸·Î ÀÎÄÚµùÀÌ µÇ¾îÀÖ¾î¾ß ÇÒ °ÍÀÌ´Ù.

: ±×¸®°í ¾Æ·¡´Â URI¸¦ ÅëÇؼ­ ·ÎÄà ½Ã½ºÅÛ¿¡¼­ ¿Àµð¿À¸¦ Àç»ýÇÏ°íÀÚ ÇÒ ¶§ Àç»ýÇÏ´Â ¹æ¹ýÀÌ´Ù.
Uri myUri = ....; // initialize Uri here
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(getApplicationContext(), myUri);
mediaPlayer.prepare();
mediaPlayer.start();
: HTTP½ºÆ®¸®¹ÖÀ» ÅëÇÑ ¿ø°ÝÀÇ URL¿¡¼­ Àç»ýÀ» ÇÏ´Â °æ¿ì´Â ¾Æ·¡¿Í °°ÀÌ ±¸ÇöÇÏ¸é µÈ´Ù.
String url = "http://........"; // your URL here
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(url);
mediaPlayer.prepare(); // might take long! (for buffering, etc)
mediaPlayer.start();
* Âü°í: URLÀ» ÅëÇؼ­ ½ºÆ®¸®¹ÖÀ» ÇÏ´Â °æ¿ì ¼­¹ö¿¡ ÀÖ´Â ÆÄÀÏÀÌ progressive download °¡ °¡´ÉÇØ¾ß ÇÑ´Ù.
* ÁÖÀÇ: setDataSource¸¦ ÅëÇؼ­ ÆÄÀÏÀÌ Á¸ÀçÇÏÁö ¾Ê´Â´Ù¸é, IllegalArgumentExceptionÀ̳ª IOExceptionÀ» ¹Þ°Ô µÉ °ÍÀÌ´Ù.


* ºñµ¿±â »çÀüÁغñ
: MediaPlayer´Â ±âº»ÀûÀ¸·Î ¾ÆÁÖ Á÷°üÀûÀÏ °ÍÀÌ´Ù. ÇÏÁö¸¸, ´Ù¸¥ ¾Èµå·ÎÀÌµå ¾Û¿¡ ÅëÇÕÇÒ ¶§¿¡´Â ¸î °¡Áö ÁÖÀÇÇÒ °ÍÀÌ ÀÖ´Ù. ¿¹¸¦ µé¸é, prepare() ÇÔ¼ö¸¦ È£ÃâÇÏ´Â °ÍÀº ½Ã°£ÀÌ ´Ù¼Ò ¿À·¡ °É¸±¼öµµ ÀÖ´Ù. ¿Ö³ÄÇϸé, ¹Ìµð¾î µ¥ÀÌÅ͸¦ °¡Á®¿À°í µðÄÚµùÀ» ÇÏ´Â °úÁ¤ÀÌ Æ÷Ç﵃ ¼öµµ Àֱ⠶§¹®ÀÌ´Ù. µû¶ó¼­, ÀÌ °æ¿ì³×´Â Àý´ë UI ¾²·¹µå »ó¿¡¼­´Â È£ÃâÇÏÁö ¾Ê´Â °ÍÀÌ ÁÁ´Ù. ¸¸¾à ±×·¸°Ô ÇÏ°Ô µÈ´Ù¸é UI´Â ÀϽÃÁ¤Áö¿¡ °É¸®°Ô µÇ°í ANR(Application Not Responsing)µî°ú °°Àº ¸Å¿ì ÁÁÁö ¾ÊÀº UX¸¦ Á¦°øÇÏ°Ô µÉ °ÍÀÌ´Ù. µû¶ó¼­ ¹Ìµð¾î°¡ ºü¸£°Ô ºÒ·¯¿À°Ô µÇ´õ¶óµµ, UI¿¡¼­´Â ÀÌ°ÍÀÌ °É¸®´Â ½Ã°£ÀÌ 1/10ÃÊÀÌ´õ¶óµµ »ç¿ëÀÚ´Â ¾ÛÀÌ ´À¸®´Ù´Â ´À³¦À» ¹Þ°Ô µÉ °ÍÀÌ´Ù.


: ÀÌ·¸°Ô UI ¾²·¹µå¿¡¼­ ÀϽà Á¤ÁöµÇ´Â Çö»óÀ» ¾ø¾Ö±â À§Çؼ­´Â, ´Ù¸¥ ¾²·¹µå¿¡¼­ prepare¸¦ ÇÑ µÚ, ¸ÞÀÎ ¾²·¹µå¿¡ ¾Ë·ÁÁÖ´Â °ÍÀÌ ÇÊ¿äÇÏ´Ù. ¾î¶µç, ¾²·¹µå ·ÎÁ÷À» Á÷Á¢ ÀÛ¼ºÇÒ¼öµµ ÀÖÁö¸¸, MediaPlayer¿¡¼­´Â prepareAsync() ÇÔ¼ö¸¦ ÅëÇؼ­ ÀÌ°ÍÀ» ½±°Ô Á¦°øÇØÁÖ°í ÀÖ´Ù. ÀÌ ÇÔ¼ö´Â ¹Ìµð¾î¸¦ ¹é±×¶ó¿îµå¿¡¼­ Áغñ½ÃÅ°±â ½ÃÀÛÇؼ­ ¹Ù·Î ¸®ÅÏÇÑ´Ù. ÀÌÈÄ ¹Ìµð¾î°¡ ÁغñµÇ¸é setOnPreparedListener() ÇÔ¼ö¸¦ ÅëÇؼ­ ¼³Á¤ÇÑ MediaPlayer.OnPreparedListenerÀÇ onPrepared() ÇÔ¼ö°¡ È£ÃâµÈ´Ù.


* »óÅ °ü¸®Çϱâ
: ´Ù¸¥ °üÁ¡¿¡¼­ »ìÆ캸¸é MediaPlayerÀÇ »óűâ¹Ý µ¿ÀÛµéÀ» Ç×»ó ÁÖÀÇÇØ¾ß ÇÑ´Ù. MediaPlater´Â Ç×»ó ³»ºÎÀûÀÎ »óŸ¦ °¡Áö°í ÀÖ°í, ƯÁ¤ µ¿ÀÛµéÀº player°¡ ƯÁ¤ »óÅ¿¡ ÀÖÀ» ¶§¿¡¸¸ µ¿ÀÛÀÌ °¡´ÉÇÏ´Ù. ¸¸¾à µ¿ÀÛÀÌ ºÒ°¡´ÉÇÑ »óÅ¿¡¼­ ƯÁ¤ µ¿ÀÛÀ» ¿äûÇÏ°Ô µÇ¸é ½Ã½ºÅÛÀº exceptionÀ̳ª ¿øÇÏÁö ¾ÊÀº µ¿ÀÛÀ» ÇÏ°Ô µÉ °¡´É¼ºÀÌ ÀÖ´Ù.

¸ÕÀú ÃÖÃÊ¿¡ MediaPlayer¸¦ »ý¼ºÇϸé Idle »óÅ·Π°¡°í, setDataSource()¸¦ È£ÃâÇÏ°Ô µÇ¸é Initialized »óÅ°¡ µÈ´Ù. ÀÌÈÄ¿¡ prepare() ¶Ç´Â prepareAsync() ÇÔ¼ö¸¦ È£ÃâÇÒ ¼ö ÀÖ°í, MediaPlayer°¡ Áغñ µÇ¸é Prepared »óÅ°¡ µÈ´Ù. ÀÌÈÄ¿¡´Â start() ÇÔ¼ö¸¦ È£ÃâÇÏ¿© ¹Ìµð¾î°¡ Àç»ýµÇµµ·Ï ÇÒ ¼ö ÀÖ´Ù. ÀÌ ¶§¿¡´Â Started¿Í Paused, PlaybackCompleted »çÀ̸¦ ¿Ô´Ù°¬´ÙÇÒ ¼ö ÀÖ°í, start(), pause(), seekTo() ÇÔ¼ö¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ÀÌÈÄ stop()À» È£ÃâÇÏ°Ô µÇ¸é, prepared »óÅ°¡ µÇÁö ¾ÊÀ¸¸é start()¸¦ È£ÃâÇÒ ¼ö ¾øÀ½À» ¸í½ÉÇÏÀÚ.

: Ʋ¸° »óÅ¿¡¼­ Ʋ¸° ÇÔ¼ö¸¦ È£ÃâÇÏ°Ô µÇ¸é ¹ö±×°¡ ¹ß»ýÇÒ ¼ö Àֱ⠶§¹®¿¡, Ç×»ó À§ÀÇ »óÅ ´ÙÀ̾î±×·¥À» ¿°µÎ¿¡ µÎ°í MediaPlayer Ŭ·¡½º¸¦ »ç¿ëÇϸé ÁÁ´Ù.


* MediaPlayer ÇØÁ¦Çϱâ
: MediaPlayer´Â ½Ã½ºÅÛ ÀÚ¿øÀ» ¼Ò¸ðÇÑ´Ù. µû¶ó¼­, ÇÊ¿äÀÌ»óÀ¸·Î MediaPlayer¸¦ °¡Áö°í ÀÖ´Â °ÍÀº ÁÁÁö ¾Ê´Ù. ¹Ìµð¾î Àç»ýÀÌ ³¡³µ´Ù¸é Ç×»ó release() ÇÔ¼ö¸¦ È£ÃâÇÏ¿© ½Ã½ºÅÛ ÀÚ¿øÀ» ÇØÁ¦ÇÏ´Â °ÍÀÌ ¹Ù¶÷Á÷ÇÏ´Ù. ¿¹¸¦ µé¸é, MediaPlayer¸¦ »ç¿ëÇÏ°í ÀÖÀ» ¶§ onStop()À» ¹Þ°Ô µÈ´Ù¸é MediaPlayer¸¦ ÇØÁ¦ÇÏ´Â °ÍÀÌ Activity°¡ »ç¿ëÀÚ¿Í »óÈ£ÀÛ¿ëÇÏ°í ÀÖÁö ¾ÊÀ» ¶§ ÁÁÀ» °ÍÀÌ´Ù. ±×¸®°í ÀÌÈÄ Activity°¡ ´Ù½Ã resumeµÇ°Å³ª restart µÉ ¶§ ´Ù½Ã »ý¼ºÇÏ¿© Áغñ½ÃÅ°´Â °ÍÀÌ È¿À²ÀûÀÏ °ÍÀÌ´Ù.

: ¾Æ·¡´Â MediaPlayer¸¦ ÇØÁ¦ÇÏ´Â ¹æ¹ýÀÌ´Ù.
mediaPlayer.release();
mediaPlayer = null;
: ¿¹¸¦ Çϳª µéÀÚ¸é, ¸¸¾à MediaPlayer¸¦ ÇØÁ¦ÇÏ´Â °ÍÀ» Àؾî¹ö·È´Ù¸é, activity °¡ ¸ØÃ⶧¸¶´Ù »õ·Î¿î °´Ã¼¸¦ ¸¸µé¾î³¾ °ÍÀÌ´Ù. ±×¸®°í »ç¿ëÀÚ°¡ È­¸éÀÇ ¹æÇâÀ» ¹Ù²Ù°Ô µÈ´Ù¸é, ½Ã½ºÅÛÀº ±âº»ÀûÀ¸·Î activity¸¦ Àç½ÃÀÛÇÏ´Â °ÍÀ¸·Î ´Ù·ç°Ô µÇ±â ¶§¹®¿¡ »ç¿ëÀÚ°¡ È­¸éÀ» ȸÀü ½Ãų¶§¸¶´Ù ½Ã½ºÅÛ ÀÚ¿øÀ» ºü¸£°Ô ¼Ò¸ðÇÏ°Ô µÉ °ÍÀÌ´Ù.

: ÀÌ¿Ü¿¡µµ ´Ù¸¥ À½¾Ç ¾Û¿¡¼­ activity°¡ Á¾·áµÈ ÀÌÈÄ¿¡µµ ¹é±×¶ó¿îµå·Î ¹Ìµð¾î¸¦ Àç»ýÇÏ´Â ¹æ¹ý¿¡ ´ëÇؼ­ ±Ã±ÝÇØ ÇÒ ¼öµµ ÀÖ´Ù. ÀÌ ¶§¿¡´Â MediaPlayer´Â ¼­ºñ½º¸¦ ÅëÇؼ­ Á¦¾îµÇ´Â °ÍÀÌ´Ù.


* Service¸¦ ÀÌ¿ëÇؼ­ MediaPlayer »ç¿ëÇϱâ
: ¾ÛÀÌ È­¸é¿¡ ³ª¿ÍÀÖÁö ¾ÊÀ» ¶§¿¡µµ ¹Ìµð¾î¸¦ ¹é±×¶ó¿îµå·Î Àç»ýµÇ±â¸¦ ¿øÇÑ´Ù¸é, Áï »ç¿ëÀÚ°¡ ´Ù¸¥ ¾ÛÀ» »ç¿ëÇÏ°í Àִµ¥µµ »ç¿ëÇϱ⸦ ¿øÇÑ´Ù¸é, Service¸¦ »ý¼ºÇÏ¿© MediaPlayer °´Ã¼·Î ¹Ìµð¾î¸¦ Àç»ýÇÏ¸é µÈ´Ù. ÀÌ ¶§¿¡´Â ¼­ºñ½º·Î ¹é±×¶ó¿îµå¿¡¼­ µ¹¾Æ°¥ ¶§¿¡ ´Ù¸¥ ¾ÛµéÀ̳ª ½Ã½ºÅÛ°ú »óÈ£ÀÛ¿ëÀ¸·Î ¿µÇâÀ» ¹ÌÄ¥ ¼ö Àֱ⠶§¹®¿¡ Á¶½ÉÈ÷ °³¹ßÇØ¾ß ÇÑ´Ù. ÀÌ·¯ÇÑ »óÈ£ÀÛ¿ëÀ» Á¦´ë·Î ÀÌÇØÇÏÁö ¸øÇÑ´Ù¸é ÇüÆí¾ø´Â UX¸¦ »ç¿ëÀڵ鿡°Ô Á¦°øÇÏ°Ô µÉ °ÍÀÌ´Ù. À̹ø¿¡´Â ±×·¯ÇÑ ¹é±×¶ó¿îµå¿¡¼­ Àç»ýÀ» ÇÒ ¶§ À¯ÀÇÇØ¾ß ÇÒ Á¡µéÀ» »ìÆ캻´Ù.


* ºñµ¿±â ½ÇÇà
: ±âº»ÀûÀ¸·Î Service¿¡¼­´Â Activity¿Í µ¿ÀÏÇÏ°Ô ½Ì±Û¾²·¹µå°¡ ±âº»À¸·Î µÇ¾îÀÖ´Ù. ¸¸¾à Activity ¾È¿¡¼­ °°Àº ¾ÛÀÇ Service¸¦ ½ÇÇàÇÑ´Ù¸é µ¿ÀÏÇÑ ¸ÞÀÎ ¾²·¹µå¸¦ ±âº»ÀûÀ¸·Î »ç¿ëÇÏ°Ô µÈ´Ù. µû¶ó¼­, Service µéÀº µé¾î¿À´Â IntentµéÀ» ºü¸£°Ô ó¸®ÇÏ°í ÀÀ´äÀ» ÇØÁÖ°í ±æ°Ô µ¿±âÀûÀΠ󸮸¦ Çؼ­´Â ¾ÈµÈ´Ù. ¸¸¾à °è»ê·®ÀÌ ¸¹Àº ÀÛ¾÷À» ¼öÇàÇÏ°Ô µÈ´Ù¸é ±×°ÍµéÀº ºñµ¿±âÀûÀ¸·Î ´Ù¸¥ ¾²·¹µå¿¡¼­ ½ÇÇàÀ» ÇÒ ¼ö ÀÖ°Ô ÇÁ·¹ÀÓ¿öÅ©¸¦ »ç¿ëÇÏ´øÁö ÀÚüÀûÀ¸·Î °³¹ßÇØ¾ß ÇÑ´Ù.

: ¿¹¸¦ µé¸é, MediaPlayer¸¦ ¸ÞÀÎ ¾²·¹µå¿¡¼­ »ç¿ëÇÏ°Ô µÉ ¶§¿¡´Â prepare()¸¦ È£ÃâÇÏÁö ¸»°í prepareAsync()¸¦ È£ÃâÇÏ´Â °ÍÀÌ ÁÁ°í, MediaPlayer.OnPreparedListener¸¦ ±¸ÇöÇÏ¿© Áغñ°¡ ´Ù µÇ¾úÀ» ¶§¿¡ ÄݹéÀ» ½ÇÇàÇÏ´Â ¹æ½ÄÀ¸·Î Àç»ýÀ» ½ÃÀÛÇÏ´Â °ÍÀÌ ÁÁ´Ù.
public class MyService extends Service implements MediaPlayer.OnPreparedListener {
    private static final String ACTION_PLAY = "com.example.action.PLAY";
    MediaPlayer mMediaPlayer = null;

    public int onStartCommand(Intent intent, int flags, int startId) {
        ...
        if (intent.getAction().equals(ACTION_PLAY)) {
            mMediaPlayer = ... // initialize it here
            mMediaPlayer.setOnPreparedListener(this);
            mMediaPlayer.prepareAsync(); // prepare async to not block main thread
        }
    }

    /** MediaPlayer°¡ ÁغñµÇ¸é È£ÃâµÈ´Ù */
    public void onPrepared(MediaPlayer player) {
        player.start();
    }
}


* ºñµ¿±â ¿À·ù ´Ù·ç±â
: µ¿±âÀûÀÎ µ¿ÀÛµéÀ» ¼öÇàÇÏ´Ù°¡ ¿¡·¯°¡ ³­´Ù¸é, ExceptionÀÌ ÀϾ°Å³ª ¿¡·¯Äڵ带 ¹Þ°Ô µÈ´Ù. ÇÏÁö¸¸, ºñµ¿±âÀûÀ¸·Î ¹Ìµð¾î¸¦ »ç¿ëÇÏ°Ô µÇ´Â °æ¿ì, ¾Û¿¡¼­ ¿¡·¯°¡ ³ª´Â °æ¿ì Á¤»óÀûÀ¸·Î ¾Ë¸®°í ÀÖ´ÂÁö È®ÀÎÇØ¾ß ÇÑ´Ù. ÀÌ ¶§¿¡´Â MediaPlayer¿¡ MediaPlayer.OnErrorListener¸¦ ¼³Á¤ÇØ¾ß ÇÑ´Ù.
public class MyService extends Service implements MediaPlayer.OnErrorListener {
    MediaPlayer mMediaPlayer;

    public void initMediaPlayer() {
        // ...MediaPlayer¸¦ ÃʱâÈ­ÇÏ´Â ÇÔ¼ö...

        mMediaPlayer.setOnErrorListener(this);
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        // ... ¿¡·¯¸¦ ó¸®Çϱâ ...
        // MediaPlayer¸¦ error »óÅ·Πµ¹ÀÔÇÏ¿´°í, resetÀÌ ÇÊ¿äÇÏ´Ù.
    }
}

: Áß¿äÇÑ °ÍÀº ¿¡·¯°¡ ÀϾÀ» ¶§ MediaPlayer¸¦ Error »óÅ·Πµé¾î°¡°Ô µÇ¹Ç·Î, ´Ù½Ã ÇØ´ç °´Ã¼¸¦ »ç¿ëÇϱâ Àü¿¡ resetÀ» ÇØ¾ß ÇÑ´Ù´Â °ÍÀÌ´Ù.


* Wake lock »ç¿ëÇϱâ
: ¹Ìµð¾î¸¦ ¹é±×¶ó¿îµå¿¡¼­ Àç»ýÇÏ´Â ¾ÛÀ» µðÀÚÀÎÇÒ ¶§ Service¸¦ ½ÇÇàÁßÀÏ ¶§ Àåºñ°¡ ÈÞ¸é¸ðµå·Î µé¾î°¥ ¼ö ÀÖ´Ù. ¾Èµå·ÎÀÌµå ½Ã½ºÅÛ¿¡¼­´Â Àåºñ°¡ ÈÞ¸é¸ðµå·Î µé¾î°¡°Ô µÇ¸é ¹èÅ͸® ¼Ò¸ð¸¦ ÃÖ¼ÒÈ­Çϱâ À§ÇÏ¿© ºÒÇÊ¿äÇÑ CPU³ª ¿ÍÀÌÆÄÀ̸¦ Æ÷ÇÔÇÑ ¸ðµç ±â´ÉµéÀº Á¤Áö½ÃÅ°·Á°í ÇÑ´Ù. ÀÌ ¶§¿¡ Service°¡ À½¾ÇÀ̳ª ½ºÆ®¸®¹Ö À½¾ÇÀ» Àç»ýÇÏ°í ÀÖ´Ù¸é, ½Ã½ºÅÛ¿¡¼­ À½¾ÇÀÌ Àç»ýµÇ´Â °ÍÀ» Á¤Áö ½ÃÅ°Áö ¸øÇÏ°Ô ¹æÁöÇØ¾ß ÇÒ °ÍÀÌ´Ù.

: Service °¡ Áö¼ÓÀûÀ¸·Î ½ÇÇàÀÌ µÇ°í ÀÖ´Â °ÍÀ» È®½ÇÇÏ°Ô º¸ÀåÇϱâ À§Çؼ­ "wake locks"¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù. Wake lock´Â ¾Û¿¡¼­ ƯÁ¤ ±â´ÉµéÀ» °è¼Ó È°¼ºÈ­ ½ÃÄѳõ¾Æ¾ß ÇÑ´Ù´Â °ÍÀ» ½Ã½ºÅÛ¿¡ ¾Ë·ÁÁÖ´Â ¿ªÇÒÀ» ÇÏ´Â °ÍÀÌ´Ù.

* Âü°í: Ç×»ó wake locks´Â Á¤¸»·Î ÇÊ¿äÇÒ ¶§¿¡¸Á ÀÚÁ¦Çؼ­ »ç¿ëÇØ¾ß »ç¿ëÀÚµéÀÇ ÀåºñÀÇ ¹èÅ͸® ¼ö¸íÀÌ ÁÙ¾îµå´Â °ÍÀ» ¹æÁöÇÒ ¼ö ÀÖÀ» °ÍÀÌ´Ù.

: CPU°¡ MediaPlayer¸¦ À§Çؼ­ °è¼Ó ½ÇÇàµÇµµ·Ï Çϱâ À§Çؼ­´Â MediaPlayer°´Ã¼¸¦ ÃʱâÈ­ÇÒ ¶§ setWakeMode() ÇÔ¼ö¸¦ ½ÇÇàÇØ¾ß ÇÑ´Ù. ÀÏ´Ü MediaPlayer°¡ Àç»ý ÁßÀÏ ¶§¿¡´Â wake lock¸¦ °É¾î³õ°í, ÀϽà Á¤ÁöÇϰųª ¸ØÃß¾úÀ» ´ë¿¡´Â lockÀ» ÇØÁ¦ÇÏ°Ô µÈ´Ù.
mMediaPlayer = new MediaPlayer();
// ... ´Ù¸¥ ÃʱâÈ­ ÀÛ¾÷ ¼öÇà ...
mMediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
: À§ÀÇ ¿¹¿¡¼­´Â CPU¸¸ Á¤Áö½ÃÅ°Áö ¾Êµµ·Ï lock¸¦ °Å´Â °ÍÀÌ´Ù. ¸¸¾à ³×Æ®¿öÅ©¸¦ ÅëÇÑ ½ºÆ®¸®¹Ö ¼­ºñ½º¸¦ Á¦°øÇÑ´Ù¸é, ¿ÍÀÌÆÄÀÌ°¡ Á¤ÁöµÇ´Â °Íµµ ¹æÁöÇØ¾ß ÇÒ °ÍÀÌ´Ù. ÀÌ ¶§¿¡´Â WifiLockÀ» ¼öµ¿ÀûÀ¸·Î lockÀ» °É¾ú´Ù°¡ ÇØÁ¦ÇØ¾ß ÇÑ´Ù. µû¶ó¼­, ¿ø°ÝÀÇ URLÀ» »ç¿ëÇÏ¿© ¹Ìµð¾î¸¦ Àç»ýÇÏ´Â °æ¿ì MediaPlayer¸¦ ÁغñÇÒ ¶§¿¡ WifiLock¸¦ ¼³Á¤ÇÏ¸é µÉ °ÍÀÌ´Ù.
WifiLock wifiLock = ((WifiManager) getSystemService(Context.WIFI_SERVICE))
    .createWifiLock(WifiManager.WIFI_MODE_FULL, "mylock");

wifiLock.acquire();
: ±×¸®°í ÀÌÈÄ¿¡ Àç»ýÀ» ÀϽÃÁ¤ÁöÇϰųª ¸ØÃß¾úÀ» ¶§¿¡´Â ¼öµ¿ÀûÀ¸·Î wifiLockÀ» ÇØÁ¦ÇØÁà¾ß ÇÑ´Ù.
wifiLock.release();


* Foreground ¼­ºñ½º·Î ½ÇÇàÇϱâ
: ¼­ºñ½ºµéÀº À̸ÞÀÏÀ» °¡Á®¿À°Å³ª, µ¥ÀÌÅ͸¦ µ¿±âÈ­Çϰųª, ´Ù¿î·Îµå¸¦ Çϰųª ¿©·¯ °¡Áö »óȲµé¿¡¼­ ÀϹÝÀûÀ¸·Î ¹é±×¶ó¿îµå¿¡¼­ ½ÇÇàÀÌ µÈ´Ù. ÀÌ·¯ÇÑ »óȲ¿¡¼­ »ç¿ëÀÚ´Â ¼­ºñ½ºÀÇ ½ÇÇàÀ» ÁÖµµÀûÀ¸·Î Á¶Á¾ÇÏÁö ¾Ê°í, ¶§·Î´Â ÀÌ·¯ÇÑ ¼­ºñ½ºµéÀÌ ¾î¶»°Ô µ¹¾Æ°¡´ÂÁö ¾ËÁö ¸øÇÒÁöµµ ¸ð¸¥´Ù.

: ÇÏÁö¸¸ À̹ø¿¡´Â À½¾ÇÀ» Àç»ýÇÏ´Â °æ¿ì¸¦ »ý°¢Çغ¸¸é, ÀÌ·¯ÇÑ ¼­ºñ½º´Â »ç¿ëÀÚ°¡ UX¿¡ ±²ÀåÈ÷ ¹Î°¨ÇÏ°Ô »ý°¢Çϸ鼭 Áß°£¿¡ À½¾ÇÀÌ ²÷±âÁö ¾Êµµ·Ï »ý°¢ÇÒ °ÍÀÌ´Ù. Ãß°¡ÀûÀ¸·Î, »ç¿ëÀÚ´Â À½¾ÇÀÌ Àç»ýµÇ°í ÀÖÀ» ¶§¿¡´Â »óÈ£ÀÛ¿ëÀ» Çϸ鼭 ¼­ºñ½º¸¦ »ç¿ëÇÏ±æ ¿øÇÒ °ÍÀÌ´Ù. ÀÌ·¯ÇÑ °æ¿ì¿¡´Â "Foreground ¼­ºñ½º"·Î ½ÇÇàÀ» ÇÏ¸é µÈ´Ù. Foreground ¼­ºñ½º´Â ½Ã½ºÅÛ¿¡¼­ ´õ ³ôÀº ¿ì¼±¼øÀ§¸¦ °¡Áö°í ½ÇÇàÀ» ÇÏ°Ô µÇ¸ç, ÇöÀç ½ÇÇà ÁßÀÎ ¼­ºñ½º°¡ »ç¿ëÀÚ¿¡°Ô Áß¿äÇÑ ¼­ºñ½ºÀ̹ǷΠ°ÅÀÇ ÁßÁö ½ÃÅ°´Â ÀÏÀÌ ¾ø´Ù. Foreground ¼­ºñ½º¸¦ ½ÇÇàÇÒ ¶§¿¡´Â »óŹٿ¡¼­ ¾Ë¸²À» Á¦°øÀ» ÇØ¾ß »ç¿ëÀÚ°¡ ¼­ºñ½º°¡ ÇöÀç ½ÇÇà ÁßÀ̶ó´Â °ÍÀ» ¾Ë ¼ö ÀÖ°í, ¾×ƼºñƼ¸¦ ½±°Ô ¿­¾î¼­ ¼­ºñ½º¿Í »óÈ£ÀÛ¿ëÀ» ½±°ÔÇÒ ¼ö ÀÖµµ·Ï ÇÒ ¼ö ÀÖ´Ù.

: ¼­ºñ½º¸¦ foreground ¼­ºñ½º·Î Á¦°øÇϱâ À§Çؼ­´Â, »óŹٿ¡ ¾Ë¸²À» ³ªÅ¸³»±â À§ÇØ Notification °ú Service¿¡¼­ startForeground() ¸¦ ½ÇÇàÇØ¾ß ÇÑ´Ù. ¿¹¸¦ µé¸é, ¾Æ·¡¿Í °°´Ù.
String songName;
// assign the song name to songName
PendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0,
                new Intent(getApplicationContext(), MainActivity.class),
                PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new Notification();
notification.tickerText = text;
notification.icon = R.drawable.play0;
notification.flags |= Notification.FLAG_ONGOING_EVENT;
notification.setLatestEventInfo(getApplicationContext(), "MusicPlayerSample",
                "Playing: " + songName, pi);
startForeground(NOTIFICATION_ID, notification);

: ¼­ºñ½º°¡ foreground¿¡¼­ ½ÇÇàÀÌ µÇ°í ÀÖÀ» ¶§¿¡´Â, notificationÀÇ ¼³Á¤ °ªÀ» visible·Î ¼³Á¤ÇÏ¸é »ó´ÜÀÇ notification¹Ù¿¡ ³ª¿À°Ô µÈ´Ù. ¸¸¾à »ç¿ëÀÚ°¡ notificationÀ» ¼±ÅÃÇÏ°Ô µÈ´Ù¸é, ½Ã½ºÅÛ¿¡¼­´Â ÇÁ·Î±×·¥¿¡¼­ ¼³Á¤ÇÑ PendingIntentÀ» È£ÃâÇÏ°Ô µÇ°í, À§ÀÇ ¿¹¿¡¼­´Â MainActivity¸¦ ¿­°Ô µÈ´Ù. Foreground ¼­ºñ½º´Â »ç¿ëÀÚ¿¡°Ô ƯÁ¤ ¼­ºñ½º¸¦ Á¦°øÇÏ°í ÀÖÀ» ¶§¿¡¸¸ ½ÇÇàÀÌ µÇ¾î¾ß ÇÏ°í, ¼­ºñ½º Á¦°øÀ» ÇÏÁö ¾Ê°Ô µÈ´Ù¸é ¹Ýµå½Ã stopForeground() ÇÔ¼ö¸¦ È£ÃâÇØ¾ß ÇÑ´Ù.
stopForeground(true);


* ¿Àµð¿À Æ÷Ä¿½º Çڵ鸵
: Çѹø¿¡ ÇϳªÀÇ ¾×ƼºñƼƼ¸¸ ½ÇÇàµÉ ¼ö ÀÖÁö¸¸, ¾Èµå·ÎÀ̵å´Â ¸ÖƼŽºÅ· ȯ°æÀ» Á¦°øÇØ ÁØ´Ù. ÀÌ·¯ÇÑ È¯°æÀº ¿Àµð¿À¸¦ »ç¿ëÇÒ ¶§ ¼­·Î ´Ù¸¥ ¹Ìµð¾î ¼­ºñ½ºµéÀÌ ¿Àµð¿À¸¦ »ç¿ëÇÒ ¶§ ¼­·Î °æÀïÀ» ÇÏ°Ô µÇ¾î À̸¦ ÇØ°áÇØ¾ß ÇÒ ¹®Á¦°¡ µÉ °ÍÀÌ´Ù. ¾Èµå·ÎÀ̵å 2.2 ¹öÀü ÀÌÀü¿¡´Â À̸¦ ÇØ°áÇÒ ¼ö ÀÖ´Â ºôÆ®ÀÎ ¸ÞÄ«´ÏÁòÀº ¾ø¾î¼­ À½¾ÇÀ» µè´Â Áß¿¡ ´Ù¸¥ ¾Û¿¡¼­ ¿Àµð¿À¸¦ »ç¿ëÇؼ­ À½¾ÇÀÌ ²÷±â´Â °ÍÀ» °æÇèÇÏ°Ô µÇ¸é ¾È ÁÁÀº UX¸¦ Á¦°øÇϱ⵵ ÇÏ¿´´Ù. ÀÌ¿¡ ¾Èµå·ÎÀ̵å 2.2 ¹öÀüºÎÅÍ´Â Ç÷§Æû¿¡¼­ ¾Û³¢¸® ¼­·Î ¿Àµð¿À ÀåÄ¡¸¦ »ç¿ëÇÏ´Â ¸ÞÄ«´ÏÁòÀ» Á¦°øÇØÁÖ°í ÀÖÀ¸¸ç, ÀÌ´Â ¿Àµð¿À Æ÷Ä¿½º¶ó°í ÇÑ´Ù.

: ¾Û¿¡¼­ À½¾ÇÀ̳ª ¾Ë¸²À» Çϱâ À§ÇØ ¿Àµð¿À Ãâ·ÂÀÌ ÇÊ¿ä·Î ÇÏ°Ô µÉ ¶§¿¡´Â Ç×»ó ¿Àµð¿À Æ÷Ä¿½º¸¦ ¿äûÇØ¾ß ÇÑ´Ù. Çѹø ¿Àµð¿À Æ÷Ä¿½º¸¦ ȹµæÇÏ°Ô µÇ¾ú´Ù¸é, ÀÚÀ¯·Ó°Ô À½Çâ Ãâ·ÂÀ» ÇÒ ¼ö ÀÖ°Ô µÇ¸ç, ÀÌÈÄ Ç×»ó Æ÷Ä¿½º°¡ º¯È­µÇ´Â °ÍÀ» ½Å°æ½á¾ß ÇÑ´Ù. ¸¸¾à ¿Àµð¿À Æ÷Ä¿½º¸¦ ÀÒ°Ô µÇ¾úÀ» ¶§¿¡´Â ¿Àµð¿À¸¦ Á×À̰ųª À½Çâ ·¹º§À» ÁÙ¿©¾ß ÇÑ´Ù.

: ¿Àµð¿À Æ÷Ä¿½º´Â ¾Û °£¿¡ »óÈ£ÀÛ¿ëÀÌ ´ç¿¬ÇÑ °ÍÀ̸ç, ¾Û¿¡¼­ ¿Àµð¿À Æ÷Ä¿½ºÀÇ °¡À̵å¶óÀÎÀ» µû¸¦ °ÍÀ» ±âº»ÀûÀ¸·Î ±ÇÇÏ°í ÀÖÁö¸¸ ½Ã½ºÅÛ¿¡¼­ °­¿ä¸¦ ÇÏ°í ÀÖÁö´Â ¾Ê´Ù. ¸¸¾à ¾Û¿¡¼­ ¿Àµð¿À Æ÷Ä¿½º¸¦ ÀÒ´õ¶óµµ Å©°Ô À½¾ÇÀ» Àç»ýÇϱ⠿øÇÑ´Ù¸é ½Ã½ºÅÛ¿¡¼­´Â À̸¦ ¹æÁöÇÏÁö ¾Ê´Â´Ù. ÇÏÁö¸¸, ±×·¸°Ô ±¸ÇöÇÏ´Â °æ¿ì¿¡´Â »ç¿ëÀÚ´Â ¾È ÁÁÀº UX¸¦ Á¦°ø ¹Þ¾Æ ¿¹»óÇÏ´Â °Í°ú ´Ù¸¥ ¾ÛÀÇ Çൿµé·Î ÀÎÇÏ¿© ¾ÛÀ» ¾ðÀνºÅçÇÏ°Ô µÉÁöµµ ¸ð¸¥´Ù.

: ¿Àµð¿À Æ÷Ä¿½º¸¦ ¿äûÇϱâ À§Çؼ­´Â AudioManagerÀÇ requestAudioFocus()¸¦ È£ÃâÇÏ¸é µÈ´Ù.
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC,
    AudioManager.AUDIOFOCUS_GAIN);

if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
    // ¿Àµð¿À Æ÷Ä¿½º¸¦ ȹµæÇÒ ¼ö ¾ø´Ù.
}

: requestAudioFocus()ÀÇ Ã¹ ¹ø° ÆĶó¹ÌÅÍ´Â AudioManager.OnAudioFocusChangeListener·Î ¿Àµð¿À Æ÷Ä¿½º°¡ º¯°æµÇ´Â °æ¿ì onAudioFocusChange90 ÇÔ¼ö¸¦ È£ÃâÇÏ°Ô µÇ´Â À̺¥Æ® Çڵ鷯ÀÌ´Ù. µû¶ó¼­, À§ÀÇ ¿¹Ã³·³ this¸¦ ³Ñ°ÜÁÖ±â À§Çؼ­´Â service³ª ¾×ƼºñƼ¿¡¼­ ÇØ´ç ÀÎÅÍÆäÀ̽º¸¦ ±¸ÇöÇØ¾ß ÇÑ´Ù. ¿¹¸¦ µé¸é ¾Æ·¡¿Í °°´Ù.
class MyService extends Service
                implements AudioManager.OnAudioFocusChangeListener {
    // ....
    public void onAudioFocusChange(int focusChange) {
        // Æ÷Ä¿½º°¡ º¯°æµÈ °ÍÀ» ó¸®ÇÑ´Ù.
    }
}

: onAudioFocusChange() ÇÔ¼öÀÇ ÆĶó¹ÌÅÍ focusChange´Â ¿Àµð¿À°¡ ¾î¶»°Ô º¯°æÀÌ µÇ¾ú´ÂÁö ¾Ë·ÁÁÖ´Â ÆĶó¹ÌÅÍ·Î AudioManager¿¡ »ó¼ö·Î ¼±¾ðµÇ¾î ÀÖ´Ù.

AUDIOFOCUS_GAIN: ¿Àµð¿À Æ÷Ä¿½º¸¦ ȹµæÇß´Ù
AUDIOFOCUS_LOSS: ¿Àµð¿À Æ÷Ä¿½º¸¦ Àå±âÀûÀ¸·Î ÀÒ°Ô µÇ¾ú´Ù. Æ÷Ä¿½º°¡ ´Ù¼Ò Àå±â°£ µ¿¾È ȹµæÇÏÁö ¸øÇÏ°Ô µÉ °ÍÀÌ ¿¹»óµÇ¹Ç·Î, ¸ðµç ¿Àµð¿ÀÀÇ Àç»ýÀ» ÀüºÎ Áß´ÜÇØ¾ß ÇÑ´Ù. ÀÌ ¶§¿¡´Â »ç¿ëÇÏ°í ÀÖ´Â ¸®¼Ò½º¸¦ ÇØÁ¦Çϱ⿡ ÁÁÀº ¶§°¡ µÉ °ÍÀÌ´Ù.
AUDIOFOCUS_LOSS_TRANSIENT: Àá½Ã ¿Àµð¿À Æ÷Ä¿½º¸¦ ÀÒ°Ô µÇ¾úÁö¸¸, ªÀº ½Ã°£ ³»¿¡ ´Ù½Ã Æ÷Ä¿½º¸¦ ȹµæÇÏ°Ô µÉ °ÍÀÌ´Ù. ÀÌ ¶§¿¡µµ ¸ðµç ¿Àµð¿ÀÀÇ Àç»ýÀ» Áß´ÜÇØ¾ß ÇÏÁö¸¸, Æ÷Ä¿½º¸¦ ´Ù½Ã ±Ý¹æ ȹµæÇÏ°Ô µÉ °ÍÀ̱â 떄¹®¿¡ ¸®¼Ò½º´Â º¸°üÇÏ°í À־ µÈ´Ù.
AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: Àá½Ã ¿Àµð¿À Æ÷Ä¿½º¸¦ ÀÒ°Ô µÇ¾úÁö¸¸, À½¾Ç Àç»ýÀ» Áß´ÜÇÏÁö ¾Ê°í º¼·ýÀ» ³·Ãá ´ÙÀ½ Àç»ýÀ» À¯ÁöÇصµ µÈ´Ù.
: ¾Æ·¡´Â À̸¦ ±¸ÇöÇÑ ¿¹ÀÌ´Ù.
public void onAudioFocusChange(int focusChange) {
    switch (focusChange) {
        case AudioManager.AUDIOFOCUS_GAIN:
            // ´Ù½Ã Àç»ý
            if (mMediaPlayer == null) initMediaPlayer();
            else if (!mMediaPlayer.isPlaying()) mMediaPlayer.start();
            mMediaPlayer.setVolume(1.0f, 1.0f);
            break;

        case AudioManager.AUDIOFOCUS_LOSS:
            // Æ÷Ä¿½º¸¦ ¾ÆÁÖ Àå±âÀûÀ¸·Î ÀÒ¾ú´Ù. À½¾Ç Àç»ýÀ» ¸ØÃß°í, ¹Ìµð¾î Ç÷¹À̾î ÀÚ¿øµµ ÇØÁ¦
            if (mMediaPlayer.isPlaying()) mMediaPlayer.stop();
            mMediaPlayer.release();
            mMediaPlayer = null;
            break;

        case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
            // Àá½Ã Æ÷Ä¿½º¸¦ ÀÒ¾úÁö¸¸, À½¾ÇÀ» Áß´ÜÇØ¾ß ÇÑ´Ù. ÇÏÁö¸¸ Æ÷Ä¿½º°¡ ±Ý¹æ µ¹¾Æ¿Ã °ÍÀ¸·Î ¿¹»óÇϱâ 떄¹®¿¡ ¹Ìµð¾î Ç÷¹À̾î´Â ÇØÁ¦ ÇÏÁö ¾Ê´Â´Ù
            if (mMediaPlayer.isPlaying()) mMediaPlayer.pause();
            break;

        case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
            // Àá½Ã Æ÷Ä¿½º¸¦ ÀÒ¾úÁö¸¸, º¼·ýÀ» ÁÙÀÎ »óÅ¿¡¼­ À½¾Ç Àç»ýÀ» À¯ÁöÇصµ µÈ´Ù.
            if (mMediaPlayer.isPlaying()) mMediaPlayer.setVolume(0.1f, 0.1f);
            break;
    }
}

: ÁÖÀÇÇÒ °ÍÀº ¿Àµð¿À Æ÷Ä¿½º API´Â ¾Èµå·ÎÀ̵å 2.2, API level 8 ÀÌÈÄ¿¡¸¸ ÀÖ´Ù. ÀÌÀü ¹öÀü¿¡¼­µµ ¿Àµð¿À Æ÷Ä¿½º¸¦ Àû¿ëÇϱâ À§Çؼ­´Â ÇÏÀ§ ȣȯ¼ºÀ» Á¦°øÇØÁÖ¾î¾ß ÇÑ´Ù. ÀÌ ¶§¿¡´Â ¿Àµð¿À Æ÷Ä¿½º¿Í °ü·ÃµÈ ±â´ÉµéÀ» ¾Æ·¡¿Í °°ÀÌ º°µµÀÇ Å¬·¡½º¿¡ ±¸ÇöÇصξî¾ß ÇÑ´Ù.
public class AudioFocusHelper implements AudioManager.OnAudioFocusChangeListener {
    AudioManager mAudioManager;

    // other fields here, you'll probably hold a reference to an interface
    // that you can use to communicate the focus changes to your Service

    public AudioFocusHelper(Context ctx, /* other arguments here */) {
        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
        // ...
    }

    public boolean requestFocus() {
        return AudioManager.AUDIOFOCUS_REQUEST_GRANTED ==
            mAudioManager.requestAudioFocus(mContext, AudioManager.STREAM_MUSIC,
            AudioManager.AUDIOFOCUS_GAIN);
    }

    public boolean abandonFocus() {
        return AudioManager.AUDIOFOCUS_REQUEST_GRANTED ==
            mAudioManager.abandonAudioFocus(this);
    }

    @Override
    public void onAudioFocusChange(int focusChange) {
        // let your service know about the focus change
    }
}

: ±×¸®°í À§ÀÇ AudioFocusHelper Ŭ·¡½º´Â ½Ã½ºÅÛ¿¡¼­ API ·¹º§À» üũÇÑ µÚ, 8 ÀÌ»óÀÎ °æ¿ì¿¡¸¸ ¾Æ·¡¿Í °°ÀÌ »ç¿ëÇÏ¸é µÈ´Ù.
if (android.os.Build.VERSION.SDK_INT >= 8) {
    mAudioFocusHelper = new AudioFocusHelper(getApplicationContext(), this);
} else {
    mAudioFocusHelper = null;
}


* ¹Ìµð¾î Ç÷¹À̾î ÇØÁ¦
: ÀÌÀü¿¡ ¾ð±ÞÇßµíÀÌ, ¹Ìµð¾î Ç÷¹À̾î´Â ½Ã½ºÅÛ ÀÚ¿øÀ» ¸¹ÀÌ Àâ¾Æ¸Ô°Ô µÇ¹Ç·Î, ²À ÇÊ¿äÇÑ ¸¸Å­¸¸ »ç¿ëÇÏ´Ù°¡ »ç¿ëÀ» ¿Ï·áÇÏ°Ô µÈ´Ù¸é release()¸¦ È£ÃâÇØ¾ß ÇÑ´Ù. ÀÌ·¸°Ô ¹Ìµð¾î¿Í °ü·ÃµÈ ÀÚ¿øÀ» »ç¿ëÇÒ ¶§¿¡´Â ½Ã½ºÅÛÀÇ °¡ºñÁö Ä÷ºÅÍ¿¡ ÀÇÁ¸Çϱ⠺¸´Ù °¡ºñÁö Ä÷ºÅ͸¦ ÅëÇÏ¿© ¸Þ¸ð¸®°¡ ÇØÁ¦µÇ±â Àü¿¡ ÇØÁ¦¸¦ ½ÃÄÑÁÖ´Â °ÍÀÌ ÁÁ´Ù. ¶ÇÇÑ onDestroy() ÇÔ¼ö¿¡´Â ¹Ýµå½Ã ¹Ìµð¾î Ç÷¹À̾ ÇØÁ¦ÇØ ÁÖ¾î¾ß ÇÑ´Ù.
public class MyService extends Service {
   MediaPlayer mMediaPlayer;
   // ...

   @Override
   public void onDestroy() {
       if (mMediaPlayer != null) mMediaPlayer.release();
   }
}

: ÀÌ¿Ü¿¡µµ Ç×»ó ¹Ìµð¾î°¡ ²¨Áú ¶§¿¡´Â ¹Ìµð¾î Ç÷¹À̾ ÇØÁ¦ÇÒ ¼ö ÀÖ´Â ±âȸ¿¡´Â ÇØÁ¦¸¦ ÇØÁà¾ß ÇÑ´Ù. ¿¹¸¦ µé¸é, ¿Àµð¿À Æ÷Ä¿½º¸¦ ÀҾ Àå½Ã°£µ¿¾È ¹Ìµð¾î¸¦ Àç»ýÇÒ ÀÏÀÌ ¾ø´Ù°í ÇÑ´Ù¸é, ¹Ìµð¾î Ç÷¹À̾ ¹Ýµå½Ã ÇØÁ¦ÇÑ ´ÙÀ½ ³ªÁß¿¡ ´Ù½Ã Àç»ýÀ» ½ÃÀÛÇÏ°Ô µÉ ¶§¿¡ ´Ù½Ã »ý¼ºÇØ¾ß ÇÑ´Ù. ¹Ý¸é, ¸¸¾à ªÀº ½Ã°£µ¿¾È¸¸ Àç»ýÀÌ ¾ÈµÈ´Ù°í Çϸé, À̸¦ ÇØÁ¦ÇÏ°í ´Ù½Ã »ý¼ºÇÏ´Â ºÎ´ãÀ» ÁÙÀ̱â À§ÇØ ÇØÁ¦¸¦ ÇØÁÖÁö ¾Ê¾Æµµ µÉ °ÍÀÌ´Ù.


* AUDIO_BECOMING_NOISY ÀÎÅÙÆ® Çڵ鸵
: ¿Àµð¿À¸¦ »ç¿ëÇÏ´Â Àß ¸¸µé¾îÁø ¾ÛµéÀº ¿Àµð¿À Ãâ·ÂÀÌ ¿ÜºÎ Ãâ·ÂÀ¸·Î ½Ã²ô·¯¿öÁö°Ô µÇ¸é ÀÚµ¿À¸·Î À½¾Ç Àç»ýÀ» ¸ØÃßµµ·Ï °³¹ßÇÏ°í ÀÖ´Ù. ¿¹¸¦ µé¸é, »ç¿ëÀÚ°¡ ÇìµåÆùÀ¸·Î À½¾ÇÀ» Å©°Ô µè´Ù°¡ ½Ç¼ö·Î ÇìµåÆùÀÌ ºüÁö°Ô µÇ¸é ¿ÜºÎ Ãâ·ÂÀåÄ¡·Î À½¾ÇÀÌ ½Ã²ô·´°Ô Àç»ýµÉ °ÍÀÌ´Ù. ÀÌ·¯ÇÑ »óȲÀ» ¹æÁöÇϱâ À§Çؼ­ ½Ã½ºÅÛ¿¡¼­´Â ÀÚµ¿À¸·Î ÇØÁÖ´Â °ÍÀÌ ¾ø°í, ÀÌ »óȲÀ» ´Ù·ç´Â °ÍÀ» ±¸ÇöÇÏÁö ¾ÊÀ¸¸é »ç¿ëÀÚ°¡ ¿øÇÏÁö ¾Ê¾ÒÀ»Áöµµ ¸ð¸¦ »óȲ¿¡¼­ ¿ÜºÎ Ãâ·ÂÀåÄ¡·Î ±×´ë·Î À½¾ÇÀÌ Àç»ýµÉ °ÍÀÌ´Ù.

: ÀÌ·¯ÇÑ »óȲÀº ACTION_AUDIO_BECOMING_NOISY ÀÎÅÙÆ®¸¦ µî·ÏÇÏ¿© manifest ÆÄÀÏ¿¡¼­ ¾î´À ÀÎÅÙÆ®°¡ ¼ö½ÅÀ» ÇÏ¿© ó¸®ÇÏ°Ô µÉ °ÍÀÎÁö ¸í½ÃÇÏ¸é µÈ´Ù.
<receiver android:name=".MusicIntentReceiver">
   <intent-filter>
      <action android:name="android.media.AUDIO_BECOMING_NOISY" />
   </intent-filter>
</receiver>

: Manifest ÆÄÀÏ¿¡ À§¿Í °°ÀÌ µî·ÏÇÏ°Ô µÇ¸é, MusicIntentReceiver Ŭ·¡½º°¡ ºê·Îµåij½ºÆ® receiver·Î¼­ ÀÎÅÙÆ®¸¦ ¼ö½ÅÇÏ°Ô µÈ´Ù. ÀÌ Å¬·¡½º´Â ¾Æ·¡¾Æ °°ÀÌ ±¸ÇöÀÌ °¡´ÉÇÏ´Ù.
public class MusicIntentReceiver extends android.content.BroadcastReceiver {
   @Override
   public void onReceive(Context ctx, Intent intent) {
      if (intent.getAction().equals(
                    android.media.AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {
          // ¼­ºñ½º¿¡ intent µîÀ¸·Î À½¾Ç Àç»ýÀ» ÁßÁöÇ϶ó°í Àü´Þ
      }
   }
}


* ¹Ìµð¾î¸¦ Content Resolver·ÎºÎÅÍ ¼ö½ÅÇϱâ
: ¹Ìµð¾î Ç÷¹À̾ »ç¿ëÇÏ´Â ¾Û¿¡¼­ À¯¿ëÇÏ°Ô ±¸ÇöÀÌ °¡´ÉÇÑ ¹æ¹ýÀº ¹Ù·Î »ç¿ëÀÚ°¡ ÀåÄ¡¿¡ ÀÖ´Â À½¾ÇÀ» °¡Á®¿Í¼­ Àç»ýÇÏ´Â ¹æ¹ýÀÌ´Ù. ÀÌ ¶§¿¡´Â ContentResolver¸¦ ÅëÇؼ­ ¿ÜºÎÀÇ ¹Ìµð¾î¸¦ ¿äûÇÏ´Â ¹æ¹ýµµ ÀÖ´Ù.
ContentResolver contentResolver = getContentResolver();
Uri uri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor cursor = contentResolver.query(uri, null, null, null, null);
if (cursor == null) {
    // Äõ¸® ½ÇÆÐ, ¿¡·¯ ó¸®
} else if (!cursor.moveToFirst()) {
    // ¹Ìµð¾î°¡ ÀåÄ¡¿¡ ¾øÀ½
} else {
    int titleColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media.TITLE);
    int idColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media._ID);
    do {
       long thisId = cursor.getLong(idColumn);
       String thisTitle = cursor.getString(titleColumn);
       // ¸ñ·ÏÀ» ó¸®
    } while (cursor.moveToNext());
}

: ¹Ìµð¾î Ç÷¹À̾¼­´Â ¾Æ·¡¿Í °°ÀÌ ±¸Çö ÇÏ¸é µÈ´Ù.
long id = /* ¾îµð¼±°¡ ¾ÆÀ̵𸦠°¡Á®¿Í¼­ ¼³Á¤ */;
Uri contentUri = ContentUris.withAppendedId(
        android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id);

mMediaPlayer = new MediaPlayer();
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setDataSource(getApplicationContext(), contentUri);

// ÁغñÇÏ°í ¾Û ½ÃÀÛ
ÃßõÃßõ : 618 Ãßõ ¸ñ·Ï
¹øÈ£ Á¦¸ñ
1,196
Service & Notification(¾Ë¸²¹Ù¶ç¿ì±â) ÀÌ¿ëÇϱâ
1,195
È­¸é ȸÀü(rotation) ó¸®
1,194
[Android] Àüüȭ¸é, title bar ¾ø¾Ö±â, status bar ¾ø¾Ö±â
ANDROID(¾Èµå·ÎÀ̵å) ¾Û °³¹ß ±âÃÊ] MEDIAPLAYER À½¾Ç Àç»ýÇϱâ
1,192
[Android]MediaPlayer¿¡¼­ »ç¿îµå¸¦ Àç»ýÇÏ´Â µÎ °¡Áö °æ·Î
1,191
¾Èµå·ÎÀ̵å Intent »ç¿ë¹ý
1,190
¾Èµå·ÎÀ̵å È­¸é Á¤¸®
1,189
ffmpeg ¿ÀÇ ¼Ò½º on ¾Èµå·ÎÀ̵å
1,188
WebView¿¡¼­ <a> ű×ÀÇ "_blank" target ó¸®Çϱâ.
1,187
Ư¼ö¹®ÀÚ, Ư¼ö¹®ÀÚÇ¥, Ư¼ö¹®ÀÚ ÇÏÆ®, ¿¹»Û Ư¼ö¹®ÀÚ
1,186
MediaPlayer 5¹ø¸¸ ¹Ýº¹Àç»ý
1,185
ÆÄÀÏ À§Ä¡¿¡ µû¸¥ ¹Ìµð¾î Àç»ý »ùÇÃÄÚµå
1,184
MJPEG on Android anyone?
1,183
Android °³¹ß
1,182
¾Èµå·ÎÀ̵å : ¾×ƼºñƼ ¶óÀÌÇÁ »çÀÌŬ (Activity Life Cycle)
1,181
¾Èµå·ÎÀ̵å ÇÁ·Î±×·¥ ÄÚµå·Î À¥ ºê¶ó¿ìÀú ½ÇÇàÇϱ⠿¹Á¦ (ÀÎÅÙÆ® »ç¿ë)
1,180
Áøµ¿ È¿°ú [Android]
1,179
Á¾·á ´ÙÀ̾ó·Î±× [Android]
1,178
´Ù¸¥¾Û È£Ãâ [Android]
1,177
TabActivity back key Event [Android]
1,176
³×Æ®¿öÅ© »óÅ [Android]
1,175
¾Èµå·ÎÀ̵忡¼­ À¥¼­¹ö¿¡ post·Î ±Û¾²±â [Android]
1,174
Webview ¼Ò½º [Android]
1,173
Coach mark View [Android]
1,172
¸ÖƼ ÇØ»óµµ [Android]
1,171
Webview source [Android]
1,170
°øÀ¯ Intent [Android]
1,169
intent uri ¸ðÀ½ [Android]
1,168
http post [Android]
1,167
http ¿äû [Android]
¸ñ·Ï
¹ÂÁ÷Æ®·ÎÆ® ºÎ»ê±¤¿ª½Ã ºÎ»êÁø±¸ °¡¾ßµ¿ ¤Ó °³ÀÎÁ¤º¸Ãë±Þ¹æħ
Copyright ¨Ï musictrot All rights reserved.