Count time(seconds) the button remained clicked in Android - android

I want to make a program which will tell me the number of seconds I kept holding the button.
for example if I clicked the button for 5 seconds, it should tell me the button remained pressed for 5 seconds.
is this achievable in android?
This is how I tried, didn't work because when I put the while loop in, the button stays clicked even I press it for just one second. The program doesn't crash but the button remains clicked and I think it freezes.
thread = new HandlerThread("");
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
while(btn.isPressed())
{
try {
thread.sleep(1000);
total = total++;
temp = temp++;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Toast.makeText(MainActivity.this, ""+temp+" "+total, 0).show();
}
});

You could use time stamps, and an OnTouchListener to achieve this.
When your OnTouchListener receives an ACTION_DOWN event, store the first time stamp. When it receives an ACTION_UP event, store the second time stamp and calculate the difference between the two.
As mentioned by Raghunandan, you should never block on the UI thread using calls such as thread.sleep, as this will cause the UI to stop responding, and in some cases can cause the program to be killed because of this.
Here is an example of what I've outlined above. Please note, this code was written from memory, and has not been tested, but you should get the general gist of it.
btn.setOnTouchListener(new OnTouchListener() {
private long firstTouchTS = 0;
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction()==MotionEvent.ACTION_DOWN) {
this.firstTouchTS = System.currentTimeMillis();
} else if (event.getaction()==MotionEvent.ACTION_UP) {
Toast.makeText(MainActivity.this,((System.currentTimeMillis()-this.firstTouchTS)/1000)+" seconds",0).show();
}
}
});
References: OnTouchListener MotionEvent

thread.sleep(1000);
Calling sleep on the ui thread hence it freezes. Do not call sleep on the ui thread. It blocks the ui thread.
Read
http://developer.android.com/training/articles/perf-anr.html.
Use a Handler if you want to repeat some task

Related

(View.INVISIBLE) before Timer.sleep() not working

I have several buttons I want to make INVISIBLE for a short while then make them VISIBLE again. The (View.INVISIBLE) before Timer.sleep() does not work. I have yet to figure this out. Any ideas?
Thanks, Steve
private void commonBtnHandler(Button btn) {
try {
btn.setVisibility(View.INVISIBLE);
Thread.sleep(250);
btn.setVisibility(View.VISIBLE);
} catch (Exception e) {
e.printStackTrace();
}
}
You should not do Thread.sleep() on the UI/main thread. It will cause the UI to freeze & ANR
Try :
btn.setVisibility(View.INVISIBLE);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
btn.setVisibility(View.VISIBLE);
}
}, 250);
Also 250 ms is a very small amount of time.
btn.setVisibility(View.INVISIBLE);
new Thread() {
public void run() {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
btn.setVisibility(View.VISIBLE);
}
});
Thread.sleep(250);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
always put the runOnUiThread when need to change the UI in runtime, This is helps to you.
Thanks for all the input.
I tried all the suggestions with a 3000 millisecond delay but still did not see a blink.
Also, I was wondering if I was blocking the UI thread. I thought the INVISIBLE would complete before the sleep() took effect.
Summary: I wrote a loop to make the call 10 times. The delay seems to be ignored in all cases. I appreciate everyone’s help. It looks like I need to rethink how this should work. I wouldn’t think this would be much different than how a game programmer would insure synchronous operations.
Addressing this issue in another way I did not INVISIBLE the button but temporarily changed the color using MotionEvent within a setOnTouchListener. When pressed the button changes color and when released reverts back to the original color. Works great!
mBtn.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch ( event.getAction() ) {
case MotionEvent.ACTION_DOWN:
mBtn.setBackgroundColor(getResources().getColor(R.color.colorLightOrange));
break;
case MotionEvent.ACTION_UP:
mBtn.setBackgroundColor(getResources().getColor(R.color.colorOrange));
break;
}
return true;
}
});

Realtime drawing using threads on android

I simply have a button in my application where onClick, I need it to start collecting gps points and do some process with it and on click again, i need it to stop that process.
Collected points will be pushed into an sqlite database while the thread is running and also I will draw lines on my map while the button is activated using collected gps points.
My problem is how to implement that thread and which way would be safest.
Extending AsyncTask class seems to be a robust solution but it runs only once and I need this thread to be available just like a toggle button for numerous times.
I tried the following test to see if I can maintain a simple thread in my app but it doesnt work. I cant use stop() method.
After I started my thread however and stopping by falsifying the controller in while loop, start() method to start it again just crashes.
class RunBuffer implements Runnable{
#Override
public void run() {
// TODO Auto-generated method stub
while(toggleBufferIsActive){
try {
Thread.sleep(1000);
test++;
Log.v("Thread running", String.valueOf(test));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
and my toggle button is implemented as follows:
public void ToggleBuffer(View view) {
if(this.toggleBufferIsActive){
this.locationManager.removeUpdates(this.locationListener);
this.gpsLatLongCollectionSize = 0;
// TODO stop collecting and drawing buffer polygon thread
this.toggleBufferIsActive = false;
}
else{
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,
0, locationListener);
// TODO start collecting and drawing buffer polygon thread
this.toggleBufferIsActive = true;
runBuffer.start(); // crashes here
}
}
my runBuffer object is of type RunBuffer and instantiated in my onCreate() method in my activity.
any suggestion would be appreciable.
my runBuffer object is of type RunBuffer and instantiated in my
onCreate() method in my activity.
it is not possible. runBuffer can not be an instance of RunBuffer, since it extends Runnable. So you are probably wrapping this in a Thread. Something like:
Thread runBuffer = new Thread(new RunBuffer());
runBuffer.start();
Let's hypothesize the after you set
this.toggleBufferIsActive = false;
the while loop ends correctly. In this case, you are trying to restart, which can not be done. An extract of the Thread.start() method from the doc:
It is never legal to start a thread more than once. In particular, a
thread may not be restarted once it has completed execution.

Thread.sleep() inside android application [duplicate]

I'm working on a memory game for Android and I'm having a problem. When the user taps the second image - if the images are not the same I want the second image to show for 1, 2 seconds.
What I've tried is to sleep for 1-2 sec. the UI thread after the second image is activated - but this doesn't seem to work - the second image doesn't seem to show! (only the first images is showed)
Here's my code:
public void whenTapedImage(View v, int position)
{
i++;
ImageView imgV=(ImageView)v;
if(i%2!=0)
{
firstClick=position;
imgV.setImageResource(im.images.get(firstClick));
}
else
{
secondClick=position;
imgV.setImageResource(im.images.get(secondClick));
try {
Thread.currentThread().sleep(1000);
if(!(im.images.get(firstClick).equals(im.images.get(secondClick))))
{
Toast.makeText(easyGame.this, "Try Again!", Toast.LENGTH_SHORT).show();
im.notifyDataSetChanged();
gridview.setAdapter(im);
gridview.invalidate();
aux=player1Turn;
player1Turn=player2Turn;
player2Turn=aux;
}
else{
done=done+2;
ImageAdapter.keepVisibleViews.add(firstClick);
ImageAdapter.keepVisibleViews.add(secondClick);
if(player1Turn==true)
{
player1Score++;
String score=Integer.toString(player1Score);
score1.setText(score);
}
if(player2Turn==true)
{
player2Score++;
String score=Integer.toString(player2Score);
score2.setText(score);
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
What am I doing wrong?
You must not sleep the UI thread as this would prevent android from delivering any other events to your activity's UI.
Instead, do something such as use a timer and have the timer's method use the run on ui thread facility to make the desired postponed change.
For robustness you may need to implement a state machine (either formally, or in effect) to keep track of what is supposed to be happening - you'll need to decide if the current delay should be aborted or enforced if another button is pushed, and make the state machine treat that appropriately.
This is similar to Waiting in android app
Try following the solution posted there and use the Timer Class

ANR timeout too long

I think I'm being a bit daft here, but I don't understand why I'm getting faulty ANR timeout values.
Example one:
public void onClick(View v) {
while(true);
}
I run this code and trigger a touch event on another view. I will get the ANR after ten seconds, whereas I expected five seconds.
Example two:
public void onClick(View v) {
try {
Thread.sleep(60*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Again, I run the code and trigger a touch event. This time I will not get an ANR at all.
Any ideas of what is going on?

How I can use a handler to change the ImageView's picture after 2 sec, and 5?

I have an ImageView, what shows one picture . I tried to use a thread, but it doesn't change the picture. Then I tried a handler, but it doesn't treat the sleep(int) method, so I can't increase the time, what elapsed. How can I make it? Can you write an example please?
Here is my original code:
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Thread timer = new Thread() {
public void run() {
int time = 0;
while (time <= 7000) {
try {
sleep(100);
time =+ 100;
if(time == 2000) {
radar.setImageResource(R.drawable.radar_full);
}
if(time == 5000) {
radar.setImageResource(R.drawable.radar_50);
}
if(time == 7000) {
radar.setImageResource(R.drawable.radar_found);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
};
timer.start();
};
};
Here are a couple of tutorials for you:
Android GUI thread timer sample
A Stitch in Time
It appears that you need to learn more about Threads and Handlers in general. However, it's worth pointing out that you cannot update a UI element from within a Thread, which is what I'm guessing you tried to do; UI updating (such as changing the content of an ImageView) must be done within the UI thread. Therefore, updating the image inside a Handler on the UI thread was going in the right direction. You just need a way to call that Handler at timed intervals, and the tutorial above demonstrates one such way, by simply posting messages to the Handler.

Categories

Resources