Search code examples
androidandroid-studioandroid-serviceandroid-mediaplayerandroid-intentservice

Android - Repeat sound in background X times with a Y delay each time


Rx with timer looks like the way to go. If you are not up for it Handler could work as well.

http://reactivex.io/documentation/operators/timer.html


Solution

  • You can also use any timer idea but what I would do most likely is encapsulating the beep in a separate Runnable class and then will call it from my activity/fragment/view whenever it is needed.

    public final class BeepRunnable implements Runnable {
        private final MediaPlayer mediaPlayer;
        private final View view;
        private final int repeats;
        private final int interval;
        private int currentRepeat;
    
        public BeepRunnable(@NonNull View view, int repeats, int interval) {
            this.view = view;
            mediaPlayer = MediaPlayer.create(this.view.getContext(), R.raw.beep);
            this.repeats = repeats;
            this.interval = interval;
        }
    
        @Override
        public void run() {
            mp.start();
            if (currentRepeat < repeats) {
                // set to beep again
                currentRepeat = currentRepeat + 1;
                view.postDelayed(this, interval);
            }
            else {
                // beep is over, just reset the counter
                reset();
            }
        }
    
        public void reset() {
            currentRepeat = 0;
        }
    
        public void destroy() {
            if (mediaPlayer.isPlaying()) {
                mediaPlayer.stop();
            }
    
            mediaPlayer.release();
            view.removeCallbacks(this);
        }
    }
    

    Then in you activity for example

    public final ApplicationActivity extends Activity {
        private BeepRunnable beepRunnable;
        ...
        // in your place where you need to start the beeping
        beepRunnable = new BeepRunnable(anyNonNullView, 4, 500);
        anyNonNullView.post(beepRunnable);
    }
    
    public void onDestroy() {
        super.onDestroy();
    
        if (beepRunnable != null) {
            beepRunnable.destroy();
            beepRunnable = null;
        }
    }