【问题标题】:how to turn speaker on/off programmatically in android 4.0如何在 android 4.0 中以编程方式打开/关闭扬声器
【发布时间】:2012-08-15 16:45:35
【问题描述】:

我通过媒体播放器播放文件,我想提供扬声器开/关、通过耳机播放、蓝牙等选项。 我尝试了下面的代码,它适用于 android 2.2,但我想要的东西也适用于 2.2 和 4.0。 您能帮我以编程方式打开/关闭扬声器并通过耳机播放吗?

AudioManager audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
    if(isOn){
        audioManager.setMode(AudioManager.MODE_IN_CALL);    
        audioManager.setMode(AudioManager.MODE_NORMAL); 
    }else{
        //Seems that this back and forth somehow resets the audio channel
        audioManager.setMode(AudioManager.MODE_NORMAL);     
        audioManager.setMode(AudioManager.MODE_IN_CALL);        
    }
    audioManager.setSpeakerphoneOn(isOn);

P.S:我已在清单中授予此权限:

android.permission.MODIFY_AUDIO_SETTINGS 

【问题讨论】:

  • 你是怎么解决这个问题的?

标签: android android-4.0-ice-cream-sandwich speaker


【解决方案1】:

试试

AudioManager.speakerphone(true);

this

【讨论】:

  • 我猜你的意思是AudioManager.setSpeakerPhoneOn? (这是他已经在使用的)。 AudioSystem 中没有扬声器方法。
  • 查看我发布的链接。在该链接中,您可以找到该方法。
  • 您在答案中写了 AudioSystem,但链接到 AudioManager 参考。这就是我问的原因。
  • @chirag : AudioManager.speakerphone(true);这行不通。你能推荐其他适用于 2.2 和 4.0 的东西吗
  • 你也必须这样做:audioManager.setMode(AudioManager.MODE_IN_CALL);
【解决方案2】:

这样的东西可能适用于某些设备(我只在 XPeria P 上测试过):

final static int FOR_MEDIA = 1;
final static int FORCE_NONE = 0;
final static int FORCE_SPEAKER = 1;

Class audioSystemClass = Class.forName("android.media.AudioSystem");
Method setForceUse = audioSystemClass.getMethod("setForceUse", int.class, int.class);
setForceUse.invoke(null, FOR_MEDIA, FORCE_SPEAKER);
// To get back to the default behaviour, use the combination FOR_MEDIA,FORCE_NONE.

FOR_MEDIA, FORCE_SPEAKER 组合通常仅在内部用于将 FM 收音机音频路由到扬声器(因为 FM 收音机需要您插入有线耳机/耳机以充当天线)。没有 FM 收音机功能(或使用替代实现)的设备可能会忽略此参数组合,因此此方法不适用于此类设备。

【讨论】:

  • 这适用于我的 Galaxy S2 和 android 4.0.4。你是怎么想出这个主意的?这就像一个奇迹
  • setForceUse 是内部用于将某些音频类型强制到给定设备的方法。我之所以知道这一点,是因为我以使用 Android 音频为生。
  • 我不喜欢这样的 hack,因为它们几乎肯定会被 Android 框架的未来版本打破。但这是我发现在插入耳机时实际上允许通过扬声器输出的唯一方法。适用于运行 Android-4.1.1 的华为 Y300
  • 嘿迈克尔,当我们必须设置回默认行为时,即让它通过耳机播放,我们是否执行 setForceUse.invoke(null, 1, 0); ?
  • 它不能在 Android Pie 设备上运行,知道为什么吗?
【解决方案3】:

您可以随时购买后置扬声器或前置听筒。

如果没有连接配件;

使用audioManager.setMode(AudioManager.MODE_IN_CALL); & audioManager.setSpeakerphoneOn(false); 使用前置扬声器/听筒。但这会在听筒而不是扬声器上播放音频。要使用后置扬声器,请使用audioManager.setMode(AudioManager.MODE_NORMAL); & audioManager.setSpeakerphoneOn(true);

如果连接了附件;使用 audioManager.setMode(AudioManager.MODE_IN_CALL); & audioManager.setSpeakerphoneOn(假);使用前置扬声器/听筒。但这会在听筒而不是扬声器上播放音频。要使用后置扬声器,请使用audioManager.setMode(AudioManager.MODE_IN_CALL); & audioManager.setSpeakerphoneOn(true);

注意:确保 audioManager.setWiredHeadsetOn(boolean on)audioManager.setBluetoothScoOn(boolean on) 设置为 false 以通过听筒路由音频。并设置为 true 以相应地路由音频。

【讨论】:

    【解决方案4】:

    问题解决了。对于仍在寻找答案的所有人。那么这不是一个错误,而只是一个棘手的事情。您需要使用 PhoneStateListener

    使用本指南:http://danielthat.blogspot.co.il/2013/06/android-make-phone-call-with-speaker-on.html

    【讨论】:

      【解决方案5】:

      如果你只是想打开你的免提电话,只需在你的活动的 oncreate() 中写下这一行。

      static AudioManager audioManager =  (AudioManager)getSystemService(Context.AUDIO_SERVICE);
      audioManager.setMode(AudioManager.MODE_IN_CALL);
      audioManager.setSpeakerphoneOn(true);
      

      【讨论】:

        【解决方案6】:
        AudioManager mAudioMgr = (AudioManager)getSystemService(Context.AUDIO_SERVICE); 
        
        Button mVolumeButton = (Button)findViewById(R.id.btn_Volume);
                mVolumeButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if(mAudioMgr.isWiredHeadsetOn()){
                            mAudioMgr = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
                            mAudioMgr.setWiredHeadsetOn(false);
                            mAudioMgr.setSpeakerphoneOn(true);
                            mAudioMgr.setMode(AudioManager.MODE_IN_COMMUNICATION);
        
                            Toast.makeText(getApplicationContext(), "SpeakerPhone On", Toast.LENGTH_LONG).show();
                        }else{
                            mAudioMgr.setMode(AudioManager.MODE_IN_COMMUNICATION);
                            mAudioMgr.setSpeakerphoneOn(false);
                            mAudioMgr.setWiredHeadsetOn(true);
                            Toast.makeText(getApplicationContext(), "Wired Headset On", Toast.LENGTH_LONG).show();
                        }
                    }
                });
        

        【讨论】:

          【解决方案7】:

          试试这个。

          AudioManager audioManager =(AudioManager)getSystemService(Context.AUDIO_SERVICE);
              if (isOn) {
                  isOn = false;
                  audioManager.setMode(AudioManager.MODE_IN_CALL);
                  audioManager.setMode(AudioManager.MODE_NORMAL);
          
              } else {
                  isOn = true;
                  audioManager.setMode(AudioManager.MODE_NORMAL);
                  audioManager.setMode(AudioManager.MODE_IN_CALL);
          
              }
              audioManager.setSpeakerphoneOn(isOn);
          

          【讨论】:

            【解决方案8】:

            尝试按照代码 sn-p:

            //for speakerphone on
            audioManager.setMode(AudioManager.MODE_NORMAL);
            audioManager.setSpeakerphoneOn(true);
            
            //for headphone on
            audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
            audioManager.setSpeakerphoneOn(false);
            

            顺便说一句,我在 Android 7.0(Redmi 4x) 上测试过,效果很好。

            【讨论】:

            • 这对我有用!耶!已经为此苦苦挣扎了一段时间。我现在唯一的问题是,在从免提电话到接收器的过渡过程中大约有一秒钟的死气。没什么大不了的,但有点烦人。
            • audioManager.setMode(AudioManager.MODE_NORMAL);此行代码对我有用
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-05-27
            • 1970-01-01
            • 2014-02-02
            • 1970-01-01
            相关资源
            最近更新 更多