I want to develop an android wear application that listens to the user when the watch is brought near the mouth. How can I detect such motion?
I designed a covid-19 wear app with a similar feature to prevent users from touching their mouth/eyes(face region). You can register the Gravity sensor listener and detect when a user lifts their hand towards the mouth/head area.
private SensorManager mSensorManager;
//register in #onResume
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY), SensorManager.SENSOR_DELAY_NORMAL);
When a user wears the watch, the x-component of gravity measured by the Gravity Sensor is +9.8 when the hand is downward and -9.8 when the hand is upward towards the mouth. These values are reversed when the watch is worn on the right hand. Since the upward or downward values may not be precise, you could leave some room, so instead of 9.8, you could use a GRAVITY THRESHOLD
of (7.0f
). You could also consider the up/down movement successful if it takes less than a threshold of 2000000000
nanoseconds:
// An movement to the mouth and down that takes more than 2 seconds will not be registered (in nanoseconds).
private static final long TIME_THRESHOLD_NS = TimeUnit.SECONDS.toNanos(2);
private static final float HAND_DOWN_GRAVITY_X_THRESHOLD = -.040f;
private static final float HAND_UP_GRAVITY_X_THRESHOLD = -.010f;
@Override
public void onSensorChanged(SensorEvent event) {
detectMouthTouched(event.values[0], event.timestamp);
}
private void detectMouthTouched(float xGravity, long timestamp) {
if ((xGravity <= HAND_DOWN_GRAVITY_X_THRESHOLD)
|| (xGravity >= HAND_UP_GRAVITY_X_THRESHOLD)) {
if (timestamp - mLastTime < TIME_THRESHOLD_NS) {
// Hand is down when yValue is negative.
onFaceTouched(xGravity <= HAND_DOWN_GRAVITY_X_THRESHOLD);
}
mLastTime = timestamp;
}
}
private void onFaceTouched(boolean handDown) {
if (mHandDown != handDown) {
mHandDown = handDown;
}
}