package vandy.mooc.presenter;
import java.io.IOException;
import vandy.mooc.common.LifecycleLoggingService;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.IBinder;
import android.util.Log;
/**
* This MusicService extends Service and uses a MediaPlayer to
* download and play a song in the background. Although it runs in
* the UI Thread, it implements MediaPlayer.OnPreparedListener to
* avoid blocking the UI Thread while a song is initially prepared to
* start playing.
*/
public class MusicService extends LifecycleLoggingService
implements MediaPlayer.OnPreparedListener {
/**
* Intent used to start the Service.
*/
private static String ACTION_PLAY = "course.examples.action.PLAY";
/**
* Keep track of whether a song is currently playing.
*/
private static boolean mSongPlaying;
/**
* The MediaPlayer that plays a song in the background.
*/
private MediaPlayer mPlayer;
/**
* This factory method returns an intent used to play and stop
* playing a song, which is designated by the @a songUri.
*/
public static Intent makeIntent(final Context context,
Uri songUri) {
Log.d("MusicService",
"makeIntent() entered with songUri "
+ songUri);
// Create and return an intent that points to the
// MusicService.
return new Intent(ACTION_PLAY,
songUri,
context,
MusicService.class);
}
/**
* Hook method called when a new instance of Service is created.
* One time initialization code goes here.
*/
@Override
public void onCreate() {
Log.d(TAG,"onCreate() entered");
// Always call super class for necessary
// initialization/implementation.
super.onCreate();
// Create a MediaPlayer that will play the requested song.
mPlayer = new MediaPlayer();
// Indicate the MediaPlayer will stream the audio.
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
/**
* Hook method called every time startService() is called with an
* Intent associated with this MusicService.
*/
@Override
public int onStartCommand (Intent intent,
int flags,
int startid) {
// Extract the URL for the song to play.
final String songUri =
intent.getDataString();
Log.d(TAG,
"onStartCommand() entered with song URL "
+ songUri);
if (mSongPlaying)
// Stop playing the current song.
stopSong();
try {
// Indicate the URL indicating the song to play.
mPlayer.setDataSource(songUri);
// Register "this" as the callback when the designated
// song is ready to play.
mPlayer.setOnPreparedListener(this);
// This call doesn't block the UI Thread.
mPlayer.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}
// Don't restart Service if it shuts down.
return START_NOT_STICKY;
}
/**
* Called back when MediaPlayer is ready to play the song.
*/
public void onPrepared(MediaPlayer player) {
Log.d(TAG, "onPrepared() entered");
// Just play the song once, rather than have it loop
// endlessly.
player.setLooping(false);
// Note that song is now playing.
mSongPlaying = true;
// Start playing the song.
player.start();
}
/**
* Hook method called when the MusicService is stopped.
*/
@Override
public void onDestroy() {
Log.d(TAG, "onDestroy() entered");
// Stop playing the song.
stopSong();
// Call up to the super class.
super.onDestroy();
}
/**
* Stops the MediaPlayer from playing the song.
*/
private void stopSong() {
Log.d(TAG, "stopSong() entered");
// Stop playing the song.
mPlayer.stop();
// Reset the state machine of the MediaPlayer.
mPlayer.reset();
// Note that no song is playing.
mSongPlaying = false;
}
/**
* This no-op method is necessary since MusicService is a
* so-called "Started Service".
*/
@Override
public IBinder onBind(Intent intent) {
return null;
}
}