send track informations via A2DP/AVRCP

前端 未结 5 875
北海茫月
北海茫月 2020-12-04 11:46

I\'m trying to send track informations via A2DP/AVRCP. Right now, music is perfectly streamed, but on the \"receiver\" (ie: car audio), the \"track informations screen\" is

5条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-04 12:04

    If you just want to send metadata information from your phone to a connected AVRCP compatible audio bluetooth device and DON'T want to control your app from the bluetooth device at all, you may find the code below usefull. And there is NO need to implement and register a MediaButtonEventReceiver with AudioManager.

    I also included code for API Version 21 (LOLLIPOP, 5.0). From API 21 usage of the RemoteControlClient is deprecated and usage of MediaSession is encouraged.

    Init phase:

        if (mAudioManager == null) {
            mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        }
    
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            if (mRemoteControlClient == null) {
                Log.d("init()", "API " + Build.VERSION.SDK_INT + " lower then " + Build.VERSION_CODES.LOLLIPOP);
                Log.d("init()", "Using RemoteControlClient API.");
    
                mRemoteControlClient = new RemoteControlClient(PendingIntent.getBroadcast(this, 0, new Intent(Intent.ACTION_MEDIA_BUTTON), 0));
                mAudioManager.registerRemoteControlClient(mRemoteControlClient);
            }
        } else {
            if (mMediaSession == null) {
                Log.d("init()", "API " + Build.VERSION.SDK_INT + " greater or equals " + Build.VERSION_CODES.LOLLIPOP);
                Log.d("init()", "Using MediaSession API.");
    
                mMediaSession = new MediaSession(this, "PlayerServiceMediaSession");
                mMediaSession.setFlags(MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);
                mMediaSession.setActive(true);
    
            }
        }
    

    Method for sending song metadata information to AVRCP compatible bluetooth audio device:

    private void onTrackChanged(String title, String artist, String album, long duration, long position, long trackNumber) {
    
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
    
            RemoteControlClient.MetadataEditor ed = mRemoteControlClient.editMetadata(true);
            ed.putString(MediaMetadataRetriever.METADATA_KEY_TITLE, title);
            ed.putString(MediaMetadataRetriever.METADATA_KEY_ARTIST, artist);
            ed.putString(MediaMetadataRetriever.METADATA_KEY_ALBUM, album);
            ed.putLong(MediaMetadataRetriever.METADATA_KEY_DURATION, duration);
            ed.putLong(MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER, trackNumber);
            ed.apply();
    
            mRemoteControlClient.setPlaybackState(RemoteControlClient.PLAYSTATE_PLAYING, position, 1.0f);
        } else {
    
            MediaMetadata metadata = new MediaMetadata.Builder()
                    .putString(MediaMetadata.METADATA_KEY_TITLE, title)
                    .putString(MediaMetadata.METADATA_KEY_ARTIST, artist)
                    .putString(MediaMetadata.METADATA_KEY_ALBUM, album)
                    .putLong(MediaMetadata.METADATA_KEY_DURATION, duration)
                    .putLong(MediaMetadata.METADATA_KEY_TRACK_NUMBER, trackNumber)
                    .build();
    
            mMediaSession.setMetadata(metadata);
    
            PlaybackState state = new PlaybackState.Builder()
                    .setActions(PlaybackState.ACTION_PLAY)
                    .setState(PlaybackState.STATE_PLAYING, position, 1.0f, SystemClock.elapsedRealtime())
                    .build();
    
            mMediaSession.setPlaybackState(state);
        }
    }
    

    Call if metadata changes but check if we have a A2DP connection to an audio bluetooth device. No need to send metadata information if we are not connected:

    if (mAudioManager.isBluetoothA2dpOn()) {
        Log.d("AudioManager", "isBluetoothA2dpOn() = true");
        onTrackChanged(getTitle(), getArtist(), getAlbum(), getDuration(), getCurrentPosition(), getId());
    }
    

    Clean up on destroy:

    @Override
    public void onDestroy() {
        super.onDestroy();
    
    [..]    
    
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            mAudioManager.unregisterRemoteControlClient(mRemoteControlClient);
        } else {
            mMediaSession.release();
        }
    }
    

    This is how it looks like on my car stereo

提交回复
热议问题