Android Auto: мое приложение не воспроизводит звук

Я реализую поддержку Android Auto для своего приложения, но оно работает неправильно. Я следил за документацией Google и некоторыми учебными пособиями, но звук не работает. Элементы управления, обложка альбома, имя исполнителя и т. д. отображаются просто отлично.

Странное поведение: после запуска приложения Spotify через эмулятор Auto и воспроизведения песни, если я захожу в свое приложение и пытаюсь воспроизвести звук, все работает!

Вот класс обслуживания, который я реализовал:

/**
 * Created by FelipeRRM on 8/13/2016.
 */
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class AutoMediaBrowserService extends MediaBrowserServiceCompat {

    private static final String CURRENT_MEDIA_POSITION = "media_position_key";
    private static final int PLAY = 1;
    private static final int PAUSE = 2;
    private static final int BUFFERING = 3;
    private static final int CONNECTING = 4;
    private static final int STOPPED = 5;
    MediaPlayer mediaPlayer;

    private static final String MY_MEDIA_ROOT_ID = "meuiddaraiz";
    MediaSessionCompat mSession;

    @Override
    public void onCreate() {
        super.onCreate();
        mSession = new MediaSessionCompat(this, "session tag");
        setSessionToken(mSession.getSessionToken());

        // Set a callback object to handle play control requests, which
        // implements MediaSession.Callback
        mSession.setCallback(new MediaSessionCompat.Callback() {
            @Override
            public void onPlay() {
                super.onPlay();
                playMedia( PreferenceManager.getDefaultSharedPreferences( getApplicationContext() ).getInt( CURRENT_MEDIA_POSITION, 0 ), null );
            }

            //This is called when the pause button is pressed, or when onPlayFromMediaId is called in
            //order to pause any currently playing media
            @Override
            public void onPause() {
                super.onPause();
               setMediaPlaybackState(PAUSE);
                pauseMedia();
            }

            @Override
            public void onStop() {
                super.onStop();
                setMediaPlaybackState(STOPPED);
                if( mediaPlayer != null ) {
                    pauseMedia();
                    mediaPlayer.release();
                    PreferenceManager.getDefaultSharedPreferences(AutoMediaBrowserService.this).edit().putInt( CURRENT_MEDIA_POSITION,
                            0 ).commit();
                }
            }

            @Override
            public void onPlayFromMediaId(String mediaId, Bundle extras) {
                super.onPlayFromMediaId(mediaId, extras);
                mSession.setMetadata(new MediaMetadataCompat.Builder()
                        .putText(MediaMetadataCompat.METADATA_KEY_TITLE, "primeira musica")
                        .putText(MediaMetadataCompat.METADATA_KEY_ARTIST, "Joãozinho das Rezas")
                        .putText(MediaMetadataCompat.METADATA_KEY_GENRE, "Gospel")
                        .putText(MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI, "http://70.38.6.72/~vivafe/web/wp-content/uploads/2016/08/01.jpg")
                        .build()
                );
                playMedia(0, mediaId);
            }



            @Override
            public void onPlayFromSearch(String query, Bundle extras) {
                super.onPlayFromSearch(query, extras);
            }

        });

        mSession.setActive(true);
    }

    private void setMediaPlaybackState( int state ) {
        PlaybackStateCompat playbackState = null;
        switch (state) {
            case PLAY:
            playbackState = new PlaybackStateCompat.Builder()
                    .setActions( PlaybackStateCompat.ACTION_PLAY_PAUSE | PlaybackStateCompat.ACTION_SKIP_TO_NEXT | PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS )
                    .setState( PlaybackStateCompat.STATE_PLAYING, 0, 1 )
                    .build();
                break;

            case PAUSE:
            playbackState = new PlaybackStateCompat.Builder()
                    .setActions( PlaybackStateCompat.ACTION_PLAY_PAUSE )
                    .setState(PlaybackStateCompat.STATE_PAUSED, 0, 1)
                    .build();
                break;

            case BUFFERING:
                playbackState = new PlaybackStateCompat.Builder()
                        .setActions( PlaybackStateCompat.ACTION_STOP )
                        .setState(PlaybackStateCompat.STATE_BUFFERING, 0, 1)
                        .build();
                break;

            case CONNECTING:
                playbackState = new PlaybackStateCompat.Builder()
                        .setActions( PlaybackStateCompat.ACTION_STOP )
                        .setState(PlaybackStateCompat.STATE_CONNECTING, 0, 1)
                        .build();
                break;

            case STOPPED:
                playbackState = new PlaybackStateCompat.Builder()
                        .setActions( PlaybackStateCompat.ACTION_PLAY_FROM_MEDIA_ID )
                        .setState(PlaybackStateCompat.STATE_STOPPED, 0, 1)
                        .build();
                break;
        }
        mSession.setPlaybackState( playbackState );
    }

    private void playMedia(final int position, String id ) {
        setMediaPlaybackState(BUFFERING);
        if( mediaPlayer != null )
            try {
                mediaPlayer.reset();
            }
            catch (Exception e){
                mediaPlayer = new MediaPlayer();
                e.printStackTrace();
            }
        else
            mediaPlayer = new MediaPlayer();
        try {
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mediaPlayer.setDataSource("http://70.38.6.72/~vivafe/web/wp-content/uploads/2016/08/Mateus-01.mp3");
            mediaPlayer.prepareAsync();
        }
        catch (Exception e){
            e.printStackTrace();
        }
        mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mediaPlayer) {
                mediaPlayer.start();
                if( position > 0 )
                    mediaPlayer.seekTo( position );
                setMediaPlaybackState(PLAY);
            }
        });

        mediaPlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {
            @Override
            public boolean onInfo(MediaPlayer mediaPlayer, int state, int extra) {
                switch (state){
                    case MediaPlayer.MEDIA_INFO_BUFFERING_START:{
                        Log.d("MediaPlayer","StartBuffer");
                        setMediaPlaybackState(BUFFERING);
                        break;
                    }

                    case MediaPlayer.MEDIA_INFO_BUFFERING_END:{
                        Log.d("MediaPlayer","EndBuffer");
                        setMediaPlaybackState(PLAY);
                    }
                }
                return true;
            }
        });

        mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
            @Override
            public boolean onError(MediaPlayer mediaPlayer, int state, int extra) {
                Log.e("MediaPlayer Error", String.valueOf(state));
                return false;
            }
        });

    }

    private void pauseMedia() {
        if( mediaPlayer != null ) {
            mediaPlayer.pause();
            PreferenceManager.getDefaultSharedPreferences( this ).edit().putInt( CURRENT_MEDIA_POSITION,
                    mediaPlayer.getCurrentPosition() ).commit();
        }
    }


    @Nullable
    @Override
    public BrowserRoot onGetRoot(String s, int i, Bundle bundle) {
        return new BrowserRoot(MY_MEDIA_ROOT_ID, null);
    }

    @Override
    public void onLoadChildren(@NonNull String parentId, @NonNull Result<List<MediaBrowserCompat.MediaItem>> result) {
        List<MediaBrowserCompat.MediaItem> mediaItems = new ArrayList<>();
        // Check if this is the root menu:

        if (parentId.equals(MY_MEDIA_ROOT_ID)) {
            mediaItems.add(new MediaBrowserCompat.MediaItem(new MediaDescriptionCompat.Builder().setMediaId("iddopastor").setTitle("Pastor").build(), MediaBrowserCompat.MediaItem.FLAG_BROWSABLE));
        } else if (parentId.equals("iddopastor")) {
            mediaItems.add(new MediaBrowserCompat.MediaItem(new MediaDescriptionCompat.Builder().setMediaId("iddopastor2").setTitle("Pastor 2").build(), MediaBrowserCompat.MediaItem.FLAG_BROWSABLE));

            // examine the passed parentMediaId to see which submenu we're at,
            // and put the children of that menu in the mediaItems list
        }
        else if(parentId.equals("iddopastor2")){
            mediaItems.add(new MediaBrowserCompat.MediaItem(new MediaDescriptionCompat.Builder().setMediaId("genealogia")
                    .setTitle("Tomé filho de José")
                    .setMediaUri(Uri.parse("http://70.38.6.72/~vivafe/web/wp-content/uploads/2016/08/Mateus-01.mp3"))
                    .setIconUri(Uri.parse("http://70.38.6.72/~vivafe/web/wp-content/uploads/2016/08/01.jpg"))
                    .build(), MediaBrowserCompat.MediaItem.FLAG_PLAYABLE));
        }
        result.sendResult(mediaItems);

    }

    @Override
    public void onDestroy() {
        mSession.release();
        if( mediaPlayer != null ) {
            pauseMedia();
            mediaPlayer.release();
            PreferenceManager.getDefaultSharedPreferences( this ).edit().putInt( CURRENT_MEDIA_POSITION,
                    0 ).commit();
        }
        super.onDestroy();
    }
}

Извините за длинный код, но ошибка может быть где угодно в этом классе!

Я также поместил это в свой AndroidManifest.xml:

<meta-data android:name="com.google.android.gms.car.application"
        android:resource="@xml/automotive_app_desc"/>

<meta-data android:name="com.google.android.gms.car.notification.SmallIcon"
        android:resource="@drawable/ic_notification" />

<service android:name=".Auto.AutoMediaBrowserService"
        android:exported="true">
        <intent-filter>
            <action android:name=
                "android.media.browse.MediaBrowserService"/>
        </intent-filter>
    </service>

И у меня есть это в моем файле res\xml\automotive_app_desc.xml:

<automotiveApp>
<uses name="media" />
</automotiveApp>

person Felipe Ribeiro R. Magalhaes    schedule 23.08.2016    source источник
comment
В последнее время при воспроизведении звука в эмуляторе возникают ошибки, иногда он отключается, у меня были такие же проблемы, это не ваш код.   -  person ShadowGod    schedule 24.08.2016
comment
@ShadowGod, почему приложение Spotify безупречно работает в эмуляторе? Это так странно... Кажется, что я не запускаю или инициализирую что-то, что должен, потому что, когда я перехожу из приложения Spotify в мое, оно работает, иначе звук никогда не будет воспроизводиться!   -  person Felipe Ribeiro R. Magalhaes    schedule 24.08.2016
comment
Можете ли вы попробовать это на реальном устройстве? Я думаю, это будет сложно, если у вас нет машины с Android Auto, лол, я даже не знаю, сможете ли вы это сделать ... в любом случае, все, что я могу сказать, это то, что у меня были проблемы с эмулятором. на реальном устройстве (телефоне) все было в порядке ... Кроме того, как и во всех приложениях для воспроизведения аудио, убедитесь, что вы следуете правилам фокусировки звука: developer.android.com/training/managing-audio/audio-focus.html .. кроме этого, вам понадобится кто-то более продвинутый, чем я, чтобы просмотри код, ничего не выделяется как ошибка   -  person ShadowGod    schedule 24.08.2016
comment
@ShadowGod, к сожалению, у меня здесь нет настоящего устройства Android Auto. Попробую сделать аудиофокус!   -  person Felipe Ribeiro R. Magalhaes    schedule 24.08.2016
comment
@ShadowGod, на самом деле фокус звука сделал свое дело! Большое спасибо! Хотя очень интересно видеть, что ни один из официальных примеров никогда не упоминает о том, что это такая важная часть!   -  person Felipe Ribeiro R. Magalhaes    schedule 25.08.2016


Ответы (1)


Я думаю, что у меня может быть такая же проблема. попробуйте запросить фокус звука, прежде чем начать играть. Я слышу свою музыку на настольном головном устройстве

person sasebt    schedule 31.01.2021