Use broadcasts instead of callbacks in PlaybackService

This commit is contained in:
Christopher Eby 2010-03-06 21:28:58 -06:00
parent acd259e305
commit a87a185c3c
5 changed files with 86 additions and 122 deletions

View File

@ -18,10 +18,12 @@
package org.kreed.vanilla;
import org.kreed.vanilla.IMusicPlayerWatcher;
import org.kreed.vanilla.IPlaybackService;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
@ -49,7 +51,6 @@ public class CoverView extends View {
private float mStartX;
private float mStartY;
private IPlaybackService mService;
private boolean loaded;
Song[] mSongs = new Song[3];
private Bitmap[] mBitmaps = new Bitmap[3];
@ -61,13 +62,19 @@ public class CoverView extends View {
super(context, attributes);
mScroller = new Scroller(context);
IntentFilter filter = new IntentFilter();
filter.addAction(PlaybackService.EVENT_LOADED);
filter.addAction(PlaybackService.EVENT_SONG_CHANGED);
context.registerReceiver(mReceiver, filter);
}
public void setPlaybackService(IPlaybackService service)
{
try {
mService = service;
mService.registerWatcher(mWatcher);
if (mService.isLoaded())
refreshSongs();
} catch (RemoteException e) {
}
}
@ -279,8 +286,6 @@ public class CoverView extends View {
{
if (mService == null)
throw new RemoteException();
if (delta != 0 && !loaded)
return;
mHandler.sendMessage(mHandler.obtainMessage(GO, delta, 0));
}
@ -289,7 +294,7 @@ public class CoverView extends View {
if (!mScroller.isFinished())
mScroller.abortAnimation();
scrollTo(getWidth(), 0);
postInvalidate();
invalidate();
}
@Override
@ -449,24 +454,22 @@ public class CoverView extends View {
}
};
private IMusicPlayerWatcher mWatcher = new IMusicPlayerWatcher.Stub() {
public void loaded()
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent)
{
loaded = true;
refreshSongs();
}
String action = intent.getAction();
public void songChanged(Song playingSong)
{
Song currentSong = mSongs[STORE_SIZE / 2];
if (currentSong == null)
mHandler.sendMessage(mHandler.obtainMessage(SET_COVER, playingSong));
else if (!currentSong.equals(playingSong))
if (PlaybackService.EVENT_LOADED.equals(action)) {
refreshSongs();
}
public void stateChanged(int oldState, int newState)
{
} else if (PlaybackService.EVENT_SONG_CHANGED.equals(action)) {
Song currentSong = mSongs[STORE_SIZE / 2];
Song playingSong = intent.getParcelableExtra("song");
if (currentSong == null)
mHandler.sendMessage(mHandler.obtainMessage(SET_COVER, playingSong));
else if (!currentSong.equals(playingSong))
refreshSongs();
}
}
};
}

View File

@ -19,11 +19,9 @@
package org.kreed.vanilla;
import org.kreed.vanilla.Song;
import org.kreed.vanilla.IMusicPlayerWatcher;
interface IPlaybackService {
void registerWatcher(IMusicPlayerWatcher watcher);
void unregisterWatcher(IMusicPlayerWatcher watcher);
boolean isLoaded();
Song getSong(int delta);
int getState();

View File

@ -18,14 +18,15 @@
package org.kreed.vanilla;
import org.kreed.vanilla.IMusicPlayerWatcher;
import org.kreed.vanilla.IPlaybackService;
import org.kreed.vanilla.R;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.graphics.Color;
import android.os.Bundle;
@ -187,6 +188,11 @@ public class NowPlayingActivity extends Activity implements ServiceConnection, V
super.onStart();
prepareService();
IntentFilter filter = new IntentFilter();
filter.addAction(PlaybackService.EVENT_SONG_CHANGED);
filter.addAction(PlaybackService.EVENT_STATE_CHANGED);
registerReceiver(mReceiver, filter);
}
@Override
@ -196,6 +202,11 @@ public class NowPlayingActivity extends Activity implements ServiceConnection, V
if (mService != null) {
unbindService(this);
try {
unregisterReceiver(mReceiver);
} catch (IllegalArgumentException e) {
// we haven't registered the receiver yet
}
mHandler.sendEmptyMessage(UNSET_SERVICE);
}
}
@ -215,15 +226,9 @@ public class NowPlayingActivity extends Activity implements ServiceConnection, V
int state = mState;
if (service == null) {
if (mService != null)
try {
mService.unregisterWatcher(mWatcher);
} catch (RemoteException e) {
}
mCoverView.clearSongs();
} else {
try {
service.registerWatcher(mWatcher);
mCoverView.setPlaybackService(service);
state = service.getState();
mDuration = service.getDuration();
@ -247,31 +252,21 @@ public class NowPlayingActivity extends Activity implements ServiceConnection, V
setService(null);
}
private IMusicPlayerWatcher mWatcher = new IMusicPlayerWatcher.Stub() {
public void loaded()
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent)
{
}
public void songChanged(Song playingSong)
{
if (mService == null)
return;
try {
mDuration = mService.getDuration();
mHandler.sendEmptyMessage(UPDATE_PROGRESS);
} catch (RemoteException e) {
}
}
public void stateChanged(final int oldState, final int newState)
{
runOnUiThread(new Runnable() {
public void run()
{
setState(newState);
String action = intent.getAction();
if (PlaybackService.EVENT_SONG_CHANGED.equals(action)) {
try {
mDuration = mService.getDuration();
mHandler.sendEmptyMessage(UPDATE_PROGRESS);
} catch (RemoteException e) {
setService(null);
}
});
} else if (PlaybackService.EVENT_STATE_CHANGED.equals(action)) {
setState(intent.getIntExtra("newState", 0));
}
}
};

View File

@ -27,7 +27,6 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Random;
import org.kreed.vanilla.IMusicPlayerWatcher;
import org.kreed.vanilla.IPlaybackService;
import org.kreed.vanilla.R;
@ -48,8 +47,6 @@ 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.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
@ -64,13 +61,20 @@ public class PlaybackService extends Service implements Runnable, MediaPlayer.On
public static final String TOGGLE_PLAYBACK = "org.kreed.vanilla.action.TOGGLE_PLAYBACK";
public static final String NEXT_SONG = "org.kreed.vanilla.action.NEXT_SONG";
public static final String EVENT_LOADED = "org.kreed.vanilla.event.LOADED";
public static final String EVENT_STATE_CHANGED = "org.kreed.vanilla.event.STATE_CHANGED";
public static final String EVENT_SONG_CHANGED = "org.kreed.vanilla.event.SONG_CHANGED";
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;
public IPlaybackService.Stub mBinder = new IPlaybackService.Stub() {
public boolean isLoaded()
{
return mHandler != null;
}
public Song getSong(int delta)
{
return PlaybackService.this.getSong(delta);
@ -111,22 +115,6 @@ public class PlaybackService extends Service implements Runnable, MediaPlayer.On
mHandler.sendMessage(mHandler.obtainMessage(GO, 0, 0));
}
public void registerWatcher(IMusicPlayerWatcher watcher) throws RemoteException
{
if (watcher != null) {
mWatchers.register(watcher);
// if we're already loaded callback immediately
if (mHandler != null)
watcher.loaded();
}
}
public void unregisterWatcher(IMusicPlayerWatcher watcher)
{
if (watcher != null)
mWatchers.unregister(watcher);
}
public void seekToProgress(int progress)
{
if (mMediaPlayer == null)
@ -149,8 +137,6 @@ public class PlaybackService extends Service implements Runnable, MediaPlayer.On
@Override
public void onCreate()
{
mWatchers = new RemoteCallbackList<IMusicPlayerWatcher>();
new Thread(this).start();
}
@ -182,7 +168,11 @@ public class PlaybackService extends Service implements Runnable, MediaPlayer.On
player.release();
}
unregisterReceiver(mReceiver);
try {
unregisterReceiver(mReceiver);
} catch (IllegalArgumentException e) {
// we haven't registered the receiver yet
}
mNotificationManager.cancel(NOTIFICATION_ID);
resetWidgets();
@ -415,14 +405,7 @@ public class PlaybackService extends Service implements Runnable, MediaPlayer.On
if (mPendingSeek != 0)
mMediaPlayer.seekTo(mPendingSeek);
int i = mWatchers.beginBroadcast();
while (--i != -1) {
try {
mWatchers.getBroadcastItem(i).loaded();
} catch (RemoteException e) {
}
}
mWatchers.finishBroadcast();
sendBroadcast(new Intent(EVENT_LOADED));
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_HEADSET_PLUG);
@ -467,15 +450,10 @@ public class PlaybackService extends Service implements Runnable, MediaPlayer.On
mState = state;
if (mState != oldState) {
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();
Intent intent = new Intent(EVENT_STATE_CHANGED);
intent.putExtra("oldState", oldState);
intent.putExtra("newState", state);
sendBroadcast(intent);
}
Song song = getSong(0);
@ -596,15 +574,9 @@ public class PlaybackService extends Service implements Runnable, MediaPlayer.On
mLastSongBroadcast = song;
int i = mWatchers.beginBroadcast();
while (--i != -1) {
try {
mWatchers.getBroadcastItem(i).songChanged(song);
} catch (RemoteException e) {
// Null elements will be removed automatically
}
}
mWatchers.finishBroadcast();
Intent intent = new Intent(EVENT_SONG_CHANGED);
intent.putExtra("song", song);
sendBroadcast(intent);
}
private void setCurrentSong(int delta)

View File

@ -18,14 +18,15 @@
package org.kreed.vanilla;
import org.kreed.vanilla.IMusicPlayerWatcher;
import org.kreed.vanilla.IPlaybackService;
import org.kreed.vanilla.R;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
@ -72,6 +73,7 @@ public class RemoteActivity extends Activity implements ServiceConnection, View.
super.onResume();
reconnect();
registerReceiver(mReceiver, new IntentFilter(PlaybackService.EVENT_STATE_CHANGED));
}
private void reconnect()
@ -87,6 +89,11 @@ public class RemoteActivity extends Activity implements ServiceConnection, View.
super.onPause();
unbindService(this);
try {
unregisterReceiver(mReceiver);
} catch (IllegalArgumentException e) {
// we haven't registered the receiver yet
}
}
public void onServiceConnected(ComponentName name, IBinder binder)
@ -94,7 +101,6 @@ public class RemoteActivity extends Activity implements ServiceConnection, View.
IPlaybackService service = IPlaybackService.Stub.asInterface(binder);
mCoverView.setPlaybackService(service);
try {
service.registerWatcher(mWatcher);
setState(service.getState());
} catch (RemoteException e) {
}
@ -136,23 +142,13 @@ public class RemoteActivity extends Activity implements ServiceConnection, View.
mPlayPauseButton.setImageResource(state == PlaybackService.STATE_PLAYING ? R.drawable.pause : R.drawable.play);
}
private IMusicPlayerWatcher mWatcher = new IMusicPlayerWatcher.Stub() {
public void loaded()
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent)
{
}
public void songChanged(Song playingSong)
{
}
public void stateChanged(final int oldState, final int newState)
{
runOnUiThread(new Runnable() {
public void run()
{
setState(newState);
}
});
String action = intent.getAction();
if (PlaybackService.EVENT_STATE_CHANGED.equals(action))
setState(intent.getIntExtra("newState", 0));
}
};
}