Java tutorial
/* * Copyright 2018 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 androidx.media; import static androidx.media.AudioAttributesCompat.CONTENT_TYPE_UNKNOWN; import static androidx.media.AudioAttributesCompat.USAGE_UNKNOWN; import static androidx.media.MediaMetadata2.METADATA_KEY_DISPLAY_DESCRIPTION; import static androidx.media.MediaMetadata2.METADATA_KEY_DISPLAY_ICON; import static androidx.media.MediaMetadata2.METADATA_KEY_DISPLAY_ICON_URI; import static androidx.media.MediaMetadata2.METADATA_KEY_DISPLAY_SUBTITLE; import static androidx.media.MediaMetadata2.METADATA_KEY_DISPLAY_TITLE; import static androidx.media.MediaMetadata2.METADATA_KEY_EXTRAS; import static androidx.media.MediaMetadata2.METADATA_KEY_MEDIA_ID; import static androidx.media.MediaMetadata2.METADATA_KEY_MEDIA_URI; import static androidx.media.MediaMetadata2.METADATA_KEY_TITLE; import android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle; import android.os.Parcelable; import android.support.v4.media.MediaBrowserCompat.MediaItem; import android.support.v4.media.MediaDescriptionCompat; import android.support.v4.media.MediaMetadataCompat; import android.support.v4.media.RatingCompat; import android.support.v4.media.session.PlaybackStateCompat; import androidx.media.MediaSession2.CommandButton; import java.util.ArrayList; import java.util.List; class MediaUtils2 { static final String AUDIO_ATTRIBUTES_USAGE = "androidx.media.audio_attrs.USAGE"; static final String AUDIO_ATTRIBUTES_CONTENT_TYPE = "androidx.media.audio_attrs.CONTENT_TYPE"; static final String AUDIO_ATTRIBUTES_FLAGS = "androidx.media.audio_attrs.FLAGS"; private MediaUtils2() { } /** * Creates a {@link MediaItem} from the {@link MediaItem2}. * * @param item2 an item. * @return The newly created media item. */ static MediaItem createMediaItem(MediaItem2 item2) { if (item2 == null) { return null; } MediaDescriptionCompat descCompat; MediaMetadata2 metadata = item2.getMetadata(); if (metadata == null) { descCompat = new MediaDescriptionCompat.Builder().setMediaId(item2.getMediaId()).build(); } else { MediaDescriptionCompat.Builder builder = new MediaDescriptionCompat.Builder() .setMediaId(item2.getMediaId()).setSubtitle(metadata.getText(METADATA_KEY_DISPLAY_SUBTITLE)) .setDescription(metadata.getText(METADATA_KEY_DISPLAY_DESCRIPTION)) .setIconBitmap(metadata.getBitmap(METADATA_KEY_DISPLAY_ICON)).setExtras(metadata.getExtras()); String title = metadata.getString(METADATA_KEY_TITLE); if (title != null) { builder.setTitle(title); } else { builder.setTitle(metadata.getString(METADATA_KEY_DISPLAY_TITLE)); } String displayIconUri = metadata.getString(METADATA_KEY_DISPLAY_ICON_URI); if (displayIconUri != null) { builder.setIconUri(Uri.parse(displayIconUri)); } String mediaUri = metadata.getString(METADATA_KEY_MEDIA_URI); if (mediaUri != null) { builder.setMediaUri(Uri.parse(mediaUri)); } descCompat = builder.build(); } return new MediaItem(descCompat, item2.getFlags()); } /** * Creates a {@link MediaItem2} from the {@link MediaItem}. * * @param item an item. * @return The newly created media item. */ static MediaItem2 createMediaItem2(MediaItem item) { if (item == null || item.getMediaId() == null) { return null; } MediaMetadata2 metadata2 = createMediaMetadata2(item.getDescription()); return new MediaItem2.Builder(item.getFlags()).setMediaId(item.getMediaId()).setMetadata(metadata2).build(); } /** * Creates a {@link MediaMetadata2} from the {@link MediaDescriptionCompat}. * * @param descCompat A {@link MediaDescriptionCompat} object. * @return The newly created {@link MediaMetadata2} object. */ static MediaMetadata2 createMediaMetadata2(MediaDescriptionCompat descCompat) { if (descCompat == null) { return null; } MediaMetadata2.Builder metadata2Builder = new MediaMetadata2.Builder(); metadata2Builder.putString(METADATA_KEY_MEDIA_ID, descCompat.getMediaId()); CharSequence title = descCompat.getTitle(); if (title != null) { metadata2Builder.putText(METADATA_KEY_DISPLAY_TITLE, title); } CharSequence description = descCompat.getDescription(); if (description != null) { metadata2Builder.putText(METADATA_KEY_DISPLAY_DESCRIPTION, descCompat.getDescription()); } CharSequence subtitle = descCompat.getSubtitle(); if (subtitle != null) { metadata2Builder.putText(METADATA_KEY_DISPLAY_SUBTITLE, subtitle); } Bitmap icon = descCompat.getIconBitmap(); if (icon != null) { metadata2Builder.putBitmap(METADATA_KEY_DISPLAY_ICON, icon); } Uri iconUri = descCompat.getIconUri(); if (iconUri != null) { metadata2Builder.putText(METADATA_KEY_DISPLAY_ICON_URI, iconUri.toString()); } Bundle bundle = descCompat.getExtras(); if (bundle != null) { metadata2Builder.setExtras(descCompat.getExtras()); } Uri mediaUri = descCompat.getMediaUri(); if (mediaUri != null) { metadata2Builder.putText(METADATA_KEY_MEDIA_URI, mediaUri.toString()); } return metadata2Builder.build(); } /** * Creates a {@link MediaMetadata2} from the {@link MediaMetadataCompat}. * * @param metadataCompat A {@link MediaMetadataCompat} object. * @return The newly created {@link MediaMetadata2} object. */ MediaMetadata2 createMediaMetadata2(MediaMetadataCompat metadataCompat) { if (metadataCompat == null) { return null; } return new MediaMetadata2(metadataCompat.getBundle()); } /** * Creates a {@link MediaMetadataCompat} from the {@link MediaMetadata2}. * * @param metadata2 A {@link MediaMetadata2} object. * @return The newly created {@link MediaMetadataCompat} object. */ MediaMetadataCompat createMediaMetadataCompat(MediaMetadata2 metadata2) { if (metadata2 == null) { return null; } MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder(); List<String> skippedKeys = new ArrayList<>(); Bundle bundle = metadata2.toBundle(); for (String key : bundle.keySet()) { Object value = bundle.get(key); if (value instanceof CharSequence) { builder.putText(key, (CharSequence) value); } else if (value instanceof Rating2) { builder.putRating(key, createRatingCompat((Rating2) value)); } else if (value instanceof Bitmap) { builder.putBitmap(key, (Bitmap) value); } else if (value instanceof Long) { builder.putLong(key, (Long) value); } else { // There is no 'float' or 'bundle' type in MediaMetadataCompat. skippedKeys.add(key); } } MediaMetadataCompat result = builder.build(); for (String key : skippedKeys) { Object value = bundle.get(key); if (value instanceof Float) { // Compatibility for MediaMetadata2.Builder.putFloat() result.getBundle().putFloat(key, (Float) value); } else if (METADATA_KEY_EXTRAS.equals(value)) { // Compatibility for MediaMetadata2.Builder.setExtras() result.getBundle().putBundle(key, (Bundle) value); } } return result; } /** * Creates a {@link Rating2} from the {@link RatingCompat}. * * @param ratingCompat A {@link RatingCompat} object. * @return The newly created {@link Rating2} object. */ Rating2 createRating2(RatingCompat ratingCompat) { if (ratingCompat == null) { return null; } if (!ratingCompat.isRated()) { return Rating2.newUnratedRating(ratingCompat.getRatingStyle()); } switch (ratingCompat.getRatingStyle()) { case RatingCompat.RATING_3_STARS: case RatingCompat.RATING_4_STARS: case RatingCompat.RATING_5_STARS: return Rating2.newStarRating(ratingCompat.getRatingStyle(), ratingCompat.getStarRating()); case RatingCompat.RATING_HEART: return Rating2.newHeartRating(ratingCompat.hasHeart()); case RatingCompat.RATING_THUMB_UP_DOWN: return Rating2.newThumbRating(ratingCompat.isThumbUp()); case RatingCompat.RATING_PERCENTAGE: return Rating2.newPercentageRating(ratingCompat.getPercentRating()); default: return null; } } /** * Creates a {@link RatingCompat} from the {@link Rating2}. * * @param rating2 A {@link Rating2} object. * @return The newly created {@link RatingCompat} object. */ RatingCompat createRatingCompat(Rating2 rating2) { if (rating2 == null) { return null; } if (!rating2.isRated()) { return RatingCompat.newUnratedRating(rating2.getRatingStyle()); } switch (rating2.getRatingStyle()) { case Rating2.RATING_3_STARS: case Rating2.RATING_4_STARS: case Rating2.RATING_5_STARS: return RatingCompat.newStarRating(rating2.getRatingStyle(), rating2.getStarRating()); case Rating2.RATING_HEART: return RatingCompat.newHeartRating(rating2.hasHeart()); case Rating2.RATING_THUMB_UP_DOWN: return RatingCompat.newThumbRating(rating2.isThumbUp()); case Rating2.RATING_PERCENTAGE: return RatingCompat.newPercentageRating(rating2.getPercentRating()); default: return null; } } static Parcelable[] toMediaItem2ParcelableArray(List<MediaItem2> playlist) { if (playlist == null) { return null; } List<Parcelable> parcelableList = new ArrayList<>(); for (int i = 0; i < playlist.size(); i++) { final MediaItem2 item = playlist.get(i); if (item != null) { final Parcelable itemBundle = item.toBundle(); if (itemBundle != null) { parcelableList.add(itemBundle); } } } return parcelableList.toArray(new Parcelable[0]); } static List<MediaItem2> fromMediaItem2ParcelableArray(Parcelable[] itemParcelableList) { List<MediaItem2> playlist = new ArrayList<>(); if (itemParcelableList != null) { for (int i = 0; i < itemParcelableList.length; i++) { if (!(itemParcelableList[i] instanceof Bundle)) { continue; } MediaItem2 item = MediaItem2.fromBundle((Bundle) itemParcelableList[i]); if (item != null) { playlist.add(item); } } } return playlist; } static Parcelable[] toCommandButtonParcelableArray(List<CommandButton> layout) { if (layout == null) { return null; } List<Bundle> layoutBundles = new ArrayList<>(); for (int i = 0; i < layout.size(); i++) { Bundle bundle = layout.get(i).toBundle(); if (bundle != null) { layoutBundles.add(bundle); } } return layoutBundles.toArray(new Parcelable[0]); } static List<CommandButton> fromCommandButtonParcelableArray(Parcelable[] list) { List<CommandButton> layout = new ArrayList<>(); if (layout != null) { for (int i = 0; i < list.length; i++) { if (!(list[i] instanceof Bundle)) { continue; } CommandButton button = CommandButton.fromBundle((Bundle) list[i]); if (button != null) { layout.add(button); } } } return layout; } static Bundle toAudioAttributesBundle(AudioAttributesCompat attrs) { if (attrs == null) { return null; } Bundle bundle = new Bundle(); bundle.putInt(AUDIO_ATTRIBUTES_USAGE, attrs.getUsage()); bundle.putInt(AUDIO_ATTRIBUTES_CONTENT_TYPE, attrs.getContentType()); bundle.putInt(AUDIO_ATTRIBUTES_FLAGS, attrs.getFlags()); return bundle; } static AudioAttributesCompat fromAudioAttributesBundle(Bundle bundle) { if (bundle == null) { return null; } return new AudioAttributesCompat.Builder().setUsage(bundle.getInt(AUDIO_ATTRIBUTES_USAGE, USAGE_UNKNOWN)) .setContentType(bundle.getInt(AUDIO_ATTRIBUTES_CONTENT_TYPE, CONTENT_TYPE_UNKNOWN)) .setFlags(bundle.getInt(AUDIO_ATTRIBUTES_FLAGS, 0)).build(); } static List<Bundle> toBundleList(Parcelable[] array) { if (array == null) { return null; } List<Bundle> bundleList = new ArrayList<>(); for (Parcelable p : array) { bundleList.add((Bundle) p); } return bundleList; } static int createPlaybackStateCompatState(int playerState, int bufferingState) { switch (playerState) { case MediaPlayerBase.PLAYER_STATE_PLAYING: switch (bufferingState) { case MediaPlayerBase.BUFFERING_STATE_BUFFERING_AND_STARVED: return PlaybackStateCompat.STATE_BUFFERING; } return PlaybackStateCompat.STATE_PLAYING; case MediaPlayerBase.PLAYER_STATE_PAUSED: return PlaybackStateCompat.STATE_PAUSED; case MediaPlayerBase.PLAYER_STATE_IDLE: return PlaybackStateCompat.STATE_NONE; case MediaPlayerBase.PLAYER_STATE_ERROR: return PlaybackStateCompat.STATE_ERROR; } // For unknown value return PlaybackStateCompat.STATE_ERROR; } static int toPlayerState(int playbackStateCompatState) { switch (playbackStateCompatState) { case PlaybackStateCompat.STATE_ERROR: return MediaPlayerBase.PLAYER_STATE_ERROR; case PlaybackStateCompat.STATE_NONE: return MediaPlayerBase.PLAYER_STATE_IDLE; case PlaybackStateCompat.STATE_PAUSED: case PlaybackStateCompat.STATE_STOPPED: case PlaybackStateCompat.STATE_BUFFERING: // means paused for buffering. return MediaPlayerBase.PLAYER_STATE_PAUSED; case PlaybackStateCompat.STATE_FAST_FORWARDING: case PlaybackStateCompat.STATE_PLAYING: case PlaybackStateCompat.STATE_REWINDING: case PlaybackStateCompat.STATE_SKIPPING_TO_NEXT: case PlaybackStateCompat.STATE_SKIPPING_TO_PREVIOUS: case PlaybackStateCompat.STATE_SKIPPING_TO_QUEUE_ITEM: case PlaybackStateCompat.STATE_CONNECTING: // Note: there's no perfect match for this. return MediaPlayerBase.PLAYER_STATE_PLAYING; } return MediaPlayerBase.PLAYER_STATE_ERROR; } static boolean isDefaultLibraryRootHint(Bundle bundle) { return bundle != null && bundle.getBoolean(MediaConstants2.ROOT_EXTRA_DEFAULT, false); } }