I am working on a live streaming radio Android app...i have an array with 4 tracks, when i reach the end of the list suppose that the next button will represent " the last song" but it doesn't and crashes the app.
Here is the button code:
counter=0;
mediaPlayer=new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
btn_next.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
if (counter < songurl.length) {
counter = counter + 1;
textview.setText(songurl[counter]);
try {
mediaPlayer.reset();
} catch (Exception ex) {
try {
mediaPlayer.setDataSource(songurl[counter]);
} catch (IOException e) {
e.printStackTrace();
}
try {
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.start();
}
} else {
Toast.makeText(MainActivity.this, "last song", Toast.LENGTH_SHORT).show();
}
}
});
One more question... in case I want to make it a closed loop when the app reaches the last song and I want to press next to start the list from the beginning how can I do it?
Thanks.
You can simply add a modulo (%) operator in your code
counter = counter++ % songurl.length
no need to add an extra if else block
btn_next.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
counter = counter++ % songurl.length
textview.setText(songurl[counter]);
try {
mediaPlayer.reset();
} catch (Exception ex) {
try {
mediaPlayer.setDataSource(songurl[counter]);
} catch (IOException e) {
e.printStackTrace();
}
try {
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.start();
}
}
});
One problem you have is that you are incrementing the counter just after you check that it is within the bounds, which means your safety check is useless. Move counter = counter + 1; to the end of the if statement.
As far as making it loop continuously, you can change it to counter = (counter + 1) % songurl.length; at the end of the if statement body.
Beyond the scope of the question you asked, there are some problems with your usage of MediaPlayer. It doesn't make any sense to have so much key logic in a catch statement. That means you expect the exception to happen. You should re-think what you are doing there.
You see you called mediaPlayer.setDataSource(songurl[counter]) in the catch block.
what if it will not have exception when you call mediaPlayer.reset()
try this:
try{
mediaPlayer.reset();
mediaPlayer.setDataSource();
mediaPlayer.prepareAsync();--or mediaPlayer.prepare();
(It depends on whether you load the url on the internet)
mediaPlayer.start(); -- if you call mediaPlayer.prepareAsync() you should call mediaPlayer.start() at the OnPreparedListener;
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.start();
}
});
}
And if you still wondering, I suggest you to read something about MediaPlay's state.
PS If mediaPlayer is playing ,and you wanna let it play another one ,call mediaPlayer.stop() first;
To make the loop you should check in the onclicklistener that the if the counter is equal to the songurl.length which is i think the total number of song in the playlist.
int counter=0;
MediaPlayer mediaPlayer=new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
btn_next.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
if (counter < songurl.length) {
counter = counter + 1;
textview.setText(songurl[counter]);
try {
mediaPlayer.reset();
} catch (Exception ex) {
try {
mediaPlayer.setDataSource(songurl[counter]);
} catch (IOException e) {
e.printStackTrace();
}
try {
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.start();
}
} else if(counter == songurl.length) {
counter = 0;
// Toast.makeText(MainActivity.this, "last song", Toast.LENGTH_SHORT).show();
textview.setText(songurl[counter]);
try {
mediaPlayer.reset();
} catch (Exception ex) {
try {
mediaPlayer.setDataSource(songurl[counter]);
} catch (IOException e) {
e.printStackTrace();
}
try {
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.start();
}
}
}
});
in the elseif condition i have set the counter to 0. so that it will get in the loop.
Related
I m trying to play song by clicking a button in my application. There are two buttons in the application. Each button can play a different song. I allocated all those songs in Assets folder. There are total of two songs in the folder of Assets now.
public class AudioCollective implements MediaPlayer.OnPreparedListener, OnCompletionListener{
static String TAG = "AudioCollective====>";
Context mContext;
MediaPlayer mPlayer;
ArrayList<AssetFileDescriptor> array;
public AudioCollective(Context theContext){
mContext = theContext;
}
public void addSound(int SoundID){
array = new ArrayList<AssetFileDescriptor>();
AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(SoundID);
array.add(afd);
}
public void playSound() {
for (int i =0; i<array.size();i++) {
Log.i(TAG,"preparing audio " + array.get(i) );
mPlayer = new MediaPlayer();
try {
mPlayer.setDataSource(array.get(i).getFileDescriptor());
} catch (IOException e) {
e.printStackTrace();
}
try {
mPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mPlayer.setOnPreparedListener(this);
mPlayer.setOnCompletionListener(this);
}
}
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
if (mPlayer != null) {
Log.d(TAG, "releasing audio now");
mPlayer.release();
mPlayer = null;
mediaPlayer.release();
//mediaPlayer = null;
}
}
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
Log.i(TAG, "playing audio now");
mediaPlayer.start();
}
}
meanwhile in my MainActivity :
AudioCollective ac = new AudioCollective();
ac.addSounds(R.raw.na);
playButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view){
ac.playSound();
}
});
So, the problem is every time I clicked the button, the application play the two songs together instead of playing the required song. anyone can tell me why would this be happen?
Yes it because you are playing both of them at same in for loop.
Update your playSound() method pass value in it as argument.
To play first song pass 0 , To play second song pass 1 .
playSound(0) playSound(1)
public void playSound(int pos) {
Log.i(TAG,"preparing audio " + array.get(pos) );
mPlayer = new MediaPlayer();
try {
mPlayer.setDataSource(array.get(pos).getFileDescriptor());
} catch (IOException e) {
e.printStackTrace();
}
try {
mPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mPlayer.setOnPreparedListener(this);
mPlayer.setOnCompletionListener(this);
}
}
It works for a few buttons, but when I tap about 6 then only some of them work. The ones that don't work give the error (1, -19). I do the media player state wrapper set up, so if I need to use that to get states of my "mp"s, let me know.
public class SoundFile {
public SoundFile(final Activity activity, final String soundfile, int imgButtonId, ArrayList<MediaPlayerStateWrapper> mps) {
this.mp = new MediaPlayerStateWrapper();
try {
this.afd = activity.getAssets().openFd(soundfile + ".mp3");
} catch (IOException e) {
e.printStackTrace();
}
this.allMps = mps;
mps.add(this.mp);
this.position = (ImageButton) activity.findViewById(imgButtonId);
this.position.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
mp.reset();
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
mp.prepareAsync();
mp.start();
}catch (Exception ex){
ex.printStackTrace();
}
....
You have to add an onPreparedListener. Here is what I did and it worked.
try {
mp = new MediaPlayer();
mp.reset();
try {
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
} catch (IOException e) {
e.printStackTrace();
}
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
mp.release();
}
});
mp.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mpm) {
mpm.start();
mp.start();
}
});
mp.prepareAsync();
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
}
}
I used this code for play a sound by click on a button.
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(mp.isPlaying())
{
mp.stop();
}
try {
mp.reset();
AssetFileDescriptor afd;
afd = getAssets().openFd("sound/07.mp3");
mp.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
mp.prepare();
mp.start();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
it's working well but i can't stop sound!
I use mp.stop(); .but click on button plays sound again!
when your onClickListener runs, the if statement checks after that other codes run. try to put an else statement after if you code should be like this :
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(mp.isPlaying())
{
mp.stop();
}else{
try {
mp.reset();
AssetFileDescriptor afd;
afd = getAssets().openFd("sound/07.mp3");
mp.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
mp.prepare();
mp.start();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
try {
mp.setDataSource(text);
mp.prepare();
mp.setVolume(0.4f, 0.4f);
}
catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
catch (IllegalMonitorStateException e)
{
e.printStackTrace();
}
final Handler hlr = new Handler();
final Runnable looper = new Runnable() {
#Override
public void run()
{
if(mp!=null)
{
if(mp.isPlaying())
{
mp.stop();
}
}
mp.start();
}
};
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp)
{
hlr.postDelayed(looper, 5000);
}
});
The above line of code is part of an Alarm Activity , My objective is to loop an Audio file, with a delay of 5000 ms. However, the code doesn't seems to have any effect. Unable to play the audio. What am I doing wrong? Please help me fix this. Any help will be appreciated.
I am new in android programming. I have a problem in stopping mediaplayer when I click the button for stop. I think I have some problem with my code because my sounds are looping that's is why mp.stop(); is not working or probably because of the sleep? I am not sure. Is there anyone who can help me with these? Thanks in advance.
Here is my code for stop:
bb5.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0){
if (mp.isPlaying()){
mp.stop();
}
} // END onClick()
});
Here is my code for playing the sound:
protected void managerOfSound() {
int size = tempq.size();
for (int i = 0; i < tempq.size(); i++) {
String u =tempq.get(i);
//WHOLE
if (u.equals("a4")){
mp = MediaPlayer.create(this, R.raw.a4);
mp.start();
try {
Thread.sleep(2000);
} catch (InterruptedException ie) {
// TODO Auto-generated catch block
}
}else if (u.equals("b4")){
mp = MediaPlayer.create(this, R.raw.b4);
mp.start();
try {
Thread.sleep(2000);
} catch (InterruptedException ie) {
// TODO Auto-generated catch block
}
}else if (u.equals("c4")){
mp = MediaPlayer.create(this, R.raw.c4);
mp.start();
try {
Thread.sleep(2000);
} catch (InterruptedException ie) {
// TODO Auto-generated catch block
}