我设计了一个在线音乐播放器,该播放器从服务器流式传输文件并将其显示在recyclerView中。当我单击特定的歌曲时,它会自动播放,但是当我返回到recyclerview并再次选择它时,它不再播放,甚至歌曲持续时间也变得疯狂。我什至尝试使用onBackPressed()
方法或OnRestart()
或onResume()
方法处理媒体播放器。我很困惑。请让我知道任何建议。
这是我给玩家的代码:
public class PlayerActivity extends AppCompatActivity implements View.OnClickListener {
private CircularMusicProgressBar cover;
private ImageButton playPause, rewind, forward, repeat, fav, download;
private TextView title, term, spendingTime, totalTime, emptyRec;
private Context context;
public static MediaPlayer mediaPlayer;
int i;
private Timer timer;
private Bundle extra;
Uri uri;
RecyclerView recyclerView;
RequestQueue requestQueue;
SuggestionAdapter suggestionAdapter;
LinearLayoutManager layoutManager;
List<Listening> list = new ArrayList<>();
String url = "https://www.learnhere.ir/listening.php";
AccessDataOnServer suggestionData;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player);
initFields();
playOnStart();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.play_pause:
if (i == 1) {
i = 2;
playPause.setImageResource(R.drawable.ic_baseline_play);
mediaPlayer.pause();
} else {
i = 1;
playPause.setImageResource(R.drawable.ic_baseline_pause);
int b = mediaPlayer.getCurrentPosition();
mediaPlayer.seekTo(b);
mediaPlayer.start();
}
break;
case R.id.rewind:
Toast.makeText(context, "rewind", Toast.LENGTH_SHORT).show();
break;
case R.id.forward:
Toast.makeText(context, "forward", Toast.LENGTH_SHORT).show();
break;
case R.id.repeat:
Toast.makeText(context, "repeat", Toast.LENGTH_SHORT).show();
break;
case R.id.fav:
Toast.makeText(context, "fav", Toast.LENGTH_SHORT).show();
break;
case R.id.download:
Toast.makeText(context, "download", Toast.LENGTH_SHORT).show();
break;
}
}
public void initFields() {
i = 0;
context = this;
cover = findViewById(R.id.cover_progress);
playPause = findViewById(R.id.play_pause);
rewind = findViewById(R.id.rewind);
forward = findViewById(R.id.forward);
repeat = findViewById(R.id.repeat);
fav = findViewById(R.id.fav);
download = findViewById(R.id.download);
title = findViewById(R.id.title_tv);
term = findViewById(R.id.term_tv);
emptyRec = findViewById(R.id.empty_rec);
spendingTime = findViewById(R.id.spending_time);
totalTime = findViewById(R.id.total_time);
playPause.setOnClickListener(this);
rewind.setOnClickListener(this);
forward.setOnClickListener(this);
repeat.setOnClickListener(this);
fav.setOnClickListener(this);
download.setOnClickListener(this);
extra = getIntent().getExtras();
Picasso.get().load(extra.getString("cover")).into(cover);
title.setText(extra.getString("title"));
term.setText(extra.getString("term"));
timer = new Timer();
uri = Uri.parse(extra.getString("link"));
recyclerView = findViewById(R.id.suggestion_recycler);
requestQueue = Volley.newRequestQueue(context);
layoutManager = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false);
suggestionAdapter = new SuggestionAdapter(list, context);
suggestionData = new AccessDataOnServer();
recyclerView.setAdapter(suggestionAdapter);
recyclerView.setLayoutManager(layoutManager);
suggestionData.getSuggestion(context, list, recyclerView, url, requestQueue);
if (list.size() <= 1) {
emptyRec.setVisibility(View.VISIBLE);
recyclerView.setVisibility(View.GONE);
} else {
emptyRec.setVisibility(View.GONE);
recyclerView.setVisibility(View.VISIBLE);
}
}
public void play() {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioAttributes(
new AudioAttributes
.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build());
mediaPlayer.setDataSource(context, uri);
mediaPlayer.prepare();
mediaPlayer.start();
} catch (Exception e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
@Override
public void run() {
try {
getTime();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
});
thread.start();
}
public void playOnStart() {
Toast.makeText(context, "Please wait until the audio plays...", Toast.LENGTH_SHORT).show();
play();
i = 1;
playPause.setImageResource(R.drawable.ic_baseline_pause);
}
public String millisecondToSecond(long millisecond) {
String finalTimerString = "";
String secondString = "";
String minuteString = "";
//convert total duration into time
int hour = (int) (millisecond / (1000 * 60 * 60));
int minute = (int) (millisecond % (1000 * 60 * 60) / (1000 * 60));
int second = (int) (millisecond % (1000 * 60 * 60) % (1000 * 60) / 1000);
//Add hours if there
if (hour > 0) {
finalTimerString = hour + ":";
}
//Prepending 0 to second if it's one digit
if (second < 10) {
secondString = "0" + second;
} else {
secondString = "" + second;
}
//Prepending 0 to minute if it's one digit
if (minute < 10) {
minuteString = "0" + minute;
} else {
minuteString = "" + minute;
}
finalTimerString = finalTimerString + minuteString + ":" + secondString;
//Return timer string
return finalTimerString;
}
public void getTime() {
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
// Without runOnUiThread we don't have access to modifiers like text view
runOnUiThread(new Runnable() {
@Override
public void run() {
long current = mediaPlayer.getCurrentPosition();
int i = (mediaPlayer.getCurrentPosition() * 100) / mediaPlayer.getDuration();
spendingTime.setText("" + millisecondToSecond(current));
cover.setValue(i);
int duration = mediaPlayer.getDuration();
String time = String.format(Locale.US, "%02d:%02d",
TimeUnit.MILLISECONDS.toMinutes(duration),
TimeUnit.MILLISECONDS.toSeconds(duration) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration)));
totalTime.setText(time);
}
});
}
}, 0, 1000);
}
@Override
public void onBackPressed() {
mediaPlayer.stop();
finish();
}
@Override
protected void onRestart() {
super.onRestart();
playOnStart();
}
答案 0 :(得分:1)
好吧,我检查了您的代码,看来您没有正确使用Media Player类。 我对您的代码的每个部分进行了一些更改。我希望它能解决您的问题。
首先更改以下范围:
public static MediaPlayer mediaPlayer;
收件人
MediaPlayer mediaPlayer = new MediaPlayer();
我为您的mediaPlayer
创建了一种方法,您应该在onCreate()
中使用它:
private void prepareMediaPlayer() {
try {
mediaPlayer.setDataSource(context, uri);
mediaPlayer.prepare();
updateSeekBarTimer();
} catch (Exception e) {
e.printStackTrace();
}
}
一种更新您的seekbar
的方法:
private void updateSeekBarTimer() {
try {
if (mediaPlayer.isPlaying()) {
total_time = mediaPlayer.getDuration();
current_time = mediaPlayer.getCurrentPosition();
totalTime.setText("" + utils.milliSecondsToTimer(total_time));
spendingTime.setText("" + utils.milliSecondsToTimer(current_time));
int progress = (int) (utils.getProgressPercentage(current_time, total_time));
seekBar.setProgress(progress);
Runnable runnable = new Runnable() {
@Override
public void run() {
updateSeekBarTimer();
}
};
handler.postDelayed(runnable, 1000);
}
} catch (Exception e) {
e.printStackTrace();
}
}
最后,您需要一个接口来确定轨道结束时会发生什么:
public class PlayerActivity extends AppCompatActivity implements View.OnClickListener, MediaPlayer.OnCompletionListener
@Override
public void onCompletion(MediaPlayer mp) {
handler.removeCallbacks(null);
playPause.setImageResource(R.drawable.ic_baseline_play);
if (rep) {
mediaPlayer.start();
playPause.setImageResource(R.drawable.ic_baseline_pause);
updateSeekBarTimer();
} else {
seekBar.setProgress(0);
totalTime.setText(R.string.zero_time);
spendingTime.setText(R.string.zero_time);
playPause.setImageResource(R.drawable.ic_baseline_play);
mediaPlayer.reset();
prepareMediaPlayer();
}
}