因此,我有下面的代码,它是正常工作,但我想显示在用户通知区域的媒体控件,以便他们可以播放和停止音乐,因为他们喜欢,而应用程序在后台。
我想知道一个人是怎么做到的?
代码:
package com.radiomedia.a1liferadio;
import androidx.appcompat.app.AppCompatActivity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private ImageView imagePlayPause;
private TextView textCurrentTime, textTotalDuration;
private SeekBar playerSeekBar;
private MediaPlayer mediaPlayer;
private Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imagePlayPause = findViewById(R.id.imagePlayPause);
textCurrentTime = findViewById(R.id.textCurrentTime);
textTotalDuration = findViewById(R.id.textTotalDuration);
playerSeekBar = findViewById(R.id.playerSeekBar);
mediaPlayer = new MediaPlayer();
playerSeekBar.setMax(100);
imagePlayPause.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(mediaPlayer.isPlaying())
{
handler.removeCallbacks(updater);
mediaPlayer.pause();
imagePlayPause.setImageResource(R.drawable.ic_play);
}else{
mediaPlayer.start();
imagePlayPause.setImageResource(R.drawable.ic_pause);
updateSeekBar();
}
}
});
prepareMediaPlayer();
}
private void prepareMediaPlayer() {
try {
mediaPlayer.setDataSource("http://stream.radiomedia.com.au:8003/stream"); //url of media
mediaPlayer.prepare();
textTotalDuration.setText(milliSecondsToTimer(mediaPlayer.getDuration()));
} catch (Exception exception){
Toast.makeText(this,exception.getMessage(), Toast.LENGTH_SHORT).show();
}
};
private Runnable updater = new Runnable() {
@Override
public void run() {
updateSeekBar();
long currentDuration = mediaPlayer.getCurrentPosition();
textCurrentTime.setText(milliSecondsToTimer(currentDuration));
}
};
private void updateSeekBar(){
if(mediaPlayer.isPlaying()) {
playerSeekBar.setProgress((int) (((float) mediaPlayer.getCurrentPosition() / mediaPlayer.getDuration()) * 100));
handler.postDelayed(updater, 1000);
}
};
private String milliSecondsToTimer(long milliSeconds) {
String timerString = "";
String secondsString;
int hours = (int)(milliSeconds / (1000 * 60 * 60));
int minutes = (int)(milliSeconds % (1000 * 60 * 60)) / (1000 *60);
int seconds = (int)((milliSeconds % (1000 * 60 *60)) % (1000 * 60) / 1000);
if(hours > 0)
{
timerString = hours + ":";
}
if(seconds < 10)
{
secondsString = "0" + seconds;
}else{
secondsString = "" + seconds;
}
timerString = timerString + minutes + ":" + secondsString;
return timerString;
}
}
2条答案
按热度按时间vsaztqbk1#
有两种情况:
第一
如果你想在后台播放歌曲,你应该启动一个forground服务。forground服务带有通知(将seekbar位置、播放暂停状态、播放列表或视频url传递给服务)。
使用媒体控件创建自定义通知后
您必须将媒体播放器添加到服务中,并将您的参数(如位置、播放暂停状态)传递给服务播放器,使其从以前的活动播放器状态播放。
在单击通知时,必须将相同的参数传递给活动。
第二
通过附加一个播放器启动forground服务,并将活动绑定到它,同时处理来自通知和活动的所有控件。
您可以将播放器控件传递给通知服务,以便在后台启动和播放歌曲。
在第一种情况下,您可以使用preference或tinydb来获得要传递的参数的最佳性能。
bvhaajcl2#
如果您想继续使用mediaplayer,您应该遵循这个旧的googlemediaplayer示例(如果主版本崩溃,请使用这个commit)。
但是如果您不介意使用exoplayer,那么您应该使用这个新的,因为exoplayer已经可以处理部分通知内容了。
但在这些示例项目中,您可以看到:
它不仅仅是一个简单的通知,它还与人们按下耳机上的播放按钮等联系在一起。
为此,您确实需要一个服务,绑定到通知,处理action.media\u按钮意图。
使用mediaplayer(而不是exoplayer)在mediasession和服务中添加此类通知的最低代码如下所示:将media compat库添加到应用程序的内部版本:
然后创建用于创建通知的类:
然后创建一个处理回放的服务类,并按下通知按钮:
更新您的清单以声明服务并向其发送action.media\u按钮。
上面的mediabuttonreceiver对于pre-oreo设备是必需的,它将事件转发到这些平台上的服务。
然后从你的主要活动开始服务。
这里仍然要做的事情是让您的主要活动以某种方式向您的服务或服务中的播放器发送操作,在更改时更新通知和服务状态,但是您应该能够使用此代码获得一些有用的信息,并从google示例代码中找出其余部分。