#android #android-studio #kotlin #android-music-player
Вопрос:
Я создал приложение для медитации, в котором пользователи могут выбрать нужный им класс из представления переработчика внутри фрагмента, затем в нем будет показано подробное содержимое и шаги в новом действии. В новом упражнении я реализовал функции воспроизведения звука, с помощью которых пользователь может передавать аудиофайл из firebase. Проблема теперь в том, что всякий раз, когда я переключаюсь обратно на вид переработчика внутри фрагмента, аудиофайл все еще воспроизводится в фоновом режиме. Как остановить воспроизведение аудиофайла всякий раз, когда я переключаюсь на другую страницу в приложении или переключаюсь на другое приложение ?
Это код для представления переработчика внутри фрагмента
class ClassFragment : Fragment() {
private lateinit var recyclerView: RecyclerView
private lateinit var classArrayList: ArrayList<Classes>
private lateinit var tempArraylist: ArrayList<Classes>
private lateinit var classAdapter: ClassAdapter
private lateinit var db: FirebaseFirestore
var mediaPlayer: MediaPlayer? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view: View = inflater.inflate(R.layout.fragment_class, container, false)
recyclerView = view.findViewById(R.id.ClassList)
recyclerView.layoutManager = LinearLayoutManager(context)
recyclerView.setHasFixedSize(true)
classArrayList = arrayListOf()
tempArraylist = arrayListOf()
eventChangeListener()
classAdapter = ClassAdapter(requireContext(), classArrayList)
recyclerView.adapter = classAdapter
return view
}
private fun eventChangeListener() {
db = FirebaseFirestore.getInstance()
db.collection("class").addSnapshotListener(object : EventListener<QuerySnapshot> {
override fun onEvent(value: QuerySnapshot?, error: FirebaseFirestoreException?) {
if (error != null) {
Log.e("Firestore error", error.message.toString())
return
}
for (dc: DocumentChange in value?.documentChanges!!) {
if (dc.type == DocumentChange.Type.ADDED) {
classArrayList.add(
dc.document.toObject(
(Classes::class.java)
)
)
}
}
tempArraylist.clear()
tempArraylist.addAll(classArrayList)
classAdapter.notifyDataSetChanged()
}
})
}
}
Это код для новой страницы действий, на которой будет отображаться содержимое, когда пользователь выберет из recyclerview
class DetailActivity : AppCompatActivity() {
private lateinit var imageViewClass: ImageView
private lateinit var textViewClassName: TextView
private lateinit var textViewClassDes: TextView
private lateinit var textViewClassContent: TextView
private var stop:Boolean = false
var mediaPlayer: MediaPlayer? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_detail)
val btnPlay: Button = findViewById(R.id.btnPlay)
val btnStop: Button = findViewById(R.id.btnStop)
imageViewClass = findViewById(R.id.imageViewClassImage)
textViewClassName = findViewById(R.id.textViewClassName)
textViewClassDes = findViewById(R.id.textViewClassDescription)
textViewClassContent = findViewById(R.id.textViewClassContent)
val classImage = intent.getStringExtra("class_image")
val className = intent.getStringExtra("class_name")
val classDes = intent.getStringExtra("class_des")
val classContent = intent.getStringExtra("class_content")
val classAudio = intent.getStringExtra("class_audio")
Glide.with(this)
.load(classImage)
.centerCrop()
.into(imageViewClass)
textViewClassName.text = className
textViewClassDes.text = classDes
textViewClassDes.text = classDes!!.replace("\n", "n")
textViewClassContent.text = classContent
textViewClassContent.text = classContent!!.replace("\n", "n")
btnPlay.isEnabled = true
btnStop.isEnabled = false
btnPlay.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View?) {
if (mediaPlayer == null) {
mediaPlayer = MediaPlayer.create(this@DetailActivity, Uri.parse(classAudio))
mediaPlayer!!.isLooping = true
mediaPlayer!!.start()
btnStop.isEnabled = true
btnPlay.isEnabled = false
Toast.makeText(applicationContext,"Audio Starts",Toast.LENGTH_SHORT).show()
} else mediaPlayer!!.start()
}
})
mediaPlayer?.setOnCompletionListener {
btnPlay.isEnabled = true
btnStop.isEnabled = false
Toast.makeText(this,"end",Toast.LENGTH_SHORT).show()
}
btnStop.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View?) {
if(mediaPlayer!!.isPlaying){
stop = false
mediaPlayer!!.stop()
mediaPlayer!!.reset()
mediaPlayer!!.release()
mediaPlayer = null
btnPlay.isEnabled = true
btnStop.isEnabled = false
Toast.makeText(applicationContext,"Audio Stops",Toast.LENGTH_SHORT).show()
}
}
})
}
}
Ответ №1:
Это классический случай onDestroy
Activity
того, что называется. Я буду краток, но существует жизненный цикл, через который Activity
проходит, и когда вы, кажется, возвращаетесь от второго действия к первому действию, onDestroy
ваше второе действие вызывается для выполнения функции уничтожения
Итак, решение, переопределите onDestroy
метод в своем DetailActivity
классе и сделайте что-то вроде этого
override fun onDestroy(){
if(mediaPlayer != null){
mediaPlayer!!.stop()
mediaPlayer!!.reset()
mediaPlayer!!.release()
mediaPlayer = null
}
}
Вы можете подробно прочитать о жизненном цикле деятельности