Search code examples
androidtimermedia-playerrepeat

Android Media player Repeat song For 'n' times and Timer value


I would like to play the song for 'n' number of times as per the user input like 5,10 ..etc using android media player.

For loop is not working as expected Please guide me how to achieve this.

I used the "onCompletion" but it is not working as expected but default repeat for infinite loop is working.

package com.example.vsr1.setitplayerversion2;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;
import java.util.Timer;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.FragmentManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;


public class MainActivity extends Activity implements OnCompletionListener, SeekBar.OnSeekBarChangeListener {

    private ImageButton btnPlay;
    private ImageButton btnForward;
    private ImageButton btnBackward;
    private ImageButton btnNext;
    private ImageButton btnPrevious;
    private ImageButton btnPlaylist;
    private ImageButton btnRepeat;
    private ImageButton btnShuffle;
    private SeekBar songProgressBar;
    private TextView songTitleLabel;
    private TextView songCurrentDurationLabel;
    private TextView songTotalDurationLabel;
    private Dialog supportDialog;
    private RadioButton selectedBtn;
    private Context ctx;
    // Media Player
    private MediaPlayer mp;
    // Handler to update UI timer, progress bar etc,.
    private Handler mHandler = new Handler();;
    private SongsManager songManager;
    private Utilities utils;
    private int seekForwardTime = 5000; // 5000 milliseconds
    private int seekBackwardTime = 5000; // 5000 milliseconds
    private int currentSongIndex = 0;
    private boolean isShuffle = false;
    private boolean isRepeat = false;
    private ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>();

    private TextView songRepeatLabel;
    private TextView songRepeatCount;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.player);

        ctx = this;
        // All player buttons
        btnPlay = (ImageButton) findViewById(R.id.btnPlay);
        btnForward = (ImageButton) findViewById(R.id.btnForward);
        btnBackward = (ImageButton) findViewById(R.id.btnBackward);
        btnNext = (ImageButton) findViewById(R.id.btnNext);
        btnPrevious = (ImageButton) findViewById(R.id.btnPrevious);
        btnPlaylist = (ImageButton) findViewById(R.id.btnPlaylist);
        btnRepeat = (ImageButton) findViewById(R.id.btnRepeat);
        btnShuffle = (ImageButton) findViewById(R.id.btnShuffle);
        songProgressBar = (SeekBar) findViewById(R.id.songProgressBar);
        songTitleLabel = (TextView) findViewById(R.id.songTitle);
        songCurrentDurationLabel = (TextView) findViewById(R.id.songCurrentDurationLabel);
        songTotalDurationLabel = (TextView) findViewById(R.id.songTotalDurationLabel);
        songRepeatLabel = (TextView) findViewById(R.id.txtRepeatLabel);
         songRepeatCount = (TextView) findViewById(R.id.txtRepeatCount);
        // Mediaplayer
        mp = new MediaPlayer();
        songManager = new SongsManager();
        utils = new Utilities();

        // Listeners
        songProgressBar.setOnSeekBarChangeListener(this); // Important
        mp.setOnCompletionListener(this); // Important
        mp.setLooping(false);

        // Getting all songs list
        songsList = songManager.getPlayList(Environment.getExternalStorageDirectory());

        //Button showDialog = (Button)findViewById(R.id.sh)

        // By default play first song
       //if(songsList!=null && songsList.size()>0) playSong(0);

        /**
         * Play button click event
         * plays a song and changes button to pause image
         * pauses a song and changes button to play image
         * */
        btnPlay.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // check for already playing
                if(mp.isPlaying()){
                    if(mp!=null){
                        mp.pause();
                        // Changing button image to play button
                        btnPlay.setImageResource(R.drawable.btn_play);
                    }
                }else{
                    // Resume song
                    if(mp!=null){
                        mp.start();
                        // Changing button image to pause button
                        btnPlay.setImageResource(R.drawable.btn_pause);
                    }
                }

            }
        });

        /**
         * Forward button click event
         * Forwards song specified seconds
         * */
        btnForward.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // get current song position
                int currentPosition = mp.getCurrentPosition();
                // check if seekForward time is lesser than song duration
                if(currentPosition + seekForwardTime <= mp.getDuration()){
                    // forward song
                    mp.seekTo(currentPosition + seekForwardTime);
                }else{
                    // forward to end position
                    mp.seekTo(mp.getDuration());
                }
            }
        });

        /**
         * Backward button click event
         * Backward song to specified seconds
         * */
        btnBackward.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // get current song position
                int currentPosition = mp.getCurrentPosition();
                // check if seekBackward time is greater than 0 sec
                if(currentPosition - seekBackwardTime >= 0){
                    // forward song
                    mp.seekTo(currentPosition - seekBackwardTime);
                }else{
                    // backward to starting position
                    mp.seekTo(0);
                }

            }
        });

        /**
         * Next button click event
         * Plays next song by taking currentSongIndex + 1
         * */
        btnNext.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // check if next song is there or not
                if(currentSongIndex < (songsList.size() - 1)){
                    playSong(currentSongIndex + 1);
                    currentSongIndex = currentSongIndex + 1;
                }else{
                    // play first song
                    playSong(0);
                    currentSongIndex = 0;
                }

            }
        });

        /**
         * Back button click event
         * Plays previous song by currentSongIndex - 1
         * */
        btnPrevious.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                if(currentSongIndex > 0){
                    playSong(currentSongIndex - 1);
                    currentSongIndex = currentSongIndex - 1;
                }else{
                    // play last song
                    playSong(songsList.size() - 1);
                    currentSongIndex = songsList.size() - 1;
                }

            }
        });

        /**
         * Button Click event for Repeat button
         * Enables repeat flag to true
         * */
        btnRepeat.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                if(isRepeat){
                    isRepeat = false;
                    Toast.makeText(getApplicationContext(), "Repeat is OFF", Toast.LENGTH_SHORT).show();
                    btnRepeat.setImageResource(R.drawable.btn_repeat);
                }else{
                    // make repeat to true
                    isRepeat = true;
                    Toast.makeText(getApplicationContext(), "Repeat is ON", Toast.LENGTH_SHORT).show();
                    showDialog(); // call popup
                    songRepeatCount.setText(String.valueOf(initialRepeatCount));
                    // make shuffle to false
                    isShuffle = false;
                    btnRepeat.setImageResource(R.drawable.btn_repeat_focused);
                    btnShuffle.setImageResource(R.drawable.btn_shuffle);
                }
            }
        });

        /**
         * Button Click event for Shuffle button
         * Enables shuffle flag to true
         * */
        btnShuffle.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                if(isShuffle){
                    isShuffle = false;
                    Toast.makeText(getApplicationContext(), "Shuffle is OFF", Toast.LENGTH_SHORT).show();
                    btnShuffle.setImageResource(R.drawable.btn_shuffle);
                }else{
                    // make repeat to true
                    isShuffle= true;
                    Toast.makeText(getApplicationContext(), "Shuffle is ON", Toast.LENGTH_SHORT).show();
                    // make shuffle to false
                    isRepeat = false;
                    btnShuffle.setImageResource(R.drawable.btn_shuffle_focused);
                    btnRepeat.setImageResource(R.drawable.btn_repeat);
                }
            }
        });

        /**
         * Button Click event for Play list click event
         * Launches list activity which displays list of songs
         * */
        btnPlaylist.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                Intent i = new Intent(getApplicationContext(), PlayListActivity.class);
                startActivityForResult(i, 100);
            }
        });

    }

    /**
     * Receiving song index from playlist view
     * and play the song
     * */
    @Override
    protected void onActivityResult(int requestCode,
                                    int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode == 100){
            currentSongIndex = data.getExtras().getInt("songIndex");
            // play selected song
            playSong(currentSongIndex);
        }

    }

    /**
     * Function to play a song
     * @param songIndex - index of song
     * */
    public void  playSong(int songIndex){
        // Play song
        try {
            if(songsList!=null && songsList.size()>0) {
                mp.reset();
                mp.setDataSource(songsList.get(songIndex).get("songPath"));
                mp.prepare();
                mp.start();
                // Displaying Song title
                String songTitle = songsList.get(songIndex).get("songTitle");
                songTitleLabel.setText(songTitle);

                // Changing Button Image to pause image
                btnPlay.setImageResource(R.drawable.btn_pause);

                // set Progress bar values
                songProgressBar.setProgress(0);
                songProgressBar.setMax(100);

                // Updating progress bar
                updateProgressBar();
            }
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Update timer on seekbar
     * */
    public void updateProgressBar() {
        mHandler.postDelayed(mUpdateTimeTask, 100);
    }

    /**
     * Background Runnable thread
     * */
    private Runnable mUpdateTimeTask = new Runnable() {
        public void run() {
            long totalDuration = mp.getDuration();
            long currentDuration = mp.getCurrentPosition();

            // Displaying Total Duration time
            songTotalDurationLabel.setText(""+utils.milliSecondsToTimer(totalDuration));
            // Displaying time completed playing
            songCurrentDurationLabel.setText(""+utils.milliSecondsToTimer(currentDuration));

            // Updating progress bar
            int progress = (int)(utils.getProgressPercentage(currentDuration, totalDuration));
            //Log.d("Progress", ""+progress);
            songProgressBar.setProgress(progress);

            // Running this thread after 100 milliseconds
            mHandler.postDelayed(this, 100);
        }
    };

    /**
     *
     * */
    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {

    }

    /**
     * When user starts moving the progress handler
     * */
    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
        // remove message Handler from updating progress bar
        mHandler.removeCallbacks(mUpdateTimeTask);
    }

    /**
     * When user stops moving the progress hanlder
     * */
    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        mHandler.removeCallbacks(mUpdateTimeTask);
        int totalDuration = mp.getDuration();
        int currentPosition = utils.progressToTimer(seekBar.getProgress(), totalDuration);

        // forward or backward to certain seconds
        mp.seekTo(currentPosition);

        // update timer progress again
        updateProgressBar();
    }

    private int initialRepeatCount;
    private Timer initialRepeatTimerValue;
    /**
     * On Song Playing completed
     * if repeat is ON play same song again
     * if shuffle is ON play random song
     * */
    @Override
    public void onCompletion(MediaPlayer arg0) {

        int count = 0;
        // check for repeat is ON or OFF
        if(isRepeat)
        {
            if(initialRepeatCount>0)
            {
                // initial Repeat song
                count=initialRepeatCount;
                for (int i=count;i>=1; i--){
                    songRepeatCount.setText(String.valueOf(count));
                    playSong(currentSongIndex);
                    Toast.makeText(getApplicationContext(), "Repeat ", Toast.LENGTH_SHORT).show();
                    count=i;
                }
                // Next song repeat same count
                if(songsList!=null && currentSongIndex < (songsList.size() - 1)){
                    currentSongIndex = currentSongIndex + 1;

                    count=initialRepeatCount;
                    for (int i=count;i>=1; i--){
                        playSong(currentSongIndex);
                        count=i;
                        Toast.makeText(getApplicationContext(), "Next song Repeat ", Toast.LENGTH_SHORT).show();
                        songRepeatCount.setText(String.valueOf(count));
                    }
                }
                else
                {
                    // play first song
                    playSong(0);
                    currentSongIndex = 0;
                    count=initialRepeatCount;

                    for (int i=count;i>=1; i--){
                        playSong(currentSongIndex);
                        count=i;
                        songRepeatCount.setText(String.valueOf(count));
                    }
                }
            }
            // inital Timer value
           /* else if (Timer.value)
            {

            }*/
            // default Repeat
            else
            {   // repeat is on play same song again
                playSong(currentSongIndex);
            }
        }

        else if(isShuffle)
        {
            // shuffle is on - play a random song
            Random rand = new Random();
            currentSongIndex = rand.nextInt((songsList.size() - 1) - 0 + 1) + 0;
            playSong(currentSongIndex);
        } else
        {
            // no repeat or shuffle ON - play next song
            if(songsList!=null && currentSongIndex < (songsList.size() - 1))
            {
                playSong(currentSongIndex + 1);
                Toast.makeText(getApplicationContext(), "Default next song ", Toast.LENGTH_SHORT).show();
                currentSongIndex = currentSongIndex + 1;
            }else
            {
                // play first song
                playSong(0);
                currentSongIndex = 0;
            }
        }
    }

    @Override
    public void onDestroy(){
        super.onDestroy();
        mp.release();
    }


    public void showDialog(){
        supportDialog = new Dialog(ctx,android.R.style.Theme_Black_NoTitleBar);

        supportDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        supportDialog.setContentView(R.layout.user_input_fragment); // add your custom layout pop up
        supportDialog.setCancelable(true);
        supportDialog.setCanceledOnTouchOutside(true); // if it is set false if you touch outside of the popup ,popup will not close.
        supportDialog.setTitle("Set Repeat");


        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
        Window window = supportDialog.getWindow();
        lp.copyFrom(window.getAttributes());
        //This makes the dialog take up the full width
        lp.width = WindowManager.LayoutParams.MATCH_PARENT; // it will take respective mobile screen hight and width
        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;

        window.setAttributes(lp);
        //supportDialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT)); // enable to set color transparant

        final RadioGroup rgrp;
        final EditText txt2;
        final TimePicker tp;
        // TextView txtRepeatValue;
         //TextView txtRepeatLabel;
        Button ok;
        Button cancel;

        rgrp = (RadioGroup)supportDialog.findViewById(R.id.rgrp);
        txt2 = (EditText)supportDialog.findViewById(R.id.txt2);
        tp = (TimePicker)supportDialog.findViewById(R.id.txt3);
        ok = (Button)supportDialog.findViewById(R.id.ok_btn);
        cancel =(Button)supportDialog.findViewById(R.id.cancel_btn);

        tp.setIs24HourView(true);
        txt2.setVisibility(View.GONE);
        tp.setVisibility(View.GONE);

        rgrp.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                int id = rgrp.getCheckedRadioButtonId();

                View radioButton = rgrp.findViewById(id);

                // Check which radio button was clicked
                switch (radioButton.getId()) {
                    case R.id.rb1:
                        txt2.setVisibility(View.GONE);
                        tp.setVisibility(View.GONE);
                        break;
                    case R.id.rb2:
                        txt2.setVisibility(View.VISIBLE);
                        tp.setVisibility(View.GONE);
                        txt2.setFocusable(true);
                        txt2.setCursorVisible(true);
                        break;
                    case R.id.rb3:
                        tp.setVisibility(View.VISIBLE);
                        txt2.setVisibility(View.GONE);
                        tp.setFocusable(true);
                        break;
                }
            }
        });

        supportDialog.show();

        ok.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int id = rgrp.getCheckedRadioButtonId();

                View radioButton = rgrp.findViewById(id);

                // Check which radio button was clicked
                switch (radioButton.getId()) {
                    case R.id.rb1:
                        Toast.makeText(ctx, "default selected", Toast.LENGTH_LONG).show();
                        supportDialog.dismiss();
                        break;
                    case R.id.rb2:
                        Toast.makeText(ctx, "set count edit text value " + txt2.getText().toString(), Toast.LENGTH_LONG).show();
                        initialRepeatCount = Integer.parseInt(txt2.getText().toString());
                        songRepeatLabel.setText("Repeat :");
                        songRepeatCount.setText(txt2.getText());
                        supportDialog.dismiss();
                        break;
                    case R.id.rb3:
                        String strDateTime = tp.getCurrentHour() + " : " + tp.getCurrentMinute();
                        Toast.makeText(ctx, "Timer selected " + strDateTime, Toast.LENGTH_LONG).show();
                        supportDialog.dismiss();
                        break;
                }
            }
        });

        cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                supportDialog.cancel();
            }
        });

    }

}

Solution

  • you can try the following mp.setLooping(false);.

    Edits

    Please set on complete listener on Media player object like

    mp.setOnCompletionListener(this);

    You can achieve your requirement following way.

    You can set the mp.setLooping(false).set the counter to increase by 1 onCompletion(MediaPlayer mediaPlayer) method and check

      if(count==total){
            //create method to change the song
            changetheSongorreleaseMediaplayer();
            }  
        else{
          //create method to replay the song
           replaythesamesong();
         }