J'essaie d'envoyer des informations de piste via A2DP/AVRCP. Pour le moment, la musique est parfaitement diffusée en continu, mais sur le "récepteur" (audio de la voiture, par exemple), "l'écran d'informations sur la piste" est vide (ce qui n'est pas le cas avec les lecteurs les plus populaires) .
Ce code a fonctionné pour moi:
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);
}
Appelez bluetoothNotifyChange avec l'intention appropriée (définie ci-dessus) en fonction de votre statut de lecture: pause/lecture/métadonnées modifiées.
Cela m'a pris pour toujours à comprendre. Diffuser simplement l'intention n'a pas fonctionné. AVRCP fonctionne en envoyant l'intention ET à l'aide de RemoteControlClient
Voici le code que j'ai utilisé:
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();
}
Pour envoyer les métadonnées de la piste à l'unité principale, vous devez envoyer une intention.
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);
Lorsque la chanson est terminée, envoyez une autre intention avec des chaînes vides pour le second paramètre de la méthode putExtra.
Vous n'avez pas besoin de contrôler SDK_INT si vous utilisez la version Compat des composants . Le code ci-dessous a été testé avec de nombreux périphériques Bluetooth pour voiture et fonctionne comme un charme . Certains périphériques ne comprennent pas certaines clés et il est donc préférable d'utiliser CLÉ. Référence . N'oubliez pas de .build () après putBitmap pas avant
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();
}
}
}