Download File
Download Project
Settings
Line Wrap
Themes
default
ambiance
bespin
dracula
eclipse
material
mbo
mdn-like
neat
solarized dark
ttcn
zenburn
MusicService.java
/* * 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.service; import android.app.Notification; import android.content.Intent; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v4.content.ContextCompat; import android.support.v4.media.MediaBrowserCompat; import android.support.v4.media.MediaBrowserServiceCompat; import android.support.v4.media.MediaDescriptionCompat; import android.support.v4.media.MediaMetadataCompat; import android.support.v4.media.session.MediaSessionCompat; import android.support.v4.media.session.PlaybackStateCompat; import android.util.Log; import com.example.android.mediasession.service.contentcatalogs.MusicLibrary; import com.example.android.mediasession.service.notifications.MediaNotificationManager; import com.example.android.mediasession.service.players.MediaPlayerAdapter; import java.util.ArrayList; import java.util.List; public class MusicService extends MediaBrowserServiceCompat { private static final String TAG = MusicService.class.getSimpleName(); private MediaSessionCompat mSession; private PlayerAdapter mPlayback; private MediaNotificationManager mMediaNotificationManager; private MediaSessionCallback mCallback; private boolean mServiceInStartedState; @Override public void onCreate() { super.onCreate(); // Create a new MediaSession. mSession = new MediaSessionCompat(this, "MusicService"); mCallback = new MediaSessionCallback(); mSession.setCallback(mCallback); mSession.setFlags( MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_QUEUE_COMMANDS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); setSessionToken(mSession.getSessionToken()); mMediaNotificationManager = new MediaNotificationManager(this); mPlayback = new MediaPlayerAdapter(this, new MediaPlayerListener()); Log.d(TAG, "onCreate: MusicService creating MediaSession, and MediaNotificationManager"); } @Override public void onTaskRemoved(Intent rootIntent) { super.onTaskRemoved(rootIntent); stopSelf(); } @Override public void onDestroy() { mMediaNotificationManager.onDestroy(); mPlayback.stop(); mSession.release(); Log.d(TAG, "onDestroy: MediaPlayerAdapter stopped, and MediaSession released"); } @Override public BrowserRoot onGetRoot(@NonNull String clientPackageName, int clientUid, Bundle rootHints) { return new BrowserRoot(MusicLibrary.getRoot(), null); } @Override public void onLoadChildren( @NonNull final String parentMediaId, @NonNull final Result
> result) { result.sendResult(MusicLibrary.getMediaItems()); } // MediaSession Callback: Transport Controls -> MediaPlayerAdapter public class MediaSessionCallback extends MediaSessionCompat.Callback { private final List
mPlaylist = new ArrayList<>(); private int mQueueIndex = -1; private MediaMetadataCompat mPreparedMedia; @Override public void onAddQueueItem(MediaDescriptionCompat description) { mPlaylist.add(new MediaSessionCompat.QueueItem(description, description.hashCode())); mQueueIndex = (mQueueIndex == -1) ? 0 : mQueueIndex; } @Override public void onRemoveQueueItem(MediaDescriptionCompat description) { mPlaylist.remove(new MediaSessionCompat.QueueItem(description, description.hashCode())); mQueueIndex = (mPlaylist.isEmpty()) ? -1 : mQueueIndex; } @Override public void onPrepare() { if (mQueueIndex < 0 && mPlaylist.isEmpty()) { // Nothing to play. return; } final String mediaId = mPlaylist.get(mQueueIndex).getDescription().getMediaId(); mPreparedMedia = MusicLibrary.getMetadata(MusicService.this, mediaId); mSession.setMetadata(mPreparedMedia); if (!mSession.isActive()) { mSession.setActive(true); } } @Override public void onPlay() { if (!isReadyToPlay()) { // Nothing to play. return; } if (mPreparedMedia == null) { onPrepare(); } mPlayback.playFromMedia(mPreparedMedia); Log.d(TAG, "onPlayFromMediaId: MediaSession active"); } @Override public void onPause() { mPlayback.pause(); } @Override public void onStop() { mPlayback.stop(); mSession.setActive(false); } @Override public void onSkipToNext() { mQueueIndex = (++mQueueIndex % mPlaylist.size()); mPreparedMedia = null; onPlay(); } @Override public void onSkipToPrevious() { mQueueIndex = mQueueIndex > 0 ? mQueueIndex - 1 : mPlaylist.size() - 1; mPreparedMedia = null; onPlay(); } @Override public void onSeekTo(long pos) { mPlayback.seekTo(pos); } private boolean isReadyToPlay() { return (!mPlaylist.isEmpty()); } } // MediaPlayerAdapter Callback: MediaPlayerAdapter state -> MusicService. public class MediaPlayerListener extends PlaybackInfoListener { private final ServiceManager mServiceManager; MediaPlayerListener() { mServiceManager = new ServiceManager(); } @Override public void onPlaybackStateChange(PlaybackStateCompat state) { // Report the state to the MediaSession. mSession.setPlaybackState(state); // Manage the started state of this service. switch (state.getState()) { case PlaybackStateCompat.STATE_PLAYING: mServiceManager.moveServiceToStartedState(state); break; case PlaybackStateCompat.STATE_PAUSED: mServiceManager.updateNotificationForPause(state); break; case PlaybackStateCompat.STATE_STOPPED: mServiceManager.moveServiceOutOfStartedState(state); break; } } class ServiceManager { private void moveServiceToStartedState(PlaybackStateCompat state) { Notification notification = mMediaNotificationManager.getNotification( mPlayback.getCurrentMedia(), state, getSessionToken()); if (!mServiceInStartedState) { ContextCompat.startForegroundService( MusicService.this, new Intent(MusicService.this, MusicService.class)); mServiceInStartedState = true; } startForeground(MediaNotificationManager.NOTIFICATION_ID, notification); } private void updateNotificationForPause(PlaybackStateCompat state) { stopForeground(false); Notification notification = mMediaNotificationManager.getNotification( mPlayback.getCurrentMedia(), state, getSessionToken()); mMediaNotificationManager.getNotificationManager() .notify(MediaNotificationManager.NOTIFICATION_ID, notification); } private void moveServiceOutOfStartedState(PlaybackStateCompat state) { stopForeground(true); stopSelf(); mServiceInStartedState = false; } } } }