use of android.support.v4.media.session.PlaybackStateCompat in project AndroidAudioExample by SergeyVinyar.
the class MainActivity method onCreate.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button playButton = (Button) findViewById(R.id.play);
final Button pauseButton = (Button) findViewById(R.id.pause);
final Button stopButton = (Button) findViewById(R.id.stop);
final Button skipToNextButton = (Button) findViewById(R.id.skip_to_next);
final Button skipToPreviousButton = (Button) findViewById(R.id.skip_to_previous);
callback = new MediaControllerCompat.Callback() {
@Override
public void onPlaybackStateChanged(PlaybackStateCompat state) {
if (state == null)
return;
boolean playing = state.getState() == PlaybackStateCompat.STATE_PLAYING;
playButton.setEnabled(!playing);
pauseButton.setEnabled(playing);
stopButton.setEnabled(playing);
}
};
serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
playerServiceBinder = (PlayerService.PlayerServiceBinder) service;
try {
mediaController = new MediaControllerCompat(MainActivity.this, playerServiceBinder.getMediaSessionToken());
mediaController.registerCallback(callback);
callback.onPlaybackStateChanged(mediaController.getPlaybackState());
} catch (RemoteException e) {
mediaController = null;
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
playerServiceBinder = null;
if (mediaController != null) {
mediaController.unregisterCallback(callback);
mediaController = null;
}
}
};
bindService(new Intent(this, PlayerService.class), serviceConnection, BIND_AUTO_CREATE);
playButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mediaController != null)
mediaController.getTransportControls().play();
}
});
pauseButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mediaController != null)
mediaController.getTransportControls().pause();
}
});
stopButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mediaController != null)
mediaController.getTransportControls().stop();
}
});
skipToNextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mediaController != null)
mediaController.getTransportControls().skipToNext();
}
});
skipToPreviousButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mediaController != null)
mediaController.getTransportControls().skipToPrevious();
}
});
}
use of android.support.v4.media.session.PlaybackStateCompat in project AntennaPod by AntennaPod.
the class CustomMRControllerDialog method onCreateMediaControlView.
@Override
public View onCreateMediaControlView(Bundle savedInstanceState) {
boolean landscape = getContext().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
if (landscape) {
/*
* When a horizontal LinearLayout measures itself, it first measures its children and
* settles their widths on the first pass, and only then figures out its height, never
* revisiting the widths measurements.
* When one has a child view that imposes a certain aspect ratio (such as an ImageView),
* then its width and height are related to each other, and so if one allows for a large
* height, then it will request for itself a large width as well. However, on the first
* child measurement, the LinearLayout imposes a very relaxed height bound, that the
* child uses to tell the width it wants, a value which the LinearLayout will interpret
* as final, even though the child will want to change it once a more restrictive height
* bound is imposed later.
*
* Our solution is, given that the heights of the children do not depend on their widths
* in this case, we first figure out the layout's height and only then perform the
* usual sequence of measurements.
*
* Note: this solution does not take into account any vertical paddings nor children's
* vertical margins in determining the height, as this View as well as its children are
* defined in code and no paddings/margins that would influence these computations are
* introduced.
*
* There were no resources online for this type of issue as far as I could gather.
*/
rootView = new LinearLayout(getContext()) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// We'd like to find the overall height before adjusting the widths within the LinearLayout
int maxHeight = Integer.MIN_VALUE;
if (MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY) {
for (int i = 0; i < getChildCount(); i++) {
int height = Integer.MIN_VALUE;
View child = getChildAt(i);
ViewGroup.LayoutParams lp = child.getLayoutParams();
// we only measure children whose layout_height is not MATCH_PARENT
if (lp.height >= 0) {
height = lp.height;
} else if (lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
child.measure(widthMeasureSpec, heightMeasureSpec);
height = child.getMeasuredHeight();
}
maxHeight = Math.max(maxHeight, height);
}
}
if (maxHeight > 0) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.EXACTLY));
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
};
rootView.setOrientation(LinearLayout.HORIZONTAL);
} else {
rootView = new LinearLayout(getContext());
rootView.setOrientation(LinearLayout.VERTICAL);
}
FrameLayout.LayoutParams rootParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
rootParams.setMargins(0, 0, 0, getContext().getResources().getDimensionPixelSize(R.dimen.media_router_controller_bottom_margin));
rootView.setLayoutParams(rootParams);
// Start the session activity when a content item (album art, title or subtitle) is clicked.
View.OnClickListener onClickListener = v -> {
if (mediaController != null) {
PendingIntent pi = mediaController.getSessionActivity();
if (pi != null) {
try {
pi.send();
dismiss();
} catch (PendingIntent.CanceledException e) {
Log.e(TAG, pi + " was not sent, it had been canceled.");
}
}
}
};
LinearLayout.LayoutParams artParams;
/*
* On portrait orientation, we want to limit the artView's height to 9/16 of the available
* width. Reason is that we need to choose the height wisely otherwise we risk the dialog
* being much larger than the screen, and there doesn't seem to be a good way to know the
* available height beforehand.
*
* On landscape orientation, we want to limit the artView's width to its available height.
* Otherwise, horizontal images would take too much space and severely restrict the space
* for episode title and play/pause button.
*
* Internal implementation of ImageView only uses the source image's aspect ratio, but we
* want to impose our own and fallback to the source image's when it is more favorable.
* Solutions were inspired, among other similar sources, on
* http://stackoverflow.com/questions/18077325/scale-image-to-fill-imageview-width-and-keep-aspect-ratio
*/
if (landscape) {
artView = new ImageView(getContext()) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int desiredWidth = widthMeasureSpec;
int desiredMeasureMode = MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY ? MeasureSpec.EXACTLY : MeasureSpec.AT_MOST;
if (MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.EXACTLY) {
Drawable drawable = getDrawable();
if (drawable != null) {
int intrHeight = drawable.getIntrinsicHeight();
int intrWidth = drawable.getIntrinsicWidth();
int originalHeight = MeasureSpec.getSize(heightMeasureSpec);
if (intrHeight < intrWidth) {
desiredWidth = MeasureSpec.makeMeasureSpec(originalHeight, desiredMeasureMode);
} else {
desiredWidth = MeasureSpec.makeMeasureSpec(Math.round((float) originalHeight * intrWidth / intrHeight), desiredMeasureMode);
}
}
}
super.onMeasure(desiredWidth, heightMeasureSpec);
}
};
artParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
MarginLayoutParamsCompat.setMarginStart(artParams, getContext().getResources().getDimensionPixelSize(R.dimen.media_router_controller_playback_control_horizontal_spacing));
} else {
artView = new ImageView(getContext()) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int desiredHeight = heightMeasureSpec;
if (MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY) {
Drawable drawable = getDrawable();
if (drawable != null) {
int originalWidth = MeasureSpec.getSize(widthMeasureSpec);
int intrHeight = drawable.getIntrinsicHeight();
int intrWidth = drawable.getIntrinsicWidth();
float scale;
if (intrHeight * 16 > intrWidth * 9) {
// image is taller than 16:9
scale = (float) originalWidth * 9 / 16 / intrHeight;
} else {
// image is more horizontal than 16:9
scale = (float) originalWidth / intrWidth;
}
desiredHeight = MeasureSpec.makeMeasureSpec(Math.round(intrHeight * scale), MeasureSpec.EXACTLY);
}
}
super.onMeasure(widthMeasureSpec, desiredHeight);
}
};
artParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
// When we fetch the bitmap, we want to know if we should set a background color or not.
artView.setTag(landscape);
artView.setScaleType(ImageView.ScaleType.FIT_CENTER);
artView.setOnClickListener(onClickListener);
artView.setLayoutParams(artParams);
rootView.addView(artView);
ViewGroup wrapper = rootView;
if (landscape) {
// Here we wrap with a frame layout because we want to set different layout parameters
// for landscape orientation.
wrapper = new FrameLayout(getContext());
wrapper.setLayoutParams(new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1f));
rootView.addView(wrapper);
rootView.setWeightSum(1f);
}
View playbackControlLayout = View.inflate(getContext(), R.layout.media_router_controller, wrapper);
titleView = (TextView) playbackControlLayout.findViewById(R.id.mrc_control_title);
subtitleView = (TextView) playbackControlLayout.findViewById(R.id.mrc_control_subtitle);
playbackControlLayout.findViewById(R.id.mrc_control_title_container).setOnClickListener(onClickListener);
playPauseButton = (ImageButton) playbackControlLayout.findViewById(R.id.mrc_control_play_pause);
playPauseButton.setOnClickListener(v -> {
PlaybackStateCompat state;
if (mediaController != null && (state = mediaController.getPlaybackState()) != null) {
boolean isPlaying = state.getState() == PlaybackStateCompat.STATE_PLAYING;
if (isPlaying) {
mediaController.getTransportControls().pause();
} else {
mediaController.getTransportControls().play();
}
AccessibilityManager accessibilityManager = (AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
if (accessibilityManager != null && accessibilityManager.isEnabled()) {
AccessibilityEvent event = AccessibilityEvent.obtain(AccessibilityEventCompat.TYPE_ANNOUNCEMENT);
event.setPackageName(getContext().getPackageName());
event.setClassName(getClass().getName());
int resId = isPlaying ? android.support.v7.mediarouter.R.string.mr_controller_pause : android.support.v7.mediarouter.R.string.mr_controller_play;
event.getText().add(getContext().getString(resId));
accessibilityManager.sendAccessibilityEvent(event);
}
}
});
viewsCreated = true;
updateViews();
return rootView;
}
use of android.support.v4.media.session.PlaybackStateCompat in project android-UniversalMusicPlayer by googlesamples.
the class FullScreenPlayerActivity method connectToSession.
private void connectToSession(MediaSessionCompat.Token token) throws RemoteException {
MediaControllerCompat mediaController = new MediaControllerCompat(FullScreenPlayerActivity.this, token);
if (mediaController.getMetadata() == null) {
finish();
return;
}
MediaControllerCompat.setMediaController(FullScreenPlayerActivity.this, mediaController);
mediaController.registerCallback(mCallback);
PlaybackStateCompat state = mediaController.getPlaybackState();
updatePlaybackState(state);
MediaMetadataCompat metadata = mediaController.getMetadata();
if (metadata != null) {
updateMediaDescription(metadata.getDescription());
updateDuration(metadata);
}
updateProgress();
if (state != null && (state.getState() == PlaybackStateCompat.STATE_PLAYING || state.getState() == PlaybackStateCompat.STATE_BUFFERING)) {
scheduleSeekbarUpdate();
}
}
use of android.support.v4.media.session.PlaybackStateCompat in project android-UniversalMusicPlayer by googlesamples.
the class FullScreenPlayerActivity method updatePlaybackState.
private void updatePlaybackState(PlaybackStateCompat state) {
if (state == null) {
return;
}
mLastPlaybackState = state;
MediaControllerCompat controllerCompat = MediaControllerCompat.getMediaController(FullScreenPlayerActivity.this);
if (controllerCompat != null && controllerCompat.getExtras() != null) {
String castName = controllerCompat.getExtras().getString(MusicService.EXTRA_CONNECTED_CAST);
String line3Text = castName == null ? "" : getResources().getString(R.string.casting_to_device, castName);
mLine3.setText(line3Text);
}
switch(state.getState()) {
case PlaybackStateCompat.STATE_PLAYING:
mLoading.setVisibility(INVISIBLE);
mPlayPause.setVisibility(VISIBLE);
mPlayPause.setImageDrawable(mPauseDrawable);
mControllers.setVisibility(VISIBLE);
scheduleSeekbarUpdate();
break;
case PlaybackStateCompat.STATE_PAUSED:
mControllers.setVisibility(VISIBLE);
mLoading.setVisibility(INVISIBLE);
mPlayPause.setVisibility(VISIBLE);
mPlayPause.setImageDrawable(mPlayDrawable);
stopSeekbarUpdate();
break;
case PlaybackStateCompat.STATE_NONE:
case PlaybackStateCompat.STATE_STOPPED:
mLoading.setVisibility(INVISIBLE);
mPlayPause.setVisibility(VISIBLE);
mPlayPause.setImageDrawable(mPlayDrawable);
stopSeekbarUpdate();
break;
case PlaybackStateCompat.STATE_BUFFERING:
mPlayPause.setVisibility(INVISIBLE);
mLoading.setVisibility(VISIBLE);
mLine3.setText(R.string.loading);
stopSeekbarUpdate();
break;
default:
LogHelper.d(TAG, "Unhandled state ", state.getState());
}
mSkipNext.setVisibility((state.getActions() & PlaybackStateCompat.ACTION_SKIP_TO_NEXT) == 0 ? INVISIBLE : VISIBLE);
mSkipPrev.setVisibility((state.getActions() & PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS) == 0 ? INVISIBLE : VISIBLE);
}
use of android.support.v4.media.session.PlaybackStateCompat in project react-native-track-player by react-native-kit.
the class Metadata method updatePlayback.
@SuppressWarnings("WrongConstant")
public void updatePlayback(Playback playback) {
// Reset the playback state when there's no playback attached
if (playback == null) {
pb = new PlaybackStateCompat.Builder();
PlaybackStateCompat state = pb.build();
session.setPlaybackToLocal(AudioManager.STREAM_MUSIC);
session.setPlaybackState(state);
notification.updatePlayback(state);
noisyReceiver.setEnabled(false);
volume = null;
return;
}
int playerState = playback.getState();
// Update the state, position, speed and buffered position
pb.setState(playerState, playback.getPosition(), playback.getSpeed());
pb.setBufferedPosition(playback.getBufferedPosition());
// Update the capabilities
pb.setActions(capabilities);
if (playback.isRemote()) {
// Set the volume control to remote
if (volume == null) {
volume = new CustomVolume(playback, playback.getVolume(), 100, true);
} else {
volume.setVolume(playback.getVolume());
}
session.setPlaybackToRemote(volume);
} else {
// Set the volume control to local
session.setPlaybackToLocal(AudioManager.STREAM_MUSIC);
volume = null;
}
// Update the playback state to the MediaSession and the notification
PlaybackStateCompat state = pb.build();
session.setPlaybackState(state);
notification.updatePlayback(state);
// Update the noisy listener to start receiving when it's playing
noisyReceiver.setEnabled(Utils.isPlaying(playerState));
}
Aggregations