20

Well, the question is rather simple - how can i handle left/right/middle click, wheel and (!)hover move in android 2/3/4.

I've been digging on this topic and found the following

  • in api 14 we can handle almost anything with fancy new MotionEvent
  • we also have Open Accessory that seems to be ok with USB mouse since api 12 (still missing bluetooth) (UPD OA backported to 2.3.4)
  • mouse actually works well on tablets with ICS and Honeycomb and cyanogen 2.3.7, but act like just single touch on every button.I wonder is there a way to intercept mouse messages.

Help me please to understand how i can handle bluetooth and usb mouse in most simple and right way in each version of android. Or say its impossible.

UPD2: seems like USB Host only in 3.1+, while USB Accessory useless for this task

mjollneer
  • 1,005
  • 2
  • 19
  • 36
  • Read http://www.zdnet.com/blog/burnette/how-to-use-multi-touch-in-android-2-part-3-understanding-touch-events/1775 and http://developer.android.com/reference/android/view/MotionEvent.html – Pankaj Kumar Oct 03 '12 at 09:07
  • 1
    I looked at those articles, but a haven't found anything new. What are you hinting at? – mjollneer Oct 03 '12 at 09:33

3 Answers3

25

These are my findings:

For Api Level < 9:

  • External mouse primary button is handled just as a normal finger touch. There seems to be no way to detect the mouse.
  • Secondary button is dispatched trough a KeyEvent with KeyEvent.KEYCODE_BACK. No way to distinguish between actual "Back" presses and secondary button presses.

For Api Level 9+:

  • A new method has been added MotionEvent.getSource(). I use this one to detect if input is from mouse.
  • Secondary button is still dispatched through a KeyEvent with KeyEvent.KEYCODE_BACK. On some devices the KeyEvent.getSource() returns InputDevice.SOURCE_MOUSE, so secondary button detection works in some cases.

For Api Level 12+:

  • OnGenericMotionListener has been added. I use this one to detect mouse moves with ACTION_HOVER_MOVE and wheel changes with ACTION_SCROLL.

For Api Level 14+:

  • New method MotionEvent.getButtonState(). I track this one to distinguish if a primary, secondary, tertiary mouse button is pressed when the MotionEvent.getActionMasked() is ACTION_MOVE, ACTION_DOWN or ACTION_UP.

I haven't looked into Api Level 15/16 or the tool type, because I'm able to track all mouse events with what I described above. Would be interesting if anybody has additional information or if I' missing out with 15/16/tooltypes.

Maik
  • 3,419
  • 1
  • 23
  • 34
  • Clear presentation and some new hints)) – mjollneer Oct 08 '12 at 08:13
  • On Samsung devices with API level 23 I still only get an *KeyEvent* and not a *MotionEvent* and there is no way to detect a MousUp event with *OnGenericMotionListener* on _vanilla_ Android devices it works with the *OnGenericMotionListener*. – Roel Jul 10 '17 at 12:21
  • @Maik, This works somewhat, but I noticed a problem. When I hold down the left mouse button and drag the mouse, it only fires ACTION_BUTTON_PRESS once. It does not fire ACTION_HOVER_MOVE or any other actions anymore until I release the left mouse button, so it can't track for moving the mouse while holding down mouse buttons. – Robin Sep 02 '19 at 02:34
  • `ACTION_HOVER_MOVE` will only happen as long as you don't press any buttons. If I remember correctly you should receive `ACTION_MOVE` while a mouse button is pressed. It has been a long time since the last time I looked at this, but there was definitely a way to track it. – Maik Sep 02 '19 at 03:24
  • I just log and return false in OnGenericMotion. Nothing is fired while moving with mouse button held down – Robin Sep 03 '19 at 13:57
  • `ACTION_MOVE` events are delivered through `onTouchEvent()`, not through `onGenericMotionEvent()`. If you still cannot observe it, it can also be related to the device or API level you are testing on. I investigated this on vanilla Android devices running API level 7 - 16. Haven't tested this since, so it can be that the behavior changed yet again. – Maik Sep 04 '19 at 03:09
  • I have onTouchEvent overridden, nothing in the logs. I'm testing on later devices, so u are probably right. – Robin Sep 04 '19 at 07:01
  • Is there a way to detect right click of the mouse, anywhere ? Meaning no matter where it's done while on the app? – android developer Oct 06 '20 at 10:16
1

OK. I think i got a clue. I've read highlights about android 3.x/4.x and realized that...

  1. we can use mouse in android 3+, in older versions mouse is device-specific

  2. we can intercept recognized mouse events from any source (BT or USB)...

2.1. ... scroll or hover_move in 3.1+ in onGenericMotionEvent

2.2. ... primary, secondary, and tertiary buttons and hover enter/leave in android 4.0+ (and finally TOOL_TYPE_MOUSE constant)

The other option is to parse pretty lowlevel data from bluetooth socket or usb in host mode.

Am i right? Still wonder if anybody have better solution.

mjollneer
  • 1,005
  • 2
  • 19
  • 36
0

Please, consult the Android SDK documentation, exactly on your own SDK directory: android-sdk/docs/reference/android/view/MotionEvent.html

No Reply
  • 9
  • 1
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 25 '22 at 04:42