This post in our Android Wear developer tutorial series is a collection of thoughts, tips, and experiences related to developing apps for Android Wear. I collected these items here because previous posts in this series are already lengthy enough, but there were still some things that I thought might be useful.
Android Data Layer – Things to Know About Data Items
Using the Message Api, you can pass a message with an optional payload to a specific node (node simply refers to a device on the wearable network, i.e. a wearable device or the handheld device that the wearables are paired with). However, the Android Wear Data Layer is capable of more than merely passing a piece of data from one device to another. When you use a DataItem, your data is automatically synced to all nodes on the wearable network, even if they are not currently connected. Here are some things to be aware of regarding data items:
- Data items can be placed on the data layer even when there are no other nodes currently connected. When a node later connects, it will then the receive the data change event.
- Using a DataMap is a convenient way to place items on the data layer, although a data map only supports certain types. In order to use a custom object, you will need to provide some way to marshall and unmarshall the object. One way to do that is to convert the object itself to a DataMap (i.e. write all of its properties to the data map as name/value pairs). A DataMap is one of the types that can be placed on a DataMap, meaning that all of your custom objects can be individually converted to DataMaps and placed in a single DataMap, which can then be used to sync the data item on the data layer.
- If the same data item is placed on the data layer more than once (i.e. it has not changed since that last time it was placed on the data layer), it will not trigger multiple data change events. If you need to work around this, you can add an additional property that is always different, such as a timestamp.
Starting with Play Services 8.3, the Wearable DataApi allows a priority to be configured when syncing data items. It is important to know the the default is low priority, which means that it may take up to 30 minutes for your data to be synced to other devices. In my experience, it usually takes less than a minute, but sometimes you want your data to be synced immediately. In this case, you can call setUrgent on the PutDataReqeust. You can read more about it here.
Using Data Items in a Request/Response Model
Suppose you have an Android app that manages some sort of data, and now you want to extend it for wearable devices. The ideal situation would be to always keep the data layer up to date with the latest data. That way, whenever the wearable app needs to access the data, all it has to do is retrieve it from the data layer; there is no need to request anything from the handheld device because you always have current data. This would not be too difficult if your app is the only user of that data. Or, if the data is on a remote server where it can be updated by other clients, you could use push notifications to notify your app whenever the data changes.
However, sometimes this may not be possible, and your wearable app will need to request data on demand via the handheld device. Suppose that your wearable app requests data by sending a message to the handheld, and then waits for a response. The handheld app receives the message and retrieves data from the server and then places it on the data layer. If the data has not changed since the last time it was placed on the data layer, there will not be a data change event, and the wearable app will be left waiting for an event that will never come.
A simple way around this is to add a property to the data item that is always different, such as the current time in milliseconds. If using a data map, you can just do dataMap.putLong(System.currentTimeMillis()). Another option would be to delete the data item from the data layer as soon as it has been received by the wearable, to indicate that the data has been consumed.
Adding Wearable Api to the GoogleApiClient: addApi vs addApiIfAvailable
Throughout this tutorial, when creating a GoogleApiClient, I have used code like this:
GoogleApiClient googleApiClient = new GoogleApiClient.Builder(context)
If the Wearable Api is not available (e.g. the app is running on a handheld device and the Android Wear companion app is not installed), the attempt to connect to this client will fail. If all we are trying to do is access the wearable data layer (as is the case here), then this is not a big deal. Most of the time, all this means is that the user does not have any wearable devices.
However, if you are trying to connect to multiple Google APIs at the same time, then you probably don’t want the connection to fail simply because the wearable data layer is not available. In that case, you can use addApiIfAvailable:
GoogleApiClient googleApiClient = new GoogleApiClient.Builder(context)
//add more APIs
This way, a failure to connect to the Wearable Data Layer will not fail the entire connection. Before trying to access the Wearable API, you can check if it is available:
Communication Between Handheld and Wearable Apps
In order for your wearable app and handheld app to communicate with each other, Android must be able to determine that they are a part of the same application. To ensure communication between the two apps, be sure that:
- They have the same package. This is the “applicationId” in the module’s build.gradle file.
- They are the same version (versionCode in build.gradle).
- They declare the same permissions.
- They are signed with the same certificate.
These steps are also required when packaging the wear module within the mobile module, so that it can be distributed. See here for more information on packaging the wear module.
Developing and Testing the Wear Module
In general, when developing for Android, I have found it best to have a physical device that is attached to your development machine via USB to use for day to day testing. The same is true for Android Wear. You can use the emulator to run a virtual device for Android Wear, and even pair it with a handheld device, but in my experience there is no substitute for having real hardware on hand. The emulator is convenient for testing your layouts on a variety of screen shapes and sizes, and for testing specific features with different API levels, but it cannot match the speed and reliability of real hardware. When developing for Android Wear, I like to have both a real handheld device and a real wearable device that are paired to each other, both of which are connected to my development machine via USB.
To distribute your wearable app to users, it needs to be packaged with the handheld app, since users cannot install apps directly on a wearable device (see here for more information). However, for development, you can use Android Studio to directly install the wearable app to a connected wearable device. In the Android Studio toolbar, next to the Run button, select your Android Wear module and click Run. You will be prompted to select a compatible device (i.e. a wearable device), which can be either a virtual device or a connected physical device. As long as you have followed the steps in the previous section, your handheld app and your wearable app will be able to communicate using the data layer. Additionally, if you make a coding change to only one of the modules, only that module needs to be re-installed to the relevant device (handheld or wearable).
Sharing Code and Resources Between Modules
An Android Wear project will contain at least two modules: one for the handheld app and one for the wearable app. However, they will often have some things in common, such as resources (e.g. images and colors), model classes, etc. Of course, you don’t want to duplicate these items in each module. Instead, you can create a library module to contain these common items, and then declare it as a dependency in both the handheld and wearable modules. This way you can avoid duplication.
This concludes our Android Wear developer tutorial series. I hope you have found this series helpful. If you’re just finding this Android Wear Developer tutorial now, here are a couple links to the rest of the posts in the series: