1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.example.android.supportv4.media.utils; 18 19 import static com.example.android.supportv4.media.utils.MediaIDHelper.MEDIA_ID_MUSICS_BY_GENRE; 20 import static com.example.android.supportv4.media.utils.MediaIDHelper.MEDIA_ID_MUSICS_BY_SEARCH; 21 22 import android.support.v4.media.MediaMetadataCompat; 23 import android.support.v4.media.session.MediaSessionCompat; 24 import android.util.Log; 25 26 import com.example.android.supportv4.media.model.MusicProvider; 27 28 import java.util.ArrayList; 29 import java.util.Collections; 30 import java.util.Iterator; 31 import java.util.List; 32 33 /** 34 * Utility class to help on queue related tasks. 35 */ 36 public class QueueHelper { 37 38 private static final String TAG = "QueueHelper"; 39 getPlayingQueue(String mediaId, MusicProvider musicProvider)40 public static List<MediaSessionCompat.QueueItem> getPlayingQueue(String mediaId, 41 MusicProvider musicProvider) { 42 43 // extract the browsing hierarchy from the media ID: 44 String[] hierarchy = MediaIDHelper.getHierarchy(mediaId); 45 46 if (hierarchy.length != 2) { 47 Log.e(TAG, "Could not build a playing queue for this mediaId: " + mediaId); 48 return null; 49 } 50 51 String categoryType = hierarchy[0]; 52 String categoryValue = hierarchy[1]; 53 Log.d(TAG, "Creating playing queue for " + categoryType + ", " + categoryValue); 54 55 Iterable<MediaMetadataCompat> tracks = null; 56 // This sample only supports genre and by_search category types. 57 if (categoryType.equals(MEDIA_ID_MUSICS_BY_GENRE)) { 58 tracks = musicProvider.getMusicsByGenre(categoryValue); 59 } else if (categoryType.equals(MEDIA_ID_MUSICS_BY_SEARCH)) { 60 tracks = musicProvider.searchMusic(categoryValue); 61 } 62 63 if (tracks == null) { 64 Log.e(TAG, "Unrecognized category type: " + categoryType + " for mediaId " + mediaId); 65 return null; 66 } 67 68 return convertToQueue(tracks, hierarchy[0], hierarchy[1]); 69 } 70 getPlayingQueueFromSearch(String query, MusicProvider musicProvider)71 public static List<MediaSessionCompat.QueueItem> getPlayingQueueFromSearch(String query, 72 MusicProvider musicProvider) { 73 74 Log.d(TAG, "Creating playing queue for musics from search " + query); 75 76 return convertToQueue(musicProvider.searchMusic(query), MEDIA_ID_MUSICS_BY_SEARCH, query); 77 } 78 79 getMusicIndexOnQueue(Iterable<MediaSessionCompat.QueueItem> queue, String mediaId)80 public static int getMusicIndexOnQueue(Iterable<MediaSessionCompat.QueueItem> queue, 81 String mediaId) { 82 int index = 0; 83 for (MediaSessionCompat.QueueItem item : queue) { 84 if (mediaId.equals(item.getDescription().getMediaId())) { 85 return index; 86 } 87 index++; 88 } 89 return -1; 90 } 91 getMusicIndexOnQueue(Iterable<MediaSessionCompat.QueueItem> queue, long queueId)92 public static int getMusicIndexOnQueue(Iterable<MediaSessionCompat.QueueItem> queue, 93 long queueId) { 94 int index = 0; 95 for (MediaSessionCompat.QueueItem item : queue) { 96 if (queueId == item.getQueueId()) { 97 return index; 98 } 99 index++; 100 } 101 return -1; 102 } 103 convertToQueue( Iterable<MediaMetadataCompat> tracks, String... categories)104 private static List<MediaSessionCompat.QueueItem> convertToQueue( 105 Iterable<MediaMetadataCompat> tracks, String... categories) { 106 List<MediaSessionCompat.QueueItem> queue = new ArrayList<>(); 107 int count = 0; 108 for (MediaMetadataCompat track : tracks) { 109 110 // We create a hierarchy-aware mediaID, so we know what the queue is about by looking 111 // at the QueueItem media IDs. 112 String hierarchyAwareMediaID = MediaIDHelper.createMediaID( 113 track.getDescription().getMediaId(), categories); 114 115 MediaMetadataCompat trackCopy = new MediaMetadataCompat.Builder(track) 116 .putString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID, hierarchyAwareMediaID) 117 .build(); 118 119 // We don't expect queues to change after created, so we use the item index as the 120 // queueId. Any other number unique in the queue would work. 121 MediaSessionCompat.QueueItem item = new MediaSessionCompat.QueueItem( 122 trackCopy.getDescription(), count++); 123 queue.add(item); 124 } 125 return queue; 126 127 } 128 129 /** 130 * Create a random queue. For simplicity sake, instead of a random queue, we create a 131 * queue using the first genre. 132 * 133 * @param musicProvider the provider used for fetching music. 134 * @return list containing {@link android.media.session.MediaSession.QueueItem}'s 135 */ getRandomQueue(MusicProvider musicProvider)136 public static List<MediaSessionCompat.QueueItem> getRandomQueue(MusicProvider musicProvider) { 137 Iterator<String> genres = musicProvider.getGenres().iterator(); 138 if (!genres.hasNext()) { 139 return Collections.emptyList(); 140 } 141 String genre = genres.next(); 142 Iterable<MediaMetadataCompat> tracks = musicProvider.getMusicsByGenre(genre); 143 144 return convertToQueue(tracks, MEDIA_ID_MUSICS_BY_GENRE, genre); 145 } 146 isIndexPlayable(int index, List<MediaSessionCompat.QueueItem> queue)147 public static boolean isIndexPlayable(int index, List<MediaSessionCompat.QueueItem> queue) { 148 return (queue != null && index >= 0 && index < queue.size()); 149 } 150 } 151