Android 12 Developer Preview is here! Try it out, and give us your feedback!

Physical buttons

A wearable device typically contains one or more physical buttons, also known as stems. Wear OS devices always have, at minimum, one button (the power button). Beyond that, zero or more multifunction buttons might be present.

In your app, you can assign multifunction buttons to actions. For example, a fitness app could start or pause a workout via these buttons:

For suitable use cases and design considerations, review the Wear OS design guidelines.

In this guide, you will learn how to retrieve information about available multifunction buttons on a device and how to process button presses.

Button metadata

To get extra information about the buttons on a device, use the API defined in the Wear Input AndroidX library. Add the following dependency in your app module’s build.gradle file.

dependencies {
implementation "androidx.wear:wear-input:1.0.0"
}

Number of buttons

To find out how many buttons are available on the device, use the WearableButtons.getButtonCount() method. This method includes the power button, so if the method returns a value greater than one, then there are multifunction buttons available for use. To get an accurate count of all assignable multifunction buttons, remember to subtract one from the count, since the first button is always the power button.

Keycodes for button presses

Each button is mapped to an int constant from the KeyEvent class, as shown in the following table:

Button KeyEvent
MF button 1 KEYCODE_STEM_1
MF button 2 KEYCODE_STEM_2
MF button 3 KEYCODE_STEM_3

The following example code shows how to get the available button count:

Kotlin

val count = WearableButtons.getButtonCount(context)

if (count > 1) {
    // There are multifunction buttons available
}

val buttonInfo = WearableButtons.getButtonInfo(activity, KeyEvent.KEYCODE_STEM_1)

if (buttonInfo == null) {
    // KEYCODE_STEM_1 is unavailable
} else {
    // KEYCODE_STEM_1 is present on the device
}

Java

int count = WearableButtons.getButtonCount(context);

if (count > 1) {
  // There are multifunction buttons available
}

WearableButtons.ButtonInfo buttonInfo =
  WearableButtons.getButtonInfo(activity, KeyEvent.KEYCODE_STEM_1);

if (buttonInfo == null) {
  // KEYCODE_STEM_1 is unavailable
} else {
  // KEYCODE_STEM_1 is present on the device
}

Handle button presses

There are a number of possible button keycodes that your app can handle:

  • KEYCODE_STEM_1
  • KEYCODE_STEM_2
  • KEYCODE_STEM_3

Your app can receive these key codes and convert them to specific in-app actions.

To handle a button press, implement the onKeyDown() method.

For example, this implementation responds to a button press to control actions in an app:

Kotlin

// Activity
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
    return if (event.repeatCount == 0) {
        when (keyCode) {
            KeyEvent.KEYCODE_STEM_1 -> {
                // Do stuff
                true
            }
            KeyEvent.KEYCODE_STEM_2 -> {
                // Do stuff
                true
            }
            KeyEvent.KEYCODE_STEM_3 -> {
                // Do stuff
                true
            }
            else -> {
                super.onKeyDown(keyCode, event)
            }
        }
    } else {
        super.onKeyDown(keyCode, event)
    }
}

Java

@Override
// Activity
public boolean onKeyDown(int keyCode, KeyEvent event){
  if (event.getRepeatCount() == 0) {
    if (keyCode == KeyEvent.KEYCODE_STEM_1) {
      // Do stuff
      return true;
    } else if (keyCode == KeyEvent.KEYCODE_STEM_2) {
      // Do stuff
      return true;
    } else if (keyCode == KeyEvent.KEYCODE_STEM_3) {
      // Do stuff
      return true;
    }
  }
  return super.onKeyDown(keyCode, event);
}

Determine the button positions

The AndroidX Library provides two methods that describes the location of a button:

Note: We recommend that you not use textual descriptors when describing buttons and their functions. Use visual indicators instead. However, there may be some cases in which describing a button makes more sense.

The above methods were designed for simple descriptions. If these APIs do not suit your app’s needs, you can also use the WearableButtons.getButtonInfo() API to get the location of the button on the screen and handle it in a more cusomized way. For more information on the APIs, see the Wear API reference.