Skip to main content
This tutorial runs an Edge Impulse motion classification model on a Wear OS smartwatch. The app reads the accelerometer through SensorManager, fills a buffer sized to the model’s window, and runs the C++ classifier through JNI each time the buffer is full. Jetpack Compose for Wear OS shows the result on the watch face. The keyword spotting example uses the same buffered approach for audio on a phone.
Round Wear OS watch face listing motion classification labels and confidence scores

Wear OS app showing motion classification results on a round watch face

Prerequisites

  • A motion classification model trained in Edge Impulse on accelerometer data, and optionally gyroscope data
  • Android Studio with NDK 27.0.12077973 and CMake 3.22.1 installed
  • A Wear OS device or emulator running API 30 or later

1. Clone the repository

2. Download TensorFlow Lite libraries

3. Export your model

  1. In Edge Impulse Studio, go to Deployment.
  2. Select Android (C++ library).
  3. Enable EON Compiler to reduce inference time and battery use.
  4. Click Build and download the .zip file.

4. Integrate the model

Extract the downloaded .zip file and copy its contents, except CMakeLists.txt, into app/src/main/cpp/. The folder then looks like this:

5. Match the input frame size

The model expects a fixed number of float values as input. Find the value in model_metadata.h:
Then update MainActivity.kt to match:
If the values don’t match, the classifier returns incorrect results or crashes.

6. Build and run

  1. Open the project in Android Studio.
  2. Select Build -> Make Project.
  3. Connect your Wear OS device or start a Wear OS emulator.
  4. Run the app.
Perform one of your trained movements. The classification result appears on the watch face.

How it works

Sensor setup

The app registers the accelerometer listener in onResume and removes it in onPause, so the sensor doesn’t drain the battery while the app isn’t visible:

Ring buffer collection

Each sensor event writes its x, y, and z values into the buffer. When the buffer is full, the app runs inference and resets the index:

Native inference

The float array crosses the JNI boundary, and the native code passes it to the classifier:

Wear OS UI

The app shows the result in a Jetpack Compose for Wear OS Chip:

Adding gyroscope data

If your model was trained with both accelerometer and gyroscope, register both sensors and write all six values per sample:
The axis order in the buffer must match the order you used when you collected the training data.

Troubleshooting

  • Check that EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE matches your model’s input size.
  • Check that the sensor sampling rate matches your training data. If you trained at a higher rate, change SENSOR_DELAY_NORMAL to SENSOR_DELAY_GAME (about 50 Hz).
  • Check that the axis order in the buffer matches your training data.
  • Keep the unregisterListener call in onPause().
  • Lower the sampling rate to the minimum your model needs.
  • Enable EON Compiler when you build the deployment.
  • Use the emulator’s extended controls to inject sensor data.
  • Test on a physical Wear OS device for realistic sensor data.

Next steps

Resources