4package org.qtproject.qt.android.multimedia;
6import java.util.ArrayList;
7import android.bluetooth.BluetoothA2dp;
8import android.bluetooth.BluetoothAdapter;
9import android.bluetooth.BluetoothDevice;
10import android.bluetooth.BluetoothHeadset;
11import android.content.BroadcastReceiver;
12import android.content.Context;
13import android.content.Intent;
14import android.content.IntentFilter;
15import android.media.AudioDeviceInfo;
16import android.media.AudioFormat;
17import android.media.AudioManager;
18import android.media.AudioRecord;
19import android.media.AudioTrack;
20import android.media.MediaRecorder;
21import android.util.Log;
25 private static final String TAG =
"QtAudioDeviceManager";
26 static private AudioManager m_audioManager =
null;
27 static private final AudioDevicesReceiver m_audioDevicesReceiver =
new AudioDevicesReceiver();
28 static private AudioRecord m_recorder =
null;
29 static private AudioTrack m_streamPlayer =
null;
30 static private Thread m_streamingThread =
null;
31 static private boolean m_isStreaming =
false;
32 static private final int m_sampleRate = 8000;
33 static private final int m_channels = AudioFormat.CHANNEL_CONFIGURATION_MONO;
34 static private final int m_audioFormat = AudioFormat.ENCODING_PCM_16BIT;
35 static private final int m_bufferSize = AudioRecord.getMinBufferSize(m_sampleRate, m_channels, m_audioFormat);
40 static private class AudioDevicesReceiver
extends BroadcastReceiver
43 public void onReceive(Context
context, Intent intent) {
51 IntentFilter audioDevicesFilter =
new IntentFilter();
52 audioDevicesFilter.addAction(AudioManager.ACTION_HEADSET_PLUG);
53 audioDevicesFilter.addAction(AudioManager.ACTION_HDMI_AUDIO_PLUG);
56 audioDevicesFilter.addAction(
BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED);
58 audioDevicesFilter.addAction(
BluetoothDevice.ACTION_BOND_STATE_CHANGED);
59 audioDevicesFilter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
60 audioDevicesFilter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED);
61 audioDevicesFilter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
62 audioDevicesFilter.addAction(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED);
64 context.registerReceiver(m_audioDevicesReceiver, audioDevicesFilter);
69 m_audioManager = (AudioManager)
context.getSystemService(Context.AUDIO_SERVICE);
72 private static String[] getAudioOutputDevices()
74 return getAudioDevices(AudioManager.GET_DEVICES_OUTPUTS);
77 private static String[] getAudioInputDevices()
79 return getAudioDevices(AudioManager.GET_DEVICES_INPUTS);
82 private static boolean isBluetoothDevice(AudioDeviceInfo deviceInfo)
84 switch (deviceInfo.getType()) {
93 private static boolean setAudioInput(MediaRecorder
recorder,
int id)
95 if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.P)
99 m_audioManager.getDevices(AudioManager.GET_DEVICES_INPUTS);
101 for (AudioDeviceInfo deviceInfo : audioDevices) {
102 if (deviceInfo.getId() !=
id)
105 boolean isPreferred =
recorder.setPreferredDevice(deviceInfo);
106 if (isPreferred && isBluetoothDevice(deviceInfo)) {
107 m_audioManager.startBluetoothSco();
108 m_audioManager.setBluetoothScoOn(
true);
117 private static void setInputMuted(
boolean mute)
120 m_audioManager.setMicrophoneMute(mute);
123 private static boolean isMicrophoneMute()
125 return m_audioManager.isMicrophoneMute();
128 private static String audioDeviceTypeToString(
int type)
138 return "Built in earpiece";
140 return "Built in microphone";
142 return "Built in speaker";
156 return "Line analog";
158 return "Line digital";
162 return "USB accessory";
164 return "Wired headphones";
166 return "Wired headset";
170 return "Unknown-Type";
174 private static String[] getAudioDevices(
int type)
176 ArrayList<String>
devices =
new ArrayList<>();
178 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
179 boolean builtInMicAdded =
false;
180 boolean bluetoothDeviceAdded =
false;
181 for (AudioDeviceInfo deviceInfo : m_audioManager.getDevices(
type)) {
188 if (builtInMicAdded) {
197 builtInMicAdded =
true;
198 }
else if (isBluetoothDevice(deviceInfo)) {
199 if (bluetoothDeviceAdded) {
205 bluetoothDeviceAdded =
true;
209 + deviceInfo.getProductName().toString() +
")");
218 private static boolean setAudioOutput(
int id)
221 m_audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
222 for (AudioDeviceInfo deviceInfo : audioDevices) {
223 if (deviceInfo.getId() ==
id) {
224 switch (deviceInfo.getType())
228 setAudioOutput(AudioManager.MODE_IN_COMMUNICATION,
true,
false);
231 setAudioOutput(AudioManager.STREAM_MUSIC,
false,
true);
235 setAudioOutput(AudioManager.MODE_IN_COMMUNICATION,
false,
false);
241 Log.w(TAG,
"Built in Earpiece may not work when "
242 +
"Wired Headphones are connected");
243 setAudioOutput(AudioManager.MODE_IN_CALL,
false,
false);
253 private static void setAudioOutput(
int mode,
boolean bluetoothOn,
boolean speakerOn)
255 m_audioManager.setMode(
mode);
257 m_audioManager.startBluetoothSco();
259 m_audioManager.stopBluetoothSco();
261 m_audioManager.setBluetoothScoOn(bluetoothOn);
262 m_audioManager.setSpeakerphoneOn(speakerOn);
266 private static void streamSound()
268 byte data[] =
new byte[m_bufferSize];
269 while (m_isStreaming) {
270 m_recorder.read(
data, 0, m_bufferSize);
271 m_streamPlayer.play();
272 m_streamPlayer.write(
data, 0, m_bufferSize);
273 m_streamPlayer.stop();
277 private static void startSoundStreaming(
int inputId,
int outputId)
280 stopSoundStreaming();
282 m_recorder =
new AudioRecord(MediaRecorder.AudioSource.DEFAULT, m_sampleRate, m_channels,
283 m_audioFormat, m_bufferSize);
284 m_streamPlayer =
new AudioTrack(AudioManager.STREAM_MUSIC, m_sampleRate, m_channels,
285 m_audioFormat, m_bufferSize, AudioTrack.MODE_STREAM);
288 for (AudioDeviceInfo deviceInfo :
devices) {
289 if (deviceInfo.getId() == outputId) {
290 m_streamPlayer.setPreferredDevice(deviceInfo);
291 }
else if (deviceInfo.getId() == inputId) {
292 m_recorder.setPreferredDevice(deviceInfo);
296 m_recorder.startRecording();
297 m_isStreaming =
true;
299 m_streamingThread =
new Thread(
new Runnable() {
305 m_streamingThread.start();
308 private static void stopSoundStreaming()
313 m_isStreaming =
false;
315 m_streamingThread.join();
316 m_streamingThread =
null;
317 }
catch (InterruptedException
e) {
321 m_recorder.release();
322 m_streamPlayer.release();
323 m_streamPlayer =
null;
void AudioDeviceInfo()
[Audio output state changed]
auto run(QThreadPool *pool, Function &&f, Args &&...args)
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
static QInputDevice::DeviceType deviceType(const UINT cursorType)