如果我们打开我们的应用程序,就会加载新闻片段并且新闻会自动开始播放。我们正在使用 Exoplayer 播放新闻。通知由 Exoplayer 通过 PlayerNotificationManager 创建。问题是播放暂停按钮不跟随通知。我们已经实现了事件总线,它只改变了可绘制对象。因此,如果我们单击通知上的暂停按钮,片段上的按钮被视为已暂停,但当我们单击它时,它会用作暂停按钮(而不是用作播放按钮)。
我们打算做的是:如果通知说暂停,片段上的按钮将被暂停,然后如果我们点击它,内容将开始播放。
代码:
NewsReaderFragment.java
public static NewsReaderFragment newInstance() {
return new NewsReaderFragment();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_news_reader, container, false);
bPlay = rootView.findViewById(R.id.button_play);
unbinder = ButterKnife.bind(this, rootView);
NetworkInfoUtility networkInfoUtility = new NetworkInfoUtility();
boolean net = networkInfoUtility.isNetWorkAvailableNow(getContext());
if (!net) {
Toast.makeText(getContext(), CHECKNET, Toast.LENGTH_LONG).show();
}
exoHelper = new ExoHelper(getContext(), new Player.EventListener() {
@Override
public void onPlayerError(ExoPlaybackException error) {
Crashlytics.logException(error);
Toast.makeText(getContext(), rootView.getContext().getString(R.string.server_off), Toast.LENGTH_LONG).show();
exoHelper.ToggleButton(false);
}
}, bPlay, "NewsReader");
isPlaying = true;
setButton();
exoHelper.startExo(rootView.getContext().getString(R.string.bbc_news));
return rootView;
}
private void setButton() {
bPlay.setOnClickListener(view -> {
if (!isPlaying) {
exoHelper.startExo(rootView.getContext().getString(R.string.bbc_news));
} else {
exoHelper.stopExo();
}
isPlaying = !isPlaying;
});
}
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(ButtonEvent event)
{
exoHelper.ToggleButton(event.isState());
}
Exophelper.java
public void stopExo() {
if (exoPlayer != null) { //if exo is running
Log.d(TAG, "Stopping exo....");
exoPlayer.stop();
//playerNotificationManager.setPlayer(null);
customPlayerNotificationManager.setPlayer(null);
exoPlayer.release();
exoPlayer = null;
ToggleButton(false);
} else {
Log.d(TAG, "Can't stop because No exoplayer is running");
}
}
public void startExo(String newUrl) {
if (newUrl == null || newUrl.isEmpty()) {
Log.d(TAG, "startExo: empty url");
Toast.makeText(context, R.string.server_off, Toast.LENGTH_SHORT).show();
ToggleButton(false); // show pause button
return;
}
if (exoPlayer != null) {
Log.d(TAG, "startExo: Exo is already running now");
return;
}
iceURL = newUrl;
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
final ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
TrackSelection.Factory trackSelectionFactory =
new AdaptiveTrackSelection.Factory(bandwidthMeter);
TrackSelector defaultTrackSelector =
new DefaultTrackSelector(trackSelectionFactory);
DefaultBandwidthMeter defaultBandwidthMeter = new DefaultBandwidthMeter();
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(
context,
Util.getUserAgent(context, context.getApplicationInfo().name),
defaultBandwidthMeter);
MediaSource mediaSource = new ExtractorMediaSource(
Uri.parse(iceURL),
dataSourceFactory,
extractorsFactory,
new Handler(), error -> {
});
exoPlayer = ExoPlayerFactory.newSimpleInstance(context, defaultTrackSelector);
if (eventListener != null) {
exoPlayer.addListener(eventListener);
}
exoPlayer.prepare(mediaSource);
exoPlayer.setPlayWhenReady(true);
//EventStatus(true);
ToggleButton(true);
//setPlayerNotificationManager(exoPlayer);
createCustomPlayerNotificationManger(exoPlayer);
}
public void ToggleButton(boolean state) {
if (state) {
Drawable img = button.getContext().getResources().getDrawable(R.drawable.play_button);
button.setCompoundDrawablesWithIntrinsicBounds(img, null, null, null);
button.setText(R.string.now_playing);
} else {
Drawable img1 = button.getContext().getResources().getDrawable(R.drawable.pause_button);
button.setCompoundDrawablesWithIntrinsicBounds(img1, null, null, null);
button.setText(R.string.server_off);
}
}
PlayerNotificationManager.java
这是一个大文件,所以我们只附加我们使用事件总线的接收器:
public class NotificationBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Player player = PlayerNotificationManager.this.player;
if (player == null
|| !isNotificationStarted
|| intent.getIntExtra(EXTRA_INSTANCE_ID, instanceId) != instanceId) {
return;
}
String action = intent.getAction();
if (ACTION_PLAY.equals(action)) {
if (player.getPlaybackState() == Player.STATE_IDLE) {
if (playbackPreparer != null) {
playbackPreparer.preparePlayback();
}
} else if (player.getPlaybackState() == Player.STATE_ENDED) {
controlDispatcher.dispatchSeekTo(player, player.getCurrentWindowIndex(), C.TIME_UNSET);
}
controlDispatcher.dispatchSetPlayWhenReady(player, /* playWhenReady= */ true);
EventBus.getDefault().post(new ButtonEvent(true));
Log.d(TAG, "ButtonEvent: True");
} else if (ACTION_PAUSE.equals(action)) {
controlDispatcher.dispatchSetPlayWhenReady(player, /* playWhenReady= */ false);
if (player.getPlaybackState() == Player.STATE_READY)
{
EventBus.getDefault().post(new ButtonEvent(false));
Log.d(TAG, "ButtonEvent: False");
}
} else if (ACTION_STOP.equals(action)) {
controlDispatcher.dispatchStop(player, /* reset= */ true);
} else if (ACTION_DISMISS.equals(action)) {
stopNotification(/* dismissedByUser= */ true);
} else if (action != null
&& customActionReceiver != null
&& customActions.containsKey(action)) {
customActionReceiver.onCustomAction(player, action, intent);
}
}
}
按钮事件.java
public class ButtonEvent {
public boolean state;
public ButtonEvent(boolean state) {
this.state = state;
}
public boolean isState() {
return state;
}
public void setState(boolean state) {
this.state = state;
}
}