0

I was following Google's Touch Gestures Guide on detecting D-pad key events, but they don't seem to be working.

Here is part of my code:

    public final class ResultActivity extends Activity implements AsyncResponse{
    
    [...] 
    
    @Override
    public boolean onKeyUp(int keycode, KeyEvent event){
       if(keycode == KeyEvent.KEYCODE_DPAD_DOWN){
        //this doesnt get detected
        return true;
       }
       if(keycode == 4){
        //this gets detected
        return true;
       }
       return false;
    }//end onKeyUp

    }//end activity

Yes, I've also tried onKeyDown.

What could be causing this problem?

Community
  • 1
  • 1
kemicofa ghost
  • 16,349
  • 8
  • 82
  • 131

2 Answers2

2

This isn't exactly answering your question, but I think it is a good suggestion. I had the same issue when I was trying to detect keyevents this way. I could only get two of the events to register correctly. After messing around with it for a couple of days, I decided to look for other options and came upon the GestureDetector, tried it, and it worked perfectly. You can find the API docs here for the GestureDetector. I'm also going to give you some code on my own to help out.

This is the way I used the GestureDetector in my code. At the very top, I declared a private GestureDetector:

private GestureDetector gestureDetector;

Then, in the onCreate() method, I call a method that creates the GestureDetector (there is no reason to do it this way over just creating it in the onCreate() method - it just looks cleaner this way and is more organized):

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    gestureDetector = createGestureDetector(this);
}

The createGestureDetector() method looks like this:

private GestureDetector createGestureDetector(Context context) {
    GestureDetector gestureDetectorTemp = new GestureDetector(context, new GestureDetector.OnGestureListener() {
                        //we are creating our gesture detector here
        @Override
        public boolean onDown(MotionEvent motionEvent) {
            return false;
        }

        @Override
        public void onShowPress(MotionEvent motionEvent) {
        }

        @Override
        public boolean onSingleTapUp(MotionEvent motionEvent) {  //onTap
            AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
            am.playSoundEffect(SoundEffectConstants.CLICK);   //if we tap once, play a click sound 
            return false;
        }
        @Override
        public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent2, float distanceX, float distanceY) {
            return false; //this is the wrong kind of scroll
        }
        @Override
        public void onLongPress(MotionEvent motionEvent) {
        }

        @Override
        public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent2, float v, float v2) { //fling = a single slide
            int dx = (int) (motionEvent2.getX() - motionEvent.getX());   //figure out the distance moved horizontally
            int dy = (int) (motionEvent2.getY() - motionEvent.getY());   //figure out the distance moved vertically

            //if dx > 0, moved forward, if dx < 0, moved backward
            //if dy > 0, moved up, if dy < 0, moved down

            return true;
        }
    });

    return gestureDetectorTemp;
}

@Override
public boolean onGenericMotionEvent(MotionEvent event) {
    if (gestureDetector != null) {
        return gestureDetector.onTouchEvent(event);
    }
    return false;
}

You have to make sure to include that onGenericMotionEvent() method that I have at the end there. That is what makes sure that your GestureDetector is notified every time a motion event occurs.

One last thing to note is the returns in the GestureDetector - you return true to consume the event, or false to not consume it. In other words, if you want to override what happens by default, such as closing the app when you slide down, just go into the onFling() event, and if dy < 0, return true. This consumes the event and doesn't send it on to other default methods to act upon.

Alex K
  • 8,269
  • 9
  • 39
  • 57
  • @Grimbode sure. It's a better way to go about detecting all of the touch events, in my opinion. – Alex K Dec 07 '14 at 15:44
  • currently working on the gesturedetector since it could answer my other question (linking it at the end of this comment). I was curious as to why you chose GestureDetector from the android lib and not from the google glass lib. Is there a reason why?http://stackoverflow.com/questions/27251831/recognizerintent-action-recognize-speech-blocked-when-a-tap-occurs – kemicofa ghost Dec 09 '14 at 13:46
  • @Grimbode I've used them for android before - I guess I just stuck with it. You can user whichever one you want. I'm going to go ahead and write an answer on your other question that will solve your problem – Alex K Dec 09 '14 at 20:13
  • I tried out the GestureDetector worked great. However, I did use the one from the glass lib. https://developers.google.com/glass/develop/gdk/touch – kemicofa ghost Dec 09 '14 at 21:59
1

In your code you have KeyEvent.KEYCODE_DPAD_DOWN but your subject says you are after KeyEvent.KEYCODE_DPAD_CENTER (which is for tap).

I don't think DPAD_DOWN is mapped on glass, as swiping down is mapped to KEYCODE_BACK.

so if you are trying to detect a tap use KeyEvent.KEYCODE_DPAD_CENTER or if you are after swiping down use KeyEvent.KEYCODE_BACK.

Ben
  • 1,767
  • 16
  • 32