I have created a meditation application that users can select the class they want from the recycler view within the fragment, then it will show the detailed content and steps in a new activity. In the new activity, I have implemented a audio playing functions where user can stream the audio file from the firebase. The problem now is whenever I switch back to the recycler view within the fragment, the audio file still plays in the background. How do I stop the audio file from playing whenever I switch to another page within the app or switch to another app ?
This is the code for the recycler view within the fragment
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()
}
})
}
}
This is the code for the new activity page where it will show content when the user selects from 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()
}
}
})
}
}
This is a classic case of onDestroy
of the Activity
being called. I'll keep it short but there is a lifecycle through which an Activity
undergoes and when you seem to come back from the SecondActivity to the first Activity, the onDestroy
of your second activity is called to perform the destruction function
So the solution, override the onDestroy
method in your DetailActivity
class and do something like this
override fun onDestroy(){
if(mediaPlayer != null){
mediaPlayer!!.stop()
mediaPlayer!!.reset()
mediaPlayer!!.release()
mediaPlayer = null
}
}
You can read in detail about Activity Lifecyle