I am playing a song from the sdcard.
Its plays fine. I tried to implement the seekbar such that when the user moves the seekbar the song gets forwarded or rewnided as per the seek bar position.
Here is the code
public class ViewAudio extends Activity implements OnSeekBarChangeListener,OnSeekCompleteListener,OnCompletionListener,OnPreparedListener{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.audio_player);
System.gc();
Intent i = getIntent();
Bundle extras = i.getExtras();
filename = extras.getString("audiofilename");
try {
mPlayer.setDataSource(filename);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
mPlayer.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mPlayer.setOnCompletionListener(this);
mPlayer.setOnPreparedListener(this);
mPlayer.setOnSeekCompleteListener((OnSeekCompleteListener) this);
mPlayer.start();
TextView tv=(TextView) findViewById(R.id.file);
tv.setText("Playing "+filename);
seekbar = (SeekBar)findViewById(R.id.seekBar1);
mPlay = (Button)findViewById(R.id.play);
mPause = (Button)findViewById(R.id.pause);
seekbar.setProgress(0);
seekbar.setOnSeekBarChangeListener(this);
total = mPlayer.getDuration();
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
Log.d("Progres changed",""+progress);
if(fromUser){
mPlayer.seekTo(progress);
seekbar.setProgress(progress);
}
}
}
Now where ever i click the seekbar the song is getting played from the beginning not from the position i clicked. And it is not moving based on the song.
Any one please help.
i have solved it.
Create a thread that will check the song position every second and move the seekbar based on the song position
mediaPos = mplayer.getCurrentPosition();
mediaMax = mplayer.getDuration();
seekbar.setMax(mediaMax); // Set the Maximum range of the
seekbar.setProgress(mediaPos);// set current progress to song's
handler.removeCallbacks(moveSeekBarThread);
handler.postDelayed(moveSeekBarThread, 100); //cal the thread after 100 milliseconds
}
/**
* The Move seek bar. Thread to move seekbar based on the current position
* of the song
*/
private Runnable moveSeekBarThread = new Runnable() {
public void run() {
if(mplayer.isPlaying()){
int mediaPos_new = mPlayer.getCurrentPosition();
int mediaMax_new = mPlayer.getDuration();
seekbar.setMax(mediaMax_new);
seekbar.setProgress(mediaPos_new);
handler.postDelayed(this, 100); //Looping the thread after 0.1 second
}
}
};
Related
I have listview with layout for playing audio.in that layout i have seekbar and play/pause button when i click on play button media file is played but seekbar not updating I also user Runnable and handler but it not works.
I am doing this in baseadapter inside getview method.
Please help me to sort out this
mAudioViewHolder.play.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String yofile = "file://" + filepath;
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mediaPlayer.setDataSource(yofile);
} catch (IllegalArgumentException | SecurityException | IllegalStateException | IOException e) {
// TODO Auto-generated catch block
Log.e("Node", "ERRORSS Part 1 is" + e);
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mAudioViewHolder.isPlaying = false;
/**
* since audio is stop playing, remove its position value
* */
playingAudioPosition = -1;
}
});
}
try {
mediaPlayer.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("Node", "ERRORSS is Part 2 " + e);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("Node", "ERRORSS is Part 3 " + e);
} // might take long! (for buffering, etc)
mediaPlayer.start();
mAudioViewHolder.progressBar.setMax(mediaPlayer.getDuration());
Runnable mRunnable = new Runnable() {
#Override
public void run() {
if (mediaPlayer != null) {
int mCurrentPosition = mediaPlayer.getCurrentPosition() / 1000;
mAudioViewHolder.progressBar.setProgress(mCurrentPosition);
Log.d("Node", "get current position " + mCurrentPosition);
}
}
};
Log.d("Node", "StartTime Updation " + mediaPlayer.getDuration() + " " + mediaPlayer.getCurrentPosition());
mHandler.postDelayed(mRunnable, 1000);
//mAudioViewHolder.isPlaying = false;
}
You are calling your runnable only once, when you need to call it every time you want to update your progress bar.
You can do this
Runnable mRunnable = new Runnable() {
#Override
public void run() {
if(mediaPlayer != null){
int mCurrentPosition = mediaPlayer.getCurrentPosition() / 1000;
mAudioViewHolder.progressBar.setProgress(mCurrentPosition);
Log.d("Node", "get current position "+mCurrentPosition);
mHandler.postDelayed(this, 1000);
}
}
};
Log.d("Node", "StartTime Updation "+mediaPlayer.getDuration()+" "+mediaPlayer.getCurrentPosition());
mHandler.postDelayed(mRunnable, 1000);
Make sure you remove the runnable from the handler when you stop the playback.
mHandler.removeCallbacks(mRunnable);
I am playing music form my sd card and i want my seekbar to getprogress every 2 sec when music is playing. I am trying to do it with Handler. But i dont know how to use Handler coretly
Here is my code:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
seekBar1 = (SeekBar) findViewById(R.id.seekBar1);
button1 = (Button) findViewById(R.id.button1);
button2 = (Button) findViewById(R.id.button2);
textView1 = (TextView) findViewById(R.id.textView1);
button1.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
MediaPlayer mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(Environment.getExternalStorageDirectory()+"/MyImages/.audio2.wav");
mediaPlayer.prepare();
mediaPlayer.start();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
setupHandler();
}
});
}
private void setupHandler()
{
handler.removeCallbacks(moveSeekBarThread);
handler.postDelayed(moveSeekBarThread, 2000); //cal the thread after millisec
}
private Runnable moveSeekBarThread = new Runnable() {
public void run() {
if(mediaPlayer.isPlaying()){
int mediaPos = mediaPlayer.getCurrentPosition();
int mediaMax = mediaPlayer.getDuration();
seekBar1.setMax(mediaMax);
seekBar1.setProgress(mediaPos);
handler.postDelayed(this, 2000); //Looping the thread after second
// seconds
}
}
};
}
My app crashing 2 second after i clikc the button1. So i am sure the problem here is Handler. Do i call this handler wrong or something?
Post your logcat always when you ask about app crashes.
Therefor in this case you have NullPointerException here, i think:
if(mediaPlayer.isPlaying())
You doesn't initialize your mediaplayer variable.
EDITED:
MediaPlayer mediaPlayer;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
seekBar1 = (SeekBar) findViewById(R.id.seekBar1);
button1 = (Button) findViewById(R.id.button1);
button2 = (Button) findViewById(R.id.button2);
textView1 = (TextView) findViewById(R.id.textView1);
button1.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(Environment.getExternalStorageDirectory()+"/MyImages/.audio2.wav");
mediaPlayer.prepare();
mediaPlayer.start();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
setupHandler();
}
});
}
private void setupHandler()
{
handler.removeCallbacks(moveSeekBarThread);
handler.postDelayed(moveSeekBarThread, 2000); //cal the thread after millisec
}
private Runnable moveSeekBarThread = new Runnable() {
public void run() {
if(mediaPlayer.isPlaying()){
int mediaPos = mediaPlayer.getCurrentPosition();
int mediaMax = mediaPlayer.getDuration();
seekBar1.setMax(mediaMax);
seekBar1.setProgress(mediaPos);
handler.postDelayed(this, 2000); //Looping the thread after second
// seconds
}
}
};
Use The below code to Update the SeekBar after 2Seconds.
Create the Object for Handler inside your onCreate() like the following one.
Handler miHandler=new Handler();
add Paste the code inside your thread.
miHandler.postDelayed(new Runnable() {
#Override
public void run() {
try{
seekBar1.setProgress(mediaPos+ add 2sec delay time also);
}catch(Exception e) {e.printStrackTrace();}
}
}, 1500);
i have a seekbar that should move while streaming from url but it's not automatically moving, but when you press on the seekbar it takes you where you should be. and my class doesnt fire run() function!
public void run() {
// TODO Auto-generated method stub
int currentPosition = 0;
int total = mediaPlayer.getDuration();
seekprogress.setMax(total);
while (mediaPlayer != null && currentPosition <total) {
try {
Thread.sleep(100);
currentPosition = mediaPlayer.getCurrentPosition();
} catch (InterruptedException e) {
return;
} catch (Exception e) {
return;
}
seekprogress.setProgress(currentPosition);
}
}
You can update UI elements only from the UI thread. Use runOnUiThread
In my application I am trying to implement SeekBar.. The SeekBar is working fine when playing the sound at first time. but When I click the button to play the sound again then I am an endless loop of errors regarding the MediaPlayer. The thing that I want is that when I while playing the sound if I click the the play button the sound should play again from the beginning and the SeekBar should also start from beginning. If I remove the the SeekBar then everything is working fine.. But SeekBar is must in my application.. I have implemented all these things in the BaseAdapter.. I have to do all the things in the BaseAdapter. So please help me in letting me the code that works with the BaseAdapter..
This is my code... Please have a look...
mediaPlayer.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(activity, "Loading Message", Toast.LENGTH_LONG).show();
mp.reset();
try {
mp.setDataSource("url for any mp3 audio file");
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mp.prepareAsync();
mp.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(final MediaPlayer mp) {
// TODO Auto-generated method stub
mp.start();
mediaPlayer.setBackgroundResource(R.drawable.m_pause);
seekBar.setProgress(0);
seekBar.setMax(100);
mUpdateTimeTask = new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long totalDuration = mp.getDuration();
long currentDuration = mp.getCurrentPosition();
int progress = (int)(utils.getProgressPercentage(currentDuration, totalDuration));
seekBar.setProgress(progress);
mHandler.post(this);
}
});
mUpdateTimeTask.start();
}
});
}
});
mp.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
mediaPlayer.setBackgroundResource(R.drawable.m_play);
mp.stop();
try {
mUpdateTimeTask.join();
mHandler.sendEmptyMessage(0);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mHandler.removeCallbacks(mUpdateTimeTask);
}
});
seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
public void onStopTrackingTouch(final SeekBar seekBar) {
// TODO Auto-generated method stub
//mHandler.removeCallbacks(mUpdateTimeTask);
if(mp.isPlaying())
{
int totalDuration = mp.getDuration();
int currentPosition = utils.progressToTimer(seekBar.getProgress(), totalDuration);
mp.seekTo(currentPosition);
mUpdateTimeTask = new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long totalDuration = mp.getDuration();
long currentDuration = mp.getCurrentPosition();
int progress = (int)(utils.getProgressPercentage(currentDuration, totalDuration));
//timer.setText(""+utils.milliSecondsToTimer(currentDuration));
seekBar.setProgress(progress);
mHandler.post(this);
}
});
mUpdateTimeTask.start();
}
else
{
seekBar.setProgress(0);
}
}
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
if(mp.isPlaying())
{
mHandler.removeCallbacks(mUpdateTimeTask);
}
else
{
seekBar.setProgress(0);
}
}
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
}
});
mp.setOnErrorListener(new OnErrorListener() {
public boolean onError(MediaPlayer mp, int what, int extra) {
// TODO Auto-generated method stub
return false;
}
});
Thanks...
Create a method in your BaseAdapter which sets the current seekbarprogress to zero
void setSeekBarValuetoZero(){
seekBar.setProgress(0);
}
Please check the initially that seekbar is initialized.
You can call this function from yourMediaPlayer class before mp.reset();
I have recorded audio, and play it through the mediaplayer. Recording, playing works fine. I used a seekbar, while playing the recorded voice. I used the following coding to play the content stored in sdcard. It works fine.. mFileName is the audio file in sdcard.
The seek bar doesnt move, while playing. Any suggestions...
private void startPlaying()
{
MediaPlayer mPlayer = new MediaPlayer();
try {
mPlayer.setDataSource(mFileName);
mPlayer.prepare();
mPlayer.start();
mSeekBar.setMax(mPlayer.getDuration());
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
}
And I used
mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
// TODO Auto-generated method stub
if(fromUser){
mPlayer.seekTo(progress);
mSeekBar.setProgress(progress);
}
}
});
Thread currentThread = new Thread((Runnable) this);
currentThread.start();
public void run() {
// TODO Auto-generated method stub
try {
while(mPlayer != null){
int currentPosition = mPlayer.getCurrentPosition();
Message msg = new Message();
msg.what = currentPosition;
threadHandler.sendMessage(msg);
}
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private Handler threadHandler = new Handler(){
public void handleMessage(Message msg){
mSeekBar.setProgress(msg.what);
}
};
The progressbar moves only when the user moves. It doent move atomatically.
The seekbar isn't going to magically update itself to show the MediaPlayer's current position. Here's a link that shows how to do this with a polling thread that checks the MediaPlayer's position every second or so and updates the seekbar accordingly:
http://united-coders.com/nico-heid/an-android-seekbar-for-your-mediaplayer