Develop Android Wear Apps with Xamarin and Visual Studio

Develop Android Wear Apps with Xamarin and Visual Studio

Build a development environment

The first thing we need to do is install the necessary tools. Therefore, you need to install Visual Studio first. If you are using Visual Studio 2010, 2012 or 2013, then make sure it is a Professional version or higher, because the Xamarin extension for Visual Studio does not support the Lite version. For more information, see https://xamarin.com/faq.

For me, I used Visual Studio 2013 Untimate. Once you have a supported version of Visual Studio installed, proceed to download the Xamarin extension for Visual Studio from http://xamarin.com/visual-studio. (You can try it for free or apply for a license).

From now on, just follow the instructions in the downloaded wizard until the installation is complete. You may need to restart your computer in order to use the extension properly.

Now, when you start Visual Studio normally, you should be able to see the following items under the Tools menu as shown.

Figure 1: Android Tools and SDK

To make sure everything you need is installed correctly, you can verify it through the Android SDK Manager. To do this, just open Tools > Android > Android SDK Manager. This will open the window shown below:

Figure 2: Android SDK Manager

Now, after making sure you have everything you need installed, you can start creating your own Android applications using Xamarin in Visual Studio.

Creating a simple Android wearable app

First, let's create a new Visual Studio project and select Android > Wear App (Android) from the templates. You should be able to see something like the following image.

Figure 3: Visual Studio template list

Now, just click OK to let Visual Studio generate the files you need to create a wearable application. The image below shows the default generated files. Note: Sample code is provided to get you started building a wearable application.

Figure 4: Default wearable application code

It's easy, isn't it? The URL for the official documentation on Xamarin.Android application profiling is http://developer.xamarin.com/guides/android/getting_started/.

Run the program

In order to run the application without a real device, we first need to build an emulator program. You can create an emulator program by following the steps below.

Go to command Tools > Andriod > Andriod Emulator Manager or click on the AVD icon on the toolbar. Refer to the image below.

Figure 5: Android built-in emulator program

After that, the Android Device Manager window should be displayed. Here we can edit, start, create, delete or repair virtual devices.

Now, we need to click on the "Create" button. The window in the image below should open, allowing you to select the device you would like to create. In this case, we only need to create a virtual Android wearable device to run our application on the emulator.

Figure 6: AVD dialog box

Once everything is set up, just click OK to create the virtual device. In the image below, you should be able to see the device you just created through the AVD Manager.

Figure 7: AVD Manager

Now, just click Start > Launch to run the simulator in the background. Note that it may take some time for the system to load the simulator. Once the simulator is loaded and ready, you should be able to see the name of the virtual device you just created appear in the Start debugging drop-down list.

Figure 8: Newly created virtual device

Now, set your application as the startup project and press F5 to run it. The following figure shows the output of the sample wearable application in the simulator program.

Figure 9: Output

Keep in mind that the default emulator integrated into Visual Studio is a bit slow and is only suitable for testing small applications. To create and test applications in real development, I would recommend using the Xamarin Android Player (https://developer.xamarin.com/guides/android/deployment,_testing,_and_metrics/debug-on-emulator/) to emulate android applications.

That’s it! If you want to refer to more examples of wearable device applications, just visit this link: http://developer.xamarin.com/samples/android/Android%20Wear/.

Synchronize data between Android wearable devices and handheld devices

Let's go a little further and create a working application that supports communication between your wearable app and your handheld device. This exercise will demonstrate how to synchronize data between your Android apps.

Creating an Android Wearable Device App

To get started, let's start Visual Studio 2013 and select the command "File" -> "New" -> "Project...". In the templates select C# > Android and choose Wear App (Android) Project.

Name your application and click OK to have Visual Studio generate the necessary files for you. In this exercise, the program is named "WearDemo". The image below shows the files generated by the default sample code to help you write a wearable device application.

Figure 10: Wearable device application project

Before we start modifying the default code, I want to point out that there are two ways to communicate between the wearable device and the handheld device, namely DataApi and MessageApi. Below is a short description of each API.

DataApi: It exports an API for components to read or write data items (Items) and related resources (Assets). Among them, DataItem provides data storage and supports automatic synchronization between PDAs and handheld devices. Assets are used to send Blob data such as images. You only need to associate Assets with DataItems, and the system will automatically implement other processing for you. For details, please read this URL (https://developers.google.com/android/reference/com/google/android/gms/wearable/DataApi).

MessageApi: It provides an API for components to send messages to other nodes. Messages should usually contain small payloads. You should use Assets and DataApi to store large data. For details, read this URL (https://developers.google.com/android/reference/com/google/android/gms/wearable/MessageApi).

In this particular demo application provided below, I am going to use DataApi to send/sync data between devices. Since DataApi is part of Google Play Services, the first thing we need to do is add the following namespace reference:

  1. using Android.Gms.Common.Apis;
  2.  
  3. using Android.Gms.Wearable;

Android.Gms.Common.Apis allows us to use GoogleApiClient, which is the main entry point for integrating Google Play Services. Android.Gms.Wearable enables us to use the WearableClass class. The next step is to extend our MainActivity class, which requires inheriting the following interface:

1. IDataApiDataListener

2. IGoogleApiClientConnectionCallbacks

3. IGoogleApiClientOnConnectionFailedListener

IDataApiDataListener is used to receive data events. The callback function provided by the IGoogleApiClientConnectionCallbacks interface is called when the client connects to or disconnects from the service. The callback function provided by the IGoogleApiClientOnConnectionFailedListener interface is called when the client fails to connect to the service.

To summarize, the sample code for sending data to a handheld device is as follows:

  1. using System;
  2.  
  3. using Android.Runtime;
  4.  
  5. using Android.Widget;
  6.  
  7. using Android.OS;
  8.  
  9. using Android.Support.Wearable.Views;
  10.  
  11. using Java.Interop;
  12.  
  13. using Android.Gms.Common.Apis;
  14.  
  15. using Android.Gms.Wearable;
  16.  
  17. using System.Linq;
  18.  
  19. namespace WearDemo
  20.  
  21. {
  22.  
  23. [Activity(Label = "WearDemo" , MainLauncher = true , Icon = "@drawable/icon" )]
  24.  
  25. public class MainActivity : Activity,IDataApiDataListener, IGoogleApiClientConnectionCallbacks, IGoogleApiClientOnConnectionFailedListener
  26.  
  27. {
  28.  
  29. private IGoogleApiClient _client;
  30.  
  31. const string _syncPath = "/WearDemo/Data" ;
  32.  
  33. protected override void OnCreate(Bundle bundle) {
  34.  
  35. base.OnCreate(bundle);
  36.  
  37. _client = new GoogleApiClientBuilder(this, this, this)
  38.  
  39. .AddApi(WearableClass.Api)
  40.  
  41. .Build();
  42.  
  43. // Set our view   from the "main" layout resource
  44.  
  45. SetContentView(Resource.Layout.Main);
  46.  
  47. var v = FindViewById<WatchViewStub>(Resource.Id.watch_view_stub);
  48.  
  49. v.LayoutInflated += delegate {
  50.  
  51. // Get our button from the layout resource,
  52.  
  53. // and attach an event to it
  54.  
  55. Button button = FindViewById<Button>(Resource.Id.myButton);
  56.  
  57. button.Click += delegate {
  58.  
  59. SendData();
  60.  
  61. };
  62.  
  63. };
  64.  
  65. }
  66.  
  67. public void SendData() {
  68.  
  69. try {
  70.  
  71. var request = PutDataMapRequest. Create (_syncPath);
  72.  
  73. var map = request.DataMap;
  74.  
  75. map.PutString( "Message" , "Vinz says Hello from Wearable!" );
  76.  
  77. map.PutLong( "UpdatedAt" , DateTime.UtcNow.Ticks);
  78.  
  79. WearableClass.DataApi.PutDataItem(_client, request.AsPutDataRequest());
  80.  
  81. }
  82.  
  83. finally {
  84.  
  85. _client.Disconnect();
  86.  
  87. }
  88.  
  89. }
  90.  
  91. protected override void OnStart() {
  92.  
  93. base.OnStart();
  94.  
  95. _client.Connect ();
  96.  
  97. }
  98.  
  99. public void OnConnected(Bundle p0) {
  100.  
  101. WearableClass.DataApi.AddListener(_client, this);
  102.  
  103. }
  104.  
  105. public void OnConnectionSuspended( int reason) {
  106.  
  107. Android.Util.Log.Error( "GMSonnection suspended " + reason);
  108.  
  109. WearableClass.DataApi.RemoveListener(_client, this);
  110.  
  111. }
  112.  
  113. public void OnConnectionFailed(Android.Gms.Common.ConnectionResult result) {
  114.  
  115. Android.Util.Log.Error( "GMSonnection failed " + result.ErrorCode);
  116.  
  117. }
  118.  
  119. protected override void OnStop() {
  120.  
  121. base.OnStop();
  122.  
  123. _client.Disconnect();
  124.  
  125. }
  126.  
  127. public void OnDataChanged(DataEventBuffer dataEvents) {
  128.  
  129. var dataEvent = Enumerable.Range(0, dataEvents.Count )
  130.  
  131. . Select (i => dataEvents.Get(i).JavaCast<IDataEvent)
  132.  
  133. .FirstOrDefault(x => x.Type == DataEvent.TypeChanged && x.DataItem.Uri.Path.Equals(_syncPath));
  134.  
  135. if (dataEvent == null )
  136.  
  137. return ;
  138.  
  139. //do stuff here
  140.  
  141. }
  142.  
  143. }
  144.  
  145. }

Now let's explain what's happening in the code above. In the OnCreate event, we build a Google Play Services client, which includes the Wearable API. Then, we call the SendData() method in the button's click event handler to send the data. The SendData() method contains the actual logic for sending the data. Specifically, we create a DataMapRequest request by passing the data object path (i.e. WearDemo/Data). The actual data is a DataMap, which contains a Message value and an UpdatedAt value. The recipient can use the path to determine the source of the data described later in this article.

event

1.OnStart: This event is triggered when the activity starts and is used to connect to the data layer.

2.OnConnected: This event is triggered when the data layer is connected successfully.

3.OnStop: This event is triggered when the data layer connection is disconnected, and the activity stops. You can use OnConnectionSuspended and OnConnectionFailed to implement the corresponding connection callbacks (for example, in this demonstration we log errors and detach services).

4.OnDataChanged: This event is triggered when the data changes.

Things to keep in mind

1. Paths should always start with a forward slash (/) character.

2. The timestamp is a must when sending data, because the OnDataChanged() event is only triggered when the data is really changed. Adding the timestamp to the data will ensure that the method is called.

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

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

Create the main program project

In order to test the synchronization and data sending, we need to create a main Android application that will be responsible for receiving the data objects from the wearable device. This main application will be installed in a handheld device (such as a mobile phone or tablet).

Now, right-click on the solution project and select the command "Add->New Project". In the "Add->New Project" window, select "Visual C# > Android > Blank App (Android)". You should be able to see something like the following:

Figure 11: Android main program project

For simplicity, I named the project MainAppDemo. After that, just click OK to let the system generate the required files for you. Finally, you will see the result as shown in the figure in the solution interface.

Figure 12: Solution Explorer

Before we start adding logic to the main application, I want to highlight two points:

First point: the namespace of your wearable device application and main application should be the same. In this example, the namespace used by the wearable application is "WearDemo". So, be sure to rename your main application's namespace to "WearDemo" to match. To change the default namespace, you can refer to these steps:

(1) Go to the command "Project->Properties->Default Namespace".

(2) To change other items, you can use the CTRL + H shortcut to replace the default namespace with WearDemo.

(3) You can also use the refactoring code technique to change the namespace. To do this, just right-click the namespace and select the "Refactor->Rename" command.

Second point: The package name of your wearable device program and the main application should also be the same. You can find the package name by right-clicking the project and selecting "Properties->Android Manifest" as shown in the image below:

Figure 13: Android configuration file

Please make sure that both package names are set to "WearDemo.WearDemo". Make sure that both projects build successfully. Once you have done this, you can move on to modifying the project. First, change the "Compile using Android version" to the "API Level 21 (Xamarin.Android v5.0 Support)" API. Please refer to the image below:

Figure 14: Application Settings

In the References section, check if you have referenced Xamarin.Android.Support.V4. If you don't, you can also right-click References and select Manage NUGET Packages. Then, search for "Xamarin.Android.Support.V4" under "Online > Nuget.Org". You should be able to see something like this:

Figure 15: NuGet Package Manager

Just click on Install and wait until the task is completed. Now, you need to do the same and install "Xamarin.Android.Wear-1.0.0".

Add service WearableListenerService

Extending the WearableListenerService service allows you to listen to any updates in the data layer. The system manages the lifecycle of the service: you bind to the service when you need to send data items or messages; and you unbind the service when there is no work to do. For more details, please refer to this URL (https://developers.google.com/android/reference/com/google/android/gms/wearable/WearableListenerService).

After that, we will use WearableListenerService to listen to update events sent from the data layer and process the data. So, the next step is to add a class that extends WearableListenerService. To do this, right-click the project root and select "Add->Class", then name it "WearService". The complete logic implementation code of this class is given below.

  1. using System.Linq;
  2.  
  3. using Android.App;
  4.  
  5. using Android.Content;
  6.  
  7. using Android.Runtime;
  8.  
  9. using Android.Gms.Wearable;
  10.  
  11. using Android.Gms.Common.Apis;
  12.  
  13. using Android.Support.V4.Content;
  14.  
  15. namespace WearDemo
  16.  
  17. {
  18.  
  19. [Service]
  20.  
  21. [IntentFilter(new[] { "com.google.android.gms.wearable.BIND_LISTENER" })]
  22.  
  23. public class WearService : WearableListenerService
  24.  
  25. {
  26.  
  27. const string _syncPath = "/WearDemo/Data" ;
  28.  
  29. IGoogleApiClient _client;
  30.  
  31. public override void OnCreate() {
  32.  
  33. base.OnCreate();
  34.  
  35. _client = new GoogleApiClientBuilder(this.ApplicationContext)
  36.  
  37. .AddApi(WearableClass.Api)
  38.  
  39. .Build();
  40.  
  41. _client.Connect ();
  42.  
  43. Android.Util.Log.Info( "WearIntegrationreated" );
  44.  
  45. }
  46.  
  47. public override void OnDataChanged(DataEventBuffer dataEvents) {
  48.  
  49. var dataEvent = Enumerable.Range(0, dataEvents.Count )
  50.  
  51. . Select (i => dataEvents.Get(i).JavaCast<IDataEvent)
  52.  
  53. .FirstOrDefault(x => x.Type == DataEvent.TypeChanged && x.DataItem.Uri.Path.Equals(_syncPath));
  54.  
  55. if (dataEvent == null )
  56.  
  57. return ;
  58.  
  59. //get data from wearable
  60.  
  61. var dataMapItem = DataMapItem.FromDataItem(dataEvent.DataItem);
  62.  
  63. var map = dataMapItem.DataMap;
  64.  
  65. string message = dataMapItem.DataMap.GetString( "Message" );
  66.  
  67. Intent intent = new Intent();
  68.  
  69. intent.SetAction(Intent.ActionSend);
  70.  
  71. intent.PutExtra( "WearMessage" , message);
  72.  
  73. LocalBroadcastManager.GetInstance(this).SendBroadcast(intent);
  74.  
  75. }
  76.  
  77. }
  78.  
  79. }

The above code implements the OnDataChanged event, which is responsible for filtering data events sent from the "TypeChanged" event. Specifically, it checks the data object path "/ WearDemo /Data" and then broadcasts it locally.

Create the Main Activity

Given below is the code section of the main Activity:

  1. using Android.App;
  2. using Android.Content;
  3. using Android.Widget;
  4. using Android.OS;
  5. using Android.Support.V4.Content;
  6.    
  7. namespace WearDemo
  8. {
  9. [Activity(Label = "MainAppDemo" , MainLauncher = true , Icon = "@drawable/icon" )]
  10. public class MainActivity : Activity
  11. {
  12. TextView _txtMsg;
  13.    
  14. protected override void OnCreate(Bundle bundle) {
  15. base.OnCreate(bundle);
  16.    
  17. // Set our view   from the "main" layout resource
  18. SetContentView(Resource.Layout.Main);
  19.    
  20. // Get our TextBox from the layout resource,
  21. _txtMsg = FindViewById<TextView>(Resource.Id.txtMessage);
  22.    
  23.    
  24. IntentFilter filter = new IntentFilter(Intent.ActionSend);
  25. MessageReciever receiver = new MessageReciever(this);
  26. LocalBroadcastManager.GetInstance(this).RegisterReceiver(receiver, filter);
  27. }
  28.    
  29. public void ProcessMessage(Intent intent) {
  30. _txtMsg.Text = intent.GetStringExtra( "WearMessage" );
  31. }
  32.    
  33. internal class MessageReciever: BroadcastReceiver
  34. {
  35. MainActivity _main;
  36. public MessageReciever(MainActivity owner) { this._main = owner; }
  37. public override void OnReceive(Context context, Intent intent) {
  38. _main.ProcessMessage(intent);
  39. }
  40. }
  41. }
  42. }

In the above code, we registered to receive broadcast messages from the ListenerService in the OnCreate() event, then defined a nested class that inherits from the BroadcastReceiver class, implemented the OnReceive() method and extracted the relevant data. Finally, the Process() method is responsible for handling the display of data to the UI.

layout

Open the file Main.xaml and replace the original content with the following:

  1. <?xml version= "1.0" encoding= "utf-8" ?>
  2.  
  3. <LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android"  
  4.  
  5. android:orientation= "vertical"  
  6.  
  7. android:layout_width= "fill_parent"  
  8.  
  9. android:layout_height= "fill_parent" >
  10.  
  11. <TextView
  12.  
  13. android:id= "@+id/txtMessage"  
  14.  
  15. android:layout_width= "fill_parent"  
  16.  
  17. android:layout_height= "wrap_content"  
  18.  
  19. android:layout_marginTop= "50dp"  
  20.  
  21. android:gravity= "center"  
  22.  
  23. android:textColor= "@android:color/white"  
  24.  
  25. android:textSize= "80sp" />
  26.  
  27. </LinearLayout>

There is nothing special in the markup above. In summary, it mainly contains a text box for displaying a message.

Add metadata required by Google Play Services

Finally, we add metadata to the <application> element under the configuration file AndroidManifest.xml. The code is as follows:

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

Next, I'll describe how to deploy each application to each device and test the results.

Testing, debugging, and deploying programs

In this section, we will learn how to deploy and test the application in real devices. First of all, I need to explain that I use Nexus 9 and LG G Watch as my test devices.

Before we begin, make sure that the USB driver for Android is installed on your machine. You can verify this by right-clicking the command "Computer > Manage > Device Manager > Other Devices". If the driver is not in the list, then you must first download the driver (refer to this address: http://developer.android.com/sdk/win-usb.htmland) and install it (for installation methods, please refer to the link: 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 this feature using the command "Settings > Developer Options > Usb Debugging". Once you have installed the necessary drivers and enabled debugging support for your device, you can simply plug your handheld device into your PC or laptop. In Visual Studio, you should be able to see the connected handheld device displayed as shown below:

Figure 16: Project interface after connecting to the handheld device

Deploy the main program to the handheld device

Following are the main steps to deploy the main application:

(1) Right-click the main application project and select "Properties > Android Options". Then, uncheck "Use Fast Deployment (debug mode only)" under the Packaging tab.

(2) Uninstall the project.

(3) Edit the .csproj file and add a PropertyGroup section to it:

  1. <PropertyGroup>
  2.  
  3. <JavaMaximumHeapSize>1G</JavaMaximumHeapSize>
  4.  
  5. </PropertyGroup>

(4) Save the file and then load the project.

(5) Right-click the main application project and set it as the startup project.

(6) Build the application.

(7) Click the Run or Play button. The system will begin packaging and installing the application onto the device. Just wait a few moments for it to complete.

Deploy wearable device applications

You can follow the same process as above to deploy a wearable app. However, if you want to deploy and debug your app over Bluetooth, there are some additional steps required:

1) Open the Android Wear integration app on your handheld device.

2) Select Settings from the menu in the upper right corner.

3) Enable "Debugging Over Bluetooth". You should see output similar to the following:

Host: disconnected

Target: connected

4) Connect the PDA to your PC or laptop via USB.

5) In Visual Studio, go to Tools > Android > Android Adb Command Prompt and run the following command:

adb forward tcp:4444 localabstract:/adb-hub

adb connect localhost:4444

6) You should then be able to see the wearable device appear in the list of devices as shown in the image below:

Figure 17: Displays the successfully connected device

7) Repeat the same steps as steps 1-5 above to deploy the main program to the handheld device.

8) Now, set your wearable app as the startup project, build the app and run it.

Once the installation is complete, you should be able to set breakpoints in Visual Studio to start debugging and testing your application. Here is the output of the sample application:

Figure 18: Final output

Finally, you can download the source code of this article's demonstration project from Github for your reference.

summary

In this article, you have learned the following:

1. Have a general understanding of wearable devices and Android systems

2. Set up the development environment

3. Create a simple Android wearable device application

4. Created an application that keeps data synchronized between the wearable device and the Android handheld device

5. Test, debug, and deploy Android applications across wearable and handheld devices.

<<:  SmartGO, a new brand of Huidian Technology, is launched to promote mobile informatization of government and enterprises

>>:  SmartPoint Technology makes further efforts, and its mobile platform "SmartGO" helps government and enterprise mobile informatization

Recommend

It's about the college entrance examination! Be careful of these "pitfalls"!

The college entrance examination is a major test ...

[Single Lesson Encryption] [Exchange Meeting] Super Big Turning Point - He Yan

[Single course encryption] [Exchange meeting] Sup...

How to improve product conversion rate?

When we start promoting a product, we must first ...

Are they all cactus fruits? Why do dragon fruits come in so many colors?

Audit expert: Shen Tingting PhD in Botany Dragon ...

Where's my nose? Why can't I see it?

Audit expert: Liu Dongbao Chief Physician of Opht...

Please set your alarm, Mars will go retrograde at the end of the month!

October 30, 2022: The red planet Mars begins to m...

Can I optimize my phone without rooting? I tried these 10 apps

We cannot easily obtain root permissions on every...

Warcraft Movie: The Sunset of a Legendary IP

(Original title: Warcraft Movie: The Sunset of a ...