android 蓝牙hfp server实现简介

本文介绍了如何在蓝牙HFP(Hands-Free Profile)1.6版本中实现语音识别功能,包括配置文件设置、底层实现原理及Java层回调机制,并详细说明了通过发送AT+BVRA命令激活语音识别的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先确认配置文件是否开启hfp profile功能。根据设备的角色(hfp client / hfp server)来配置hfp profile.
profile 配置文件路径:
       alps/packages/apps/Bluetooth/res/values/config.xml
       alps/device/${customer}/${ProjectName}/overlay/packages/apps/Bluetooth/res/values/config.xml 


e.g.  设备的角色定义为hfp server,需做如下配置:
    <bool name="profile_supported_hs_hfp">true</bool>

    <bool name="profile_supported_hfpclient">false</bool>


接下来介绍hfp server的实现,以通过蓝牙耳机激活语音识别为例。hfp1.6 版本已经支持了语音识别的实现。


//HF通过发送AT+BVRA命令给AG来发起激活语音识别应用。语音识别应用安装在AG中。

除了audio的路由、语音识别的激活控制等功能需要用到蓝牙功能,其余都依赖于语音识别应用的实现。


//AG 中的bt stack收到hf发过来的cmd AT+BVRA,调用回调函数处理

external/bluetooth/bluedroid/btif/src/btif_hf.c

static void btif_hf_upstreams_evt(UINT16 event, char* p_param){

.....

        case BTA_AG_AT_BVRA_EVT:
            HAL_CBACK(bt_hf_callbacks, vr_cmd_cb,
                (p_data->val.num == 1) ? BTHF_VR_STATE_STARTED :
                      BTHF_VR_STATE_STOPPED, &btif_hf_cb[idx].connected_bda);
            break;

}


//java层的hfp service在初始化的时候,注册回调

packages/apps/Bluetooth/jni/com_android_bluetooth_hfp.cpp

static bthf_callbacks_t sBluetoothHfpCallbacks = {
    sizeof(sBluetoothHfpCallbacks),
    connection_state_callback,
    audio_state_callback,
    voice_recognition_callback,
    answer_call_callback,
    hangup_call_callback,
    volume_control_callback,
    dial_call_callback,
    dtmf_cmd_callback,
    noice_reduction_callback,
    wbs_callback,
    at_chld_callback,
    at_cnum_callback,
    at_cind_callback,
    at_cops_callback,
    at_clcc_callback,
    unknown_at_callback,
    key_pressed_callback
};


packages/apps/Bluetooth/src/com/android/bluetooth/hfp/HeadsetStateMachine.java

private HeadsetStateMachine(HeadsetService context) {

......

initializeNative(max_hf_connections);


packages/apps/Bluetooth/jni/com_android_bluetooth_hfp.cpp

initializeNative(){

......

    if ( (status = sBluetoothHfpInterface->init(&sBluetoothHfpCallbacks,
          max_hf_clients)) != BT_STATUS_SUCCESS) {
        ALOGE("Failed to initialize Bluetooth HFP, status: %d", status);
        sBluetoothHfpInterface = NULL;
        return;
    }

}


external/bluetooth/bluedroid/btif/src/btif_hf.c

static bt_status_t init( bthf_callbacks_t* callbacks, int max_hf_clients){

......

bt_hf_callbacks = callbacks;

}


//回调函数( e.g. voice_recognition_callback)首先通过JNI 调用到java中的函数(onVrStateChanged) 


static void voice_recognition_callback(bthf_vr_state_t state, bt_bdaddr_t* bd_addr) {
......
    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVrStateChanged, (jint) state, addr);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    sCallbackEnv->DeleteLocalRef(addr);
}

packages/apps/Bluetooth/src/com/android/bluetooth/hfp/HeadsetStateMachine.java

    private void onVrStateChanged(int state, byte[] address) {
        StackEvent event = new StackEvent(EVENT_TYPE_VR_STATE_CHANGED);
        event.valueInt = state;
        event.device = getDevice(address);
        sendMessage(STACK_EVENT, event);
    }


//java中通过发送intent携带action的方式启动语音识别的app

private void processVrEvent(int state, BluetoothDevice device) {

.....

mService.startActivity(sVoiceCommandIntent);

}


HeadsetStateMachine(){

......

        if (sVoiceCommandIntent == null) {
            sVoiceCommandIntent = new Intent(Intent.ACTION_VOICE_COMMAND);
            sVoiceCommandIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }

}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值