Próbuję wysłać informacje o trasie przez A2DP/AVRCP. Obecnie muzyka jest idealnie przesyłana strumieniowo, ale w "odbiorniku" (np. Car audio) "ekran informacji o utworach" jest pusty (co nie ma miejsca w przypadku popularnych odtwarzaczy). Każdy pomysł?wysyłaj informacje o utworach przez A2DP/AVRCP
Odpowiedz
Ten kod pracował dla mnie:
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);
}
połączeń bluetoothNotifyChange z odpowiednią intencją (zdefiniowany powyżej) W zależności od stanu odtwarzania: pauza/odtwarzanie/metadata zmieniło.
Aby wysłać metadane ścieżki do radioodtwarzacza, należy wysłać intencję.
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);
Po zakończeniu utworu wyślij inną intencję z pustymi ciągami dla drugiego parametru metody putExtra.
Chociaż ja nie znalazłem innego sposobu, aby to zrobić. Wydaje się, że to podejście hackowskie. Wygląda na to, że polegasz na aplikacji muzycznej Google do obsługi tego zamiaru. W jaki sposób działa aplikacja muzyczna Google? –
Rzeczywiście. Czy jest możliwe, że muzyka google jest jedyną, która może korzystać z avrcp? Wszystkie aplikacje powinny mieć taką możliwość za pośrednictwem prawa RemoteControlClient? –
Zajęło mi to na zawsze zrozumienie. Po prostu transmisja intencji nie zadziałała. Mam AVRCP pracować wysyłając intencję I wykonawczych RemoteControlClient
Oto kod użyłem:
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();
}
można wyjaśnić wiersz 'NazwaKomponentu rec = nowa nazwa komponentu (getPackageName(), MyReceiver.class.getName());' – Distwo
Tak wyglądasz BroadcastReceiver za pomocą refleksji ... –
Próbowałem kodu, który rzeczywiście jest zgodny z tym, co możemy znaleźć na https://android.googlesource.com/platform/packages/apps/Music/+/android -5.1.1_r13/src/com/android/music/MediaPlaybackService.java, ale to nie działa. Czy to możliwe, ponieważ mamy do czynienia z AudioManager.AUDIOFOCUS? –
Jeśli chcesz tylko do wysyłania informacji metadanych z telefonu do podłączonego AVRCP kompatybilne urządzenia audio Bluetooth i DO NOT chcesz w ogóle kontrolować swoją aplikację z urządzenia bluetooth, kod może być poniżej przydatny. I istnieje NO potrzeba zaimplementować i zarejestrować MediaButtonEventReceiver z AudioManager.
Zawarłem również kod wersji API 21 (LOLLIPOP, 5.0). Od API 21 użycie RemoteControlClient jest przestarzałe i zachęca się do korzystania z MediaSession.
Init faza:
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);
}
}
Sposób przesyłania informacji metadanych piosenka AVRCP Bluetooth kompatybilne urządzenia audio:
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);
}
}
zadzwonić, jeśli zmiany metadanych, ale sprawdzić, czy mamy połączenie A2DP do Bluetooth Audio urządzenie. Nie ma potrzeby wysyłania informacji metadanych, jeśli nie są podłączone:
if (mAudioManager.isBluetoothA2dpOn()) {
Log.d("AudioManager", "isBluetoothA2dpOn() = true");
onTrackChanged(getTitle(), getArtist(), getAlbum(), getDuration(), getCurrentPosition(), getId());
}
Clean up na zniszczenie:
@Override
public void onDestroy() {
super.onDestroy();
[..]
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
mAudioManager.unregisterRemoteControlClient(mRemoteControlClient);
} else {
mMediaSession.release();
}
}
This jak to wygląda na mojego radia samochodowego
Co powiesz na tryb powtarzania losowego? czy ty też sobie z tym poradziłeś? dzięki – issamux
@issamux Spójrz na to http://stackoverflow.com/questions/31194180/how-do-i-make-shuffle-playlist-button-and-repeat-button-in-android-studio –
Nie trzeba kontrolować SDK_INT, jeśli używasz wersji Compat. Poniżej kod testowany z wieloma samochodowymi urządzeniami bluetooth i działa jak urok. Niektóre urządzenia nie rozumieją niektórych KLUCZY, więc lepiej użyć KEY. Reference. Nie zapomnij.budować() po putBitmap nie przed
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. Informacje o mechanizmach debugowania używanych przez debugger
- 2. Wysyłaj pliki przez PSSession
- 3. Wysyłaj ramkę wideo przez gniazdo
- 4. Informacje o oddziałach OCaml
- 5. Informacje o wyjątku: System.Reflection.TargetInvocationException
- 6. Informacje o procesie NODEJS
- 7. Wysyłaj do github przez wiersz poleceń (Windows)
- 8. Dlaczego informacje o identyfikatorze openID nie są przekazywane przez protokół?
- 9. Wysyłaj dane JSON przez formularz w MVC4
- 10. Wysyłaj HTML w e-mailu przez PHP?
- 11. Wysyłaj sms przez AT Polecenie działa dziwnie
- 12. Informacje o urządzeniu z Androidem
- 13. Drupal uzyskać informacje o module?
- 14. Jak sortować informacje o wersji
- 15. AssemblyInfo informacje o wersji gwiazdkami
- 16. informacje o identyfikatorze procesu log4net
- 17. Noś informacje o poprzednich obliczeniach
- 18. Informacje o trybie androidowym "singleTask"
- 19. km0ae9gr6m Informacje o wtrysku js
- 20. Informacje o rozszerzeniu pliku .MI?
- 21. Otrzymuj bieżące informacje o lokalizacji
- 22. maven build - informacje o wersji
- 23. Netbeans/Ruby - zewnętrzne (?) Informacje o autouzupełnianiu
- 24. Informacje o używaniu quada w MATLAB
- 25. Informacje o nagłówku obwiedni Axis2 SOAP
- 26. Trwałe informacje o zabezpieczeniach w .Net 4
- 27. Zapytanie SQL o informacje dotyczące kolumny misc
- 28. Uzyskaj informacje o sprzęcie w systemie Android?
- 29. Uzyskaj informacje o żądaniu w widoku pomocnika
Ten kod działa dla mnie przy użyciu zestawu słuchawkowego Bluetooth, ale wyświetla tylko nazwę utworu ... Przetestuje więcej. Dzięki. – DavyJonesUA
Ten kod nie działa dla mnie na słuchawkach Sony, ale aplikacja Muzyka Google wciąż może wyświetlać informacje o utworach na tym zestawie słuchawkowym. – Wayne
Czy możesz podać przykładowy link z dostępnymi metadanymi? – Wayne