Shake that Windows Phone 7 and detect it

Alright, when you look at what apps are popular, you’ll see a lot of apps that interact with the accelerometer in a way like: Shake your phone baby!

Yes we have the accelerometer on the Windows Phone 7 as well, how to use it? That’s simple.

1: Reference the Microsoft.Devices.Sensors assembly.

Add a Add a reference to the Microsoft.Devices.Sensors assembly

2: Create an instance of the Accelerometer.

private readonly Accelerometer _sensor = new Accelerometer();

3: Start listening to the ReadingChanged

_sensor.ReadingChanged += ReadingChanged;

private void ReadingChanged(object sender, AccelerometerReadingEventArgs e)
{
}

The structure of the AccelerometerReadingEventArgs looks like this.

public class AccelerometerReadingEventArgs : EventArgs
{
    public double X { get; }
    public double Y { get; }
    public double Z { get; }
    public DateTimeOffset Timestamp { get; }
}

Pretty simple, X, Y and Z coordinates, how to read them?

image

Source: http://windowsteamblog.com/windows_phone/b/wpdev/archive/2010/09/08/using-the-accelerometer-on-windows-phone-7.aspx

Shake it

That’s about it for the basics. You can do a lot of things with the accelerometer. I want to know when the device is shaken. I started with a bit of google, and found: Shake Detection by Mark Arteaga. Nice article with a good explanation of the code. Though, he didn’t have a chance to test the code, and it was also based on a pre-release version of the Developer Tools. So after some adjustments I came with the following code that both compiles in the final Windows Phone 7 Developers Tools and also runs on the LG Prototype.

public class AccelerometerSensorWithShakeDetection : IDisposable
{
    private const double ShakeThreshold = 0.7;
    private readonly Accelerometer _sensor = new Accelerometer();
    private AccelerometerReadingEventArgs _lastReading;
    private int _shakeCount;
    private bool _shaking;

    public AccelerometerSensorWithShakeDetection()
    {
        var sensor = new Accelerometer();
        if (sensor.State == SensorState.NotSupported)
            throw new NotSupportedException("Accelerometer not supported on this device");
        _sensor = sensor;
    }

    public SensorState State
    {
        get { return _sensor.State; }
    }

    #region IDisposable Members

    public void Dispose()
    {
        if (_sensor != null)
            _sensor.Dispose();
    }

    #endregion

    private event EventHandler ShakeDetectedHandler;

    public event EventHandler ShakeDetected
    {
        add
        {
            ShakeDetectedHandler += value;
                
        }
        remove
        {
            ShakeDetectedHandler -= value;
            _sensor.ReadingChanged -= ReadingChanged;
        }
    }

    public void Start()
    {
        if (_sensor != null)
            _sensor.Start();
    }

    public void Stop()
    {
        if (_sensor != null)
            _sensor.Stop();
    }

    private void ReadingChanged(object sender, AccelerometerReadingEventArgs e)
    {
        //Code for checking shake detection
        if (_sensor.State == SensorState.Ready)
        {
            AccelerometerReadingEventArgs reading = e;
            try
            {
                if (_lastReading != null)
                {
                    if (!_shaking && CheckForShake(_lastReading, reading, ShakeThreshold) && _shakeCount >= 1)
                    {
                        //We are shaking
                        _shaking = true;
                        _shakeCount = 0;
                        OnShakeDetected();
                    }
                    else if (CheckForShake(_lastReading, reading, ShakeThreshold))
                    {
                        _shakeCount++;
                    }
                    else if (!CheckForShake(_lastReading, reading, 0.2))
                    {
                        _shakeCount = 0;
                        _shaking = false;
                    }
                }
                _lastReading = reading;
            }
            catch
            {
                /* ignore errors */
            }
        }
    }

    private void OnShakeDetected()
    {
        if (ShakeDetectedHandler != null)
            ShakeDetectedHandler(this, EventArgs.Empty);
    }

    private static bool CheckForShake(AccelerometerReadingEventArgs last, AccelerometerReadingEventArgs current,
                                        double threshold)
    {
        double deltaX = Math.Abs((last.X - current.X));
        double deltaY = Math.Abs((last.Y - current.Y));
        double deltaZ = Math.Abs((last.Z - current.Z));

        return (deltaX > threshold && deltaY > threshold) ||
                (deltaX > threshold && deltaZ > threshold) ||
                (deltaY > threshold && deltaZ > threshold);
    }
}

And of course you want to use it in your app, which can be done like this.

_shakeSensor = new AccelerometerSensorWithShakeDetection();
Loaded += (sender, args) =>
                {
                    _shakeSensor.ShakeDetected += ShakeDetected;
                    _shakeSensor.Start();
                };
Unloaded += (sender, args) =>
                {
                    _shakeSensor.ShakeDetected -= ShakeDetected;
                    _shakeSensor.Stop();
                };
Be aware that the event is fired on a different thread, so if you want to use this in the UI thread you might want to read an old article on UI threads from my hand.
  • Gravatar AlexH November 3rd, 2010 at 22:07
    Hi Mark,
    I'm seeking your permission to reuse this code in some examples for WP7 Hands-On-Labs. Can you contact me please?
    Thank you.
  • Gravatar Chris Rae November 11th, 2010 at 06:52
    This is a great article - you have a couple of tiny omissions. Firstly you somehow don't actually assign the sensor ReadingChanged event handler, so your code:

    add
    {
    ShakeDetectedHandler += value;
    }

    Should actually read:


    add
    {
    ShakeDetectedHandler += value;
    _sensor.ReadingChanged += ReadingChanged;
    }


    And secondly you don't mention that in your code you need a ShakeDetected handler, i.e.:


    private void ShakeDetected(object sender, EventArgs e)
    {
    }


    Great article, though - saved me a ton of work!
  • Gravatar Luke Lowrey November 29th, 2010 at 08:47
    Awesome code. Might implement me some shake to refresh.
  • Gravatar Edwin Evans December 14th, 2010 at 02:21
    Thanks! I used this in my Bubbles Magic app ( http://www.youtube.com/watch?v=vw1aw7I4Nyc ) to pop all the bubbles :)
  • Gravatar mbt shoes uk sale May 9th, 2014 at 19:01
    mbt shoes kisumu Shake that Windows Phone 7 and detect it - Silverlight, WP7, .NET, C#, ASP.NET MVC
  • Gravatar bad credit home loan June 17th, 2014 at 05:58
    Moreover, when you repay the loan, you will be using your after-tax
    dollars and again when you withdraw cash from the 401k
    account at retirement, you'll be paying taxes.
    Though the fixed-rate mortgage is more common to obtain, it
    doesn't mean that an adjustable-rate mortgage is not a good
    investment to make. Many banks have simply canceled their sub-prime loan programs,
    resulting in millions of borrowers effectively being shut out of the mortgage market.
  • Gravatar california hard money lenders June 19th, 2014 at 03:35
    So here are a few options that are available for getting financing if you don. Western Sky Financial tell you up
    front "yes the money is expensive" and they are not kidding about that.
    Let's also say that you have the property under
    contract for $50,000.
  • Gravatar Pamala June 19th, 2014 at 23:31
    With the economy still in the tank for 65 percent of the population (or more), many have lost faith in the banking system.
    You will feel delighted to know that websites cater free of cost, round the clock.
    The tuition of my seminars ranges from $395 to $695 depending on the venue.
  • Gravatar hollister sweater July 29th, 2014 at 03:51
    Additionally, porcelain tile can be used for interior and exterior applications as well as heavy shopping or Areas. After the finished tiles-have-been inspected.please for quality insurance, They are packaged, crated and ready to be shipped.
  • Gravatar online jewelry shoppe August 9th, 2014 at 21:42
    A recent study by the Silver Promotion Service showed that 46 percent of consumers prefer white metals for diamond jewelry.
    Do you want it to look brand new for an upcoming rendezvous.
    Please remove your four-leaf clover before sports, heavy manual labor or repair,
    in case of any damage or abrasion.
  • ' Well, in a way that is what your are in MLM because you are
    the distributor. Poor marketing - primarily failing to
    meet the needs of the customer or not fully understanding the true size of
    the market. But in the case of employed individuals it is left to the employer’s discretion whether or not to
    contribute matching funds.
  • Gravatar Terri August 24th, 2014 at 22:48
    During the coarse of the loan your contractor will
    submit invoices to the lender and the lender will issue incremental payments.
    If the package survives the legislative process, this funding could support as much as
    $9 billion in additional loan guarantees for nuclear power plant construction and $3 billion in loan guarantees for wind and solar power generating facility construction, including
    the $2 billion "borrowed" from earlier legislative proposals to fund extension of the "cash for clunkers" program in the economic stimulus package.
    They instead avail commercial interest-only loans to businesses during the renovation phase
    if a building already exists or during construction phase.
  • Gravatar http://www.productionsprestige.com/?id=31 August 31st, 2014 at 05:52
    Forecast: Retail sales to rise 4.3% in 2014
Gravatar