Search code examples
androideventsaccessibilityservice

How to track long press key events in AccessibilityService?


I want to listen to KeyEvents inside my AccessibilityService. The ACTION_DOWN events are successfully triggered inside the onKeyEvent method of the AccessibilityService class.

But it is not receiving the onKeyLongPress event even if call startTracking() on the event. Look at this code:

@Override
protected boolean onKeyEvent(KeyEvent event) {

    if (event.getAction() == KeyEvent.ACTION_DOWN) {

        if (isVolumeKey(event.getKeyCode())) {

            event.startTracking();

            Log.d(LOG_TAG, "Started tracking!");

            return true;
        }

    } else if (event.isLongPress()) {

        // This code is not executing

        Log.d(LOG_TAG, "Received a long press event");

        return true;
    }

    return super.onKeyEvent(event);
}

UPDATE: The onKeyEvent method is only receiving a single ACTION_DOWN but not multiple from the same event. However, the same is possible with Activity.


Solution

  • There is no specific listener to detect long press event in Accessibility Service. However, you can use the Handler with postDelayed() method to achieve this. You can initialise and start handler in KeyEvent.ACTION_DOWN like below.

    if (mLongPressHandler == null) {
                mLongPressHandler = new Handler();
            }
            mLongPressHandler.postDelayed(new Runnable() {
                public void run() {
                    //Your code
                    mLongPressHandler.postDelayed(this, DELAY_VOLUME_LONG_PRESS);
                }
            }, DELAY_VOLUME_LONG_PRESS);
    

    And you can removeCallbacksAndMessages() in KeyEvent.ACTION_UP to remove callbacks from handler.

    mLongPressHandler.removeCallbacksAndMessages(null);
    

    I have done this to detect volume up/down hardware keys long press event.