I'm looking for a way to get a callback when a VideoView is playing, indicating the video progress. Something like described here, but for a VideoView. Polling the current progress every fixed duration seems a bad solution…
Is there any listener existing for this that I missed?
You can use a thread to get the progress.
mRunnable = new Runnable() {
public void run() {
Log.i(TAG, "::run: getCurrentPosition = " + mVideoView.getCurrentPosition());
if(mVideoView.isPlaying()){
mHandler1.postDelayed(this, 250);
}
}
};
mHandler1.post(mRunnable);
Runnable onEverySecond=new Runnable() {
public void run() {
if(seekbar != null) {
seekbar.setProgress(mPlayer.getCurrentPosition());
}
if(mPlayer.isPlaying()) {
System.out.println("inside runnable :::::: is playing ");
seekbar.postDelayed(onEverySecond, 10);
}
}
};
seekbar.postDelayed(onEverySecond, 10);
Related
I have a tune in my android app. I have added a feature that if user selects a time then the tune will repeat until the time ends. I have also added the feature of infinite time but when I run my app goes in ANR (not responding) mode.
if(tinydb.getString("timer").equals("infinity"))
{
boolean valid = true; //Here i want to play the tune for infinite time
while(valid)
{
water_player = MediaPlayer.create(MainActivity.this, R.raw.water);
water_player.start();
}
}
else
{
while(!timerText.equals("0h: 0m: 1s")) //Here i want to play the tune until the timer gets zero
{
water_player = MediaPlayer.create(MainActivity.this, R.raw.water);
water_player.start();
}
you can use setLooping for the first case
and for the second case
final Runnable r = new Runnable() {
public void run() {
water_player.stop();
}
};
handler.postDelayed(r, 1000); //your time in millisecond
with your code :
if(tinydb.getString("timer").equals("infinity"))
{
water_player = MediaPlayer.create(MainActivity.this, R.raw.water);
water_player.setLooping(true);
water_player.start();
}
else
{
water_player = MediaPlayer.create(MainActivity.this, R.raw.water);
water_player.start();
final Runnable r = new Runnable() {
public void run() {
water_player.stop();
}
};
handler.postDelayed(r, 1000); //your time in millisecond
}
Use countdownTimer to complete your goal in which you can set countdown timer till x seconds 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();
If you have only 2 cases, use a boolean.
boolean infinitely;
if(infinitely == true){
water_player = MediaPlayer.create(MainActivity.this, R.raw.water);
water_player.start();
}
else {
water_player = new MediaPlayer.create(MainActivity.this, R.raw.water);
water_player.start();
Handler handler = new Handler();
handler.postDelayed(new Runnable(){
water_player.stop();
}
}
, 2000);
The handler method will be executed when 2sec passed. (put your own desired time).
my_text.setText("Dave");
//Small pause...
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
my_text.setText("Bob");
I want to change my textView, pause 1 second, then change it again. When I run the program, it doesn't refresh after first change. It just shows the second change after returning. How can I force the refresh on the first change to the textview?
Try use Handler like below code
my_text.setText("Dave");
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
my_text.setText("Bob");
}
});
}
}, 1000);
Try below for the edited question
Keep your all 20 names in any collection array or list.
int position = 0;
String names [] = {"0","1","20"};
Handler handler = new Handler(getMainLooper());
Runnable runnable = new Runnable() {
public void run() {
my_text.setText(names[position++]);
if (position < names.length) {
handler.postDelayed(this, 1000);
}
}
};
handler.postDelayed(runnable, 1000);
I am updating my UI using the handler.postDelayed() but it is not stopping when I'm wanting it to stop. it keeps updating the UI.
int progress = 10;
Runnable mStatusChecker = new Runnable() {
#Override
public void run() {
try {
Log.d( "","entered run ");
mWaveLoadingView.setCenterTitle(String.valueOf(progress)+"%");
mWaveLoadingView.setProgressValue(progress);
progress+=1;
if(progress==90)
stopRepeatingTask();
} finally {
// 100% guarantee that this always happens, even if
// your update method throws an exception
mHandler.postDelayed(mStatusChecker, mInterval);
}
}
};
void startRepeatingTask() {
Log.d( "","entered update ");
mStatusChecker.run();
}
void stopRepeatingTask() {
mHandler.removeCallbacks(mStatusChecker);
}
The handler is being started from another method:
Client.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Log.d( "","entered client ");
mHandler = new Handler();
startRepeatingTask();
}
});
any idea on how to make it stop?
Right now, you call stopRepeatingTask() on reaching a certain limit (progress == 90). But in the finally block, you unconditionally start the next task. You should only start the new task if the limit has not yet been reached:
Runnable mStatusChecker = new Runnable() {
#Override
public void run() {
try {
Log.d( "","entered run ");
mWaveLoadingView.setCenterTitle(String.valueOf(progress)+"%");
mWaveLoadingView.setProgressValue(progress);
progress+=1;
if(progress==90)
stopRepeatingTask();
} finally {
// 100% guarantee that this always happens, even if
// your update method throws an exception
// only if limit has not been reached:
if(progress<90){
mHandler.postDelayed(mStatusChecker, mInterval);
}
}
}
};
I want to present bitmap images from a internetstream. Every 500 millisec i get a new image and i want to present this image to the user. What is the best way to do this? Can i use an image view and chenge the image every 500 millisec?
I tried to do this in an timer task like this:
timer.schedule(new TimerTask() {
public void run() {
if(flag){
Bitmap bmp = null;
Log.i(APPID, "New frame");
try {
bmp = session.getImage();
setImage(bmp);
} catch (Exception e) {
e.printStackTrace();
}
} else {
timer.cancel();
}
}
}, 500, 500);
But this does not work.
Updating the UI from a thread other than the UI/main thread will fail as Android does not allow it. Try using a Handler to post messages back to the UI thread. You could do something like this.
final Handler h = new Handler();
timer.schedule(new TimerTask() {
public void run() {
if(flag){
h.post(new Runnable() {
public void run() {
Bitmap bmp = null;
Log.i(APPID, "New frame");
try {
bmp = session.getImage();
setImage(bmp);
} catch (Exception e) {
e.printStackTrace();
}
}
} else {
timer.cancel();
}
}
}, 500, 500);
Timer task runs on a different thread. you need to update ui on the ui thread. You should use runOnUiThread or Handler
runOnUiThread(new Runnable() //run on ui threa
{
public void run()
{
// update ui here
}
});
Handler
Handler m_handler;
Runnable m_handlerTask ;
m_handler= new Handler();
m_handlerTask = new Runnable()
{
#Override
public void run() {
// do soemthing
m_handler.postDelayed(m_handlerTask, 1000);
// change 1000 to whatever you want
}
};
m_handlerTask.run();
When you wan to cancel call this m_handler.removeCallbacks(m_handlerTask).
How to call record method after 5 millisecond playing audio with MediaPlayer. I tried something like that but i don't know and i didn't find any good examples to end this.
while(mp.isPlaying()){
if(record=0){
for(int i=0; i<5millisec; i++){ //how to define 5 millisec or is any better solution
}
startRecord();
record=1;
}
}
mp.stop();
mp.release();
mp=null;
5 milliseconds is a very short time period and you can't limit audio output to such duration.
you can use Handler to execute a delayed function but it will not ensure execution at 5 milliseconds after scheduling.
a code for doing that:
Handler handler = new Handler();
handler.postDelayed(new Runnable(){
#Override
public void run(){
startRecord();
mp.stop();
mp.release();
}
}, 5);
You can use the method postDelayed.
In the example below I run my routine 100 millis after to call the method.
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
barVolume.setProgress(audioManager.getStreamVolume(AudioManager.STREAM_MUSIC));
}
},
100);
try this:
//Auto Start after 2 seconds
if(ENABLE_AUTO_START) {
new Timer().schedule(new TimerTask() {
#Override
public void run() {
// this code will be executed after 2 seconds
doThis();
}
}, 2000);
}
Perhaps you want to use Thread.sleep?
Like so:
if(record == 0){
Thread.sleep(5);
}
Notice that I used == in the if statement to check for equality, rather than assigning the value of 0 each time, I assume this is what you want.
It is worth mentioning that putting a Thread to sleep will stop it doing anything for the duration that you specify. If this is a UI Thread, then you will effectively "freeze" the UI for that duration, so make sure you are using it appropriately. Hwoever, you example for loop indicates this is exactly the kind of thing you are attempting to do.
You could try using Thread.sleep(5), or, if you don't want to use the UI thread for this, you could use a Timer, or an AsyncTask which triggers a callback after waiting 5ms in the doInBackground() method.
Here is a pretty good example for using Timer:
https://stackoverflow.com/a/4598737/832008
You can also use ScheduledExecutorService
Using an ExecutorService, you can schedule commands to run after a given delay, or to execute periodically. The following example shows a class with a method that sets up a ScheduledExecutorService to beep every ten seconds for an hour:
import static java.util.concurrent.TimeUnit.*;
class BeeperControl {
private final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
public void beepForAnHour() {
final Runnable beeper = new Runnable() {
public void run() { System.out.println("beep"); }
};
final ScheduledFuture<?> beeperHandle =
scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
scheduler.schedule(new Runnable() {
public void run() { beeperHandle.cancel(true); }
}, 60 * 60, SECONDS);
}
}
public static MediaRecorder mRecorder = new MediaRecorder();
public void startRecording(String fileName) {
if(mRecorder != null) {
try {
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setOutputFile(fileName);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
mRecorder.prepare();
} catch (IOException e) {
Log.e(StartPhoneCallService.class.getSimpleName(), "prepare() failed");
}
mRecorder.start();
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
}
public void stopRecording() {
if(mRecorder != null) {
mRecorder.stop();
mRecorder.release();
mRecorder = null;
}
}
Now you can call the Handler to play 5 millisecond
private final int recording_time = 5;
Handler handler = new Handler();
handler.postDelayed(new Runnable(){
#Override
public void run() {
startRecording("YOUR FILE NAME");
// Stop your recording after 5 milliseconds
stopRecording();
}
}, recording_time );