zmxv / react-native-sound

React Native module for playing sound clips
MIT License
2.78k stars 748 forks source link

After app got killed sound still playing #709

Open lyseiha opened 3 years ago

lyseiha commented 3 years ago

My app have background service (tracking location). after playing sound and app got killed sound still playing. How to stop sound when app got killed?

nguyen-vo commented 3 years ago

How you found the solution for this yet? I have the same issue as well. It seems like when app comes back to foreground the stop() and pause() functions do not work

nguyen-vo commented 3 years ago

I found the solution for this:

  1. You need to initialize the sound object outside of your component, then call it. Screen Shot 2021-04-30 at 8 58 05 PM
  2. Use AppState to listen to events when the app state changes or the app gets focus. More detail here https://reactnative.dev/docs/appstate.In my case, I want the sound to turn off when the user opens the app. So I use AppState.addEventListener('focus', this._handleAppFocus); .In _handleAppFocus, I call playerRN.stop(err => console.log("Player stopped", err)). Screen Shot 2021-04-30 at 8 59 08 PM
pafry7 commented 1 year ago

If someone is still experiencing the problem, the patch below may fix it:

diff --git a/node_modules/react-native-sound/android/src/main/java/com/zmxv/RNSound/RNSoundModule.java b/node_modules/react-native-sound/android/src/main/java/com/zmxv/RNSound/RNSoundModule.java
index e6f51ec..eaa868b 100644
--- a/node_modules/react-native-sound/android/src/main/java/com/zmxv/RNSound/RNSoundModule.java
+++ b/node_modules/react-native-sound/android/src/main/java/com/zmxv/RNSound/RNSoundModule.java
@@ -13,6 +13,7 @@ import com.facebook.react.bridge.Callback;
 import com.facebook.react.bridge.ReactApplicationContext;
 import com.facebook.react.bridge.ReactContext;
 import com.facebook.react.bridge.ReactContextBaseJavaModule;
+import com.facebook.react.bridge.LifecycleEventListener;
 import com.facebook.react.bridge.ReactMethod;
 import com.facebook.react.bridge.ReadableMap;
 import com.facebook.react.bridge.WritableMap;
@@ -26,7 +27,7 @@ import java.io.IOException;

 import android.util.Log;

-public class RNSoundModule extends ReactContextBaseJavaModule implements AudioManager.OnAudioFocusChangeListener {
+public class RNSoundModule extends ReactContextBaseJavaModule implements AudioManager.OnAudioFocusChangeListener, LifecycleEventListener {
   Map<Double, MediaPlayer> playerPool = new HashMap<>();
   ReactApplicationContext context;
   final static Object NULL = null;
@@ -37,6 +38,7 @@ public class RNSoundModule extends ReactContextBaseJavaModule implements AudioMa

   public RNSoundModule(ReactApplicationContext context) {
     super(context);
+    context.addLifecycleEventListener(this);
     this.context = context;
     this.category = null;
   }
@@ -388,10 +390,10 @@ public class RNSoundModule extends ReactContextBaseJavaModule implements AudioMa

   @ReactMethod
   public void setSpeed(final Double key, final Float speed) {
-   if (android.os.Build.VERSION.SDK_INT < 23) {
-     Log.w("RNSoundModule", "setSpeed ignored due to sdk limit");
-     return;
-   }
+  if (android.os.Build.VERSION.SDK_INT < 23) {
+    Log.w("RNSoundModule", "setSpeed ignored due to sdk limit");
+    return;
+  }

     MediaPlayer player = this.playerPool.get(key);
     if (player != null) {
@@ -494,4 +496,29 @@ public class RNSoundModule extends ReactContextBaseJavaModule implements AudioMa
   public void removeListeners(Integer count) {
     // Keep: Required for RN built in Event Emitter Calls.
   }
+
+  @Override
+  public void onHostDestroy() {
+    java.util.Iterator it = this.playerPool.entrySet().iterator();
+    while (it.hasNext()) {
+      Map.Entry entry = (Map.Entry)it.next();
+      MediaPlayer player = (MediaPlayer)entry.getValue();
+      if (player != null) {
+        player.reset();
+        player.release();
+      }
+      it.remove();
+    }
+  }
+
+  @Override
+  public void onHostPause() {
+    // Required for LifecycleEventListener
+
+  }
+
+  @Override
+  public void onHostResume() {
+    // Required for LifecycleEventListener
+  }
 }
aleena-adnan1 commented 5 months ago

any solution to this ? i'm still stuck