ȸ¿ø·Î±×ÀÎ
ANDROID(¾Èµå·ÎÀ̵å) ¾Û °³¹ß ±âÃÊ] MEDIAPLAYER À½¾Ç Àç»ýÇϱâ
8³â Àü
* ¹Ìµð¾î Àç»ýÇϱâ
: ¾Èµå·ÎÀÌµå ¸ÖƼ¹Ìµð¾î ÇÁ·¹ÀÓ¿öÅ©´Â ´Ù¾çÇÑ ¹Ìµð¾î ÇüŸ¦ Àç»ýÇÒ ¼ö ÀÖµµ·Ï Áö¿øÇØÁØ´Ù. µû¶ó¼, ¿Àµð¿À, ºñµð¿À³ª À̹ÌÁö¸¦ ¾Û¿¡¼ È°¿ëÇÏ´Â °ÍÀº ¾ÆÁÖ ½±°Ô ±¸ÇöÀÌ °¡´ÉÇÏ´Ù. ¾ÛÀÇ 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);
// ÁغñÇÏ°í ¾Û ½ÃÀÛ
̵̧ : 662
̵̧
¸ñ·Ï