Merge MusicPlayer back into PlaybackService

This commit is contained in:
Christopher Eby 2010-02-21 16:55:19 -06:00
parent 40ebd4ec1b
commit 0a95320bce
4 changed files with 432 additions and 477 deletions

View File

@ -1,452 +0,0 @@
package org.kreed.tumult;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.preference.PreferenceManager;
public class MusicPlayer implements Runnable, MediaPlayer.OnCompletionListener, SharedPreferences.OnSharedPreferenceChangeListener {
private static final int NOTIFICATION_ID = 2;
public static final int STATE_NORMAL = 0;
public static final int STATE_NO_MEDIA = 1;
public static final int STATE_PLAYING = 2;
public IPlaybackService.Stub mBinder = new IPlaybackService.Stub() {
public Song[] getCurrentSongs()
{
return new Song[] { getSong(-1), getSong(0), getSong(1) };
}
public Song getSong(int delta)
{
return MusicPlayer.this.getSong(delta);
}
public int getState()
{
return mState;
}
public int getPosition()
{
if (mMediaPlayer == null)
return 0;
return mMediaPlayer.getCurrentPosition();
}
public int getDuration()
{
if (mMediaPlayer == null)
return 0;
return mMediaPlayer.getDuration();
}
public void nextSong()
{
if (mHandler == null)
return;
mHandler.sendMessage(mHandler.obtainMessage(SET_SONG, 1, 0));
}
public void previousSong()
{
if (mHandler == null)
return;
mHandler.sendMessage(mHandler.obtainMessage(SET_SONG, -1, 0));
}
public void togglePlayback()
{
if (mHandler == null)
return;
mHandler.sendMessage(mHandler.obtainMessage(PLAY_PAUSE, 0, 0));
}
public void registerWatcher(IMusicPlayerWatcher watcher)
{
if (watcher != null)
mWatchers.register(watcher);
}
public void unregisterWatcher(IMusicPlayerWatcher watcher)
{
if (watcher != null)
mWatchers.unregister(watcher);
}
public void seekToProgress(int progress)
{
if (mMediaPlayer == null || !mMediaPlayer.isPlaying())
return;
long position = (long)mMediaPlayer.getDuration() * progress / 1000;
mMediaPlayer.seekTo((int)position);
}
};
public void queueSong(int songId)
{
if (mHandler == null)
return;
mHandler.sendMessage(mHandler.obtainMessage(QUEUE_ITEM, ITEM_SONG, songId));
}
public void stopQueueing()
{
if (mHandler == null)
return;
mHandler.sendMessage(mHandler.obtainMessage(QUEUE_ITEM, ITEM_RESET, 0));
}
private PlaybackService mService;
private RemoteCallbackList<IMusicPlayerWatcher> mWatchers;
private boolean mHeadsetOnly;
private boolean mUseRemotePlayer;
private Handler mHandler;
private MediaPlayer mMediaPlayer;
private Random mRandom;
private PowerManager.WakeLock mWakeLock;
private int[] mSongs;
private ArrayList<Song> mSongTimeline;
private int mCurrentSong = -1;
private int mQueuePos = 0;
private boolean mPlugged = true;
private int mState = STATE_NORMAL;
public MusicPlayer(PlaybackService service)
{
mService = service;
mWatchers = new RemoteCallbackList<IMusicPlayerWatcher>();
mSongTimeline = new ArrayList<Song>();
new Thread(this).start();
}
private static final int SET_SONG = 0;
private static final int PLAY_PAUSE = 1;
private static final int HEADSET_PLUGGED = 2;
private static final int HEADSET_PREF_CHANGED = 3;
private static final int QUEUE_ITEM = 4;
private static final int TRACK_CHANGED = 5;
private static final int RELEASE_WAKE_LOCK = 6;
private static final int HANDLE_PLAY = 7;
private static final int HANDLE_PAUSE = 8;
private static final int RETRIEVE_SONGS = 9;
private static final int REMOTE_PLAYER_PREF_CHANGED = 10;
private static final int ITEM_SONG = 0;
private static final int ITEM_RESET = 1;
public void run()
{
Looper.prepare();
mMediaPlayer = new MediaPlayer();
mRandom = new Random();
mHandler = new Handler() {
public void handleMessage(Message message)
{
switch (message.what) {
case SET_SONG:
setCurrentSong(message.arg1);
break;
case PLAY_PAUSE:
setPlaying(!mMediaPlayer.isPlaying());
break;
case HEADSET_PLUGGED:
boolean plugged = message.arg1 == 1;
if (plugged != mPlugged) {
mPlugged = plugged;
if (mCurrentSong == -1)
return;
if (!plugged && mMediaPlayer.isPlaying())
setPlaying(false);
}
break;
case HEADSET_PREF_CHANGED:
mHeadsetOnly = message.arg1 == 1;
if (mHeadsetOnly && !mPlugged && mMediaPlayer.isPlaying())
pause();
break;
case QUEUE_ITEM:
switch (message.arg1) {
case ITEM_SONG:
int i = mCurrentSong + 1 + mQueuePos++;
Song song = new Song(message.arg2);
Toast.makeText(Tumult.getContext(), "Enqueued " + song.title, Toast.LENGTH_SHORT).show();
if (i < mSongTimeline.size())
mSongTimeline.set(i, song);
else
mSongTimeline.add(song);
break;
case ITEM_RESET:
mQueuePos = 0;
break;
}
break;
case TRACK_CHANGED:
setCurrentSong(+1);
break;
case RELEASE_WAKE_LOCK:
if (mWakeLock.isHeld())
mWakeLock.release();
break;
case HANDLE_PLAY:
setState(STATE_PLAYING);
mService.startForegroundCompat(NOTIFICATION_ID, createNotification());
break;
case HANDLE_PAUSE:
setState(STATE_NORMAL);
mService.stopForegroundCompat(0);
break;
case RETRIEVE_SONGS:
retrieveSongs();
break;
case REMOTE_PLAYER_PREF_CHANGED:
mUseRemotePlayer = message.arg1 == 1;
if (mState == STATE_PLAYING)
mService.startForegroundCompat(NOTIFICATION_ID, createNotification());
break;
}
}
};
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_HEADSET_PLUG);
filter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
filter.addAction(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
mService.registerReceiver(mReceiver, filter);
PowerManager powerManager = (PowerManager)mService.getSystemService(Context.POWER_SERVICE);
mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "TumultSongChangeLock");
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setWakeMode(mService, PowerManager.PARTIAL_WAKE_LOCK);
mMediaPlayer.setOnCompletionListener(this);
retrieveSongs();
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(mService);
mHeadsetOnly = settings.getBoolean("headset_only", false);
mUseRemotePlayer = settings.getBoolean("remote_player", true);
settings.registerOnSharedPreferenceChangeListener(this);
setCurrentSong(1);
NotificationManager manager = (NotificationManager)mService.getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(NOTIFICATION_ID, createNotification());
Looper.loop();
}
public void release()
{
if (mMediaPlayer != null) {
if (mMediaPlayer.isPlaying())
mMediaPlayer.pause();
mMediaPlayer.release();
mMediaPlayer = null;
}
mService.unregisterReceiver(mReceiver);
mService.stopForegroundCompat(NOTIFICATION_ID);
if (mWakeLock != null && mWakeLock.isHeld())
mWakeLock.release();
}
public void setState(int state)
{
if (mState == state)
return;
int oldState = mState;
mState = state;
int i = mWatchers.beginBroadcast();
while (--i != -1) {
try {
mWatchers.getBroadcastItem(i).stateChanged(oldState, mState);
} catch (RemoteException e) {
// Null elements will be removed automatically
}
}
mWatchers.finishBroadcast();
}
private void retrieveSongs()
{
mSongs = Song.getAllSongs();
if (mSongs == null) {
setState(STATE_NO_MEDIA);
} else {
if (mState == STATE_NO_MEDIA)
setState(STATE_NORMAL);
}
}
private Notification createNotification()
{
Song song = getSong(0);
RemoteViews views = new RemoteViews(mService.getPackageName(), R.layout.statusbar);
views.setImageViewResource(R.id.icon, R.drawable.status_icon);
views.setTextViewText(R.id.title, song.title);
views.setTextViewText(R.id.artist, song.artist);
Notification notification = new Notification();
notification.contentView = views;
notification.icon = R.drawable.status_icon;
notification.flags |= Notification.FLAG_ONGOING_EVENT;
Intent intent = new Intent(mService, mUseRemotePlayer ? RemoteActivity.class : NowPlayingActivity.class);
notification.contentIntent = PendingIntent.getActivity(mService, 0, intent, 0);
return notification;
}
private void play()
{
if (mHeadsetOnly && !mPlugged)
return;
mMediaPlayer.start();
mHandler.sendEmptyMessage(HANDLE_PLAY);
}
private void pause()
{
mMediaPlayer.pause();
mHandler.sendEmptyMessage(HANDLE_PAUSE);
}
private void setPlaying(boolean play)
{
if (play)
play();
else
pause();
}
private void setCurrentSong(int delta)
{
Song song = getSong(delta);
if (song == null)
return;
mCurrentSong += delta;
try {
mMediaPlayer.reset();
mMediaPlayer.setDataSource(song.path);
mMediaPlayer.prepare();
if (mState == STATE_PLAYING)
play();
} catch (IOException e) {
Log.e("Tumult", "IOException", e);
}
int i = mWatchers.beginBroadcast();
while (--i != -1) {
try {
mWatchers.getBroadcastItem(i).songChanged(song);
} catch (RemoteException e) {
// Null elements will be removed automatically
}
}
mWatchers.finishBroadcast();
getSong(+2);
while (mCurrentSong > 15) {
mSongTimeline.remove(0);
--mCurrentSong;
}
}
public void onCompletion(MediaPlayer player)
{
mWakeLock.acquire();
mHandler.sendEmptyMessage(TRACK_CHANGED);
mHandler.sendEmptyMessage(RELEASE_WAKE_LOCK);
}
private Song randomSong()
{
return new Song(mSongs[mRandom.nextInt(mSongs.length)]);
}
private synchronized Song getSong(int delta)
{
int pos = mCurrentSong + delta;
if (pos < 0)
return null;
int size = mSongTimeline.size();
if (pos > size)
return null;
if (pos == size) {
if (mSongs == null)
return null;
mSongTimeline.add(randomSong());
}
return mSongTimeline.get(pos);
}
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context content, Intent intent)
{
String action = intent.getAction();
if (Intent.ACTION_HEADSET_PLUG.equals(action) && mHandler != null) {
int plugged = intent.getIntExtra("state", 0) == 130 ? 1 : 0;
mHandler.sendMessage(mHandler.obtainMessage(HEADSET_PLUGGED, plugged, 0));
} else if (Intent.ACTION_MEDIA_SCANNER_FINISHED.equals(action)
|| Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)) {
mHandler.sendEmptyMessage(RETRIEVE_SONGS);
}
}
};
public void onSharedPreferenceChanged(SharedPreferences settings, String key)
{
if (mHandler == null)
return;
if ("headset_only".equals(key)) {
int arg = settings.getBoolean(key, false) ? 1 : 0;
mHandler.sendMessage(mHandler.obtainMessage(HEADSET_PREF_CHANGED, arg, 0));
} else if ("remote_player".equals(key)) {
int arg = settings.getBoolean(key, true) ? 1 : 0;
mHandler.sendMessage(mHandler.obtainMessage(REMOTE_PLAYER_PREF_CHANGED, arg, 0));
}
}
}

View File

@ -130,19 +130,19 @@ public class NowPlayingActivity extends Activity implements ServiceConnection, V
}
switch (state) {
case MusicPlayer.STATE_NORMAL:
case PlaybackService.STATE_NORMAL:
mControlsBottom.setVisibility(View.VISIBLE);
// fall through
case MusicPlayer.STATE_PLAYING:
case PlaybackService.STATE_PLAYING:
removeMessageOverlay();
if (!mHandler.hasMessages(HIDE))
mControlsBottom.setVisibility(View.GONE);
mSeekBar.setEnabled(state == MusicPlayer.STATE_PLAYING);
mPlayPauseButton.setImageResource(state == MusicPlayer.STATE_PLAYING ? R.drawable.pause : R.drawable.play);
mSeekBar.setEnabled(state == PlaybackService.STATE_PLAYING);
mPlayPauseButton.setImageResource(state == PlaybackService.STATE_PLAYING ? R.drawable.pause : R.drawable.play);
break;
case MusicPlayer.STATE_NO_MEDIA:
case PlaybackService.STATE_NO_MEDIA:
makeMessageOverlay();
RelativeLayout.LayoutParams layoutParams =
@ -353,7 +353,7 @@ public class NowPlayingActivity extends Activity implements ServiceConnection, V
if (view == mCoverView) {
if (mControlsTop.getVisibility() == View.VISIBLE) {
mControlsTop.setVisibility(View.GONE);
if (mState == MusicPlayer.STATE_PLAYING)
if (mState == PlaybackService.STATE_PLAYING)
mControlsBottom.setVisibility(View.GONE);
} else {
mControlsTop.setVisibility(View.VISIBLE);
@ -383,7 +383,7 @@ public class NowPlayingActivity extends Activity implements ServiceConnection, V
switch (message.what) {
case HIDE:
mControlsTop.setVisibility(View.GONE);
if (mState == MusicPlayer.STATE_PLAYING)
if (mState == PlaybackService.STATE_PLAYING)
mControlsBottom.setVisibility(View.GONE);
break;
case UPDATE_PROGRESS:

View File

@ -1,27 +1,122 @@
package org.kreed.tumult;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Random;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
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.os.PowerManager;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast;
public class PlaybackService extends Service {
private MusicPlayer mPlayer;
public class PlaybackService extends Service implements Runnable, MediaPlayer.OnCompletionListener, SharedPreferences.OnSharedPreferenceChangeListener {
private static final int NOTIFICATION_ID = 2;
public static final int STATE_NORMAL = 0;
public static final int STATE_NO_MEDIA = 1;
public static final int STATE_PLAYING = 2;
private RemoteCallbackList<IMusicPlayerWatcher> mWatchers;
private NotificationManager mNotificationManager;
private Method mStartForeground;
private Method mStopForeground;
public IPlaybackService.Stub mBinder = new IPlaybackService.Stub() {
public Song[] getCurrentSongs()
{
return new Song[] { getSong(-1), getSong(0), getSong(1) };
}
public Song getSong(int delta)
{
return PlaybackService.this.getSong(delta);
}
public int getState()
{
return mState;
}
public int getPosition()
{
if (mMediaPlayer == null)
return 0;
return mMediaPlayer.getCurrentPosition();
}
public int getDuration()
{
if (mMediaPlayer == null)
return 0;
return mMediaPlayer.getDuration();
}
public void nextSong()
{
if (mHandler == null)
return;
mHandler.sendMessage(mHandler.obtainMessage(SET_SONG, 1, 0));
}
public void previousSong()
{
if (mHandler == null)
return;
mHandler.sendMessage(mHandler.obtainMessage(SET_SONG, -1, 0));
}
public void togglePlayback()
{
if (mHandler == null)
return;
mHandler.sendMessage(mHandler.obtainMessage(PLAY_PAUSE, 0, 0));
}
public void registerWatcher(IMusicPlayerWatcher watcher)
{
if (watcher != null)
mWatchers.register(watcher);
}
public void unregisterWatcher(IMusicPlayerWatcher watcher)
{
if (watcher != null)
mWatchers.unregister(watcher);
}
public void seekToProgress(int progress)
{
if (mMediaPlayer == null || !mMediaPlayer.isPlaying())
return;
long position = (long)mMediaPlayer.getDuration() * progress / 1000;
mMediaPlayer.seekTo((int)position);
}
};
@Override
public IBinder onBind(Intent intent)
{
if (mPlayer == null)
return null;
return mPlayer.mBinder;
return mBinder;
}
@Override
@ -35,29 +130,41 @@ public class PlaybackService extends Service {
// Running on an older platform.
mStartForeground = mStopForeground = null;
}
mPlayer = new MusicPlayer(this);
mWatchers = new RemoteCallbackList<IMusicPlayerWatcher>();
new Thread(this).start();
}
@Override
public void onStart(Intent intent, int flags)
{
int id;
if (mHandler == null)
return;
if ((id = intent.getIntExtra("songId", -1)) != -1)
mPlayer.queueSong(id);
else
mPlayer.stopQueueing();
int id = intent.getIntExtra("songId", -1);
mHandler.sendMessage(mHandler.obtainMessage(QUEUE_ITEM, id, 0));
}
@Override
public void onDestroy()
{
super.onDestroy();
if (mPlayer != null) {
mPlayer.release();
mPlayer = null;
if (mMediaPlayer != null) {
MediaPlayer player = mMediaPlayer;
mMediaPlayer = null;
if (player.isPlaying())
player.pause();
player.release();
}
unregisterReceiver(mReceiver);
stopForegroundCompat(NOTIFICATION_ID);
if (mWakeLock != null && mWakeLock.isHeld())
mWakeLock.release();
}
public void startForegroundCompat(int id, Notification notification)
@ -93,4 +200,304 @@ public class PlaybackService extends Service {
}
}
}
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context content, Intent intent)
{
String action = intent.getAction();
if (Intent.ACTION_HEADSET_PLUG.equals(action) && mHandler != null) {
int plugged = intent.getIntExtra("state", 0) == 130 ? 1 : 0;
mHandler.sendMessage(mHandler.obtainMessage(HEADSET_PLUGGED, plugged, 0));
} else if (Intent.ACTION_MEDIA_SCANNER_FINISHED.equals(action)
|| Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)) {
mHandler.sendEmptyMessage(RETRIEVE_SONGS);
}
}
};
public void onSharedPreferenceChanged(SharedPreferences settings, String key)
{
if (mHandler == null)
return;
if ("headset_only".equals(key)) {
int arg = settings.getBoolean(key, false) ? 1 : 0;
mHandler.sendMessage(mHandler.obtainMessage(HEADSET_PREF_CHANGED, arg, 0));
} else if ("remote_player".equals(key)) {
int arg = settings.getBoolean(key, true) ? 1 : 0;
mHandler.sendMessage(mHandler.obtainMessage(REMOTE_PLAYER_PREF_CHANGED, arg, 0));
}
}
private boolean mHeadsetOnly;
private boolean mUseRemotePlayer;
private Handler mHandler;
private MediaPlayer mMediaPlayer;
private Random mRandom;
private PowerManager.WakeLock mWakeLock;
private int[] mSongs;
private ArrayList<Song> mSongTimeline;
private int mCurrentSong = -1;
private int mQueuePos = 0;
private boolean mPlugged = true;
private int mState = STATE_NORMAL;
private static final int SET_SONG = 0;
private static final int PLAY_PAUSE = 1;
private static final int HEADSET_PLUGGED = 2;
private static final int HEADSET_PREF_CHANGED = 3;
private static final int QUEUE_ITEM = 4;
private static final int TRACK_CHANGED = 5;
private static final int RELEASE_WAKE_LOCK = 6;
private static final int HANDLE_PLAY = 7;
private static final int HANDLE_PAUSE = 8;
private static final int RETRIEVE_SONGS = 9;
private static final int REMOTE_PLAYER_PREF_CHANGED = 10;
public void run()
{
Looper.prepare();
mMediaPlayer = new MediaPlayer();
mSongTimeline = new ArrayList<Song>();
mRandom = new Random();
mHandler = new Handler() {
public void handleMessage(Message message)
{
switch (message.what) {
case SET_SONG:
setCurrentSong(message.arg1);
break;
case PLAY_PAUSE:
setPlaying(!mMediaPlayer.isPlaying());
break;
case HEADSET_PLUGGED:
boolean plugged = message.arg1 == 1;
if (plugged != mPlugged) {
mPlugged = plugged;
if (mCurrentSong == -1)
return;
if (!plugged && mMediaPlayer.isPlaying())
setPlaying(false);
}
break;
case HEADSET_PREF_CHANGED:
mHeadsetOnly = message.arg1 == 1;
if (mHeadsetOnly && !mPlugged && mMediaPlayer.isPlaying())
pause();
break;
case QUEUE_ITEM:
if (message.arg1 == -1) {
mQueuePos = 0;
} else {
Song song = new Song(message.arg1);
Toast.makeText(Tumult.getContext(), "Enqueued " + song.title, Toast.LENGTH_SHORT).show();
int i = mCurrentSong + 1 + mQueuePos++;
if (i < mSongTimeline.size())
mSongTimeline.set(i, song);
else
mSongTimeline.add(song);
}
break;
case TRACK_CHANGED:
setCurrentSong(+1);
break;
case RELEASE_WAKE_LOCK:
if (mWakeLock.isHeld())
mWakeLock.release();
break;
case HANDLE_PLAY:
setState(STATE_PLAYING);
startForegroundCompat(NOTIFICATION_ID, createNotification());
break;
case HANDLE_PAUSE:
setState(STATE_NORMAL);
stopForegroundCompat(0);
break;
case RETRIEVE_SONGS:
retrieveSongs();
break;
case REMOTE_PLAYER_PREF_CHANGED:
mUseRemotePlayer = message.arg1 == 1;
if (mState == STATE_PLAYING)
startForegroundCompat(NOTIFICATION_ID, createNotification());
break;
}
}
};
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_HEADSET_PLUG);
filter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
filter.addAction(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
registerReceiver(mReceiver, filter);
PowerManager powerManager = (PowerManager)getSystemService(POWER_SERVICE);
mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "TumultSongChangeLock");
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setWakeMode(this, PowerManager.PARTIAL_WAKE_LOCK);
mMediaPlayer.setOnCompletionListener(this);
retrieveSongs();
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
mHeadsetOnly = settings.getBoolean("headset_only", false);
mUseRemotePlayer = settings.getBoolean("remote_player", true);
settings.registerOnSharedPreferenceChangeListener(this);
setCurrentSong(1);
mNotificationManager.notify(NOTIFICATION_ID, createNotification());
Looper.loop();
}
public void setState(int state)
{
if (mState == state)
return;
int oldState = mState;
mState = state;
int i = mWatchers.beginBroadcast();
while (--i != -1) {
try {
mWatchers.getBroadcastItem(i).stateChanged(oldState, mState);
} catch (RemoteException e) {
// Null elements will be removed automatically
}
}
mWatchers.finishBroadcast();
}
private void retrieveSongs()
{
mSongs = Song.getAllSongs();
if (mSongs == null) {
setState(STATE_NO_MEDIA);
} else {
if (mState == STATE_NO_MEDIA)
setState(STATE_NORMAL);
}
}
private Notification createNotification()
{
Song song = getSong(0);
RemoteViews views = new RemoteViews(getPackageName(), R.layout.statusbar);
views.setImageViewResource(R.id.icon, R.drawable.status_icon);
views.setTextViewText(R.id.title, song.title);
views.setTextViewText(R.id.artist, song.artist);
Notification notification = new Notification();
notification.contentView = views;
notification.icon = R.drawable.status_icon;
notification.flags |= Notification.FLAG_ONGOING_EVENT;
Intent intent = new Intent(this, mUseRemotePlayer ? RemoteActivity.class : NowPlayingActivity.class);
notification.contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
return notification;
}
private void play()
{
if (mHeadsetOnly && !mPlugged)
return;
mMediaPlayer.start();
mHandler.sendEmptyMessage(HANDLE_PLAY);
}
private void pause()
{
mMediaPlayer.pause();
mHandler.sendEmptyMessage(HANDLE_PAUSE);
}
private void setPlaying(boolean play)
{
if (play)
play();
else
pause();
}
private void setCurrentSong(int delta)
{
Song song = getSong(delta);
if (song == null)
return;
mCurrentSong += delta;
try {
mMediaPlayer.reset();
mMediaPlayer.setDataSource(song.path);
mMediaPlayer.prepare();
if (mState == STATE_PLAYING)
play();
} catch (IOException e) {
Log.e("Tumult", "IOException", e);
}
int i = mWatchers.beginBroadcast();
while (--i != -1) {
try {
mWatchers.getBroadcastItem(i).songChanged(song);
} catch (RemoteException e) {
// Null elements will be removed automatically
}
}
mWatchers.finishBroadcast();
getSong(+2);
while (mCurrentSong > 15) {
mSongTimeline.remove(0);
--mCurrentSong;
}
}
public void onCompletion(MediaPlayer player)
{
mWakeLock.acquire();
mHandler.sendEmptyMessage(TRACK_CHANGED);
mHandler.sendEmptyMessage(RELEASE_WAKE_LOCK);
}
private Song randomSong()
{
return new Song(mSongs[mRandom.nextInt(mSongs.length)]);
}
private synchronized Song getSong(int delta)
{
if (mSongTimeline == null)
return null;
int pos = mCurrentSong + delta;
if (pos < 0)
return null;
int size = mSongTimeline.size();
if (pos > size)
return null;
if (pos == size) {
if (mSongs == null)
return null;
mSongTimeline.add(randomSong());
}
return mSongTimeline.get(pos);
}
}

View File

@ -101,10 +101,10 @@ public class RemoteActivity extends Activity implements ServiceConnection, View.
private void setState(int state)
{
if (state == MusicPlayer.STATE_NO_MEDIA)
if (state == PlaybackService.STATE_NO_MEDIA)
finish();
mPlayPauseButton.setImageResource(state == MusicPlayer.STATE_PLAYING ? R.drawable.pause : R.drawable.play);
mPlayPauseButton.setImageResource(state == PlaybackService.STATE_PLAYING ? R.drawable.pause : R.drawable.play);
}
private IMusicPlayerWatcher mWatcher = new IMusicPlayerWatcher.Stub() {