diff --git a/android/src/main/java/com/zmxv/RNSound/RNSoundModule.java b/android/src/main/java/com/zmxv/RNSound/RNSoundModule.java index 698032c1..d9e9bc11 100644 --- a/android/src/main/java/com/zmxv/RNSound/RNSoundModule.java +++ b/android/src/main/java/com/zmxv/RNSound/RNSoundModule.java @@ -25,6 +25,13 @@ public class RNSoundModule extends ReactContextBaseJavaModule { Map playerPool = new HashMap<>(); ReactApplicationContext context; final static Object NULL = null; + /** + * Number of loops for the sound. + * -1 - play inifity + * 0 - play once + * 1 - play twice etc. + */ + Integer loops = 0; public RNSoundModule(ReactApplicationContext context) { super(context); @@ -134,22 +141,7 @@ public void play(final Integer key, final Callback callback) { if (player.isPlaying()) { return; } - player.setOnCompletionListener(new OnCompletionListener() { - boolean callbackWasCalled = false; - - @Override - public synchronized void onCompletion(MediaPlayer mp) { - if (!mp.isLooping()) { - if (callbackWasCalled) return; - callbackWasCalled = true; - try { - callback.invoke(true); - } catch (Exception e) { - //Catches the exception: java.lang.RuntimeException·Illegal callback invocation from native module - } - } - } - }); + player.setOnCompletionListener(new OnCompletionListenerLooped(callback, this.loops)); player.setOnErrorListener(new OnErrorListener() { boolean callbackWasCalled = false; @@ -201,11 +193,16 @@ public void setVolume(final Integer key, final Float left, final Float right) { } @ReactMethod - public void setLooping(final Integer key, final Boolean looping) { - MediaPlayer player = this.playerPool.get(key); - if (player != null) { - player.setLooping(looping); - } + public void setNumberOfLoops(final Integer key, final Integer loops) { + if (loops == -1) { + MediaPlayer player = this.playerPool.get(key); + if (player != null) { + player.setLooping(true); + } + } + else { + this.loops = loops; + } } @ReactMethod @@ -258,3 +255,39 @@ public Map getConstants() { return constants; } } + +class OnCompletionListenerLooped implements OnCompletionListener { + /** + * Number of loops. 0 - play once, 1 - play twice etc. + * Media player have set looping to true if -1 is given from react component. + */ + Integer loops = 0; + boolean callbackWasCalled = false; + Callback callback; + + public OnCompletionListenerLooped(Callback callback, Integer loops) { + super(); + this.callback = callback; + this.loops = loops; + } + + @Override + public synchronized void onCompletion(MediaPlayer mp) { + if (!mp.isLooping()) { + if (this.loops > 0) { + mp.start(); + this.loops--; + return; + } + if (callbackWasCalled) + return; + callbackWasCalled = true; + try { + callback.invoke(true); + } + catch (Exception e) { + //Catches the exception: java.lang.RuntimeException·Illegal callback invocation from native module + } + } + } +} \ No newline at end of file diff --git a/sound.js b/sound.js index d4b2f9e0..ea4a6dbe 100644 --- a/sound.js +++ b/sound.js @@ -123,7 +123,7 @@ Sound.prototype.getNumberOfLoops = function() { Sound.prototype.setNumberOfLoops = function(value) { this._numberOfLoops = value; if (this._loaded) { - if (IsAndroid || IsWindows) { + if (IsWindows) { RNSound.setLooping(this._key, !!value); } else { RNSound.setNumberOfLoops(this._key, value);