Воспроизведение звука небольшой продолжительности с помощью MediaPlayer или SoundPool при нажатии кнопки.Android

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Anonymous
 Воспроизведение звука небольшой продолжительности с помощью MediaPlayer или SoundPool при нажатии кнопки.

Сообщение Anonymous »

У меня есть приложение для Android, написанное на Kotlin и Jetpack Compose. Приложение работает на устройстве с физической клавиатурой.
Моя цель — воспроизводить звук каждый раз, когда я нажимаю кнопку.
В идеале я хочу воспроизводить звук небольшой продолжительности, поэтому, когда я делаю быстро печатая, я хочу воспроизводить один звук при каждом нажатии кнопки. Звуки большой продолжительности, работают, но иногда они не такие частые, как частота набора текста.
Сначала пробовал использовать MediaPlayer. Проблема с этим подходом заключается в том, что когда я использую определенные звуки, приложение аварийно завершает работу, и я получаю исключение с нулевым указателем. Приложение даже не запускается. Чаще всего это происходит при небольших звуках.
class MainActivity : ComponentActivity() {

private lateinit var mediaPlayer: MediaPlayer

@OptIn(ExperimentalComposeUiApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

mediaPlayer = MediaPlayer.create(this, R.raw.keypress33)

setContent {
DemoTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {

val focusRequester = remember { FocusRequester() }
val keyboardController = LocalSoftwareKeyboardController.current
val cursorPosition = remember { mutableStateOf(1) }
var textFieldValue by remember { mutableStateOf(TextFieldValue(text = "1", selection = TextRange(cursorPosition.value)) ) }

Box(
contentAlignment = Alignment.Center
) {

OutlinedTextField(
value = textFieldValue,
onValueChange = { newValue ->
textFieldValue = newValue
},
modifier = Modifier
.focusRequester(focusRequester)
)

LaunchedEffect(Unit) {
focusRequester.requestFocus()
keyboardController?.hide()
}

}
}
}
}
}

override fun onDestroy() {
mediaPlayer.release()
super.onDestroy()
}

@SuppressLint("RestrictedApi")
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
if (event?.action == KeyEvent.ACTION_DOWN) {
playSound()
}
return super.dispatchKeyEvent(event)
}

private fun playSound() {
if (::mediaPlayer.isInitialized) {
mediaPlayer.start()
}
}

}


С другой стороны, я попробовал SoundPool. Здесь есть проблемы другого рода. Приложение не вылетает, но не воспроизводит звук. Если я изменю звук и использую что-то более продолжительное, оно работает, но после нескольких щелчков мышью перестает работать.

class MainActivity : ComponentActivity() {

private lateinit var soundPool: SoundPool
private var soundId: Int = 0
private var isSoundLoaded = false

@OptIn(ExperimentalComposeUiApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContent {
DemoTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {

val attributes = AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build()

soundPool = SoundPool.Builder()
.setAudioAttributes(attributes)
.setMaxStreams(2)
.build()

soundPool.setOnLoadCompleteListener { _, _, status ->
if (status == 0) {
isSoundLoaded = true
}
}

soundId = soundPool.load(this, R.raw.keypress, 1)

val focusRequester = remember { FocusRequester() }
val keyboardController = LocalSoftwareKeyboardController.current
val cursorPosition = remember { mutableStateOf(1) }
var textFieldValue by remember { mutableStateOf(TextFieldValue(text = "1", selection = TextRange(cursorPosition.value)) ) }

Box(
contentAlignment = Alignment.Center
) {

OutlinedTextField(
value = textFieldValue,
onValueChange = { newValue ->
textFieldValue = newValue
},
modifier = Modifier
.focusRequester(focusRequester)
)

LaunchedEffect(Unit) {
focusRequester.requestFocus()
keyboardController?.hide()
}

}
}
}
}
}

override fun onDestroy() {
soundPool.release()
super.onDestroy()
}

@SuppressLint("RestrictedApi")
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
if (event?.action == KeyEvent.ACTION_DOWN) {
playSound()
}
return super.dispatchKeyEvent(event)
}

private fun playSound() {
if (isSoundLoaded) {
soundPool.play(
soundId,
1.0f,
1.0f,
1,
0,
1.0f
)
}

}

}



Подробнее здесь: https://stackoverflow.com/questions/786 ... tton-click
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Soundpool Soundpool Soundpool в разных томах
    Anonymous » » в форуме Android
    0 Ответы
    15 Просмотры
    Последнее сообщение Anonymous
  • Как обновить конструктор SoundPool для использования SoundPool.Builder?
    Anonymous » » в форуме JAVA
    0 Ответы
    11 Просмотры
    Последнее сообщение Anonymous
  • Как обновить конструктор SoundPool для использования SoundPool.Builder?
    Anonymous » » в форуме Android
    0 Ответы
    23 Просмотры
    Последнее сообщение Anonymous
  • Почему воспроизведение звука JavaFX MediaPlayer отлично работает на Windows и Mac, но возникают проблемы в Linux (popOS/
    Anonymous » » в форуме Linux
    0 Ответы
    43 Просмотры
    Последнее сообщение Anonymous
  • Случайное исключение IllegalStateException в Android mediaPlayer.prepare или mediaPlayer.setDataSource
    Anonymous » » в форуме Android
    0 Ответы
    61 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Android»