diff options
5 files changed, 359 insertions, 343 deletions
diff --git a/media/MediaBrowserService/Application/src/main/java/com/example/android/mediasession/client/MediaBrowserAdapter.java b/media/MediaBrowserService/Application/src/main/java/com/example/android/mediasession/client/MediaBrowserAdapter.java deleted file mode 100644 index d2f0b7f5..00000000 --- a/media/MediaBrowserService/Application/src/main/java/com/example/android/mediasession/client/MediaBrowserAdapter.java +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.example.android.mediasession.client; - -import android.content.ComponentName; -import android.content.Context; -import android.os.RemoteException; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.v4.media.MediaBrowserCompat; -import android.support.v4.media.MediaMetadataCompat; -import android.support.v4.media.session.MediaControllerCompat; -import android.support.v4.media.session.MediaSessionCompat; -import android.support.v4.media.session.PlaybackStateCompat; -import android.util.Log; - -import com.example.android.mediasession.service.MusicService; - -import java.util.ArrayList; -import java.util.List; - -/** - * Adapter for a MediaBrowser that handles connecting, disconnecting, - * and basic browsing. - */ -public class MediaBrowserAdapter { - - private static final String TAG = MediaBrowserAdapter.class.getSimpleName(); - - /** - * Helper class for easily subscribing to changes in a MediaBrowserService connection. - */ - public static abstract class MediaBrowserChangeListener { - - public void onConnected(@Nullable MediaControllerCompat mediaController) { - } - - public void onMetadataChanged(@Nullable MediaMetadataCompat mediaMetadata) { - } - - public void onPlaybackStateChanged(@Nullable PlaybackStateCompat playbackState) { - } - } - - private final InternalState mState; - - private final Context mContext; - private final List<MediaBrowserChangeListener> mListeners = new ArrayList<>(); - - private final MediaBrowserConnectionCallback mMediaBrowserConnectionCallback = - new MediaBrowserConnectionCallback(); - private final MediaControllerCallback mMediaControllerCallback = - new MediaControllerCallback(); - private final MediaBrowserSubscriptionCallback mMediaBrowserSubscriptionCallback = - new MediaBrowserSubscriptionCallback(); - - private MediaBrowserCompat mMediaBrowser; - - @Nullable - private MediaControllerCompat mMediaController; - - public MediaBrowserAdapter(Context context) { - mContext = context; - mState = new InternalState(); - } - - public void onStart() { - if (mMediaBrowser == null) { - mMediaBrowser = - new MediaBrowserCompat( - mContext, - new ComponentName(mContext, MusicService.class), - mMediaBrowserConnectionCallback, - null); - mMediaBrowser.connect(); - } - Log.d(TAG, "onStart: Creating MediaBrowser, and connecting"); - } - - public void onStop() { - if (mMediaController != null) { - mMediaController.unregisterCallback(mMediaControllerCallback); - mMediaController = null; - } - if (mMediaBrowser != null && mMediaBrowser.isConnected()) { - mMediaBrowser.disconnect(); - mMediaBrowser = null; - } - resetState(); - Log.d(TAG, "onStop: Releasing MediaController, Disconnecting from MediaBrowser"); - } - - /** - * The internal state of the app needs to revert to what it looks like when it started before - * any connections to the {@link MusicService} happens via the {@link MediaSessionCompat}. - */ - private void resetState() { - mState.reset(); - performOnAllListeners(new ListenerCommand() { - @Override - public void perform(@NonNull MediaBrowserChangeListener listener) { - listener.onPlaybackStateChanged(null); - } - }); - Log.d(TAG, "resetState: "); - } - - public MediaControllerCompat.TransportControls getTransportControls() { - if (mMediaController == null) { - Log.d(TAG, "getTransportControls: MediaController is null!"); - throw new IllegalStateException(); - } - return mMediaController.getTransportControls(); - } - - public void addListener(MediaBrowserChangeListener listener) { - if (listener != null) { - mListeners.add(listener); - } - } - - public void removeListener(MediaBrowserChangeListener listener) { - if (listener != null) { - if (mListeners.contains(listener)) { - mListeners.remove(listener); - } - } - } - - public void performOnAllListeners(@NonNull ListenerCommand command) { - for (MediaBrowserChangeListener listener : mListeners) { - if (listener != null) { - try { - command.perform(listener); - } catch (Exception e) { - removeListener(listener); - } - } - } - } - - public interface ListenerCommand { - - void perform(@NonNull MediaBrowserChangeListener listener); - } - - // Receives callbacks from the MediaBrowser when it has successfully connected to the - // MediaBrowserService (MusicService). - public class MediaBrowserConnectionCallback extends MediaBrowserCompat.ConnectionCallback { - - // Happens as a result of onStart(). - @Override - public void onConnected() { - try { - // Get a MediaController for the MediaSession. - mMediaController = new MediaControllerCompat(mContext, - mMediaBrowser.getSessionToken()); - mMediaController.registerCallback(mMediaControllerCallback); - - // Sync existing MediaSession state to the UI. - mMediaControllerCallback.onMetadataChanged( - mMediaController.getMetadata()); - mMediaControllerCallback - .onPlaybackStateChanged(mMediaController.getPlaybackState()); - - performOnAllListeners(new ListenerCommand() { - @Override - public void perform(@NonNull MediaBrowserChangeListener listener) { - listener.onConnected(mMediaController); - } - }); - } catch (RemoteException e) { - Log.d(TAG, String.format("onConnected: Problem: %s", e.toString())); - throw new RuntimeException(e); - } - - mMediaBrowser.subscribe(mMediaBrowser.getRoot(), mMediaBrowserSubscriptionCallback); - } - } - - // Receives callbacks from the MediaBrowser when the MediaBrowserService has loaded new media - // that is ready for playback. - public class MediaBrowserSubscriptionCallback extends MediaBrowserCompat.SubscriptionCallback { - - @Override - public void onChildrenLoaded(@NonNull String parentId, - @NonNull List<MediaBrowserCompat.MediaItem> children) { - assert mMediaController != null; - - // Queue up all media items for this simple sample. - for (final MediaBrowserCompat.MediaItem mediaItem : children) { - mMediaController.addQueueItem(mediaItem.getDescription()); - } - - // Call "playFromMedia" so the UI is updated. - mMediaController.getTransportControls().prepare(); - } - } - - // Receives callbacks from the MediaController and updates the UI state, - // i.e.: Which is the current item, whether it's playing or paused, etc. - public class MediaControllerCallback extends MediaControllerCompat.Callback { - - @Override - public void onMetadataChanged(final MediaMetadataCompat metadata) { - // Filtering out needless updates, given that the metadata has not changed. - if (isMediaIdSame(metadata, mState.getMediaMetadata())) { - Log.d(TAG, "onMetadataChanged: Filtering out needless onMetadataChanged() update"); - return; - } else { - mState.setMediaMetadata(metadata); - } - performOnAllListeners(new ListenerCommand() { - @Override - public void perform(@NonNull MediaBrowserChangeListener listener) { - listener.onMetadataChanged(metadata); - } - }); - } - - @Override - public void onPlaybackStateChanged(@Nullable final PlaybackStateCompat state) { - mState.setPlaybackState(state); - performOnAllListeners(new ListenerCommand() { - @Override - public void perform(@NonNull MediaBrowserChangeListener listener) { - listener.onPlaybackStateChanged(state); - } - }); - } - - // This might happen if the MusicService is killed while the Activity is in the - // foreground and onStart() has been called (but not onStop()). - @Override - public void onSessionDestroyed() { - resetState(); - onPlaybackStateChanged(null); - Log.d(TAG, "onSessionDestroyed: MusicService is dead!!!"); - } - - private boolean isMediaIdSame(MediaMetadataCompat currentMedia, - MediaMetadataCompat newMedia) { - if (currentMedia == null || newMedia == null) { - return false; - } - String newMediaId = - newMedia.getString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID); - String currentMediaId = - currentMedia.getString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID); - return newMediaId.equals(currentMediaId); - } - - } - - // A holder class that contains the internal state. - public class InternalState { - - private PlaybackStateCompat playbackState; - private MediaMetadataCompat mediaMetadata; - - public void reset() { - playbackState = null; - mediaMetadata = null; - } - - public PlaybackStateCompat getPlaybackState() { - return playbackState; - } - - public void setPlaybackState(PlaybackStateCompat playbackState) { - this.playbackState = playbackState; - } - - public MediaMetadataCompat getMediaMetadata() { - return mediaMetadata; - } - - public void setMediaMetadata(MediaMetadataCompat mediaMetadata) { - this.mediaMetadata = mediaMetadata; - } - } - -}
\ No newline at end of file diff --git a/media/MediaBrowserService/Application/src/main/java/com/example/android/mediasession/client/MediaBrowserHelper.java b/media/MediaBrowserService/Application/src/main/java/com/example/android/mediasession/client/MediaBrowserHelper.java new file mode 100644 index 00000000..4586712c --- /dev/null +++ b/media/MediaBrowserService/Application/src/main/java/com/example/android/mediasession/client/MediaBrowserHelper.java @@ -0,0 +1,260 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.android.mediasession.client; + +import android.content.ComponentName; +import android.content.Context; +import android.os.RemoteException; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.media.MediaBrowserCompat; +import android.support.v4.media.MediaBrowserServiceCompat; +import android.support.v4.media.MediaMetadataCompat; +import android.support.v4.media.session.MediaControllerCompat; +import android.support.v4.media.session.MediaControllerCompat.Callback; +import android.support.v4.media.session.MediaSessionCompat; +import android.support.v4.media.session.PlaybackStateCompat; +import android.util.Log; + +import com.example.android.mediasession.service.MusicService; + +import java.util.ArrayList; +import java.util.List; + +/** + * Helper class for a MediaBrowser that handles connecting, disconnecting, + * and basic browsing with simplified callbacks. + */ +public class MediaBrowserHelper { + + private static final String TAG = MediaBrowserHelper.class.getSimpleName(); + + private final Context mContext; + private final Class<? extends MediaBrowserServiceCompat> mMediaBrowserServiceClass; + + private final List<Callback> mCallbackList = new ArrayList<>(); + + private final MediaBrowserConnectionCallback mMediaBrowserConnectionCallback; + private final MediaControllerCallback mMediaControllerCallback; + private final MediaBrowserSubscriptionCallback mMediaBrowserSubscriptionCallback; + + private MediaBrowserCompat mMediaBrowser; + + @Nullable + private MediaControllerCompat mMediaController; + + public MediaBrowserHelper(Context context, + Class<? extends MediaBrowserServiceCompat> serviceClass) { + mContext = context; + mMediaBrowserServiceClass = serviceClass; + + mMediaBrowserConnectionCallback = new MediaBrowserConnectionCallback(); + mMediaControllerCallback = new MediaControllerCallback(); + mMediaBrowserSubscriptionCallback = new MediaBrowserSubscriptionCallback(); + } + + public void onStart() { + if (mMediaBrowser == null) { + mMediaBrowser = + new MediaBrowserCompat( + mContext, + new ComponentName(mContext, mMediaBrowserServiceClass), + mMediaBrowserConnectionCallback, + null); + mMediaBrowser.connect(); + } + Log.d(TAG, "onStart: Creating MediaBrowser, and connecting"); + } + + public void onStop() { + if (mMediaController != null) { + mMediaController.unregisterCallback(mMediaControllerCallback); + mMediaController = null; + } + if (mMediaBrowser != null && mMediaBrowser.isConnected()) { + mMediaBrowser.disconnect(); + mMediaBrowser = null; + } + resetState(); + Log.d(TAG, "onStop: Releasing MediaController, Disconnecting from MediaBrowser"); + } + + /** + * Called after connecting with a {@link MediaBrowserServiceCompat}. + * <p> + * Override to perform processing after a connection is established. + * + * @param mediaController {@link MediaControllerCompat} associated with the connected + * MediaSession. + */ + protected void onConnected(@NonNull MediaControllerCompat mediaController) { + } + + /** + * Called after loading a browsable {@link MediaBrowserCompat.MediaItem} + * + * @param parentId The media ID of the parent item. + * @param children List (possibly empty) of child items. + */ + protected void onChildrenLoaded(@NonNull String parentId, + @NonNull List<MediaBrowserCompat.MediaItem> children) { + } + + /** + * Called when the {@link MediaBrowserServiceCompat} connection is lost. + */ + protected void onDisconnected() { + } + + @NonNull + protected final MediaControllerCompat getMediaController() { + if (mMediaController == null) { + throw new IllegalStateException("MediaController is null!"); + } + return mMediaController; + } + + /** + * The internal state of the app needs to revert to what it looks like when it started before + * any connections to the {@link MusicService} happens via the {@link MediaSessionCompat}. + */ + private void resetState() { + performOnAllCallbacks(new CallbackCommand() { + @Override + public void perform(@NonNull Callback callback) { + callback.onPlaybackStateChanged(null); + } + }); + Log.d(TAG, "resetState: "); + } + + public MediaControllerCompat.TransportControls getTransportControls() { + if (mMediaController == null) { + Log.d(TAG, "getTransportControls: MediaController is null!"); + throw new IllegalStateException("MediaController is null!"); + } + return mMediaController.getTransportControls(); + } + + public void registerCallback(Callback callback) { + if (callback != null) { + mCallbackList.add(callback); + + // Update with the latest metadata/playback state. + if (mMediaController != null) { + final MediaMetadataCompat metadata = mMediaController.getMetadata(); + if (metadata != null) { + callback.onMetadataChanged(metadata); + } + + final PlaybackStateCompat playbackState = mMediaController.getPlaybackState(); + if (playbackState != null) { + callback.onPlaybackStateChanged(playbackState); + } + } + } + } + + private void performOnAllCallbacks(@NonNull CallbackCommand command) { + for (Callback callback : mCallbackList) { + if (callback != null) { + command.perform(callback); + } + } + } + + /** + * Helper for more easily performing operations on all listening clients. + */ + private interface CallbackCommand { + void perform(@NonNull Callback callback); + } + + // Receives callbacks from the MediaBrowser when it has successfully connected to the + // MediaBrowserService (MusicService). + private class MediaBrowserConnectionCallback extends MediaBrowserCompat.ConnectionCallback { + + // Happens as a result of onStart(). + @Override + public void onConnected() { + try { + // Get a MediaController for the MediaSession. + mMediaController = + new MediaControllerCompat(mContext, mMediaBrowser.getSessionToken()); + mMediaController.registerCallback(mMediaControllerCallback); + + // Sync existing MediaSession state to the UI. + mMediaControllerCallback.onMetadataChanged(mMediaController.getMetadata()); + mMediaControllerCallback.onPlaybackStateChanged( + mMediaController.getPlaybackState()); + + MediaBrowserHelper.this.onConnected(mMediaController); + } catch (RemoteException e) { + Log.d(TAG, String.format("onConnected: Problem: %s", e.toString())); + throw new RuntimeException(e); + } + + mMediaBrowser.subscribe(mMediaBrowser.getRoot(), mMediaBrowserSubscriptionCallback); + } + } + + // Receives callbacks from the MediaBrowser when the MediaBrowserService has loaded new media + // that is ready for playback. + public class MediaBrowserSubscriptionCallback extends MediaBrowserCompat.SubscriptionCallback { + + @Override + public void onChildrenLoaded(@NonNull String parentId, + @NonNull List<MediaBrowserCompat.MediaItem> children) { + MediaBrowserHelper.this.onChildrenLoaded(parentId, children); + } + } + + // Receives callbacks from the MediaController and updates the UI state, + // i.e.: Which is the current item, whether it's playing or paused, etc. + private class MediaControllerCallback extends MediaControllerCompat.Callback { + + @Override + public void onMetadataChanged(final MediaMetadataCompat metadata) { + performOnAllCallbacks(new CallbackCommand() { + @Override + public void perform(@NonNull Callback callback) { + callback.onMetadataChanged(metadata); + } + }); + } + + @Override + public void onPlaybackStateChanged(@Nullable final PlaybackStateCompat state) { + performOnAllCallbacks(new CallbackCommand() { + @Override + public void perform(@NonNull Callback callback) { + callback.onPlaybackStateChanged(state); + } + }); + } + + // This might happen if the MusicService is killed while the Activity is in the + // foreground and onStart() has been called (but not onStop()). + @Override + public void onSessionDestroyed() { + resetState(); + onPlaybackStateChanged(null); + + MediaBrowserHelper.this.onDisconnected(); + } + } +}
\ No newline at end of file diff --git a/media/MediaBrowserService/Application/src/main/java/com/example/android/mediasession/service/MusicService.java b/media/MediaBrowserService/Application/src/main/java/com/example/android/mediasession/service/MusicService.java index 5d98bc20..df4b7363 100644 --- a/media/MediaBrowserService/Application/src/main/java/com/example/android/mediasession/service/MusicService.java +++ b/media/MediaBrowserService/Application/src/main/java/com/example/android/mediasession/service/MusicService.java @@ -104,12 +104,14 @@ public class MusicService extends MediaBrowserServiceCompat { public void onAddQueueItem(MediaDescriptionCompat description) { mPlaylist.add(new MediaSessionCompat.QueueItem(description, description.hashCode())); mQueueIndex = (mQueueIndex == -1) ? 0 : mQueueIndex; + mSession.setQueue(mPlaylist); } @Override public void onRemoveQueueItem(MediaDescriptionCompat description) { mPlaylist.remove(new MediaSessionCompat.QueueItem(description, description.hashCode())); mQueueIndex = (mPlaylist.isEmpty()) ? -1 : mQueueIndex; + mSession.setQueue(mPlaylist); } @Override diff --git a/media/MediaBrowserService/Application/src/main/java/com/example/android/mediasession/ui/MainActivity.java b/media/MediaBrowserService/Application/src/main/java/com/example/android/mediasession/ui/MainActivity.java index 4991789b..530cf738 100644 --- a/media/MediaBrowserService/Application/src/main/java/com/example/android/mediasession/ui/MainActivity.java +++ b/media/MediaBrowserService/Application/src/main/java/com/example/android/mediasession/ui/MainActivity.java @@ -16,10 +16,13 @@ package com.example.android.mediasession.ui; +import android.content.Context; import android.os.Bundle; -import android.support.annotation.Nullable; +import android.support.annotation.NonNull; +import android.support.v4.media.MediaBrowserCompat; import android.support.v4.media.MediaMetadataCompat; import android.support.v4.media.session.MediaControllerCompat; +import android.support.v4.media.session.MediaSessionCompat; import android.support.v4.media.session.PlaybackStateCompat; import android.support.v7.app.AppCompatActivity; import android.view.View; @@ -28,9 +31,12 @@ import android.widget.ImageView; import android.widget.TextView; import com.example.android.mediasession.R; -import com.example.android.mediasession.client.MediaBrowserAdapter; +import com.example.android.mediasession.client.MediaBrowserHelper; +import com.example.android.mediasession.service.MusicService; import com.example.android.mediasession.service.contentcatalogs.MusicLibrary; +import java.util.List; + public class MainActivity extends AppCompatActivity { private ImageView mAlbumArt; @@ -39,7 +45,7 @@ public class MainActivity extends AppCompatActivity { private ImageView mMediaControlsImage; private MediaSeekBar mSeekBarAudio; - private MediaBrowserAdapter mMediaBrowserAdapter; + private MediaBrowserHelper mMediaBrowserHelper; private boolean mIsPlaying; @@ -47,69 +53,103 @@ public class MainActivity extends AppCompatActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - initializeUI(); - mMediaBrowserAdapter = new MediaBrowserAdapter(this); - mMediaBrowserAdapter.addListener(new MediaBrowserListener()); - } - private void initializeUI() { - mTitleTextView = (TextView) findViewById(R.id.song_title); - mArtistTextView = (TextView) findViewById(R.id.song_artist); - mAlbumArt = (ImageView) findViewById(R.id.album_art); - mMediaControlsImage = (ImageView) findViewById(R.id.media_controls); - mSeekBarAudio = (MediaSeekBar) findViewById(R.id.seekbar_audio); - - final Button buttonPrevious = (Button) findViewById(R.id.button_previous); - buttonPrevious.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - mMediaBrowserAdapter.getTransportControls().skipToPrevious(); - } - }); - - final Button buttonPlay = (Button) findViewById(R.id.button_play); - buttonPlay.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (mIsPlaying) { - mMediaBrowserAdapter.getTransportControls().pause(); - } else { - mMediaBrowserAdapter.getTransportControls().play(); - } - } - }); + mTitleTextView = findViewById(R.id.song_title); + mArtistTextView = findViewById(R.id.song_artist); + mAlbumArt = findViewById(R.id.album_art); + mMediaControlsImage = findViewById(R.id.media_controls); + mSeekBarAudio = findViewById(R.id.seekbar_audio); - final Button buttonNext = (Button) findViewById(R.id.button_next); - buttonNext.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - mMediaBrowserAdapter.getTransportControls().skipToNext(); - } - }); + final ClickListener clickListener = new ClickListener(); + findViewById(R.id.button_previous).setOnClickListener(clickListener); + findViewById(R.id.button_play).setOnClickListener(clickListener); + findViewById(R.id.button_next).setOnClickListener(clickListener); + + mMediaBrowserHelper = new MediaBrowserConnection(this); + mMediaBrowserHelper.registerCallback(new MediaBrowserListener()); } @Override public void onStart() { super.onStart(); - mMediaBrowserAdapter.onStart(); + mMediaBrowserHelper.onStart(); } @Override public void onStop() { super.onStop(); mSeekBarAudio.disconnectController(); - mMediaBrowserAdapter.onStop(); + mMediaBrowserHelper.onStop(); } - private class MediaBrowserListener extends MediaBrowserAdapter.MediaBrowserChangeListener { + /** + * Convenience class to collect the click listeners together. + * <p> + * In a larger app it's better to split the listeners out or to use your favorite + * library. + */ + private class ClickListener implements View.OnClickListener { + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.button_previous: + mMediaBrowserHelper.getTransportControls().skipToPrevious(); + break; + case R.id.button_play: + if (mIsPlaying) { + mMediaBrowserHelper.getTransportControls().pause(); + } else { + mMediaBrowserHelper.getTransportControls().play(); + } + break; + case R.id.button_next: + mMediaBrowserHelper.getTransportControls().skipToNext(); + break; + } + } + } + + /** + * Customize the connection to our {@link android.support.v4.media.MediaBrowserServiceCompat} + * and implement our app specific desires. + */ + private class MediaBrowserConnection extends MediaBrowserHelper { + private MediaBrowserConnection(Context context) { + super(context, MusicService.class); + } @Override - public void onConnected(@Nullable MediaControllerCompat mediaController) { - super.onConnected(mediaController); + protected void onConnected(@NonNull MediaControllerCompat mediaController) { mSeekBarAudio.setMediaController(mediaController); } @Override + protected void onChildrenLoaded(@NonNull String parentId, + @NonNull List<MediaBrowserCompat.MediaItem> children) { + super.onChildrenLoaded(parentId, children); + + final MediaControllerCompat mediaController = getMediaController(); + + // Queue up all media items for this simple sample. + for (final MediaBrowserCompat.MediaItem mediaItem : children) { + mediaController.addQueueItem(mediaItem.getDescription()); + } + + // Call prepare now so pressing play just works. + mediaController.getTransportControls().prepare(); + } + } + + /** + * Implementation of the {@link MediaControllerCompat.Callback} methods we're interested in. + * <p> + * Here would also be where one could override + * {@code onQueueChanged(List<MediaSessionCompat.QueueItem> queue)} to get informed when items + * are added or removed from the queue. We don't do this here in order to keep the UI + * simple. + */ + private class MediaBrowserListener extends MediaControllerCompat.Callback { + @Override public void onPlaybackStateChanged(PlaybackStateCompat playbackState) { mIsPlaying = playbackState != null && playbackState.getState() == PlaybackStateCompat.STATE_PLAYING; @@ -129,5 +169,15 @@ public class MainActivity extends AppCompatActivity { MainActivity.this, mediaMetadata.getString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID))); } + + @Override + public void onSessionDestroyed() { + super.onSessionDestroyed(); + } + + @Override + public void onQueueChanged(List<MediaSessionCompat.QueueItem> queue) { + super.onQueueChanged(queue); + } } } diff --git a/media/MediaBrowserService/Application/src/main/java/com/example/android/mediasession/ui/MediaSeekBar.java b/media/MediaBrowserService/Application/src/main/java/com/example/android/mediasession/ui/MediaSeekBar.java index 71de9cae..e70af6de 100644 --- a/media/MediaBrowserService/Application/src/main/java/com/example/android/mediasession/ui/MediaSeekBar.java +++ b/media/MediaBrowserService/Application/src/main/java/com/example/android/mediasession/ui/MediaSeekBar.java @@ -71,8 +71,9 @@ public class MediaSeekBar extends AppCompatSeekBar { } @Override - public void setOnSeekBarChangeListener(OnSeekBarChangeListener l) { + public final void setOnSeekBarChangeListener(OnSeekBarChangeListener l) { // Prohibit adding seek listeners to this subclass. + throw new UnsupportedOperationException("Cannot add listeners to a MediaSeekBar"); } public void setMediaController(final MediaControllerCompat mediaController) { |