【问题标题】:How to send out pointer event in Android如何在Android中发送指针事件
【发布时间】:2011-12-22 06:46:43
【问题描述】:

我正在尝试检测 Android 中的虚拟键盘高度。

我发现了一个类似的话题:Get the height of virtual keyboard in Android

看来作者找到了一种检测高度的方法:

我找到了获得它的方法。在我请求打开虚拟键盘后,我 发送我生成的指针事件。他们的y坐标从 设备的高度并减小。

我不明白该怎么做。

【问题讨论】:

    标签: android events android-softkeyboard


    【解决方案1】:

    我将使用您发布的链接中提供的代码:

    // Declare Variables
    
    int softkeyboard_height = 0;
    boolean calculated_keyboard_height;
    Instrumentation instrumentation;
    
    // Initialize instrumentation sometime before starting the thread
    instrumentation = new Instrumentation();
    

    mainScreenView 是您的基本视图,您的活动视图。 m(ACTION_DOWN) 和m1(ACTION_UP) 是使用Instrumentation#sendPointerSync(MotionEvent) 调度的触摸事件。逻辑是调度到显示键盘的位置的 MotionEvent 将导致以下SecurityException

    java.lang.SecurityException:注入到另一个应用程序需要 INJECT_EVENTS 权限

    因此,我们从屏幕底部开始,在循环的每次迭代中向上(通过递减y)。对于一定数量的迭代,我们将得到一个 SecurityException(我们将捕获它):这意味着 MotionEvent 正在键盘上发生。当y 变得足够小时(当它刚好在键盘上方时),我们将跳出循环并使用以下方法计算键盘的高度:

    softkeyboard_height = mainScreenView.getHeight() - y;
    

    代码:

    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):

    调度一个指针事件。在收件人之后的某个时间完成 已从其事件处理中返回,尽管它可能没有 完全完成对事件的反应——例如,如果它 因此需要更新其显示,它可能仍在 这样做的过程。

    【讨论】:

    • 这是一个公共 API 吗?我找不到关于 INTERNAL_POINTER_META_STATE 的文档。
    • @rid 很抱歉。 INTERNAL_POINTER_META_STATE 是一个整数常量。出于问题的目的,使用任何整数值都可以。我已经编辑了上面的代码。感谢您指出。
    • 不过,在任何未来版本的 Android 中,如果该功能有机会消失,使用它是否安全? 1 是否保证始终相同?它是否由 Google 正式记录在任何地方?你能依赖它而不用担心产生脆弱的代码吗?
    • @rid 关于这个功能很快就会消失:我猜no。我们指望的 SecurityException 因为缺少权限而被抛出:INJECT_EVENTS。此权限只能通过系统应用程序获得:Romain Guy 确认此hereCan you rely on this without fear of producing brittle code? 严格来说,这是一个典型的 hack。使用它,但当它松懈时要做好准备。
    • @rid 1 是有面子的。它不参与程序的逻辑。它映射到KeyEvent.META_SHIFT_ON。如果您使用未映射的值感觉更好,请使用零。但我不能推荐一个值,因为它们都只是填充 ...。第六个参数可以采用 KeyEvent.META_X 形式的值。 Shift / alt / ctrl / caps-on 等组成元/修饰键。
    【解决方案2】:

    使用 OnGlobalLayoutListener,它非常适合我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-20
      • 2015-11-19
      • 1970-01-01
      • 2021-04-04
      • 1970-01-01
      • 1970-01-01
      • 2013-04-22
      相关资源
      最近更新 更多