android - how to delay an audio file by a few seconds - android

I'm trying to figure out how to delay an audio file by about 15 seconds. The audio file is 5 seconds long and it's a sound effect saying "5,4,3,2,1 go!", the countdown is from 20 so it should start after 15 seconds. I heard I can do this with a handler but I don't know how to implement it in the code, so here it is, help would be much appreciated!
I edited it with the way below, however now the player doesn't start at all, here's the new code:
public class WorkoutGymEasy1 extends Activity {
CountDownTimer cdt = null;
MediaPlayer mp;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.workout_gym_easy1);
RelativeLayout rl5 = (RelativeLayout) findViewById(R.id.rl5);
rl5.setBackgroundColor(Color.BLACK);
mp = MediaPlayer.create(WorkoutGymEasy1.this, R.raw.countdown);
try {
mp.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new CountDownTimer(20000, 1000) { //20 seconds count down with 1s interval (1000 ms)
TextView c = (TextView) findViewById(R.id.timer_gym_easy1); //access TextView element on the screen to set the timer value
public void onTick(long millisUntilFinished) { // Code in this method is executed every 1000ms (1s)
c.setText("" + ((millisUntilFinished / 1000) - 1) + ""); //update the timer
if(millisUntilFinished == 9000) {
mp.start();
}
}
#Override
public void onFinish() {
// TODO Auto-generated method stub
c.setText("GO!");
Intent myIntent = new Intent(getApplicationContext(), WorkoutGymEasy2.class);
startActivity(myIntent);
finish(); // call finish() method to destroy this activity and return to instructions screen
}
}.start();
}
protected void OnPause() {
super.onPause();
mp.release();
finish();
}
}

Don't start playing the audio in onCreate(). Remove mp.start() from onCreate().
mp = MediaPlayer.create(WorkoutGymEasy1.this, R.raw.countdown);
try {
mp.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Play the audio in onTick(). The CountDownTimer is not precise, it will return as close to 1 second as it can. It will never be 20000, 19000... etc. As an optimization you can round the millisUntilFinished on each onTick() and do a simple check to see if you should play the audio or not.
public void onTick(long millisUntilFinished) { // Code in this method is executed every 1000ms (1s)
c.setText("" + ((millisUntilFinished / 1000) - 1) + ""); //update the timer
if(Math.round((float)millisUntilFinished / 1000.0f) == 5) {
mp.start();
}
}

Related

How do I call mediaplayer once only?

In android, I have a mediaplayer on detail screen, which duplicates when I select another screen then play another detail, causing sound files to play on the same time. how do I fix this problem? Id like to play the most recent selected media only.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_feeddetail);
tc_recDurat = (TextView)findViewById(R.id.recDetDurat);
tc_recDuratBack = (TextView)findViewById(R.id.recDetDuratBack);
TextView tc_recPath = (TextView)findViewById(R.id.recDetPath);
recPath = (String) intent.getSerializableExtra("INTENT_PATH");
tc_recPath.setText(recPath);
mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(recPath);
} catch (IOException e1) {
// TODO Auto-generated catch block
Toast.makeText(getApplicationContext(), e1.getLocalizedMessage(), Toast.LENGTH_LONG);
}
ImageButton mClickButton1 = (ImageButton)findViewById(R.id.btnPlay);
mClickButton1.setOnClickListener( new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (mediaPlayer !=null){
try {
mediaPlayer
mediaPlayer.prepare();
seekBar.setMax(mediaPlayer.getDuration());
mediaPlayer.start();
seekUpdate();
isPlaying = true;
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
ImageButton mClickButton2 = (ImageButton)findViewById(R.id.btnStop);
mClickButton2.setOnClickListener( new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
mediaPlayer.stop();
isPlaying = false;
}
});
I am not sure what your problem is, but i believe you are trying to say that as you change through different activities, the sounds files do not stop playing
In that case you can do the following
In the activity
You can override the onPause method and put mediaPlayer.stop() inside it
#Override
public void onPause() {
super.onPause();
mediaPlayer.stop();
}

seekbar not updating when playing media file

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);

Android handling state of ProgressBar onPause/onResume

Hi have a progressBar that i run. but when the user exits the app via the home button and then re-enters it by holding down the home button and selected the app. The progressBar setProgress flickers between an old value and a new one almost as if its remembering the previous state. I have created a function in my on pause/onResume methods to pause the timer save the values and on resume get those values and start the timer and progress bar again. The confusing thing is it works the onPause stuff works perfectly if the onPause function is run and the user stays in the app for example presses the back button. Does anyone know where im going wrong or how to correctly implement a progressBar using a CountDownTimer?
heres my code
#Override
protected void onResume() {
// TODO Auto-generated method stub
Log.v("Game","ONRESUME");
loadData();
layoutChecks();
loadViews();
try {
if(!myData.get("completed").equals("3")){
hintCheck();
getHints();
startTimer();
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
super.onResume();
}
#Override
protected void onPause() {
Log.v("Game","ONPAUSE");
try {
if(!myData.get("completed").equals("3")){
pauseTimer();
updateData();
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
super.onPause();
}
public void loadViews(){
progressBar = new ProgressBar(this);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
progressD = progressBar.getProgressDrawable();
}
public void prepareProgressBar(){
progressD.setLevel(0);
progressBar.setProgress(0);
progressD.setLevel(points*100);
progressBar.setProgress(points);
}
public void startTimer(){
try {
points = Integer.valueOf(myData.getJSONObject("Data").getString("points"));
int timer = points;
hasTimerCancelled = false;
prepareProgressBar();
counter = new MyCount(timer/2 * 1000,1000);
counter.start();
} catch (NumberFormatException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
public void pauseTimer(){
try {
counter.cancel();
hasTimerCancelled = true;
JSONObject Data = myData.getJSONObject("Data");
Data.put("points", String.valueOf(points));
myData.put("Data", Data);
updateData();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public class MyCount extends CountDownTimer{
public long totaltime;
public MyCount(long totalTime, long countDownInterval) {
super(totalTime, countDownInterval);
totaltime = totalTime;
}
#Override
public void onFinish() {
counter.cancel();
points = 0;
progressBar.setProgress(0);
}
#Override
public void onTick(long millisUntilFinished) {
if(!hasTimerCancelled){
if(points > 0){
points = points - 1;
}
progressBar.setProgress((int) totaltime);
}
}
}

Android SeekBar don't go when audio playing

I've a problem with seek bar, when i play the audio with mediaplayer the seekbar don't start with it.
i don't understand why the seekbar don't "refresh" progress.
thank you for help.
below i post the code, i don't understand when i wrong.
MediaPlayer player=new MediaPlayer();
SeekBar seekBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
AssetFileDescriptor afd = this.getResources().openRawResourceFd(R.raw.mymp3);
player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
afd.close();
player.prepare();
} 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();
}
Button pausa=(Button)findViewById(R.id.button2);
pausa.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
player.pause();
}
});
Button vai=(Button)findViewById(R.id.button3);
vai.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
player.start();
}
});
int tutto=player.getDuration();
seekBar = (SeekBar)findViewById(R.id.seekBar1);
seekBar.setMax(tutto);
seekBar.setProgress(player.getCurrentPosition() / 1000);
}
An easy way you can do it is to create a Timer object that fires every second.
Inside the code of the timer you call
seekBar.setProgress(player.getCurrentPosition() / 1000);
Additionally, you may want to implement setOnCompletionListener to get notified when the playback has reached it's end so you can stop the timer. The timer should be stopped either if the playback reached it's end, the applications finishes, or you stop the music manually (in response to a stop button, for example)
Because you set the progress in onCreate() and that gets called only once - you guessed it, when the Activity is created. I'm not very familiar with the MediaPlayer so I don't know if there is some kind of update listener, but you need some kind of timer that updates the progress every second or so.

synchronizing seekbar with the audio song

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
}
}
};

Categories

Resources