我试图通过A2DP / AVRCP发送跟踪信息。 眼下,音乐是完全流,但在“接收器”(即:汽车音响),在“轨道信息屏幕”为空白(这是没有使用流行的球员那里的情况下)。 任何的想法 ?
Answer 1:
此代码为我工作:
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);
}
暂停/播放/元数据改变:与这取决于您的播放状态相应的意图(如上定义)调用bluetoothNotifyChange。
Answer 2:
如果你只是想从你的手机发送的元数据信息的连接AVRCP音频兼容的蓝牙设备, 不希望在所有从蓝牙设备来控制你的应用程序,你会发现下面的有用的代码。 而且也没有必要实施并注册AudioManager一个MediaButtonEventReceiver。
我还包括用于API版本21(棒棒糖,5.0)的代码。 从API的RemoteControlClient 21用法已过时,并且使用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);
}
}
发送歌曲的元数据信息,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);
}
}
如果调用元数据的变化,但是否我们有A2DP连接到音频蓝牙设备。 不需要发送,如果我们没有连接的元数据信息:
if (mAudioManager.isBluetoothA2dpOn()) {
Log.d("AudioManager", "isBluetoothA2dpOn() = true");
onTrackChanged(getTitle(), getArtist(), getAlbum(), getDuration(), getCurrentPosition(), getId());
}
清理的破坏:
@Override
public void onDestroy() {
super.onDestroy();
[..]
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
mAudioManager.unregisterRemoteControlClient(mRemoteControlClient);
} else {
mMediaSession.release();
}
}
这是怎么看起来像我的汽车音响
Answer 3:
这花了我永远搞清楚。 只是广播的意图没有工作。 我AVRCP通过发送意图和实施工作RemoteControlClient
下面是我使用的代码:
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();
}
Answer 4:
要发送的轨道元数据需要发送的意图音响主机。
Intent avrcp = new Intent("com.android.music.metachanged");
avrcp.putExtra("track", "song title");
avrcp.putExtra("artist", "artist name");
avrcp.putExtra("album", "album name");
Context.sendBroadcast(avrcp);
当歌曲播放完毕再派意图与该putExtra方法的第二个参数空字符串。
Answer 5:
你并不需要,如果你正在使用的组件的版本COMPAT控制SDK_INT。 下面的代码与许多车载蓝牙设备测试和工程般的魅力。 有些设备不理解一些键,以便其更好地使用可能的密钥。 参考 。 不要在此之前忘记.build()putBitmap后
public static void sendTrackInfo() {
if(audioManager == null) {
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
}
if (mMediaSession == null) {
mMediaSession = new MediaSessionCompat(this, "PlayerServiceMediaSession");
mMediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
mMediaSession.setActive(true);
}
if (audioManager.isBluetoothA2dpOn()) {
try {
String songTitle = getTitle();
String artistTitle = getArtist();
String radioImageUri = getImagesArr().get(0);
String songImageUri = getImagesArr().get(1);
long duration = getDuration();
final MediaMetadataCompat.Builder metadata = new MediaMetadataCompat.Builder();
metadata.putString(MediaMetadataCompat.METADATA_KEY_TITLE, songTitle);
metadata.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, songTitle);
metadata.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, artistTitle);
metadata.putString(MediaMetadataCompat.METADATA_KEY_ALBUM_ARTIST, artistTitle);
metadata.putString(MediaMetadataCompat.METADATA_KEY_ART_URI, radioImageUri);
metadata.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON_URI, radioImageUri);
metadata.putString(MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI, songImageUri);
metadata.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, duration);
imageCounter = 0;
Glide.with(act)
.load(Uri.parse(radioImageUri))
.asBitmap()
.into(new SimpleTarget<Bitmap>(250, 250) {
@Override
public void onResourceReady(Bitmap bitmap, GlideAnimation anim) {
metadata.putBitmap(MediaMetadataCompat.METADATA_KEY_ART, bitmap);
metadata.putBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON, bitmap);
imageCounter = imageCounter + 1;
if(imageCounter == 2) {
mMediaSession.setMetadata(metadata.build());
}
}
});
Glide.with(act)
.load(Uri.parse(songImageUri))
.asBitmap()
.into(new SimpleTarget<Bitmap>(250, 250) {
@Override
public void onResourceReady(Bitmap bitmap, GlideAnimation anim) {
metadata.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, bitmap);
imageCounter = imageCounter + 1;
if(imageCounter == 2) {
mMediaSession.setMetadata(metadata.build());
}
}
});
}
catch (JSONException e) {
e.printStackTrace();
}
}
}
文章来源: send track informations via A2DP/AVRCP