Introducing Twilio’s AudioSwitch: Easily Manage Audio Devices on Android

August 25, 2020
Written by

Introducing Twilio’s AudioSwitch: Easily Manage Audio Devices on Android

Providing users with the ability to switch between the speakerphone, earpiece, or headset to handle audio input and output selection is a required feature for any real-time communication app. To implement audio device selection using the Android framework requires hundreds of lines of complex code. AudioSwitch was written to encapsulate the complexity of this feature and solves the following challenges:

  • Manage audio device selection
  • Detect changes in audio device availability
  • Handle audio device selection errors and timeouts
  • Provide a reliable Bluetooth selection service

Today, we are proud to announce the General Availability of AudioSwitch!

AudioSwitch enables developers to easily integrate audio device management into an Android application with the following capabilities:

  • Manage audio focus for VoIP and Video conferencing use cases
  • Manage audio input and output device selection
    • Detect changes in available audio devices
    • Enumerate audio devices
    • Select an audio device
  • Support for the following audio devices:
    • Bluetooth Headset
    • Wired Headset
    • Earpiece
    • Speakerphone

Getting Started with AudioSwitch

Setup

The AudioSwitch class needs to be instantiated with an application context reference passed as a constructor parameter.

val audioSwitch = AudioSwitch(applicationContext)

Only a single AudioSwitch instance is needed throughout the lifecycle of an app. Typically, Android applications use a dependency injection framework to inject dependencies into Android Components, and the AudioSwitch instance is a great candidate for an injectable dependency.

Listen for Devices

To begin listening for live audio device changes, call the start function:

audioSwitch.start { _, _ ->}

Note: Don't forget to stop listening for audio devices when no longer needed in order to prevent a memory leak.

audioSwitch.stop()

Select and Activate A Device

After audio devices are made available from invoking the start() function, a device can be selected for audio routing. This can be done either manually by the consuming application, or automatically by the library. By default the library will automatically select a device based on the following priority:

  1. Bluetooth Headset
  2. Wired Headset
  3. Earpiece
  4. Speakerphone

Here’s how to manually select a device (Speakerphone in this case) by querying the list of available audio devices.

devices.find { it is AudioDevice.Speakerphone }?.let { audioSwitch.selectDevice(it) }

If you would like your app to be notified as soon as changes in available audio devices occur, you can use the AudioDeviceChangeListener lambda as a parameter in the start function. The app could pass the devices to the UI to allow for the user to select a device for example.

audioSwitch.start { audioDevices, selectedAudioDevice ->
    // TODO Pass audioDevices to UI for user selection
}

After a device has been selected, it needs to be activated in order for the library to enable audio routing. This is required by the developer application since a common user experience for real-time communication apps is to allow users to select an audio device before engaging in a VoIP call or video call experience. Another reason these two operations are separated is because your app will acquire system audio focus when the library is activated. It is important in Android to only acquire audio focus when necessary and abandon it when it is no longer needed to provide a great user experience.

Activating and deactivating an audio device is simple after it has been selected. All that’s needed are the following lines.

audioSwitch.activate()
audioSwitch.deactivate()

Note: The stop() function will call deactivate() before closing AudioSwitch resources.

If subscribing to changes in system audio focus is important in your app, you can configure it via the following constructor parameter.

val audioSwitch = AudioSwitch(context, audioFocusChangeListener = OnAudioFocusChangeListener { focusChange ->
    // Do something with audio focus change
))}

All Done!

That’s all you need to know to get up and running with AudioSwitch in your app. We are very excited about this library and welcome any feedback.

Also, a big thank you goes out to the community for reporting 16 issues and submitting 3 pull requests for bug fixes and enhancements. Without these contributions, the library would not be in the stable condition that it is in today. Feel free to open any issues or open a pull request if you’d like to see something change more quickly. We can’t wait to see what you build with AudioSwitch!

Reference Applications

We have a few reference apps that utilize this library.

 

John Qualls is a Programmable Video and Voice Android Engineer at Twilio. His goal is to make developer’s lives easier when using the mobile SDKs by providing reference applications and libraries like AudioSwitch. He can be reached at jaltonqualls [at] twilio.com or on twitter at @John_A_Qualls.