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();
}
});
}
}
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();
}