首页 > 编程知识 正文

怎么连接车上的蓝牙放歌,无蓝牙音频装置连接

时间:2023-05-05 10:32:46 阅读:107278 作者:1603

以下内容都是基于android6.0的故事,相对于android4.4架构有了很大的变化。

先借个图用一下吧。

上图显示了蓝牙协议栈。 此图显示了在协议栈中调用A2dp代码的流程。 分层结构如下。

1 .蓝牙系统服务服务通过JNI与bluedroid协议栈通信。 协议栈分为两层:蓝牙嵌入式系统(bte )和蓝牙应用程序层(BTA )。 这两层与框架层APP应用程序进行通信。

蓝牙服务通过Binder IPC通信与APP应用程序交互。

3 .系统服务为开发者提供了获取各种配置文件的接口。

一.接下来,我们将深入探讨Framework层的蓝牙连接

1 )那么,从connectInt ) )开始

同步语音连接(localbluetoothprofileprofile ) if (! ensurePaired (() ) { return; }if(profile.connect(mdevice ) ) if ) utils.d ) log.d ) tag,' commandsentsuccesfully 3360 connect ' describe ) ) }log.I(tag,' failedtoconnect ' profile.tostring ) )、' to ' mName ); }2)如果配置文件是a2dp配置文件,则为a2dp配置文件. connect () ) )。

publicbooleanconnect (bluetoothdevicedevice ) if ) mservice==null )返回假; listbluetoothdevicesinks=getconnecteddevices (; if(sinks!=null () for ) bluetoothdevicesink:sinks ) mservice.disconnect(sink ); }returnmservice.connect(device ); }上面的代码很清楚。 检查连接的设备并断开连接。 释放蓝牙节点后,可以供其他使用。

3 )蓝牙a2dp.connect () )。

publicbooleanconnect (蓝牙设备) if ) DBG ) log ) ) connect ) device ); if(mservice!=nullisenabled(isvaliddevice )设备) try{returnmservice.connect )设备; }catch(remoteexceptione ) log.e ) tag,' stack : ' log.getstacktracestring (new throwable ) ); 返回假; }if(mservice==null ) log.w ) tag,' Proxy not attached to service '; 返回假; }蓝牙a2dp类是做什么的呢? 这是蓝牙a2dp服务器的代理,上层尝试使用时必须使用。 如何获取蓝牙a2dp,请参阅蓝牙adapter.getprofileproxy ()

4.A2DP服务. connect (

mstate machine.sendmessage (a2 dpstatemachine.connect,device ); 将蓝牙连接消息发送到A2dpStateMachine进行连接操作。 a2dp连接之前一定是disconnect状态,所以连接的时候会一点一点地。 请注意,以下代码位于mDisconnected中。

switch(message.what ) case connect :蓝牙devicedevice=)蓝牙设备(message.obj ); broadcastconnectionstate(dev

ice, BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED);----(1) if (!connectA2dpNative(getByteAddress(device)) ) {-----(2) broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING); break; } synchronized (A2dpStateMachine.this) { mTargetDevice = device; transitionTo(mPending);---------(3) } // TODO(BT) remove CONNECT_TIMEOUT when the stack // sends back events consistently sendMessageDelayed(CONNECT_TIMEOUT, 30000); break;

        上面的(1)处是发送一个连接蓝牙状态改变事件。

                         (2)进行a2dp连接,很明显就要进入jni里了

                           (3)状态转换到==》pending==>connected

JNI

5.这里只讲连接,所以下面要分析jni了

static jboolean connectA2dpNative(JNIEnv *env, jobject object, jbyteArray address) { jbyte *addr; bt_bdaddr_t * btAddr; bt_status_t status; ALOGI("%s: sBluetoothA2dpInterface: %p", __FUNCTION__, sBluetoothA2dpInterface); if (!sBluetoothA2dpInterface) return JNI_FALSE; addr = env->GetByteArrayElements(address, NULL); btAddr = (bt_bdaddr_t *) addr; if (!addr) { jniThrowIOException(env, EINVAL); return JNI_FALSE; } if ((status = sBluetoothA2dpInterface->connect((bt_bdaddr_t *)addr)) != BT_STATUS_SUCCESS) { ALOGE("Failed HF connection, status: %d", status); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;}

那么这个sBluetoothA2dpInterface这个是什么呢?其实这个就相当于java中对外提供的api接口,只是在c中是头文件而已。

既然是蓝牙肯定是在蓝牙的头文件里bt_av.h里

typedef struct { /** set to sizeof(btav_interface_t) */ size_t size; /** * Register the BtAv callbacks */ bt_status_t (*init)( btav_callbacks_t* callbacks ); /** connect to headset */ bt_status_t (*connect)( bt_bdaddr_t *bd_addr ); /** dis-connect from headset */ bt_status_t (*disconnect)( bt_bdaddr_t *bd_addr ); /** Closes the interface. */ void (*cleanup)( void );} btav_interface_t;

接下来就调用到./btif/src/btif_av.c

static const btav_interface_t bt_av_src_interface = { sizeof(btav_interface_t), init_src, src_connect_sink, disconnect, cleanup_src,};static const btav_interface_t bt_av_sink_interface = { sizeof(btav_interface_t), init_sink, sink_connect_src, disconnect, cleanup_sink,};

至于a2dp的断开,流程和连接类似,请大家自行分析。

上面有两个connect到底使用哪一个呢?那就要看你的机器是发送连接还是接收连接了。就到这了,接下来的东西其实我没搞太明白,就不误导大家了。

如果感觉不错,就赞一下。





版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。