Making an Android Wear App

Dharmin Majmudar posted August 10, 2015

TripAdvisor helps you in multiple ways to plan your perfect trip right from finding places you would enjoy, getting trusted reviews from fellow travelers about that place, finding great restaurants that would enhance your trip and finally booking a relaxing hotel to end your perfect day. Once you are actually on your trip you would want to explore what’s nearby, and what better way to lookup something quickly than turning your wrist and launching TripAdvisor right on your watch.

Why make an Android Wear watch app?!

In certain situations using the watch to quickly get information is more natural than taking your phone out for doing that. However it does not make sense to port all the features from the phone app directly to the watch app. You need to assess which features (existing or new) should be implemented for the watch, and how the phone can help achieve that. Read on to know what you might need to consider for creating an Android Wear app that complements an existing full featured phone app.

Design decisions (Visual and Technical)

There are certain things that you need to make sure while developing for such a small form factor such as usability of the features being implemented, not running frequent processor intensive tasks on the watch directly, not transferring too much data back and forth between the watch and the phone to preserve battery on both ends, etc.

Using the right communication APIs

Currently there are three ways you can transfer data between the phone and the watch:

  • MessageApi – Good for issuing short commands and for request/response kind of communication model.
  • DataApi – Ideal for syncing data across multiple connected nodes and data can be set even if the node is not connected. The data will be synced once the node comes online.
  • ChannelApi  – Useful for efficiently transferring large amount of data such as audio or video.

The TripAdvisor Android Wear app uses the MessageApi as it primarily requests small text responses that would not make much sense to sync if the connected node goes offline because the user’s location would change frequently. Before sending a message you need to get the ID of the connected device and it is better to check for the connected device each time you want to send a message. This way if we detect that no phone is connected anymore we can notify the UI  on the watch to notify the user to connect to a phone.

Requesting location updates

Using Android’s fused location provider, it is possible to get very accurate location pretty quickly. The app leverages this to provide nearby points of interest pretty quickly with as much accuracy as possible. As soon as the watch app starts it pings the app on the phone, telling it to update the location so when the user clicks on an item to load, say restaurants, the phone uses the latest known location to fetch the list of items.

This algorithm could also be further improved by requesting location as soon as the watch app starts and waiting for a couple of seconds or until a location update is received (whichever is shorter) to query for places of interest. This makes sure the phone has more time to update the location before showing nearby locations to the user.

Requesting user actions and showing confirmations

Certain errors or requirements occurring while interacting with the watch app need to be communicated to the user effectively. Examples of such behavior in the our Wear app includes indicating to the user that they need to turn on location services to see the nearby locations, telling the user that they need to sign in on the phone app before they could save interesting points of interest, notifying the user that the selected location has been started on the phone for getting more details about it, etc.

Android provides ConfirmationActivity that takes a custom message and effectively communicates it to the user.

In the app we implemented a custom ConfirmationActivity to make the desired tweaks to the UI, while also keeping the messaging brief so that it does not clutter the small screen.

dm.sign-indm.no-location

Conserving Battery

The phone contains a bigger battery and a faster processor compared to your watch. Take advantage of that by doing as much processing of data as possible on the connected phone instead of deferring it to the watch. For instance if you are getting a JSON response from a web service, sending the whole response to the watch so that it can process and display only tiny portions of useful information out of it is wasteful for the watch’s battery in two ways:

  • You could possibly be sending lot of unnecessary data to the watch as your API might be initially intended for the phone to display all the returned data but since the watch does not display all of it, it doesn’t need all of it. So the bluetooth hardware would consume unnecessary power on the phone as well as the watch.
  • Secondly, parsing the full JSON response and converting it to a useful model (a minified version of the original model compared to the phone) would lead to the processor running for a longer time and eating up the battery.

One clear fix for that would be to process the API call on the phone itself and then transferring only the required amount of data to the watch. The phone can cache the full response and when the same request is made the phone can serve whatever minified version of the cached data is needed by the watch. Our Android Wear app uses this technique to keep the level of communication to a required minimum amount of data between the devices.

Circular vs Square Layout

Currently Android Wear comes in two shapes circle and square. You might need to handle the UI based on the shape of the screen. For instance you could design the layout completely differently for a square watch vs a circular one. There are multiple ways of achieving that:

  • Using the WatchViewStub which allows you to define multiple layouts based on different screen shapes.
  • Using BoxInsetLayout that extends from the FrameLayout and centers the contents of the layout on a circular watch to avoid UI flowing out of the visible area.
  • Implementing a View.OnApplyWindowInsetsListener which will get a callback indicating the shape of the screen and allowing you to handle the insets in a custom way.

Our app implements the third technique to get notified about the WindowInsets that the view needs to respect, in this case the parent GridViewPager that displays the list of locations for the nearby search. When the onApplyWindowInsets method is called for this listener we notify the underlying adapter about the shape of the screen and the adapter decides whether to show a fragment defined for the circular shape or the square one.

As can be seen the layout for each shape has been defined such that it doesn’t waste screen space and also does not clutter the views on either shape.

dm.Screen Shot 2015-06-30 at 9.18.07 PMdm.seq3-1

Defining user interactions

User interactions for the app are defined using standard guidelines from Google. In the app vertical swiping action switches between different points of interest while swiping horizontal allows to see different actions that fall under the same point of interest. For instance if the user searches for nearby restaurants, in the resulting grid swiping vertical the user can switch between different restaurants while swiping horizontally allows the user to save the location or launch it on the phone.

It is important to not switch the two gestures with each other as it won’t be as intuitive as with the UX in rest of the OS.The following images show how the grid items are laid out from top to bottom and left to right.

dm.seq3-1dm.seq1-2dm.seq1-3

dm.seq1-1dm.seq1-2dm.seq1-3

dm.seq2-1dm.seq1-2dm.seq1-3

Gradle and project configuration

If not handled carefully this could be a critical challenge for integrating the Wear app with the existing phone app. Make sure you follow the proper guidelines for packaging the Wear app along with the phone app from the Android developer website, taking proper care of versioning, signing keystores and adding dependency on the Wear module in the gradle file of the phone app. Also creating a shared module that the phone app and the watch app depend on would be a good idea since a lot of code would be repeating between the two apps such as messaging, message path URIs, etc.

Conclusion

Android Wear based watches are a pretty powerful companion to your phone and provides lots of opportunities to engage the user based on their interest and locations. Designed properly and efficiently, the Wear version of the app can greatly improve the user’s experience with the product.

 

One response to “Making an Android Wear App”

  1. Sneh says:

    This is an amazing article giving insights about how a good software engineer think 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *