Detecting device shakes

A fairly common gesture that can be implemented using sensors is the shake gesture. This can be used to shuffle cards in a game or tracks in a playlist.

How to do it...

To detect a shake, we will need to record the data from the accelerometer and determine whether a shake has occurred:

  1. First, we implement the ISensorEventListener interface, and register it with the manager:
    var manager = SensorManager.FromContext(this);
    var type = SensorType.Accelerometer;
    var accelerometer = manager.GetDefaultSensor(type);
    manager.RegisterListener(
      this, accelerometer, SensorDelay.Fastest);
  2. Then, we will need a few fields that will store the values across the accelerometer events:
    private int lastUpdate;
    private float lastX;
    private float lastY;
    private float lastZ;
  3. As we are also going to process shakes, we will need a field to hold the shake related data:
    private int lastShake;
  4. In the OnSensorChanged() method, we ensure that we only process the events after a reasonable interval of time has passed:
    const int EventTimeLimit = 100;
    var current = System.Environment.TickCount;
    var updateDelta = current - lastUpdate;
    if (updateDelta < EventTimeLimit) {
      return;
    }
  5. Then, we calculate the distance by which the device has moved to detect a shake gesture:
    const int ShakeThreshold = 350;
    var x = e.Values[0];
    var y = e.Values[1];
    var z = e.Values[2];
    var delta = x + y + z - lastX - lastY – lastZ;
    var speed = Math.Abs(delta) / updateDelta * 1000;
    if (speed > ShakeThreshold) {
      lastShake = current;
      // there was a shake
    }
  6. We ensure that we update the fields with the latest values from the sensor so that we can start checking for another shake:
    lastUpdate = current;
    lastX = x;
    lastY = y;
    lastZ = z;

How it works...

Just like we can process touch events to detect touch gestures, we can process sensor data to detect device gestures. One gesture can be that when the user shakes the device, we shuffle tracks in a playlist or move on-screen objects.

Tip

Encapsulating touch or device gesture detection logic allows the logic to be reused across apps and helps reduce maintenance efforts.

If we want to implement a shake detector, we make use of the accelerometer, and track the amount of change the device experiences every few milliseconds. If the direction changes rapidly, then the user is shaking the device.

The way we detect this is by storing the old accelerometer values and then comparing the new values. When the difference between the values over a time period reaches a certain threshold, then we record a shake.

There's more...

We can extend this model to only record a shake gesture after a few shakes have already occurred. This reduces the chance of incorrectly detecting a shake if the user makes a sudden movement. To do this, we count the number of shakes every time the device is shaken, and after a certain number of times, we actually record the shake.

First, we change the shake detection logic to rather count the shakes, reporting only after it reaches a certain number:

const int ShakesRequired = 3;
if (speed > ShakeThreshold) {
  lastShake = current;
  shakeCount++;
  if (shakeCount > ShakesRequired) {
    // there was a shake
    shakeCount = 0;
  }
}

To prevent the number of shakes from growing continuously, we can reset the counter after a short period of no shakes:

const int ShakeTimeLimit = 500;
if (shakeDelta > ShakeTimeLimit) {
  shakeCount = 0;
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.183.1