Plugin 05: Accelerometer

In our series on plugins, today we’re going to cover plugin which can help us to work with Accelerometer sensor. This sensor is responsible to detect X, Y, Z co-ordinates of the devices. Using data received from this sensor, you can build games like TempleRun, where users can collect the coins by tilting the device.

There are different APIs for different platform and their usage is different too. First, lets see how we can use this sensor in different platform and then we’ll use plugin in Xamarin.Forms application.

Being Windows Runtime API, the API and its usage is same in Windows and Windows Phone. Here, you create object of the sensor and register for ‘ReadingChanged’ event. Whenever device position is changed, it is reported through that event and UI can be updated using Dispatcher.

public sealed partial class MainPage : Page
{
private Accelerometer _accelerometer;
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
}
/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached.
/// This parameter is typically used to configure the page.</param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
_accelerometer = Accelerometer.GetDefault();
if (_accelerometer != null)
{
// Establish the report interval
uint minReportInterval = _accelerometer.MinimumReportInterval;
var desiredReportInterval = minReportInterval > 16 ? minReportInterval : 16;
_accelerometer.ReportInterval = desiredReportInterval;
try
{
_accelerometer.ReadingChanged += async (a, b) =>
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
txtXAxis.Text = "X axis: " + b.Reading.AccelerationX.ToString("F");
txtYAxis.Text = "Y axis: " + b.Reading.AccelerationY.ToString("F");
txtZAxis.Text = "Z axis: " + b.Reading.AccelerationZ.ToString("F");
});
};
}
catch (Exception ex)
{
throw;
}
}
else
{
new Windows.UI.Popups.MessageDialog("Accelerometer not found", "Error:").ShowAsync();
}
}
}

In case of Android, it is again similar to Windows platform. Create object of SensorManager and register for SensorChanged event.

[Activity(Label = "Accelerometer_Droid", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity, ISensorEventListener
{
private SensorManager _sensorManager;
private static readonly object _syncLock = new object();
private TextView x_axis; private TextView y_axis; private TextView z_axis;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
_sensorManager = (SensorManager)GetSystemService(Context.SensorService);
x_axis = FindViewById<TextView>(Resource.Id.lblXAxis);
y_axis = FindViewById<TextView>(Resource.Id.lblYAxis);
z_axis = FindViewById<TextView>(Resource.Id.lblZAxis);
}
public void OnAccuracyChanged(Sensor sensor, SensorStatus accuracy)
{
//Doing nothing. Just implementing interface.
}
public void OnSensorChanged(SensorEvent e)
{
lock (_syncLock)
{
x_axis.Text = e.Values[0].ToString("F");
y_axis.Text = e.Values[1].ToString("F");
z_axis.Text = e.Values[2].ToString("F");
}
}
protected override void OnResume()
{
base.OnResume();
_sensorManager.RegisterListener(this, _sensorManager.GetDefaultSensor(SensorType.Accelerometer), SensorDelay.Ui);
}
protected override void OnPause()
{
base.OnPause();
_sensorManager.UnregisterListener(this);
}
}

iOS is not any different. You create object of CMMotionManager and then listen to sensor for changes.

public override void ViewDidLoad()
{
base.ViewDidLoad();
_motionManager = new CMMotionManager();
_motionManager.StartAccelerometerUpdates(NSOperationQueue.CurrentQueue, (data, error) =>
{
lblXAxis.Text = data.Acceleration.X.ToString("F");
lblYAxis.Text = data.Acceleration.Y.ToString("F");
lblZAxis.Text = data.Acceleration.Z.ToString("F");
});
// Perform any additional setup after loading the view, typically from a nib.
}

As you can see, for three different platforms the APIs are totally different. But with Plugins for Xamarin.Forms it becomes easy. You can use DeviceMotion plugin which can work across all these platforms. And the code for same looks like:

private void BtnStart_OnClicked(object sender, EventArgs e)
{
CrossDeviceMotion.Current.Start(MotionSensorType.Accelerometer, MotionSensorDelay.Ui);
CrossDeviceMotion.Current.SensorValueChanged += (s, a) =>
{
switch (a.SensorType)
{
case MotionSensorType.Accelerometer:
lblXAxis.Text = ((MotionVector)a.Value).X.ToString("F");
lblYAxis.Text = ((MotionVector)a.Value).Y.ToString("F");
lblZAxis.Text = ((MotionVector)a.Value).Z.ToString("F");
break;
}
};
}
private void BtnStop_OnClicked(object sender, EventArgs e)
{
CrossDeviceMotion.Current.Stop(MotionSensorType.Accelerometer);
}

In this series on plugin we’ve seen how particular concept can be implemented in all the three platforms and how we can use plugin to make life easier. This will be be last post in this series, but there are many plugins available which you can explore and use in your projects. Do let me know if you want to cover any specific plugin. We’ll start with a new series in couple of weeks. Till then… happy coding :)

Namaste
Mayur Tendulkar

Xamarin.Forms for Windows Phone –Differences You Must Know

Xamarin.Forms is cross platform solution to create native apps. Whilst Xamarin allows us to build native apps for each platform (Android, iOS and Windows) with maximum code sharing, Xamarin.Forms goes one step ahead and allows UI code sharing as well. That means, I can create a TabbedPage and it will be rendered natively on each platform as ActionBar, UITabView and Pivot.

Xamarin.Forms allows creating UI in both C# as well as XAML. To keep things simple and less confusing across different platforms, there are new properties, new elements. XAML as a language is still the same. So we get to create objects from XAML, initialize them using InitializeComponent(). Everything is still the same. You just need to know the small differences. For example there is no Margin property, but there is Spacing property <grin>

While you can add a XAML page from XAML project template category, you should add one from Code -> Forms Xaml Page

image

The first thing to notice here is namespace

image

And this actually makes the difference. The two lines define the XAML page. First two are for Xamarin.Forms whereas last two are for normal XAML page in Windows app.

When creating User Interface, Xamarin.Forms provides Views (controls in our language) which abstract away the different controls in different platform. So, to create a TextBox on Windows Phone and a button which will be right aligned within StackPanel, following code will do the magic:

image

As you can see here, rather than StackPanel, StackLayout is used to represent controls positioned in stack (horizontal or vertical) and to avoid confusion with any stack in these platforms. This StackLayout will internally render native Stack of controls on each platform.

Also, in above code, Entry element is used, which is new to us. However, this entry represents a single line text-input control. That is, on Windows Phone it will become a TextBox.

Along with control names, some properties are named differently. For example Margin is now Spacing. We have left 25px space from each side in our code. Padding is still the same.  HorizontalAlignment is changed to HorizontalOptions. And possible values for that will be: Start [Left], Center and End [Right], with option to mention Expand which will take-up the space available. It also has FillAndExpand option, which is similar to Stretch mode.

While working with Font, usually we’ve different properties for FontFamily, FontSize, FontWeight etc. In Xamarin.Forms, we get one Font property which accepts multiple values (comma separated), which is parsed at runtime (Type Converters). So, below code can render TextBlock (label) with specified font details:

image

One thing to notice here is OnPlatform element. This element helps to override certain values (in above code, label renders with different font setting on different platform) for specific platform. There is a Device class with methods to work on platform specific code in XAML or C#.

The data binding concept is still the same as it was in traditional XAML.

image

The code above mentioned, with details is available at ‘An Introduction to Xamarin.Forms’ i.e.: http://bit.ly/1l1zg06 on Xamarin.com site.

Having said that XAML syntax is still the same. The features like code behind in partial class (with InitializeComponent), Type Converters, Property Element syntax, Attached Property syntax, Content properties, external library declarations (xmlns : somedifferentype=”uri”), adding event handlers, ResourceDictionary, StaticResources, etc… are still the same.

With this, I’m sure Xamarin.Forms will help C# and XAML developers to do Rapid Application Development on multiple platforms.

You can read more here at:

  1. An Introduction to Xamarin.Forms
  2. Getting Started with Xamarin.Forms: Basics
  3. Xamarin.Forms Samples
  4. XForms Labs (Open Source Project)

Happy Coding & Namaste
Mayur Tendulkar

#365 Admin

I carpool to work with Dev. We enjoy our ~45 mins. ride and while traveling we listen to 80’s/90’s songs (If given a chance he would kill me for my choice of songs Smile) and also talk about various things at our day-to-day job and how those can be automated. One of the thing that we discussed was basic – User Management. E.g. adding a user, resetting password, etc.… So, we thought about enabling IT admins to manage their Active Directory remotely.

Recently, I was working on a project where we had to use Azure Active Directory for user management. And I thought it can add value if ported on mobile. So – #365 Admin.

Using this tool, IT admins can browse through users, reset their password or add a new user. This is v1.0 release and I’m planning to add more features and release updates once in a month or as and when ready/required.

Thanks to Girish, Aviraj and Vittorio for all their support while building this app.

The app is certified in the store and will be available in general in coming weeks.

Thanks,
Mayur Tendulkar