How to send out pointer event in Android

蓝咒 提交于 2019-12-08 18:03:16

问题


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.


回答1:


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.




回答2:


Use OnGlobalLayoutListener, it works perfectly for me.



来源:https://stackoverflow.com/questions/8600299/how-to-send-out-pointer-event-in-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!