@Override public void play(QueueItem item) { mPlayOnFocusGain = true; tryToGetAudioFocus(); registerAudioNoisyReceiver(); String mediaId = item.getDescription().getMediaId(); boolean mediaHasChanged = !TextUtils.equals(mediaId, mCurrentMediaId); if (mediaHasChanged) { mCurrentPosition = 0; mCurrentMediaId = mediaId; } if (mState == PlaybackStateCompat.STATE_PAUSED && !mediaHasChanged && mMediaPlayer != null) { configMediaPlayerState(); } else { mState = PlaybackStateCompat.STATE_STOPPED; relaxResources(false); // release everything except MediaPlayer MediaMetadataCompat track = mMusicProvider.getMusic( MediaIDHelper.extractMusicIDFromMediaID(item.getDescription().getMediaId())); String source = MusicProvider.getTrackSource(track.getString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID)); try { createMediaPlayerIfNeeded(); mState = PlaybackStateCompat.STATE_BUFFERING; mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mMediaPlayer.setDataSource(source); // Starts preparing the media player in the background. When // it's done, it will call our OnPreparedListener (that is, // the onPrepared() method on this class, since we set the // listener to 'this'). Until the media player is prepared, // we *cannot* call start() on it! mMediaPlayer.prepareAsync(); // If we are streaming from the internet, we want to hold a // Wifi lock, which prevents the Wifi radio from going to // sleep while the song is playing. mWifiLock.acquire(); if (mCallback != null) { mCallback.onPlaybackStatusChanged(mState); } } catch (IOException ex) { LogHelper.e(TAG, ex, "Exception playing song"); if (mCallback != null) { mCallback.onError(ex.getMessage()); } } } }
@Override public void onCustomAction(@NonNull String action, Bundle extras) { if (CUSTOM_ACTION_THUMBS_UP.equals(action)) { LogHelper.i(TAG, "onCustomAction: favorite for current track"); MediaMetadataCompat track = getCurrentPlayingMusic(); if (track != null) { String musicId = track.getString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID); mMusicProvider.setFavorite(musicId, !mMusicProvider.isFavorite(musicId)); } // playback state needs to be updated because the "Favorite" icon on the // custom action will change to reflect the new favorite state. updatePlaybackState(null); } else { LogHelper.e(TAG, "Unsupported action: ", action); } }
private void setCustomAction(PlaybackStateCompat.Builder stateBuilder) { MediaMetadataCompat currentMusic = getCurrentPlayingMusic(); if (currentMusic != null) { // Set appropriate "Favorite" icon on Custom action: String musicId = currentMusic.getString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID); int favoriteIcon = R.drawable.ic_star_off; if (mMusicProvider.isFavorite(musicId)) { favoriteIcon = R.drawable.ic_star_on; } LogHelper.d( TAG, "updatePlaybackState, setting Favorite custom action of music ", musicId, " current favorite=", mMusicProvider.isFavorite(musicId)); Bundle customActionExtras = new Bundle(); WearHelper.setShowCustomActionOnWear(customActionExtras, true); stateBuilder.addCustomAction( new PlaybackStateCompat.CustomAction.Builder( CUSTOM_ACTION_THUMBS_UP, getString(R.string.favorite), favoriteIcon) .setExtras(customActionExtras) .build()); } }
private void updateMetadata() { if (!QueueHelper.isIndexPlayable(mCurrentIndexOnQueue, mPlayingQueue)) { LogHelper.e(TAG, "Can't retrieve current metadata."); updatePlaybackState(getResources().getString(R.string.error_no_metadata)); return; } MediaSessionCompat.QueueItem queueItem = mPlayingQueue.get(mCurrentIndexOnQueue); String musicId = MediaIDHelper.extractMusicIDFromMediaID(queueItem.getDescription().getMediaId()); MediaMetadataCompat track = mMusicProvider.getMusic(musicId); if (track == null) { throw new IllegalArgumentException("Invalid musicId " + musicId); } final String trackId = track.getString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID); if (!TextUtils.equals(musicId, trackId)) { IllegalStateException e = new IllegalStateException("track ID should match musicId."); LogHelper.e( TAG, "track ID should match musicId.", " musicId=", musicId, " trackId=", trackId, " mediaId from queueItem=", queueItem.getDescription().getMediaId(), " title from queueItem=", queueItem.getDescription().getTitle(), " mediaId from track=", track.getDescription().getMediaId(), " title from track=", track.getDescription().getTitle(), " source.hashcode from track=", track.getString(MusicProvider.CUSTOM_METADATA_TRACK_SOURCE).hashCode(), e); throw e; } LogHelper.d(TAG, "Updating metadata for MusicID= " + musicId); mSession.setMetadata(track); // Set the proper album artwork on the media session, so it can be shown in the // locked screen and in other places. if (track.getDescription().getIconBitmap() == null && track.getDescription().getIconUri() != null) { String albumUri = track.getDescription().getIconUri().toString(); AlbumArtCache.getInstance() .fetch( albumUri, new AlbumArtCache.FetchListener() { @Override public void onFetched(String artUrl, Bitmap bitmap, Bitmap icon) { MediaSessionCompat.QueueItem queueItem = mPlayingQueue.get(mCurrentIndexOnQueue); MediaMetadataCompat track = mMusicProvider.getMusic(trackId); track = new MediaMetadataCompat.Builder(track) // set high resolution bitmap in METADATA_KEY_ALBUM_ART. This is used, for // example, on the lockscreen background when the media session is active. .putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, bitmap) // set small version of the album art in the DISPLAY_ICON. This is used on // the MediaDescriptionCompat and thus it should be small to be serialized // if // necessary.. .putBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON, icon) .build(); mMusicProvider.updateMusic(trackId, track); // If we are still playing the same music String currentPlayingId = MediaIDHelper.extractMusicIDFromMediaID( queueItem.getDescription().getMediaId()); if (trackId.equals(currentPlayingId)) { mSession.setMetadata(track); } } }); } }