android自动桌面头单元在选择歌曲时不会显示播放/暂停控件

问题描述 投票:0回答:1

如果我尝试Spotify应用程序,它确实显示了播放控件。如何使我的MP3应用程序显示控件?enter image description here 这里是我的MediaPlayBackservice(我一定缺少一些东西!):

public class MediaPlaybackService extends MediaBrowserServiceCompat { private static final String MEDIA_ROOT_ID = "media_root_id"; private static final String EMPTY_MEDIA_ROOT_ID = "empty_root_id"; private static final String PLAYLIST = "playlist"; private static final String ALBUMS = "albums"; private static final String ALBUM = "album"; private static final String ARTISTS = "artists"; private static final String ARTIST = "artist"; private static final String LOG_TAG = "mediaPlaybackService"; private static final String SONG = "song"; private MediaSessionCompat mediaSession; private Result<List<MediaBrowserCompat.MediaItem>> saveResult; private DaoHelper daoHelper; private MyDatabase db; List<SongItem> songItemList = new ArrayList<>(); private static final String CURRENT_MEDIA_POSITION = "media_position_key"; private static final int PLAY = 1; private static final int PAUSE = 2; private static final int BUFFERING = 3; private static final int CONNECTING = 4; private static final int STOPPED = 5; //MediaPlayer mediaPlayer; MediaService mediaService; String TAG = "DJ"; FileContentProvider fileProvider; @Override public void onCreate() { super.onCreate(); db = MyDatabase.getDatabase(this, "/data/data/com.emrick.dj"); if (db == null) { Log.e(TAG,"In oncreate, db is null"); } daoHelper = DaoHelper.getInstance(db, null); if (daoHelper ==null) { Log.e(TAG,"DaoHelper is null"); } // Create a MediaSessionCompat Context context = getBaseContext(); try { mediaSession = new MediaSessionCompat(context, TAG); } catch (Exception ex) { Log.e(TAG,"Exception while creating media session " + ex.getMessage()); } if (mediaSession == null) { Log.e(TAG, "initMediaSession: mediaSession = null"); return; } mediaSession.setActive(true); mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); mediaService = MediaService.getInstance(); if (mediaService.isPlaying()) { setMediaPlaybackState(PLAY); } else { setMediaPlaybackState(STOPPED); } fileProvider = new FileContentProvider(); mediaSession.setCallback(new MediaSessionCompat.Callback() { @Override public void onPrepare() { Log.d(TAG, "prepare called"); } @Override public boolean onMediaButtonEvent(Intent mediaButtonIntent) { Log.d(TAG, "onMediaButtonEvent called: " + mediaButtonIntent); return false; } @Override public void onPause() { Log.d(TAG, "onPause called (media button pressed)"); super.onPause(); setMediaPlaybackState(PAUSE); mediaService.pause(); } @Override public void onPlay() { Log.d(TAG, "onPlay called (media button pressed)"); super.onPlay(); mediaService.resume(); } @Override public void onPlayFromMediaId(String mediaId, Bundle extras) { Log.d(TAG, "onPlayFromMediaId"); String[] tokens = mediaId.split("_"); if (tokens.length > 0) { if (mediaId.toLowerCase().equals("playlist")) { if (songItemList != null && songItemList.size() > 0) { mediaService.play(songItemList.get(0)); } } else { String trackIdString = tokens[1]; long trackId = Long.parseLong(trackIdString); boolean found = false; for (SongItem item : songItemList) { if (item.getTrackid() == trackId) { found = true; mediaService.play(item); setMediaPlaybackState(PLAY); break; } } if (!found) { Log.d(TAG, "Song item not found in list for trackId " + trackId); } } } else { Log.e(TAG,"No track id in mediaId? " + mediaId); } } @Override public void onStop() { Log.d(TAG, "onStop called (media button pressed)"); super.onStop(); setMediaPlaybackState(STOPPED); mediaService.stop(); } @Override public void onRewind () { Log.d(TAG, "rewind called"); } @Override public void onSkipToNext () { Log.d(TAG, "skip to next called"); } @Override public void onSkipToPrevious () { Log.d(TAG, "skip to previous called"); } }) ; // Set the session's token so that client activities can communicate with it. setSessionToken(mediaSession.getSessionToken()); } @Nullable @Override public BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) { Log.d(TAG,"onGetRoot called"); Bundle extras = new Bundle(); extras.putInt( MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE, MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM); extras.putInt( MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE, MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM); return new BrowserRoot(MEDIA_ROOT_ID, extras); } @Override public void onLoadChildren(@NonNull String parentId, @NonNull Result<List<MediaBrowserCompat.MediaItem>> result) { Log.d(TAG,"onLoadChildren called " + parentId); saveResult = result; // Browsing not allowed if (TextUtils.equals(EMPTY_MEDIA_ROOT_ID, parentId)) { result.sendResult(null); return; } List<MediaBrowserCompat.MediaItem> mediaItems = new ArrayList<>(); MediaDescriptionCompat.Builder descBuilder = new MediaDescriptionCompat.Builder(); // Check if this is the root menu: if (MEDIA_ROOT_ID.equals(parentId)) { MediaBrowserCompat.MediaItem item = new MediaBrowserCompat.MediaItem(descBuilder .setMediaId(PLAYLIST) .build(),MediaBrowserCompat.MediaItem.FLAG_BROWSABLE ); mediaItems.add(item); result.sendResult(mediaItems); } else { // Examine the passed parentMediaId to see which submenu we're at, // and put the children of that menu in the mediaItems list... if (parentId.equals((PLAYLIST))) { Log.d(TAG,"getChildren playlist"); daoHelper.getPlaylistSongs(this,Playlist.PLAYING_LIST); result.detach(); } else if (parentId.startsWith(SONG)) { Log.d(TAG, "getChildren song " + parentId); String idArray[] = parentId.split("_"); String id = idArray[1]; long trackId = Long.parseLong(id); for (SongItem songItem : songItemList) { if (songItem.getTrackid() == trackId) { Uri uri = null; try { uri = Uri.parse(songItem.getLocation()); } catch (Exception e) { throw new RuntimeException(e); } Uri artUri = null; try { artUri = Uri.parse(songItem.getArtLocation()); } catch (Exception e) { throw new RuntimeException(e); } MediaBrowserCompat.MediaItem item = new MediaBrowserCompat.MediaItem(descBuilder.setMediaId(id) .setDescription(songItem.getName()) .setMediaUri(uri) .setIconUri(artUri) .build(), MediaBrowserCompat.MediaItem.FLAG_PLAYABLE); mediaItems.add(item); } } result.sendResult(mediaItems); } } } public void setSongItemList(List<SongItem> songList) { if (songItemList == null) { songItemList = new ArrayList<SongItem>(); } songItemList.clear(); songItemList.addAll(songList); songItemList= songList; List<MediaBrowserCompat.MediaItem> mediaItems = new ArrayList<>(); MediaDescriptionCompat.Builder descBuilder = new MediaDescriptionCompat.Builder(); int count = 0; for (SongItem songItem:songItemList) { String id = SONG + "_" + songItem.getTrackid(); Uri uri = null; Uri mediaUri = null; Bitmap art = null; if (songItem.getArtLocation() != null) { File f = new File(songItem.getArtLocation()); if (f.exists()) { //Must use parse, not fromFile! uri = Uri.parse(songItem.getArtLocation()); uri = fileProvider.mapUri(uri); } else { Log.d(TAG,"File doesn't exist:" + songItem.getArtLocation()); } f = new File(songItem.getLocation()); if (f.exists()) { //Must use parse, not fromFile! mediaUri = Uri.parse(songItem.getLocation()); mediaUri = fileProvider.mapUri(mediaUri); } else { Log.d(TAG, "File doesn't exist: " + songItem.getLocation()); } } Bundle extras = new Bundle(); MediaBrowserCompat.MediaItem item = new MediaBrowserCompat.MediaItem(descBuilder.setMediaId(id) .setDescription(songItem.getName()) .setSubtitle(songItem.getArtist()) .setIconUri(uri) .setMediaUri(mediaUri) .setMediaId(id) .setTitle(songItem.getName()) .setExtras(extras) .build(),MediaBrowserCompat.MediaItem.FLAG_PLAYABLE); mediaItems.add(item); count++; if (count > 20) { break; } } saveResult.sendResult(mediaItems); } private void setMediaPlaybackState( int state ) { PlaybackStateCompat playbackState = null; switch (state) { case PLAY: playbackState = new PlaybackStateCompat.Builder() .setActions( PlaybackStateCompat.ACTION_PLAY_PAUSE | PlaybackStateCompat.ACTION_SKIP_TO_NEXT | PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS ) .setState( PlaybackStateCompat.STATE_PLAYING, 0, 1 ) .build(); break; case PAUSE: playbackState = new PlaybackStateCompat.Builder() .setActions( PlaybackStateCompat.ACTION_PLAY_PAUSE ) .setState(PlaybackStateCompat.STATE_PAUSED, 0, 1) .build(); break; case BUFFERING: playbackState = new PlaybackStateCompat.Builder() .setActions( PlaybackStateCompat.ACTION_STOP ) .setState(PlaybackStateCompat.STATE_BUFFERING, 0, 1) .build(); break; case CONNECTING: playbackState = new PlaybackStateCompat.Builder() .setActions( PlaybackStateCompat.ACTION_STOP ) .setState(PlaybackStateCompat.STATE_CONNECTING, 0, 1) .build(); break; case STOPPED: playbackState = new PlaybackStateCompat.Builder() .setActions( PlaybackStateCompat.ACTION_PLAY_FROM_MEDIA_ID ) .setState(PlaybackStateCompat.STATE_STOPPED, 0, 1) .build(); break; } mediaSession.setPlaybackState( playbackState ); } }

这是我在AndroidManifest中添加的内容:

<service
        android:name=".MediaService"
        android:enabled="true"
        android:icon="@mipmap/ic_launcher"/>

    <meta-data android:name="com.android.automotive"
        android:resource="@xml/automotive_app_desc"/>
    <meta-data android:name="com.google.android.gms.car.application"
        android:resource="@xml/automotive_app_desc"/>
    <receiver android:name="androidx.media.session.MediaButtonReceiver"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.MEDIA_BUTTON" />
        </intent-filter>
    </receiver>
    <service android:name="com.emrick.dj.MediaPlaybackService"
        android:exported="true"
        android:enabled="true"
        tools:ignore="ExportedService">
        <intent-filter>
            <action android:name="android.media.browse.MediaBrowserService"/>
        </intent-filter>

    </service>
    <provider
        android:name=".utils.FileContentProvider"
        android:authorities="com.emrick.dj"
        android:exported="true" />

Media3图书馆作者建议支持该服务中的两个动作,以供遗产和新的浏览器支持:
java media-player android-auto
1个回答
0
投票

You didn't post it, but assuming your automotive_app_desc.xml file contains

<?xml version="1.0" encoding="utf-8" ?>
<automotiveAPP>
    <uses name="media" />
</automotiveAPP>

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.