How to send out pointer event in Android

I'm trying to detect the virtual keyboard height in Android.

I found a similar topic: Get the height of virtual keyboard in Android

It seems the author found a way to detect the height:

I found a way to get it. After I request to open virtual keyboard, I send pointer event that I generate. their y coordinate starts from height of device and decreases.

I don't understand how to do that.


I'll be using the code provided at the link that you posted:

// Declare Variables

int softkeyboard_height = 0;
boolean calculated_keyboard_height;
Instrumentation instrumentation;

// Initialize instrumentation sometime before starting the thread
instrumentation = new Instrumentation();

mainScreenView is your base view, your activity's view. m (ACTION_DOWN) and m1 (ACTION_UP) are touch events that are dispatched using Instrumentation#sendPointerSync(MotionEvent) . The logic is that a MotionEvent dispatched to where the keyboard is being displayed will cause the following SecurityException :

java.lang.SecurityException: Injecting to another application requires INJECT_EVENTS permission

So, we start at the bottom of the screen and make our way up (by decrementing y ) on every iteration of the loop. For certain number of iterations, we will get a SecurityException (which we'll catch): this would imply that the MotionEvent is happening over the keyboard. The moment y gets small enough (when its just above the keyboard), we'll break out of the loop and calculate the keyboard's height using:

softkeyboard_height = mainScreenView.getHeight() - y;

Code:

Thread t = new Thread(){
        public void run() {
            int y = mainScreenView.getHeight()-2;
            int x = 10;
            int counter = 0;
            int height = y;
            while (true){
                final MotionEvent m = MotionEvent.obtain(
                        SystemClock.uptimeMillis(),
                        SystemClock.uptimeMillis(),
                        MotionEvent.ACTION_DOWN,
                        x, 
                        y,
                        1);
                final MotionEvent m1 = MotionEvent.obtain(
                        SystemClock.uptimeMillis(),
                        SystemClock.uptimeMillis(),
                        MotionEvent.ACTION_UP,
                        x, 
                        y,
                        1);
                boolean pointer_on_softkeyboard = false;
                try {
                    instrumentation.sendPointerSync(m);
                    instrumentation.sendPointerSync(m1);
                } catch (SecurityException e) {
                    pointer_on_softkeyboard = true;
                }
                if (!pointer_on_softkeyboard){
                    if (y == height){
                        if (counter++ < 100){
                            Thread.yield();
                            continue;
                        }
                    } else if (y > 0){
                        softkeyboard_height = mainScreenView.getHeight() - y;
                        Log.i("", "Soft Keyboard's height is: " + softkeyboard_height);
                    }
                    break;
                }
                y--;

            }
            if (softkeyboard_height > 0 ){
                // it is calculated and saved in softkeyboard_height
            } else {
                calculated_keyboard_height = false;
            }
        }
    };
    t.start();

Instrumentation#sendPointerSync(MotionEvent) :

Dispatch a pointer event. Finished at some point after the recipient has returned from its event processing, though it may not have completely finished reacting from the event -- for example, if it needs to update its display as a result, it may still be in the process of doing that.


使用OnGlobalLayoutListener,它对我来说非常合适。

链接地址: http://www.djcxy.com/p/56824.html

上一篇: 在VB.NET中使用typedef的等效方法或解决方法是什么?

下一篇: 如何在Android中发送指针事件