Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Getting Started With Android Wearable Using Xamarin and Visual Studio

0.00/5 (No votes)
9 Jun 2016 1  
A one-stop tutorial that helps you get started on building apps on Android Wears and Handheld device.

Introduction

The terms “wearable devices“, and “wearables” all refer to electronic technologies or computers that are incorporated into items of clothing and accessories that can comfortably be worn on the body. Examples are Google Glass and Smart Watches. (Source: What is a Wearable Device)

I had the opportunity to explore on android wearable devices, particularly smart watches and have decided to use Xamarin and Visual Studio for the following reasons.

  • Xamarin allows you to build cross-platform apps (iOS, Andriod and Windows app) using C#.
  • I am an experienced C# developer.
  • I am more familiar with Visual Studio development tools.
  • Gives me less learning curve as I don't need to learn how to use other frameworks, editors, tools and other programming languages to build native apps.
  • I can take advantage of the cool features provided by Xamarin such as cloud testing and app monitoring.
  • Xamarin and Visual Studio are quite popular and stable platform for building real world apps.

Having the opportunity to work with android wearable is very exciting as this is getting more popular nowadays. Yes it's exciting but at the same time scary because I don't have any much experience on the technology, smart watch device and android stuff. This means that I will need to learn from scratch about how everything works with this technology and the android framework itself. I am also aware that there's a bit of learning curve to deal with as working with this technologies is completely different compared to web development. So that's why I'm writing this article to guide new comers like me to get started with Android Wear application development.

What you will learn

In this article you will learn the following:

  • Setting up the Development Environment
  • Creating a Simple Android Wear Application
  • Creating Apps that would Sync data between Wearable and Android Handheld Device
  • Testing, Debugging and Deploying Android Applications across Wears and Handheld Devices

Setting up the Development Environment

The first thing we need is to install the necessary tools. So first you need to install Visual Studio. If you are using Visual Studio 2010, 2012 or 2013 then make sure it's a professional or higher version because the Xamarin extension for Visual Studio will only be supported for non-express editions. For details, see https://xamarin.com/faq.

In my case I have used Visual Studio 2013 Ultimate version. Once you have installed the supported version of Visual Studio then go ahead and download the Xamarin extension for Visual Studio here http://xamarin.com/visual-studio. (You can start with a free trial or a license version of it).

Just follow the instructions in the download wizard until it's complete ( note that this may take longer depending on the frameworks that you are installing). You may need to restart your machine to reflect everything that is installed in your machine. 

Now when you launch Visual Studio, you should be able to see the following items below under Tools menu.

Figure 1: Android Tools and SDK

To ensure that everything you need is installed, you can verify it at the Android SDK Manager. Just go to Tools > Android > Android SDK Manager. This will open the following window below:

Figure 2: Android SDK Manager

Now if you think that everything you need was installed, then congratulations you can now start creating your own awesome android app using Xamarin within Visual Studio.

Creating a Simple Android Wear Application

Let's go ahead and create a new project within Visual Studio and then from the Templates select Android > Wear App (Android). You should be able to see something as in the following.

Figure 3: Visual Project Template list

Just click OK to let Visual Studio generate the necessary files to build the wear app for you. The image below shows the generated files with default sample codes for you to get started working on building wear apps.

Figure 4: Default Wear App Code

That was easy right? Here's the Anatomy of Xamarin.Android Application that is taken from the official documentation here: http://developer.xamarin.com/guides/android/getting_started/.

Folder           Purpose

References Contains the assemblies required to build and run the application. 
Components The Components directory houses ready-made features from the Xamarin Components.
Assets Contains the files the application needs to run including fonts, local data files and text files. 
Properties Contains the AndroidManifest.xml file that describes all the requirements for our Xamarin.Android application, including name, version number and permissions. 
Resources Contains application resources such as strings, images and layouts. We can access these resources in code through the generated Resource class. 

Running the Application

In order for us to run the application without a real device, we need to first setup an emulator. You can create one by following these few steps.

Go to Tools > Andriod > Andriod Emulator Manager or simply click on the AVD icon at the tool bar. See below.

Figure 5: Andriod Built-in Emulator

The Android Device Manager window should show. This is where we can edit, start, create, delete or repair virtual devices. Now click on the "Create" button. The following window should open that allows you to select the device that you want to create. In this case, we just need to create a virtual Android Wear Device for us to run our application in the emulator.

Figure 6: AVD dialog

Once everything is set then just click OK to create the virtual device. You should be able to see the device that you have just created in the AVD Manager as shown in the figure below.

Figure 7: AVD Manager

Just click Start > Launch to run the emulator in the background. Note that it may take some time to load the emulator. When the emulator is loaded and ready, you should be able to see the name of the virtual device that you have just created in the start debugging dropdown as in the following.

Figure 8: Newly created virtual device

Now set your application as the startup project and then run it by pressing F5. Here's the sample output of the wear application that is running within the emulator.

Figure 9: Output

Keep in mind that the default emulator integrated within Visual Studio is a bit slow and it's good only for testing small Apps. In real development where you create and test apps, I would highly recommend you to use the Xamarin Android Player to simulate android apps.

That's it! If you want to refer more wear app examples then just visit this link: Android Wear

Syncing Data Between Wearable and Android Handheld Device

Let's move a bit further and create a working apps that communicate between your wear app and handheld device. This exercise shows how to sync data in your Android application.

Creating the Android Wear App

To get started, let's fire up Visual Studio 2013 and select "File" -> "New" -> "Project...". Under Templates select C# > Android, select Wear App (Android) Project. 

Name your app to whatever you like and then click OK to let Visual Studio generate the necessary files for you. In this exercise, I named it "WearDemo". The image below shows the generated files with default sample codes to help you get started on building wear apps.

Figure 10: Wear App Project

Before we start modifying the default code, I'd like to point out that there are two ways to communicate between wearable and handheld devices and these are the DataApi and the MessageApi. The following are the short descriptions of each API. 

DataApi exposes an API for components to read or write data items and assets. A DataItem provides data storage with automatic syncing between the handheld and wearable. An asset is used for sending BLOBs of data such as images. You attach assets to DataItems and the system automatically takes care of the transfer for you. Read more here.

MessageApi exposes an API for components to send messages to other nodes. Messages should generally contain small payloads. You should use Assests with DataApi to store larger data. Read more here.

In this particular demo, I'm going to use the DataApi to send/sync data between devices. Since DataApi is part of Google Play Services, then the first thing we need here is to add the following namespaces below:

using Android.Gms.Common.Apis;  
using Android.Gms.Wearable;

Android.Gms.Common.Apis allows us to use GoogleApiClient, that is the main entry point for Google Play Services integration. The Android.Gms.Wearable enables us to use the WearableClass. Next is to extend our MainActivity class to inherit the following interfaces:

  • IDataApiDataListener.
  • IGoogleApiClientConnectionCallbacks IGoogleApiClientOnConnectionFailedListener.

IDataApiDataListener is used to receive data events. The IGoogleApiClientConnectionCallbacks provides callbacks that are called when the client is connected or disconnected from the service. IGoogleApiClientOnConnectionFailedListener provide callbacks for scenarios that result in a failed attempt to connect the client to the service.

Wrapping everything up, here's the sample code for sending data to the handheld device:

using System;  
using Android.Runtime;  
using Android.Widget;  
using Android.OS;  
using Android.Support.Wearable.Views;  
using Java.Interop;  
using Android.Gms.Common.Apis;  
using Android.Gms.Wearable;  
using System.Linq;  
  
namespace WearDemo  
{  
    [Activity(Label = "WearDemo", MainLauncher = true, Icon = "@drawable/icon")]  
    public class MainActivity : Activity,IDataApiDataListener, IGoogleApiClientConnectionCallbacks, IGoogleApiClientOnConnectionFailedListener  
    {  
  
        private IGoogleApiClient _client;  
        const string _syncPath = "/WearDemo/Data";  
        protected override void OnCreate(Bundle bundle) {  
            base.OnCreate(bundle);  
  
            _client = new GoogleApiClientBuilder(this, this, this)  
                             .AddApi(WearableClass.Api)  
                             .Build();  
  
            // Set our view from the "main" layout resource  
            SetContentView(Resource.Layout.Main);  
            var v = FindViewById<WatchViewStub>(Resource.Id.watch_view_stub);  
            v.LayoutInflated += delegate {  
  
                // Get our button from the layout resource,  
                // and attach an event to it  
                Button button = FindViewById<Button>(Resource.Id.myButton);  
  
                button.Click += delegate {  
                    SendData();  
                };  
            };  
        }  
  
        public void SendData() {  
            try {  
                var request = PutDataMapRequest.Create(_syncPath);  
                var map = request.DataMap;  
                map.PutString("Message", "Vinz says Hello from Wearable!");  
                map.PutLong("UpdatedAt", DateTime.UtcNow.Ticks);  
                WearableClass.DataApi.PutDataItem(_client, request.AsPutDataRequest());  
            }  
            finally {  
                _client.Disconnect();  
            }  
  
        }  
        protected override void OnStart() {  
            base.OnStart();  
            _client.Connect();  
        }  
        public void OnConnected(Bundle p0) {  
            WearableClass.DataApi.AddListener(_client, this);  
        }  
  
        public void OnConnectionSuspended(int reason) {  
            Android.Util.Log.Error("GMSonnection suspended " + reason);  
            WearableClass.DataApi.RemoveListener(_client, this);  
        }  
  
        public void OnConnectionFailed(Android.Gms.Common.ConnectionResult result) {  
            Android.Util.Log.Error("GMSonnection failed " + result.ErrorCode);  
        }  
  
        protected override void OnStop() {  
            base.OnStop();  
            _client.Disconnect();  
        }  
  
        public void OnDataChanged(DataEventBuffer dataEvents) {  
            var dataEvent = Enumerable.Range(0, dataEvents.Count)  
                                      .Select(i => dataEvents.Get(i).JavaCast<IDataEvent)  
                                      .FirstOrDefault(x => x.Type == DataEvent.TypeChanged && x.DataItem.Uri.Path.Equals(_syncPath));  
            if (dataEvent == null)  
                return;  
  
            //do stuffs here  
        }  
    }  
}  

Okay, I'll try to explain what happens in the code. At the OnCreate event we build a Google Play Services client that includes the Wearable API. We then called the SendData() method at the Button's click handler to send the data. The SendData() method contains the actual logic for sending the data. There, we created a DataMapRequest by passing the path of the data object that is "/WearDemo/Data". The actual data is the DataMap that cotains a Message and UpdatedAt values. The receiving side can use the path to identify the origin of the data that I'll talk about later in this article.

The Events

  • OnStart connects to the data layer when the activity starts. 
  • OnConnected  triggers when the data layer connection is successful. 
  • OnStop  disconnects from the data layer when the activity stops OnConnectionSuspended and OnConnectionFailed is where you do stuff for the required connection callbacks (for example in this demo we log errors and detach the service). 
  • OnDataChanged  triggers when the data changes.

Things to Keep in Mind

  • The path should always start with a forward-slash (/). 
  • Timestamps is a must when sending data because the OnDataChanged() event is only called when the data really changes. Adding the Timestamp to the data will ensure that the method is called.

Add the following MetaData in the AndroidManifest.xml under <application> element:

<meta-data android:name="com.google.android.gms.version" 
           android:value="@integer/google_play_services_version" />  

Creating the Main App Project

To test the syncing and sending of the data, we need to create the main Android app that will receive the data object coming from the wearable. The main app will be installed in the handheld device (for example mobile or tablet).

Now right-click on the solution project and select ADD > NEW PROJECT. In the Add New Project window select Visual C# > Android > Blank App (Android). You should be able to see like this:

Figure 11: Android Main App Project

I named the project "MainAppDemo" for simplicity. Just click OK to generate the necessary files for you. You should have something like this in your solution now.

Figure 12: The Solution Explorer

Before we start adding the logic to the main app, I'd like to highlight the following.

The Namespace of your Wear app and Main app should be the same. In this example the Wear app uses the namespace "WearDemo". So be sure to rename the namespace of your main app to "WearDemo" to match up. To change the default namespace you can follow these steps.

  • Go to PROJECT > PROPERTIES > DEFAULT NAMESPACE.
     
  • To change the rest you can use CTRL + H and replace the default namespace to "WearDemo".
     
  • You can also use the refactor code to change the namespace. To do this just simply right-click on the namespace and select REFACTOR > RENAME.

The package name of your Wear and Main app should also be the same. You can find the package name by right-clicking on the project and select PROPERTIES > ANDROID MANIFEST as shown in the image below:

Figure 13: Android Manifest

Make sure that both package names are set to "WearDemo.WearDemo". Be sure to build both projects to see if it builds successfully. Once you've done that then let's go ahead and start modifying the project. First change the value of "Compile using Android version" to "API Level 21 (Xamarin.Android v5.0 Support). See the image below:

Figure 14: Application Settings

Under references, check if you have Xamarin.Android.Support.V4. If you don't have that then just right-click on the References and select MANAGE NUGET PACKAGES. Under Online > Nuget.Org search "Xamarin.Android.Support.V4". You should be able to see something like this:

Figure 15: NuGet Package Manager

Just click install and wait until it is done. Now do the same procedure and install "Xamarin.Android.Wear -Version 1.0.0". 

Adding the WearableListenerService

Extending the WearableListenerService lets you listen for any updates in the data layer. The system manages the lifecycle of the service, binding to the service when it needs to send data items or messages and unbinding the service when no work is needed. Read more here.

Having that statement we will use the WearableListenerService to listen for an update from the data layer and handle the data. So the next step is to add a class that extends WearableListenerService. To do this right-click on the project root and select ADD > Class and name it "WearService". Here's the entire logic of the class.

using System.Linq;  
using Android.App;  
using Android.Content;  
using Android.Runtime;  
using Android.Gms.Wearable;  
using Android.Gms.Common.Apis;  
using Android.Support.V4.Content;  
  
namespace WearDemo  
{  
    [Service]  
    [IntentFilter(new[] { "com.google.android.gms.wearable.BIND_LISTENER" })]  
    public class WearService : WearableListenerService  
    {  
        const string _syncPath = "/WearDemo/Data";  
        IGoogleApiClient _client;  
  
        public override void OnCreate() {  
            base.OnCreate();  
            _client = new GoogleApiClientBuilder(this.ApplicationContext)  
                    .AddApi(WearableClass.Api)  
                    .Build();  
  
            _client.Connect();  
  
            Android.Util.Log.Info("WearIntegrationreated");  
        }  
  
        public override void OnDataChanged(DataEventBuffer dataEvents) {  
            var dataEvent = Enumerable.Range(0, dataEvents.Count)  
                                      .Select(i => dataEvents.Get(i).JavaCast<IDataEvent)  
                                      .FirstOrDefault(x => x.Type == DataEvent.TypeChanged && x.DataItem.Uri.Path.Equals(_syncPath));  
            if (dataEvent == null)  
                return;  
  
            //get data from wearable  
            var dataMapItem = DataMapItem.FromDataItem(dataEvent.DataItem);  
            var map = dataMapItem.DataMap;  
            string message = dataMapItem.DataMap.GetString("Message");  
  
            Intent intent = new Intent();  
            intent.SetAction(Intent.ActionSend);  
            intent.PutExtra("WearMessage", message);  
            LocalBroadcastManager.GetInstance(this).SendBroadcast(intent);  
        }  
    }  
}  

The code above implements OnDataChanged event that filters incoming data events for those of "TypeChanged", it checks for the data object path of "/WearDemo/Data", then broadcasts the data locally.

The Main Activity

Here's the code block for the main activity class.

using Android.App;  
using Android.Content;  
using Android.Widget;  
using Android.OS;  
using Android.Support.V4.Content;  
  
namespace WearDemo  
{  
    [Activity(Label = "MainAppDemo", MainLauncher = true, Icon = "@drawable/icon")]  
    public class MainActivity : Activity  
    {  
        TextView _txtMsg;  
  
        protected override void OnCreate(Bundle bundle) {  
            base.OnCreate(bundle);  
  
            // Set our view from the "main" layout resource  
            SetContentView(Resource.Layout.Main);  
  
            // Get our TextBox from the layout resource,  
            _txtMsg = FindViewById<TextView>(Resource.Id.txtMessage);  
  
  
            IntentFilter filter = new IntentFilter(Intent.ActionSend);  
            MessageReciever receiver = new MessageReciever(this);  
            LocalBroadcastManager.GetInstance(this).RegisterReceiver(receiver, filter);  
        }  
  
        public void ProcessMessage(Intent intent) {  
            _txtMsg.Text = intent.GetStringExtra("WearMessage");  
        }  
  
        internal class MessageReciever : BroadcastReceiver  
        {  
            MainActivity _main;  
            public MessageReciever(MainActivity owner) { this._main = owner; }  
            public override void OnReceive(Context context, Intent intent) {  
                _main.ProcessMessage(intent);  
            }  
        }  
    }  
}  

In the code above, we register to receive broadcasts from the ListenerService in the OnCreate() event and then define a nested class that extends the BroadcastReceiver, implements the OnReceive() method and extract the data. The Process() method handles the displaying of data to the UI.

The Main layout

Change your Main.xaml to this:

<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:orientation="vertical"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent">  
    <TextView  
        android:id="@+id/txtMessage"  
        android:layout_width="fill_parent"  
        android:layout_height="wrap_content"  
        android:layout_marginTop="50dp"  
        android:gravity="center"  
        android:textColor="@android:color/white"  
        android:textSize="80sp" />  
</LinearLayout>  

There's nothing really fancy in the markup above. It just contain a TextView for displaying the message. 

Adding the MetaData for Google Play Services

And finally, add the Meta data in the AndroidManifest.xml under the <application> element:

<meta-data android:name="com.google.android.gms.version" 
           android:value="@integer/google_play_services_version" />

Next, I'm going to show how to deploy each application in each device and test the result.

Testing, Debugging and Deploying Android Applications Across Wears and Handheld Devices

In this section, we'll take a look at how to deploy and test apps in real devices. First of all, I am using a Nexus 9 and a LG G Watch as my test devices. 

Before we start, make sure that USB Driver for Android is installed in your machine. You can verify it by right-clicking on the COMPUTER > MANAGE > DEVICE MANAGER > OTHER DEVICES. If the driver isn't in the list then you must download the driver here: http://developer.android.com/sdk/win-usb.htmland refer to this link for the installation guide: http://developer.android.com/tools/extras/oem-usb.html#InstallingDriver

The next important thing is to enable USB Debugging in your handheld device. You can enable it under SETTINGS > DEVELOPER OPTIONS > USB DEBUGGING. Once you have the required driver installed and you have enabled debugging for your device then just plug your handheld device into your PC or laptop. In Visual Studio you should be able to see the connected handheld device as shown in the figure below:

Figure 16: The Projects

Deploying the Main App to Handheld Device

The following is the procedure for deploying the app:

  • Right-click on the main app project and select PROPERTIES > ANDROID OPTIONS. Under the Packaging tab uncheck the "Use Fast Deployment (debug mode only)".
  • Under the Packaging tab uncheck the "Use Fast Deployment (debug mode only)".
  • Unload the project.
  • Edit the .CSPROJ file and add this PropertyGroup:
<PropertyGroup>  
   <JavaMaximumHeapSize>1G</JavaMaximumHeapSize>  
</PropertyGroup>
  • Save and then load the project.  
  • Right-click on the main app project and set it as the startup project.
  • Build the app.
  • And then click run or the Play button. This will package and install the app to the device. Just wait for it to finish.

Deploying the Wear App

You can follow the same procedure for deploying the wear app just as what we've done for the main app. If you want to deploy and debug your app over Bluetooth then here are the extra steps:

  • Open the Android Wear companion app in your handheld device.
  • Tap the menu on the top right and select SETTINGS.
  • Enable "Debugging Over Bluetooth". You should be able to see the status like this: 
Host: disconnected  
Target: connected  
  • Connect the handheld to your PC or laptop over USB.
  • In Visual Studio, go to TOOLS > ANDROID > ANDROID ADB COMMAND PROMPT and run the following commands:     
adb forward tcp:4444 localabstract:/adb-hub  
adb connect localhost:4444 
  • You should then be able to see the wear device in the device list as shown in the image below: 

Figure 17: Connected Device

  • Repeat the same steps 1-5 mentioned in Deploying Main App to Handheld device
  • Now set your Wear App as the startup project, build the app and run. 

Once installed you should be able to set a breakpoint in Visual Studio to do the debugging and test your application. Here's the output of the sample application:

Figure 18: Final Output

You can download or get the demo project on Github for your reference. I hope someone find this post useful.

Summary

In this article, we've learned the following:

  • Brieft overview of Wearables and Android
  • Setting up the Development Environment
  • Creating a Simple Android Wear Application
  • Creating Apps that would Sync data between Wearable and Android Handheld Device
  • Testing, Debugging and Deploying Android Applications across Wears and Handheld Devices

History

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here