Hi
In my android application i am using videoview.
I would like to start a timer and stop the player after 30 minutes.
I tried using the below code but the alert is displaying before the time is reached.
public final void timerAlert() {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
mVideoView.pause();
Alerts.ShowAlert("Cannot play",
"Subscribed time has been completed", context);
}
}, realtime);
Where realtime is the time after which i want the dialogue to be executed.
And am calling this in onprepared listener of player.
Please let me know if i require to change anything.
Please forward your valuable suggestions.
Thanks in advance :)
Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == 1) {
Log.d(tag, "Handling msg.");
// YOUR CODE GOES HERE..
// DISPLAY DIALOG..
msg.what = 2;
}
};
};
// USE HANDLER
mHandler.sendEmptyMessageDelayed(1, 30 * 60 * 1000); // 30 Minutes = 30 * 60 * 1000
First you create handler , processe Message : apply your logic here..
use handler to send delayed message after 30Minutes. ( See Comment)
Thanks :)
Related
My handler will record the camera screen every 5 minutes
recently, I found handler runs in duplicate.
handler is before record the camera screen, create record file name.
if normal, 15:00:00.mp4 , 15:05:00.mp4, 15:10:00.mp4.
but current my state is 15:00:00.mp4, 15:02:15.mp4, 15:05:00.mp4, 15:07:15.mp4.
It seems that the same handler is duplicated and the 2 are executed.
so, I want if there is a handler already working, delete the old handler, execute new handler.
then, I think solve same handler duplicate problem. is right?
to sum it up,
1. Before doing handler.sendEmptyMessage, Is it possible to check if the same handler is working?.
if 1 is possible, How to delete a running handler and run only the new handler.
current my source.
private RecHandler mHandler = new RecHandler(this);
#Override
public void onCreate(Bundle savedInstanceState) {
...
mHandler.sendEmptyMessage(REQUEST_HANDLE_INIT_RECORD);
}
RecHandler.class
public class RecHandler extends Handler {
private final SoftReference<MainActivity> weak;
public RecHandler(MainActivity act) {
weak = new SoftReference<BlackEyeActivity>(act);
}
#Override
public void handleMessage(Message msg) {
MainActivity act = weak.get();
RecHandler mHandler = new RecHandler(act);
if (act != null) {
switch (msg.what) {
case REQUEST_HANDLE_INIT_RECORD:
initCapturing(); //init camera preview..
mHandler = new RecHandler(act);
mHandler.sendEmptyMessageDelayed(REQUEST_HANDLE_START_RECORD, 1000); //after 1 second, start REQUEST_HANDLE_START_RECORD.
this.removeMessages(REQUEST_HANDLE_HOLD_RECORD);
break;
case REQUEST_HANDLE_START_RECORD :
startRecording(); //start Recording.. record file 5 minute.
mHandler.sendEmptyMessageDelayed(REQUEST_HANDLE_HOLD_RECORD, 300000); //after 5 minute, start REQUEST_HANDLE_HOLD_RECORD.
this.removeMessages(REQUEST_HANDLE_INIT_RECORD);
break;
case REQUEST_HANDLE_HOLD_RECORD:
stopRecording();
mHandler.sendEmptyMessageDelayed(REQUEST_HANDLE_INIT_RECORD, 1000); //after 1 second, start REQUEST_HANDLE_INIT_RECORD.
this.removeMessages(REQUEST_HANDLE_START_RECORD);
break;
so, My handler if always record, repeat INIT(1 seconds) -> START (5 minute) -> HOLD(1 seconds)
if you know how to check if the same handler is working, and how to delete a running handler and run only the new handler. please advice for me.
I am making an app which need to compare two date and time continuously.
I just saw some example which just compare once. I think I can use timer to repeat a method but it seem not very efficient. Anyone did this before?
Maybe you can use postDelayed like below.
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
compareTime();
}
}, 5000);
replace 5000 with your own interval milliseconds.
It is easy, you can use handler; When the first time to check time send the normal message like this
mHandler.sendMessage(mHandler.obtainMessage(CHECK_TIME);
Afterwards sendDelayedMessage from inside the handler.
private final Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case CHECK_TIME:
// Your compare time code here
// ....
// Send the delayed message to handler to check time again
mHandler.sendMessageDelayed(mHandler.obtainMessage(CHECK_TIME),
DELAY_CHECK_TIME_INTERVAL);
break;
}
}
}
I create 1 minute delayed timer to shutdown service if it's not completed. Looks like this:
private Handler timeoutHandler = new Handler();
inside onCreate()
timeoutHandler.postDelayed(new Runnable()
{
public void run()
{
Log.d(LOG_TAG, "timeoutHandler:run");
DBLog.InsertMessage(getApplicationContext(), "Unable to get fix in 1 minute");
finalizeService();
}
}, 60 * 1000);
If I get job accomplished before this 1 minute - I would like to get this delayed thing cancelled but not sure how.
You can't really do it with an anonymous Runnable. How about saving the Runnable to a named variable?
Runnable finalizer = new Runnable()
{
public void run()
{
Log.d(LOG_TAG, "timeoutHandler:run");
DBLog.InsertMessage(getApplicationContext(), "Unable to get fix in 1 minute");
finalizeService();
}
};
timeoutHandler.postDelayed(finalizer, 60 * 1000);
...
// Cancel the runnable
timeoutHandler.removeCallbacks(finalizer);
If you don't want to keep a reference of the runnable, you could simply call:
timeoutHandler.removeCallbacksAndMessages(null);
The official documentation says:
... If token is null, all callbacks and messages will be removed.
You might want to replace use of postDelayed with use of sendMessageDelayed like so:
private Handler timeoutHandler = new Handler(){
#Override
public void handleMessage(Message msg)
{
switch (msg.what){
case 1:
((Runnable)msg.obj).run();
break;
}
}
};
Then post a Message:
Message m = Message.obtain();
m.what = 1;
m.obj = new Runnable(){
public void run()
{
Log.d(LOG_TAG, "timeoutHandler:run");
DBLog.InsertMessage(getApplicationContext(), "Unable to get fix in 1 minute");
finalizeService();
}
};
timeoutHandler.sendMessageDelayed(m, 60 * 1000);
and then cancel:
timeoutHandler.removeMessages(1);
No tracking of the runnable necessary.
If I get job accomplished before this 1 minute - I would like to get this delayed thing cancelled but not sure how.
Use Handler.removeCallbacks(yourRunnable).
I need to display 4 "Toast"s spaced by 2 seconds between them.
How do I do this in such a way that they wait for each other and that the program itself waits until the last of them has displayed?
simply use handlers.
handler has a method called sendMessageDelayed(Message msg, long delayMillis).
just schedule your messages at the interval of 2 seconds.
here is a sample code.
int i=1;
while(i<5){
Message msg=Message.obtain();
msg.what=0;
hm.sendMessageDealayed(msg, i*2);
i++;
}
now this code will call handler's method handleMessage after every 2 seconds.
here is your Handler
Handler hm = new Handler(){
public void handleMessage(Message msg)
{
//Toast code.
}
};
and you are done.
Thanks.
Handlers are definitely the way to go but I would just postDelayed instead of handling an empty message.
Also extending Toast and creating a method for showing it longer is nice.
Sample Code:
// make sure to declare a handler in the class
private final Handler mHandler = new Handler();
// The method to show longer
/**
* Show the Toast Longer by repeating it.
* Depending upon LENGTH_LONG (3.5 seconds) or LENGTH_SHORT (2 seconds)
* - The number of times to repeat will extend the length by a factor
*
* #param number of times to repeat
*/
public void showLonger(int repeat) {
// initial show
super.show();
// to keep the toast from fading in/out between each show we need to check for what Toast duration is set
int duration = this.getDuration();
if (duration == Toast.LENGTH_SHORT) {
duration = 1000;
} else if (duration == Toast.LENGTH_LONG) {
duration = 2000;
}
for (int i = 1; i <= repeat; i++) {
// show again
handler.postDelayed(new Runnable() {
#Override
public void run() {
show();
}
}, i * duration);
}
}
I've made a simple Android music player. I want to have a TextView that shows the current time in the song in minutes:seconds format. So the first thing I tried was to make the activity Runnable and put this in run():
int position = 0;
while (MPService.getMP() != null && position<MPService.duration) {
try {
Thread.sleep(1000);
position = MPService.getSongPosition();
} catch (InterruptedException e) {
return;
}
// ... convert position to formatted minutes:seconds string ...
currentTime.setText(time); // currentTime = (TextView) findViewById(R.id.current_time);
But that fails because I can only touch a TextView in the thread where it was created. So then I tried using runOnUiThread(), but that doesn't work because then Thread.sleep(1000) is called repeatedly on the main thread, so the activity just hangs at a blank screen. So any ideas how I can solve this?
new code:
private int startTime = 0;
private Handler timeHandler = new Handler();
private Runnable updateTime = new Runnable() {
public void run() {
final int start = startTime;
int millis = appService.getSongPosition() - start;
int seconds = (int) ((millis / 1000) % 60);
int minutes = (int) ((millis / 1000) / 60);
Log.d("seconds",Integer.toString(seconds)); // no problem here
if (seconds < 10) {
// this is hit, yet the text never changes from the original value of 0:00
currentTime.setText(String.format("%d:0%d",minutes,seconds));
} else {
currentTime.setText(String.format("%d:%d",minutes,seconds));
}
timeHandler.postAtTime(this,(((minutes*60)+seconds+1)*1000));
}
};
private ServiceConnection onService = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder rawBinder) {
appService = ((MPService.LocalBinder)rawBinder).getService();
// start playing the song, etc.
if (startTime == 0) {
startTime = appService.getSongPosition();
timeHandler.removeCallbacks(updateTime);
timeHandler.postDelayed(updateTime,1000);
}
}
what about this:
int delay = 5000; // delay for 5 sec.
int period = 1000; // repeat every sec.
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask()
{
public void run()
{
//your code
}
}, delay, period);
Use a Timer for this (instead of a while loop with a Thread.Sleep in it). See this article for an example of how to use a timer to update a UI element periodically:
Updating the UI from a timer
Edit: updated way-back link, thanks to Arialdo: http://web.archive.org/web/20100126090836/http://developer.android.com/intl/zh-TW/resources/articles/timed-ui-updates.html
Edit 2: non way-back link, thanks to gatoatigrado: http://android-developers.blogspot.com/2007/11/stitch-in-time.html
You have to use a handler to handle the interaction with the GUI. Specifically a thread cannot touch ANYTHING on the main thread. You do something in a thread and if you NEED something to be changed in your main thread, then you call a handler and do it there.
Specifically it would look something like this:
Thread t = new Thread(new Runnable(){
... do stuff here
Handler.postMessage();
}
Then somewhere else in your code, you do
Handler h = new Handler(){
something something...
modify ui element here
}
Idea its like this, thread does something, notifies the handler, the handler then takes this message and does something like update a textview on the UI thread.
This is one more Timer example and I'm using this code in my project.
https://stackoverflow.com/a/18028882/1265456
I think the below blog article clearly gives a very nice solution. Especially, if you are a background service and want to regularly update your UI from this service using a timer-like functionality.
It really helped me, much more than the 2007 blog link posted by MusiGenesis above.
https://www.websmithing.com/2011/02/01/how-to-update-the-ui-in-an-android-activity-using-data-from-a-background-service/