Processing Key Events

After the insanity of the last section, we deserve something dead simple. Welcome to processing key events.

To catch key events, we implement another listener interface, called OnKeyListener. It has a single method called onKey(), with the following signature:

public boolean onKey(View view, int keyCode, KeyEvent event)

The View specifies the view that received the key event, the keyCode argument is one of the constants defined in the KeyEvent class, and the final argument is the key event itself, which has some additional information.

What is a key code? Each key on the (onscreen) keyboard and each of the system keys has a unique number assigned to it. These key codes are defined in the KeyEvent class as static public final integers. One such key code is KeyCode.KEYCODE_A, which is the code for the A key. This has nothing to do with the character that is generated in a text field when a key is pressed. It really just identifies the key itself.

The KeyEvent class is similar to the MotionEvent class. It has two methods that are relevant for us:

KeyEvent.getAction(): This method returns KeyEvent.ACTION_DOWN, KeyEvent.ACTION_UP, and KeyEvent.ACTION_MULTIPLE. For our purposes we can ignore the last key event type. The other two will be sent when a key is either pressed or released.

KeyEvent.getUnicodeChar(): This returns the Unicode character the key would produce in a text field. Say we hold down the Shift key and press the A key. This would be reported as an event with a key code of KeyEvent.KEYCODE_A, but with a Unicode character A. We can use this method if we want to do text input ourselves.

To receive keyboard events, a View must have the focus. This can be forced with the following method calls:

View.setFocusableInTouchMode(true); View.requestFocus();

The first method will guarantee that the View can be focused. The second method requests that the specific view gets the focus.

Let's implement a simple test activity to see how this works in combination. We want to get key events and display the last one we received in a TextView. The information we'll display is the key event type, along with the key code and the Unicode character, if one would be produced. Note that some keys do not produce a Unicode character on their own, but only in combination with other characters. Listing 4-5 demonstrates how we can achieve all this in a couple of code lines.

Listing 4-5. KeyTest.Java; Testing the Key Event API

package com.badlogic.androidgames;

import android.app.Activity;

import android.os.Bundle;

import android.util.Log;

import android.view.KeyEvent;

import android.view.View;

import android.view.View.OnKeyListener;

import android.widget.TextView;

public class KeyTest extends Activity implements OnKeyListener { StringBuilder builder = new StringBuilder(); TextView textView;

public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); textView = new TextView(this);

textView.setText("Press keys (if you have some)!"); textView.setOnKeyListener(this); textView.setFocusableInTouchMode(true); textView.requestFocus(); setContentView(textView);

^Override public boolean onKey(View view, int keyCode, KeyEvent event) { builder.setLength(o); switch (event.getAction()) { case KeyEvent.ACTION_DOWN: builder.append("down, "); break;

case KeyEvent.ACTION_UP: builder.append("up, "); break;

builder.append(event.getKeyCode()); builder.append(", ");

builder.append((char) event.getUnicodeChar()); String text = builder.toString(); Log.d("KeyTest", text); textView.setText(text);

if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) return false;

else return true;

We start off by declaring that the activity implements the OnKeyListener interface. Next we define two members we are already familiar with: a StringBuilder to construct the text to be displayed and a TextView to display the text.

In the onCreate() method we make sure the TextView has the focus so it can receive key events. We also register the activity as the OnKeyListener via the TextView.setOnKeyListener() method.

The onKey() method is also pretty straightforward. We process the two event types in the switch statement, appending a proper string to the StringBuilder. Next we append the key code as well as the Unicode character from the KeyEvent itself and output it to LogCat as well as the TextView.

The last if statement is interesting: in case the back key is pressed, we return false from the onKey() method, making the TextView process the event. Otherwise we return true. Why differentiate here?

If we were to return true in the case of the back key, we'd mess with the activity life cycle a little. The activity would not be closed, as we decided to consume the back key ourselves. Of course, there are scenarios where we'd actually want to catch the back key so that our activity does not get closed. However, it is strongly advised not to do this unless absolutely necessary.

Figure 4-8 illustrates the output of the activity while I hold down the Shift and A keys on the keyboard of my Droid.

Figure 4-8. Pressing the Shift and A keys simultaneously

There are couple of things to note here:

When you look at the LogCat output, notice that we can easily process simultaneous key events. Holding down multiple keys is not a problem.

Pressing the D-pad and rolling the trackball are both reported as key events.

As with touch events, key events can eat up considerable CPU resources on old Android versions and first-generation devices. However, they will not produce a flood of events.

That was pretty relaxing compared to the previous section, wasn't it?

NOTE: The key processing API is a bit more complex than what I have shown here. For our game programming projects, the information contained here is more than sufficient, though. If you need something a bit more complex, refer to the official documentation on the Android Developers site.

0 0

Post a comment