Input Methods in Android Development
Adding listeners and handling keyboard input in Android development is essential for interactive user experiences. Learn how to implement View.OnKeyListener, override key events, and create custom Views for efficient input handling. Explore the nuances of working with device sensors and touch controls to enhance your app's functionality.
Download Presentation

Please find below an Image/Link to download the presentation.
The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.
You are allowed to download the files provided on this website for personal or commercial use, subject to the condition that they are used lawfully. All files are the property of their respective owners.
The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.
E N D
Presentation Transcript
Cosc 5/4730 Input Keyboard, touch, controllers, and device sensors
View For most input, you add a custom listener to a View class EditView has a keyboard listener, since it accepts input. You add a listener to a View (widgets) and then it only work for that widget You can t have a listener for a screen Unless the view takes up the entire screen The exception is the Sensor, which is for the device. Most of the activity classes have built-in Touch and key listener. We ll come back to this later.
View (2) There is a View class that you can extend and use to create custom Views For the purpose of this lecture, we ll use an ImageView widget and add listeners View and SurfaceView will be covered later on.
A Note View will need several attributed in order to work with these listeners In the xml you will need to add android:focusable="true" android:focusableInTouchMode="true" android:clickable="true"
View.OnKeyListener For "keyboard" input Implement the View.OnKeyListener And override public boolean onKey(View v, int keyCode, KeyEvent event) Note, that there is not a char field here. You get the KeyCode as a parameter or event.getKeyCode()
View.OnKeyListener (2) What key was pressed? Use event.getMatch(char[] chars) Pass it an array of characters you want to test against. If it matches, then returns that character Else returns \0 Use keycode == KeyEvent. Constants Example: KeyEvent.KEYCODE_0 for Zero Gives you access to any key that was pushed: KEYCODE_CAMERA, KEYCODE_DPAD_LEFT KEYCODE_ENDCALL, KEYCODE_VOLUME_DOWN, etc http://developer.android.com/reference/android/view/KeyEvent.html for a full list.
ViewOnKeyListener (3) Add the listener to the view ImageView in our case iv.setOnKeyListener(new myKeyListener()); When the ImageView has focus, then the keylistener will be called for any key events.
View Overrides When extending a View class you also can override several more You also override them in an activity as well. onKeyDown(int, KeyEvent) Called when a new key event occurs. onKeyUp(int, KeyEvent) Called when a key up event occurs. onTrackballEvent(MotionEvent) Called when a trackball motion event occurs. There is also a touchEvent
Touch Events. There is an OnTouchListener But you can also use the OnClickListener and OnLongClickListener as well. Normally associated with buttons. Note that OnTouchListener appears to be call first, so if you don t consume the event, then the click and/or LongClick are called.
View.OnTouchListener Implement the View.OnTouchListener And override public boolean onTouch(View v, MotionEvent event) return true if event consumed, false otherwise. the event has all the information about the touch event.
View.OnTouchListener (2) MotionEvent getX(), getY() returns the X, Y location of the touch in the Widget Not the position on the screen. getRawX(), getRawY() returns the original raw X and Y coordinate, which is the position on the screen. getAction() Return the kind of action being performed one of either ACTION_DOWN, ACTION_MOVE, ACTION_UP, or ACTION_CANCEL.
Gesture events. There is a GestureDetector and Gesture.SimpleOnGestureListener() From everything I ve seen, you declare a OnTouchListener, that then calls a SimpleOnGestureListener with the Gestures you are interested in. example: public boolean onTouch(View v, MotionEvent event) { if (myGestureDetector.onTouchEvent(event)) return true; //gesture detector consumed the event int action = event.getAction(); //check for touch ACTION_MOVE, etc
SimpleOnGestureListener() On previous slide the myGestureDetector extends the class, instead of implement, since I was looking for only onFling event for swipes There are two interfaces, you can implement to use a real listener GestureDetector.OnDoubleTapListener The listener that is used to notify when a double-tap or a confirmed single-tap occur. GestureDetector.OnGestureListener The listener that is used to notify when gestures occur.
SimpleOnGestureListener() Extend (only the ones you want) or implement the following methods: boolean onDown(MotionEvent e) Notified when a tap occurs with the down MotionEvent that triggered it. boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) Notified of a fling event when it occurs with the initial on down MotionEvent and the matching up MotionEvent. void onLongPress(MotionEvent e) Notified when a long press occurs with the initial on down MotionEvent that trigged it. boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) Notified when a scroll occurs with the initial on down MotionEvent and the current move MotionEvent. void onShowPress(MotionEvent e) The user has performed a down MotionEvent and not performed a move or up yet. boolean onSingleTapUp(MotionEvent e) Notified when a tap occurs with the up MotionEvent that triggered it.
Swipe event using onFling you can do the math to figure out a swipe event across the view Example for Right Swipe: float dX = e2.getX()-e1.getX(); if (Math.abs(dY)<SWIPE_MAX_OFF_PATH && Math.abs(velocityX)>=SWIPE_THRESHOLD_VELOCITY && Math.abs(dX)>=SWIPE_MIN_DISTANCE ) { if (dX>0) { //Right Swipe }
Touch, Gesture, and swipes. To see how all the code for touch, gestures, and swipes works together see the associated code with the lecture.
Touch and keys for the screen An activity has onTouchEvent(MotionEvent event) and key methods built in. You can over ride them. Note, you will need to be careful about do this because of the other widgets maybe need them. Example: If you consume the key events, then how does the EditText work?
Full screen gestures Implement OnGuestureListener and OnDoubleTapListenver (if you want) Using the support v4 library as well. private GestureDetectorCompat mDetector; GestureDetector.OnGestureListener mDetector = new GestureDetectorCompat(this,this); Set the gesture detector as the double tap listener. mDetector.setOnDoubleTapListener(this);
Full screen gestures(2) We still have to use the onTouchEvent method. @Override public boolean onTouchEvent(MotionEvent event){ this.mDetector.onTouchEvent(event); // Be sure to call the superclass implementation return super.onTouchEvent(event); } Now you can detect and deal with gestures that are across multiple widgets, such as Swipes/Flings.
Example code Input goes though most of the input using widgets Input2 sets them for the screen . The code is less in depth and just toasts and logs results.
Supporting Game Controllers Android has built-in support for them. From an Activity/fragment dispatchGenericMotionEvent(android.view. MotionEvent) Called to process generic motion events such as joystick movements. dispatchKeyEvent(android.view.KeyEvent) Called to process key events such as a press or release of a gamepad or D-pad button. From View: onGenericMotionEvent(android.view.MotionEvent) Called to process generic motion events such as joystick movements. onKeyDown(int, android.view.KeyEvent) Called to process a press of a physical key such as a gamepad or D-pad button. onKeyUp(int, android.view.KeyEvent) Called to process a release of a physical key such as a gamepad or D-pad button.
Supporting Game Controllers (2) KeyEvent An object that describes directional pad (D-pad) and gamepad button events. Key events are accompanied by a key code that indicates the specific button triggered, such as DPAD_DOWN or BUTTON_A. You can obtain the key code by calling getKeyCode() or from key event callbacks such as onKeyDown(). MotionEvent An object that describes input from joystick and shoulder trigger movements. Motion events are accompanied by an action code and a set of axis values. The action code specifies the state change that occurred such as a joystick being moved. The axis values describe the position and other movement properties for a specific physical control, such as AXIS_X or AXIS_RTRIGGER. You can obtain the action code by calling getAction() and the axis value by calling getAxisValue().
Do we have Game Controllers? You can check to see if you have a game controller connected by int[] deviceIds = InputDevice.getDeviceIds(); for (int deviceId : deviceIds) { InputDevice dev = InputDevice.getDevice(deviceId); int sources = dev.getSources(); Verify that the device has gamepad buttons, control sticks, or both. if ( ((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) || ((sources & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK)) { //we have a game controller. } }
Do we have Game Controllers? (2) A source type of SOURCE_GAMEPAD indicates that the input device has gamepad buttons (for example, BUTTON_A). Note that this source type does not strictly indicate if the game controller has D-pad buttons, although most gamepads typically have directional controls. A source type of SOURCE_DPAD indicates that the input device has D-pad buttons for example, DPAD_UP A source type of SOURCE_JOYSTICK indicates that the input device has analog control sticks for example, a joystick that records movements along AXIS_X and AXIS_Y
Key Events With the buttons, you use the dispatchKeyEvent( android.view.KeyEvent) from the activity. Figure out if it's the ACTION_DOWN (ie button pressed) or ACTION_UP (button back to original state, ie lifted). As a note the key codes may not match the devices button names. KeyEvent.KEYCODE_BUTTON_X is the left button. KeyEvent.KEYCODE_BUTTON_A is the bottom KeyEvent.KEYCODE_BUTTON_Y is the top KeyEvent.KEYCODE_BUTTON_B is the right button Note, I've found that some devices don't seem to present the right codes for A,B,X and Y.
JoyStick/Dpad It's possible for a device to have both one to act is both joystick and dpad. onGenericMotionEvent(android.view.MotionEvent motionEvent) Then use the getAxisValue to get the information.
Axis Data JoyStick xaxis = motionEvent.getAxisValue(MotionEvent.AXIS_X); yaxis = motionEvent.getAxisValue(MotionEvent.AXIS_Y); Numbers between -1.0 to 1.0 with 0.0 the joystick is in center. 0.0, assumes perfect calibration of the joystick. GamePad xaxis = motionEvent.getAxisValue(MotionEvent.AXIS_HAT_X); yaxis = motionEvent.getAxisValue(MotionEvent.AXIS_HAT_Y); Android reports D-pad UP and DOWN presses as AXIS_HAT_Y events with a range from -1.0 (up), 1.0 (down), and D-pad LEFT or RIGHT presses as AXIS_HAT_X events with a range from -1.0 (left) and 1.0 (right). With 0.0 as center.
API and support Some parts are supported back to API 12 (android 3.1), but API 16 (android 4.1) is the lowest API for some code shown here. The develop pages show how to get backward compact to 3.1 and even 2.3.3 if that is desired. https://developer.android.com/training/game- controllers/compatibility.html
Multiplayer/multi controller. You can connect more then on controller at a time, which allows you to have two more players at the same time. You will need map each controller to each player. InputDevices.getDeviceIds() will give you the full list of device ids, which can be all before "starting" a game to get player 1 controller, etc. KeyEvent and MotionEvent each have a getDeviceID() method, so when an action has taken place you can map between the controller to the player.
addition controller features there is support for both xbox and Playstation controllers or generic controllers with Haptics (vibration) motion sensors lights controller touchpad https://developer.android.com/develop/ui/views/touch-and- input/game-controllers/controller-features
References https://developer.android.com/training/game- controllers/controller-input.html https://developer.android.com/training/game- controllers/compatibility.html https://developer.android.com/training/game- controllers/multiple-controllers.html
Sensor(s) Android is built with ability to handle many sensors ACCELEROMETER accelerometer sensor, which is the acceleration movement of the phone. GYROSCOPE a gyroscope sensor LIGHT a light sensor MAGNETIC_FIELD a magnetic field sensor. ORIENTATION Orientation is space PRESSURE a pressure sensor PROXIMITY an proximity sensor TEMPERATURE A temperature sensor
Android Sensor packages are android.hardware.Sensor; android.hardware.SensorEvent; android.hardware.SensorEventListener; android.hardware.SensorManager; (Easter egg) private SensorManager myManager; private Sensor accSensor; private List<Sensor> sensors; SensorEventListener mySensorListener;
Framework classes and interfaces SensorManager Access and listen to sensors Register and unregister sensor event listeners Acquire orientation information Provides constants for accuracy, data acquisition rates, and calibration 39
Important framework classes Sensor: Determine specific sensor's capabilities SensorEvent: Info about event, including raw sensor data SensorEventListener: Receives notifications about sensor events When sensor has new data When sensor accuracy changes 40
Sensor class types and typical uses Detecting motion (shake, tilt, etc.) TYPE_ACCELEROMETER Monitoring air temperature TYPE_AMBIENT_TEMPERATURE Detecting motion (shake, tilt, etc.) TYPE_GRAVITY Detecting rotation (spin, turn, etc.) TYPE_GYROSCOPE Controlling screen brightness TYPE_LIGHT Monitoring acceleration along single axis TYPE_LINEAR_ACCELERATION Creating a compass TYPE_MAGNETIC_FIELD 41
Using sensors Determine which sensors are available on device Determine an individual sensor's capabilities Maximum range, manufacturer, power requirements, resolution Register sensor event listeners Acquire raw sensor data Also define minimum rate for acquiring sensor data Unregister sensor event listeners 42
Orientation (deprecated) deprecated but this useful as a example. First we need to get a Sensor Manager for the sensors myManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); Now we have two methods to get the Accelerometer GetDefaultSensor, which may return a sensor could be a composite sensor Or to get the raw sensor, get a list of the Sensors for that TYPE and then choose one (normally the first one.)
Orientation (2) Example: sensors = myManager.getSensorList(Sensor.TYPE_ORIENTATION); if(sensors.size() > 0) accSensor = sensors.get(0); OR accSensor = myManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); A Note: Google states this sensor type exists for legacy reasons please use getRotationMatrix() in conjunction with remapCoordinateSystem() and getOrientation() to compute these values instead. This option is shown in the pitchroll2 example on the handout page.
Orientation (2) Create a call back listener for the Sensor. You can use the same listener for more then one sensor. SensorEventListener Override the two methods public void onAccuracyChanged(Sensor sensor, int accuracy) Called when the accuracy changes. public void onSensorChanged(SensorEvent event) Called when the Sensor data changes.
SensorEvent The data is a SensorEvent is based on the Sensor TYPE (ORIENTATION, ACELEROMETER, etc), values[] contains the data Sensor.TYPE_ORIENTATION: All values are angles in degrees. values[0]: Azimuth, angle between the magnetic north direction and the Y axis, around the Z axis (0 to 359). 0=North, 90=East, 180=South, 270=West values[1]: Pitch, rotation around X axis (-180 to 180), with positive values when the z-axis moves toward the y-axis. values[2]: Roll, rotation around Y axis (-90 to 90), with positive values when the x-axis moves toward the z-axis. Important note: For historical reasons the roll angle is positive in the clockwise direction (mathematically speaking, it should be positive in the counter-clockwise direction). Sensor.TYPE_ACCELEROMETER: All values are in SI units (m/s^2) and measure the acceleration applied to the phone minus the force of gravity. values[0]: Acceleration minus Gx on the x-axis values[1]: Acceleration minus Gy on the y-axis values[2]: Acceleration minus Gz on the z-axis
Orientation (3) Lastly add the listener myManager.registerListener(mySensorListener, accSensor, SensorManager.SENSOR_DELAY_GAME); Where AccSensor is the Sensor SENSOR_DELAY_GAME is a suitable time interval for games, which SENSOR_DELAY_NORMAL is for applications, and SENSOR_DELAY_UI is for screen flipping .
And lastly Don t forget to unregister the listener when you are done (free memory and save battery life) myManager.unregisterListener(mySensorListener);
Screen: portrait and landscape Remember when using the sensors that you screen may change from landscape to portrait and vise versa. In the XML you can set the landscape, portrait to prevent screen flipping for each activity android:screenOrientation="portrait android:screenOrientation= landscape"
What's next? google: Concept chapter: 3.1 Sensor basics Practical: 3.1 Working with sensor data 50