我配对号蓝牙耳机,然后拨打电话,接通后,声音会从蓝牙耳机里面出来,这个流程是怎么样的呢?今天就来分析。

首先肯定的是在开启蓝牙通话的这个通道是在Phone进程里面。

APP层核文件:

BluetoothHandsfree.java

接通开通蓝牙的通话通道不是在Incscreen,而是在这个BluetoothHandsfree内部类BluetoothPhoneState类里面注册了一个广播的监听器来监听电话的状态:

代码片段:

case PRECISE_CALL_STATE_CHANGED:
                case PHONE_CDMA_CALL_WAITING:
                    Connection connection = null;
                    if (((AsyncResult) msg.obj).result instanceof Connection) {
                        connection = (Connection) ((AsyncResult) msg.obj).result;
                    }

handlePreciseCallStateChange(sendUpdate(), connection);

当Phone处于Dialing状态的时候就会去建立连接。

流程:handlePreciseCallStateChange---->audioOn();--->mHeadset.connect()   (mHeadset在原生态代码中为BluetoothAudioGateway,在MTK平台中为HeadsetBase,但实现的效果都一样)

Framework:

(BluetoothAudioGateway或则BluetoothAudioGateway)connect--->connectNative()---->connectNative()(android_bluetooth_BluetoothAudioGateway)----->

当系统建立连接后就会通过BluetoothHeadsetService来通知BluetoothAudioGateway进行出里。

BluetoothHeadsetService中的代码片段:

case BluetoothAudioGateway.SCO_ACCEPTED:
                    case BluetoothAudioGateway.SCO_CONNECTED:
                    case BluetoothAudioGateway.SCO_CLOSED:
                        if(msg.obj == null) {
                            logWarn("Remote Device is null when receive SCO msg");
                            mBtHandsfree.handleSCOEvent(msg.what, null);

BluetoothAudioGateway:

handleSCOEvent--->mAudioManager.setBluetoothScoOn(true);---->AudioManager----->AudioService

AudioService:

setBluetoothScoOn代码片段:

public void setBluetoothScoOn(boolean on){
        if (!checkAudioSettingsPermission("setBluetoothScoOn()")) {
            return;
        }
        mForcedUseForComm = on ? AudioSystem.FORCE_BT_SCO : AudioSystem.FORCE_NONE;

sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SHARED_MSG, SENDMSG_QUEUE,
                AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, null, 0);
        sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SHARED_MSG, SENDMSG_QUEUE,
                AudioSystem.FOR_RECORD, mForcedUseForComm, null, 0);
        Log.d(TAG, "setBluetoothScoOn " + mForcedUseForComm);
    }

注意这里发送了两次消息。猜测两次的目的是一次是告诉系统我要使用的是通话功能,二次是告诉系统录音功能,因为通话的时候应该是可以录音的,如果把第二次For_RECORD去掉,应该是也能成功设置的。

setForceUse---> AudioSystem.setForceUse------>AudioSystem::setForceUse-------->AudioPolicyService::setForceUse------->AudioYusuPolicyManager::setForceUse

AudioYusuPolicyManager:

这里面有个很重要的位置判断:

if(AudioSystem::popCount(newDevice) != 2 )
    {

一些蓝牙不能传出声音很有可能就是这里出现了问题!

拨打电话通过蓝牙接通相关推荐

  1. android 蓝牙电话号码,Android拨打电话和蓝牙状态监听

    一.拨打电话 权限管理 思路 通过Intent设置Action为ACTION_DIAL或者 ACTION_CALL,通过intent启动直接拨打电话或者打开拨打电话界面. 示例代码 直接拨打电话 /* ...

  2. 安卓源码避坑指南3——拨打电话的SIM卡无效导致蓝牙断开连接

    安卓源码避坑指南3--拨打电话的SIM卡无效导致蓝牙断连 它来了.它来了,它带着BUG赶来了,欢迎大家查看本期的安卓源码避坑指南.本期的问题场景比较特殊,电话SIM卡是无效的(欠费过期了,很是贫穷-) ...

  3. python实现自动拨打电话_twilio python自动拨打电话,播放自定义mp3音频的方法

    有个小项目,需求是某事件发生时,给客户打电话,提醒客户.需要事先录制好一段音频,客户接通电话后,自动播放. 1. 注册twilio账号 2. 买一个电话号码 3. 安装twilio pip insta ...

  4. 蓝牙电话协议HFP(Hands-Free Profile) 通过号码拨打电话/memory拨打电话(Memory Dialing)/尾号重播(Last Number Re-Dial) 功能介绍

    零. 概述 本文章主要讲下电话免提协议HFP(Hands-Free Profile)通过号码拨打电话(Place a call with the phone number)/memory拨打电话(Me ...

  5. 用Android平板模拟蓝牙耳机,与手机连接,实现接听与拨打电话-预研

    用Android平板模拟蓝牙耳机,与手机连接,实现接听与拨打电话 结论: 没找到可以用的方案.据说要蓝牙协议支持.普通手机.平板做不了. 正常蓝牙打电话时,手机是实现了蓝牙协议的AG端,耳机是HF端, ...

  6. Flutter 拨打电话和跳转网页

    首先需要一如库 url_launcher  如下 具体写法如下 import 'package:flutter/material.dart'; import 'package:url_launcher ...

  7. swift3.0最新拨打电话方法

    let alertVC : UIAlertController = UIAlertController.init(title: "是否拨打报警电话:10086", message: ...

  8. 用Python拨打电话

    用python拨打电话,先看小视频 Python自动化技术广泛应用于测试.运维相关领域,我自己现在也是做的这方面,工资也不比其他方向少,就业相对容易的多,而且需求的公司也多,对后端框架之类也要求不是很 ...

  9. java 打电话_第四十二篇----拨打电话

    界面: MainActivity.java packagecom.example.aimee.phone;importandroid.Manifest;importandroid.content.In ...

最新文章

  1. 通过句柄找到广告弹窗进程
  2. oracle中那个日期怎么相减_二手车鉴定中最容易混淆的日期读法,你会是那个读错的人吗?...
  3. [转]开源项目学习方法ABC
  4. Ruby中的%表示法
  5. web前端面试问答_Web服务面试问答
  6. 前端学习(1683):前端系列实战课程之让蛇吃食物变长
  7. python能和c语音交互吗_Python和C语言交互--ctypes,struct
  8. 【java.lang.NoClassDefFoundError: t/SpringBootConfiguration】
  9. cocos2dx游戏开发简单入门视频教程 (cocos2d-x)-第2天
  10. LoadRunner测试ajax框架,回放后系统中没有产生数据解决方法
  11. 亲戚问我工资多少钱,该说实话吗?
  12. 林子雨大数据软件安装和编程指南导航
  13. IDEA类图标有小叉叉×
  14. 润物无声:java的字符串操作
  15. 常见的电商直播模式有哪些,你都了解过吗?
  16. Mobius反演总结
  17. 关于测试的一篇论文, 基于web端selenium的自动化测试设计与实现(有需要的联系我 此论文内容缺失,不要直接用 一经发现,后果自负)
  18. matlab偏微分图像修复,图像修复 Region filling and object removal by exemplar-based image inpainting matlab实现...
  19. 分布式发号器——Vesta
  20. 【学习笔记】求矩阵的特征多项式

热门文章

  1. CentOS 6 nfs共享存储配置
  2. android 删除短信权限,Android删除短信的方法
  3. (二) 简单认识Emacs
  4. 笔记本电脑打开摄像头
  5. 美签 计算机 敏感专业,美国签证:14个最容易被check的敏感专业
  6. xbel文档_什么是.recently-used.xbel?如何永久删除它?
  7. 在计算机中移动硬盘一般用作什么,台式机硬盘通用吗-普通电脑的硬盘可以当成移动硬盘用吗普通电脑 – 手机爱问...
  8. 【C/C++】劫持技术
  9. C++实验课指针笔记2
  10. Android实战--汉字转全拼