All platforms allow controlling the audio level and mobile devices have got hardware buttons and soft keys to do so. But how would you change the audio volume from within a Xamarin.Forms app?
Recently, I had a discussion with somebody building Xamarin.Forms app where they would play back audio content and wanted to make sure that users can change the volume directly from within the app and also they wanted to be able to set the audio level for the app when first being launched. We could not find a complete existing solution, so I thought that a volume level UI control is maybe something that app developers might deem useful. The result is a multi target Nuget library, available here. Of course, you are invited to check out the source code over on Github.
VolumeSlider view is implemented for iOS and Android and features:
- Setting and getting the volume level
- Listen to system initiated volume changes via the devices native interfaces (hardware keys, soft keys) and updated itself to the current volume level
- Event based callback for volume level changes
- Data bindable
- Customizable colours and images
On Android, the implementation is essentially a clone of the Xamarin.Forms slider. I first thought about subclassing Slider and its renderer but then decided against because features like min and max values would not work correctly and also I needed additional functionality that just would not fit in there nicely. It is using Android’s AudioManager to set the current volume and MediaRouter to observe system initiated volume changes.
For iOS there is no direct access to the system’s volume. It’s all based on a special view called MPVolumeView. This view allows users to set the desired audio level but also to redirect output to AirPlay devices (Note: MPVolumeView can only be used on physical devices. On the Simulator the view simply won’t show up!). MPVolumeView is also the reason why I did not create a pure API based abstraction for getting and setting volume: a UI element is always required on iOS! To be able to set the volume level programmatically, I’m scanning the view hierarchy of the control to find the internal UISlider and update its value directly…yes, kind of a hack but that’s the only way to do it. 🙂
To use the plugin, install the Nuget first to all of your projects (Forms, iOS and Android):
PM> Install-Package VolumeSliderPlugin -Version 1.0.0
An example XAML page could then look like this:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:App1" x:Class="App1.MainPage" xmlns:vs="clr-namespace:VolumeSliderPlugin.Shared;assembly=VolumeSliderPlugin"> <StackLayout> <vs:VolumeSlider x:Name="volumeSlider" Volume="0.5" WidthRequest="300" HorizontalOptions="Center"/> </StackLayout> </ContentPage>
Hint: if you just want to control the volume purely programmatically, you can add VolumeSlider to your UI and hide it (or set the size to 0/0) and then update its Volume property.Insider knowledge 🙂