Проблема с кнопкой остановки звука в Android Studio (Kotlin)

#android-studio #kotlin

#android-студия #kotlin

Вопрос:

в настоящее время изучает Kotlin и создал приложение, которое имеет 7 кнопок (6 воспроизводят определенный звук, а 7-я — кнопка остановки).Когда я воспроизводю первый звук, звук запускается, а когда я нажимаю кнопку остановки, звук останавливается, но проблема возникает, если я воспроизводю первый звук, а затем второй и третий одновременно, кнопка остановки работает только для первого звука, а остальные продолжают воспроизводиться одновременно.Заранее благодарю за помощь.

Это основная деятельность и xml:

     override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        var layout = findViewById<RelativeLayout>(R.id.parent_layout)
        val animation = layout.background as AnimationDrawable?
        animation?.setEnterFadeDuration(3000)
        animation?.setExitFadeDuration(1000)
        animation?.start()
    }
    fun PlaySoundOnButtons(view: View){
        val sound = view as Button
        val mediaPlayer = MediaPlayer.create(this@MainActivity,resources.getIdentifier(sound.tag as String,"raw",packageName))
        mediaPlayer.start()
        if (mediaPlayer.isPlaying) {
            sound.setBackgroundColor(Color.RED)
        }
        mediaPlayer.setOnCompletionListener { sound.setBackgroundColor(Color.WHITE)
        }
        val stopSound = findViewById(R.id.stop_btn) as Button
        stopSound.setOnClickListener {
            mediaPlayer.stop()
            if (mediaPlayer.isPlaying){
                mediaPlayer.stop()
            }
        }     
    }
}

**XML File**:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@ id/parent_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/mix_colours"
    tools:context=".MainActivity">
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="30dp"
        android:layout_marginStart="20dp"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginBottom="20dp">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >
            <Button
                android:id="@ id/button4"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="20dp"
                android:onClick="PlaySoundOnButtons"
                android:tag="one"
                android:text="Hip Hop"
                android:textColor="@color/black"
                android:textSize="20sp"
                app:backgroundTint="@color/white" />
            <Button
                android:id="@ id/button5"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="20dp"
                android:onClick="PlaySoundOnButtons"
                android:tag="two"
                android:text="Rap"
                android:textColor="@color/black"
                android:textSize="20sp"
                app:backgroundTint="@color/white" />
            <Button
                android:id="@ id/button6"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="20dp"
                android:onClick="PlaySoundOnButtons"
                android:tag="three"
                android:text="Jazz"
                android:textColor="@color/black"
                android:textSize="20sp"
                app:backgroundTint="@color/white" />
            <Button
                android:id="@ id/button"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="20dp"
                android:onClick="PlaySoundOnButtons"
                android:tag="four"
                android:text="Agressive rap"
                android:textColor="@color/black"
                android:textSize="20sp"
                app:backgroundTint="@color/white" />
            <Button
                android:id="@ id/button2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="20dp"
                android:onClick="PlaySoundOnButtons"
                android:tag="five"
                android:text="Old school"
                android:textColor="@color/black"
                android:textSize="20sp"
                app:backgroundTint="@color/white" />
            <Button
                android:id="@ id/button3"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="20dp"
                android:onClick="PlaySoundOnButtons"
                android:tag="six"
                android:text="Underground rap"
                android:textColor="@color/black"
                android:textSize="20sp"
                app:backgroundTint="@color/white" />
            <Button
                android:id="@ id/stop_btn"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Stop"
                android:soundEffectsEnabled="false"
                app:backgroundTint="@color/design_default_color_error" />
        </LinearLayout>
    </ScrollView>
</RelativeLayout>```
 

Комментарии:

1. Затем вам нужно найти какой-то способ предоставить stopSound.setOnClickListener доступ ко всем MediaPlayer экземплярам, а не только к самому последнему запущенному.

Ответ №1:

если вы хотите воспроизводить один звук, вам необходимо объявить mediaPlayer внешнюю часть функции щелчка и функцию кнопки остановки, чтобы onCreate

 lateinit var mediaPlayer:MediaPlayer
    
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    var layout = findViewById<RelativeLayout>(R.id.parent_layout)
    val animation = layout.background as AnimationDrawable?
    animation?.setEnterFadeDuration(3000)
    animation?.setExitFadeDuration(1000)
    animation?.start()


    val stopSound = findViewById(R.id.stop_btn) as Button
    stopSound.setOnClickListener {
        if (::mediaPlayer.isInitialized amp;amp; mediaPlayer.isPlaying){
            mediaPlayer.stop()
        }
    }     
}

fun PlaySoundOnButtons(view: View){
    val sound = view as Button
    
    if (::mediaPlayer.isInitialized amp;amp; mediaPlayer.isPlaying){
        mediaPlayer.stop()
    }
    mediaPlayer = MediaPlayer.create(this@MainActivity,resources.getIdentifier(sound.tag as String,"raw",packageName))
    mediaPlayer.start()
    if (mediaPlayer.isPlaying) {
        sound.setBackgroundColor(Color.RED)
    }
    mediaPlayer.setOnCompletionListener { 
        sound.setBackgroundColor(Color.WHITE)
    }
}
 

Ответ №2:

Все ваши кнопки вызывают один и тот же прослушиватель щелчков, который создает новый MediaPlayer , запускает его воспроизведение, а затем устанавливает кнопку остановки, чтобы остановить этот MediaPlayer экземпляр.

Итак, проблема в том, что у вас есть одна кнопка остановки, и она может остановить только последний медиаплеер, который был ему назначен. Каждый раз, когда происходит новый щелчок, создается новый проигрыватель, и кнопка остановки забывает, с каким плеером она работала раньше. Даже если вы дважды нажмете одну и ту же кнопку.

Вам необходимо отслеживать все ваши текущие MediaPlayer экземпляры, чтобы ваша кнопка остановки могла вызывать stop() их все. И действительно, вам все равно нужно отслеживать их, чтобы вы могли звонить release() и освобождать ресурсы

Когда вы закончите MediaPlayer , вы должны позвонить release() , чтобы освободить ресурсы. Если не отпустить, слишком много MediaPlayer экземпляров приведет к исключению.

Возможно, вы захотите сохранить их карту, и при вызове прослушивателя кликов попробуйте get медиаплеер, связанный с тем view , на который был нажат, создав новый для этого представления, если он не существует. Затем вы можете перебрать их все, чтобы остановить (и, возможно, вызвать release их, пока вы это делаете)