Long Press handing of D Pad center button via TV remote control

5.7k views Asked by At

I am working on TV application using Amazon Fire Stick TV. I need to handle long press event for the Dpad center button via TV remote control. For the Dpad center button, only I receive a call to onKeyDown() multiple times if I long press the DPad center button.

I do not receive any call to OnKeyUp() methods and onLongKeyPress() methods of the Activity while trying to long press the DPad center button. Is this a bug?

My compile SDK version is '23'.

2

There are 2 answers

0
Isha Dhawan On BEST ANSWER

I solved it by handling KEYCODE_DPAD_CENTER keyevent in the dispatchKeyEvent(KeyEvent event) like this:

@Override
public boolean dispatchKeyEvent(KeyEvent event) {

    int action = event.getAction();
    int keyCode = event.getKeyCode();

    switch (keyCode) {
        case KeyEvent.KEYCODE_DPAD_CENTER:
            Log.d(TAG,"Down time is" + event.getDownTime()+"with action:" + event.getAction()+ "with repeat count"+ event.getRepeatCount()+"with long press"+ event.isLongPress());
            if (action == KeyEvent.ACTION_DOWN && event.isLongPress()) {
                Log.d(TAG,"LOng pres Down time is" + event.getDownTime());
                Log.d(TAG, "Inside long press of Dpad center event");
                onCenter();
                return true;
            }

        default:
            return super.dispatchKeyEvent(event);
    }
}
2
Koerfer_P On

Isha Dhawan I have found a little hack to handle a Longpress Key Event:

I did the following. I created a long value to store my last event down time. In addiotion I created a delta member do determine when the LongPress event should be fired:

private long mLastKeyDownTime = 0;
private long mPressedDelta = 1000;

and when pressing on center I check if enough time passed since the press started to dispatch a longpress event:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    boolean handled = false;
    switch (keyCode) {
        case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
            break;

        case KeyEvent.KEYCODE_MEDIA_REWIND:
            break;

        case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
            break;

        case KeyEvent.KEYCODE_DPAD_CENTER:
            handled = true;
            long time = SystemClock.uptimeMillis();
            if (mLastKeyDownTime + mPressedDelta <= time) {
                onCenterLongress();
            }
            mLastKeyDownTime = event.getDownTime();
            onCenter();
            break;

        case KeyEvent.KEYCODE_DPAD_LEFT:
            handled = true;
            onLeft();
            break;

        case KeyEvent.KEYCODE_DPAD_RIGHT:
            handled = true;
            onRight();
            break;

        case KeyEvent.KEYCODE_DPAD_UP:
            handled = true;
            onUp();
            break;

        case KeyEvent.KEYCODE_DPAD_DOWN:
            handled = true;
            onDown();
            break;

        case KeyEvent.KEYCODE_BACK:
            handled = true;
            onBack();
            break;

        case KeyEvent.KEYCODE_MENU:
            handled = true;
            if (event.getDownTime() == mLastKeyDownTime) {
                break;
            }
            mLastKeyDownTime = event.getDownTime();
            onMenu();
            break;
    }
    return handled || super.onKeyDown(keyCode, event);
}

I know this isn´t the most elegant solution but I think it will do what you´d like it to do. The multiple calls to onKeyDown(..) are caused by the private SDK Amazon uses for handling KeyInput from the remote.