Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Detecting a Windows Phone physical drop - Part 1 - Intro and theory

DZone's Guide to

Detecting a Windows Phone physical drop - Part 1 - Intro and theory

· Mobile Zone
Free Resource

Download this comprehensive Mobile Testing Reference Guide to help prioritize which mobile devices and OSs to test against, brought to you in partnership with Sauce Labs.

I saw this Android project recently and I thought that it would be nice to implement something like this for Windows Phone. It required some understanding of physics and general accelerometer data processing, but it is definitely an interesting project to implement. I was ready for the fact that Windows Phone will have some limitations (e.g. no automated call without user approval), but generally it should work in a similar manner.

So let's think about the general concept. I need to read the accelerometer data first, so what I did is create a test console that both shows the current accelerometer values, as well as graphs the net force, returned by the accelerometer. Here is the final result (UI):

The process of capturing the data is as simple as it gets - I am using the standard Accelerometer class coupled with a Dispatcher, that passes the data back to the UI. Here is the code:

Accelerometer acc;
public MainPage()
{
    InitializeComponent();
    acc = new Accelerometer();
    acc.CurrentValueChanged += new EventHandler<SensorReadingEventArgs<AccelerometerReading>>(acc_CurrentValueChanged);
}

void acc_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e)
{
    double f = Math.Sqrt(e.SensorReading.Acceleration.X * e.SensorReading.Acceleration.X +
        e.SensorReading.Acceleration.Y * e.SensorReading.Acceleration.Y +
        e.SensorReading.Acceleration.Z * e.SensorReading.Acceleration.Z);

    Dispatcher.BeginInvoke(new Action(() =>
        {
            accList.Items.Add(f);
            var rectangle = new System.Windows.Shapes.Rectangle();
            rectangle.Width = 1.0;
            rectangle.Height = f * 25;
            rectangle.Fill = new SolidColorBrush(Colors.Blue);

            GraphGrid.Children.Add(rectangle);
        }));
}

private void btnStart_Click(object sender, RoutedEventArgs e)
{
    acc.Start();
}

private void btnStop_Click(object sender, RoutedEventArgs e)
{
    acc.Stop();
}

Notice how I am calculating the value of f, that represents the net force. Considering the Euclidean norm, I am calculating the single value from three existing vectors - X, Y and Z. I should not simply add them together because I am not working with scalar values. The static value, when the phone is not in motion, should be equal to one (1G - gravitational unit), with small fluctuations.

The XAML for the main page is this:

<phone:PhoneApplicationPage 
    x:Class="MANGO_PIVOT.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait"  Orientation="Portrait" mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" d:DesignHeight="800" d:DesignWidth="480">

    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="500"></RowDefinition>
            <RowDefinition Height="200"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
        <ListBox x:Name="accList" Grid.Row="0"></ListBox>

        <ScrollViewer Grid.Row="1" HorizontalScrollBarVisibility="Auto">
            <StackPanel Orientation="Horizontal" x:Name="GraphGrid">
            
            </StackPanel>
        </ScrollViewer>
        
        <StackPanel Orientation="Horizontal" Grid.Row="2">
            <Button x:Name="btnStart" Content="Start" Width="240" Click="btnStart_Click"></Button>
            <Button x:Name="btnStop" Content="Stop" Width="240" Click="btnStop_Click"></Button>
        </StackPanel>
    </Grid>
 
</phone:PhoneApplicationPage>

The positioning of accelerometer-based vectors can be easily seen on this picture:

The same gravitational force is applied to the phone if it is stationary (whether it is face up or face down) and the negative or positive values show the phone orientation - due to the way the accelerometer works, it can detect the direction of the gravitational pull.

For abstraction purposes, you can ignore the positive and negative indicators - the direction of the gravitational pull is not something we're interested in at this moment.

In the position of the phone in the picture, the X and Y axes have no active forces associated with them. The G-force is applied to the Z axis and its value is currently 1G = 9.8m/s.

Let's suppose that the phone is dropped now and is flying with either face up or face down. As it is free falling, the total acceleration will reach a point of zero, because:

  • For abstraction purposes, we ignore the small values generated by X and Y for now. They are zero.
  • The force of air resistance quickly will become the same as the weight (mass * g), cancelling each other out. That being said, the net acceleration will become zero (0).

That's why if you look at the initial graph, you can see that there is a timespan when the graph goes down to a thin line - it's getting close to zero, but not yet there. by inspecting the values of AccelerometerReading.Z, you will notice that those are approaching zero quite fast.

When the phone collides with the ground, we see a spike in the resulting force, as the phone falls and moves quite randomly, pretty much all three axes experiencing an external force.  That's when we know that there was in fact a collision - or so we assume in a perfect situation. The same result can be achieved if the phone is actively shaken in one's hand.

After that, the acceleration values are returning to normal, the net force being around 1G without external influences.

In the next (and last) part of this article, I will show you how to detect the collision and how to take the appropriate actions, so that we have an application similar to the one mentioned at the beginning, only running on Windows Phone.

Analysts agree that a mix of emulators/simulators and real devices are necessary to optimize your mobile app testing - learn more in this white paper, brought to you in partnership with Sauce Labs.

Topics:

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}