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.
To detect a shake, we will need to record the data from the accelerometer and determine whether a shake has occurred:
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);
private int lastUpdate; private float lastX; private float lastY; private float lastZ;
private int lastShake;
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; }
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 }
lastUpdate = current; lastX = x; lastY = y; lastZ = z;
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.
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.
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; }