7

I'm new in Android programming so I am asking for your help in my problem. I am trying to measure in seconds/milliseconds the amount of time between a MouseEvent.ACTION_DOWN and MouseEvent.ACTION_UP.

@Override
public boolean onTouchEvent(MotionEvent event) {
    long start=0;
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        // manage down press
        start=System.nanoTime();//START
        System.out.println("START");
    }
    else if (event.getAction() == MotionEvent.ACTION_MOVE) {
        // manage move
        System.out.println(event.getRawX()+","+event.getRawY());
    }
    else {
        // manage up
        long finish=System.nanoTime()//FINISH
        long seconds = (finish-start) / 1000000000;//for seconds
        Toast.makeText(this, "FINISH, duration: "+seconds, Toast.LENGTH_SHORT).show();
        System.out.println("FINISH, duration: "+seconds);
    }
    return true;
}




Logcat:
03-19 04:04:27.140: I/System.out(4348): START
03-19 04:04:27.160: I/System.out(4348): 517.0,280.0
03-19 04:04:27.190: I/System.out(4348): 517.0,280.0
03-19 04:04:27.200: I/System.out(4348): 517.0,280.0
03-19 04:04:27.220: I/System.out(4348): 517.0,280.0
03-19 04:04:27.250: I/System.out(4348): 517.0,280.0
03-19 04:04:27.260: I/System.out(4348): 517.0,280.0
03-19 04:04:27.300: I/System.out(4348): 517.0,280.0
03-19 04:04:27.310: I/System.out(4348): 517.0,280.0
03-19 04:04:27.330: I/System.out(4348): FINISH, duration: 16545

My problem consist in fact that seconds variable doesn't show what I want, I even don't know if its measuring correctly.For the above example duration was 16545 (???!?!?) but it should have been between 1-3 seconds.What shall I do to measure correctly in seconds or milliseconds the time between two MotionEvents or what am I wrong in my example ? Thank you !

Rahul garg
  • 9,202
  • 5
  • 34
  • 67
Matey
  • 107
  • 1
  • 1
  • 4

4 Answers4

12

A MotionEvent has a timestamp. Use getEventTime() to access it.

In fact, since there is no guarantee that the MotionEvent is delivered immediately to your code, this timestamp is more accurate than any times you get from System.getCurrentTimeMillis().

CvR
  • 151
  • 1
  • 7
  • 1
    +1 This, used with `android.os.SystemClock.uptimeMillis()` is actually the correct solution to finding the time between down and up events. – Nick Hartung Jan 12 '14 at 20:45
10
long startTime;
public boolean onTouchEvent(MotionEvent event) {

    if (event.getAction() == MotionEvent.ACTION_DOWN) 
        startTime = System.nanoTime();    

    else if (event.getAction() == MotionEvent.ACTION_UP) {
        long elapseTime = System.nanoTime() - startTime;
        //do whatever u want with elapseTime now, its in nanoseconds
    }
}
Rahul garg
  • 9,202
  • 5
  • 34
  • 67
  • Thank you, looking at your code I discovered my fault: variable long start should be declared global, not local in my function, thank you very much ! – Matey Mar 19 '12 at 02:51
  • 3
    You should use `System.nanoTime()` instead of `System.currentTimeMillis()`. Please read javadoc for both functions, it is said that `currentTimeMillis()` should not be used for measuring intervals because it might be adjusted at runtime. – keaukraine Mar 05 '13 at 13:36
  • Thanks keaukraine, accomodated changes to use nanoTime() – Rahul garg Aug 16 '13 at 07:32
  • There is a problem with this answer - it will just tag the time that the event is processed, not when it is generated - thus it depends on things like thread contention and can be way off. CvR's answer shows the right way to get the timestamp - use `MotionEvent.getEventTime()` instead (this internally uses System.nanoTime()), but does it when the event is generated. – Peter Jul 28 '22 at 14:26
1

Here is the solution described by @CvR:

private long startTimeInMilliSec;
@Override 
public boolean onTouchEvent(MotionEvent event) {

    if (event.getAction() == MotionEvent.ACTION_DOWN) 
        startTimeInMilliSec = event.getEventTime();    

    else if (event.getAction() == MotionEvent.ACTION_UP) {
        long elapsedTime = event.getEventTime() - startTimeInMilliSec;
        //do whatever u want with elapsedTime now, its in milliseconds 
    } 
} 
Phileo99
  • 5,581
  • 2
  • 46
  • 54
1

Each event also have getDownTime() method. So when you received MotionEvent.ACTION_UP you can simple use

event.getDownTime() - event.getEventTime()

to calculate elapsed time.

Taras Lozovyi
  • 876
  • 9
  • 15