aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--media/MediaBrowserService/Application/src/main/java/com/example/android/mediasession/client/MediaBrowserAdapter.java297
-rw-r--r--media/MediaBrowserService/Application/src/main/java/com/example/android/mediasession/client/MediaBrowserHelper.java260
-rw-r--r--media/MediaBrowserService/Application/src/main/java/com/example/android/mediasession/service/MusicService.java2
-rw-r--r--media/MediaBrowserService/Application/src/main/java/com/example/android/mediasession/ui/MainActivity.java140
-rw-r--r--media/MediaBrowserService/Application/src/main/java/com/example/android/mediasession/ui/MediaSeekBar.java3
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) {