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

Wearable Compass : A journey from sample to awesome app

0.00/5 (No votes)
8 Oct 2015 1  
This article will give you a walk-through from sample android wearable app to Nice pro app.

          

1 - Introduction

It has been a long time since I wrote an article in codeproject but I often visit this community and it's time that I write one now. In this article I will focus on how to a make simple and fine app for an android wearable device. I must say wearable devices have a lot of potential in the future. Right now it's in transforming phase so resources are not available to learn about development of wearable technology, I will try to make this article simple and end up with a fine compass app. It will be good for learners especially who are interested in android and are ready to give a chance to wearable devices. As a mobile developer I personally believe if you have a good knowledge in android then making a wearable device app is very easy for you. Here in this article I will start with basics of android wearable device and then move to make a nice and clean compass app.

2 - Background

I usually make android application using Xamarin (Yea! I feel much comfortable in c# ) so I picked Xamarin for android wear app. As making android app in Xamarin exactly same as compared to android development in official Android Studio or Eclipse. The plus point is that you can use many C# functions which is real beauty of Xamarin Studio. I can mention a lot of advantages of Xamarin but this will be out of scope for this article. Let me give some high level advantages of Xamarin

  • Xamarin technology allows you to keep Native UI across all three platforms.
  • Xamarin is integrated with SDKs of all of the different operating systems
  • Best Native experience app
  • Single codebase share to all mobile platform
  • You can use your c# powerful function like extension, delegate, lambda , Linq etc. in mobile development

That’s enough about  Xamarin. If you want more information on this you can look here

P.S. As I mentioned Xamarin Android development is similar to development on Android Studio or Eclipse. So it really doesn’t matter in which IDE you want to make the application.

3 - App walkthrough

I am assuming that you have basic knowledge in android app development. This article will walkthrough only to android wearable app development from small app to finesse compass app.

Many android wearable device article available for beginner in internet and all start with the famous app Hello World. But IMO if you want to understand new mobile platform then start with playing with inbuilt UI functionality. This will give you basic knowledge that how UI interact with the code behind?

Anyway Final app which you gonna make looks like below – (Nice yaa!)

Square Wearable-                                                                                                            Round Wearable-                   

4 - Kickoff wearable app

Lets start with brief information on requirement and setup.

a) Prerequisites-  You need following tool for wearable development

  1. Wearable development IDE ( i.e. Xamarin, Android Studio or Eclipse)
  2. Android SDK Tool must be version 23 or higher.
  3. Install wearable emulator from android SDK manager.
  4. Setup emulator

Bonus information: Many of people know about official android emulator, running on GPU and slow in nature. So some of free lightning emulators are available for  android development.

  1. Genymotion emulator – It is free for personal use and runs on virtualbox. You can get more information here
  2. Xamarin Android player- This is also free emulator and runs on virtualbox. More information here
  3. Visual studio emulator for android- This is my favorite emulator and it runs on hyper-V . Very fast and it has multiple android device images which are available to use. It have multiple option to simulate shake, battery, network, GPS etc . For your information this emulator will work for any platform i.e Android Studio, Eclipse etc. you can get more information here

b) Setup Android wearable emulator- As mentioned above in the bonus information all emulators are only for the android mobile app. So far android wearable app you have to stick to the official emulator (which is slower and has no simulation), At least till other emulators for wearable devices are available.

Setup of android wearable device is easy. Install android wearable image from android manager and create AVD (Android Virtual Device) just like that.

You can see there are two kind of emulator available for wearable device

  1. Rounded wearable device
  2. Square wearable device

(Image from google official wear site)

So for making app you have to consider both kind of wearable devices so that you can target multiple devices in the market.

Bonus Information- if you want to connect Physical device to android emulator you have to forward port as shown in the image given below-

In the command prompt window, type: adb -d forward tcp:5601 tcp:5601. Then hit Enter. If the steps are successful, your command prompt will look like the example below. If you have a problem, make sure that your phone is connected properly to the computer.

5 - Create sample project (Basic learning)

Here is the setup to create sample project – Assuming you installed Xamarin in visual studio,

  1. Open visual studio and create new project as wear app under android

  1. Wear App have scaffolding app and if you look project hierarchy is similar as what in android studio and eclipse

  1. Open layout folder and you will notice it have three file
  • Main.axml – Called in main activity class
  • RectagngleMain.axml- As we already discussed currently wearable have two size – Square and Round. So if you want your app specific to rectangle device then modified android xml accordingly. Android give option to detect type of wear and render appropriate activity at runtime. I will discuss this thing later. For now it’s a good practice if your app UI is consistent across wearable devices.
  • Roundmain.axml – same as above
  1. Open main.axml
<?xml version="1.0" encoding="utf-8"?>

<android.support.wearable.view.WatchViewStub xmlns:android="http://schemas.android.com/apk/res/android"



    xmlns:app="http://schemas.android.com/apk/res-auto"



    xmlns:tools="http://schemas.android.com/tools"



    android:id="@+id/watch_view_stub"



    android:layout_width="match_parent"



    android:layout_height="match_parent"



    app:rectLayout="@layout/RectangleMain"



    app:roundLayout="@layout/RoundMain"



    tools:context=".MainActivity" />

as you can see in highlighted part it will render specific xml according to type of watch – to do more

  1. Though you can make different UI for rect and round devices but for sake of ease I will make same xml configuration in RectangeMain.axml and RoundMain.axml.

Now just add button and Textview in xml like below :

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"



    xmlns:tools="http://schemas.android.com/tools"



    android:orientation="vertical"



    android:layout_width="fill_parent"



    android:layout_height="fill_parent"



    tools:context=".MainActivity"



    tools:deviceIds="wear_round">

    <Button



        android:id="@+id/myButton"



        android:layout_width="fill_parent"



        android:layout_height="80dp"



         android:gravity="center"



        android:text="Click" />

    <TextView



        android:id="@+id/myText"



        android:text="Sample"



        android:layout_height="40dp"



        android:gravity="center"



        android:layout_centerHorizontal="true"



        android:textColor="@android:color/white"



        android:layout_width="wrap_content" />

  </LinearLayout>

Note: did you notice this is exactly same as in android app development?

  1. Now add some code part which is also very easy to understand
public class MainActivity : Activity

    {

        int count = 1;


        protected override void OnCreate(Bundle bundle)

        {

            base.OnCreate(bundle);


            // 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);

                TextView headingDegree = FindViewById<TextView>(Resource.Id.myText); ;

                button.Click += delegate

                {

                    headingDegree.Text = string.Format("You clicked button at {0}", count);

                    count++;

                };

            };

        }

    }

Most of the above code is pretty self explanatory but I want to focus on watchviewstub. Remember, main activity only have WatchViewStub layout definition file. The layouts that you specify for square or round screens are not inflated until WatchViewStub detects the shape of the screen, so your app cannot access their views immediately. To access these views, set a listener in your activity to be notified when the shape-specific layout has been inflated.

So Output like as

That’s it. Notice wear development is quite similar to android mobile app development.

Voila you made your first wear app though it’s ugly but hope you will get flavor of wear development also you have seen how these easy steps of development are followed to make simple app in android wear. Indeed, it's very similar to make android mobile app.

Let's make something which is easy, crisp, bold and beautiful app for wearable device.

6 - Create Compass app (Awesome app)

Before making a great compass app I would like to draw your attention towards image size for wearable android device. You must understand designed standard for android wear devices. You can get more information in official wear site here

As for compass app I will use multiple background image so you should be careful for image dimension. 

At the moment using a 320x320 bitmap should cover all the bases for you.

Here are details:

  • Asus Zen Watch: 320x320 pixels, density 1.75, 182dpx182dp
  • Gear Live: 320x320 pixels, density 1.75, 182dpx182dp
  • LG G Watch: 280x280 pixels, density 1.5, 186dpx186dp
  • LG G Watch R: 320x320 pixels, density 1.5, 213dpx213dp
  • LG Urbane: 320x320pixels, density 1.5 213dpx213dp
  • Moto 360: 320x290 pixels, density 1.33, 240x217dp
  • Sony Smartwatch: 320x320 pixels, density 1.75, 182dpx182dp

So I have compass background image of size 320x320. I get this image from an open source community.  For making your own compass you can use any background compass image.

I also uploaded multiple color themes , in case you are intrested to make your own compass app for wearable devices in your own way

Enough of talk now let's jump into the coding part. As from above image it have two image and two textview

  1. Use same sample app and delete all content in RectagngleMain.axml and RoundMain.axml.
<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"



    xmlns:tools="http://schemas.android.com/tools"



    android:orientation="vertical"



    android:layout_width="fill_parent"



    android:layout_height="fill_parent"



    tools:context=".MainActivity"



    tools:deviceIds="wear_round">

    <ImageView



        android:id="@+id/imageViewCompass"



        android:layout_width="wrap_content"



        android:layout_height="wrap_content"



        android:layout_below="@+id/tvHeading"



        android:layout_centerHorizontal="true"



        android:src="@drawable/scompass" />

    <ImageView



        android:id="@+id/imageViewDial"



        android:layout_width="wrap_content"



        android:layout_height="wrap_content"



        android:layout_gravity="center"



        android:layout_centerHorizontal="true"



        android:src="@drawable/dialbig" />

    <RelativeLayout



        android:layout_width="match_parent"



        android:layout_height="match_parent"



        android:gravity="center">

        <TextView



            android:id="@+id/headingDirection"



            android:text="NE"



            android:textSize="25dp"



            android:textStyle="bold"



            android:layout_height="40dp"



            android:layout_below="@+id/imageViewDial"



            android:gravity="center|top"



            android:layout_centerHorizontal="true"



            android:textColor="@android:color/white"



            android:layout_width="60dp" />

        <TextView



            android:text="320\u00B0"



            android:id="@+id/headingDegree"



            android:textSize="15dp"



            android:layout_height="50dp"



            android:layout_below="@+id/imageViewDial"



            android:textColor="@android:color/white"



            android:layout_width="60dp"



            android:gravity="center|bottom"



            android:layout_centerHorizontal="true" />

    </RelativeLayout>

and here is the code. Code is well commented and very easy to understand.

public class MainActivity : Activity,ISensorEventListener
   {
       //Initialize sensor manager for compass direction
       private SensorManager sensorManager;
       private float currentDegree = 0f;

       //Initilaize global variable for UI view
       ImageView outerDialImage;
       ImageView dialImage;
       TextView headingDirection;
       TextView headingDegree;
       protected override void OnCreate(Bundle bundle)
       {
           base.OnCreate(bundle);

           // Set our view from the "main" layout resource
           SetContentView(Resource.Layout.Main);

           // Initilize system sensor service
           sensorManager = (SensorManager)GetSystemService(SensorService);

           // WatchViewStub determine wearable type and render view accordinglr from specfic xml defination
           var v = FindViewById<WatchViewStub>(Resource.Id.watch_view_stub);

           //Infalte watchviewstub
           v.LayoutInflated += delegate
           {

               // Get elemnt from the layout resource,
               outerDialImage = FindViewById<ImageView>(Resource.Id.imageViewCompass);
               headingDirection = FindViewById<TextView>(Resource.Id.headingDirection);
               headingDegree = FindViewById<TextView>(Resource.Id.headingDegree);
               dialImage = FindViewById<ImageView>(Resource.Id.imageViewDial);

           };
       }

       protected override void OnResume()
       {
           base.OnResume();
           // Listen sensor manger on resume activity of app
           sensorManager.RegisterListener(this, sensorManager.GetDefaultSensor(SensorType.Orientation),SensorDelay.Game);
       }

       protected override void OnPause()
       {
           base.OnPause();
           // stop listening if app is no longer used. This is importent step otherwise it will drain your watch battery.
           sensorManager.UnregisterListener(this);
       }

       public void OnAccuracyChanged(Sensor sensor, SensorStatus accuracy)
       {

       }

       public void OnSensorChanged(SensorEvent e)
       {
           //Get sensor degree
           float degree = (float)Math.Round(e.Values[0]);

           //values[0]: Angle between the magnetic north direction and the y-axis around the z-axis (0 to 359), where 0=North, 90=East, 180=South, 270=West.
           //values[1]: Rotation around x-axis (-180 to 180), with positive values when the z-axis moves towards the y-axis.
           //values[2]: Rotation around x-axis, (-90 to 90), increasing as the device moves clockwise.

           //calculate direction coordinal
           headingDirection.Text = CalculateDirection(degree);

           // Set text for degree
           headingDegree.Text = Convert.ToString(degree) + "\u00B0";
           outerDialImage.Rotation = degree;

           //currentDegree is updated with the value of -degree so that the next animation will start from the new position.
           currentDegree = -degree;
       }

       private string CalculateDirection(float degree)
       {
           if (degree > 322 && degree < 54)
               return "NE";
           if (degree > 235 && degree < 322)
               return "NW";
           if (degree > 148 && degree < 235)
               return "SW";
           if (degree > 54 && degree < 148)
               return "SE";
           if (degree == 322)
               return "N";
           if (degree == 235)
               return "W";
           if (degree == 54)
               return "E";
           if (degree == 148)
               return "S";

           return "NE"; //Default :)

       }
   }
  1. SensorManager lets you access the device's sensors. Get an instance of this class by calling Context.getSystemService() with the argument SENSOR_SERVICE.  As you can see outerimage have set rotation by calculating degree in sensor so it will rotate according to magnatic field.
  2. As you can see in below gif image that both textview are updating from  
    OnSensorChange

calulated degree param value option are

//values[0]: Angle between the magnetic north direction and the y-axis around the z-axis (0 to 359), where 0=North, 90=East, 180=South, 270=West.
//values[1]: Rotation around x-axis (-180 to 180), with positive values when the z-axis moves towards the y-axis.
//values[2]: Rotation around x-axis, (-90 to 90), increasing as the device moves clockwise.

  1. Always make sure to disable sensors you don't need, especially when your activity is paused. Failing to do so can drain the battery in just a few hours. Note that the system will not disable sensors automatically when the screen turns off.              

Final Output in wear emulator:

Points of Interest

I hope its a great fun to make application for android wearable and few point which may be you will intrested .

  1. Wearable technology is here to stay. I believe that this article hioghlights some of its features that can help you understand the phenomenon of app building. The illustration of this compass app and insights to other basic things required to make an app of such kind will help in furthering your understanding for other such wearable teachnology apps. Hope this article severs its purpose.
  2. If you want to use android studio or eclipse then app flow is almost the same. You will easily corelate article c# code in java. If you still have confusion, feel free to contact me.
  3. Added Multiple compass theme if you are intrested to make your own compass app.

if you enjoyed this article then I deserve a 5 star :) (it will boost my morale to make more apps like this)

And If you really liked this article or have any suggestion or question, Please post in the comment section.  

History

  • Release Version: 1.0

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