Reputation: 349
So I have a Sound I want to play continuously throughout the whole of my App. But as soon as the App goes to background, the sound should stop. I´m trying to do this during onStop(). The problem is that onStop() is called every time the activity is stopped, regardless of whether I stay within the app or not. Is there a way to differentiate between those cases? Something like this:
override fun onStop() {
if [App is left but not destroyed] {
super.onStop()
mediaLength = mediaPlayer.currentPosition
mediaPlayer.pause()
}
else { //i.e. activity is left but the new activity is from the same app.
super.onStop()
}
}
EDIT:
I tried to implement this answer, but had to translate it to kotlin. I think I did everything right, but I get an unresolved reference: mediaPlayer
in the Lifecycleobserver.
Here´s the Observer:
package com.example.asdasd.soulfetch
import android.app.Application
import android.arch.lifecycle.Lifecycle
import android.arch.lifecycle.LifecycleObserver
import android.arch.lifecycle.OnLifecycleEvent
import android.arch.lifecycle.ProcessLifecycleOwner
class CheckLifeCycle: Application(), LifecycleObserver {
override fun onCreate() {
super.onCreate()
ProcessLifecycleOwner.get().getLifecycle().addObserver(this)
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun onAppBackground() {
MainActivity.mediaPlayer.pause()
}
}
And here are the relevant parts of MainActivity
class MainActivity : AppCompatActivity() {
lateinit var mediaPlayer: MediaPlayer
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mediaPlayer = MediaPlayer()
fun playBordun() {
mediaPlayer = MediaPlayer.create(this, R.raw.cbordun)
mediaPlayer.isLooping = true
mediaPlayer.start()
}
playBordun()
}
override fun onDestroy() {
super.onDestroy()
mediaPlayer.stop()
mediaPlayer.reset()
mediaPlayer.release()
}
Any idea what I am missing here?
Upvotes: 0
Views: 2266
Reputation: 1
Based on @Elam parithi 's answer, I made some modifications. This method can keep playing background music while switching activities within the app, and the music will be stopped when the BACK/HOME/MENU button is pressed or use gesture navigation (swipe from bottom to top) to go back HOME.
I create another class BackgroundMusicService
using Service
to play the background music.
import android.app.Service
import android.content.Intent
import android.media.MediaPlayer
import android.os.Build
import android.os.IBinder
import androidx.annotation.RequiresApi
class BackgroundMusicService : Service() {
private lateinit var player: MediaPlayer
val ACTION_STOP = "stop_music_service"
val ACTION_START = "start_music_service"
override fun onBind(p0: Intent?): IBinder? {
return null
}
@RequiresApi(Build.VERSION_CODES.N)
override fun onCreate() {
super.onCreate()
player = MediaPlayer.create(this, R.raw.bgm)
player.isLooping = true // Set looping
player.setVolume(50f, 50f)
}
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
if(intent.action == ACTION_STOP)
player.stop()
else
player.start()
return startId
}
override fun onStart(intent: Intent, startId: Int) {
// TO DO
}
fun onUnBind(arg0: Intent): IBinder? {
// TO DO Auto-generated method
return null
}
fun onStop() {
player.stop()
}
fun onPause() {
}
override fun onDestroy() {
player.stop()
player.release()
}
override fun onLowMemory() {
}
}
In the onAppBackground()
function, I use the code below to stop the background music. Switching the activities within the app doesn't stop the BGM. However, when exiting the app, the BGM will be stopped.
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun onAppBackground() {
val musicIntent = Intent(this, BackgroundMusicService::class.java)
musicIntent.action = "stop_music_service"
stopService(musicIntent)
}
BTW, the including library should be the androidx
package, because the android.arch
package will cause conflict.
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
I hope this help.
Upvotes: 0
Reputation: 98
You can use the LifecycleObserver to check whether the application in background or not.
public class CheckLifeCycle extends Application implements LifecycleObserver {
@Override
public void onCreate()
{
super.onCreate();
ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onAppBackground()
{
MainActivity.mediaPlayer.pause();
}
}
and add the class name CheckLifeCycle in a manifest
<manifest >
....
<application
android:name=".CheckLifeCycle"
......
</application>
</manifest>
don't forget to include the basic Support library in gradle.
implementation "android.arch.lifecycle:extensions:1.1.1"
annotationProcessor "android.arch.lifecycle:compiler:1.1.1"
Upvotes: 0
Reputation: 4442
You can't gain such functionality using activity. Activity is highly prone to be destroyed, recreated. You should use Service to attain such functionality, as the service will persist, whether your activity is destroyed or not.
This article is old and out of date, but can still learn using service with music from it
Upvotes: 1
Reputation: 317
You can create a custom Application class (extends Application) and implement it with LifecycleObserver interface, and create a function within the CustomApplication class and annotate it with @OnLifecycleEvent(Lifecycle.Event.ON_STOP) so when the app is in background the function will be triggered and inside it you will put the logic to stop the mediaPlayer (make it global to access it from different place whiting the app)
In order to use the LifecycleObserver you need to add LifeCycle to your app (it's an Android architecture component) here is the link: https://developer.android.com/topic/libraries/architecture/adding-components
Upvotes: 1