开发者

Is android's motion event handling accurate?

Bug

I have a weird bug in my piano app. Sometimes keys (and thus notes) hang. I did a lot of debugging and narrowed it down to what looks like androids inaccuracy of motion event handling:

 DEBUG/(2091): ACTION_DOWN A4
 DEBUG/(2091): KeyDown: A4
 DEBUG/(2091): ACTION_MOVE A4 => A4
 DEBUG/(2091): ACTION_MOVE ignoring
 DEBUG/(2091): ACTION_MOVE A4 => A4
 DEBUG/(2091): ACTION_MOVE ignoring
 DEBUG/(2091): ACTION_MOVE A4 => A4
 DEBUG/(2091): ACTION_MOVE ignoring
 DEBUG/(2091): ACTION_UP B4 //HOW CAN THIS BE????
 DEBUG/(2091): KeyUp: B4
 DEBUG/(2091): Stream is null, can't stop
 DEBUG/(2091): Hanging Note: A4 X=240-287 EventX=292 Y=117-200 EventY=164
 DEBUG/(2091): KeyUp Note:   B4 X=288-335 EventX=292 Y=117-200 EventY=164

Clearly it can be seen here that out of nowhere I suddenly hav开发者_StackOverflow中文版e an ACTION_UP for another note. Shouldn't I definitely get a ACTION_MOVE first?

As shown in the end of the log, it's definitely not an error in region detection, since the ACTION_UP event is clearly in the B4 region.

Logging Implementation details

Every onTouchEvent() call is logged, so the log is accurate.

The relevant pseudo-code for the ACTION_MOVE logging is:

 Key oldKey = Key.get(event.getHistoricalX(), event.getHistoricalY());
 Key newKey = Key.get(event.getX(), event.getY());

Question

Is this normal behaviour for Android (the jumping in coordinates)?

Can a ACTION_UP just occur without any previous ACTION_MOVE towards it's coordinates?


I had a similar issue when I was trying to develop a simple shooter game on Android. The trick I used to solve this may not work if the problem is caused by the hardware, but it's worth a try anyhow.

The general idea is to have an array of "TouchEvents" and iterate through this array over time in a loop. This way, when the device registers multiple and/or simultaneous touch envents, they are stocked linearly in an array, but not handled on the spot. you make sure to handle them one after the other, removing any unsynchronized event to occur.

List<TouchEvent> touchEvents = game.getInput().getTouchEvents();
    int len = touchEvents.size();
    for(int i = 0; i < len; i++) {
        TouchEvent event = touchEvents.get(i);

        if(event.type == TouchEvent.TOUCH_DRAGGED || event.type == TouchEvent.TOUCH_DOWN) ...    

Where : "game.getInput().getTouchEvents()" simply refers to a TouchEvent object and its methods such as getTouchEvent

That did the trick for me, I hope this helps somehow, good luck!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜