我正在尝试使用服务播放音频并更新适配器中的搜索栏项目。但我无法从服务中获得音频的持续时间。此外,在滚动recyclerview时,会更新多个项目视图,而不是更新当前正在播放的搜索栏项目。我试过下面的代码。
public class LocalService extends Service {
boolean mBound = false;
private final IBinder mBinder = new LocalBinder();
private String path = "";
private int timer;
private static MediaPlayer mediaPlayer = new MediaPlayer();
// Random number generator
/**
* Class used for the client Binder. Because we know this service always
* runs in the same process as its clients, we don't need to deal with IPC.
*/
public class LocalBinder extends Binder {
public LocalService getService() {
// Return this instance of LocalService so clients can call public methods
return LocalService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
/**
* method for clients
*/
public int getTotalTime() {
return mediaPlayer.getDuration();
}
public int getDuration() {
// Log.v("player duration",timer+"");
try {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
Log.v("playing", (mediaPlayer.getCurrentPosition() / 1000) + "");
return mediaPlayer.getCurrentPosition() / 1000;
} else {
//Log.v("not playing", (mediaPlayer.getCurrentPosition() / 1000) + "");
return 0;
}
}catch (IllegalStateException i)
{
i.printStackTrace();
return 0;
}
catch (Exception e)
{
e.printStackTrace();
return 0;
}
}
@Override
public void onCreate() {
super.onCreate();
try {
mediaPlayer = new MediaPlayer();
} catch (Exception e) {
e.printStackTrace();
}
}
public void setAudio(String path)
{
try {
mediaPlayer.setDataSource(path);
} catch (IOException e) {
e.printStackTrace();
}
catch (Exception e)
{
e.printStackTrace();
}
}
public void playAudio() {
Log.v("audio path", path);
try {
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer.prepareAsync();
mediaPlayer.start();
timer=mediaPlayer.getDuration();
Log.v("total timer1",timer+"");
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
timer=0;
mediaPlayer.stop();
mediaPlayer.reset();
//mediaPlayer.release();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
@Override
public void unbindService(ServiceConnection conn) {
super.unbindService(conn);
mediaPlayer.reset();
mediaPlayer.release();
}
@Override
public void onDestroy() {
super.onDestroy();
mediaPlayer.reset();
mediaPlayer.release();
}
服务从适配器构造函数启动。
Intent intent = new Intent(mContext, LocalService.class);
mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
玩家项目点击回收器adpater
vhItemHolder.playPauseImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
currentlyPlayingPosition = position;
if (mBound) {
Log.v("service","bound");
//Make sure you update Seekbar on UI thread
mService.setAudio(audioDirectory+messageArrayList.get(position).getmMediaValue());
mPlayer=new MediaPlayer();
try {
mPlayer.setDataSource(audioDirectory+messageArrayList.get(position).getmMediaValue());
mPlayer.prepareAsync();
vhItemHolder.seekBar.setMax(mPlayer.getDuration());
} catch (IOException e) {
e.printStackTrace();
}
mService.playAudio();
Log.v("duration",(mService.getTotalTime())+"");
vhItemHolder.seekBar.setMax(mService.getTotalTime());
mHandler.removeCallbacks(null);
mHandler=new Handler();
((DoctorActivity)mContext).runOnUiThread(new Runnable() {
@Override
public void run() {
num = mService.getDuration();
Log.v("progress",num+"");
vhItemHolder.seekBar.setProgress((num));
vhItemHolder.runningTimerTextView.setText(convertMilliToMinutes((long)mService.getDuration()));
mHandler.postDelayed(this, 50);
}
});
}
else
{
Log.v("service","not bound");
}
答案 0 :(得分:0)
在适配器类中: 您正在viewHolder的playPauseImageView的onClickListener中创建MediaPlayer(mPlayer)的新对象,并在其上调用setDataSource()方法,该方法将此本地mPlayer对象的数据源设置为LocalService类的mediaPlayer对象。
调用mService.playAudio()和mService.getDuration()方法访问尚未调用setDataSource()方法的LocalService类'mediaPlayer对象,因此必须返回错误的持续时间且无法播放。
您应该在适配器类中进行更改,如下所示:
vhItemHolder.playPauseImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
currentlyPlayingPosition = position;
if (mBound) {
Log.v("service","bound");
//Make sure you update Seekbar on UI thread
mService.setAudio(audioDirectory+messageArrayList.get(position).getmMediaValue());
mPlayer = mService.mediaPlayer;// or mPlayer = LocalService.mediaPlayer; as being static object.
//rather new MediaPlayer();
try {
mPlayer.setDataSource(audioDirectory+messageArrayList.get(position).getmMediaValue());
mPlayer.prepareAsync();
vhItemHolder.seekBar.setMax(mPlayer.getDuration());
} catch (IOException e) {
e.printStackTrace();
}
mService.playAudio();
Log.v("duration",(mService.getTotalTime())+"");
vhItemHolder.seekBar.setMax(mService.getTotalTime());
mHandler.removeCallbacks(null);
mHandler=new Handler();
((DoctorActivity)mContext).runOnUiThread(new Runnable() {
@Override
public void run() {
num = mService.getDuration();
Log.v("progress",num+"");
vhItemHolder.seekBar.setProgress((num));
vhItemHolder.runningTimerTextView.setText(convertMilliToMinutes((long)mService.getDuration()));
mHandler.postDelayed(this, 50);
}
});
}
else
{
Log.v("service","not bound");
}