package com.asp.radiorake;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.ConnectivityManager;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import com.commonsware.cwac.wakeful.WakefulIntentService;
import com.asp.radiorake.filehandling.M3uHandler;
import com.asp.radiorake.filehandling.PlsHandler;
import com.aspillai.R;
import java.io.File;
import java.io.IOException;
public class PlayerService extends WakefulIntentService {
private static final String TAG = "com.asp.radiorake.PlayerService";
public PlayerService() {
super("PlayerService");
}
@Override
protected void doWakefulWork(Intent intent) {
RadioApplication radioApplication = (RadioApplication) getApplicationContext();
MediaPlayer mediaPlayer = radioApplication.getMediaPlayer();
super.onCreate();
if (mediaPlayer == null) {
mediaPlayer = new MediaPlayer();
}
radioApplication.setMediaPlayer(mediaPlayer);
Bundle bundle = intent.getExtras();
int operation = bundle.getInt(getString(R.string.player_service_operation_key));
switch (operation) {
case RadioApplication.StartPlayingRadio:
RadioDetails radioDetails = bundle.getParcelable(getString(R.string.radio_details_key));
playStream(radioDetails);
break;
case RadioApplication.StartPlayingFile:
String file = bundle.getString(getString(R.string.player_service_file_name_key));
playFile(file);
break;
case RadioApplication.PausePlaying:
pause();
break;
case RadioApplication.ResumePlaying:
resume();
break;
case RadioApplication.StopPlaying:
stop();
break;
default:
Log.e(TAG, "Unexpected operation delivered to PlayerService");
}
}
private void updateActivity(String text) {
Intent intent = new Intent(getString(R.string.player_service_update_playing_key));
((RadioApplication) getApplication()).setPlayingStatus(text);
getApplicationContext().sendBroadcast(intent);
}
private void sendError(String radioDetails, String exceptionMessage) {
Intent intent = new Intent(getString(R.string.player_service_update_playing_error_key));
intent.putExtra(getString(R.string.player_service_update_playing_error_radio_details), radioDetails);
intent.putExtra(getString(R.string.player_service_update_playing_error_exception), exceptionMessage);
getApplicationContext().sendBroadcast(intent);
}
private void playStream(RadioDetails radioDetails) {
final RadioApplication radioApplication = (RadioApplication) getApplicationContext();
final RadioDetails incomingRadioDetails = radioDetails;
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager.getActiveNetworkInfo() == null || !connectivityManager.getActiveNetworkInfo().isConnected()) {
// No network connection
String error = "Failed to play " + incomingRadioDetails.getStationName() + ", network unavailable";
Notification errorNotification = NotificationHelper.getNotification(this, NotificationHelper.NOTIFICATION_PLAYING_ID, incomingRadioDetails, error, error, Notification.FLAG_ONLY_ALERT_ONCE);
((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).notify(NotificationHelper.NOTIFICATION_PLAYING_ID, errorNotification);
updateActivity("Network Unavailable");
Log.e(TAG, error);
return;
}
MediaPlayer mediaPlayer = radioApplication.getMediaPlayer();
try {
if (mediaPlayer == null) {
mediaPlayer = new MediaPlayer();
radioApplication.setMediaPlayer(mediaPlayer);
}
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mediaPlayer) {
Log.d(TAG, "onCompletion called");
if (mediaPlayer.isPlaying()) { //should be false if error occurred
mediaPlayer.start();
}
}
});
mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
public boolean onError(MediaPlayer mediaPlayer, int what, int extra) {
Log.e(TAG, "Error occurred trying to play: " + incomingRadioDetails);
updateActivity("Error playing");
sendError(incomingRadioDetails.toString(), "onError invoked");
return false;
}
});
if (incomingRadioDetails.getPlaylistUrl().endsWith(".pls") || incomingRadioDetails.getPlaylistUrl().endsWith(".m3u")) {
String basePath = getApplicationContext().getFilesDir().getPath();
if (incomingRadioDetails.getPlaylistUrl().endsWith(".pls")) {
radioDetails = PlsHandler.parse(radioDetails, basePath);
} else {
radioDetails = M3uHandler.parse(radioDetails, basePath);
}
} else {
radioDetails.setStreamUrl(radioDetails.getPlaylistUrl());
}
updateActivity(getString(R.string.buffering_string) + " " + radioDetails.getStationName());
radioApplication.setPlayingStatus(getString(R.string.buffering_string) + " " + radioDetails.getStationName());
// need to check we aren't buffering before proceeding
if (radioApplication.isBuffering()) {
Log.d(TAG, "Buffering already, so resetting MediaPlayer before starting again");
while (radioApplication.isBuffering()) {
try {
Thread.sleep(1000);
} catch (InterruptedException ignored) {
}
}
mediaPlayer.reset();
}
mediaPlayer.setDataSource(radioDetails.getStreamUrl());
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setLooping(false);
mediaPlayer.prepareAsync();
radioApplication.setBuffering(true);
final RadioDetails radioDetailsToPlay = radioDetails;
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.start();
radioApplication.setBuffering(false);
radioApplication.setPlayingType(RadioApplication.PlayingStream);
String status = getString(R.string.playing_string) + " " + radioDetailsToPlay.getStationName();
updateActivity(status);
NotificationHelper.showNotification(getApplicationContext(), NotificationHelper.NOTIFICATION_PLAYING_ID, status, status);
}
});
} catch (IllegalArgumentException iae) {
Log.e(TAG, "IllegalArgumentException caught in PlayService for url: " + radioDetails.getStreamUrl(), iae);
updateActivity("Error trying to play stream");
mediaPlayer.reset();
sendError(radioDetails.toString(), iae.toString());
} catch (IOException ioe) {
Log.e(TAG, "IOException caught in PlayService for url: " + radioDetails.getStreamUrl(), ioe);
updateActivity("Error trying to play stream");
mediaPlayer.reset();
sendError(radioDetails.toString(), ioe.getMessage());
} finally {
//radioApplication.setMediaPlayer(mediaPlayer);
radioApplication.setPlayingStation(radioDetails);
}
}
private void playFile(final String file) {
final RadioApplication radioApplication = (RadioApplication) getApplicationContext();
MediaPlayer mediaPlayer = radioApplication.getMediaPlayer();
try {
if (mediaPlayer == null) {
mediaPlayer = new MediaPlayer();
radioApplication.setMediaPlayer(mediaPlayer);
}
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mediaPlayer) {
NotificationHelper.cancelNotification(getApplicationContext(), NotificationHelper.NOTIFICATION_PLAYING_ID);
updateActivity("");
mediaPlayer.reset();
}
});
mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
public boolean onError(MediaPlayer mediaPlayer, int what, int extra) {
Log.e(TAG, "Error occurred trying to play: " + file);
updateActivity("Error playing " + file);
return false;
}
});
String recFolder = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + getString(R.string.app_name);
// need to check we aren't buffering before proceeding
if (radioApplication.isBuffering()) {
Log.d(TAG, "Buffering already, so resetting MediaPlayer before starting again");
updateActivity("Preparing to play " + file);
while (radioApplication.isBuffering()) {
try {
Thread.sleep(1000);
} catch (InterruptedException ignored) {
}
}
mediaPlayer.reset();
}
// TODO - cater for already playing stream
mediaPlayer.setDataSource(recFolder + File.separator + file);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setLooping(false);
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mediaPlayer) {
radioApplication.setPlayingType(RadioApplication.PlayingFile);
radioApplication.setPlayingFileDetails(new PlayingFile(mediaPlayer.getDuration(), file));
// If filename is in session, then retrieve position and jump to it
if (radioApplication.getLastPlayedFile() != null && file.equals(radioApplication.getLastPlayedFile().getName())) {
if (mediaPlayer.getDuration() > radioApplication.getLastPlayedFile().getCurrentPosition()) {
mediaPlayer.seekTo(radioApplication.getLastPlayedFile().getCurrentPosition());
}
}
mediaPlayer.start();
String status = getString(R.string.playing_string) + " " + file;
updateActivity(status);
NotificationHelper.showNotification(getApplicationContext(), NotificationHelper.NOTIFICATION_PLAYING_ID, status, status);
}
});
} catch (IllegalArgumentException iae) {
Log.e(TAG, "IllegalArgumentException caught in PlayService for file: " + file, iae);
updateActivity("Error trying to play stream");
mediaPlayer.reset();
} catch (IOException ioe) {
Log.e(TAG, "IOException caught in PlayService for file: " + file, ioe);
updateActivity("Error trying to play stream");
mediaPlayer.reset();
}
}
private void pause() {
RadioApplication radioApplication = (RadioApplication) getApplicationContext();
MediaPlayer mediaPlayer = radioApplication.getMediaPlayer();
if (mediaPlayer != null) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
}
}
updateActivity("Paused");
}
private void resume() {
RadioApplication radioApplication = (RadioApplication) getApplicationContext();
MediaPlayer mediaPlayer = radioApplication.getMediaPlayer();
if (mediaPlayer != null) {
mediaPlayer.start();
}
updateActivity("Resumed playing " + radioApplication.getPlayingStation().getStationName());
}
private void stop() {
RadioApplication radioApplication = (RadioApplication) getApplicationContext();
MediaPlayer mediaPlayer = radioApplication.getMediaPlayer();
if (mediaPlayer != null) {
if (mediaPlayer.isPlaying() && radioApplication.getPlayingFileDetails() != null) {
radioApplication.setLastPlayedFile(new LastPlayedFile(radioApplication.getPlayingFileDetails().getName(), mediaPlayer.getCurrentPosition()));
mediaPlayer.stop();
}
mediaPlayer.reset();
}
radioApplication.setMediaPlayer(null);
updateActivity("");
NotificationHelper.cancelNotification(getApplicationContext(), NotificationHelper.NOTIFICATION_PLAYING_ID);
}
}