Monthly Archives: July 2013

In developing the GClient (detailed in the preceeding post), I discovered for myself that the method to be implemented for some interfaces and object types (such as run() in a Runnable object) are done by declaring them as ‘abstract’ methods. This means when a programmer creates a new instance of that object, the abstract method that needs to be implemented is shown to be ‘filled up’ with context specific code. Below is an example:

This is an abstract method from my ‘PythonConnection’ class:

  * Implement this to act on data received
  * @param data String containing the data received from the remote python host
	public abstract void onReceive(String data);

When a new PythonConnection object is created, the opportunity to implement onReceive() is shown as below:

PythonConnection pyCon = new PythonConnection() {

			public void onReceive(String data) {
				//Put code to use the 'data' String here!
				//Update UI, send a response etc...


Where does the ‘data’ String come from, you ask? Well when the underlying Thread receives data from the BufferedReader, it calls onReceive(), supplying the String read from the Reader and continues listening once onReceive() returns. Here is where that occurs in a typical server (such as in the GClient):

  * Start the receiving thread that will call onReceive() when it has data
	private void startListening() {

		receiveThread = new Thread(new Runnable() {

			public void run() {
				listening = true;
				System.out.println("Ready to receive.");

				while(listening) {
					try {
						String packet = fromPython.readLine();
						if(packet != null) {
					} catch (IOException e) {


Previously to get around this ‘sending data across classes’ problem (which got especially nasty when Threads came into it) I would either pass the object creating the abstract object or use some sort of ‘shared static class’, which wasn’t ideal and generated problems of its own.

This is an example of one of the joys of exploring a language by using it! I foresee much use for this functionality.

GClientLOgoWhile developing a number of different minor projects that involved communication between Android and my laptop, Pebble or Raspberry Pi I found myself almost writing a new app for each project, with names like ‘PebbleButtonDemo’ or ‘AndroidTestClient’.

It occurred to me ‘why keep inventing the wheel?’, meaning that this was a wasted practice. The vast majority of these situations simply called for a TCP Socket connection that sent pre-defined commands as text strings. With that in mind, I conspired to create a general purpose app that did these things and did them well.

But in order to solve the problem of writing a new app for every application when the underlying mechanism remained the same, it needed more ‘customisability’ than simply an EditText for address and port. The next logical step to this is to allow each project/application (server, that is) to customize the general client on the Android phone to it’s purpose, and in this first incarnation offers the following ‘customisables’:

  • Android Activity title in the Action bar by sending “TITLE” + the new title String
  • A set of three customizable Buttons by sending ‘BUTTON” followed by the button number, button text and the command it should trigger to be sent back to the application server.
  • Protocols agreed for these actions in both Java and Python servers I’ve written.

More features are possible with a more advanced protocol, such as sending vectors to draw on the remote Canvas, or even images, but those will have to come later when a specific project calls for it.

So, upon opening the app, this is what is seen:

Screenshot_2013-07-25-22-37-13The key UI elements to note are:

  • The customizable Activity title.
  • The ‘I/O Traffic’ section, which contains a customized SurfaceView element (actually a subclass of my Android Game Engine), which fills up green when a connection is established and animates blue ‘bits’ left and right whenever data is sent or received.
  • The ‘Connection Settings’ section, which contains EditText fields for host address and port number, a Spinner for language selection on the application server side, and connect/disconnect Buttons.
  • The ‘Log History’ section contains a ScrollView housing a TextView that shows all events that take place, be they received data, sent commands or local events such as IOExceptions and disconnects.
  • The ‘Custom Buttons’ section, which houses the three customizable Buttons that can be setup from the application server side with details I’ll now detail below.

To continue the spirit of a general purpose app, I created static methods for setting up these customizable UI elements, shown below:

public class GClientTools {
	//Protocol configuration
	private static final String PROTOCOL_TITLE = "TITLE";
	private static final String PROTOCOL_BUTTON = "BUTTON";
	private static final String PROTOCOL_SEP_1 = ":";
	private static final String PROTOCOL_SEP_2 = ";";
	private static final String PROTOCOL_SEP_3 = ".";

	 * Use the GClient syntax to set the GClient Activity title
	 * @param inStream 	Established output stream.
	 * @param inTitle	Title to set to.
	public static void setTitle(PrintStream inStream,String inTitle) {
		String packet = PROTOCOL_TITLE + PROTOCOL_SEP_1 + inTitle;
		System.out.println("Title now '" + inTitle + "'. (" + packet + ")");

	 * Configure a GClient custom button
	 * @param inStream		Established output stream.
	 * @param inButtonNumber	Which button to customise. No range checking.
	 * @param inText		Text to display on the button.
	 * @param inCommand		Command the button will send back to this server.
	public static void setCustomButton(PrintStream inStream, int inButtonNumber, String inText, String inCommand) {
		String packet = PROTOCOL_BUTTON + PROTOCOL_SEP_1 + inButtonNumber + PROTOCOL_SEP_2 + inText + PROTOCOL_SEP_3 + inCommand;
		System.out.println("Button " + inButtonNumber + " now '" + inText + "' --> <" + inCommand + ">. (" + packet + ")");


As a test case, I wrote a quick application server that accepts the GClient connection and makes use of these static methods to set the Activity title and one custom Button. The I/O Traffic bar has filled up green and the Log History shows all events:

Screenshot_2013-07-25-22-36-50That’s it for now. The major things I learned writing this app were:

  • A much more stable and UI friendly threaded approach to networking, using four threads (UI, sending, receiving and connecting)
  • Precise Android XML UI design including nested layouts and more features of the RelativeLayout.
  • Setting Android UI views to use 9-Patch images and custom background styles and colours.

First version source code is available here! The GClientTestServer port is a constant field in the class file. The GClientTestServer also contains the GClientTools class in the util package, which I’ll be next using for adapting current project servers and eliminating a few test apps altogether!

Previous Tutorial Sections

All six previous parts of this tutorial series can be found on the ‘Pebble SDK Tutorial’ page link at the top of the page. Please read them if you are not already up to speed!


By request, this part of the tutorial will focus on using the ScrollLayer structure provided by the Pebble SDK. This is the Layer type used for menus, such as the main menu or settings menu. In fact, the MenuLayer itself contains a ScrollLayer!

The features of a ScrollLayer are thus:

  • It can be controlled with the up and down buttons to show more content that can fit on the screen at any one time.
  • It automatically shows ‘shadows’ at the top and bottom of the screen to indicate there is more to see in both the up and down direction.
  • It can contain all the Layers that it scrolls, making parent-child layer management easier.

Lets get started!

Using a ScrollLayer

To make use of this Layer type in a watch app, you will need something to display inside it. For this example, I’ll be using a snippet of text from, in a char array as shown below (using the fiendishly hidden WordPress code tags!):

char scrollText[] = "Pebble is the first watch built for the 21st century. It's infinitely customizable, with beautiful downloadable watchfaces and useful internet-connected apps. Pebble connects to iPhone and Android smartphones using Bluetooth, alerting you with a silent vibration to incoming calls, emails and messages. While designing Pebble, we strove to create a minimalist yet fashionable product that seamlessly blends into everyday life.";

You can use other Layer types, but this is good for simplicity.

As is usual for the Pebble SDK, we call functions to initialize and setup our Window and Layers, in the handle_init() function. I’ll show this process below, but first here are the constants and globals that will be making an appearance:

Window window;
ScrollLayer sLayer;
TextLayer tLayer;

//Maximum dimensions
static int WIDTH = 144;
static int MAX_HEIGHT = 1000;

//Compensate for top window bar
static int TOP_BAR_PADDING = 20;

And now the main code segment:

	* Resource initialisation handle function
void handle_init(AppContextRef ctx) {

	//Init window
	window_init(&window, "Main window");
	window_set_background_color(&window, GColorWhite);
	//Init ScrollLayer and attach button click provider
	scroll_layer_init(&sLayer, GRect(0, 0, 144, 168));
	scroll_layer_set_click_config_onto_window(&sLayer, &window);
	//Init TextLayer
	text_layer_init(&tLayer, GRect(0, 0, WIDTH, MAX_HEIGHT));
	text_layer_set_text(&tLayer, scrollText);
	text_layer_set_background_color(&tLayer, GColorClear);
	text_layer_set_text_color(&tLayer, GColorBlack);
	text_layer_set_text_alignment(&tLayer, GTextAlignmentLeft);

	//Get size used by TextLayer
	GSize max_size = text_layer_get_max_used_size(app_get_current_graphics_context(), &tLayer);
	//Use TextLayer size
	text_layer_set_size(&tLayer, max_size);
	//Use TextLayer size for ScrollLayer - this has to be done manually for now!
	scroll_layer_set_content_size(&sLayer, GSize(WIDTH, max_size.h + TOP_BAR_PADDING));
	//Add TextLayer to ScrollLayer to Window
	scroll_layer_add_child(&sLayer, &tLayer.layer);
	layer_add_child(&window.layer, (Layer*)&sLayer);

	//Show Window
	window_stack_push(&window, true);

Read through the code above line by line and see the new additions that you might not have seen before. Below are the ones of note:

  • scroll_layer_init() – This does the same sort of actions as window_init() or text_layer_init() and initializes the ScrollLayer supplied as the first argument.
  • scroll_layer_set_click_config_onto_window() – This gives the ScrollLayer the button click information from the containing window, so that it can respond to button pressed while in this window.
  • text_layer_get_max_size_used() – This returns a GSize that is the dimensions that the TextLayer that the ScrollLayer contains uses. The alternative here is to find the point size of the font and find by trial and error the vertical height from the number of lines the text ends up using – a waste of time!
  • scroll_layer_set_content_size() – This function uses the GSize created before to set the size of the ScrollLayer. Without this information it would not be able to tell how far to be able to scroll up or down. At the moment this must be done manually.
  • scroll_layer_add_child() – This function does the same as the layer_add_child() function we’ve used before for TextLayers being added to the Window, but this time the Layer supplied as an argument is added to the layout inside the ScrollLayer, and will therefore be scrollable.

Finally, after using layer_add_child() to add the ScrollLayer to the Window, you should be all set!


The ScrollLayer can be useful for showing a lot of information or a list. It does require some extra thinking about and setup, but it is worth it for the convenience!

Full source code for a sample watch app (derived from the ‘demos’ supplied with the SDK) can be found here.

Happy scrolling!

In an almost biblical revelation, I have found it IS indeed possible to post source code in a proper fashion on WordPress, making a virtual mockery of my Pebble SDK Tutorial pages, which I might update, but not for now. The code segments are available in source links in each post.

So, what better reason to make a new post using this newly discovered feature than to write about my latest Raspberry Pi escapade. I have a cheap HC-SR04 ultrasonic sensor that I used with an Ultrasonic library with my Arduino. Having since obtained a Pi, why not have it work with this new piece of kit?

After observing the timing requirements, it seemed simple enough to replicate that behavior with a short C program, shown below in all it’s copyable glory!

#include <stdio.h>
#include <stdlib.h>
#include <wiringPi.h>

#define TRUE 1

#define TRIG 5
#define ECHO 6

void setup() {
        pinMode(TRIG, OUTPUT);
        pinMode(ECHO, INPUT);

        //TRIG pin must start LOW
        digitalWrite(TRIG, LOW);

int getCM() {
        //Send trig pulse
        digitalWrite(TRIG, HIGH);
        digitalWrite(TRIG, LOW);

        //Wait for echo start
        while(digitalRead(ECHO) == LOW);

        //Wait for echo end
        long startTime = micros();
        while(digitalRead(ECHO) == HIGH);
        long travelTime = micros() - startTime;

        //Get distance in cm
        int distance = travelTime / 58;

        return distance;

int main(void) {

        printf("Distance: %dcm\n", getCM());

        return 0;

Which results in this output:


So now I know the distance to the ceiling!

So a few days ago I acquired a Raspberry Pi. This amazing board is a SoC (System on a Chip) that runs a version of Debian Linux called Raspbian. Since then I’ve been poking around and finding out how to do my favourite useful stuff (networking, Arduino etc), aided in a way by the basic knowledge of Linux commands obtained from dabbling in Ubuntu.

After learning how to send and receive data on a network with Python, and controlling the GPIO pins in the same way as Arduino using wiringPi, I decided to try and find a project to complete.

As I’ve said to people before when they ask me about leaning to program, a good motivator to learn new features and possibilities of a language is to set a small goal that is just out of reach. For example, say you’d learned enough Java to know how an object is constructed, data stored inside and methods called from it, the stretch goal might be to use a simple object provided by someone else.

In this spirit I decided to use a combination of Python, wiringPi and scripts to solve a problem I might have had in the near future. Using SSH, I can connect to and command the Pi from another computer, eliminating the need for a mouse, keyboard, HDMI display etc, leaving just ethernet and power connected. In order to do this, I need to know the Pi’s IP address. This piece of information is presented to the user when the board is booted, on either the RCA or HDMI display outputs.

The difficulty here is that the first time the Pi is connected, the IP address it is given will be pseudo-random, and unknown.

But what if you don’t have a TV or monitor in reach? When I move house in a few weeks time, what if the router is too far from the TV? I won’t be able to use this method to get the IP. I could connect to the Wi-Fi gateway, but that relies on the service provider implementing a mechanism for doing so, which I can’t rely upon.

This brings us back to finding a project to do. As I’ve posted on this very blog, I managed to use an Arduino to show short messages on a standard LCD display, using the LiquidCrystal library. Why not use this display to show the IP address? No TV needed!

As I quickly found, the LiquidCrystal library didn’t appear to be included in wiringPi. Luckily, the author had implemented their own version, the lcd.h header file, with similar functions. So, after making the requisite connections between the boards, and being careful to note these for later use, I had a simple C file that sends a string to the LCD display, when presented as an argument from the terminal. If the argument is too long ( > 16 characters), it is not accepted, and the display instead shows “Too long!”. If it is between 8 and 16 characters, then it is copied into two buffers each 8 characters in size, then displayed alternately.

Once this was done, I wrote a Python script (with help from here) that determined the IP address, and then called the compiled executable that took the address as the argument and send it to the LCD display.

So far so good. But the main purpose of this exercise was to get around the combined problem of not knowing the IP address assigned by DHCP when the Pi is first introduced to a LAN, and having to TV guaranteed to be within reach. The final step therefore was to have the Python script run on boot. The final process is summed up below:

  1. Boot script /etc/rc.local executes the Python script.
  2. The Python script in turn finds the IP address and calls the LCD executable, supplying the address as an argument.
  3. The LCD executable sends the IP address to the LCD display
  4. I use the IP address now visible to the world to connect using SSH, saving it for later use in the process.

I think that’s mission accomplished! Here is a photo of the finished system in action:

IP cutoutAs is usual for this type of post, you can find the C and Python source files, as well as a built C executable here. The LCD display pin map is included as a comment in the C file. The Raspberry Pi pins used by the wiringPi library can be found here.

Previous Tutorial Sections

All five previous parts of this tutorial series can be found on the ‘Pebble SDK Tutorial’ page link at the top of the page. Please read them if you are not already up to speed!


One of the main selling points of the Pebble smartwatch is the fact that it can run apps that communicate with a companion app on an iPhone or Android smartphone. Indeed, it is impossible to get started without one. In the spirit of openness that is also a major selling point, this part of the tutorial series will describe how to accomplish such a task, enabling a much richer watch app experience.

Thanks to the remarkable amount of example code and documentation provided in the relatively early Pebble SDK v1.12, a lot of the code I will be using and showing here is derived from these examples. No need to fix what isn’t broken, and all that! They’ve done an excellent job on this one already.

As I have mentioned previously, I will only be covering the phone app side from an Android perspective, due to the fact I don’t own an iOS device or agree with Apple’s pricing policy to enter the ecosystem, but that’s just personal opinion.

It is assumed that the reader is already familiar with basic Android app development and the application lifecycle. If not, I could write an Android primer, which would in turn require a working knowledge of Java. We’ll see if that is required! Please let me know so I can gauge demand.

AppMessage system overview

On the Pebble platform, this is done using the AppMessage system. On the watch and on the phone, data is stored inside data structures called Dictionaries. When data is send or received, it is stored in data structures called Tuples. A Tuple contains a key and the data itself in what is known as a key-value pair. The key is a ‘label’ for that data and is constant.

For example, if you were writing an app to show the weather, you might have an int to store the temperature. You create a key (number) to identify this data, and all these keys are the same on both the watch app and the phone app. Lets set the key for the temperature variable to a value of ‘5’. The phone sends a Dictionary consisting of a tuple with the temperature data contained within, with a key value of ‘5’. When this data arrives on the watch app, because the key identifying the temperature variable is the same as on the phone app, the Dictionary is searched for the tuple with key value ‘5’, and knows the accompanying data is the temperature to be displayed.

If that explanation leaves you wanting, here’s an diagram that will hopefully make it clearer:

key and data life

Common App Features

In order to make sure that the phone app sends data to the correct watch app, both apps must use the same UUID to identify them. This has already been covered for the watch app, so here is how this is done on the phone app:

UUID member

Here is how the phone app would store the keys. Remember that these should be identical to those declared on the watch app!


Watch App Specifics

On the watch app side of things, as predicted there is a use of handler functions to manage the following events:

  • Send successful – AppMessage was sent successfully
  • Send failed – AppMessage failed to send (or was not Acknowledged by phone app)
  • Receive successful – AppMessage received from phone app
  • Receive failed – AppMessage received but dropped due to lack of space or some other error

The first stage to implement this new functionality is to add the following lines to the PebbleAppHandlers in pbl_main():

pbl_main additions

Next, create the handler functions with matching names to those referenced in the ‘.message_info’ callbacks section in pbl_main() for each of the four callback scenarios in the bullet points above. Four blank handlers are shown below:

blank handlers

Sending data to the phone app

To send data to the phone app, a Dictionary is constructed and filled with the tuples describing the data to be sent, using the appropriate keys. Here is an example function that takes an int and sends it to the phone app (adapted from the one provided in the SDK examples):


The argument sent here would be matched with a corresponding action on the phone app. In this example project (link to the source code will be at the end) each of the three buttons is given a key of 0, 1 or 2 (Select, Up, Down). When the up button is pressed,  the watch app sends ‘1’ to the phone app. Because the keys are the same on both sides, when the phone app receives ‘1’ it can use that to perform the action the programmer wants to perform upon an up button press.

Receiving data from the watch on the phone

On the phone app side, the Dictionary is received in a callback method which is registered with the Android system when the app starts, in onResume():


Hopefully you can see that when the callback is triggered, the data is identified by the key, again it must correspond to the key on the watch app. This value is then used in a switch statement to decide what action to take. The phone app must first acknowledge (ACK) the data so the watch app doesn’t report a timeout.

Another important note is that the callback must be unregistered in onPause() when the phone app is closed to prevent events being missed. Here is how that is done:


Sending data back to the watch app

Going back in the opposite direction, data is sent to the watch app by making use of a PebbleDictionary and key-value tuples. The methods used for this are provided by the PebbleKit SDK packages, which you can use and import by copying the packages into the ‘src’ folder of your Android project (shown here in Eclipse IDE for Java Developers):


The process for sending data from the phone app to the watch app is largely similar to the same process started from the watch app:

  1. Create the Dictionary (or PebbleDictionary in this case)
  2. Populate it with key-value tuples containing the data to be sent
  3. Send the Dictionary using the UUID (same as the watch app UUID)

This process is summarised in the image below, with comments for clarity:

send to pebble

Receiving data on the watch app

The final part of this process is receiving data from the phone app. This is done by (you guessed it!) extracting data from a Dictionary sent from the phone app and provided by the callback handler as an argument.

  1. A DictionaryIterator is used to search the Dictionary for data using the pre-defined key for that identifies the data received.
  2. This data is stored in a tuple
  3. The tuple contents can then be used as you wish

In the example below, the Dictionary is searched for the string data associated with the DATA_KEY, which was send from the phone app using the same key. This string is then displayed in a TextLayer for the user to see that the data has arrived successfully. Note that the Pebble OS automatically ACKs the received AppMessage:

using received data on watch


So there you have it! Sending data from watch, receiving it on the phone, then sending data from the phone to the watch and using it. I’ll admit, this is the most complicated part of this tutorial series so far, and I hope to provide a bit more of a bridge from API Documentation to understanding the examples.

The example project source code can be found here!

Please feel free to post any questions here on in my Pebble Forum thread, and I’ll do my best to answer. If there is a lot of demand, I may write an Android primer too, but that’s probably another series in itself, and there are plenty of superb ones just a Google search away!

Lots going on at the moment, so here’s a list of what’s coming soon (also a personal reminder!):

  1. Pebble SDK Tutorial Part 6 is written, just needs images. 2 Way Communications.
  2. Java <-> Pebble text bridge Android Service.
  3. Raspberry Pi obtained, working on Java <-> Pi text bridge using Pi Python.

Got to do my best not to lose sight of a current project!

So, a while ago now I created an iterative Android game engine, and used it to port Raiders. It went pretty well, and I got good performance out of it. But an almost inevitable truth I have come to accept in starting a new project based off an old (This time being porting Railways to Android) is that by the time I revisit the old code, I’ve learned so much more that it makes me wince to even read it.

There have been occasions where I’ve reduced the size of a source file by three times or more, simply by applying much more precise implementation conventions. It ends up faster, more memory efficient and easier to read and tweak. This is all good!

While I was contemplating this new port, it occurred to me I could make things a lot simpler for myself by creating a general Engine class, and simply extending it whenever I wanted a specific game implemented.

The general philosophy I’ve adopted for making games on Java and Android has been an iterative game loop and render loop. This means that for each frame, every in-game object gets one update() call (so move once etc), then one render() call to draw it. When the Java engine was made threaded, performance increased even more, but the same could not be applied to my Android phone, which is only single core. After an attempted implementation, performance was pretty inconsistent, which I chalked up to perhaps the constant changing of Thread context. We may never know.

Getting back to the new ideas, I’ve cleaned up my Android engine to the point where the state machine is internalised along with all the touch IO. To implement a new ‘menu <-> in-game’ style game all I have to do now is extend the engine and override six functions:

  • loadMenuMembers() – Allocate all objects that appear in the menu
  • loadGameMembers() – Allocate all objects that appear in-game
  • menuUpdateLoop() – Update all interactive objects in the menu
  • gameUpdateLoop() – Update all the interactive objects in-game
  • menuRenderLoop() – Render all the menu objects
  • gameRenderLoop() – Render all the in-game objects

These functions are called at the appropriate times by the superclass engine, and so the rest can be ignored by the coder, leaving them to focus on only the elements of their game.

Much simpler!

Links to Previous Sections:

Here are links to the previous sections of this tutorial. Read them if you haven’t to get up to speed!

Part #1: Beginner’s Primer to the C Language

Part #2: Applying the Primer to the Pebble SDK

Part #3: Setting Up a Ubuntu Environment for Development

Part #4: Anatomy of your First Watch Face


In this section we will be looking at some more advanced features of the Pebble SDK you can apply to your watch faces. These are animations, images and fonts.

Animations allow you to create smooth movement of Layers on screen. Images can  enhance the look and feel of your watch face but come with a few constraints. Fonts offer the easiest real customisation of the text elements of the watch face, most importantly those that tell the time!

As each new feature type is introduced, I’ll explain the conditions and limitations, the functions used to implement the them as well as sample functions I’ve written as ‘wrappers’ to the lines of code you may find yourself writing together over and over again, to make things simpler.

The Resource Map

First, a key part of any watch face that uses outside resources such as bitmap images and fonts is the Resource Map file. This is a JSON file that tells the compiler where all the resources you have used in your watch face are, so it can include them in the install package.

Whereas your source file lives in /src/, the resource map lives in /resources/src/. The resources themselves are easiest located along side, for example, an image might go in /resources/src/images/ and a font in /resources/src/fonts/.

The exact syntax of each resource referenced in this file can be found here, but the form is easy to copy or mimic for each new resource you add, with a couple of example below:

JSON example

Don’t worry if you can’t make complete sense of straight away!

In the source file side of things, you must initialise the resources you plan to use in the ‘handle_init’ function before you can use them. This is shown below:

Resource init

Make sure the APP_RESOURCES name matches that in the versionDefName in the JSON file itself.

This function call allows you to use the resources as named in the JSON file when functions ask you for the RESOURCE_ID.


Animations allow a static watch face to come alive and become more expressive. An example of an implementation of these can be found in my Split Horizon: Seconds Edition watch face. Blocks slide in from the top to mark the 15, 30, 45 and 60 second marks, and two half-screen-sized InverterLayers come in and out again to reveal the new time when the minute ticks over.

To do all this, you need to use a structure called PropertyAnimation. When using this to animate a Layer of your choice, you must do a number of steps in a certain order.

  1. First, initalise the PropertyAnimation with the PropertyAnimation structure, the Layer to be moved and start and end locations (GRects)
  2. Set the duration of the animation (in milliseconds) and the curve type (Easing in or out for example)
  3. Schedule the animation. As soon as this is called, the animation will start pretty much instantaneously.

As promised earlier, here is a function that neatly wraps up all this into one function call you can use to make the main function easier to read (Click the image to see it better):


An extra stage you can take to make the animations more complex is to use the delay feature. With a second tick handler, the fastest you can have animations start is on each second tick. But with the delay feature, you can add, say, a 500 ms delay and have one animation start half a second after the first. Here is another wrapper function, see if you can spot the difference:


The final note on this is that at the moment the PropertyAnimation can only animate properties of a Layer. There are details in the API documentation the show you how to implement an animation for pretty much anything, but it is beyond the scope of this tutorial series.

Images (Bitmaps)

Another way to add detail to your watch  face is to include some images. Some traditional watch faces use a bitmap background with hands or text time drawn on top for added effect.

The recommended format of images to be used is a 2-colour (black and white in other words) ‘.png’ file that is less than the size of the screen (common sense, to save space). Here is an example image:


Due to the black and white nature of these images, shades of gray are impossible. The next best thing however is to use a technique known as ‘dithering’, which alternates black and white pixels to emulate a shade of gray from a distance.



Getting the balance right with dithering is all trial and error, but I find that 60% or 80% is a good value, depending on the nature of the image.

Now that you have your image, place it in the right directory. You can choose this but the path must be mentioned relative to the project root folder (The folder containing the /src/ and /resources/ directories). Once this is done, add a reference to it in the JSON file, with a memorable name. An example is below:

png def

The ‘type’ is the file type. The ‘defName’ is the name you will use in the source file. The ‘file’ is the path of the resource file relative to the JSON file.

The next step is to make sure you are initialising the Resources in your main source file, as shown in the ‘The Resource Map’ section above.

Finally, call the requisite functions from the API documentation to initialise and place your image on the watch face. Again, here is an annotated wrapper function as an example:



Finally we come to fonts. These are slightly easier to use than bitmaps, but still require the proper declaration in the JSON, initialising app resources etc.

A font file to be used on a watch face should be a ‘.ttf’ TrueType font. Many are available for free from sites on the web. Once you have one you like (You can install it and test it out in Word or the system font viewer), place it in the correct folder. Again, you can choose this, but it must be written precisely in the JSON declaration. Here is an example:

def font

It is important to note that the point size of the font to be used is declared using the ‘_XX’ at the end of  the defName in the JSON file. See the example image above for just that (This will be font size 30). Therefore you can have almost as many font sizes as you like from just one font file. You do not need to include multiple copies of the same ‘.ttf’ file for each size font you want to use.

Once this is done, and the app resources have been initialised as mentioned in the last two sections, you can use it as a font in a TextLayer of your choosing in the watch face source file. Here is how that is done (This is another long one, click it to see it clearly):



So there you have animations, images and fonts. Go wild. But not too wild, because there are file size limits on the install packages (‘.pbw’ files), although I’ve yet to hit them in normal use.

Next Time

In the next part I will be detailing how to perform simple communications with a connected Android app. I’m afraid that due to available devices and iOS costs, Android will be the only perspective offered. Sorry!

If you are unfamiliar with Java and/or Android app development, speak up either here or on my General Discussion thread and I will fill in the gap with a Java and Android Primer!