I am developing a new Android application, In my application, i have audio record functionality of 3 sec. I want to show a round progress bar to show the progress of recording. The recording automatically stop after 3 sec. This is my code, Please help me to add the progress bar.
private void mStartRecordingAudio() {
try {
TemporaryModelCache.stopMediaPlayer();
TemporaryModelCache.getAsyncInstance().cancel(true);
TemporaryModelCache.clearAsyncInstance();
mAudioRecorder = new MediaRecorder();
mAudioRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
mAudioRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mAudioRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
String file_name = mFileToSaveAudio + "recording.3gp";
mAudioRecorder.setOutputFile(file_name);
mAudioRecorder.prepare();
mAudioRecorder.start();
mImageViewRecord.setImageResource(R.drawable.ic_button_recording);
circularProgressBar.setVisibility(View.VISIBLE);
mImagePlayOurs.setImageResource(R.drawable.ic_button_play_ours_disabled);
mButtonPlayRecordedAudio.setImageResource(R.drawable.button_yours_disabled);
mViewRecord.setEnabled(false);
mViewPlayYours.setEnabled(false);
mViewPlayOurs.setEnabled(false);
} catch (IllegalStateException ise) {
Log.e("error", ise.toString());
// make something ...
} catch (IOException ioe) {
Log.e("error", ioe.toString());
// make something
}
new Timer().schedule(new TimerTask() {
#Override
public void run() {
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
try {
mAudioRecorder.stop();
mAudioRecorder.reset();
mAudioRecorder.release();
} catch (RuntimeException stopException) {
//handle cleanup here
}
circularProgressBar.setVisibility(View.GONE);
mWowWordActionSounds.mPlayAudioButtonClick();
mIsAudioRecorded = true;
mButtonPlayRecordedAudio.setImageResource(R.drawable.ic_button_yours_png);
mImagePlayOurs.setImageResource(R.drawable.ic_btn_playours);
mImageViewRecord.setImageResource(R.drawable.ic_btn_record);
mViewPlayYours.setEnabled(true);
mViewPlayOurs.setEnabled(true);
mViewRecord.setEnabled(true);
}
});
}
}, 3000);
}
You are not updating the progress bar anywhere in the code
You should be using circularProgressBar.setProgress(circularProgressBar.getProgress()+1000); inside run().
But in my opinion, you should be using a Countdown Timer class instead of scheduling with Timer.schedule().
A simple example of CountDownTimer that will do a task inside onTick() after every 1 second and call onFinish() after 3 second
You can place the code for setProgress inside onTick().
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
Read more at: https://developer.android.com/reference/android/os/CountDownTimer
Related
In my app i want to have a delay of 5 seconds and in this five seconds user should see progress dialog
i tried this
progressdialog.show();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
progressdialog.dismiss();
but while Thread is sleeping the progessdialog also wont show .
new CountDownTimer(6000, 1000) {
public void onFinish() {
mProgressDialog.dismiss();
// my whole code
}
public void onTick(long millisUntilFinished) {
mProgressDialog.show();
}
}.start();
This works fine
progressDialog.show();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
progressDialog.dismiss();
}
},3000);
i am calling this medthod show() in onCreate()
, whats wrong in my code
public void show()
{
Toast.makeText(getApplicationContext(),"1",Toast.LENGTH_SHORT).show();
new Thread(new Runnable() {
#Override
public void run() {
Looper.prepare();
Toast.makeText(getApplicationContext(),"2",Toast.LENGTH_SHORT).show();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),"3",Toast.LENGTH_SHORT).show();
int arr[]={R.drawable.img1,R.drawable.img2,R.drawable.img3,R.drawable.img4};
int i=1;
do
{
i++;
try
{
imageView.setImageResource(arr[i]);
Thread.sleep(2000);
}
catch (InterruptedException e) {e.printStackTrace();}
}
while(i==arr.length);
}
},2000);
}
}).start();
}
i think it should wait for 2 sec. every time and show next image but its doing nothing even no error
i used toast to counter processing then i found its only reaching to first toast
I am trying to update seekbar with respect to the progress of the song in MediaPlayer.
I am using Thread to do that task.
First i have used Thred inside thread and trying to update the UI but it crashing the app and says that only original thread can attached to the view.
Then i have try to update it with handler inside the thread runnable. which works fine but it is not updating the seekbar. When i have do log then i come to know loop is not going inside my handler. I dont know where is the problem. Please help me to updating SeekBar.
Code:
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
try {
if ((musicPath != mIRemoteService.getPath())) {
System.out.println("..... MUSIC CHANGE.....");
setOrUpdateData();
updateFragmentLayout();
}
// Displaying Current Duration time/Progress
new Handler().post(new Runnable() {
#Override
public void run() {
try {
songCurrentDurationLabel.setText(""+ Utilities.milliSecondsToTimer(mIRemoteService.position()));
songProgressBar.setProgress((int)mIRemoteService.position());
System.out.println("Runnnnn.........");
//songProgressBar.invalidate();
} catch (RemoteException e) {
e.printStackTrace();
System.out.println("Runnnnn......... EXCEPTION....");
}
}
});
System.out.println("Runnnnn.........MAIN....");
if (!(mIRemoteService.isPlayerRunning())) {
btnPlay.setImageDrawable(getResources().getDrawable(R.drawable.play_now_playing));
mHandler.removeCallbacks(mUpdateTimeTask);
System.out.println("Runnnnn.........MAIN....IF");
}else{
System.out.println("Runnnnn.........MAIN....ELSE");
mHandler.post(mUpdateTimeTask);
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
you can use either a handler or a thread, with thread you should make sure to post the modifications on the UI thread:
private class UpdateSeekBar extends Thread
{
#Override
public void run()
{
super.run();
while (null != mp && mp.isPlaying() && this.isAlive())
{
//final int min = (mp.getCurrentPosition() / 1000) / 60;
//final int sec = (mp.getCurrentPosition() / 1000) % 60;
MainActivity.this.runOnUiThread(new Runnable()
{
#Override
public void run()
{
try
{
songCurrentDurationLabel.setText("" + Utilities.milliSecondsToTimer(mIRemoteService.position()));
songProgressBar.setProgress((int) mIRemoteService.position());
System.out.println("Runnnnn.........");
// songProgressBar.invalidate();
}
catch (RemoteException e)
{
e.printStackTrace();
System.out.println("Runnnnn......... EXCEPTION....");
}
}
});
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
I am working on an app with recorder and player. I am using mediaplayer to play the recorded .wav file and meantime I want to update to a seekbar. Everything is working fine But my problem is mediaplayer progress updation to seekbar is not happening smoothly, If we are playig a small file, thumb of the seekbar jumps in seconds or between.
Can anyone help me with a workaround to make it smooth seeking of the progress in seekbar. My code is shown below.I am totlay stuck here.
mediaPlayerIntiate();
mediaPlayerSetSource();
mMediaPlayer.start();
task = new TimerTask() {
#Override
public void run() {
Graphbar.post(new Runnable() {
#Override
public void run() {
if (mMediaPlayer != null) {
if (playButtonState == MediaMode.PLAY) {
if (mMediaPlayer.isPlaying()) {
Graphbar.setProgress(mMediaPlayer
.getCurrentPosition());
mediaPlayerUpdateTimer(mMediaPlayer
.getCurrentPosition());
enableRewindandForward();
}
}
}
}
});
}
};
timer = new Timer();
timer.schedule(task, 0, 8);
mMediaPlayer.getCurrentPosition() Return current Time in millisecond and you are updating this to Seekbar which maximum capacity is 100. Make one formula to with length of file and 100. try this function
MediaPlayer mMediaPlayer = new MediaPlayer();
final SeekBar mSeelBar = new SeekBar(this);
final int duration = mMediaPlayer.getDuration();
final int amoungToupdate = duration / 100;
Timer mTimer = new Timer();
mTimer.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (!(amoungToupdate * mSeelBar.getProgress() >= duration)) {
int p = mSeelBar.getProgress();
p += 1;
mSeelBar.setProgress(p);
}
}
});
};
}, amoungToupdate);
And this process should be called when Media player start playing. inside
mediaPlayer.setOnPreparedListener(new OnPreparedListener(){
#Override
public void onPrepared(MediaPlayer mp) {
**// call here**
}
});
Update
Update 125 times in seconds is not something you should do. Please increase your interval for updating SeekBar. I adding this after reading comments of NullPointer
seekbar.setProgress() only accepts int. Hence, most of us tend to pass the elapsed percentage to this method. However, if you need much smoother progression, then you can use the duration in milliseconds as the MAX. Then we get to update the progression of the seekbar every millisecond. Below is an example and I have updated it every 15th millisecond as almost every android phone comes with a refresh rate of 60 fps (frames per second).
try{
mediaPlayer.start();
seekbar.setProgress(0);
seekbar.setMax(mediaPlayer.getDuration());
// Updating progress bar
seekHandler.postDelayed(updateSeekBar, 15);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
}
/**
* Background Runnable thread
* */
private Runnable updateSeekBar = new Runnable() {
public void run() {
long totalDuration = mediaPlayer.getDuration();
long currentDuration = mediaPlayer.getCurrentPosition();
// Displaying Total Duration time
remaining.setText(""+ milliSecondsToTimer(totalDuration-currentDuration));
// Displaying time completed playing
elapsed.setText(""+ milliSecondsToTimer(currentDuration));
// Updating progress bar
seekbar.setProgress((int)currentDuration);
// Call this thread again after 15 milliseconds => ~ 1000/60fps
seekHandler.postDelayed(this, 15);
}
};
/**
* Function to convert milliseconds time to
* Timer Format
* Hours:Minutes:Seconds
* */
public String milliSecondsToTimer(long milliseconds){
String finalTimerString = "";
String secondsString = "";
// Convert total duration into time
int hours = (int)( milliseconds / (1000*60*60));
int minutes = (int)(milliseconds % (1000*60*60)) / (1000*60);
int seconds = (int) ((milliseconds % (1000*60*60)) % (1000*60) / 1000);
// Add hours if there
if(hours > 0){
finalTimerString = hours + ":";
}
// Prepending 0 to seconds if it is one digit
if(seconds < 10) {
secondsString = "0" + seconds;
}else {
secondsString = "" + seconds;
}
finalTimerString = finalTimerString + minutes + ":" + secondsString;
// return timer string
return finalTimerString;
}
Here is how i handle the seekbar;
mediaPlayer.setOnPreparedListener(new OnPreparedListener(){
#Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start();
new SeekBarHandler().execute();
});
Now i have an Async Task called SeekBarHandler that handles the seekbar like this:
public class SeekBarHandler extends AsyncTask<Void, Void, Void> {
#Override
protected void onPostExecute(Void result) {
Log.d("##########Seek Bar Handler ################","###################Destroyed##################");
super.onPostExecute(result);
}
#Override
protected void onProgressUpdate(Void... values) {
seekBar.setProgress(mediaPlayer.getCurrentPosition());
super.onProgressUpdate(values);
}
#Override
protected Void doInBackground(Void... arg0) {
while(mediaPlayer.isPlaying()&&isViewOn==true) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
onProgressUpdate();
}
return null;
}
}
Now in my onPause, i terminate the AsyncTask as it doesnt make sense to keep the thread going when the user is not able to see the seekbar
protected void onPause() {
isViewOn=false;
super.onPause();
}
And on onResume i start the AsyncTaskAgain like this
protected void onResume() {
isViewOn=true;
new SeekBarHandler().execute();
super.onResume();
}
As you can see i use a boolean flag isViewOn to check whether the view is on or not to handle the seekbar.
player.prepare(); // or start()
ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
service.scheduleWithFixedDelay(new Runnable()
{
#Override
public void run()
{
progressBar.setProgress(player.getCurrentPosition());
}
}, 1, 1, TimeUnit.MICROSECONDS);
The problem you're experiencing has to do with the way Android's SeekBar is designed/implemented. While it functions very well, you're limited by a combination of segments used (i.e. seekbar.setMax(int)) and the delay time of your Handler.
That being said, I subclassed SeekBar to make my own SmoothSeekBar that uses ViewPropertyAnimators instead of a Handler.
Check it out here: https://github.com/Indatus/Android-SmoothSeekBar
private void startPlaying() {
mediaPlayer = new MediaPlayer();
try {
mediaPlayer.reset();
mediaPlayer.setDataSource(audioPlayerName);
mediaPlayer.prepare();
mediaPlayer.start();
setAudioProgress(); //call method
} catch (Exception e) {
e.printStackTrace();
}
}
public void setAudioProgress() {
total_duration = mediaPlayer.getDuration();
binding.total.setText(timeConversion((long) total_duration));
binding.current.setText(timeConversion((long) current_pos));
binding.seekbar.setMax((int) total_duration);
runnable = new Runnable() {
#Override
public void run() {
try {
current_pos = mediaPlayer.getCurrentPosition();
binding.current.setText(timeConversion((long) current_pos));
binding.seekbar.setProgress((int) current_pos);
handlerProgressBar.postDelayed(this, 1000);
Log.e(LOG_TAG, "11111");
} catch (IllegalStateException ed) {
ed.printStackTrace();
}
}
};
handlerProgressBar.postDelayed(runnable, 1000);
}
I am working on Android , I am creating a player for audio songs. I want to play a song only for just 30 seconds. After that, player must be closed. It should be start again, if I press START button again.
This is the code for creating a media player:
MediaPlayer mediaPlayer = new MediaPlayer();
public void songPreview(String songURL){
try{
mediaPlayer=new MediaPlayer();
mediaPlayer.setDataSource(songURL);
mediaPlayer.prepare();
mediaPlayer.start();
} catch(Exception ex){
ex.printStackTrace();
}
}
Please suggest me what code should I use to play my song only for 30 seconds after that it will stop, and if I want to play again then I have to press start button.
Note: Please provide me logic to stop media player after 30 second.
Thank you in advance.
use countdownTimer to complete your goal in which you can set countdown timer till 30 second manually. when countdown finish process it will go to finish method and execute finish method code
::
CountDownTimer cntr_aCounter = new CountDownTimer(3000, 1000) {
public void onTick(long millisUntilFinished) {
mp_xmPlayer2.start();
}
public void onFinish() {
//code fire after finish
mp_xmPlayer2.stop();
}
};cntr_aCounter.start();
private void playSoundForXSeconds(final Uri soundUri, int seconds) {
if(soundUri!=null) {
final MediaPlayer mp = new MediaPlayer();
try {
mp.setDataSource(Settings.this, soundUri);
mp.prepare();
mp.start();
}catch(Exception e) {
e.printStackTrace();
}
Handler mHandler = new Handler();
mHandler.postDelayed(new Runnable() {
public void run() {
try {
mp.stop();
}catch(Exception e) {
e.printStackTrace();
}
}
}, seconds * 1000);
}
}
This method jumps to the end of the track after a given time and allows the native onCompleted callback do its work. You'd obviously need to expand the code to handle any pause events fired before the playback completes.
private static void startMedia(final MediaPlayer mediaPlayer, #Nullable Integer previewDuration) {
mediaPlayer.start();
if( previewDuration != null) {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
mediaPlayer.seekTo(mediaPlayer.getDuration());
}
}, previewDuration);
}
}