Why seek bar is not updating programmatically in android? - android

In my app, I am using media player class. I want to update the progress of playing audio file on seek bar and for this I am using below code for playing media file
public class AudioPlayer implements MediaPlayer.OnCompletionListener {
private final static int SAMPLE_RATE = 16000;
private final int DELAY_FOR_HANDLER = 1_000;
static final String LOG_TAG = AudioPlayer.class.getSimpleName();
private Context mContext;
private MediaPlayer mPlayer;
private AudioTrack mProgressTone;
private MediaPlayerStatusCallbacks mMediaPlayerStatusCallBacks;
private Handler mHandler;
private PlayerUpdater mPlayerUpdater;
private SeekBar mSeekBar;
public AudioPlayer(SeekBar seekBar, Context context, MediaPlayerStatusCallbacks mediaPlayerStatusCallbacks) {
mPlayer = new MediaPlayer();
mPlayer.setOnCompletionListener(this);
mMediaPlayerStatusCallBacks = mediaPlayerStatusCallbacks;
mHandler = new Handler();
mContext = context;
mSeekBar = seekBar;
}
private void startSendingProgress() {
mPlayerUpdater = new PlayerUpdater();
((MessagingActivity) mContext).runOnUiThread(mPlayerUpdater);
}
private class PlayerUpdater implements Runnable {
#Override
public void run() {
if(mPlayer != null){
int currentProgress = mPlayer.getCurrentPosition() / 1000;
mSeekBar.setProgress(currentProgress);
}
mHandler.postDelayed(this, DELAY_FOR_HANDLER);
}
}
public static String getMediaDuration(String path) {
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
mmr.setDataSource(path);
String duration = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
mmr.release();
return duration;
}
public void playAudio(String path) throws IOException {
mPlayer.reset();
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mPlayer.setDataSource(path);
mPlayer.prepare();
mSeekBar.setMax(mPlayer.getDuration());
mPlayer.start();
startSendingProgress();
}
public void stopAudio() {
if (mPlayer != null) {
mPlayer.stop();
}
}
public MediaPlayer getMediaPlayer() {
return mPlayer;
}
#Override
public void onCompletion(MediaPlayer mp) {
mMediaPlayerStatusCallBacks.onMediaCompleted();
mHandler.removeCallbacks(mPlayerUpdater);
}
}
And below is the code I am using in View Holder of my recycler view
public class AudioViewHolder extends RecyclerView.ViewHolder {
public View mView;
public QuickContactBadge qcbProfileImage;
public ImageView ivPlay, ivDeliveryStatus;
public SeekBar sbAudioPlayer;
public TextView tvDateTime, tvDuration;
public VoipMessage mItem;
public MyAudioViewsClickListener myAudioViewsClickListener;
public AudioViewHolder(View itemView) {
super(itemView);
mView = itemView;
qcbProfileImage = (QuickContactBadge) itemView.findViewById(R.id.img_view_user);
ivPlay = (ImageView) itemView.findViewById(R.id.iv_play);
sbAudioPlayer = (SeekBar) itemView.findViewById(R.id.sb_audio_player);
ivDeliveryStatus = (ImageView) itemView.findViewById(R.id.img_view_message_status);
tvDateTime = (TextView) itemView.findViewById(R.id.txt_view_duration);
tvDuration = (TextView) itemView.findViewById(R.id.txt_view_time);
myAudioViewsClickListener = new MyAudioViewsClickListener();
ivPlay.setOnClickListener(myAudioViewsClickListener);
}
private class MyAudioViewsClickListener implements View.OnClickListener {
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.iv_play:
try {
playAndPauseAudio(getAdapterPosition());
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}
private void playAndPauseAudio(int adapterPosition) throws IOException {
VoipMessage currentMessage = mMessages.get(adapterPosition);
RecyclerView.ViewHolder holder = mRecyclerView.findViewHolderForLayoutPosition(adapterPosition);
final AudioViewHolder audioViewHolder = (AudioViewHolder) holder;
String audioPath = currentMessage.getMediaReference();
AudioPlayer audioPlayer = new AudioPlayer(audioViewHolder.sbAudioPlayer, mContext, new AudioPlayer.MediaPlayerStatusCallbacks() {
#Override
public void onMediaCompleted() {
ivPlay.setImageResource(R.drawable.ic_audio_play);
}
#Override
public void onUpdatedMediaProgress(int progress) {
//audioViewHolder.sbAudioPlayer.setProgress(progress);
Logger.e("test","progress in adapter " + progress);
//sbAudioPlayer.setProgress(progress);
}
#Override
public void setDuration(int duration) {
//audioViewHolder.sbAudioPlayer.setMax(duration);
//sbAudioPlayer.setMax(duration);
}
});
if (audioPlayer.getMediaPlayer().isPlaying()) {
audioPlayer.stopAudio();
ivPlay.setImageResource(R.drawable.ic_audio_play);
} else {
audioPlayer.playAudio(audioPath);
ivPlay.setImageResource(R.drawable.ic_audio_pause);
}
}
}
I am passing seek bar reference from ViewHolder to the Audio Player class. I am using thread for updating seek bar. Thread is calculating progress and setting that progress to seek bar but the problem is seek bar is not updating on UI. For clear understanding I am attaching image of UI.
enter image description here
My my seek bar is not updating any help. I have spent many hours but could not solve this problem.

Try mSeekBar.setMax(mPlayer.getDuration() / 1000); instead of mSeekBar.setMax(mPlayer.getDuration());, because You set current process in seconds:
int currentProgress = mPlayer.getCurrentPosition() / 1000;
mSeekBar.setProgress(currentProgress);
but max value is in milliseconds and progress is less than 1 px.

Related

Recyclerview scrolling when play audio with mediaplayer

I am developing a chat app, this application has the ability to send voice to chat
The sound is played correctly, but the problem
When I click on the play button, recyclerview scroll to top:
private void playVoice(Message message, final ImageView playBtn, final SeekBar seekBar, final CfTextView timer) {
isCurrentMediaPlayer = !isCurrentMediaPlayer;
if (isCurrentMediaPlayer) {
try {
if (mediaPlayer != null) {
playBtn.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.ic_play, null));
seekBar.setProgress(0);
mediaPlayer.stop();
timerClass.purge();
timerClass.cancel();
}
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(message.getVoice().getUrl());
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
if (mp.isPlaying()) {
mp.pause();
playBtn.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.ic_play, null));
} else {
mp.start();
playBtn.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.ic_pause, null));
}
timer.setText(formatDuration(0));
seekBar.setMax(mediaPlayer.getDuration());
if (mediaPlayer != null) {
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) {
mediaPlayer.seekTo(progress);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
timerClass = new Timer();
timerClass.schedule(new MainTimer(timer, seekBar), 0, 1000);
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
//mediaPlayer = null;
//mp.release();
timerClass.purge();
timerClass.cancel();
playBtn.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.ic_play, null));
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}
private class MainTimer extends TimerTask {
private CfTextView timer;
private SeekBar seekBar;
private MainTimer(CfTextView timer, SeekBar seekBar) {
this.timer = timer;
this.seekBar = seekBar;
}
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
seekBar.setProgress(mediaPlayer.getCurrentPosition());
timer.setText(formatDuration(mediaPlayer.getCurrentPosition()));
}
});
}
}
When you click on any play button, the following code runs:
CustomIncomingVoiceMessageViewHolder.Payload payload = new CustomIncomingVoiceMessageViewHolder.Payload();
payload.onPlayButtonClickListener = new CustomIncomingVoiceMessageViewHolder.onPlayButtonClickListener() {
#Override
public void onPlayButtonClick(Message message, final ImageView imageView, final CfTextView timer, final CfTextView time, final SeekBar seekBar) {
//isCurrentMediaPlayer = !isCurrentMediaPlayer;
playVoice(message, imageView, seekBar, timer);
}
};
my view holder code:
public class CustomIncomingVoiceMessageViewHolder extends MessageHolders.IncomingTextMessageViewHolder<Message> {
private ImageView playButton;
private SeekBar seekBar;
private CfTextView timer;
private CfTextView time;
public CustomIncomingVoiceMessageViewHolder(View itemView, Object payload) {
super(itemView, payload);
playButton = itemView.findViewById(R.id.playButton);
seekBar = itemView.findViewById(R.id.seekBar);
timer = itemView.findViewById(R.id.timerVoice);
time = itemView.findViewById(R.id.timeVoice);
}
#Override
public void onBind(final Message message) {
super.onBind(message);
final Payload payload = (Payload) this.payload;
playButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (payload != null && payload.onPlayButtonClickListener != null) {
payload.onPlayButtonClickListener.onPlayButtonClick(message, playButton, timer, time,seekBar);
}
}
});
}
public static class Payload {
public onPlayButtonClickListener onPlayButtonClickListener;
}
public interface onPlayButtonClickListener {
void onPlayButtonClick(Message message, ImageView imageView, CfTextView timer, CfTextView time,SeekBar seekBar);
}
}
i'm using library chatKit
enter image description here
The problem may be due to your layout where you have your "CfTextView timer." I had the same issue and fixed it by setting my Textview width property as follows:
<TextView
android:layout_width="match_parent" //This is what I changed
android:layout_height="wrap_content"/>
<SeekBar
android:layout_width="match_parent" //Check this as well
android:layout_height="wrap_content"/>
I can see that in your runnable you have this:
seekBar.setProgress(mediaPlayer.getCurrentPosition());
timer.setText(formatDuration(mediaPlayer.getCurrentPosition()));
Here you update the text of your timer to match the mediaPlayer's current position, so if you have the width of your textview to wrap_content it causes your Recyclerview to resize itself.
Try to apply these changes to your layout and see if it solves the scrolling issues.
Best of luck!

Android Music Application

I am new to Android stuff and hope you could help me.
I try to make a little music application.
The application has to do somthing like this:
When the user presses the play button, an audio file, lets call it "mainFile", has to be played in loop.
While the "mainFile" plays and the user presses the fillin button, another audio file, called "fillinFile",
has to be started immediately after the last loop ended.
Therefore I use the "LoopMediaPlayer" from Not able to achieve Gapless audio looping so far on Android
Actually it works fine.
My problem:
If I press the fillin button, the app loops the "mainFile" twice before the "fillinFile" starts playing.
Here is my code:
public class SoundsFragment extends Fragment implements View.OnClickListener {
public static String TAG = "PLAYER";
private XButton fillIn;
private XButton stop;
private XButton play;
private LoopMediaPlayer mediaPlayerMain;
private LoopMediaPlayer mediaPlayerFillIn;
private Taal playingTaal;
View view;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.sounds, container, false);
bindButtons();
return view;
}
#Override
public void onClick(View v) {
//stop();
XButton button = (XButton) v;
switch (button.getId()) {
case R.id.fillin:
playFillIn();
break;
case R.id.play:
playMain();
break;
default:
}
}
private void playMain() {
mediaPlayerMain = LoopMediaPlayer.create(getContext(), R.raw.d_vb_01, R.raw.d_vb_01_var);
}
private void playFillIn() {
mediaPlayerMain.setStartedFollowers(true);
}
private void bindButtons() {
fillIn = (XButton) view.findViewById(R.id.fillin);
stop = (XButton) view.findViewById(R.id.stop);
play = (XButton) view.findViewById(R.id.play);
fillIn.setOnClickListener(this);
stop.setOnClickListener(this);
play.setOnClickListener(this);
}
}
public class LoopMediaPlayer {
public static final String TAG = LoopMediaPlayer.class.getSimpleName();
private Context mContext = null;
private int mFollowersResId= 0;
private int mCounter = 1;
private MediaPlayer mCurrentPlayer = null;
private MediaPlayer mNextPlayer = null;
private boolean mStartedFollowers = false;
private boolean mStartedMain = false;
private int mResId = 0;
public static LoopMediaPlayer create(Context context, int mainResId, int followersResId) {
return new LoopMediaPlayer(context, mainResId, followersResId);
}
private LoopMediaPlayer(Context context, int mainResId, int followersResId) {
mContext = context;
mResId = mainResId;
mFollowersResId = followersResId;
mCurrentPlayer = MediaPlayer.create(mContext, mResId);
mCurrentPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
mCurrentPlayer.start();
}
});
createNextMediaPlayer(mResId);
}
private void createNextMediaPlayer(int id) {
mNextPlayer = MediaPlayer.create(mContext, id);
mCurrentPlayer.setNextMediaPlayer(mNextPlayer);
mCurrentPlayer.setOnCompletionListener(onCompletionListener);
}
private MediaPlayer.OnCompletionListener onCompletionListener = new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
if(mStartedFollowers){
mResId = mFollowersResId;
}
mCurrentPlayer = mNextPlayer;
createNextMediaPlayer(mResId);
mediaPlayer.release();
}
};
public void setStartedFollowers(boolean started){
mStartedFollowers = started;
}
}
try by removing this createNextMediaPlayer(mResId); in private LoopMediaPlayer() constructor

Can't add MediaController to VLC Android SDK

I tried creating an app that allow users watch live stream videos on their android device. From my lil research I found out VLC Sdk is cool because it support more protocols. From the code gotten from Tutorial on using vlc sdk
I was able to make the live watching app works, but the issue is I can't seem to add a control (such as pause, play, seeker etc) to the video. Please I need you help. Thanks
vlc sdk used is 1.9.8
Try this:
public class Show_Array extends AppCompatActivity implements IVLCVout.Callback {
private TextView container_extension;
private String stream_typee,stream_idd,container_extensionn ;
private String SAMPLE_URL = "";
public int mHeight;
public int mWidth;
private SurfaceView mVideoSurface = null;
private FrameLayout sdk;
private IVLCVout vlcVout;
private LibVLC mLibVlc = null;
private MediaPlayer mMediaPlayer = null;
private int flag = 0;
private ImageButton Resize;
private Media media;
private ArrayList<String> args;
private SurfaceHolder mSurfaceHolderVideo;
private MediaController controller;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.show__array);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
//Referances
Resize = findViewById(R.id.Resize);
mVideoSurface = findViewById(R.id.video_surface);
stream_typee = getIntent().getExtras().getString("stream_type");
stream_idd = getIntent().getExtras().getString("stream_id");
container_extensionn = getIntent().getExtras().getString("container_extension");
args = new ArrayList<>();
args.add("-vvv");
mLibVlc = new LibVLC(this, args);
mMediaPlayer = new MediaPlayer(mLibVlc);
vlcVout = mMediaPlayer.getVLCVout();
sdk = findViewById(R.id.sdk);
Resize_video();
setup_url();
controller = new MediaController(this);
controller.setMediaPlayer(playerInterface);
controller.setAnchorView(mVideoSurface);
mVideoSurface.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
controller.show(10000);
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
mMediaPlayer.release();
mLibVlc.release();
}
void Resize_video()
{
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
mHeight = displayMetrics.heightPixels;
mWidth = displayMetrics.widthPixels;
Resize.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
flag+=1;
int width = 1000;
int height = 560;
if(flag%2!=0) {
LinearLayout.LayoutParams myImageLayout = new LinearLayout.LayoutParams(width, height);
myImageLayout.gravity = Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL;
sdk.setLayoutParams(myImageLayout);
vlcVout.setWindowSize(width,height);
}
else
{
LinearLayout.LayoutParams myImageLayout = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
myImageLayout.gravity = Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL;
sdk.setLayoutParams(myImageLayout);
vlcVout.setWindowSize(mWidth,mHeight);
}
}
});
}
void setup_url()
{
//TextView
container_extension = findViewById(R.id.URL);
if (stream_typee.equals("live"))
{
SAMPLE_URL = "http://uautv.ru:2095/"+stream_typee+"/webserver/6tE#BzW73#sX/"+stream_idd+".ts";
container_extension.setText( SAMPLE_URL);
}else
{
SAMPLE_URL = "http://uautv.ru:2095/"+stream_typee+"/webserver/6tE#BzW73#sX/"+stream_idd+"."+container_extensionn;
container_extension.setText( SAMPLE_URL);
}
}
#Override
protected void onStart() {
super.onStart();
vlcVout.setWindowSize(mWidth,mHeight);
vlcVout.setVideoView(mVideoSurface);
vlcVout.attachViews();
mMediaPlayer.getVLCVout().addCallback(this);
if(!SAMPLE_URL.isEmpty()) {
media = new Media(mLibVlc, Uri.parse(SAMPLE_URL));
mMediaPlayer.setMedia(media);
media.release();
mMediaPlayer.play();
}else
{
Toast.makeText(getApplicationContext(),"URL EMPTY",Toast.LENGTH_LONG).show();
}
}
#Override
protected void onStop() {
super.onStop();
mMediaPlayer.stop();
mMediaPlayer.getVLCVout().detachViews();
mMediaPlayer.getVLCVout().removeCallback(this);
}
#TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
#Override
public void onNewLayout(IVLCVout vlcVout, int width, int height, int visibleWidth, int visibleHeight, int sarNum, int sarDen)
{ }
#Override
public void onSurfacesCreated(IVLCVout vlcVout) {
}
#Override
public void onSurfacesDestroyed(IVLCVout vlcVout) {
}
private MediaController.MediaPlayerControl playerInterface = new MediaController.MediaPlayerControl() {
public int getBufferPercentage() {
return 0;
}
public int getCurrentPosition() {
float pos = mMediaPlayer.getPosition();
return (int)(pos * getDuration());
}
public int getDuration() {
return (int)mMediaPlayer.getLength();
}
public boolean isPlaying() {
return mMediaPlayer.isPlaying();
}
public void pause() {
mMediaPlayer.pause();
}
public void seekTo(int pos) {
mMediaPlayer.setPosition((float)pos / getDuration());
}
public void start() {
mMediaPlayer.play();
}
public boolean canPause() {
return true;
}
public boolean canSeekBackward() {
return true;
}
public boolean canSeekForward() {
return true;
}
#Override
public int getAudioSessionId() {
return 0;
}
};
}
I was looking into this as well. You need to implement this yourself.
Simply use FrameLayout and overlay a view ( button? ) per functionality on the video surface.
Then make calls to the VLC MediaPlayer play() stop() pause() etc.
If you really want to dive deep then get the sources of the master, and see how it's done:
git clone https://code.videolan.org/videolan/vlc-android.git

Change the volume of a specif player and get its current volume

I've this class (my media player class) and I need to create 2 methods on it, one to change the volume and other to get the current volume. (I'll create a seekbar to change the player volume), ok.
public class LoopMediaPlayer {
private Context ctx = null;
private int rawId = 0;
private MediaPlayer currentPlayer = null;
private MediaPlayer nextPlayer = null;
public static LoopMediaPlayer create(Context ctx, int rawId) {
return new LoopMediaPlayer(ctx, rawId);
}
private LoopMediaPlayer(Context ctx, int rawId) {
this.ctx = ctx;
this.rawId = rawId;
currentPlayer = MediaPlayer.create(this.ctx, this.rawId);
currentPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
currentPlayer.start();
}
});
createNextMediaPlayer();
}
private void createNextMediaPlayer() {
nextPlayer = MediaPlayer.create(ctx, rawId);
currentPlayer.setNextMediaPlayer(nextPlayer);
currentPlayer.setOnCompletionListener(onCompletionListener);
}
private MediaPlayer.OnCompletionListener onCompletionListener = new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.release();
currentPlayer = nextPlayer;
createNextMediaPlayer();
}
};
public void stopPlayer() {
if (currentPlayer != null && currentPlayer.isPlaying()) {
currentPlayer.stop();
currentPlayer.release();
}
if (nextPlayer != null && nextPlayer.isPlaying()) {
nextPlayer.stop();
nextPlayer.release();
}
}
public void setVolume(float vol) {
//todo
currentPlayer.setVolume(vol, vol);//don't work
}
public int getVolume(){
//todo
return 0;
}
}
and my seekBar progress and listener
seekBar.setProgress(player.getVolume());//use the method that retrieve the current volume
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, final int i, boolean b) {
runOnUiThread(new Runnable() {
#Override
public void run() {
player.setVolume(i);//use the method that change the volume
}
});
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
I tried mp.setVolume() but didn't change any thing. And I can't get the current volume to set like the seekbar progress before show it.
Details - All Audios are in raw file (not stream). There will be more than one player playing at same time, them will be stored so I can retrieve any of them any time, and I want to change and retrieve just the volume of a specific player not of all them at same time.
Anyone know how I should implement both this methods, 'cause I have no idea.
Thanks

Can't pass an int from button if / else case to media player

how are you supposed to let the mediaplayer know what it is supposed to play?
wholeTextPlayer = MediaPlayer.create(Lesson1Reading.this, engAu);
It works fine if I declare the file in the top:
MediaPlayer wholeTextPlayer;
private int engAu = R.raw.l1r_en_l10;
Button btn_default_acc_whole;
It doesn't work from within a button click if / else statement wherever I try to put it with the following combination:
MediaPlayer wholeTextPlayer;
private int engAu;
Button btn_default_acc_whole;
The button click:
final Button btn_default_acc_whole = (Button) findViewById(R.id.btn_default_acc_whole);
btn_default_acc_whole.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
if (wholeTextPlayer.isPlaying()) {
wholeTextPlayer.pause();
} else {
wholeTextPlayer.start();
startPlayProgressUpdater();
}
setEngAu(R.raw.l1r_en_l10); //this line doesn't want to fit anywhere
}
});
The setter:
public void setEngAu(int engAu) {
this.engAu = engAu;
}
Of course they are separately placed in the activity, I just copied and pasted the relevant bits from it.
Thanks guys.
Here is the whole code:
'public class Lesson1Grammar extends Activity {
private SeekBar seekBar;
MediaPlayer wholeTextPlayer;
private int engAu;
private final Handler handler = new Handler();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.lesson1grammar);
WholeDefAccPlayer();
final RelativeLayout playerScreen = (RelativeLayout)findViewById(R.id.playerScreen);
final ImageButton btn_player_screen = (ImageButton) findViewById(R.id.btn_player_screen);
btn_player_screen.setOnClickListener(new View.OnClickListener() {
//this hides/unhides the part of the layout in which the player is
#Override
public void onClick(View arg0) {
if (playerScreen.isShown()) {
playerScreen.setVisibility(View.GONE);
} else {
playerScreen.setVisibility(View.VISIBLE);
}
}
});
final Button btn_default_acc_whole = (Button) findViewById(R.id.btn_default_acc_whole);
btn_default_acc_whole.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
if (wholeTextPlayer.isPlaying()) {
wholeTextPlayer.pause();
} else {
setEngAu(R.raw.default_acc_audio);
wholeTextPlayer.start();
startPlayProgressUpdater();
}
}
});
}
public void setEngAu(int engAu) {
this.engAu = engAu;
}
private void WholeDefAccPlayer() {
wholeTextPlayer = MediaPlayer.create(Lesson1Grammar.this, engAu);
((TextView) findViewById(R.id.getTitleOfAccent)).setText(R.string.btn_lesson1reading);
seekBar = (SeekBar) findViewById(R.id.seekBar);
seekBar.setMax(wholeTextPlayer.getDuration());
seekBar.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
seekChange(v);
return false;
}
});
}
public void startPlayProgressUpdater() {
seekBar.setProgress(wholeTextPlayer.getCurrentPosition());
if (wholeTextPlayer.isPlaying()) {
Runnable notification = new Runnable() {
public void run() {
startPlayProgressUpdater();
}
};
handler.postDelayed(notification, 1000);
}
else wholeTextPlayer.pause();
}
// This is event handler thumb moving event
private void seekChange(View v){
if(wholeTextPlayer.isPlaying()){
SeekBar sb = (SeekBar)v;
wholeTextPlayer.seekTo(sb.getProgress());
}
}
}
'
if your plan is to make the method setEngAu() is the controller as you mentioned in the comment. then you you need to use that method like this
public void setEngAu(int enAu)
{
this.EngAu = enAu;
wholeTextPlayer.setDataSource(engAu);
wholeTextPlayer.prepare();
}
you need to implement onPrepared listener from the media player
I do not know your classes but I assume where you say something like;
wholeTextPlayer = new MediaPlayer();
wholeTextPlayer.setOnPreparedListener(this);
here you start the player after it became prepared
public void onPrepared(MediaPlayer player)
{
player.start();
}
Remember to you will need to call wholeTextPlayer.release() if you do not want the player to hold on that resource anymore( think of it as memory issues - recommended if you check the documentation)
EDIT :
I adjusted your code a little, please take a look and let me know.
private SeekBar seekBar;
MediaPlayer wholeTextPlayer;
private int engAu;
final Handler handler = new Handler();
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.lesson1grammar);
WholeDefAccPlayer();
final RelativeLayout playerScreen = (RelativeLayout) findViewById(R.id.playerScreen);
final ImageButton btn_player_screen = (ImageButton) findViewById(R.id.btn_player_screen);
btn_player_screen.setOnClickListener(new View.OnClickListener()
{
//this hides/unhides the part of the layout in which the player is
#Override
public void onClick(View arg0)
{
if(playerScreen.isShown())
{
playerScreen.setVisibility(View.GONE);
}
else
{
playerScreen.setVisibility(View.VISIBLE);
}
}
});
final Button btn_default_acc_whole = (Button) findViewById(R.id.btn_default_acc_whole);
btn_default_acc_whole.setOnClickListener(new View.OnClickListener()
{
public void onClick(View arg0)
{//problem here is
if(playerState == PlayerState_Playing)
{
wholeTextPlayer.pause();
setPlayerState(PlayerState_Paused);
}
else if(playerState == PlayerState_Paused)
{
wholeTextPlayer.start();
setPlayerState(PlayerState_Playing);
}
else
{
setEngAu(R.raw.default_acc_audio);
wholeTextPlayer.start();
startPlayProgressUpdater();
setPlayerState(PlayerState_Playing);
}
}
});
}
public void setEngAu(int engAu)
{
this.engAu = engAu;
if(wholeTextPlayer !=null)
{//just in case you call this method and player was not initialized yet
wholeTextPlayer.release();
}
setPlayerState(PlayerState_Preparing);
wholeTextPlayer = MediaPlayer.create(this, engAu);
}
private void WholeDefAccPlayer()
{
//this line probably will fail because engAu is not really initialized yet, unless you have default value for it
wholeTextPlayer = MediaPlayer.create(this, engAu);
((TextView) findViewById(R.id.getTitleOfAccent)).setText(R.string.btn_lesson1reading);
seekBar = (SeekBar) findViewById(R.id.seekBar);
//you can not call getDuration unless the player is prepared, so this might crash you
// seekBar.setMax(wholeTextPlayer.getDuration());
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
{
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b)
{
if(playerState != PlayerState_Preparing)
{//if player state is preparing it means we can not seek yet, player.start() must be called first
wholeTextPlayer.seekTo(i);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar)
{
}
#Override
public void onStopTrackingTouch(SeekBar seekBar)
{
}
});
}
public void startPlayProgressUpdater()
{
if(seekBar.getMax() != wholeTextPlayer.getDuration())
{//in case you change track later, this will check if the seek bar max value with track duration.
// if they are not the same, then it will adjust it for you
seekBar.setMax(wholeTextPlayer.getDuration());
}
seekBar.setProgress(wholeTextPlayer.getCurrentPosition());
if(wholeTextPlayer.isPlaying())
{
Runnable notification = new Runnable()
{
public void run()
{
startPlayProgressUpdater();
}
};
handler.postDelayed(notification, 1000);
}
else wholeTextPlayer.pause();
}
// This is event handler thumb moving event
private void seekChange(View v)
{
if(wholeTextPlayer.isPlaying())
{
SeekBar sb = (SeekBar) v;
wholeTextPlayer.seekTo(sb.getProgress());
}
}
private final int PlayerState_Preparing = 0;
private final int PlayerState_Playing = 1;
private final int PlayerState_Paused = 2;
private int playerState;
private void setPlayerState(int state)
{//this is used to track the player state, because wholeTextPlayer.isPlaying() can return false in many conditions ( too general )
//you can check in the media player documentation to know more details about this
playerState = state;
}

Categories

Resources