gpt4 book ai didi

android - 从服务中将 PlayerView 与 SimpleExoPlayer 绑定(bind)

转载 作者:太空宇宙 更新时间:2023-11-03 13:40:48 25 4
gpt4 key购买 nike

我已经实现了一个服务来在后台运行完美运行的音频,但是我无法从服务中获取 SimpleExoPlayer 的实例来更新 UI,而且如果我退出,音频也会在后台播放两次并重新打开 Activity 。

音频播放服务

public class AudioPlayerService extends Service {

private final IBinder mBinder = new LocalBinder();
private SimpleExoPlayer player;
private Item item;
private PlayerNotificationManager playerNotificationManager;

@Override
public void onCreate() {
super.onCreate();
}

@Override
public void onDestroy() {
playerNotificationManager.setPlayer(null);
player.release();
player = null;
super.onDestroy();
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
enter code here
public SimpleExoPlayer getplayerInstance() {
return player;
}


@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Bundle b = intent.getBundleExtra(AppConstants.BUNDLE_KEY);
if (b != null) {
item = b.getParcelable(AppConstants.ITEM_KEY);
}
startPlayer();
return START_STICKY;
}

private void startPlayer() {
final Context context = this;
Uri uri = Uri.parse(item.getUrl());
player = ExoPlayerFactory.newSimpleInstance(context, new DefaultTrackSelector());
DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(context,
Util.getUserAgent(context, getString(R.string.app_name)));
MediaSource mediaSource = new ExtractorMediaSource.Factory(dataSourceFactory)
.createMediaSource(uri);
player.prepare(mediaSource);
player.setPlayWhenReady(true);
playerNotificationManager = PlayerNotificationManager.createWithNotificationChannel(context, AppConstants.PLAYBACK_CHANNEL_ID,
R.string.playback_channel_name,
AppConstants.PLAYBACK_NOTIFICATION_ID,
new PlayerNotificationManager.MediaDescriptionAdapter() {
@Override
public String getCurrentContentTitle(Player player) {
return item.getTitle();
}

@Nullable
@Override
public PendingIntent createCurrentContentIntent(Player player) {
Intent intent = new Intent(context, PlayerActivity.class);
Bundle serviceBundle = new Bundle();
serviceBundle.putParcelable(AppConstants.ITEM_KEY, item);
intent.putExtra(AppConstants.BUNDLE_KEY, serviceBundle);
return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}

@Nullable
@Override
public String getCurrentContentText(Player player) {
return item.getSummary();
}

@Nullable
@Override
public Bitmap getCurrentLargeIcon(Player player, PlayerNotificationManager.BitmapCallback callback) {
return item.getBitmap();
}
}
);
playerNotificationManager.setNotificationListener(new PlayerNotificationManager.NotificationListener() {
@Override
public void onNotificationStarted(int notificationId, Notification notification) {
startForeground(notificationId, notification);
}

@Override
public void onNotificationCancelled(int notificationId) {
stopSelf();
}
});
playerNotificationManager.setPlayer(player);
}

public class LocalBinder extends Binder {
public AudioPlayerService getService() {
return AudioPlayerService.this;
}
}
}

这是我启动服务并绑定(bind)到它的 Activity 。我必须传递 Item 对象才能运行服务,如果我不使用 Intent 传递数据,服务将崩溃,所以我不能在服务本身中执行 startService() 我必须在 Activity 中开始我猜。

播放器 Activity

public class PlayerActivity extends BaseActivity {

@BindView(R.id.video_view)
PlayerView mPlayerView;
@BindView(R.id.tvTitle)
TextView mTvTitle;
@BindView(R.id.tvSummary)
TextView mTvSummary;
@BindView(R.id.ivThumbnail)
ImageView mIvThumb;
private SimpleExoPlayer player;
private String mURL, mTitle, mSummary, mImage;
private AudioPlayerService mService;
private boolean mBound = false;
private Intent intent;

private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
AudioPlayerService.LocalBinder binder = (AudioPlayerService.LocalBinder) iBinder;
mService = binder.getService();
mBound = true;
}

@Override
public void onServiceDisconnected(ComponentName componentName) {


mBound = false;
}
};

@SuppressLint("MissingSuperCall")
@Override
protected void onCreate(Bundle savedInstanceState) {
onCreate(savedInstanceState, R.layout.activity_player);
Bundle b = getIntent().getBundleExtra(AppConstants.BUNDLE_KEY);
if (b != null) {
Item item = b.getParcelable(AppConstants.ITEM_KEY);
mURL = item.getUrl();
mImage = item.getImage();
mTitle = item.getTitle();
mSummary = item.getSummary();
intent = new Intent(this, AudioPlayerService.class);
Bundle serviceBundle = new Bundle();
serviceBundle.putParcelable(AppConstants.ITEM_KEY, item);
intent.putExtra(AppConstants.BUNDLE_KEY, serviceBundle);
Util.startForegroundService(this, intent);

}
}

private void initializePlayer() {
if (player == null && !mURL.isEmpty() && mBound) {
player = mService.getplayerInstance();
mPlayerView.setPlayer(player);
mPlayerView.setControllerHideOnTouch(false);
mPlayerView.setControllerShowTimeoutMs(10800000);
}
}

@Override
public void onStart() {
super.onStart();
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
initializePlayer();
setUI();
}

private void setUI() {
mTvTitle.setText(mTitle);
mTvSummary.setText(mSummary);
GlideApp.with(this)
.load(mImage)
.placeholder(R.color.colorPrimary)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(mIvThumb);
}

@Override
protected void onStop() {
unbindService(mConnection);
mBound = false;
releasePlayer();
super.onStop();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.player_menu, menu);
return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.share_podcast:
//Logic for Share
return true;
case R.id.download_podcast:
//Logic for download
return true;
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}

private void releasePlayer() {
if (player != null) {
player.release();
player = null;
}
}

@Override
public void onToolBarSetUp(Toolbar toolbar, ActionBar actionBar) {
TextView tvHeader = toolbar.findViewById(R.id.tvClassName);
tvHeader.setText(R.string.app_name);
actionBar.setHomeAsUpIndicator(R.drawable.ic_arrow_back_black_24dp);
}
}

我已经尝试了我所知道的一切,但因此我无法前进。

最佳答案

因此,经过大量研究后,我能够使用绑定(bind)服务并从该服务获取 SimpleExoPlayer 实例并使用以下方法将播放器 View 设置为始终显示来解决此问题。

mPlayerView.showController()

经过所有修改和设置后,只需要两个类就可以实现带有通知控件的后台音频播放,一个是activity,另一个是使用最新exoplayer版本的服务。

播放器 Activity

    public class PlayerActivity extends BaseActivity {

@BindView(R.id.video_view)
PlayerView mPlayerView;
@BindView(R.id.tvTitle)
TextView mTvTitle;
@BindView(R.id.tvSummary)
TextView mTvSummary;
@BindView(R.id.ivThumbnail)
ImageView mIvThumb;
private String mUrl, mTitle, mSummary, mImage;
private AudioPlayerService mService;
private Intent intent;
private String shareableLink;
private boolean mBound = false;

private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
AudioPlayerService.LocalBinder binder = (AudioPlayerService.LocalBinder) iBinder;
mService = binder.getService();
mBound = true;
initializePlayer();
}

@Override
public void onServiceDisconnected(ComponentName componentName) {
mBound = false;
}
};

@SuppressLint("MissingSuperCall")
@Override
protected void onCreate(Bundle savedInstanceState) {
onCreate(savedInstanceState, R.layout.activity_player);
Bundle b = getIntent().getBundleExtra(AppConstants.BUNDLE_KEY);
if (b != null) {
Item item = b.getParcelable(AppConstants.ITEM_KEY);
shareableLink = b.getString(AppConstants.SHARE_KEY);
mImage = item.getImage();
mUrl = item.getUrl();
mTitle = item.getTitle();
mSummary = item.getSummary();
intent = new Intent(this, AudioPlayerService.class);
Bundle serviceBundle = new Bundle();
serviceBundle.putParcelable(AppConstants.ITEM_KEY, item);
intent.putExtra(AppConstants.BUNDLE_KEY, serviceBundle);
Util.startForegroundService(this, intent);
mPlayerView.setUseController(true);
mPlayerView.showController();
mPlayerView.setControllerAutoShow(true);
mPlayerView.setControllerHideOnTouch(false);
}
}

private void initializePlayer() {
if (mBound) {
SimpleExoPlayer player = mService.getplayerInstance();
mPlayerView.setPlayer(player);
}
}

@Override
public void onStart() {
super.onStart();
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
initializePlayer();
setUI();
}

private void setUI() {
mTvTitle.setText(mTitle);
mTvSummary.setText(mSummary);
GlideApp.with(this)
.load(mImage)
.placeholder(R.color.colorPrimary)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(mIvThumb);
}

@Override
protected void onStop() {
unbindService(mConnection);
mBound = false;
super.onStop();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.player_menu, menu);
return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.share_podcast:
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_SUBJECT, mTitle);
shareIntent.putExtra(Intent.EXTRA_TEXT, mTitle + "\n\n" + shareableLink);
shareIntent.setType("text/plain");
startActivity(Intent.createChooser(shareIntent, getString(R.string.share_text)));
return true;
case R.id.download_podcast:
Uri uri = Uri.parse(mUrl);
ProgressiveDownloadAction progressiveDownloadAction
= new ProgressiveDownloadAction(uri, false, null, null);
AudioDownloadService.startWithAction(PlayerActivity.this, AudioDownloadService.class,
progressiveDownloadAction, false);
return true;
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}

@Override
public void onToolBarSetUp(Toolbar toolbar, ActionBar actionBar) {
TextView tvHeader = toolbar.findViewById(R.id.tvClassName);
tvHeader.setText(R.string.app_name);
actionBar.setHomeAsUpIndicator(R.drawable.ic_arrow_back_black_24dp);
}
}

音频播放服务

    public class AudioPlayerService extends Service {

private final IBinder mBinder = new LocalBinder();
private SimpleExoPlayer player;
private Item item;
private PlayerNotificationManager playerNotificationManager;

@Override
public void onCreate() {
super.onCreate();
}

@Override
public void onDestroy() {
releasePlayer();
super.onDestroy();
}

private void releasePlayer() {
if (player != null) {
playerNotificationManager.setPlayer(null);
player.release();
player = null;
}
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}

public SimpleExoPlayer getplayerInstance() {
if (player == null) {
startPlayer();
}
return player;
}


@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//releasePlayer();
Bundle b = intent.getBundleExtra(AppConstants.BUNDLE_KEY);
if (b != null) {
item = b.getParcelable(AppConstants.ITEM_KEY);
}
if (player == null) {
startPlayer();
}
return START_STICKY;
}

private void startPlayer() {
final Context context = this;
Uri uri = Uri.parse(item.getUrl());
player = ExoPlayerFactory.newSimpleInstance(context, new DefaultTrackSelector());
DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(context,
Util.getUserAgent(context, getString(R.string.app_name)));
CacheDataSourceFactory cacheDataSourceFactory = new CacheDataSourceFactory(
DownloadUtil.getCache(context),
dataSourceFactory,
CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR);
MediaSource mediaSource = new ExtractorMediaSource.Factory(cacheDataSourceFactory)
.createMediaSource(uri);
player.prepare(mediaSource);
player.setPlayWhenReady(true);
playerNotificationManager = PlayerNotificationManager.createWithNotificationChannel(context, AppConstants.PLAYBACK_CHANNEL_ID,
R.string.playback_channel_name,
AppConstants.PLAYBACK_NOTIFICATION_ID,
new PlayerNotificationManager.MediaDescriptionAdapter() {
@Override
public String getCurrentContentTitle(Player player) {
return item.getTitle();
}

@Nullable
@Override
public PendingIntent createCurrentContentIntent(Player player) {
Intent intent = new Intent(context, PlayerActivity.class);
Bundle serviceBundle = new Bundle();
serviceBundle.putParcelable(AppConstants.ITEM_KEY, item);
intent.putExtra(AppConstants.BUNDLE_KEY, serviceBundle);
return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}

@Nullable
@Override
public String getCurrentContentText(Player player) {
return item.getSummary();
}

@Nullable
@Override
public Bitmap getCurrentLargeIcon(Player player, PlayerNotificationManager.BitmapCallback callback) {
return null;
}
}
);
playerNotificationManager.setNotificationListener(new PlayerNotificationManager.NotificationListener() {
@Override
public void onNotificationStarted(int notificationId, Notification notification) {
startForeground(notificationId, notification);
}

@Override
public void onNotificationCancelled(int notificationId) {
stopSelf();
}
});
playerNotificationManager.setPlayer(player);
}

public class LocalBinder extends Binder {
public AudioPlayerService getService() {
return AudioPlayerService.this;
}
}
}

关于android - 从服务中将 PlayerView 与 SimpleExoPlayer 绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52473974/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com