Java tutorial
/* == This file is part of Tomahawk Player - <http://tomahawk-player.org> === * * Copyright 2016, Enno Gottschalk <mrmaffen@googlemail.com> * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Tomahawk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Tomahawk. If not, see <http://www.gnu.org/licenses/>. */ package org.runbuddy.tomahawk.utils; import android.content.Context; import android.os.Bundle; 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.MediaDescriptionCompat; import android.support.v4.media.session.MediaControllerCompat; import android.support.v4.media.session.MediaSessionCompat; import android.util.Log; import org.jdeferred.DoneCallback; import org.runbuddy.libtomahawk.collection.Album; import org.runbuddy.libtomahawk.collection.Artist; import org.runbuddy.libtomahawk.collection.Collection; import org.runbuddy.libtomahawk.collection.CollectionCursor; import org.runbuddy.libtomahawk.collection.CollectionManager; import org.runbuddy.libtomahawk.collection.HatchetCollection; import org.runbuddy.libtomahawk.collection.Playlist; import org.runbuddy.libtomahawk.collection.StationPlaylist; import org.runbuddy.libtomahawk.database.DatabaseHelper; import org.runbuddy.libtomahawk.infosystem.User; import org.runbuddy.tomahawk.R; import java.util.ArrayList; import java.util.List; public class MediaBrowserHelper { private static final String TAG = MediaBrowserHelper.class.getSimpleName(); public static final String MEDIA_ID_ROOT = "__ROOT__"; public static final String MEDIA_ID_SHUFFLEDPLAY = "__SHUFFLEDPLAY__"; public static final String MEDIA_ID_SHUFFLEDPLAY_TRACKS = "__SHUFFLEDPLAY_TRACKS__"; public static final String MEDIA_ID_SHUFFLEDPLAY_FAVORITES = "__SHUFFLEDPLAY_FAVORITES__"; public static final String MEDIA_ID_COLLECTION = "__COLLECTION__"; public static final String MEDIA_ID_COLLECTION_ALBUMS = "__COLLECTION_ALBUMS__"; public static final String MEDIA_ID_COLLECTION_ARTISTS = "__COLLECTION_ARTISTS__"; public static final String MEDIA_ID_PLAYLISTS = "__PLAYLISTS__"; public static final String MEDIA_ID_STATIONS = "__STATIONS__"; private PackageValidator mPackageValidator; private Context mContext; public MediaBrowserHelper(Context context) { mContext = context; mPackageValidator = new PackageValidator(context); } @Nullable public MediaBrowserServiceCompat.BrowserRoot onGetRoot(@NonNull String clientPackageName, int clientUid, @Nullable Bundle rootHints) { Log.d(TAG, "OnGetRoot: clientPackageName=" + clientPackageName + "; clientUid=" + clientUid + " ; rootHints=" + rootHints); // To ensure you are not allowing any arbitrary app to browse your app's contents, you // need to check the origin: if (!mPackageValidator.isCallerAllowed(mContext, clientPackageName, clientUid)) { // If the request comes from an untrusted package, return null. No further calls will // be made to other media browsing methods. Log.e(TAG, "OnGetRoot: IGNORING request from untrusted package " + clientPackageName); return null; } return new MediaBrowserServiceCompat.BrowserRoot(MEDIA_ID_ROOT, null); } public void onLoadChildren(@NonNull String parentId, @NonNull final MediaBrowserServiceCompat.Result<List<MediaBrowserCompat.MediaItem>> result) { Log.d(TAG, "OnLoadChildren: parentMediaId=" + parentId); result.detach(); final List<MediaBrowserCompat.MediaItem> mediaItems = new ArrayList<>(); if (MEDIA_ID_ROOT.equals(parentId)) { Log.d(TAG, "OnLoadChildren.ROOT"); mediaItems.add(new MediaBrowserCompat.MediaItem( new MediaDescriptionCompat.Builder().setMediaId(MEDIA_ID_SHUFFLEDPLAY) .setTitle(mContext.getString(R.string.mediabrowser_shuffledplay)).build(), MediaBrowserCompat.MediaItem.FLAG_BROWSABLE)); mediaItems.add(new MediaBrowserCompat.MediaItem( new MediaDescriptionCompat.Builder().setMediaId(MEDIA_ID_COLLECTION) .setTitle(mContext.getString(R.string.drawer_title_collection)).build(), MediaBrowserCompat.MediaItem.FLAG_BROWSABLE)); mediaItems.add(new MediaBrowserCompat.MediaItem( new MediaDescriptionCompat.Builder().setMediaId(MEDIA_ID_PLAYLISTS) .setTitle(mContext.getString(R.string.drawer_title_playlists)).build(), MediaBrowserCompat.MediaItem.FLAG_BROWSABLE)); mediaItems.add(new MediaBrowserCompat.MediaItem( new MediaDescriptionCompat.Builder().setMediaId(MEDIA_ID_STATIONS) .setTitle(mContext.getString(R.string.drawer_title_stations)).build(), MediaBrowserCompat.MediaItem.FLAG_BROWSABLE)); result.sendResult(mediaItems); } else if (MEDIA_ID_SHUFFLEDPLAY.equals(parentId)) { mediaItems.add(new MediaBrowserCompat.MediaItem( new MediaDescriptionCompat.Builder().setMediaId(MEDIA_ID_SHUFFLEDPLAY_FAVORITES) .setTitle(mContext.getString(R.string.drawer_title_lovedtracks)).build(), MediaBrowserCompat.MediaItem.FLAG_PLAYABLE)); mediaItems.add(new MediaBrowserCompat.MediaItem( new MediaDescriptionCompat.Builder().setMediaId(MEDIA_ID_SHUFFLEDPLAY_TRACKS) .setTitle(mContext.getString(R.string.tracks)).build(), MediaBrowserCompat.MediaItem.FLAG_PLAYABLE)); result.sendResult(mediaItems); } else if (MEDIA_ID_COLLECTION.equals(parentId)) { mediaItems.add(new MediaBrowserCompat.MediaItem( new MediaDescriptionCompat.Builder().setMediaId(MEDIA_ID_COLLECTION_ALBUMS) .setTitle(mContext.getString(R.string.albums)).build(), MediaBrowserCompat.MediaItem.FLAG_BROWSABLE)); mediaItems.add(new MediaBrowserCompat.MediaItem( new MediaDescriptionCompat.Builder().setMediaId(MEDIA_ID_COLLECTION_ARTISTS) .setTitle(mContext.getString(R.string.artists)).build(), MediaBrowserCompat.MediaItem.FLAG_BROWSABLE)); result.sendResult(mediaItems); } else if (MEDIA_ID_COLLECTION_ALBUMS.equals(parentId)) { CollectionManager.get().getUserCollection().getAlbums(Collection.SORT_ALPHA) .done(new DoneCallback<CollectionCursor<Album>>() { @Override public void onDone(CollectionCursor<Album> albums) { for (int i = 0; i < albums.size(); i++) { Album album = albums.get(i); String mediaId = buildMediaId(MEDIA_ID_COLLECTION_ALBUMS, album.getCacheKey()); mediaItems.add(new MediaBrowserCompat.MediaItem( new MediaDescriptionCompat.Builder().setMediaId(mediaId) .setTitle(album.getPrettyName()) .setSubtitle(album.getArtist().getPrettyName()).build(), MediaBrowserCompat.MediaItem.FLAG_PLAYABLE)); } albums.close(); result.sendResult(mediaItems); } }); } else if (MEDIA_ID_COLLECTION_ARTISTS.equals(parentId)) { CollectionManager.get().getUserCollection().getArtists(Collection.SORT_ALPHA) .done(new DoneCallback<CollectionCursor<Artist>>() { @Override public void onDone(CollectionCursor<Artist> artists) { for (int i = 0; i < artists.size(); i++) { Artist artist = artists.get(i); String mediaId = buildMediaId(MEDIA_ID_COLLECTION_ARTISTS, artist.getCacheKey()); mediaItems.add(new MediaBrowserCompat.MediaItem( new MediaDescriptionCompat.Builder().setMediaId(mediaId) .setTitle(artist.getPrettyName()).build(), MediaBrowserCompat.MediaItem.FLAG_PLAYABLE)); } artists.close(); result.sendResult(mediaItems); } }); } else if (MEDIA_ID_PLAYLISTS.equals(parentId)) { User.getSelf().done(new DoneCallback<User>() { @Override public void onDone(User user) { for (int i = 0; i < user.getPlaylists().size(); i++) { Playlist playlist = user.getPlaylists().get(i); String topArtistsString = ""; String[] artists = playlist.getTopArtistNames(); if (artists != null) { for (int j = 0; j < artists.length && j < 5; j++) { topArtistsString += artists[j]; if (j != artists.length - 1) { topArtistsString += ", "; } } } String mediaId = buildMediaId(MEDIA_ID_PLAYLISTS, playlist.getCacheKey()); mediaItems.add(new MediaBrowserCompat.MediaItem( new MediaDescriptionCompat.Builder().setMediaId(mediaId) .setTitle(playlist.getName()).setSubtitle(topArtistsString).build(), MediaBrowserCompat.MediaItem.FLAG_PLAYABLE)); } result.sendResult(mediaItems); } }); } else if (MEDIA_ID_STATIONS.equals(parentId)) { List<StationPlaylist> stations = DatabaseHelper.get().getStations(); for (StationPlaylist station : stations) { String mediaId = buildMediaId(MEDIA_ID_STATIONS, station.getCacheKey()); mediaItems.add( new MediaBrowserCompat.MediaItem(new MediaDescriptionCompat.Builder().setMediaId(mediaId) .setTitle(station.getName()).build(), MediaBrowserCompat.MediaItem.FLAG_PLAYABLE)); } result.sendResult(mediaItems); } } private String buildMediaId(String leaf, String cacheKey) { return leaf + "" + cacheKey; } /** * Override to handle requests to play a specific mediaId that was provided by your app. */ public void onPlayFromMediaId(final MediaSessionCompat mediaSession, final PlaybackManager playbackManager, final String mediaId, Bundle extras) { String[] parts; final MediaControllerCompat.TransportControls transportControls = mediaSession.getController() .getTransportControls(); if (MEDIA_ID_SHUFFLEDPLAY_FAVORITES.equals(mediaId)) { User.getSelf().done(new DoneCallback<User>() { @Override public void onDone(User user) { playbackManager.setPlaylist(user.getFavorites()); playbackManager.setShuffleMode(PlaybackManager.SHUFFLED); transportControls.play(); } }); } else if (MEDIA_ID_SHUFFLEDPLAY_TRACKS.equals(mediaId)) { CollectionManager.get().getUserCollection().getQueries(Collection.SORT_ALPHA) .done(new DoneCallback<Playlist>() { @Override public void onDone(Playlist collectionTracks) { playbackManager.setPlaylist(collectionTracks); playbackManager.setShuffleMode(PlaybackManager.SHUFFLED); transportControls.play(); } }); } else if ((parts = mediaId.split("", 2)).length > 1) { String leaf = parts[0]; String cacheKey = parts[1]; if (MEDIA_ID_COLLECTION_ALBUMS.equals(leaf)) { final Album album = Album.getByKey(cacheKey); CollectionManager.get().getUserCollection().getAlbumTracks(album) .done(new DoneCallback<Playlist>() { @Override public void onDone(Playlist albumTracks) { if (albumTracks != null) { playbackManager.setPlaylist(albumTracks); transportControls.play(); } else { HatchetCollection hatchetCollection = CollectionManager.get() .getHatchetCollection(); hatchetCollection.getAlbumTracks(album).done(new DoneCallback<Playlist>() { @Override public void onDone(Playlist albumTracks) { if (albumTracks != null) { playbackManager.setPlaylist(albumTracks); mediaSession.getController().getTransportControls().play(); } } }); } } }); } else if (MEDIA_ID_COLLECTION_ARTISTS.equals(leaf)) { final Artist artist = Artist.getByKey(cacheKey); CollectionManager.get().getUserCollection().getArtistTracks(artist) .done(new DoneCallback<Playlist>() { @Override public void onDone(Playlist artistTracks) { if (artistTracks != null) { playbackManager.setPlaylist(artistTracks); transportControls.play(); } else { HatchetCollection hatchetCollection = CollectionManager.get() .getHatchetCollection(); hatchetCollection.getArtistTopHits(artist).done(new DoneCallback<Playlist>() { @Override public void onDone(Playlist artistTopHits) { if (artistTopHits != null) { playbackManager.setPlaylist(artistTopHits); transportControls.play(); } } }); } } }); } else if (MEDIA_ID_PLAYLISTS.equals(leaf) || MEDIA_ID_STATIONS.equals(leaf)) { Playlist playlist = Playlist.getByKey(cacheKey); if (!(playlist instanceof StationPlaylist) && !playlist.isFilled()) { playlist = DatabaseHelper.get().getPlaylist(playlist.getId()); } playbackManager.setPlaylist(playlist); transportControls.play(); } } } }