@Override public BrowserRoot onGetRoot(@NonNull String clientPackageName, int clientUid, Bundle rootHints) { LogHelper.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(this, clientPackageName, clientUid)) { // If the request comes from an untrusted package, return null. No further calls will // be made to other media browsing methods. LogHelper.w(TAG, "OnGetRoot: IGNORING request from untrusted package " + clientPackageName); return null; } //noinspection StatementWithEmptyBody if (CarHelper.isValidCarPackage(clientPackageName)) { // Optional: if your app needs to adapt the music library to show a different subset // when connected to the car, this is where you should handle it. // If you want to adapt other runtime behaviors, like tweak ads or change some behavior // that should be different on cars, you should instead use the boolean flag // set by the BroadcastReceiver mCarConnectionReceiver (mIsConnectedToCar). } //noinspection StatementWithEmptyBody if (WearHelper.isValidWearCompanionPackage(clientPackageName)) { // Optional: if your app needs to adapt the music library for when browsing from a // Wear device, you should return a different MEDIA ROOT here, and then, // on onLoadChildren, handle it accordingly. } return new BrowserRoot(MEDIA_ID_ROOT, null); }
/** * Actual implementation of onLoadChildren that assumes that MusicProvider is already initialized. */ private void loadChildrenImpl( final String parentMediaId, final Result<List<MediaBrowser.MediaItem>> result) { LogHelper.d(TAG, "OnLoadChildren: parentMediaId=", parentMediaId); List<MediaBrowser.MediaItem> mediaItems = new ArrayList<>(); if (MEDIA_ID_ROOT.equals(parentMediaId)) { LogHelper.d(TAG, "OnLoadChildren.ROOT"); mediaItems.add( new MediaBrowser.MediaItem( new MediaDescription.Builder() .setMediaId(MEDIA_ID_MUSICS_BY_GENRE) .setTitle(getString(R.string.browse_genres)) .setIconUri( Uri.parse( "android.resource://" + "com.example.android.uamp/drawable/ic_by_genre")) .setSubtitle(getString(R.string.browse_genre_subtitle)) .build(), MediaBrowser.MediaItem.FLAG_BROWSABLE)); } else if (MEDIA_ID_MUSICS_BY_GENRE.equals(parentMediaId)) { LogHelper.d(TAG, "OnLoadChildren.GENRES"); for (String genre : mMusicProvider.getGenres()) { MediaBrowser.MediaItem item = new MediaBrowser.MediaItem( new MediaDescription.Builder() .setMediaId(createBrowseCategoryMediaID(MEDIA_ID_MUSICS_BY_GENRE, genre)) .setTitle(genre) .setSubtitle(getString(R.string.browse_musics_by_genre_subtitle, genre)) .build(), MediaBrowser.MediaItem.FLAG_BROWSABLE); mediaItems.add(item); } } else if (parentMediaId.startsWith(MEDIA_ID_MUSICS_BY_GENRE)) { String genre = MediaIDHelper.getHierarchy(parentMediaId)[1]; LogHelper.d(TAG, "OnLoadChildren.SONGS_BY_GENRE genre=", genre); for (MediaMetadata track : mMusicProvider.getMusicsByGenre(genre)) { // Since mediaMetadata fields are immutable, we need to create a copy, so we // can set a hierarchy-aware mediaID. We will need to know the media hierarchy // when we get a onPlayFromMusicID call, so we can create the proper queue based // on where the music was selected from (by artist, by genre, random, etc) String hierarchyAwareMediaID = MediaIDHelper.createMediaID( track.getDescription().getMediaId(), MEDIA_ID_MUSICS_BY_GENRE, genre); MediaMetadata trackCopy = new MediaMetadata.Builder(track) .putString(MediaMetadata.METADATA_KEY_MEDIA_ID, hierarchyAwareMediaID) .build(); MediaBrowser.MediaItem bItem = new MediaBrowser.MediaItem(trackCopy.getDescription(), MediaItem.FLAG_PLAYABLE); mediaItems.add(bItem); } } else { LogHelper.w(TAG, "Skipping unmatched parentMediaId: ", parentMediaId); } LogHelper.d(TAG, "OnLoadChildren sending ", mediaItems.size(), " results for ", parentMediaId); result.sendResult(mediaItems); }
private void onMetadataChanged(MediaMetadataCompat metadata) { LogHelper.d(TAG, "onMetadataChanged ", metadata); if (getActivity() == null) { LogHelper.w( TAG, "onMetadataChanged called when getActivity null," + "this should not happen if the callback was properly unregistered. Ignoring."); return; } if (metadata == null) { return; } mTitle.setText(metadata.getDescription().getTitle()); mSubtitle.setText(metadata.getDescription().getSubtitle()); String artUrl = null; if (metadata.getDescription().getIconUri() != null) { artUrl = metadata.getDescription().getIconUri().toString(); } if (!TextUtils.equals(artUrl, mArtUrl)) { mArtUrl = artUrl; Bitmap art = metadata.getDescription().getIconBitmap(); AlbumArtCache cache = AlbumArtCache.getInstance(); if (art == null) { art = cache.getIconImage(mArtUrl); } if (art != null) { mAlbumArt.setImageBitmap(art); } else { cache.fetch( artUrl, new AlbumArtCache.FetchListener() { @Override public void onFetched(String artUrl, Bitmap bitmap, Bitmap icon) { if (icon != null) { LogHelper.d( TAG, "album art icon of w=", icon.getWidth(), " h=", icon.getHeight()); if (isAdded()) { mAlbumArt.setImageBitmap(icon); } } } }); } } }
private void onPlaybackStateChanged(PlaybackStateCompat state) { LogHelper.d(TAG, "onPlaybackStateChanged ", state); if (getActivity() == null) { LogHelper.w( TAG, "onPlaybackStateChanged called when getActivity null," + "this should not happen if the callback was properly unregistered. Ignoring."); return; } if (state == null) { return; } boolean enablePlay = false; switch (state.getState()) { case PlaybackStateCompat.STATE_PAUSED: case PlaybackStateCompat.STATE_STOPPED: enablePlay = true; break; case PlaybackStateCompat.STATE_ERROR: LogHelper.e(TAG, "error playbackstate: ", state.getErrorMessage()); Toast.makeText(getActivity(), state.getErrorMessage(), Toast.LENGTH_LONG).show(); break; } if (enablePlay) { mPlayPause.setImageDrawable( ContextCompat.getDrawable(getActivity(), R.drawable.ic_play_arrow_black_36dp)); } else { mPlayPause.setImageDrawable( ContextCompat.getDrawable(getActivity(), R.drawable.ic_pause_black_36dp)); } MediaControllerCompat controller = ((FragmentActivity) getActivity()).getSupportMediaController(); String extraInfo = null; if (controller != null && controller.getExtras() != null) { String castName = controller.getExtras().getString(MusicService.EXTRA_CONNECTED_CAST); if (castName != null) { extraInfo = getResources().getString(R.string.casting_to_device, castName); } } setExtraInfo(extraInfo); }
@Override public BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) { LogHelper.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(this, clientPackageName, clientUid)) { // If the request comes from an untrusted package, return null. No further calls will // be made to other media browsing methods. LogHelper.w(TAG, "OnGetRoot: IGNORING request from untrusted package " + clientPackageName); return null; } //noinspection StatementWithEmptyBody if (CarHelper.isValidCarPackage(clientPackageName)) { // Optional: if your app needs to adapt ads, music library or anything else that // needs to run differently when connected to the car, this is where you should handle // it. } return new BrowserRoot(MEDIA_ID_ROOT, null); }