* Makes sure the media player exists and has been reset. This will create the media player 
     * if needed, or reset the existing media player if one already exists. 
    void createMediaPlayerIfNeeded() { 
        if (mPlayer == null) {
            mPlayer = new MediaPlayer();
            // Make sure the media player will acquire a wake-lock while playing. If we don't do 
            // that, the CPU might go to sleep while the song is playing, causing playback to stop. 
            // Remember that to use this, we have to declare the android.permission.WAKE_LOCK 
            // permission in AndroidManifest.xml. 
            mPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
            // we want the media player to notify us when it's ready preparing, and when it's done 
            // playing: 
    public void onCreate() { 
        Log.i(TAG, "debug: Creating service");
        playList.service = this;
        mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        // create the Audio Focus Helper, if the Audio Focus feature is available (SDK 8 or above) 
        if (android.os.Build.VERSION.SDK_INT >= 8)
            mAudioFocusHelper = new AudioFocusHelper(getApplicationContext(), this);
            mAudioFocus = AudioFocus.Focused; // no focus feature, so we always "have" audio focus
     * Called when we receive an Intent. When we receive an intent sent to us via startService(), 
     * this is the method that gets called. So here we react appropriately depending on the 
     * Intent's action, which specifies what is being requested of us. 
    public int onStartCommand(Intent intent, int flags, int startId) {
        // String action = intent.getAction(); 
        return START_NOT_STICKY; // Means we started the service, but don't want it to
                                 // restart in case it's killed. 
    public void processPlayPauseRequest() { 
    	switch (mState) {
    		case Stopped:
	            // If we're stopped, just go ahead to the next song and start playing 
    		case Paused:
	            // If we're paused, just continue playback and restore the 'foreground service' state. 
    			mState = State.Playing;
    		case Playing:
    		case Preparing:
    			// Pause media player and cancel the 'foreground service' state. 
                mState = State.Paused;
                relaxResources(false); // while paused, we always retain the MediaPlayer 
    public void processPlayNowRequest() { 
    public void setPosition(int pos) {
    	if (mPlayer != null) {
//    void processRewindRequest() { 
//        if (mState == State.Playing || mState == State.Paused) 
//            mPlayer.seekTo(0); 
//    } 
//    void processStopRequest() { 
//        if (mState == State.Playing || mState == State.Paused) { 
//            mState = State.Stopped; 
//            // let go of all resources... 
//            relaxResources(true); 
//            giveUpAudioFocus(); 
//            // TODO call this when finished 
//            // service is no longer necessary. Will be started again if needed. 
//            stopSelf(); 
//        } 
//    } 
     * Releases resources used by the service for playback. This includes the "foreground service" 
     * status and notification, the wake locks and possibly the MediaPlayer. 
     * @param releaseMediaPlayer Indicates whether the Media Player should also be released or not 
    void relaxResources(boolean releaseMediaPlayer) {
        // stop being a foreground service 
        // stop and release the Media Player, if it's available 
        if (releaseMediaPlayer && mPlayer != null) {
            mPlayer = null;
    void giveUpAudioFocus() { 
        if (mAudioFocus == AudioFocus.Focused && mAudioFocusHelper != null
                                && mAudioFocusHelper.abandonFocus())
            mAudioFocus = AudioFocus.NoFocusNoDuck;
     * Reconfigures MediaPlayer according to audio focus settings and starts/restarts it. This 
     * method starts/restarts the MediaPlayer respecting the current audio focus state. So if 
     * we have focus, it will play normally; if we don't have focus, it will either leave the 
     * MediaPlayer paused or set it to a low volume, depending on what is allowed by the 
     * current focus settings. This method assumes mPlayer != null, so if you are calling it, 
     * you have to do so from a context where you are sure this is the case. 
    void configAndStartMediaPlayer() { 
        if (mAudioFocus == AudioFocus.NoFocusNoDuck) {
            // If we don't have audio focus and can't duck, we have to pause, even if mState 
            // is State.Playing. But we stay in the Playing state so that we know we have to resume 
            // playback once we get the focus back. 
            if (mPlayer.isPlaying()) mPlayer.pause();
        else if (mAudioFocus == AudioFocus.NoFocusCanDuck)
            mPlayer.setVolume(DUCK_VOLUME, DUCK_VOLUME);  // we'll be relatively quiet
            mPlayer.setVolume(1.0f, 1.0f); // we can be loud
        if (!mPlayer.isPlaying()) mPlayer.start();
     * Shortcut to making and displaying a toast. Seemed cleaner than repeating 
     * this code everywhere, at least for this sample. 
    void say(String message) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
    void tryToGetAudioFocus() { 
        if (mAudioFocus != AudioFocus.Focused && mAudioFocusHelper != null
                        && mAudioFocusHelper.requestFocus())
            mAudioFocus = AudioFocus.Focused;
     * Starts playing the next song. If manualUrl is null, the next song will be randomly selected 
     * from our Media Retriever (that is, it will be a random song in the user's device). If 
     * manualUrl is non-null, then it specifies the URL or path to the song that will be played 
     * next. 
    void playNextSong(/*String manualUrl*/) { 
        mState = State.Stopped;
        relaxResources(false); // release everything except MediaPlayer 
        AudioFile file = playList.nextFile();
        if (file == null) {
        try { 
            // set the source of the media player a a content URI 
            mPlayer.setDataSource(getApplicationContext(), file.getUri());
            mState = State.Preparing;
            // MUST call this! 
            setUpAsForeground(file.getTitle() + " (loading)");
            // starts preparing the media player in the background. When it's done, it will call 
            // our OnPreparedListener (that is, the onPrepared() method on this class, since we set 
            // the listener to 'this'). 
            // Until the media player is prepared, we *cannot* call start() on it! 
        catch (IOException ex) {
            Log.e("MusicService", "IOException playing next song: " + ex.getMessage());