【问题标题】:Audio through built-in speakers when earphones are plugged in headphone jack in Android在 Android 中将耳机插入耳机插孔时通过内置扬声器播放音频
【发布时间】:2015-06-10 07:43:55
【问题描述】:

在我的应用程序中,有一个读卡器使用设备的音频插孔。现在,我的问题是当读卡器在设备的耳机插孔中完好无损时,我想从内置扬声器发出声音。

这是我尝试过的代码:

1) 使用反射方法

Class audioSystemClass;
                try {
                     audioSystemClass = Class
                            .forName("android.media.AudioSystem");

                    Method setForceUse = audioSystemClass.getMethod(
                            "setForceUse", int.class, int.class);
                    // First 1 == FOR_MEDIA, second 1 == FORCE_SPEAKER. To go
                    // back to the default
                    // behavior, use FORCE_NONE (0).
                    setForceUse.invoke(null, 1, 1);
                    final float maxVolume = mAudioManager
                            .getStreamMaxVolume(AudioManager.STREAM_MUSIC);
                    soundPool.play(soundID, maxVolume, maxVolume, 1, 0, 1f);


                } catch (ClassNotFoundException e) {
                    Log.e("Test", e.toString());
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    Log.e("Test", e.toString());
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    Log.e("Test", e.toString());
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    Log.e("Test", e.toString());
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    Log.e("Test", e.toString());
                    e.printStackTrace();
                }

2) 使用 setMode 方法

mAudioManager.setMode(AudioManager.MODE_IN_CALL);
                mAudioManager.setSpeakerphoneOn(true);
                float maxVolume = mAudioManager
                        .getStreamMaxVolume(AudioManager.STREAM_RING);
                soundPool.play(soundID, maxVolume, maxVolume, 1, 0, 1f);

但这两个代码仅在那些具有默认 FM 应用程序的设备中运行。但我希望在所有设备中都具有此功能。

请分享你的经验!!

【问题讨论】:

  • 也许this 会帮助你,它与你尝试过的略有不同。

标签: android audio soundpool android-audiomanager headphones


【解决方案1】:

或者,如果您将 SoundPool 初始化为 STREAM_VOICE_CALL,如下所示:

SoundPool spool = new SoundPool(1,AudioManager.STREAM_VOICE_CALL, 0)

那么您的音频也应该通过您上面提到的任何方式路由到扬声器。我试过了,即使没有默认 FM,它也可以在手机上运行。

【讨论】:

  • 嘿,你能提出任何可能的原因,为什么上面的代码没有在三星 4.4.2 版本上运行,但它在 Nexus 设备上运行??
  • 在三星设备中,他们可能已经调整了音频参数,这就是音频 api 表现不同的原因。但这只是我的猜测。通过将 soundpool 设置为 stream_voice 呼叫,它可能应该适用于大多数手机,因为您正在覆盖 gsm 呼叫行为!
【解决方案2】:

您的第二种方法 setMode 适用于具有默认 Fm 播放器的手机。

但是对于没有 Default FM 的设备,我尝试了以下代码:

mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
mAudioManager.setSpeakerphoneOn(true);

此代码在没有默认 Fm 播放器的手机上运行良好。我使用带有 Oxygen OS 的 OnePlus 设备并且运行良好。希望这会有所帮助。

【讨论】:

    【解决方案3】:

    在这里,我启动了 SoundPool 并加载了哔声。

     SoundPool soundPool = new SoundPool(10, AudioManager.STREAM_VOICE_CALL, 0);
    
                soundPool
                        .setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
    
                            @Override
                            public void onLoadComplete(SoundPool soundPool,
                                                       int sampleId, int status) {
                                loaded = true;
                            }
                        });
                soundID = soundPool.load(ApplicationChexology.getContext(), R.raw.beep_single, 1);
    

    现在,在加载声音之后,我将 AudioManager 设置为 MODE_IN_COMMUNICATION 并播放声音。播放完声音后,将音频管理器的模式设置为 MODE_NORMAL。

     audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
     audioManager.setSpeakerphoneOn(true);
    
     float maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
            if (loaded)
             soundPool.play(soundID, maxVolume, maxVolume, 1, 0, 1f);
    
            Timer timer = new Timer();
    
            TimerTask delayedThreadStartTask = new TimerTask() {
              @Override
              public void run() {
                 audioManager.setMode(AudioManager.MODE_NORMAL);
                 audioManager.setSpeakerphoneOn(false);
    
                    }};
        timer.schedule(delayedThreadStartTask, 500);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-06
      • 1970-01-01
      • 1970-01-01
      • 2016-01-30
      相关资源
      最近更新 更多