in my music player how I can let my seek bar back to the starting point after I clicked stop button? and set the text field of total duration and current position to zero ?? the problem happen when I click stop and then click play button ?in my log cat the error is "Attempt to call getDuration without a valid mediaplayer"
#Override
protected void onCreate(Bundle savedInstanceState) {
setVolumeControlStream(AudioManager.STREAM_MUSIC);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageButton play_btn= (ImageButton) findViewById(R.id.iv_play);
ImageButton backward_btn=(ImageButton)findViewById(R.id.imageView_backward);
ImageButton forward_btn= (ImageButton) findViewById(R.id.imageView_forward);
ImageButton stop_btn= (ImageButton) findViewById(R.id.imageView_stop);
ImageButton pause_btn= (ImageButton)findViewById(R.id.imageView_pause);
ImageButton shuffle_btn = (ImageButton) findViewById(R.id.imageView_shuffle);
song = MediaPlayer.create(getApplicationContext() ,R.raw.adele);
songProgressBar= (SeekBar) findViewById(R.id.seekBar1);
songProgressBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
mHandler.removeCallbacks(mUpdateTimeTask);
int totalDuration = song.getDuration();
int currentPosition = utils.progressToTimer(seekBar.getProgress(), totalDuration);
song.seekTo(currentPosition);
UpdateProgressBar();
}
#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
}
});
pause_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
PauseSong(); }
private void PauseSong() {
// TODO Auto-generated method stub
song.pause();
}
});
stop_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
StopSong();
}
private void StopSong() {
// TODO Auto-generated method stub
song.stop();
}
});
play_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
PlaySong();
}
private void PlaySong() {
// TODO Auto-generated method stub
song.start();
songProgressBar.setProgress(0);
songProgressBar.setMax(100);
UpdateProgressBar();
}
});
}
private void UpdateProgressBar() {
// TODO Auto-generated method stub
mHandler.postDelayed(mUpdateTimeTask, 100);
}
Runnable mUpdateTimeTask = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
totalDuration = song.getDuration();
currentDuration = song.getCurrentPosition();
// Displaying Total Duration time
songTotalDurationLabel = (TextView)findViewById(R.id.songTotalDurationLabel);
songTotalDurationLabel.setText(""+utils.milliSecondsToTimer(totalDuration));
// Displaying time completed playing
songCurrentDurationLabel = (TextView)findViewById(R.id.songCurrentDurationLabel);
songCurrentDurationLabel.setText(""+utils.milliSecondsToTimer(currentDuration));
// Updating progress bar
int progress = (int)(utils.getProgressPercentage(currentDuration, totalDuration));
Log.d("Progress", ""+progress);
songProgressBar.setProgress(progress);
// Running this thread after 100 milliseconds
mHandler.postDelayed(this, 100);
}
};
protected void onPause() {finish();}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
finish();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
Retrieve the duration from the onPrepared callback...this will ensure the music(audio) is properly loaded before you attempt to get it's duration.
song.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer song) {
int duration = song.getDuration();
song.start();
controller.show();
}
});
StopSong():
private void StopSong() {
if (song != null) {
song.stop();
song.release();
}
}
for the duration text field, i will used global variable to access from all functions.
#Override
protected void onCreate(Bundle savedInstanceState) {
int totalDuration 0;
.
.
.
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
mHandler.removeCallbacks(mUpdateTimeTask);
totalDuration = song.getDuration(); // here
.
.
.
private void StopSong() {
if (song!=null) {
song.stop();
song.release();
totalDuration = 0; // here
}
i hope this helps!
Related
say for example I have a progress bar and in onCreate activity I am setting up onProgressChanged listener.
sbt.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
int progressChanged = 0;
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// Toast.makeText(ProductDetailsInfoActivity.this,"seek bar progress:"+progressChanged,
// Toast.LENGTH_SHORT).show();
// 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) {
//recalcpriceornot=false;
// TODO Auto-generated method stub
//Toast.makeText(ProductDetailsInfoActivity.this, String.valueOf(progress), Toast.LENGTH_SHORT).show();
try {
//if (recalcpriceornot)
{ GetItemPriceCalculation(progress);
recalctotalprice();}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
progressChanged = progress;
if(progress <= 100){
setProgressBarColor(sbt,Color.GREEN);
}else{
setProgressBarColor(sbt,Color.RED);
}
}
});
My other controls (price box) adjust progress and progress bar adjusts price box therefor it will be going in a loop.
i can turn off listener by
sbt.setOnSeekBarChangeListener(null);
but to turn it back on do I have to re-write the whole part for listener. is There a better way of doing it??
thanks a lot
Instead of inline creating the SeekBar.OnSeekBarChangeListener, create a member variable of type SeekBar.OnSeekBarChangeListener. When you want it to turn it on, you can pass the variable to it. When you want to turn it off, you can pass it the null.
private SeekBar sbt; //Not sure where this gets initialized in your code.
private SeekBar.OnSeekBarChangeListener mListener = new SeekBar.OnSeekBarChangeListener() {
int progressChanged = 0;
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// Toast.makeText(ProductDetailsInfoActivity.this,"seek bar progress:"+progressChanged,
// Toast.LENGTH_SHORT).show();
// 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) {
//recalcpriceornot=false;
// TODO Auto-generated method stub
//Toast.makeText(ProductDetailsInfoActivity.this, String.valueOf(progress), Toast.LENGTH_SHORT).show();
try {
//if (recalcpriceornot)
{ GetItemPriceCalculation(progress);
recalctotalprice();}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
progressChanged = progress;
if(progress <= 100){
setProgressBarColor(sbt,Color.GREEN);
}else{
setProgressBarColor(sbt,Color.RED);
}
}
});
void enableListener()
{
sbt.setOnSeekBarChangeListener(mListener);
}
void disableListener()
{
sbt.setOnSeekBarChangeListener(null);
}
You can also let this object implement/extends the OnSeekBarChangeListener and not keep a variable to the listener. In which case the enable will pass in "this".
Your activity can implement SeekBar.OnSeekBarChangeListener and use this to reference the listener when you want to turn on the SeekBar:
import android.app.Activity;
import android.database.SQLException;
import android.graphics.Color;
import android.os.Bundle;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
public class MainActivity extends Activity implements OnSeekBarChangeListener {
private int progressChanged = 0;
private SeekBar sbt;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sbt = (SeekBar) findViewById(R.id.seekBar1);
// Turns OFF
sbt.setOnSeekBarChangeListener(null);
// Turns ON
sbt.setOnSeekBarChangeListener(this);
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// Toast.makeText(ProductDetailsInfoActivity.this,"seek bar progress:"+progressChanged,
// Toast.LENGTH_SHORT).show();
// 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) {
// recalcpriceornot=false;
// TODO Auto-generated method stub
// Toast.makeText(ProductDetailsInfoActivity.this,
// String.valueOf(progress), Toast.LENGTH_SHORT).show();
try {
// if (recalcpriceornot)
{
GetItemPriceCalculation(progress);
recalctotalprice();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
progressChanged = progress;
if (progress <= 100) {
setProgressBarColor(sbt, Color.GREEN);
} else {
setProgressBarColor(sbt, Color.RED);
}
}
}
Yes. You can store the listener in an instance variable and then reuse it in multiple places in your code.
For example, create an instance variable in your class like this:
private SeekBar.OnSeekBarChangeListener mSeekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {
int progressChanged = 0;
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// Toast.makeText(ProductDetailsInfoActivity.this,"seek bar progress:"+progressChanged,
// Toast.LENGTH_SHORT).show();
// TODO Auto-generated method stub
}
// other methods, etc
});
Then you can set the listener whenever you feel like it:
// remove listener
sbt.setOnSeekBarChangeListener(null);
// reattach it later
sbt.setOnSeekBarChangeListener(mSeekBarChangeListener);
Instead of implementing the listener inline you can implement it separately.
private SeekBar.OnSeekBarChangeListener mySeekBarListener = new SeekBar.OnSeekBarChangeListener() {
};
Now every time you need to set a listener, go with:
sbt.setOnSeekBarChangeListener(mySeekBarListener);
Edit:
You can also separate the listener implementation out into another class. Then you can create an object of that class and use it in your set method. Another way to do the same thing if you'd like
When my mediaplayer starts playing, I want to get the time elapsed from the beginning of the player till the end of the media being played. For example 00:01, 00:02, 00:03, 00:04... How can i achieve this? Below is my mediaplayer class.
public class EntityPageActivity extends Activity implements Runnable, OnClickListener, OnSeekBarChangeListener{
private SeekBar seekBar;
private Button startMedia;
private Button pauseMedia;
private MediaPlayer mp;
Uri url;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sample);
AudioControl();
}
public void AudioControl(){
seekBar = (SeekBar) findViewById(R.id.seekBar);
startMedia = (Button) findViewById(R.id.play);
pauseMedia = (Button) findViewById(R.id.pause);
startMedia.setOnClickListener(this);
pauseMedia.setOnClickListener(this);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
//System.out.println("maxvolume"+Integer.toString(maxVolume));
}
#Override
public void onStartTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
}
#Override
public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
// TODO Auto-generated method stub
mp.seekTo(arg1);
seekBar.setProgress(arg1);
}
});
}
public void run() {
int currentPosition= 0;
int total = mp.getDuration();
while (mp!=null && currentPosition<total) {
try {
Thread.sleep(1000);
currentPosition= mp.getCurrentPosition();
} catch (InterruptedException e) {
return;
} catch (Exception e) {
return;
}
seekBar.setProgress(currentPosition);
}
}
public void onClick(View v) {
if (v.equals(startMedia)) {
if (mp != null && mp.isPlaying()) return;
if(seekBar.getProgress() > 0) {
mp.start();
return;
}
mp = MediaPlayer.create(EntityPageActivity.this,Uri.parse("http://cdn-preview-e.deezer.com/stream/ed403858b3532e9c07c99d7015269848-2.mp3"));
mp.start();
seekBar.setProgress(0);
seekBar.setMax(mp.getDuration());
new Thread(this).start();
}
if (v.equals(pauseMedia) && mp!=null) {
mp.pause();
}
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
}
Here are these two methods one is to get Media Player Current Position and second is to get total duration
// returns current position
mediaPlayer.getCurrentPosition();
//returns total duration
mediaPlayer.getDuration();
hope this will help
Implement a runnable when you start your mediaplayer:
mp.start();
Handler handler = new Handler();
Runnable runnable = new Runnable() {
public void run() {
while (mp.isPlaying()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.post(new Runnable() {
public void run() {
seekbar.setMax(mp.getDuration() / 1000);
currTime.setText(getDurationString(mp
.getCurrentPosition() / 1000));
seekbar.setProgress(mp
.getCurrentPosition() / 1000);
}
});
}
}
};
new Thread(runnable).start();
How to use the seekbar in android mediplayer? I used the below code. seekbar working at a firstsong only then turn away from my application.
mp = MediaPlayer.create(player.this, (Integer) plsong.get(i));
mp.start();
mp.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer player) {
mp.release();
sname.setText(" ");
if (j < (plsong.size() - 1)) {
j++;
mp = MediaPlayer.create(player.this,(Integer) plsong.get(j));
sname.setText((CharSequence) soname.get(j));
mp.start();
mp.setOnCompletionListener(this);
}
}
});
mp.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer mpss) {
// TODO Auto-generated method stub
total = mp.getDuration();
System.out.println("total" + total);
}
});
seekbar.setProgress(0);
seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
public void onStopTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
}
public void onStartTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
}
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
if (fromUser) {
mp.seekTo(progress);
seekBar.setProgress(progress);
}
}
});
Thread currentThread = new Thread(MyCounter.this);
currentThread.start();
mplay = (Button) findViewById(R.id.mplay);
if(!mp.isPlaying())
{
mplay.setText("Pause");
mplay.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
mp.start();
seekbar.setMax(total);
}
});
}
else
{
mplay.setText("play");
mplay.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
mp.pause();
}
});
}
}
public void run() {
// TODO Auto-generated method stub
try {
while (mp != null) {
int currentPosition = mp.getCurrentPosition();
Message msg = new Message();
msg.what = currentPosition;
threadHandler.sendMessage(msg);
}
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private Handler threadHandler = new Handler() {
public void handleMessage(Message msg) {
seekbar.setProgress(msg.what);
}
};
Remove all the threads you created to move the seekbar and add these:
mp.setOnBufferingUpdateListener(new OnBufferingUpdateListener(){
public void onBufferingUpdate(MediaPlayer mp, int percent) {
SeekBar seekBar = (SeekBar)findViewById(R.id.seekBar);
if (mp.isPlaying() && seekBar!=null) {
seekBar.setProgress(mp.getCurrentPosition());
}
}
});
I recently changed my application to have the action bar tabs to switch between Fragments. I coding I have done for the first fragment which is on the main activity is working fine, but on the second Tab it displays the items in its corresponding XML file but, none of my Java code seems to be working. I want 3 seek bars to change the number of a Text View, I had it working when I wasn't using Fragments, but just cant get it to work.
Do i have to put the code in a certain place of this file?
public class CountdownFragmentTab extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.countdown, container, false);
}
}
And this is what i want to add to this file:
SeekBar seekBar1 = (SeekBar)findViewById(R.id.seekBar1);
SeekBar seekBar2 = (SeekBar)findViewById(R.id.seekBar2);
SeekBar seekBar3 = (SeekBar)findViewById(R.id.seekBar3);
final TextView seekBar1Value = (TextView)findViewById(R.id.seekbar1value);
final TextView seekBar2Value = (TextView)findViewById(R.id.seekbar2value);
final TextView seekBar3Value = (TextView)findViewById(R.id.seekbar3value);
seekBar1.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
public void onProgressChanged(SeekBar seekBar1, int progress, boolean fromUser) {
// TODO Auto-generated method stub
seekBar1Value.setText(String.valueOf(progress));
}
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
});
seekBar2.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
public void onProgressChanged(SeekBar seekBar2, int progress, boolean fromUser) {
// TODO Auto-generated method stub
seekBar2Value.setText(String.valueOf(progress));
}
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
});
seekBar3.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
public void onProgressChanged(SeekBar seekBar3, int progress, boolean fromUser) {
// TODO Auto-generated method stub
seekBar3Value.setText(String.valueOf(progress));
}
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
});
}
i have build a custom media player and i want to show the seekbar also.
The seekbar is showing for now but is not functional i.e. it is not progressing when the song is played. Let me know where am i wrong . Following is the code
public class myPlayer extends Activity implements Runnable,SeekBar.OnSeekBarChangeListener {
MediaPlayer mPlayer;
Button play,stop;
SeekBar seekbar;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
seekbar = (SeekBar)findViewById(R.id.seekbar);
mPlayer = MediaPlayer.create(this,R.raw.sajnave);
play=(Button)findViewById(R.id.play);
stop=(Button)findViewById(R.id.stop);
Toast.makeText(myPlayer.this, ""+mPlayer.getDuration(), Toast.LENGTH_SHORT).show();
play.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
mPlayer.start();
}
});
stop.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(myPlayer.this, ""+mPlayer.getCurrentPosition(), Toast.LENGTH_SHORT).show();
mPlayer.stop();
}
});
}
#Override
public void run() {
// TODO Auto-generated method stub
int currentPosition = 0;
int total = mPlayer.getDuration();
seekbar.setMax(total);
while (mPlayer != null && currentPosition < total) {
try {
Thread.sleep(1000);
currentPosition = mPlayer.getCurrentPosition();
} catch (InterruptedException e) {
return;
} catch (Exception e) {
return;
}
seekbar.setProgress(currentPosition);
}
}
#Override
public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
// TODO Auto-generated method stub
mPlayer.seekTo(arg1);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
}
Call updatePosition() method after mediplayer starts..It works for me.
private final Handler handler = new Handler();
private final Runnable updatePositionRunnable = new Runnable() {
public void run() {
updatePosition();
}
};
private void updatePosition() {
handler.removeCallbacks(updatePositionRunnable);
if (player != null) seekbar.setProgress(player.getCurrentPosition());
handler.postDelaye(updatePositionRunnable, 500);
}
#Override
public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
// TODO Auto-generated method stub
player.seekTo(arg1);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
SurfaceView mPreview=(SurfaceView)findViewById(R.id.surface);
mPreview.postDelayed(runnable,200);
Runnable runnable = new Runnable() {
#Override
public void run() {
if (mMediaPlayer != null) {
if (isPlaying) {
// converting current position into seconds so dividing by
// 1000
try {
currentPosition = mMediaPlayer.getCurrentPosition();
mVideoProgress
.setProgress((int) ((currentPosition / (float) mMediaPlayer
.getDuration()) * 100f));
} catch (Exception e) {
e.printStackTrace();
}
mPreview.postDelayed(runnable, 150);
}
}
}
};