【问题标题】:Android Auto: My App doesn't play audioAndroid Auto:我的应用不播放音频
【发布时间】:2016-08-23 21:24:46
【问题描述】:

我正在为我的应用实现 Android Auto 支持,但它无法正常工作。我遵循了 Google 的文档和一些教程,但音频无法正常工作。控件、专辑封面、艺术家姓名等都显示得很好。

奇怪的行为:通过自动模拟器运行 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>

【问题讨论】:

  • 最近,在模拟器中播放音频有问题,有时会中断,我也遇到过同样的问题,不是你的代码。
  • @ShadowGod,Spotify 的应用程序为何在模拟器中完美运行?这太奇怪了……好像我没有开始或初始化我应该做的事情,因为当我从 Spotify 的应用程序转到我的应用程序时,它可以工作,否则音频将永远播放不了!
  • 你能在真机上试试吗?我想如果您没有装有 Android Auto 的汽车,这将很难,大声笑我什至不知道您是否可以这样做.. 无论如何,我只能说我的模拟器没有播放音频而是打开了问题一个真实的设备(电话)很好......此外,与所有音频播放应用程序一样,请确保您遵循音频焦点规则:developer.android.com/training/managing-audio/audio-focus.html ..除此之外,您需要比我更高级的人来查看代码结束,对我来说没有什么是错误
  • @ShadowGod,很遗憾,我这里没有真正的 Android Auto 设备。我会尝试做音频焦点的事情!
  • @ShadowGod,实际上音频焦点的事情成功了!非常感谢你!虽然很有趣的是,官方的例子都没有提到它是一个如此重要的部分!

标签: android audio android-service android-auto


【解决方案1】:

我想我可能有同样的问题。在开始播放之前尝试请求音频焦点。我可以在桌面主机上听到我的音乐

【讨论】:

    猜你喜欢
    • 2017-01-11
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多