通过A2DP/AVRCP发送跟踪信息

elg*_*gui 26 android bluetooth avrcp a2dp

我正在尝试通过A2DP/AVRCP发送跟踪信息.现在,音乐完全流式传输,但在"接收器"(即:汽车音频)上,"音轨信息屏幕"是空白的(在那里使用流行的播放器不是这种情况).任何的想法 ?

Wil*_*ann 20

这段代码对我有用:

private static final String AVRCP_PLAYSTATE_CHANGED = "com.android.music.playstatechanged";
private static final String AVRCP_META_CHANGED = "com.android.music.metachanged";

private void bluetoothNotifyChange(String what) {
    Intent i = new Intent(what);
    i.putExtra("id", Long.valueOf(getAudioId()));
    i.putExtra("artist", getArtistName());
    i.putExtra("album",getAlbumName());
    i.putExtra("track", getTrackName());
    i.putExtra("playing", isPlaying());        
    i.putExtra("ListSize", getQueue());
    i.putExtra("duration", duration());
    i.putExtra("position", position());
    sendBroadcast(i);
}
Run Code Online (Sandbox Code Playgroud)

根据您的播放状态,使用适当的意图(如上所述)调用bluetoothNotifyChange:暂停/播放/元数据已更改.


小智 14

如果你只是想从你的手机发送的元数据信息的连接AVRCP兼容的音频蓝牙设备和不要想在所有的蓝牙设备控制应用程式,您可以在下面找到有用的代码.而且有需要落实并注册AudioManager一个MediaButtonEventReceiver.

我还包括了API Version 21(LOLLIPOP,5.0)的代码.从API 21开始,不推荐使用RemoteControlClient,并鼓励使用MediaSession.

初始阶段:

    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);

        }
    }
Run Code Online (Sandbox Code Playgroud)

将歌曲元数据信息发送到AVRCP兼容蓝牙音频设备的方法:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果元数据发生变化则调用,但检查我们是否与音频蓝牙设备建立了A2DP连接.如果我们没有连接,则无需发送元数据信息:

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

清理破坏:

@Override
public void onDestroy() {
    super.onDestroy();

[..]    

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
        mAudioManager.unregisterRemoteControlClient(mRemoteControlClient);
    } else {
        mMediaSession.release();
    }
}
Run Code Online (Sandbox Code Playgroud)

就是我的汽车音响的样子


Jam*_*ang 6

这让我永远想通了.只是广播意图不起作用.我通过发送intent 实现RemoteControlClient来使AVRCP工作

这是我使用的代码:

public void onCreate(){
    super.onCreate();

    mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
    ComponentName rec = new ComponentName(getPackageName(), MyReceiver.class.getName());
    mAudioManager.registerMediaButtonEventReceiver(rec);

    Intent i = new Intent(Intent.ACTION_MEDIA_BUTTON);
    i.setComponent(rec);
    PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
    mRemoteControlClient = new RemoteControlClient(pi);
    mAudioManager.registerRemoteControlClient(mRemoteControlClient);

    int flags = RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS
            | RemoteControlClient.FLAG_KEY_MEDIA_NEXT
            | RemoteControlClient.FLAG_KEY_MEDIA_PLAY
            | RemoteControlClient.FLAG_KEY_MEDIA_PAUSE
            | RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE
            | RemoteControlClient.FLAG_KEY_MEDIA_STOP
            | RemoteControlClient.FLAG_KEY_MEDIA_FAST_FORWARD
            | RemoteControlClient.FLAG_KEY_MEDIA_REWIND;
    mRemoteControlClient.setTransportControlFlags(flags);
}

private void onTrackChanged(...) {
    String title = ...;
    String artist = ...;
    String album = ...;
    long duration = ...;

    Intent i = new Intent("com.android.music.metachanged");
    i.putExtra("id", 1);
    i.putExtra("track", title);
    i.putExtra("artist", artist);
    i.putExtra("album", album);
    i.putExtra("playing", "true");
    sendStickyBroadcast(i);

    RemoteControlClient.MetadataEditor ed = mRemoteControlClient.editMetadata(true);
    ed.putString(MediaMetadataRetriever.METADATA_KEY_TITLE, title);
    ed.putString(MediaMetadataRetriever.METADATA_KEY_ALBUM, album);
    ed.putString(MediaMetadataRetriever.METADATA_KEY_ARTIST, artist);
    ed.putLong(MediaMetadataRetriever.METADATA_KEY_DURATION, track.getDuration());
    ed.apply();
}

public void onDestroy(){
    mAudioManager.unregisterRemoteControlClient(mRemoteControlClient);
    super.onDestroy();
}
Run Code Online (Sandbox Code Playgroud)