Using a gamepad in Android
I've recently had the pleasure of messing about with some of the codelabs created by the Google Play Games team to demonstrate their functionality. At the same time, I also got my hands on a rather fun Moga Pro game controller, which can connect to Android phones and tablets via Bluetooth. Getting the two to work together was actually very easy, so I just wanted to note down a quick example for anyone trying to do something similar!
When it comes to the gamepad input itself, there are a couple of options. Moga, along with other controller suppliers, have their own SDK to download and integrate. However, to get something going you don't really need that at all - the standard human interface device functionality in Android SDK level 12 and above includes support for gamepads and game controllers.
From this point of view a gamepad is just a series of keys and joysticks. By default, once a pad is paired with an Android device, interacting with it causes events to be sent to the application and view that have focus - so you can generally navigate around, press buttons and so forth. This focus is worth noting: if we want to receive events in a custom view (as used in a game), it will need focus. To do that we can add a <requestFocus /> tag in the layout to the view, and set setFocusable(true); in the View constructor.
To actually receive the events we just need to implement the appropriate functions. For the joystick it is onGenericMotionEvent.
When the joystick is moved this function is called with a MotionEvent, as with onTouch events. In the function we filter for joystick events and extract the positions on the X and Y axes. The value is between -1 and 1 in each direction, with the rest point at 0. This happens to fit pretty well with what we needed for my little dot view - the divide by 4 is just to limit the bounds the dot moves to.
Similarly to this, each button on the device will fire a KeyEvent to the onKeyDown function:
Here we return true if we consume the event, or pass it on to the super class for processing if not, so the pad could be used to interact with other views. In general though we'll want to suppress the events we're actually using so there aren't any unexpected interactions.
Each button is registered with a different keycode, so we can look for A and B for this little view. This is where it can get tricky with different gamepads though - not every device is necessarily going to report the same mappings keycodes for similarly placed buttons, so it may be worth testing, and perhaps supplying different "maps" for popular controllers when building a game.
Overall, very straightforward! There's a gist of the complete view these snippets were taken from as well!