Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Enviar información de las pistas a través de A2DP / AVRCP

Estoy tratando de enviar información de las pistas a través de A2DP / AVRCP. En este momento, la música está perfectamente fluida, pero en el "receptor" (es decir: audio del coche), la "pantalla de información de la pista" está en blanco (que no es el caso con los jugadores populares que hay). Alguna idea ?

  • Configuración de un servidor pc bluetooth para android
  • Android Bluetooth status 133 en onCharacteristicwrite
  • Códigos de ejemplo para Android Programación Bluetooth
  • Cómo activar / desactivar el bluetooth mediante programación en android
  • Lista de dispositivos bluetooth conectados?
  • Conector de Bluetooth
  • Sniffing / registro de su propio tráfico Bluetooth de Android
  • El bluetooth androide no puede conectarse
  • 5 Solutions collect form web for “Enviar información de las pistas a través de A2DP / AVRCP”

    Este código funcionó para mí:

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

    Llame a bluetoothNotifyChange con la intención apropiada (definida anteriormente) dependiendo del estado de reproducción: se ha cambiado la pausa / reproducción / los metadatos.

    Si sólo desea enviar información de metadatos desde su teléfono a un dispositivo Bluetooth de audio compatible con AVRCP conectado y NO desea controlar su aplicación desde el dispositivo Bluetooth en absoluto, puede encontrar el código siguiente útil. Y no hay necesidad de implementar y registrar un MediaButtonEventReceiver con AudioManager.

    También incluí código para API Versión 21 (LOLLIPOP, 5.0). Desde API 21, el uso de RemoteControlClient está desaconsejado y se recomienda el uso de MediaSession .

    Fase inicial:

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

    Método para enviar información de metadatos de canción a un dispositivo de audio bluetooth compatible con 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); } } 

    Llame si cambia los metadatos, pero compruebe si tenemos una conexión A2DP a un dispositivo Bluetooth de audio. No es necesario enviar información de metadatos si no estamos conectados:

     if (mAudioManager.isBluetoothA2dpOn()) { Log.d("AudioManager", "isBluetoothA2dpOn() = true"); onTrackChanged(getTitle(), getArtist(), getAlbum(), getDuration(), getCurrentPosition(), getId()); } 

    Limpiar en destruir:

     @Override public void onDestroy() { super.onDestroy(); [..] if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { mAudioManager.unregisterRemoteControlClient(mRemoteControlClient); } else { mMediaSession.release(); } } 

    Así es como se ve en mi estéreo de coche

    Esto me llevó una eternidad a averiguar. Sólo la difusión de la intención no funcionó. Conseguí AVRCP para trabajar enviando la intención E implementando RemoteControlClient

    Aquí está el código que usé:

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

    Para enviar los metadatos de la pista a la unidad central, debe enviar una intención.

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

    Cuando se completa la canción, envía otra intención con cadenas vacías para el segundo parámetro del método putExtra.

    No necesita controlar SDK_INT si está utilizando la versión Compat de los componentes. Debajo del código probado con muchos dispositivos Bluetooth del coche y funciona como el encanto. Algunos dispositivos no entienden algunas CLAVES, por lo que es mejor utilizar la clave posible. Referencia . No se olvide de .build () después de putBitmap no antes

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

    }

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.