タッチペンの手のひらによるタップを拒否する

ユーザーがタッチペンを使用して描画、書き込み、またはアプリの操作を行うと、手のひらが画面に触れることがあります。このタッチイベントが、手のひらでの偶発的なタッチとして認識されて無視される前に、アプリに報告される場合があります。

手のひらのタップを特定して無視する

アプリは、不要なタッチイベントを識別して無視する必要があります。Android は、MotionEvent オブジェクトをアプリにディスパッチすることにより、手のひらでのタッチをキャンセルします。

  • アプリにディスパッチされた MotionEvent オブジェクトを調べます。MotionEvent API を使用してイベント プロパティ(アクションとフラグ)を判別します。

    • シングル ポインタ イベント - ACTION_CANCEL を確認します。Android 13 以降では、FLAG_CANCELED についても確認します。
    • マルチポインタ イベント - Android 13 以降では、ACTION_POINTER_UPFLAG_CANCELED を確認します。
  • ACTION_CANCEL プロパティと ACTION_POINTER_UP/FLAG_CANCELED プロパティを持つモーション イベントを無視します。

1. モーション イベント オブジェクトを取得する

アプリに OnTouchListener を追加します。

Kotlin

val myView = findViewById<View>(R.id.myView).apply {
    setOnTouchListener { view, event ->
        // Process motion event.
    }
}

Java

View myView = findViewById(R.id.myView);
myView.setOnTouchListener( (view, event) -> {
    // Process motion event.
});

2. イベント アクションとフラグを決定する

ACTION_CANCEL を確認します。これは、すべての API レベルでのシングル ポインタ イベントを表します。Android 13 以降では、ACTION_POINTER_UPFLAG_CANCELED. を確認します。

Kotlin

val myView = findViewById<View>(R.id.myView).apply {
    setOnTouchListener { view, event ->
        when (event.actionMasked) {
            MotionEvent.ACTION_CANCEL -> {
                //Process canceled single-pointer motion event for all SDK versions.
            }
            MotionEvent.ACTION_POINTER_UP -> {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
                   (event.flags and MotionEvent.FLAG_CANCELED) == MotionEvent.FLAG_CANCELED) {
                    //Process canceled multi-pointer motion event for Android 13 and higher.
                }
            }
        }
        true
    }
}

Java

View myView = findViewById(R.id.myView);
myView.setOnTouchListener( (view, event) -> {
    switch (event.getActionMasked()) {
        case MotionEvent.ACTION_CANCEL:
            // Process canceled single-pointer motion event for all SDK versions.
        case MotionEvent.ACTION_UP:
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
               (event.getFlags() & MotionEvent.FLAG_CANCELED) == MotionEvent.FLAG_CANCELED) {
                //Process canceled multi-pointer motion event for Android 13 and higher.
            }
    }
    return true;
});

3. 操作を元に戻す

手のひらでのタップを識別した場合、操作による画面上の効果を元に戻すことができます。

手のひらでのタップなどの意図しない入力を元に戻すには、アプリでユーザー操作の履歴を保持する必要があります。履歴を維持する方法の例については、Android アプリでのタッチペン サポートの強化 Codelab の基本的な描画アプリを実装するをご覧ください。

要点

  • MotionEvent: タッチイベントと移動イベントを表します。イベントを無視するかどうかを決定するために必要な情報が含まれています。
  • OnTouchListener#onTouch(): MotionEvent オブジェクトを受け取ります。
  • MotionEvent#getActionMasked(): モーション イベントに関連付けられたアクションを返します。
  • ACTION_CANCEL: 操作を元に戻す必要があることを示す MotionEvent 定数。
  • ACTION_POINTER_UP: 最初のポインタ以外のポインタが上に移動した(つまり、デバイス画面との接続が喪失した)ことを示す MotionEvent 定数。
  • FLAG_CANCELED: ポインタの上移動により意図しないタップイベントが発生したことを示す MotionEvent 定数。Android 13(API レベル 33)以降の ACTION_POINTER_UP および ACTION_CANCEL イベントに追加されました。

結果

アプリは、Android 13 以降の API レベルにおけるマルチポインタ イベントと、すべての API レベルにおけるシングルポインタ イベントで、手のひらでのタップを識別、拒否できるようになりました。

このガイドを含むコレクション

このガイドは、Android 開発の幅広い目標を網羅する、厳選されたクイックガイド コレクションの一部です。

タブレット、折りたたみ式デバイス、ChromeOS デバイスで最適化されたユーザー エクスペリエンスをサポートするようにアプリを有効にします。

ご質問やフィードバックがある場合

よくある質問のページでクイックガイドをご覧になるか、お問い合わせフォームからご意見をお寄せください。