Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting soft keyboard being open / KeyEvent using a Service

I've read most of the posts here regarding detecting soft keyboards or detecting KeyEvent. I saw methods such as measuring the size of the view. However, the issue of my case is that I'd like to detect whether the soft keyboard is open or KeyEvent using a "service." Is it possible to do it via a service? Or, would it be possible to detect someone is typing in an activity? I'm working on a research and I need to log some activities on a phone, which include detecting typing in an activity. Thanks!

like image 715
Stanley Chang Avatar asked Oct 15 '25 10:10

Stanley Chang


2 Answers

I found a tricky way to "kind of" solve this. However, this requires your user to do something for you if you have that power :) So obviously this will not solve all of your problems.

My tricky way is to use the AccessibilityEvent. You can specify which event you want to listen. One of the events that is related to window size is TYPE_WINDOW_CONTENT_CHANGED ( see below)

public static final int TYPE_WINDOW_CONTENT_CHANGED

Added in API level 14
Represents the event of changing the content of a window and more specifically the sub-tree rooted at the event's source.

Constant Value: 2048 (0x00000800)

As long as your accessibility service of your app is enabled, you will receive this event.

To listen to this event, you have to start your own AccessibilityService. Refer to this to learn how to build one. Then you can specify which accessibility event you want to receive. You can specify them either in an xml file:

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:packageNames="MypackageName"
    android:accessibilityEventTypes="typeWindowStateChanged"
    android:accessibilityFeedbackType="feedbackSpoken"
    android:notificationTimeout="100"
/>

or in the onServiceConnected method:

protected void onServiceConnected() {   
    AccessibilityServiceInfo info = new AccessibilityServiceInfo();    
    info.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
}

Then you will receive the event in the method onAccessibilityEvent(event). However, this method has two drawbacks:

  1. whenever the window state changes, the event is fired.
  2. the user has to enable your accessibility service in [Setting] -> [Accessibility] -> [Services].

Again, this method only works for certain purposes. But it works for the case where you want to detect a soft keyboard "from a service" but not from your activity.

like image 140
Stanley Chang Avatar answered Oct 17 '25 02:10

Stanley Chang


Use this:

boolean isKeyboardOpened() {
    List<AccessibilityWindowInfo> windowInfoList = getWindows();
    for(int k = 0; k < windowInfoList.size(); k++) {
        if(windowInfoList.get(k).getType() == AccessibilityWindowInfo.TYPE_INPUT_METHOD) {
            Log.i(TAG, "keyboard is opened!");
            return true;
        }
    }
    return false;
}

Also use

android:accessibilityFlags="flagRetrieveInteractiveWindows"
like image 23
bko Avatar answered Oct 17 '25 00:10

bko



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!