diff --git a/src/android/AndroidManifest.xml b/src/android/AndroidManifest.xml index ac4467e04..75d40e1f0 100644 --- a/src/android/AndroidManifest.xml +++ b/src/android/AndroidManifest.xml @@ -3,7 +3,7 @@ package="org.musikcube" android:versionCode="1" android:versionName="1.0"> - + diff --git a/src/android/res/drawable/ic_media_next.png b/src/android/res/drawable/ic_media_next.png index 84f38e8f8..14a892422 100644 Binary files a/src/android/res/drawable/ic_media_next.png and b/src/android/res/drawable/ic_media_next.png differ diff --git a/src/android/res/drawable/ic_media_pause.png b/src/android/res/drawable/ic_media_pause.png index 688118e6b..4b0ad4411 100644 Binary files a/src/android/res/drawable/ic_media_pause.png and b/src/android/res/drawable/ic_media_pause.png differ diff --git a/src/android/res/drawable/ic_media_play.png b/src/android/res/drawable/ic_media_play.png index 7aa7af8ad..287ac6fbf 100644 Binary files a/src/android/res/drawable/ic_media_play.png and b/src/android/res/drawable/ic_media_play.png differ diff --git a/src/android/res/drawable/ic_media_previous.png b/src/android/res/drawable/ic_media_previous.png index 1bba54415..9a79d0813 100644 Binary files a/src/android/res/drawable/ic_media_previous.png and b/src/android/res/drawable/ic_media_previous.png differ diff --git a/src/android/src/org/musikcube/PlayerControl.java b/src/android/src/org/musikcube/PlayerControl.java index 46cfecaaa..083e1dc14 100644 --- a/src/android/src/org/musikcube/PlayerControl.java +++ b/src/android/src/org/musikcube/PlayerControl.java @@ -46,6 +46,8 @@ public class PlayerControl extends Activity implements OnTrackUpdateListener { nextButton.setOnClickListener(this.onNextClick); ImageButton pauseButton = (ImageButton)findViewById(R.id.MediaPause); pauseButton.setOnClickListener(this.onPauseClick); + ImageButton prevButton = (ImageButton)findViewById(R.id.MediaPrev); + prevButton.setOnClickListener(this.onPrevClick); this.callbackTrackPositionsUpdateHandler.postDelayed(callbackTrackPositionsUpdateRunnable,500); } @@ -57,6 +59,13 @@ public class PlayerControl extends Activity implements OnTrackUpdateListener { startService(intent); } }; + private OnClickListener onPrevClick = new OnClickListener() { + public void onClick(View v){ + Intent intent = new Intent(PlayerControl.this, org.musikcube.Service.class); + intent.putExtra("org.musikcube.Service.action", "prev"); + startService(intent); + } + }; private OnClickListener onPauseClick = new OnClickListener() { public void onClick(View v){ Intent intent = new Intent(PlayerControl.this, org.musikcube.Service.class); diff --git a/src/android/src/org/musikcube/Service.java b/src/android/src/org/musikcube/Service.java index 8e96adf71..ec620fb0b 100644 --- a/src/android/src/org/musikcube/Service.java +++ b/src/android/src/org/musikcube/Service.java @@ -82,6 +82,10 @@ public class Service extends android.app.Service { Player player = Player.GetInstance(); player.Next(); } + if(action.equals("prev")){ + Player player = Player.GetInstance(); + player.Prev(); + } if(action.equals("stop")){ Player player = Player.GetInstance(); player.Stop(); diff --git a/src/android/src/org/musikcube/core/Library.java b/src/android/src/org/musikcube/core/Library.java index 12e23c62f..2722b7752 100644 --- a/src/android/src/org/musikcube/core/Library.java +++ b/src/android/src/org/musikcube/core/Library.java @@ -103,6 +103,7 @@ public class Library implements Runnable{ }else{ this.shutdownCounter = -1; } + this.notifier.notifyAll(); } } public void RemovePointer(){ @@ -113,27 +114,24 @@ public class Library implements Runnable{ }else{ this.shutdownCounter = -1; } + this.notifier.notifyAll(); } } public void Startup(Context context){ -// if(context!=null){ - this.context = context; - - // Startup thread when the application sends the context for the first time - this.thread = new Thread(this); - this.running = true; - this.thread.start(); - -// } + this.context = context; + + // Startup thread when the application sends the context for the first time + this.thread = new Thread(this); + this.running = true; + this.thread.start(); } public void Restart(){ synchronized(this.notifier){ this.running = false; this.restart = true; -// this.Startup(null); if(this.socket!=null){ try { this.socket.shutdownInput(); @@ -175,7 +173,6 @@ public class Library implements Runnable{ private WriterThreadHelper writerThreadHelper; protected Library(){ -// this.writerThreadHelper = new WriterThreadHelper(this); } public void WaitForAuthroization(){ @@ -305,26 +302,6 @@ public class Library implements Runnable{ } } -/* - while(this.connections==0){ - try{ - this.notifier.wait(); - } - catch(Exception x){ - - } - }*/ -/* int countDown = 10; - while(!this.exit && !this.restart){ - try{ - this.notifier.wait(2000); - } - catch(Exception x){ - - } - }*/ - - //Log.i("musikcube::LIB","exit? "+this.exit); if(this.exit){ Intent intent = new Intent(this.context, org.musikcube.Service.class); @@ -393,6 +370,11 @@ public class Library implements Runnable{ } // Send the query query.SendQuery(writer); + }else{ + // Send a ping + WriterNode pingNode = writer.ChildNode("ping"); + pingNode.End(); + } } @@ -450,4 +432,14 @@ public class Library implements Runnable{ } } + public String GetTrackURL(int trackId){ + synchronized (notifier) { + if(this.status==STATUS_CONNECTED){ + String trackURL = "http://"+this.host+":"+this.httpPort+"/track/?track_id="+trackId+"&auth_key="+this.authorization; + return trackURL; + } + } + return null; + } + } diff --git a/src/android/src/org/musikcube/core/Player.java b/src/android/src/org/musikcube/core/Player.java index 887ec034d..7ae481029 100644 --- a/src/android/src/org/musikcube/core/Player.java +++ b/src/android/src/org/musikcube/core/Player.java @@ -70,8 +70,8 @@ public class Player implements TrackPlayer.OnTrackStatusListener, OnQueryResultL synchronized(this.lock){ if(this.nowPlaying.size()>position && position>=0){ int trackId = this.nowPlaying.get(position); - String url = "http://"+this.library.host+":"+this.library.httpPort+"/track/?track_id="+trackId+"&auth_key="+this.library.authorization; - TrackPlayer player = new TrackPlayer(url,trackId); + //String url = "http://"+this.library.host+":"+this.library.httpPort+"/track/?track_id="+trackId+"&auth_key="+this.library.authorization; + TrackPlayer player = new TrackPlayer(trackId); return player; } } @@ -165,6 +165,23 @@ public class Player implements TrackPlayer.OnTrackStatusListener, OnQueryResultL } } + public void Prev(){ + synchronized(this.lock){ + this.currentTrack = new Track(); + this.position--; + if(this.position<0){ + this.position = 0; + } + + if(this.position>=this.nowPlaying.size()){ + this.StopAllTracks(); + this.End(); + }else{ + this.Play(); + } + } + } + public void Stop(){ synchronized(this.lock){ this.StopAllTracks(); diff --git a/src/android/src/org/musikcube/core/TrackPlayer.java b/src/android/src/org/musikcube/core/TrackPlayer.java index f125481ee..c569edf2f 100644 --- a/src/android/src/org/musikcube/core/TrackPlayer.java +++ b/src/android/src/org/musikcube/core/TrackPlayer.java @@ -7,7 +7,6 @@ public class TrackPlayer implements Runnable, MediaPlayer.OnCompletionListener, public int trackId = 0; private Thread thread; - private String url; private java.lang.Object lock = new java.lang.Object(); private MediaPlayer mediaPlayer; private int buffer = 0; @@ -21,7 +20,6 @@ public class TrackPlayer implements Runnable, MediaPlayer.OnCompletionListener, public static final int STATUS_EXIT = 10; public void run() { - Log.v("mC2::TrackPlayer", "Thread started "+this.url); synchronized(this.lock){ this.mediaPlayer = new MediaPlayer(); } @@ -30,11 +28,22 @@ public class TrackPlayer implements Runnable, MediaPlayer.OnCompletionListener, this.mediaPlayer.setOnCompletionListener(this); this.mediaPlayer.setOnErrorListener(this); this.mediaPlayer.setOnBufferingUpdateListener(this); - - this.mediaPlayer.setDataSource(this.url); - Log.v("mC2::TrackPlayer", "Preparing "+this.url); - this.mediaPlayer.prepare(); - Log.v("mC2::TrackPlayer", "Prepared "+this.url); + + { + String url = Library.GetInstance().GetTrackURL(this.trackId); + while(url==null && (this.status==STATUS_PREPARED || this.status==STATUS_PLAYING)){ + Log.v("mC2::TrackPlayer","Retrying "+this.trackId); + this.lock.wait(250); + url = Library.GetInstance().GetTrackURL(this.trackId); + } + + if(url==null){ + this.status = STATUS_EXIT; + }else{ + this.mediaPlayer.setDataSource(url); + this.mediaPlayer.prepare(); + } + } synchronized(this.lock){ if(this.listener!=null){ @@ -49,8 +58,6 @@ public class TrackPlayer implements Runnable, MediaPlayer.OnCompletionListener, synchronized(this.lock){ currentStatus = this.status; } - - Log.v("mC2::TrackPlayer", "Start? "+this.url); if(currentStatus==STATUS_PLAYING) this.mediaPlayer.start(); @@ -64,7 +71,6 @@ public class TrackPlayer implements Runnable, MediaPlayer.OnCompletionListener, // The track is almost done this.almostDoneSend = true; if(this.listener!=null){ - Log.v("mC2::TrackPlayer", "OnTrackAlmostDone "+this.url); this.listener.OnTrackAlmostDone(this); } } @@ -73,7 +79,6 @@ public class TrackPlayer implements Runnable, MediaPlayer.OnCompletionListener, } } - Log.v("mC2::TrackPlayer", "Stopping "+this.url); this.mediaPlayer.stop(); this.mediaPlayer.release(); @@ -86,29 +91,17 @@ public class TrackPlayer implements Runnable, MediaPlayer.OnCompletionListener, synchronized(this.lock){ this.status = STATUS_EXIT; } - Log.v("mC2::TrackPlayer", "ExitCallbacks "+this.url); this.CallListener(); - Log.v("mC2::TrackPlayer", "END "+this.url); } - public TrackPlayer(String url,int trackId){ + public TrackPlayer(int trackId){ this.trackId = trackId; - this.url = url; this.thread = new Thread(this); this.thread.start(); } -/* public TrackPlayer(String url,boolean start){ - this.url = url; - if(start==true){ - this.status = STATUS_PLAYING; - } - this.thread = new Thread(this); - this.thread.start(); - }*/ - private void Exit(){ synchronized(this.lock){ this.status = STATUS_EXIT;