

The Android sample app demonstrates the group discovery, playback and volume features, as well as how to handle changes to groups described in the Discover and Sonos Control API documentation. Download the APK or the source code package to follow along below. See the included README.md for additional details and release notes.
Sample App User Experience
The Android sample app illustrates a few core concepts about how to use the Control API to provide a good user experience. When you first open the app, it displays a list of Sonos groups on the network. You can choose a group on which to play music. Once you have chosen a group, the app displays what is currently playing in that group, including the album art, a previous button, a play/pause button, a next button, and a volume slider with the ability to mute audio in the group.
The app displays all of the Sonos groups on a home network, regardless of household (if you have multiple households in your network, you will see a list of groups that exist in different households). There is no way to load music on Sonos, so you must either already have music loaded or add it with a Sonos controller app. The album art will be blank until after music has started playing.
Download, set up, build, & test on Android device
Click the buttons at the top of this page to download the APK or source code package.
- Android Control API Sample App.apk – click the download link above from your Android device to install the APK directly on your device. Be sure to allow installation from unknown sources.
- Android Control API Sample App Source Code Package – download this package and see the README.md file for instructions on how to set up, build, and test the app in Android Studio.
Sample App Architecture
The sample app uses Java interfaces for group discovery, handling changes to groups, playback, and volume. The SonosPlayer
class implements the playback, volume, group management interfaces and the SonosGroupDiscovery
class implements the group discovery interface. The sections below describe how the app uses these interfaces to offer these features. The sample code is richly commented. It has been edited for brevity below, please see the actual source code for more details.
Discover groups
First, your app must discover groups on the network. The sample app uses SSDP with both UDP multicast and broadcast messages, as described in the Discover documentation.
The SonosGroupDiscovery
class implements the GroupDiscoveryInterface
interface to find and display a list of groups on the network. The group discovery interface has a listener interface for finding Sonos groups and the class includes methods to start and stop group discovery and return events.
1 2 3 4 5 6 7 8 9 |
public interface GroupDiscoveryInterface { interface Listener { void onGroupDiscoveryUpdate(Map<String, HashMap<String, String>> groups); } void start(); void stop(); void listen(GroupDiscoveryInterface.Listener listener); void unlisten(GroupDiscoveryInterface.Listener listener); } |
The implementation does this by finding the groups that your app can connect to on the local network using SSDP messages, parsing and processing messages, and updating the list of groups in the group selection menu. It also identifies changes to groups by handling UDP multicast messages, as well as sending three M-SEARCH multicast and broadcast requests one second apart, while the group menu is displayed. We broadcast as well as multicast to support Wi-Fi routers that have issues with multicast messages.
Handle group changes
Once a user has selected a group and has started playing music, controlling playback, or controlling volume with your app, you must have a way to handle changes to the this group. The SonosPlayer
class implements the GroupManagementInterface
to handle and forward events about changes to the selected group. Players will send groupCoordinatorChanged
events when the group coordinator has been moved, updated, or is gone, but your app should also handle cases when the group is not reachable, or your app is not able to connect to it, such as when there are network delays.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public interface GroupManagementInterface { interface Listener { void onGroupCoordinatorMoved(String wsAddress); void onGroupCoordinatorUpdated(String groupName); void onGroupCoordinatorGone(); void onGroupNotReachable(); void onGroupUnableToConnect(); } void listen(GroupManagementInterface.Listener listener); void unlisten(GroupManagementInterface.Listener listener); void connect(String address, String groupId); void disconnect(); boolean isConnected(); } |
Control playback
The app shows a screen with playback controls for the selected group. The SonosPlayer
class implements the PlaybackInterface
interface to play, pause, go to the next track, or go to the previous track.
1 2 3 4 5 6 7 8 9 10 11 12 |
public interface PlaybackInterface { interface Listener { void onPlayStateChanged(boolean playing); void onMetadataChanged(String albumArt, String title, String artist, String album); } void play(); void pause(); void nextTrack(); void previousTrack(); void unlisten(PlaybackInterface.Listener listener); void listen(PlaybackInterface.Listener listener); } |
Control volume
Users can raise or lower volume using the volume slider. The slider also displays volume changes made by other apps or from pressing the hardware buttons on players. The SonosPlayer
class implements the VolumeInterface
interface to set the volume and mute state.
1 2 3 4 5 6 7 8 9 10 11 12 |
public interface VolumeInterface { interface Listener { void onVolumeChanged(int volume); void onMuteStateReceived(boolean muted); void onFixedStateReceived(boolean fixed); } void setVolume(int volume); void setRelativeVolume(int volume); void setMuteState(boolean muted); void unlisten(VolumeInterface.Listener listener); void listen(VolumeInterface.Listener listener); } |
Throttle volume messages
The VolumeModel
class also implements the VolumeInterface.Listener
interface as a buffer to handle the messages sent when users scrub the volume slider. This class handles how to throttle messages to the group coordinator to improve the user experience, as otherwise, a large amount of messages can be sent to all players in a group, which causes them all to send events back, causing Wi-Fi network pollution (for example, if a user has 8 players in a group and scrubs the volume up and down several times a second).