Skip to content

Enable preferred audio input device selection on Android#209

Merged
jfversluis merged 7 commits into
mainfrom
enable-bluetooth-recording-android
May 12, 2026
Merged

Enable preferred audio input device selection on Android#209
jfversluis merged 7 commits into
mainfrom
enable-bluetooth-recording-android

Conversation

@jfversluis

@jfversluis jfversluis commented May 10, 2026

Copy link
Copy Markdown
Owner

Problem

On Android, AudioRecorder and AudioStreamer hardcode AudioSource.Mic as the audio source, which always uses the system default microphone. There is no way to route recording through a Bluetooth headset, USB microphone, or other external input device.

Changes

1. New PreferredDevice property on BaseOptions (Android)

A new AudioDeviceInfo? PreferredDevice property (in BaseOptions.android.cs) allows consumers to select a specific input device:

var audioManager = (AudioManager)context.GetSystemService(Context.AudioService);
var btDevice = audioManager.GetDevices(GetDevicesTargets.Inputs)
    .FirstOrDefault(d => d.Type == AudioDeviceType.BluetoothSco);

var recorder = audioMgr.CreateRecorder(new AudioRecorderOptions
{
    PreferredDevice = btDevice
});

2. Apply SetPreferredDevice on AudioRecord and MediaRecorder

Both the AudioRecord (WAV) and MediaRecorder (AAC) recording paths now call SetPreferredDevice() when a preferred device is specified:

  • AudioRecord: API 23+ (Marshmallow)
  • MediaRecorder: API 28+ (Pie), called before Prepare()

Return values are checked and failures are logged via Trace.

3. AudioStreamer support

The AudioStream class (used by AudioStreamer) now also applies SetPreferredDevice() on its AudioRecord instance, so Bluetooth streaming works too.

4. Documentation

Added Android device selection section to audio-recorder.md with:

  • Code example for enumerating devices and setting PreferredDevice
  • API level requirements
  • BLUETOOTH_CONNECT permission note for Android 12+

Design: Opt-in only

PreferredDevice defaults to null — no behavioral change for existing users. The system default microphone is used unless the consumer explicitly sets a preferred device.

Closes #198

Companion PRs

  • #208 — iOS/macCatalyst Bluetooth recording support
  • #210 — Windows audio device selection

Copilot AI review requested due to automatic review settings May 10, 2026 11:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an Android-facing options API to allow callers to specify a preferred audio input device (e.g., Bluetooth/USB mic) and wires that preference into the Android recording implementations.

Changes:

  • Introduces BaseOptions.PreferredDevice (Android-only) for selecting an AudioDeviceInfo as the recording input.
  • Applies the preferred device to the AudioRecord (WAV) path via SetPreferredDevice.
  • Applies the preferred device to the MediaRecorder (AAC) path via SetPreferredDevice.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/Plugin.Maui.Audio/BaseOptions.android.cs Adds Android-only PreferredDevice option to the shared options base type.
src/Plugin.Maui.Audio/AudioRecorder/AudioRecorder.android.cs Attempts to route recording to the preferred device for both WAV (AudioRecord) and AAC (MediaRecorder).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/Plugin.Maui.Audio/AudioRecorder/AudioRecorder.android.cs
Comment thread src/Plugin.Maui.Audio/AudioRecorder/AudioRecorder.android.cs Outdated
Add PreferredDevice property to BaseOptions for Android, allowing
consumers to select a specific audio input device (e.g. Bluetooth
headset, USB microphone) via AudioDeviceInfo.

Changes:
- Add BaseOptions.android.cs with PreferredDevice property typed as
  AudioDeviceInfo from Android.Media
- Apply SetPreferredDevice on both AudioRecord and MediaRecorder after
  creation, before starting recording
- Guarded with OperatingSystem.IsAndroidVersionAtLeast(23) since the
  API requires Android Marshmallow (API 23+)

Usage:
  var audioManager = (AudioManager)context.GetSystemService(Context.AudioService);
  var btDevice = audioManager.GetDevices(GetDevicesTargets.Inputs)
      .FirstOrDefault(d => d.Type == AudioDeviceType.BluetoothSco);
  var recorder = audioManager.CreateRecorder(new AudioRecorderOptions
  {
      PreferredDevice = btDevice
  });

Companion to #208 which adds the equivalent iOS/macCatalyst support.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jfversluis jfversluis force-pushed the enable-bluetooth-recording-android branch from 380b4bf to 40f9f63 Compare May 10, 2026 11:26
jfversluis added a commit that referenced this pull request May 10, 2026
Add AudioDeviceId property to BaseOptions for Windows, allowing
consumers to select a specific audio capture device (e.g. Bluetooth
headset, USB microphone) by device ID.

Changes:
- Add BaseOptions.windows.cs with AudioDeviceId string property
- Pass AudioDeviceId to MediaCaptureInitializationSettings when
  specified, before initializing MediaCapture

Usage:
  // Enumerate available capture devices
  var selector = MediaDevice.GetAudioCaptureSelector();
  var devices = await DeviceInformation.FindAllAsync(selector);
  var btDevice = devices.FirstOrDefault(d => d.Name.Contains("AirPods"));

  var recorder = audioManager.CreateRecorder(new AudioRecorderOptions
  {
      AudioDeviceId = btDevice?.Id
  });

Companion to #208 (iOS/macCatalyst) and #209 (Android).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jfversluis and others added 3 commits May 10, 2026 13:37
- Move SetPreferredDevice before Prepare() for MediaRecorder, as
  Android requires configuration before Prepare()
- Fix API level check: MediaRecorder.SetPreferredDevice requires
  API 28 (Android 9), not API 23

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Apply SetPreferredDevice on AudioStreamer's AudioRecord instance so
  Bluetooth streaming works, not just recording
- Log SetPreferredDevice failures via Trace on both AudioRecord and
  MediaRecorder paths instead of silently ignoring return values
- Add Android device selection section to audio-recorder.md with code
  example, API level requirements, and BLUETOOTH_CONNECT permission
  note for Android 12+
- Update outdated text claiming only iOS/macOS options are customizable

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Required on Android 12+ (API 31+) for discovering and selecting
Bluetooth audio devices via AudioManager.GetDevices().

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jfversluis and others added 2 commits May 10, 2026 16:08
Add 'Select Input Device' picker to both the Audio Recorder and Audio
Streamer sample pages. On Android, the picker enumerates available input
devices via AudioManager.GetDevices and the selected AudioDeviceInfo is
passed via PreferredDevice on the recording options.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When a Bluetooth device is selected as preferred input, start SCO
connection and use AudioSource.VoiceCommunication instead of Mic.
This establishes the audio route needed for BT microphone capture.

Applied to both AudioRecorder and AudioStream.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jfversluis

Copy link
Copy Markdown
Owner Author

@copilot resolve the merge conflicts in this pull request

Co-authored-by: jfversluis <939291+jfversluis@users.noreply.github.com>

Copilot AI commented May 12, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts in this pull request

Resolved in 27712a3 by merging the latest main branch changes and reconciling the docs/sample conflicts while keeping the Android device-selection work intact.

@jfversluis jfversluis merged commit 6a7b61b into main May 12, 2026
2 checks passed
@jfversluis jfversluis deleted the enable-bluetooth-recording-android branch May 12, 2026 08:15
jfversluis added a commit that referenced this pull request May 12, 2026
* Enable audio input device selection on Windows

Add AudioDeviceId property to BaseOptions for Windows, allowing
consumers to select a specific audio capture device (e.g. Bluetooth
headset, USB microphone) by device ID.

Changes:
- Add BaseOptions.windows.cs with AudioDeviceId string property
- Pass AudioDeviceId to MediaCaptureInitializationSettings when
  specified, before initializing MediaCapture

Usage:
  // Enumerate available capture devices
  var selector = MediaDevice.GetAudioCaptureSelector();
  var devices = await DeviceInformation.FindAllAsync(selector);
  var btDevice = devices.FirstOrDefault(d => d.Name.Contains("AirPods"));

  var recorder = audioManager.CreateRecorder(new AudioRecorderOptions
  {
      AudioDeviceId = btDevice?.Id
  });

Companion to #208 (iOS/macCatalyst) and #209 (Android).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address review feedback

- Move AudioDeviceId from BaseOptions to AudioRecorderOptions so it
  only appears on recorder options, not player/streamer
- Use string.IsNullOrWhiteSpace instead of IsNullOrEmpty to reject
  whitespace-only values

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add Windows device selection docs and invalid device ID warning

- Add Windows device selection section to audio-recorder.md with
  code example for device enumeration via DeviceInformation API
- Document that invalid/disconnected device IDs throw (no silent
  fallback unlike Android)
- Remove outdated 'iOS/macOS only' text from recording options section
- Add XML doc warning about exception on invalid device IDs

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add input device selection to sample app

Add 'Select Input Device' picker to the Audio Recorder sample page.
On Windows, the picker enumerates audio capture devices via
DeviceInformation.FindAllAsync and the selected device ID is passed
via AudioDeviceId on AudioRecorderOptions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jfversluis <939291+jfversluis@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Audiostreaming on android does not use bluetooth device

3 participants