I am trying to create a media player. For that I am trying to play next song on completion of previous one. Here is my code:
int i = 0;
public void track(View view) {
while (!m1.isPlaying()) {
play(list.get(i));
while (m1.isPlaying()) ;
i++;
}
}
public void play(String T) {
try {
m1.setDataSource(T);
m1.prepare();
m1.start();
} catch (IOException e) {
Toast toast = Toast.makeText(getApplicationContext(), "Network Error", Toast.LENGTH_SHORT);
toast.show();
}
}
What you are looking for is setOnCompletionListener. This allows you to get a callback from the MediaPlayer when the playback is finished. You can start the next track in there:
mMediaPlayer.setOnCompletionListener(new OnCompletionListener() {
void onCompletion(MediaPlayer mp){
//play next track
play(mNextTrack);
}
})
See Android documentation for more details.
Related
Please I want to know how to set my MediaPlayer to playback continuously without stopping when activity screen rotates? The challenge I'm having now is that when playing is in progress and I happen to tilt the screen the music stops and will require another action to have it play again.
this is the part of which plays the music in my Activity
// setting up media players
public void play(View v) {
if (player == null) {
//then here, I sent the position of the chosen song in the intent extras.
//the get back the extra
int position = 0;
try{
position=getIntent().getIntExtra("soundfile",0);
}catch (Exception e)
{
e.printStackTrace();
}
String fileToPlay="song_"+position;
player = MediaPlayer.create(this, position);
Toast.makeText(this, "Hymn Tune Playing", Toast.LENGTH_SHORT ).show();
soundSeekBar = (SeekBar) findViewById(R.id.seekBar1);
soundSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser){
player.seekTo(progress);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
soundSeekBar.setProgress(player.getCurrentPosition());
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
player.getCurrentPosition();
}
});
player.setLooping(true);
player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
}
});
}
player.start();
Toast.makeText(this, "Playing Continues...", Toast.LENGTH_SHORT ).show();
soundThread = new Thread(this);
soundThread.start();
}
public void pause(View v) {
if (player != null) {
player.pause();
Toast.makeText(this, "Hymn Tune Paused", Toast.LENGTH_SHORT ).show();
}
}
public void stop(View v) {
stopPlayer();
}
private void stopPlayer() {
if (player != null) {
player.release();
player = null;
Toast.makeText(this, "Hymn Tune Stoped", Toast.LENGTH_SHORT ).show();
}
}
#Override
protected void onStop() {
super.onStop();
stopPlayer();
}
#Override
public void run() {
int currentPosition = 0;
int soundTotal = player.getDuration();
soundSeekBar.setMax(soundTotal);
while (player != null && currentPosition < soundTotal){
try {
Thread.sleep(300);
currentPosition = player.getCurrentPosition();
}
catch (InterruptedException soundException){
return;
}
catch (Exception otherException){
return;
}
soundSeekBar.setProgress(currentPosition);
}
}
#Override
public void onPointerCaptureChanged(boolean hasCapture) {
}
You must move your playback code to background service, as those will run constantly while activity is stopped and restarted during tilting. Check out extensive guide to services here
https://developer.android.com/guide/components/services
I have a problem with the Android MediaPlayer. As soon as a new sound file is clicked by user input, the old one does not stop, so all audio files overlap.
I already tried common methods like MediaPlayer.stop(); and
MediaPlayer.release();
These methods always result in an app crash, although they are called in the correct order
public void Abspielen(String Datei) {
try {
AndreasPlayer = MediaPlayer.create(MainActivity.this, getResources().getIdentifier(Datei, "raw", getPackageName()));
AndreasPlayer.start();
} catch (Exception e) {
Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_LONG).show();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Abspielen("filename");
}
I worked out the following solution:
public void Abspielen(String Datei) {
try {
stopKnopf = findViewById(R.id.fab2);
stopKnopf.show();
try {
if (AndreasPlayer.isPlaying()) {
AndreasPlayer.reset();
}
} catch (Exception ex) {
}
AndreasPlayer = MediaPlayer.create(MainActivity.this, getResources().getIdentifier(Datei, "raw", getPackageName()));
AndreasPlayer.start();
stopKnopf.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
AndreasPlayer.reset();
stopKnopf.hide();
}
});
AndreasPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
AndreasPlayer.reset();
stopKnopf.hide();
}
});
} catch (Exception e) {
Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_LONG).show();
}
}
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);
}
}
I am a beginner and I started by creating a radio app that has many stations but I have one problem.
When I hit "Play" for the radio, it starts playing then I come back to the precedent activity (stations list) and when I come back again to the same radio that is playing and hit "Pause" it diffuses "Not Playing". (I made a toast so that when I hit "Pause" while the radio is not playing it diffuses "Not Playing") but the radio is still "Playing".
Here is the code for the 2 buttons (Play and Pause):
btnPlayMFM.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (isOnline() == true) {
if (isPlaying() == false) {
Toast t = Toast.makeText(MosaiqueFM.this, "Loading \nPlease Wait", 10000);
t.show();
try {
mediaPlayer.reset();
mediaPlayer.setDataSource(stream_url);
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
} catch (IOException e) {
e.printStackTrace();
}
} else if (isPlaying() == true) {
Toast t2 = Toast.makeText(MosaiqueFM.this, "Playing", 2000);
t2.show();
}
}
if (isOnline() == false){
Toast t = Toast.makeText(MosaiqueFM.this, "Internet Connection Required", 3000);
t.show();
}
}
});
btnPauseMFM.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (isPlaying() == true) {
mediaPlayer.stop();
} else if (isPlaying() == false){
Toast t = Toast.makeText(MosaiqueFM.this, "Not Playing", 2000);
t.show();
}
}
});
public boolean isPlaying() {
return(mediaPlayer != null && mediaPlayer.isPlaying());
}
public boolean isOnline() {
cm = (ConnectivityManager) getSystemService(this.CONNECTIVITY_SERVICE);
return cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnectedOrConnecting();
}
If you have two activities - one more showing stations list and another for play/pause a particular radio station then apparently when you'll leave the second activity , your activity will get destroyed and mediaPlayer will become null and so , when you'll come back, isPlaying() will be false.
And that's why you are getting this Toast-
Toast t = Toast.makeText(MosaiqueFM.this, "Not Playing", 2000);
Suggestion - For these kind of apps, you don't want the radio to stop when the user leaves your app. So I suggest you use service for play purpose.
I'm using mediaPlayer in my Android application to stream an MP3 url from online. Instead of just playing the 1 url, how can I stream 5 urls to play one after the other? here's my code
Uri myUri = Uri.parse("https://db.tt/9nBgouRf");
final MediaPlayer sdrPlayer = new MediaPlayer();
try {
sdrPlayer.setDataSource(this, myUri);
sdrPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
sdrPlayer.prepare(); //don't use prepareAsync for mp3 playback
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(channelx.this,
"Please turn on WiFi and try again", Toast.LENGTH_LONG).show();
}
play.setOnClickListener( new OnClickListener() {
#Override
public void onClick(View v) {
sdrPlayer.start();
}
}
);
Just create a List to hold all of your URIs
Set up some class variables:
private int playlistPos = 0;
private List<Uri> myUris = new ArrayList<Uri>();
private MediaPlayer sdrPlayer = new MediaPlayer();
Set up a method for initialising the song:
public initSong(Uri myUri) {
try {
sdrPlayer.setDataSource(this, myUri);
sdrPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
sdrPlayer.prepare(); // don't use prepareAsync for mp3 playback
}
catch (IOException e) {
e.printStackTrace();
Toast.makeText(channelx.this,
"Please turn on WiFi and try again",
Toast.LENGTH_LONG).show();
}
}
Then in the onCreate()
myUris.add(Uri.parse("https://db.tt/9nBgouRf"));
// Add the others as well...
initSong(myUris.get(playlistPos);
sdrPlayer.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
playlistPos++;
initSong(myUris.get(playlistPos));
sdrPlayer.start(); // Start it as well if you wish
}
});
play.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
sdrPlayer.start();
}
});