首页 > 解决方案 > 为什么 SoundPool 不会自动路由到连接的耳机?

问题描述

我正在使用Android SoundPool类来通过我的应用播放 UI 声音。正如预期的那样,通过集成扬声器在安卓设备上进行测试时,声音可以完美播放。但是,当我连接耳机时会出现问题。

当我将有线耳机连接到安卓设备时,声音不会路由到这些耳机。它将通过手机的集成扬声器继续播放。蓝牙耳机的问题仍然存在。

为确保我的耳机和设备正常工作:

我的印象是音频路由将在我的应用程序范围之外自动处理。Android 开发者网站有一个关于处理音频的部分,但是它没有提到任何关于在设备连接时手动路由音频的内容。

SoundPool 实施

这是在名为 SoundManager 的类中设置我的 SoundPool 的相关代码。

我使用了单例实现,这样我就可以从不同的活动中引用这个类,而不必每次都创建一个新实例。

/*
Audio Settings
*/
private final int MAX_STREAMS = 1;
private final int SRC_QUALITY = 1;
private final int STREAM_TYPE = AudioAttributes.USAGE_MEDIA;

/*
Audio Attributes
*/
private final int ATT_USAGE = AudioAttributes.USAGE_GAME;
private final int ATT_FLAG = AudioAttributes.FLAG_AUDIBILITY_ENFORCED;
private final int ATT_CONTENT = AudioAttributes.CONTENT_TYPE_SONIFICATION;


private SoundManager() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

            AudioAttributes audioAttributes = new AudioAttributes.Builder()
                    .setUsage(ATT_USAGE)
                    .setFlags(ATT_FLAG)
                    .setContentType(ATT_CONTENT)
                    .build();

            soundPlayer = new SoundPool.Builder()
                    .setMaxStreams(MAX_STREAMS)
                    .setAudioAttributes(audioAttributes)
                    .build();

        } else {
            soundPlayer = new SoundPool(MAX_STREAMS, STREAM_TYPE, SRC_QUALITY);
        }

        this.audioManager = (AudioManager) appActivity.getSystemService(Context.AUDIO_SERVICE);
        appActivity.setVolumeControlStream(AudioManager.STREAM_MUSIC);
    }

    /*
    Singleton implementation.
     */
    public static synchronized SoundManager get(Context context, AppCompatActivity activity) {
        if (soundManager == null) {
            soundManager = new SoundManager(context, activity);
        }

        return soundManager;
    }

    /* Play A Loaded Clip */
    public void play(SoundElement element) {
        if (existsInLoadedClips(element)) {
            int localId = element.getLocalId();
            float volume = getVolume();

            soundPlayer.play(localId, volume, volume,
                    PRIORITY, LOOP, RATE);
        }
    }

这不是整个类,而是与我的 SoundPool 实例交互的所有部分。

流类型

我认为问题的可能根源是流类型:

private final int STREAM_TYPE = AudioAttributes.USAGE_MEDIA;
private final int ATT_USAGE = AudioAttributes.USAGE_GAME;

但是,无论我使用哪种流类型,问题都仍然存在。

音量控制流

其次,我认为音量控制流与问题有关:

appActivity.setVolumeControlStream(AudioManager.STREAM_MUSIC);

但是,我也无法通过更改它找到解决方案。

将问题简化为基础

为了消除问题的可能来源,我只使用 SoundPool 对象和准系统 UI设置了一个新项目。

使用以下代码,可以使用任何声音文件重新创建问题:

    Button myBtn;
    SoundPool soundPlayer;

    /*
    Audio Settings
     */
    private final int MAX_STREAMS = 1;
    private final int SRC_QUALITY = 1;
    private final int STREAM_TYPE = AudioAttributes.USAGE_GAME;
    /*
    Audio Attributes
     */
    private final int ATT_USAGE = AudioAttributes.USAGE_GAME;
    private final int ATT_FLAG = AudioAttributes.FLAG_AUDIBILITY_ENFORCED;
    private final int ATT_CONTENT = AudioAttributes.CONTENT_TYPE_SONIFICATION;

    /*
    Playback Settings
     */
    private final int PRIORITY = 1;
    private final int LOOP = 0;
    private final int RATE = 1;

    int clipId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        /* Create Our SoundPool Object */
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

            AudioAttributes audioAttributes = new AudioAttributes.Builder()
                    .setUsage(ATT_USAGE)
                    .setFlags(ATT_FLAG)
                    .setContentType(ATT_CONTENT)
                    .build();

            soundPlayer = new SoundPool.Builder()
                    .setMaxStreams(MAX_STREAMS)
                    .setAudioAttributes(audioAttributes)
                    .build();

        } else {
            soundPlayer = new SoundPool(MAX_STREAMS, STREAM_TYPE, SRC_QUALITY);
        }

        this.setVolumeControlStream(AudioManager.STREAM_MUSIC);

        /*Find Button & Load A Clip */
        myBtn = (Button) findViewById(R.id.button);
        myBtn.setOnClickListener(new ButtonListener());
        this.clipId = loadClip();
    }

    public int loadClip() {
        String fileName = "your_audio_file";
        String resourceFolder = "raw";

        int resId = this.getResources().getIdentifier(
                fileName, resourceFolder, this.getPackageName());

        int localId = soundPlayer.load(this, resId, 1);

        return localId;
    }

    private void playSound() {
        soundPlayer.play(clipId, 1, 1,
                PRIORITY, LOOP, RATE);
    }

    private class ButtonListener implements View.OnClickListener {
        @Override
        public void onClick(View v) {
            playSound();
        }
    }

在这个简单的示例中,当按下按钮并连接耳机时,音频剪辑仍将仅通过我的 android 设备的集成扬声器播放。

我似乎无法找到这个问题的根源。任何帮助将不胜感激。让我知道是否可以提供有关代码或问题的更多详细信息。我试图包含我认为相关的所有内容,但可能需要更多信息。

标签: javaandroidsoundpool

解决方案


推荐阅读