2

アプリに Android Auto サポートを実装していますが、正しく動作しません。Google のドキュメントといくつかのチュートリアルに従いましたが、音声が機能しません。コントロール、アルバム アート、アーティスト名など、すべて問題なく表示されます。

奇妙な動作: Auto エミュレーターを介して Spotify アプリを実行し、曲を再生した後、自分のアプリに移動してオーディオを再生しようとすると、機能します!

私が実装したサービスクラスは次のとおりです。

/**
 * 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>
4

1 に答える 1