android 声音不想从蓝牙手机中出来,Android蓝牙音频两个问题
1.qq通话,微信通话,打电话,铃声想起时,为何铃声只在手机端响起?而蓝牙耳机里只有嘟嘟声?
(1)来电铃声播放
streamType=2(AUDIO_STREAM_RING)
APM::AudioPolicyManager: startOutput() output 18, stream 2, session 24
(2)Engine::getStrategyForStream()函数可得stream 2对应
strategy 2 (STRATEGY_SONIFICATION)
(3)选设备
APM::AudioPolicyEngine: getDeviceForStrategy() strategy 2, device 82
结果为AUDIO_DEVICE_OUT_BLUETOOTH_A2DP | AUDIO_DEVICE_OUT_SPEAKER
这地方就奇怪了,明明选择的设备是蓝牙设备和扬声器,为什么只有扬声器有铃声?
log中可以发现
bt_a2dp_hw: out_set_parameters: state 5
5 对应 AUDIO_A2DP_STATE_STANDBY
经过一番费力的查找,可以发现
铃声响起时运行
adb shell dumpsys media.audio_flinger结果中
蓝牙设备对应的:
Output thread 0xecec0000 type 0 (MIXER):
Thread name: AudioOut_441
I/O handle: 1089
TID: 2033
Standby: yes
Sample rate: 44100 Hz
HAL frame count: 2560
HAL format: 0x1 (pcm16)
HAL buffer size: 10240 bytes
Channel count: 2
Channel mask: 0x00000003 (front-left, front-right)
Format: 0x1 (pcm16)
Frame size: 4 bytes
Pending config events: none
Output device: 0x80 (BLUETOOTH_A2DP)
小提示
多输出设备的时候,每个设备对应一个Mixthread,然后对应着一个总的DuplicatingThread。
蓝牙设备对应的Output thread在铃声播放的时候处于Standby状态。而这个状态赋值的地方很好找到(Threads.cpp):
if ((!mActiveTracks.size() && systemTime() > mStandbyTimeNs) ||
isSuspended()) {
// put audio hardware into standby after short delay
if (shouldStandby_l()) {
threadLoop_standby();
mStandby = true;
}
经过一番寻找,真相了:
AudioPolicyManager setPhoneState会调用checkA2dpSuspend()函数,最终导致蓝牙Thread standBy.然后整个蓝牙输出相关的MixThread都暂停工作了,此时肯定不会去调用out_write函数往下写铃声数据,也就不会发出任何声音了。
看官且看checkA2dpSuspend函数中注释:
// suspend A2DP output if:
// (NOT already suspended) &&
// ((SCO device is connected &&
// (forced usage for communication || for record is SCO))) ||
// (phone state is ringing || in call)//响铃的时候要把a2dp挂起,注意是a2dp
//
// restore A2DP output if:
// (Already suspended) &&
// ((SCO device is NOT connected ||
// (forced usage NOT for communication && NOT for record is SCO))) &&
// (phone state is NOT ringing && NOT in call)
//
以在下区区四级的英文水平观之,大意为:打电话或者is ringing(setPhonestate 0之后)的时候(sco要连接成功)要用sco,挂起a2dp.
百度搜搜sco和a2dp的区别:
蓝牙一般有两种语音相关的模式是A2DP和SCO,前者是高质量音乐播放(俗称:只进不出),后者是语音通话(俗称:有进有出)。
摘自:http://blog.csdn.net/kangear/article/details/38780185(如有冒犯,请作者原谅)
2. 通话过程中,如果开启免提,声音不再从蓝牙设备中输出,而从手机端输出,这是为什么?
我们且看看
电话接通之后,电话应用正常会调用
setBluetoothScoOn()切换蓝牙设备为Sco模式
public void setBluetoothScoOnInt(boolean on) {
if (on) {
//通话时强制使用BT_SCO
mForcedUseForComm = AudioSystem.FORCE_BT_SCO;
} else if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) {
mForcedUseForComm = AudioSystem.FORCE_NONE;
}
sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE,
AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, null, 0);
sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE,
AudioSystem.FOR_RECORD, mForcedUseForComm, null, 0);
}
,点击“扬声器”之后setSpeakerphoneOn()
public void setSpeakerphoneOn(boolean on){
if (!checkAudioSettingsPermission("setSpeakerphoneOn()")) {
return;
}
if (on) {
if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) {
//如果之前设置了通话强制使用BT_SCO
//先取消强制使用(FORCE_NONE)
sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE,
AudioSystem.FOR_RECORD, AudioSystem.FORCE_NONE, null, 0);
}
//设置强制使用SPEAKER
mForcedUseForComm = AudioSystem.FORCE_SPEAKER;
} else if (mForcedUseForComm == AudioSystem.FORCE_SPEAKER){
mForcedUseForComm = AudioSystem.FORCE_NONE;
}
sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE,
AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, null, 0);
}
case MSG_SET_FORCE_USE:
case MSG_SET_FORCE_BT_A2DP_USE:
setForceUse(msg.arg1, msg.arg2);
break;
//往下,AudioPolicyManager setForceUse的调用就略过不提了。
所以。。。就。。。不多说了
android 声音不想从蓝牙手机中出来,Android蓝牙音频两个问题相关推荐
- 如何在没有 USB 数据线的情况下使用 Android Studio 在手机中安装 Android
背景 如何在没有 USB 数据线的情况下使用 Android Studio 在手机中安装 Android 应用程序? 运行调式一个Android项目,写下必要的代码后,接下来的任务是在模拟器或手机上运 ...
- android 获取蓝牙设备id_安卓蓝牙系统中如何获取蓝牙音乐的音频跟踪会话ID
原标题:安卓蓝牙系统中如何获取蓝牙音乐的音频跟踪会话ID 蓝牙音乐AudioTrack Session ID的获取 当今这个音视频无处不在的时代,音频跟踪会话ID(AudioTrack Session ...
- 【Android 逆向】获取安装在手机中的应用的 APK 包 ( 进入 adb shell | 获取 root 权限 | 进入 /data/app/ 目录 | 拷贝 base.apk 到外置存储 )
文章目录 一.获取 APK 包流程 二.获取 APK 包完整流程命令行输出 一.获取 APK 包流程 从应用市场中下载的应用 , 安装完毕后 , 自动删除 ; 如果想要获取安装应用的 APK 包 , ...
- android便签的作用,安卓手机中的便签有什么用?
原标题:安卓手机中的便签有什么用? 目前安卓系统的手机,是当下主流市场中颇受大众欢迎的一类智能手机,因为安卓系统相对比较稳定,操作起来也较为简便,所以才会受到大众的认可.而且在很多不同品牌的安卓手机端 ...
- android qq apk,仿QQ获取手机中的APK并分享的实现
前几天看到同事里有一个界面绚丽的应用,觉得有点意思,就让他把APK发给我,我想反编译看看里面的代码.结果,这哥们在手机里找了好一阵子,最后给我说:手机没有root,找不到APK文件在哪里.我再让他试试 ...
- Android 基于google Zxing实现对手机中的二维码进行扫描
转载请注明出处:http://blog.csdn.net/xiaanming/article/details/14450809 我之前写了一篇关于google Zxing扫描二维码的文章,效果是仿微信 ...
- Android——如何在电脑里找到手机中的图片或者视频
1.先让你的手机与你的电脑进行多媒体的连接 2.首先找到你的Android的SDK目录,然后进入platform-tools目录下,然后shift+鼠标右键,选择在此处打开cmd或Powershell ...
- 【Android NDK 开发】在 C 代码中获取 Android 系统信息 ( NDK 项目创建 | NDK 配置 | 获取 Android 系统版本号 )
文章目录 I . 创建 NDK 项目 II . NDK 项目 相关配置 III . NDK 中获取 Android 版本号 IV . 使用 __system_property_get 可获取的参数 I ...
- anbox android 镜像,Anbox将使Ubuntu手机能运行Android应用程序
Anbox 就在支持Ubuntu Phone设备的OTA-3软件更新发布两天之后,Ubuntu Touch维护者UBports现在开始为用户提供即将到来的Android应用程序支持. [UBports ...
- android sutdio版本号,电脑中Android studio版本号如何查看_电脑中查看Android studio版本号的步骤-系统城...
Android studio是谷歌推出的一个Android集成开发工具,在使用的时候,经常会有新版本不断产生所以就需要查看自己的Android studio版本号来确保是否需要进行更新,很多用户不知道 ...
最新文章
- python GUI开发
- linux minicom usb串口
- springmvc读取静态数据,解决html访问不到css和js等静态数据的问题
- 「Swift」笔记第二章 Basic Operators
- MySQL修改配置 区分大小写
- 随想录(elf文件)
- 开源的WebKit 浏览器引擎受多个漏洞影响,可导致 RCE 后果
- Android SQLite数据库升级的问题
- Windows 7 下 QT5 开发环境搭建
- matlab2c使用c++实现matlab函数系列教程-repmat函数
- python多线程并发每秒6000_Python多线程并发的误区
- 如何把多个tomcat加入到window服务中
- steam邮箱服务器设置,Steam游戏通用进服教程
- 助你成为Java大神的十个建议
- 美团点评2020校园招聘商业分析师一面(2019.9.5)
- Macbook安装pkg
- java class 加密_如何给class文件加密
- Unbuntu环境编译 Android平台可用ffmpeg(带三方库fdk-aac和lame)
- 实现Word公式和普通文本的批量互转
- 老游戏《皇帝龙之崛起》修改最大建筑数到8000
热门文章
- win2008使用windows loader激活提示Unsupported partition table
- 索尼手机服务器在哪个文件夹,索尼手机云服务器
- vc ++ 实现检测变速齿轮,变速精灵, 变速类辅助工具
- 测试软硬件系统信息的工具 -- EVEREST Ultimate Edition
- CuteFTP下载包含中文的文件,无法下载的问题
- 神经网络——基础思想
- his系统计算机软件,医学系统(一)医院常用的软件系统:PACS系统、HIS系统、RIS系统、LIS系统、CIS系统...
- cloud2声卡_带你解惑HyperX Cloud2(飓风)和Alpha(阿尔法)的终极选择
- 4G的小程序与5G的Chromium OS?
- android调用webservice,Android开发调用WebService的方法示例