I have an intentService that starts a handler, but after a certain amount of time I need to stop the handler. I'm not sure how to do this. I have the class below, but I'm just not sure how to stop the handler once the time is reached, or when a certain amount of hours/min passes. I would like this to be as efficient as possible please.
public class RedirectService extends IntentService {
private Handler handler;
private Runnable runnable = new Runnable() {
#Override
public void run() {
foobar();
handler.postDelayed(this, 2000);
}
};
public LockedRedirectService() {
super("RedirectService");
}
#Override
protected void onHandleIntent(Intent redirectIntent) {
// Gets data from the incoming Intent
int hour = redirectIntent.getIntExtra("hour", 0);
int min = redirectIntent.getIntExtra("minute", 0);
handler.postDelayed(runnable, 2000);
handler.removeCallbacks(runnable);
}
}
Start a new thread and wait. When time's up, stop and remove the runnable.
Or use handler to post another delayed runnable to stop and remove the working runnable.
public class RedirectService extends IntentService {
private Handler handler;
private boolean mRun = false;
private Runnable runnable = new Runnable() {
#Override
public void run() {
if (mRun) {
foobar();
handler.postDelayed(this, 2000);
}
}
};
public LockedRedirectService() {
super("RedirectService");
}
#Override
protected void onHandleIntent(Intent redirectIntent) {
// Gets data from the incoming Intent
final int hour = redirectIntent.getIntExtra("hour", 0);
final int min = redirectIntent.getIntExtra("minute", 0);
mRun = true;
handler.postDelayed(runnable, 2000);
//handler.removeCallbacks(runnable);
new Thread(new Runnable() {
#Override
public void run() {
Thread.currentThread();
try {
Thread.sleep((hour * 60 + min) * 60 * 1000);
} catch (Exception ignore) {}
mRun = false;
handler.removeCallbacks(runnable);
}
}).start();
/* or use handler
handler.postDelayed(new Runnable() {
#Override
public void run() {
mRun = false;
handler.removeCallbacks(runnable);
}
}, (hour * 60 + min) * 60 * 1000);
*/
}
}
Related
i want to lock my application for n minutes after x times of login failure
, locking is supposed to be working after restarting application
any suggestions?
private Runnable runnable;
private Handler handler;
//Write in OnCreate
handler = new Handler();
runnable = new Runnable() {
#Override
public void run() {
try {
//Perform Here as you want.
} catch (InstantiationException e) {
e.printStackTrace();
}
}
};
startHandler();
#Override
public void onUserInteraction() {
super.onUserInteraction();
stopHandler();//stop first and then start
startHandler();
}
public void stopHandler() {
handler.removeCallbacks(runnable);
}
public void startHandler() {
handler.postDelayed(runnable, 5 * 60 * 1000); //for 5 minutes
}
Hi my app needs a realtime data from database and I'm posting it on my TextView and I can't update the TextView as the database updates. I tried using Timer but its still the same.
Here is my code,
public void startTimer() {
//set a new Timer
timer = new Timer();
//initialize the TimerTask's job
initializeTimerTask();
timer.schedule(timerTask, 0, 5000);
}
private void stopTimerTask() {
//stop the timer, if it's not already null
if (timer != null) {
timer.cancel();
timer = null;
}
}
public void initializeTimerTask() {
timerTask = new TimerTask() {
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
final AcceptCars Cars = (AcceptCars) getIntent().getSerializableExtra("cars");
renterLat.setText(Cars.renterLat);
renterLng.setText(Cars.renterLng);
Log.d(TAG,renterLat.getText().toString());
Log.d(TAG,renterLng.getText().toString());
}
});
}
};
}
And here is where I get the Cars.renterLat and Cars.renterLng,
public class AcceptCars implements Serializable {
#SerializedName("renterLat")
public String renterLat;
#SerializedName("renterLng")
public String renterLng;
}
This is the logic you should be following. I used a Handler instead of a Timer. Inside the run method you need to call your webservice and get the updated value from the db. Use runOnUiThread to update the value to the UI from a Thread.
See the code below,
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Handler taskHandler = new Handler();
taskHandler.postDelayed(myTask, 0);
}
private Runnable myTask = new Runnable(){
public void run() {
queryDb();
// repeat the task
taskHandler.postDelayed(this, 1000);
}
};
private void queryDb(){
new Thread(new Runnable() {
#Override
public void run() {
// call you webservice
String data = callWebservice();
// parse the data in to AcceptCars pojo class
AcceptCars Cars = parseData(data);
//update the UI
runOnUiThread(new Runnable() {
#Override
public void run() {
renterLat.setText(Cars.renterLat);
renterLng.setText(Cars.renterLng);
}
});
}
}).start();
}
You can even use countdown timer.
Here is the link https://developer.android.com/reference/android/os/CountDownTimer.html
TimerTasks are really hard to deal with IMO. You should use a Handler and call postDelayed to do something after a certain amount of time.
Alternatively, you can try out this timer class I wrote:
import android.os.Handler;
public class Timer {
private Handler handler;
private boolean paused;
private int interval;
private Runnable task = new Runnable () {
#Override
public void run() {
if (!paused) {
runnable.run ();
Timer.this.handler.postDelayed (this, interval);
}
}
};
private Runnable runnable;
public int getInterval() {
return interval;
}
public void setInterval(int interval) {
this.interval = interval;
}
public void startTimer () {
paused = false;
handler.postDelayed (task, interval);
}
public void stopTimer () {
paused = true;
}
public Timer (Runnable runnable, int interval, boolean started) {
handler = new Handler ();
this.runnable = runnable;
this.interval = interval;
if (started)
startTimer ();
}
}
It is really simple to use.
You can use it like this:
Timer timer = new Timer(new Runnable() {
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
final AcceptCars Cars = (AcceptCars) getIntent().getSerializableExtra("cars");
renterLat.setText(Cars.renterLat);
renterLng.setText(Cars.renterLng);
Log.d(TAG,renterLat.getText().toString());
Log.d(TAG,renterLng.getText().toString());
}
}
}
}, 5000, true);
I'm new to android and i have a problem
I used same code to repeat and delay method for two class. One class work fine but other not. I don't know why. This is my code
SpeedMeterFragment.java
public class SpeedMeterFragment extends Fragment {
....
public void speedMeterBefore() {
totalRxBytesBefore = TrafficStats.getTotalRxBytes();
Log.d("test", "Before: " + String.valueOf(totalRxBytesBefore));
}
public void speedMeterAfter() {
totalRxBytesAfter = TrafficStats.getTotalRxBytes();
Log.d("test", "After: " + String.valueOf(totalRxBytesAfter));
}
public void speedMeterDifference() {
totalRxBytesDifference = totalRxBytesAfter - totalRxBytesBefore;
tvTest.setText(String.valueOf(totalRxBytesDifference/1024) + " kb/s");
Log.d("test", "Difference: " + String.valueOf(totalRxBytesDifference));
}
public void speedMeter() {
handler = new Handler();
handler.post(runnable = new Runnable() {
#Override
public void run() {
speedMeterBefore();
final Handler handler1 = new Handler();
handler1.postDelayed(new Runnable() {
#Override
public void run() {
speedMeterAfter();
speedMeterDifference();
}
}, 1000);
handler.postDelayed(this, 1000);
}
});
}
}
and SaveDataUseage.java
public class SaveDataUseage extends BroadcastReceiver {
...
public void onReceive(Context context, Intent intent) {
...
savePreference();
}
public void savePreference() {
...
measureDataMB();
}
public void measureDataMBBefore() {
dataMBBefore = TrafficStats.getTotalRxBytes() / 1048576;
}
public void measureDataMBAfter() {
dataMBAfter = TrafficStats.getTotalRxBytes() / 1048576;
}
public void measureDataMBDifference() {
dataMBDifference = dataMBAfter - dataMBBefore;
}
public void measureDataMB() {
handler = new Handler();
handler.post(runnable = new Runnable() {
#Override
public void run() {
measureDataMBBefore();
final Handler handler1 = new Handler();
handler1.postDelayed(new Runnable() {
#Override
public void run() {
measureDataMBAfter();
measureDataMBDifference();
}
}, 1000);
handler.postDelayed(this, 1000);
}
});
}
}
SpeedMeterFragment work fine, but not SaveDataUseage
Anybody help me?
Sorry for my bad English :)
handler = new Handler();
final Runnable r = new Runnable() {
public void run() {
//Your method called here
handler.postDelayed(this, 1000);
}
};
handler.postDelayed(r, 1000);
this code will repeat method after every second
handler = new Handler();
final Runnable r = new Runnable() {
public void run() {
//Your method called here
MyMethod(isCalledFromHandeler);
handler.postDelayed(this, 1000);
}
};
handler.postDelayed(r, 1000);
use boolean argument isCalledFromHandeler to recognition the caller of method.
and then use
if(isCalledFromHandeler){
// Do Not call the Child Method
} else{
// Call the Child Method
}
Although its eight month old question, I also faced the similar problem and in solution I extended Handler class to AdvanceHandler with the postRepeated method.
Sample Usage
AdvanceHandler handler = new AdvanceHandler();
handler.postRepeated(new Runnable() {
#Override
public void run() {
//Your repeated task
}
}, 5000) //After every 5 seconds
Here is a code which I want to repeat 50 times after every 3 seconds. if I am calling this function with 'for' loop or 'while' loop it is not working properly Please give me suggestion.
for (int i = 0; i < 50; i++) {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
Generate_Ballon();
}
}, delay);
}
You can use CountDownTimer
See Example,
new CountDownTimer(150000, 3000)
{
public void onTick(long millisUntilFinished)
{
// You can do your for loop work here
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
Here onTick() method will get executed on every 3 seconds.
You should use Handler's postDelayed function for this purpose. It will run your code with specified delay on the main UI thread, so you will be able to update UI controls.
private int mInterval = 5000; // 5 seconds by default, can be changed later
private Handler mHandler;
#Override
protected void onCreate(Bundle bundle) {
...
mHandler = new Handler();
}
Runnable mStatusChecker = new Runnable() {
#Override
public void run() {
updateStatus(); //this function can change value of mInterval.
mHandler.postDelayed(mStatusChecker, mInterval);
}
};
void startRepeatingTask() {
mStatusChecker.run();
}
void stopRepeatingTask() {
mHandler.removeCallbacks(mStatusChecker);
}
private int count = 50;
private Handler handler = new Handler();
private Runnable r = new Runnable() {
public void run() {
Generate_Ballon();
if (--count > 0) {
handler.postDelayed(r, delay);
}
}
};
handler.postDelayed(r, delay);
Actually, I have designed a seprate Timer class with handler for displaying minute and second on a textview. this works fine as I have debugged it and handler will reaise handle but the text view does not get updated pl help me in this regards.
I am tagging the code below for Timer Class.
thanks in advance.
public class Timer
{
private int _interval;
public int getInterval()
{
return _interval;
}
public void setInterval(int delay)
{
_interval = delay;
}
private Handler handler;
private Runnable _tickHandler;
private Runnable delegate;
private boolean ticking;
public boolean getIsTicking()
{
return ticking;
}
public Timer(int interval)
{
_interval = interval;
handler = new Handler();
}
public Timer(int interval, Runnable onTickHandler)
{
_interval = interval;
setOnTickHandler(onTickHandler);
handler = new Handler();
}
public void start(int interval, Runnable onTickHandler)
{
if (ticking) return;
_interval = interval;
setOnTickHandler(onTickHandler);
handler.postDelayed(delegate, _interval);
ticking = true;
}
public void start()
{
if (ticking) return;
handler.postDelayed(delegate, _interval);
ticking = true;
}
public void stop()
{
handler.removeCallbacks(delegate);
ticking = false;
}
public void setOnTickHandler(Runnable onTickHandler)
{
if (onTickHandler == null) return;
_tickHandler = onTickHandler;
delegate = new Runnable()
{
public void run()
{
if (_tickHandler == null) return;
_tickHandler.run();
handler.postDelayed(delegate, _interval);
}
}
;
}
}
and below is the code that I am using for updating Text View
Timer tmr = new Timer(100,new Runnable()
{
public void run()
{
long millis = System.currentTimeMillis() - mStartTime;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
lblDevOnOff.setText("");
lblDevOnOff.setText(String.format("%d:%02d", minutes,seconds));
}
}
);
tmr.start();
put this code in
handler or runOnUIThread() something like this
runOnUIThread(new Runnable(){
public void run(){
lblDevOnOff.setText("");
lblDevOnOff.setText(String.format("%d:%02d", minutes,seconds));
}
})
you should do this because anything related to UI should run on UI Thread only...
Yeah, this is from the Android Dev Guide:
Thus, there are simply two rules to Android's single thread model:
Do not block the UI thread
Do not access the Android UI toolkit from outside the UI thread