Android 11 Quick Device Control Gotchas

This post contains a few details on implementing a Quick Access Device Control for Android 11+. As of writing (Jan ’21), this is a relatively new feature and there aren’t many support resources out there for it. To help address this in some small part, here are a few gotchas I stumbled on while implementing it for a smart lights app I’ve been working on.

Getting Started

The first step, if you haven’t done so already, is to read through Google’s developer guide on this feature:

https://developer.android.com/guide/topics/ui/device-control

As far as Google’s docs go, this one isn’t too bad. It gives a overview of the most important points. However, there are some finer points it doesn’t address which you’ll most likely run into as you start to code.

With any luck, you might find answers for these in the helpful Q+A section that follows!

Q+A / Gotchas

Q: What should I put for MY_UNIQUE_DEVICE_ID? Does it need to be globally unique to prevent conflicts with device controls for other apps?

Device IDs should identify not just a type of device (e.g. “Philips Hue bulb”) but an instance of a particular device, and remain stable over time. End users add devices to the quick access section for an app, and the platform remembers which devices they’ve added using this unique device ID.

As far as I can tell device IDs are scoped to your app, so you don’t need to worry about your IDs conflicting with those from other apps. I.e. you don’t need to create some kind of fully-qualified ID including your package name.

Q: What is a template ID and why do I need to provide it?

The quick access device control API makes use of reactive streams of immutable objects to update its UI. Because of this, it needs a way of identifying a particular template over time, independent of its object identity. This is where the template ID comes in. It lets the platform code know that two template objects with different properties (say a different title or range value) are actually referring to the same UI widget if their template IDs match.

Q: How should a communication error with my device by signaled back from performControlAction()? Via the existingPublisher for the device or the Consumer<Int> parameter?

Via publisher. The Consumer parameter is just for signalling that the control action was received successfully, not necessarily that it was delivered to the device.

Q: How do I know when it’s safe to disconnect from the device or cleanup other resources?

Add a doOnCancel()listener to the Flowable returned by createPublisherFor(). It will be called when the Quick Access Device Controls UI goes to the background.