2011-12-22 16 views
7

Androidで仮想キーボードの高さを検出しようとしています。私は同様のトピック見つけAndroidでポインタイベントを送信する方法

Get the height of virtual keyboard in Android

を著者が、高さを検出する方法を見つけたようだ:

私はそれを取得する方法を発見しました。仮想キーボードを開くように要求すると、私は 私が生成するポインタイベントを送信します。それらのy座標は から始まり、デバイスの高さが減少します。

私はそれを行う方法を理解していません。

答えて

3

私はあなたが投稿したリンクで提供されたコードを使用しています:

// 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)を使用して送出されるタッチイベントです。

java.lang.SecurityException:ロジックはMotionEventが表示されているキーボードが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)

ポインタイベントを送出します。受領者 がイベント処理から戻った後、ある時点で完了しましたが、 がイベントから完全に反応していない可能性があります。たとえば、 が結果としてそのディスプレイを更新する必要がある場合などです。それを行うプロセスは です。

+0

これは公開APIですか?私は 'INTERNAL_POINTER_META_STATE'に関するドキュメントを見つけることができません。 – rid

+0

@rid申し訳ありません。 'INTERNAL_POINTER_META_STATE'は整数定数です。質問の目的のために、任意の整数値を使用すると動作します。上記のコードを編集しました。それを指摘してくれてありがとう。 – Vikram

+0

まだ、Androidの将来のバージョンで機能が消える可能性がなくても、これを使用しても安全ですか?それは常に同じであることが保証されていますか?それはGoogleが正式にどこに文書化されていますか?あなたは脆弱なコードを生成する恐れなしにこれに頼ることができますか? – rid

1

これは、OnGlobalLayoutListenerを使用すると、完璧に動作します。

関連する問題