Create a Watch Face for Android Wear. Part 2: Let’s draw !

Charles-Eugène Loubao
5 min readOct 7, 2016

--

The part of the tutorial assumes you already setup your Android wear device or emulator. If you need proper instructions on how to do so I recommend reading this page first : https://developer.android.com/training/wearables/apps/creating.html#SetupEmulator

On Android Wear watch faces are implemented as Services . The Android Wear Support Library provides a base class that our watch face service needs to implement: WatchFaceService . In addition to the WatchFaceService we also needs a WatchFaceService.Engine. The WatchFaceService receives events from the system and passes those events to the WatchFaceService.Engine by calling the appropriate callback methods.

Our WatchFaceService provides the watch face engine by overriding onCreateEngine() . Most of the work will happen inside the MinimalWatchFaceEngine class

The CanvasWatchFaceService is a subclass of WatchFaceService that provides methods to respond to system events and a method to draw the watch face on a Canvas. In this part of the series we will focus on the following methods provided by CanvasWatchFaceService.Engine

  • onCreate(): Called when the engine is created for the first time
  • onDraw(): Where the actual drawing of the watch face happens

Now that we have a watch face service and a watch face engine we need to declare our service in the AndroidManifest.xml . The service is declared just like a regular Android service . The only difference here is that we add some metadata to the service’s declaration

Here’s a quick description of each metadata

  • android.service.wallpaper: Because WatchFaceService.Engine implements the WallpaperService class we need to provide an empty wallpaper xml file
watch_face.xml
  • com.google.android.wearable.watchface.preview: Preview Image for Square Watches used by the Watch Face picker on the watch or by the Android Wear App
  • com.google.android.wearable.watchface.preview_circular: Preview Image for Square Watch faces used by the Watch Face picker on the watch or by the Android Wear App

Because we don’t have our preview images yet I recommend creating an empty drawable in xml or provide a dummy image

  • The intent-filter tag is necessary for our watch face to be visible by user on the Watch Face Picker or the Android Wear Companion App

Now that we have our service setup it is time to try our useless (for now) watch face !

  1. Connect your watch or start your Android Wear Emulator
  2. Select the wear module on Android Studio
  3. and click the Play Button (Green arrow)

If after you click the green arrow you get a red message saying “ Error running wear: Default Activity not found” you need to update the module’s launch options and select “Nothing”

After you changed the launch options click OK. And run click the green arrow again

After the watch face is installed we can select it on our emulator or watch . As we expected nothing is displayed on the screen

Wow ! what a beautiful black screen !

Even though nothing is displayed on the screen, we now know that our basic implementation is working . We can now go ahead and starting drawing something

Drawing the watch face : Basics

CanvasWatchFaceService allows us to draw our watch face inside a Canvas . A Canvas in Android just like in real life is a surface on which we draw. On Android those drawings can be shapes (rectangles, squares, triangle, etc) or bitmaps, or text . To begin we will draw the time in milliseconds

Not really what we wanted

In onCreate() We initialize our drawing components. First we need a Paint object. A Paint object holds the information about the style of the text, shape or bitmap to draw. TextPaint is subclass of Paint optimized to draw text . In this case, we specify the text color to be White . You can change other properties such as text size, text alignment, typeface (font) , etc. More info available on the Developer Reference

The onDraw methods has 2 parameters: A Canvas to draw on and a Rect object containing the screen bounds . To Draw something on the screen we call one the Canvas.draw methods. In our case we used Canvas.drawText() . drawText takes the following parameters

  • The text to draw
  • The X Origin of text to draw
  • The Y Origin of the text to draw
  • A Paint object

In the android world, the X and Y origins represents the top left corner of the screen or of the element to be displayed / drawn

Rect.centerX() and Rect.centerY() returns the x and y coordinates of the middle of the rectangle relative to the x and y coordinates of the Rectangle object (x=0, y=0 by default)

Even though we wanted the text to be centered, our text has been drawn starting at the middle, which is not what we want . This happened because by using centerX and centerY as coordinates for the text we basically said that we want the text to be drawn starting at the middle of screen, not be located in the middle of the screen . To be able center properly the text, we need to know how big it is going to be . To do that we can use Paint.getTextBounds() to obtain a Rect object containing the text bounds .

To start drawing so that the text is perfectly in the middle, we will shift the from the center of screen of few pixels . To do that we subtract the text’s center X from the screen’s center X , and we subtract the text’s center Y from the screen’s center Y. We use Math.abs() to avoid negative values. This is what we get

Better isn’t it ?

Now that we know how to draw on a Canvas , in the next article we will draw the time in a readable format and update the watch face every minute.

The source code for that watch face is available on Github and will be updated as we go through concepts in this tutorial

Thanks for reading my article If you liked that article, please hit that heart button and share the article with others.

You can also checkout Foto, my watch face that inspired this series on the Google Play Store:https://play.google.com/store/apps/details?id=io.github.charly1811.android.watchface.foto

You can reach me on twitter at @celoubao or by emailcharlesloubao95@gmail.com

--

--