我試圖通過A2DP/AVRCP發送曲目信息。現在,音樂完美流暢,但在「接收器」(即:汽車音響)上,「軌道信息屏幕」是空白的(這不是使用流行的播放器的情況)。 有什麼想法?通過A2DP/AVRCP發送曲目信息
回答
此代碼爲我工作:
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與根據您的播放狀態相應的意圖(如上定義):暫停/播放/元數據改變。
要將軌道元數據發送到headunit,您需要發送一個intent。
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方法的第二個參數。
之前,雖然我還沒有找到另一種方式來做到這一點。這似乎是一個駭人聽聞的方法。它看起來像你依靠谷歌音樂應用來處理這個意圖。谷歌音樂應用如何做到這一點? – 2013-07-29 15:46:36
確實。谷歌音樂可能是唯一可以使用avrcp的音樂嗎?所有的應用程序都應該通過RemoteControlClient來實現這個功能嗎? – 2014-01-20 21:18:23
這花了我一直想弄清楚。只是傳播意圖沒有奏效。我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();
}
你可以解釋一下這一行:ComponentName rec = new ComponentName(getPackageName(),MyReceiver.class.getName());' – Distwo 2015-06-17 18:09:51
這就是你如何使用反射來查看BroadcastReceiver ... – 2015-07-28 21:56:09
我試過你的代碼,它確實符合我們在https://android.googlesource.com/platform/packages/apps/Music/+/android -5.1.1_r13/src/com/android/music/MediaPlaybackService.java,但這不起作用。 難道是因爲我們必須處理AudioManager.AUDIOFOCUS? – 2015-08-30 14:03:43
如果你只是想從你的手機發送的元數據信息,以連接AVRCP兼容的音頻藍牙設備和不要想從藍牙設備控制你的應用程序,你可能會發現下面的代碼有用。 有沒有需要實現和註冊與AudioManager的MediaButtonEventReceiver。
我還包含API版本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);
}
}
發送歌曲的元數據信息,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();
}
}
This是如何看起來像我的汽車音響
洗牌重複模式呢?你也處理過這個嗎?謝謝 – issamux 2016-06-03 20:25:36
@issamux看看這一個http://stackoverflow.com/questions/31194180/how-do-i-make-shuffle-playlist-button-and-repeat-button-in-android-studio – 2016-07-09 20:10:48
你不需要如果您使用Compat版本的組件,可以控制SDK_INT。 下面的代碼測試了很多車載藍牙設備,並且像魅力一樣工作。 有些設備不理解某些KEY,因此最好使用可能的KEY。 Reference。別忘了。建立()後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();
}
}
}
- 1. 通過spotify發送歌曲信息
- 2. 通過API發送信息
- 3. 我想通過通知發送信息
- 4. JAVA通過json發送/接收信息
- 5. 通過網絡發送信息
- 6. 通過藍牙發送一些信息
- 7. 通過JavaScript發送Facebook聊天信息
- 8. 通過for循環發送信息
- 9. 通過Javascript發送有效信息
- 10. 通過AJAX發送登錄信息
- 11. Quickbooks Desktop通過REST API發送信息
- 12. 通過PHP頁面發送信息
- 13. 通過網絡發送基本信息
- 14. 通過Html將信息發送到IP
- 15. 通過Android獲取歌曲信息
- 16. 通過彩信發送gif
- 17. 通過PHP發送短信
- 18. 發送短信通過.net
- 19. 通過IP發送短信
- 20. 通過NFC發送短信
- 21. 通過SMPP發送短信
- 22. 通過Android 2.3.3讀取PayWave(ISO14443-B格式)曲目信息NFC
- 23. Android:通過短信發送網絡信息
- 24. 通過HTTPS發送消息
- 25. 通過SIP發送消息
- 26. 通過SuperSocket發送消息
- 27. 通過URL發送消息
- 28. 使用作曲者通過twilio發送消息
- 29. 截取通過未加密通道發送的信息
- 30. Java通過通信/串行端口發送消息
此代碼適用於我的藍牙耳機,但只顯示曲目名稱...將測試更多。謝謝。 – DavyJonesUA 2013-07-22 13:23:46
此代碼在Sony耳機上不適用於我,但Google音樂應用程序仍然可以在該耳機上顯示歌曲信息。 – Wayne 2013-08-20 03:29:23
你可以給我一個帶有元數據的示例鏈接嗎? – Wayne 2013-08-20 06:30:30