feat: Add microphone connectivity status

This commit is contained in:
Myzel394 2023-10-21 20:37:27 +02:00
parent 825f0eb33f
commit 78453f1c4d
No known key found for this signature in database
GPG Key ID: 79CC92F37B3E1A2B
3 changed files with 85 additions and 0 deletions

View File

@ -1,11 +1,20 @@
package app.myzel394.alibi.services
import android.annotation.SuppressLint
import android.content.Context
import android.media.AudioDeviceCallback
import android.media.AudioDeviceInfo
import android.media.AudioManager
import android.media.MediaRecorder
import android.media.MediaRecorder.OnErrorListener
import android.os.Build
import android.os.Handler
import android.os.Looper
import androidx.core.content.ContextCompat.getSystemService
import app.myzel394.alibi.enums.RecorderState
import app.myzel394.alibi.ui.utils.MicrophoneInfo
import java.lang.IllegalStateException
import java.util.concurrent.Executor
class AudioRecorderService : IntervalRecorderService() {
var amplitudesAmount = 1000
@ -15,6 +24,8 @@ class AudioRecorderService : IntervalRecorderService() {
private set
var onError: () -> Unit = {}
var onSelectedMicrophoneChange: (MicrophoneInfo?) -> Unit = {}
var onMicrophoneDisconnected: () -> Unit = {}
var onMicrophoneReconnected: () -> Unit = {}
val filePath: String
get() = "$folder/$counter.${settings!!.fileExtension}"
@ -95,6 +106,12 @@ class AudioRecorderService : IntervalRecorderService() {
}
}
override fun start() {
super.start()
registerMicrophoneListener()
}
override fun pause() {
super.pause()
@ -106,6 +123,7 @@ class AudioRecorderService : IntervalRecorderService() {
resetRecorder()
selectedMicrophone = null
unregisterMicrophoneListener()
}
override fun getAmplitudeAmount(): Int = amplitudesAmount
@ -123,5 +141,51 @@ class AudioRecorderService : IntervalRecorderService() {
fun changeMicrophone(microphone: MicrophoneInfo?) {
selectedMicrophone = microphone
onSelectedMicrophoneChange(microphone)
if (state == RecorderState.RECORDING) {
startNewCycle()
}
}
private val audioDeviceCallback = object : AudioDeviceCallback() {
override fun onAudioDevicesAdded(addedDevices: Array<out AudioDeviceInfo>?) {
super.onAudioDevicesAdded(addedDevices)
if (selectedMicrophone == null) {
return;
}
if (addedDevices?.find { it.id == selectedMicrophone!!.deviceInfo.id } != null) {
onMicrophoneReconnected()
}
}
override fun onAudioDevicesRemoved(removedDevices: Array<out AudioDeviceInfo>?) {
super.onAudioDevicesRemoved(removedDevices)
if (selectedMicrophone == null) {
return;
}
if (removedDevices?.find { it.id == selectedMicrophone!!.deviceInfo.id } != null) {
onMicrophoneDisconnected()
}
}
}
@SuppressLint("NewApi")
private fun registerMicrophoneListener() {
val audioManager = getSystemService(Context.AUDIO_SERVICE)!! as AudioManager
audioManager.registerAudioDeviceCallback(
audioDeviceCallback,
Handler(Looper.getMainLooper())
)
}
private fun unregisterMicrophoneListener() {
val audioManager = getSystemService(Context.AUDIO_SERVICE)!! as AudioManager
audioManager.unregisterAudioDeviceCallback(audioDeviceCallback)
}
}

View File

@ -46,6 +46,14 @@ class AudioRecorderModel : ViewModel() {
var onRecordingSave: () -> Unit = {}
var onError: () -> Unit = {}
var microphoneStatus: MicrophoneConnectivityStatus = MicrophoneConnectivityStatus.CONNECTED
private set
enum class MicrophoneConnectivityStatus {
CONNECTED,
DISCONNECTED
}
private val connection = object : ServiceConnection {
override fun onServiceConnected(className: ComponentName, service: IBinder) {
recorderService =
@ -68,6 +76,12 @@ class AudioRecorderModel : ViewModel() {
recorder.onSelectedMicrophoneChange = { microphone ->
selectedMicrophone = microphone
}
recorder.onMicrophoneDisconnected = {
microphoneStatus = MicrophoneConnectivityStatus.DISCONNECTED
}
recorder.onMicrophoneReconnected = {
microphoneStatus = MicrophoneConnectivityStatus.CONNECTED
}
}.also {
// Init UI from the service
it.startRecording()
@ -90,6 +104,7 @@ class AudioRecorderModel : ViewModel() {
recordingTime = null
amplitudes = emptyList()
selectedMicrophone = null
microphoneStatus = MicrophoneConnectivityStatus.CONNECTED
}
fun startRecording(context: Context) {
@ -131,6 +146,10 @@ class AudioRecorderModel : ViewModel() {
fun changeMicrophone(microphone: MicrophoneInfo?) {
recorderService!!.changeMicrophone(microphone)
if (microphone == null) {
microphoneStatus = MicrophoneConnectivityStatus.CONNECTED
}
}
fun bindToService(context: Context) {

View File

@ -65,4 +65,6 @@
<string name="ui_settings_language_update_label">Change</string>
<string name="ui_audioRecorder_info_microphone_deviceMicrophone">Device Microphone</string>
<string name="ui_audioRecorder_info_microphone_changeExplanation">The selected microphone will be immediately activated</string>
<string name="ui_audioRecorder_error_microphoneDisconnected_title">Microphone disconnected</string>
<string name="ui_audioRecorder_error_microphoneDisconnected_message"><xliff:g name="name">%s</xliff:g> disconnected. Alibi will use the default microphone instead. We will automatically switch back to <xliff:g name="name">%s</xliff:g> once it reconnects.</string>
</resources>