在做voip通话的过程中,会频繁使用到免提播放和听筒接听的功能,而如何正确的切换,和AudioManager的调度是分不开的,直接上代码:

//获取AudioManager服务

private val audioManager =

AppUtils.getApplication().getSystemService(Context.AUDIO_SERVICE) as AudioManager

/**

* 扬声器切换

* true: 打开

*/

fun setSpeakerPhoneOn(on: Boolean) {

if (on) {

//设置mode

audioManager.mode = AudioManager.MODE_IN_COMMUNICATION

//设置音量,解决有些机型切换后没声音或者声音突然变大的问题

audioManager.setStreamVolume(

AudioManager.STREAM_VOICE_CALL,

audioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL),

AudioManager.FX_KEY_CLICK

)

//扬声器开启,此方法调用之前需要先设置好mode

audioManager.isSpeakerphoneOn = true

} else {

//5.0以上

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

//设置mode

audioManager.mode = AudioManager.MODE_IN_COMMUNICATION

//设置音量,解决有些机型切换后没声音或者声音突然变大的问题

audioManager.setStreamVolume(

AudioManager.STREAM_VOICE_CALL,

audioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL),

AudioManager.FX_KEY_CLICK

)

} else {

//设置mode

audioManager.mode = AudioManager.MODE_IN_CALL

audioManager.setStreamVolume(

AudioManager.STREAM_VOICE_CALL,

audioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL),

AudioManager.FX_KEY_CLICK

)

}

//扬声器关闭,此方法调用之前需要先设置好mode

audioManager.isSpeakerphoneOn = false

}

}

/**

* 麦克风开关

* RINGER_MODE_SILENT 静音,且无振动

* RINGER_MODE_VIBRATE 静音,但有振动

* RINGER_MODE_NORMAL 正常声音,振动开关由setVibrateSetting决定.

* true:静音

*/

fun setVoiceOn(on: Boolean) {

audioManager.isMicrophoneMute = on

// ToastUtils.shortBottom(if (on) "麦克风已关闭" else "麦克风已启用")

}

/**

* 重设audioManager状态

* 扬声器切换为NORMAL && 打开麦克风

*/

fun resetAudioState() {

//设置mode 为喇叭播放

audioManager.mode = AudioManager.MODE_NORMAL

//设置音量,解决有些机型切换后没声音或者声音突然变大的问题

audioManager.setStreamVolume(

AudioManager.STREAM_MUSIC,

audioManager.getStreamVolume(AudioManager.STREAM_MUSIC),

AudioManager.FX_KEY_CLICK

)

audioManager.isSpeakerphoneOn = true

setVoiceOn(false)

}

方法调用代码如上,下面来分析一下使用中要重点注意的元素:

1.audioManager.mode

AudioManager中给出了如下mode种类,正确的选择mode进行配置,才能提升用户体验;

/**

* Invalid audio mode.

*/

public static final int MODE_INVALID = AudioSystem.MODE_INVALID;

/**

* Current audio mode. Used to apply audio routing to current mode.

*/

public static final int MODE_CURRENT = AudioSystem.MODE_CURRENT;

/**

* Normal audio mode: not ringing and no call established.

*/

public static final int MODE_NORMAL = AudioSystem.MODE_NORMAL;

/**

* Ringing audio mode. An incoming is being signaled.

*/

public static final int MODE_RINGTONE = AudioSystem.MODE_RINGTONE;

/**

* In call audio mode. A telephony call is established.

*/

public static final int MODE_IN_CALL = AudioSystem.MODE_IN_CALL;

/**

* In communication audio mode. An audio/video chat or VoIP call is established.

*/

public static final int MODE_IN_COMMUNICATION = AudioSystem.MODE_IN_COMMUNICATION;

在VOIP场景中,主要就是为了通话服务,所以选择mode的时候,设置为MODE_IN_COMMUNICATION 就比较合适,如果设置为MODE_NORMAL 去开启扬声器,就可能会出现和其他音频播放声音混杂,甚至互相干扰啸叫严重的问题。

android听筒+扬声器自动切换,Android VOIP中的扬声器、听筒切换相关推荐

  1. android音频系统(7):通话过程中的音频输出设备切换

    前言:由于通话比较特殊,Android对于通话过程中音频输出设备的切换做了特殊处理,它在上层也是通过切换音频播放状态来完成切换操作的,android用CallAudioState来封装通话过程中的音频 ...

  2. android系统相机自动录像,android 调用系统相机录像并保存

    1.在AndroidManifest.xml中添加如下代码 tools:ignore="ProtectedPermissions" /> android:authoritie ...

  3. android 进度条自动增长,Android 进度条自动前进效果的实现代码

    今天给大家分享进度条自动前进功能的实现,先给大家分享实现效果图,感觉不错可以参考实现代码. 效果如下图: 首先布局要设置进度条最大值: android:id="@+id/pro1" ...

  4. android 阅读器自动滚动,Android编程实现小说阅读器滑动效果的方法

    本文实例讲述了Android编程实现小说阅读器滑动效果的方法.分享给大家供大家参考,具体如下: 看过小说都知道小说阅读器翻页有好多种效果,比如仿真翻页,滑动翻页,等等.由于某种原因,突然想写一个简单点 ...

  5. android如何设置自动补,Android Studio 中设置代码块自动补齐

    AS中很多提示键,并不如Eclipse中做的好,需要我们自己去自定义.这里以switch...case为例,讲解一下如何设置代码自动补全. 1.进入settings -->  Editor -- ...

  6. android ble 实现自动连接,Android:自动重新连接BLE设备

    经过多次试验和磨难之后,这就是我最好让Android自动连接的唯一用户操作是首先选择设备(如果使用设置菜单然后首先配对). 您必须将配对事件捕获到BroadcastReceiver中并执行Blueto ...

  7. android如何不自动获取焦点,Android 如何让EditText不自动获取焦点

    在项目中,一进入一个页面, EditText默认就会自动获取焦点. 那么如何取消这个默认行为呢? 在网上找了好久,有点 监听软键盘事件,有点 调用 clearFouse()方法,但是测试了都没有! x ...

  8. android蓝牙配对 自动联接,Android系统下蓝牙自动配对连接方法

    Android系统下蓝牙自动配对连接方法 [专利摘要]本发明涉及一种Android系统下蓝牙自动配对连接方法,其包括如下步骤:步骤1.在Android设备端内存储上次进行蓝牙连接蓝牙外设的蓝牙地址,并 ...

  9. android看彩信自动退出,Android短彩信收发流程(应用层)

    下图为ComposeMessageActivity中confirmSendMessageIfNeeded部分的信息发送流程.主要以接收者有效性的确认为主,然后转向sendMessage方法进行发送. ...

最新文章

  1. 前端/投资者能从阿里巴巴CACSC全球总决赛的项目路演中获得什么
  2. matlab 求解黄金分割率
  3. 世界级Oracle专家Jonathan Lewis:我很为DBA们的未来担心(图灵访谈)
  4. json 序列化 java_Java JSON序列化杂谈
  5. Spring Boot 核心知识点总结,值得收藏!
  6. CenterOS 7安装Nginx
  7. 如何销毁一个实例化对象_JAVA中如何创建和销毁对象
  8. 模糊查询时,页面没有数据,数据库编辑器里可以正常显示数据
  9. Old ST-LINK firmware detected.do you want to upgrade it?已解决,stlink升级
  10. annotation:@Override出现The method of type must override asuperclass解决方案
  11. MySQ随笔2(连接表、分组)
  12. Applese 的毒气炸弹(最小生成树)
  13. 用计算机检索生物学文献,文献检索期末复习
  14. java解压jar包的方法_Java 打包成jar包 和 解压jar包
  15. 吴忌寒联姻500.COM的背后秘密
  16. 你了解PowerBI中的去年同期吗
  17. office2010 打开报错 无法访问您试图使用的功能所在的网络位置
  18. 分分钟解决OSPF配置问题
  19. JavaScript测试工具对决:Sinon.js vs testdouble.js
  20. PayPal 全攻略

热门文章

  1. 40 岁的中年失业人怎么活下去?,花费近一年时间整理的Android核心知识清单
  2. java2048设计说明_基于Android的2048游戏设计与实现论文+任务书+开题报告+答辩+源码...
  3. Python读取csv文件(详解版,看了无师自通)
  4. AWS Devops所涉及的必须了解运用求职的重要服务
  5. 函数——imapprox、conv2、imadd、dither
  6. (转)[AndEngine学习教程] 第6节 模拟手柄控制器
  7. APICloud AVM多端开发 |《生鲜电商app开发》项目源码深度解析
  8. 胡继晔:中国应建区块链行业准入制度
  9. 手机中的功耗设计介绍(一)
  10. 关于厦门宽带用户升级了FTTH光纤入户,从别的地方拿来的ITV机顶盒没有办法使用的解决办法...