mirror of
https://github.com/Myzel394/Alibi.git
synced 2025-06-18 23:05:26 +02:00
feat: Add microphone connectivity status
This commit is contained in:
parent
825f0eb33f
commit
78453f1c4d
@ -1,11 +1,20 @@
|
|||||||
package app.myzel394.alibi.services
|
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.AudioManager
|
||||||
import android.media.MediaRecorder
|
import android.media.MediaRecorder
|
||||||
import android.media.MediaRecorder.OnErrorListener
|
import android.media.MediaRecorder.OnErrorListener
|
||||||
import android.os.Build
|
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 app.myzel394.alibi.ui.utils.MicrophoneInfo
|
||||||
import java.lang.IllegalStateException
|
import java.lang.IllegalStateException
|
||||||
|
import java.util.concurrent.Executor
|
||||||
|
|
||||||
class AudioRecorderService : IntervalRecorderService() {
|
class AudioRecorderService : IntervalRecorderService() {
|
||||||
var amplitudesAmount = 1000
|
var amplitudesAmount = 1000
|
||||||
@ -15,6 +24,8 @@ class AudioRecorderService : IntervalRecorderService() {
|
|||||||
private set
|
private set
|
||||||
var onError: () -> Unit = {}
|
var onError: () -> Unit = {}
|
||||||
var onSelectedMicrophoneChange: (MicrophoneInfo?) -> Unit = {}
|
var onSelectedMicrophoneChange: (MicrophoneInfo?) -> Unit = {}
|
||||||
|
var onMicrophoneDisconnected: () -> Unit = {}
|
||||||
|
var onMicrophoneReconnected: () -> Unit = {}
|
||||||
|
|
||||||
val filePath: String
|
val filePath: String
|
||||||
get() = "$folder/$counter.${settings!!.fileExtension}"
|
get() = "$folder/$counter.${settings!!.fileExtension}"
|
||||||
@ -95,6 +106,12 @@ class AudioRecorderService : IntervalRecorderService() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun start() {
|
||||||
|
super.start()
|
||||||
|
|
||||||
|
registerMicrophoneListener()
|
||||||
|
}
|
||||||
|
|
||||||
override fun pause() {
|
override fun pause() {
|
||||||
super.pause()
|
super.pause()
|
||||||
|
|
||||||
@ -106,6 +123,7 @@ class AudioRecorderService : IntervalRecorderService() {
|
|||||||
|
|
||||||
resetRecorder()
|
resetRecorder()
|
||||||
selectedMicrophone = null
|
selectedMicrophone = null
|
||||||
|
unregisterMicrophoneListener()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getAmplitudeAmount(): Int = amplitudesAmount
|
override fun getAmplitudeAmount(): Int = amplitudesAmount
|
||||||
@ -123,5 +141,51 @@ class AudioRecorderService : IntervalRecorderService() {
|
|||||||
fun changeMicrophone(microphone: MicrophoneInfo?) {
|
fun changeMicrophone(microphone: MicrophoneInfo?) {
|
||||||
selectedMicrophone = microphone
|
selectedMicrophone = microphone
|
||||||
onSelectedMicrophoneChange(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)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -46,6 +46,14 @@ class AudioRecorderModel : ViewModel() {
|
|||||||
var onRecordingSave: () -> Unit = {}
|
var onRecordingSave: () -> Unit = {}
|
||||||
var onError: () -> Unit = {}
|
var onError: () -> Unit = {}
|
||||||
|
|
||||||
|
var microphoneStatus: MicrophoneConnectivityStatus = MicrophoneConnectivityStatus.CONNECTED
|
||||||
|
private set
|
||||||
|
|
||||||
|
enum class MicrophoneConnectivityStatus {
|
||||||
|
CONNECTED,
|
||||||
|
DISCONNECTED
|
||||||
|
}
|
||||||
|
|
||||||
private val connection = object : ServiceConnection {
|
private val connection = object : ServiceConnection {
|
||||||
override fun onServiceConnected(className: ComponentName, service: IBinder) {
|
override fun onServiceConnected(className: ComponentName, service: IBinder) {
|
||||||
recorderService =
|
recorderService =
|
||||||
@ -68,6 +76,12 @@ class AudioRecorderModel : ViewModel() {
|
|||||||
recorder.onSelectedMicrophoneChange = { microphone ->
|
recorder.onSelectedMicrophoneChange = { microphone ->
|
||||||
selectedMicrophone = microphone
|
selectedMicrophone = microphone
|
||||||
}
|
}
|
||||||
|
recorder.onMicrophoneDisconnected = {
|
||||||
|
microphoneStatus = MicrophoneConnectivityStatus.DISCONNECTED
|
||||||
|
}
|
||||||
|
recorder.onMicrophoneReconnected = {
|
||||||
|
microphoneStatus = MicrophoneConnectivityStatus.CONNECTED
|
||||||
|
}
|
||||||
}.also {
|
}.also {
|
||||||
// Init UI from the service
|
// Init UI from the service
|
||||||
it.startRecording()
|
it.startRecording()
|
||||||
@ -90,6 +104,7 @@ class AudioRecorderModel : ViewModel() {
|
|||||||
recordingTime = null
|
recordingTime = null
|
||||||
amplitudes = emptyList()
|
amplitudes = emptyList()
|
||||||
selectedMicrophone = null
|
selectedMicrophone = null
|
||||||
|
microphoneStatus = MicrophoneConnectivityStatus.CONNECTED
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startRecording(context: Context) {
|
fun startRecording(context: Context) {
|
||||||
@ -131,6 +146,10 @@ class AudioRecorderModel : ViewModel() {
|
|||||||
|
|
||||||
fun changeMicrophone(microphone: MicrophoneInfo?) {
|
fun changeMicrophone(microphone: MicrophoneInfo?) {
|
||||||
recorderService!!.changeMicrophone(microphone)
|
recorderService!!.changeMicrophone(microphone)
|
||||||
|
|
||||||
|
if (microphone == null) {
|
||||||
|
microphoneStatus = MicrophoneConnectivityStatus.CONNECTED
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bindToService(context: Context) {
|
fun bindToService(context: Context) {
|
||||||
|
@ -65,4 +65,6 @@
|
|||||||
<string name="ui_settings_language_update_label">Change</string>
|
<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_deviceMicrophone">Device Microphone</string>
|
||||||
<string name="ui_audioRecorder_info_microphone_changeExplanation">The selected microphone will be immediately activated</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>
|
</resources>
|
Loading…
x
Reference in New Issue
Block a user