package com.lloydm.javakogengine_chess; import java.io.IOException; import android.annotation.SuppressLint; import android.app.Service; import android.content.Intent; import android.content.res.AssetFileDescriptor; import android.content.res.AssetManager; import android.media.AudioManager; import android.media.MediaPlayer; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.util.Log; @SuppressLint("HandlerLeak") public class MenuMusicService extends Service { private static MediaPlayer menumediaplayer; public volatile static boolean audiomuted = false; private static volatile boolean threadrunning = false; private volatile int cmd = -1; private static Handler handler; private final float volume = (float) (1 - (Math.log(80) / Math.log(100))); private final static int CMD_PLAY = 0; private final static int CMD_PAUSE = 1; private final static int CMD_FADEOUT = 2; private final static int CMD_FADEIN = 3; private final static int CMD_FINISH = 4; private final static int CMD_START = 5; // volume on/off private final static int CMD_MUTEON = 6; private final static int CMD_MUTEOFF = 7; private volatile boolean usecustommusic = false; private String custommusicfilename = ""; private final static String TAG = "com.lloydm.javakogengine_chess.MenuMusicService"; private static AssetManager assetmgr = null; @Override public void onCreate() { } @Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { if (intent == null) { return START_STICKY; } String action = intent.getAction(); if (action != null) { if (action.equals("com.lloydm.javakogengine_chess.MenuMusicService.start")) { cmd = CMD_START; // init, load and begin playback.... if (!threadrunning) { threadrunning = true; new Thread(new Runnable() { @Override public void run() { initmusic(); Looper.prepare(); handler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case CMD_MUTEON: if (menumediaplayer != null) { try { Log.i(TAG, "muting audio"); audiomuted = true; menumediaplayer.setVolume(0, 0); Log.i(TAG, "audio muted"); } catch (Exception e) { Log.e(TAG, "music player in wrong state"); } } else { Log.w(TAG, "Music player should be available but isn't"); } break; case CMD_MUTEOFF: if (menumediaplayer != null) { try { Log.i(TAG, "unmuting audio"); audiomuted = false; menumediaplayer.setVolume(volume, volume); Log.i(TAG, "audio unmuted"); } catch (Exception e) { Log.e(TAG, "music player in wrong state"); } } else { Log.w(TAG, "Music player should be available but isn't"); } break; case CMD_PLAY: handler.removeCallbacksAndMessages(null); if (menumediaplayer != null) { try { if (!menumediaplayer.isPlaying()) { menumediaplayer.start(); if (!audiomuted) { menumediaplayer.setVolume(volume, volume); } else { menumediaplayer.setVolume(0, 0); } } } catch (Exception e) { Log.e(TAG, "music player in wrong state"); } } else { Log.w(TAG, "Music player should be available but isn't"); } break; case CMD_PAUSE: handler.removeCallbacksAndMessages(null); if (menumediaplayer != null) { try { if (menumediaplayer.isPlaying()) { menumediaplayer.pause(); } } catch (Exception e) { Log.e(TAG, "music player in wrong state"); } } else { Log.w(TAG, "Music player should be available but isn't"); } break; case CMD_FINISH: finishmusic(); handler.removeCallbacksAndMessages(null); handler.getLooper().quit(); threadrunning = false; stopSelf(); // important! break; default: // currently fade in and fade out will come here - not used yet... handler.removeCallbacksAndMessages(null); break; } } }; Looper.loop(); Message msg = new Message(); msg.what = cmd; if (handler != null) { handler.sendMessage(msg); } } }).start(); } else { // cancel the CMD_FINISH if it is there.....ie get in early! - assumes there was a 'resume' command // which was to start the process again between activity onpause/onresumes... // we should probably try and run a 'play' command....regardless...just in case... if (handler != null) { try { handler.removeMessages(CMD_FINISH); } catch (Exception e) { Log.e(TAG, "Error - failed to cancel finish command"); } try { Message msg2 = new Message(); msg2.what = CMD_PLAY; handler.sendMessage(msg2); } catch (Exception e) { Log.e(TAG, "Error - failed to play music 123"); } } } } if (action.equals("com.lloydm.javakogengine_chess.MenuMusicService.muteon")) { try { cmd = CMD_MUTEON; Message msg = new Message(); msg.what = cmd; if (handler != null) { handler.sendMessage(msg); } } catch (Exception e) { Log.w(TAG, "handler problem when muting"); } } if (action.equals("com.lloydm.javakogengine_chess.MenuMusicService.muteoff")) { try { cmd = CMD_MUTEOFF; Message msg = new Message(); msg.what = cmd; if (handler != null) { handler.sendMessage(msg); } } catch (Exception e) { Log.w(TAG, "handler problem when unmuting"); } } if (action.equals("com.lloydm.javakogengine_chess.MenuMusicService.play")) { cmd = CMD_PLAY; // resume basically... Message msg = new Message(); msg.what = cmd; if (handler != null) { handler.sendMessage(msg); } } if (action.equals("com.lloydm.javakogengine_chess.MenuMusicService.pause")) { cmd = CMD_PAUSE; // if the music is playing then pause it.....(temporarily) Message msg = new Message(); msg.what = cmd; if (handler != null) { handler.sendMessage(msg); } } if (action.equals("com.lloydm.javakogengine_chess.MenuMusicService.fadeout")) { cmd = CMD_FADEOUT; // fade out to 0.1 volume... Message msg = new Message(); msg.what = cmd; if (handler != null) { handler.sendMessage(msg); } } if (action.equals("com.lloydm.javakogengine_chess.MenuMusicService.fadein")) { cmd = CMD_FADEIN; // fade in to maxvolume (0.4f?) Message msg = new Message(); msg.what = cmd; if (handler != null) { handler.sendMessage(msg); } } if (action.equals("com.lloydm.javakogengine_chess.MenuMusicService.finish")) { cmd = CMD_FINISH; // release all resources and stop playing etc...kill the looper etc... Message msg = new Message(); msg.what = cmd; if (handler != null) { handler.sendMessageDelayed(msg, 2750); } } if (action.equals("com.lloydm.javakogengine_chess.MenuMusicService.instantkill")) { cmd = CMD_FINISH; // release all resources and stop playing etc...kill the looper etc... Message msg = new Message(); msg.what = cmd; if (handler != null) { handler.sendMessageDelayed(msg, 1000); // almost instant...not quite! } } } return START_STICKY; } private static void finishmusic() { if (menumediaplayer != null) { Log.i(TAG, "ending any music"); try { if (menumediaplayer.isPlaying()) { menumediaplayer.stop(); } } catch (Exception e) { Log.e(TAG, "Music player not in right state"); } Log.i(TAG, "Releasing music player"); menumediaplayer.release(); menumediaplayer = null; } } private void initmusic() { // get default system volume for app..... if (menumediaplayer != null) { Log.i(TAG, "Releasing music player"); menumediaplayer.release(); menumediaplayer = null; } Log.i(TAG, "new media player"); menumediaplayer = new MediaPlayer(); menumediaplayer.reset(); Log.i(TAG, "setting stream type and volume music player"); menumediaplayer.setAudioStreamType(AudioManager.STREAM_MUSIC); if (!audiomuted) { menumediaplayer.setVolume(volume, volume); } { menumediaplayer.setVolume(0, 0); } menumediaplayer.setOnErrorListener(new MediaPlayer.OnErrorListener() { @Override public boolean onError(MediaPlayer mp, int what, int extra) { Log.e(TAG, "Error with media player:what:" + what + " extra:" + extra); return true; } }); loadaudiotrack(); } private void loadaudiotrack() { if (menumediaplayer != null) { // pick a track at random..... AssetFileDescriptor fd = null; if (usecustommusic) { } else { try { if (assetmgr == null) { assetmgr = getAssets(); } fd = assetmgr.openFd("media/audio/musictrack.ogg"); } catch (IOException e) { Log.e(TAG,"IO Exception reading music"); e.printStackTrace(); } } if (fd != null || usecustommusic == true) { try { Log.i(TAG, "setting data source for music"); if (fd != null) { menumediaplayer.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength()); fd.close(); } else { menumediaplayer.setDataSource(custommusicfilename); } menumediaplayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { // then start playing! if (menumediaplayer != null) { if (menumediaplayer != mp) { return; } } mp.start(); if (!audiomuted) { mp.setVolume(volume, volume); } else { mp.setVolume(0, 0); } } }); menumediaplayer.setLooping(true); // set the volume...or mute it altogether..... menumediaplayer.prepareAsync(); } catch (IllegalArgumentException e1) { e1.printStackTrace(); Log.e(TAG, "Error opening music file - illegala rgument"); } catch (IllegalStateException e1) { Log.e(TAG, "Error opening music file- illegal state"); e1.printStackTrace(); } catch (IOException e1) { Log.e(TAG, "Error opening music file - io exception"); e1.printStackTrace(); } try { if (fd != null) { fd.close(); } } catch (IOException e) { Log.i(TAG, "Error closing audio file - potentially already closed"); } } } } }