I am using IVideon Player and I have an URL which I want to play. Things are okay but I am unable to handle Seekbar status. I am getting 0 when I want to get time how much my video has been played. Please help me out. What I did is here
class SeekBarProgress implements Runnable {
#Override
public void run() {
int totalDuration = event_list.get(counter).getDuration();
for (int i = 0; i <= totalDuration; i++) {
if (isPlaying) {
final int value = i;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
mTimeUpdateHandler.post(new Runnable() {
#Override
public void run() {
strttime.setText(Utils.getDuration(Utils.getLong((double) value))); // the TextView Reference
mBufferBar.setProgress(value);
}
});
}
}
}
}
Related
I'm trying to change a textView from my thread, but it always crashes. Why?
public void startProgress(View view) {
bar.setProgress(0);
new Thread(new Task()).start();
}
class Task implements Runnable {
#Override
public void run() {
for (int i = 0; i <= 10; i++) {
final int value = i;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
bar.setProgress(value);
text.setText("i = "+i);
}
}
}
I don't know why i can't change it. Anyone knows why?
Thanks.
Views can only be modified by their parent thread. This is a common problem that people face, unfortunately you just have to work around it.
Use runOnUiThread
runOnUiThread(new Runnable(){
public void run() {
for (int i = 0; i <= 10; i++) {
final int value = i;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
bar.setProgress(value);
text.setText("i = "+i);
}
}
});
As #dodo or #CommonsWare said you must access View hiearhcy in the main ui thread.
To comply with this rule, use Handler.post(Context.getMainLooper())
new Handler(context.getMainLooper()).post(new Runnable() {
public void run() {
bar.setProgress(value);
text.setText("i = "+i);
}
});
Finally I fixed it. Thanks anyway.
public void startProgress(View view) {
bar.setProgress(0);
//new Thread(new Task()).start();
Thread th = new Thread(new Runnable() {
public void run() {
for (int i=0; i<10;i++){
final int timer = i;
runOnUiThread(new Runnable() {
#Override
public void run() {
text.setText("velocitat: "+timer);
}
});
bar.setProgress(timer);
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
th.start();
}
I'm facing with a problem. I want to get duration of video when i 'm recording it.
I can get duration of video when it's finish by code
MediaPlayer mp = MediaPlayer.create(mContext, Uri.parse(video));
if(mp == null)
return -1;
int duration = mp.getDuration();
mp.release();
But i want to get duration everytime when i record video to update to progressbar.
Hope your reply!
private class PlaybackObserver extends Thread {
public void run() {
currentPosition = 0;
try {
while (!killObserverThread) {
Thread.sleep(1000);
currentPosition = (int) mediaPlayer.getCurrentPosition();
runOnUiThread(new Runnable() {
public void run() {
yourProgressBar.setProgress(currentPosition);
}
});
}
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
protected void onDestroy() {
super.onDestroy();
killObserverThread = false;
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
if (task == null || !task.isAlive()) {
task = new PlaybackObserver();
task.start();
}
startPlaying();
}
add a private class for your UiThread to update your seekbar/progressbar. Then start it from onResume()
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.
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
in my app i am using media player and i want to place a seek bar there. In my code the song is playing but the seek bar is not moving. Following is the part of my code...
sv = (SurfaceView)findViewById(R.id.surfaceView1);
sv.postDelayed(runnable,200);
final Runnable runnable = new Runnable()
{
#Override
public void run()
{
if (mediaPlayer != null)
{
if (isPlaying)
{
try
{
int currentPosition = mediaPlayer.getCurrentPosition();
audioProgress.setProgress((int) ((currentPosition / (float) mediaPlayer.getDuration()) * 100f));
} catch (Exception e) {
e.printStackTrace();
}
sv.postDelayed(runnable, 150);
}
}
}
};
Please anyone help me in clearing the errors...
Make these changes to your code:
sv = (SurfaceView)findViewById(R.id.surfaceView1);
audioProgress.setMax(mediaPlayer.getDuration()); // this is one change
sv.postDelayed(runnable,200);
final Runnable runnable = new Runnable()
{
#Override
public void run()
{
if (mediaPlayer != null)
{
if (isPlaying)
{
try
{
int currentPosition = mediaPlayer.getCurrentPosition();
// the other change:
audioProgress.setProgress(currentPosition);
} catch (Exception e) {
e.printStackTrace();
}
sv.postDelayed(runnable, 150);
}
}
}
};