web-dev-qa-db-fra.com

envoyer les informations de piste via A2DP/AVRCP

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

24
elgui

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.

19
William Seemann

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();
}
6
James Zhang

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.

1
Bill D

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

}

0
OMArikan