У меня есть приложение для 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
Воспроизведение звука небольшой продолжительности с помощью MediaPlayer или SoundPool при нажатии кнопки. ⇐ Android
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Как обновить конструктор SoundPool для использования SoundPool.Builder?
Anonymous » » в форуме Android - 0 Ответы
- 23 Просмотры
-
Последнее сообщение Anonymous
-