问题
I am new to Android programming and I am trying to make a simple Media Player app which extracts songs from the user's SD Card and enables the user to play the songs. The problem I face is that while a song is playing, if the user clicks on some other song, that song also starts playing.
I searched for the solution and used release() but the problem persists.
I would appreciate any help given!
Relevant code:
public class Player extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener, MediaPlayer.OnCompletionListener{
NotificationManager nm;
Notification n;
private Button play, forward, backward, next, prev, repeat, shuffle;
private ImageButton playlist;
private SeekBar sb;
private TextView songTitle, currDur, totDur;
private MediaPlayer mp;
private SongManager sManager;
private Utilities utils;
private Handler mHandler = new Handler();
private int seekForwardTime = 5000;
private int seekBackwardTime = 5000;
private boolean isShuffle = false;
private boolean isRepeat = false;
private ArrayList<HashMap<String,String>> songList = new ArrayList<HashMap<String, String>>();
int songIndex;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.player);
if(mp!=null)
{
mp.stop();
mp.release();
mp=null;
}
init_player();
songIndex = getIntent().getExtras().getInt("songIndex");
nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
n = new Notification(R.drawable.notif,"Alert",System.currentTimeMillis());
Intent j = new Intent(this, MainActivity.class);
j.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pp= PendingIntent.getActivity(Player.this, 0, j, PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Builder builder = new Notification.Builder(this);
builder.setAutoCancel(true);
builder.setContentIntent(pp);
builder.setTicker(songList.get(songIndex).get("songTitle"));
builder.setContentTitle("Playing");
builder.setContentText(songList.get(songIndex).get("songTitle"));
builder.setSmallIcon(R.drawable.notif);
builder.setOngoing(true);
builder.setNumber(100);
builder.build();
n = builder.getNotification();
nm.notify(0, n);
playSong(songIndex);
//Various Button Click Listeners
}
protected void init_player() {
play = (Button)findViewById(R.id.btnPlay);
forward = (Button) findViewById(R.id.btnForward);
backward = (Button) findViewById(R.id.btnBackward);
next = (Button) findViewById(R.id.btnNext);
prev = (Button) findViewById(R.id.btnPrevious);
repeat = (Button) findViewById(R.id.btnRepeat);
shuffle = (Button) findViewById(R.id.btnShuffle);
playlist = (ImageButton) findViewById(R.id.btn_playlist);
sb = (SeekBar) findViewById(R.id.songProgressBar);
songTitle = (TextView) findViewById(R.id.songName);
currDur = (TextView) findViewById(R.id.songCurrentDurationLabel);
totDur = (TextView) findViewById(R.id.songTotalDurationLabel);
mp = new MediaPlayer();
mp.setWakeMode(getApplicationContext(),
PowerManager.PARTIAL_WAKE_LOCK);
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
sManager = new SongManager(Player.this);
utils = new Utilities();
sb.setOnSeekBarChangeListener(this);
mp.setOnCompletionListener(this);
songList = sManager.getPlaylist(0);
}
protected void playSong(int songIndex)
{
try {
mp.reset();
mp.setDataSource(songList.get(songIndex).get("songPath"));
mp.prepare();
mp.start();
songTitle.setText(songList.get(songIndex).get("songTitle"));
play.setText("PAUSE");
sb.setProgress(0);
sb.setMax(100);
updateProgressBar();
} catch (IllegalArgumentException e){
e.printStackTrace();
} catch(IllegalStateException e){
e.printStackTrace();
} catch(IOException e){
e.printStackTrace();
}
}
Note : Player class gets called by the MainActivity and receives the integer songIndex (reresenting the index of song in the ArrayList)
回答1:
Try this in playSong() method
if (mp.isPlaying()) {
mp.stop();
mp.relase();
mp.prepare();
mp.start();
}
回答2:
Could it be that you have several media player instances at the same time? You should check that.
You have to release your media player inside the onStop() method of your activity like this:
@Override
protected void onStop() {
super.onStop(); // Always call the superclass method first
mediaPlayer.release();
mediaPlayer = null;
}
From the official documentation:
As an example, consider the problems that could happen if you forgot to release the MediaPlayer when your activity is stopped, but create a new one when the activity starts again.
As you may know, when the user changes the screen orientation (or changes the device configuration in another way), the system handles that by restarting the activity (by default),
so you might quickly consume all of the system resources as the user rotates the device back and forth between portrait and landscape,
because at each orientation change, you create a new MediaPlayer that you never release.
Having too many player instances at the same time, you will have errors like OutOfMemory or too many open files.
Btw. you should not use the constructor directly but instantiate the media player using the create() method as described here:
http://www.tutorialspoint.com/android/android_mediaplayer.htm
来源:https://stackoverflow.com/questions/38460317/more-than-1-song-playing-in-media-player-at-same-time