2

I was trying to implement some sort of handler to the Accelerometer.Shaken event and then I discovered that this event isn't supported yet on Windows 10, as can be seen from the answer here.

Now, even though the shaken event doesn't work, the Accelerometer.ReadingChanged event works just fine. So I was thinking, would it be possible to manually detect a shake gesture from that data? I mean, it's probably possible, but I really wouldn't know where to start, does anyone have an idea?

You get the X, Y and Z coordinates every x milliseconds, there must be some way to calculate a shake gesture from that data.

Thanks for your help!

2
  • You can see it move. What kind of movement correlates to a "shake" is up to you to decide and implement. A tablet is a lot harder to shake than a small phone. Well, unless you drop it and it bounces :) Commented Jan 29, 2016 at 22:29
  • @HansPassant Yeah I think I could add some sort of settings to let the user decide the threshold level to reach before the custom Shaken event is raised, thanks for the suggestion! Commented Jan 30, 2016 at 14:34

1 Answer 1

3

Never mind, I ended up writing my own class to solve the problem, I'll leave it here in case it gets useful for someone else:

/// <summary>
/// A static class that manages the Shaken event for the Accelerometer class
/// </summary>
public static class CustomAccelerometer
{
    // The minimum acceleration value to trigger the Shaken event
    private const double AccelerationThreshold = 2;

    // The minimum interval in milliseconds between two consecutive calls for the Shaken event
    private const int ShakenInterval = 500;

    private static bool _AccelerometerLoaded;

    private static Accelerometer _DefaultAccelerometer;

    /// <summary>
    /// Gets the current Accelerometer in use
    /// </summary>
    private static Accelerometer DefaultAccelerometer
    {
        get
        {
            if (!_AccelerometerLoaded)
            {
                _AccelerometerLoaded = true;
                _DefaultAccelerometer = Accelerometer.GetDefault();
            }
            return _DefaultAccelerometer;
        }
    }

    private static DateTime _ShakenTimespan = DateTime.Now;

    private static bool _Enabled;

    /// <summary>
    /// Gets or sets whether or not the Accelerometer is currently enabled and can raise the Shaken event
    /// </summary>
    public static bool Enabled
    {
        get { return _Enabled; }
        set
        {
            if (_Enabled != value && DefaultAccelerometer != null)
            {
                if (value) DefaultAccelerometer.ReadingChanged += _DefaultAccelerometer_ReadingChanged;
                else DefaultAccelerometer.ReadingChanged -= _DefaultAccelerometer_ReadingChanged;
            }
            _Enabled = value;
        }
    }

    // Handles the ReadingChanged event and raises the Shaken event when necessary
    private static void _DefaultAccelerometer_ReadingChanged(Accelerometer sender, AccelerometerReadingChangedEventArgs args)
    {
        double g = Math.Round(args.Reading.AccelerationX.Square() + args.Reading.AccelerationY.Square() + args.Reading.AccelerationZ.Square());
        if (g > AccelerationThreshold && DateTime.Now.Subtract(_ShakenTimespan).Milliseconds > ShakenInterval)
        {
            _ShakenTimespan = DateTime.Now;
            Shaken?.Invoke(null, EventArgs.Empty);
        }
    }

    /// <summary>
    /// Raised whenever the Accelerometer detects a shaking gesture
    /// </summary>
    public static event EventHandler Shaken;
}

To use it, just enable it and subscribe to its event:

CustomAccelerometer.Enabled = true;
CustomAccelerometer.Shaken += (s, e) =>
{
    Debug.WriteLine("The device was shaken!");
};

EDIT: forgot to add the Square method code, here it is:

/// <summary>
/// Returns the square of the given double value
/// </summary>
/// <param name="value">The input value</param>
public static double Square(this double value) => value * value;
Sign up to request clarification or add additional context in comments.

3 Comments

The answer looks interesting. I'm just not sure how to use it. I created the sample acceleromter example that Microsoft has here. Based on what i've done so far (in that example), i'm just not sure how to use your solution.
@ThePeter I've added a small code example in my answer, it's really straightforward to use this helper class. Just enable it and subscribe to its static event, then you're set.
@Cabuxa.Mapache oh that's just an extension method I forgot to include in the snippet, it just takes a double value and returns its square value (n => n * n). I'll edit the answer with the extension code too :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.