I see that Xamarin has docs for Creating a Gesture Listener but nothing about 'shaking' the device only 'fling' on the screen. I'm wondering if Xamarin for Android is able to listen for shake gestures? Does any one know or has anyone tried? Thank you in advance.
Here is a complete example that uses Android.Hardware.ISensorEventListener
to detect a shake gesture. You should be able to drop this into your own project(s) without any hassle.
[Activity (Label = "ShakeDetection", MainLauncher = true)]
public class MainActivity : Activity, Android.Hardware.ISensorEventListener
{
bool hasUpdated = false;
DateTime lastUpdate;
float last_x = 0.0f;
float last_y = 0.0f;
float last_z = 0.0f;
const int ShakeDetectionTimeLapse = 250;
const double ShakeThreshold = 800;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
SetContentView (Resource.Layout.Main);
// Register this as a listener with the underlying service.
var sensorManager = GetSystemService (SensorService) as Android.Hardware.SensorManager;
var sensor = sensorManager.GetDefaultSensor (Android.Hardware.SensorType.Accelerometer);
sensorManager.RegisterListener(this, sensor, Android.Hardware.SensorDelay.Game);
}
#region Android.Hardware.ISensorEventListener implementation
public void OnAccuracyChanged (Android.Hardware.Sensor sensor, Android.Hardware.SensorStatus accuracy)
{
}
public void OnSensorChanged (Android.Hardware.SensorEvent e)
{
if (e.Sensor.Type == Android.Hardware.SensorType.Accelerometer)
{
float x = e.Values[0];
float y = e.Values[1];
float z = e.Values[2];
DateTime curTime = System.DateTime.Now;
if (hasUpdated == false)
{
hasUpdated = true;
lastUpdate = curTime;
last_x = x;
last_y = y;
last_z = z;
}
else
{
if ((curTime - lastUpdate).TotalMilliseconds > ShakeDetectionTimeLapse) {
float diffTime = (float)(curTime - lastUpdate).TotalMilliseconds;
lastUpdate = curTime;
float total = x + y + z - last_x - last_y - last_z;
float speed = Math.Abs(total) / diffTime * 10000;
if (speed > ShakeThreshold) {
Toast.MakeText(this, "shake detected w/ speed: " + speed, ToastLength.Short).Show();
}
last_x = x;
last_y = y;
last_z = z;
}
}
}
}
#endregion
}
The above activity implements the Android.Hardware.ISensorEventListener
interface and then registers it through the SensorManager
. The actual sensor events (shake etc) are piped into OnSensorChanged
; this is where we hold the logic for our shake detection code.
I've based this answer on this one but have made a few modifications to it. Firstly, this answer uses ISensorEventListener rather than ISensorListener (which was deprecated in API level 3). And you'll find start gesture detection included (through hasUpdated
) and some variables to control the sensitivity of the shake. By playing around with ShakeDetectionTimeLapse
and ShakeDetectionThreshold
you should be able to fine tune it to your needs.
See:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With