Reputation: 79
I am trying to make a music app in android studio. My app works fine except it has a small bug. In my Main activity I have a list of songs which i imported from my raw folder in resources folder. My second window is a NowPlaying java file where I can pause, forward, and see the lyrics for the song.
When I play the first song from the Main Activity, it works fine. But, when I want to play a second song as the first song is being played, the second song plays on top of the first song. The lyrics gets updated, the seekbar gets updated, but the two song play together. However, this does not happen when I pause the first song, go back to the Main Activity and play the second song. I used :
if(song != null){
if(song.isPlaying()){
song.reset(); song = null;
}
}
I know there is a mistake in my NowPlaying.java file: so here is the entire code:
PS. I am just in a learning process.
MediaPlayer song = null;
SeekBar seekBar;
Intent intent = getIntent();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_now_playing);
seekBar = (SeekBar) findViewById(R.id.seekBar);
//String selectedSong = getIntent().getExtras().getString("selectSong");
selectSong();
//for pause button
pauseButton();
//for songtile
getSongtitle();
getSongList();
getNextButton();
getPreviousButton();
} // end of onCreate method
/**
* Method for selecting the song
* Moves to startSong method
*/
public void selectSong(){
TextView lyricsBox = (TextView) findViewById(R.id.lyricsBox);
lyricsBox.setMovementMethod(new ScrollingMovementMethod());
String nextPlay = intent.getStringExtra("playSong");
if(song != null){
if(song.isPlaying()){
song.reset();
song = null;
}
}
if (nextPlay.equals("Demons")) {
song = MediaPlayer.create(this, R.raw.demons);
lyricsBox.setText(R.string.demonsLyrics);
} else if (nextPlay.equals("Black Space")) {
song = MediaPlayer.create(this, R.raw.blankspace);
lyricsBox.setText(R.string.blankspaceLyrics);
} else if (nextPlay.equals("Case 420")) {
song = MediaPlayer.create(this, R.raw.case420);
lyricsBox.setText(R.string.case420Lyrics);
}
else if(nextPlay.equals("Jalma")){
song = MediaPlayer.create(this, R.raw.jalma);
lyricsBox.setText(R.string.jalmaLyrics);
}
else if(nextPlay.equals("Parelima")){
song = MediaPlayer.create(this, R.raw.parelima);
lyricsBox.setText(R.string.parelimaLyrics);
}
else if(nextPlay.equals("Mero Balyakal Ko Sathi")){
song = MediaPlayer.create(this, R.raw.balyakalsathi);
lyricsBox.setText(R.string.balyakalSathi);
}
else if(nextPlay.equals("Euta Sathi")){
song = MediaPlayer.create(this, R.raw.eutasathi);
}
else if(nextPlay.equals("Audai Jadai")){
song = MediaPlayer.create(this, R.raw.audaijadai);
}
else if(nextPlay.equals("Cheerleader")){
song = MediaPlayer.create(this, R.raw.cheerleader);
}
// to start playing the song
startButton();
}
//method to make sure seekbar updates till song ends
Runnable run = new Runnable() {
@Override
public void run() {
getseekBar();
}
};
/**
* Method to start song (play the song)
*
*/
public void startButton() {
song.start();
//to update seek bar
getseekBar();
}
/**
* Method to update the seekbar.
* implement touch in seekbar to change song position
*/
public void getseekBar() {
seekBar.setMax(song.getDuration());
seekBar.setProgress(song.getCurrentPosition());
seekBar.postDelayed(run, 1000);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
int seek_to;
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
seek_to = progress;
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
song.seekTo(seek_to);
}
});
}
/**
* Method for pause Button
* to pause song once clicked and change button background to play image
* Again play the song if the button is pressed again. and change background back to pause image
*/
public void pauseButton(){
final Button playButton = (Button) findViewById(R.id.playButton);
playButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (song.isPlaying()) {
playButton.setBackgroundResource(R.drawable.playbutton);
song.pause();
} else {
playButton.setBackgroundResource(R.drawable.pausebutton);
song.start();
}
}
});
}
/**
* Method to get the song title from first java file and display in the title
*/
public void getSongtitle(){
Intent intent = getIntent();
String nextPlay = intent.getStringExtra("playSong");
TextView Songtitle = (TextView) findViewById(R.id.Songtitle);
Songtitle.setText(nextPlay);
}
/**
* Method for song list button
* Goes back to the first java file once the button is cliked,
* displays the song list
*/
public void getSongList(){
Button lyricsButton = (Button) findViewById(R.id.lyricsButton);
lyricsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(NowPlaying.this, MainActivity.class));
}
});
}
/**
* Method for next button
* the song skips every 10 seconds once clicked
*/
public void getNextButton(){
Button nextButton = (Button) findViewById(R.id.nextButton);
nextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int startTime = song.getCurrentPosition();
int forwardTime = 10000;
startTime += forwardTime;
if(startTime <= song.getDuration()){
song.seekTo(startTime);
}
else{
song.stop();
}
}
});
} // end of getNextButton
/**
* Method for previous button
* the song skips back 10 seconds once clicked
*/
public void getPreviousButton(){
Button previousButton = (Button) findViewById(R.id.previousButton);
previousButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int startTime = song.getCurrentPosition();
int previousTime = 10000;
startTime -= previousTime;
if(startTime >= 0){
song.seekTo(startTime);
}
else{
song.seekTo(0);
song.start();
}
}
});
}
Code for Main Activity:
public class MainActivity extends AppCompatActivity {
String[] songList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
populateList();
}
private void populateList(){
songList = new String[] {"Jalma", "Demons", "Parelima", "Mero Balyakal Ko Sathi", "Audai Jadai",
"Case 420", "Euta Sathi", "Cheerleader"};
ListAdapter arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
songList);
ListView theList = (ListView) findViewById(R.id.theList);
theList.setAdapter(arrayAdapter);
theList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ListView theList = (ListView) findViewById(R.id.theList);
startActivity(new Intent(MainActivity.this, NowPlaying.class));
String selectedSong = (String) (theList.getItemAtPosition(position));
Intent toSecondActivity = new Intent(getApplicationContext(), NowPlaying.class);
toSecondActivity.putExtra("playSong", selectedSong);
startActivity(toSecondActivity);
}
});
}
}
Upvotes: 0
Views: 3470
Reputation: 134
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_now_playing);
.......
@Override
public void onDestroy(){
if(song.isplaying())
{
song.pause();
song.release();
}
super.onDestroy();
}
}
You are not destroying the instance of this activity and when you have paused the song it again starts with that activity only, so make sure that you destroy your instance for this activity.
Upvotes: 2
Reputation: 1
I am also facing the same issue.Songs are playing on top of each other. Finally I found the answer from a video.
https://www.youtube.com/watch?v=4DC4XFWVFls
//For Play Button OnClick Listener
public void onClick(View v) {
if(mediaPlayer !=null)
{
mediaPlayer.release();
}
mediaPlayer = MediaPlayer.create(context, songList.getSong());
mediaPlayer.start();
}
//For Stop Button
public void onClick(View v) {
mediaPlayer.stop();
}
This code worked properly for me.
Upvotes: 0
Reputation: 287
Well without the MainActivity class I can't be sure, but it doesn't appear that you are using the same instance of MediaPlayer in NowPlaying, so I can only assume you have created a new instance for both activities.
Which probably means the original instance is still active in the first Activity.
If so, you can either destroy the MainActivity instance of MediaPlayer before switching activities, or utilize the same instance across both activities.
I would recommend the second option, if you are only ever going to want to play one song at a time, makes sense you would, then have a look into Singleton classes. I believe this would work quite well in this situation.
http://www.javaworld.com/article/2073352/core-java/simply-singleton.html
EDIT:
Give this a go,
theList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String selectedSong = (String) (theList.getItemAtPosition(position));
Intent toSecondActivity = new Intent(MainActivity.this, NowPlaying.class);
toSecondActivity.putExtra("playSong", selectedSong);
startActivity(toSecondActivity);
}
});
and you will need to make theList final
Upvotes: 0