Unable to update seekbar with Handler - android

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

Related

Get Video Play Time android from videoplayer

I write this function to get video time . This functions works fine but when I backpress then it throws exception .
public void videoTimer ()
{
try
{
running = true;
final int duration = mVideoView.getDuration();
thread = new Thread(new Runnable()
{
public void run()
{
do
{
tvVideoTimer.post(new Runnable()
{
public void run()
{
int time = (duration - mVideoView.getCurrentPosition()) / 1000;
tvVideoTimer.setText(getTimeString(mVideoView.getCurrentPosition()));
}
});
try
{
Thread.sleep(500);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
if (!running) break;
}
while (mVideoView.getCurrentPosition() <= duration);
}
});
thread.start();
}
catch (Exception e)
{
e.printStackTrace();
}
}

Stop runnable on button click

I have Runnable and have two Handlers for button background color change after some music is played.
Now how can I stop the music played using runnable for a ever delay of 700 mili sec on a button click named stop.
handler=new Handler();
runnable = new Runnable() {
#Override
public void run() {
for (int i = 0; i<Uirkeys1.length; i++) {
final int value = i;
try {
Thread.sleep(700);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.post(new Runnable() {
#Override
public void run() {
copyView.get(cnt1).getBackground().setAlpha(100);
ModeSound(Integer.parseInt(CopyMultimap.get(copykey[cnt1]).get(3)));
}
});
try {
Thread.sleep(800);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.post(new Runnable() {
#Override
public void run()
copyView.get(cnt1).getBackground().setAlpha(500);
cnt1++;
}
});
}
}
};
new Thread(runnable).start();
cnt1=0;
}
});
}
You could create a class MyRunnable that implements Runnable, and create a field in it
private boolean stopped = false;
public void stop() { stopped = true; }
And then you should check in your execution loop
if(!stopped) {..do work..} else return .
And you can of course call the stop() method on your MyRunnable object.

Redraw view with intervals from thread

I need animate menu in custom view. It must be redrawed with intervals some times(about 10), but it redraws after thread stopped.
public void menuShift() {
Runnable runnable = new Runnable() {
public void run() {
while (TablesActivity.this.view.menuShifting) {
try {
Thread.sleep(100) ;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
TablesActivity.this.view.timerRefresh() ;
TablesActivity.this.view.postInvalidate() ;
}
}
} ;
this.menuShiftThread = new Thread(runnable) ;
this.menuShiftThread.run() ;
}
this.menuShiftThread.run(); is the problem, you need
this.menuShiftThread.start()
to actualy start a new thread.

how to stop this running thread?

public class MainActivity extends Activity implements Runnable{
private int progressBarStatus = 0;
private Handler progressBarHandler = new Handler();
ProgressBar linProgressBar;
private long fileSize = 0;
Thread t1;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button b1 = (Button)findViewById(R.id.button1);
Button b2 = (Button)findViewById(R.id.button2);
b2.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View arg0)
{
linProgressBar.setProgress(0);
t1.interrupt();
}
});
b1.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View arg0)
{
basicInitializations();
}
});
}
public void basicInitializations(){
linProgressBar = (ProgressBar) findViewById(R.id.progressBar1);
linProgressBar.setProgress(0);
linProgressBar.setMax(100);
try{
t1 = new Thread()
{
public void run() {
while (progressBarStatus < 100) {
// process some tasks
progressBarStatus = doSomeTasks();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Update the progress bar
progressBarHandler.post(new Runnable() {
public void run() {
linProgressBar.setProgress(progressBarStatus);
}
});
}
if (progressBarStatus >= 100) {
try {
Thread.sleep(2000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
};
t1.start();
}catch (Exception e) {
}
}
public int doSomeTasks() {
while (fileSize <= 1000000) {
fileSize++;
if (fileSize == 100000) {
return 10;
} else if (fileSize == 200000) {
return 20;
} else if (fileSize == 300000) {
return 30;
}else if (fileSize == 400000) {
return 40;
}else if (fileSize == 500000) {
return 50;
}
}
return 100;
}
#Override
public void run() {
// TODO Auto-generated method stub
}
}
this is my main code and i could not stop this thread .
i want to stop it when i click the button b2(say cancel button).
the above code is not the original code and is a model , so please tell me how to stop that thread .
thankyou in advance . . . .
I have a alternate answer can try the same, inside your runnable loop always check a flag as run_flag, create it as a member variable and set it as true once you stared the loop, you can make it run_flag as false wenever you are done and at the same time you can set null to your thread also ... a safer way to come out through runnable loop and thread.
try{
t1 = new Thread()
{
public void run() {
while (progressBarStatus < 100 && run_flag == true) { // added run_flag here
// process some tasks
progressBarStatus = doSomeTasks();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Update the progress bar
progressBarHandler.post(new Runnable() {
public void run() {
linProgressBar.setProgress(progressBarStatus);
}
});
}
if (progressBarStatus >= 100) {
try {
Thread.sleep(2000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
};
t1.start();
}catch (Exception e) {
}
Your thread spends most of its time in Thread.sleep(), which is helpful. The thread pointer, t1, is a class member, which is also helpful. From your button handler, you can check to see if t1 is still alive and, if so, call t1.interrupt();. This will cause the thread's current sleep and future sleeps to throw the InterruptedException... now you just need to modify your exception handler to quit the thread in that case.

Need to kill and restart a thread

I am starting a thread when invoking a method to play an audio file.
The code runs ok the first time but when I call the play method again I need the thread to start as if it were being called the first time. I have tried to interrupt the thread and even stop it but nothing seems to work.
How can I properly restart the thread?
Here is some code to help explain.
Global variable
private Thread thread1;
Thread code:
thread1 = new Thread(new Runnable()
{
#Override
public void run()
{
try {
int i=0;
final TextView timeDuration = (TextView) findViewById(R.id.timeDisplay);
final SeekBar seekBar = (SeekBar)findViewById(R.id.seekBar1);
while (running)
{
info();
j = 0;
while(i>0 && running)
{
while(j<duration && running && (playStatus.getValue() == "TRANSITIONING" || playStatus.getValue() == "PLAYING"))
{
seekBar.setMax((int) duration);
seekBar.setProgress(0);
runOnUiThread(new Runnable()
{
public void run()
{
System.out.println("PLAYBACK STATUS: "+playStatus.getValue());
timeDuration.setText(""+(j+1));
seekBar.setProgress(j+1);
if(j==(duration-1))
{
setRunning(false);
}
}
});
Thread.sleep(1 * 1000);
j++;
if(seekBar.getProgress() == seekBar.getMax())
{
runOnUiThread(new Runnable()
{
public void run()
{
playButton.setVisibility(View.VISIBLE);
pauseButton.setVisibility(View.GONE);
timeDuration.setText(""+"0");
seekBar.setProgress(0);
flag = false;
System.out.println("J VALUE 1: = "+j);
duration = 0;
setRunning(false);
}
});
}
}
}
j = 0;
i++;
Thread.sleep(1 * 1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
play();
This code works fine and plays the track. It then resets the seekbar and awaits for the play method to be called again.
public void play()
{
try
{
thread1.start();
}
catch(Exception e)
{
return;
}
}
Here is the setRunning method recommended to me.
public void setRunning(boolean b)
{
this.running = b;
}
If anyone know of a solution to this problem I would really appreciate it.
Threads are not supposed to be stopped manually. You should use a boolean instead of true in your while loop, and put the boolean to false through a setter when you want to stop:
private boolean running;
#Override
public void run(){
running = true;
while(running) {...}
}
public void setRunning(boolean b){
this.running = b;
}
To restart your player you need to prepare again.
public void restartAudio() {
Log.e(TAG, "restartAudio");
if (mp.isPlaying()) {
mp.seekTo(0);
}else{
mp.stop();
try {
mp.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
When using extra boolean flag to controll thread's while loop don't forget to use volatile modifier on it:
private volatile boolean running;
or put appropriate synchronization.
Apart from that, I'd think about using Thread.isInterrupted() method instead of the additional 'running' flag:
http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#isInterrupted()
here's why:
https://stackoverflow.com/a/3196058/1350225

Categories

Resources