蓝牙(二)蓝牙搜索、配对、连接

article/2025/10/8 10:41:11

1.搜索

从上一节我们可以知道,蓝牙状态发生了改变,并发生了回调。咱们就从回调开始。

DevicePickerFragment.java 用于蓝牙设置界面的蓝牙配置和管理

 @Overridepublic void onBluetoothStateChanged(int bluetoothState) {super.onBluetoothStateChanged(bluetoothState);if (bluetoothState == BluetoothAdapter.STATE_ON) {mLocalAdapter.startScanning(false);}}

最终会回调到这个地方,具体怎么回调到这的暂时没去分析,我猜测应该是回调到这,如果有知道请不吝赐教。

好了,蓝牙搜索开始了

LocalBluetoothAdapter.java

public void startScanning(boolean force) {// Only start if we're not already scanningif (!mAdapter.isDiscovering()) {if (!force) {// Don't scan more than frequently than SCAN_EXPIRATION_MS,// unless forcedif (mLastScan + SCAN_EXPIRATION_MS > System.currentTimeMillis()) {return;}// If we are playing music, don't scan unless forced.A2dpProfile a2dp = mProfileManager.getA2dpProfile();if (a2dp != null && a2dp.isA2dpPlaying()) {return;}}if (mAdapter.startDiscovery()) {mLastScan = System.currentTimeMillis();}}

下面会调到BluetoothAdapter.startDiscovery()==>AdapterService.startDiscovery()==>AS.startDiscoveryNative()==>JNI里面的startDiscoveryNative()==>再下面就到hw里面和bluetooth.start_discovery(void),这些暂时就不分析了,有兴趣的可以自行分析。


2.连接/断开/配对/取消配对

还是从蓝牙设置界面讲起吧,当点击设置界面的某个蓝牙设备时会回调到DeviceListPreferenceFragment里面

@Overridepublic boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,Preference preference) {if (KEY_BT_SCAN.equals(preference.getKey())) {mLocalAdapter.startScanning(true);return true;}if (preference instanceof BluetoothDevicePreference) {BluetoothDevicePreference btPreference = (BluetoothDevicePreference) preference;CachedBluetoothDevice device = btPreference.getCachedDevice();mSelectedDevice = device.getDevice();onDevicePreferenceClick(btPreference);return true;}return super.onPreferenceTreeClick(preferenceScreen, preference);}
void onDevicePreferenceClick(BluetoothDevicePreference btPreference) {btPreference.onClicked();}
==》
 void onClicked() {int bondState = mCachedDevice.getBondState();if (mCachedDevice.isConnected()) {askDisconnect();} else if (bondState == BluetoothDevice.BOND_BONDED) {mCachedDevice.connect(true);} else if (bondState == BluetoothDevice.BOND_NONE) {pair();}}

上面的逻辑里会根据不同的情况执行不同的逻辑,一目了然。

    1)配对

    

private void pair() {if (!mCachedDevice.startPairing()) {Utils.showError(getContext(), mCachedDevice.getName(),R.string.bluetooth_pairing_error_message);}

注意了,开始拉红线配对了。配对之前,如果有已婚的,那么不好意思,必须拆开重新选择对象了偷笑

 public boolean startPairing() {// Pairing is unreliable while scanning, so cancel discoveryif (mLocalAdapter.isDiscovering()) {mLocalAdapter.cancelDiscovery();}if (!mDevice.createBond()) {return false;}mConnectAfterPairing = true;  // auto-connect after pairingreturn true;}

==》BluetoothDevice.createBond()==>adapterservice.createBond()==>adapterservice.createBond()==>向状态机发送绑定消息==》BondStateMachine.createBond()==>AdapterService.createBondNative()==>JNI==>hw==>external,想了解的自行分析。借用一下图

 

配对完成之后,要干嘛?大家都是正经人,所以要去结婚然后再去开房了。所以当配对成功之后,肯定有一个事件提供给上面BluetoothEventManager

,接收到bond完成事件

private class BondStateChangedHandler implements Handler {
259        public void onReceive(Context context, Intent intent,
260                BluetoothDevice device) {
261            if (device == null) {
262                Log.e(TAG, "ACTION_BOND_STATE_CHANGED with no EXTRA_DEVICE");
263                return;
264            }
265            int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
266                                               BluetoothDevice.ERROR);
267            CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
268            if (cachedDevice == null) {
269                Log.w(TAG, "CachedBluetoothDevice for device " + device +
270                        " not found, calling readPairedDevices().");
271                if (!readPairedDevices()) {
272                    Log.e(TAG, "Got bonding state changed for " + device +
273                            ", but we have no record of that device.");
274                    return;
275                }
276                cachedDevice = mDeviceManager.findDevice(device);
277                if (cachedDevice == null) {
278                    Log.e(TAG, "Got bonding state changed for " + device +
279                            ", but device not added in cache.");
280                    return;
281                }
282            }
283
284            synchronized (mCallbacks) {
285                for (BluetoothCallback callback : mCallbacks) {
286                    callback.onDeviceBondStateChanged(cachedDevice, bondState);
287                }
288            }
289            cachedDevice.onBondingStateChanged(bondState);
290
291            if (bondState == BluetoothDevice.BOND_NONE) {
292                int reason = intent.getIntExtra(BluetoothDevice.EXTRA_REASON,
293                        BluetoothDevice.ERROR);
294
295                showUnbondMessage(context, cachedDevice.getName(), reason);
296            }
297        }
void onBondingStateChanged(int bondState) {if (bondState == BluetoothDevice.BOND_NONE) {mProfiles.clear();mConnectAfterPairing = false;  // cancel auto-connectsetPhonebookPermissionChoice(ACCESS_UNKNOWN);setMessagePermissionChoice(ACCESS_UNKNOWN);setSimPermissionChoice(ACCESS_UNKNOWN);mMessageRejectionCount = 0;saveMessageRejectionCount();}refresh();if (bondState == BluetoothDevice.BOND_BONDED) {if (mDevice.isBluetoothDock()) {onBondingDockConnect();} else if (mConnectAfterPairing) { connect(false);}mConnectAfterPairing = false;}

请大家自己跟踪一下,下面我省略了一些逻辑。接下来会走到

synchronized void connectInt(LocalBluetoothProfile profile) {if (!ensurePaired()) {return;}if (profile.connect(mDevice)) {if (Utils.D) {Log.d(TAG, "Command sent successfully:CONNECT " + describe(profile));}return;}Log.i(TAG, "Failed to connect " + profile.toString() + " to " + mName);}
具体connect的蓝牙功能是什么就会通过相关的协议进行连接。

2)取消配对过程

与配对过程类似

 



3、连接与取消连接

1)       连接过程

 

2)       取消连接过程

和连接过程类似,略。

4、扫描

A、通过调用BluetoothAdapter的startDiscovery()方法告诉底层开始搜索;

B、底层发广播通知应用找到设备或者扫描状态变化,从而更新ui。

 


http://chatgpt.dhexx.cn/article/0XGvx6ri.shtml

相关文章

Android蓝牙配对

上一篇博客介绍了Android ble的一些情况。 http://blog.csdn.net/guijiaoba/article/details/41172403 蓝牙如果链接好,能够读写,基本上完成了。蓝牙还有个比较烦人的东西,就是蓝牙配对。 Android ble4.0使用的配对方式和原先版本的配对方式…

Android蓝牙开发(二)之蓝牙配对和蓝牙连接

上篇文章:https://blog.csdn.net/huangliniqng/article/details/82185983 讲解了打开蓝牙设备和搜索蓝牙设备,这篇文章来讲解蓝牙配对和蓝牙连接 1.蓝牙配对 搜索到蓝牙设备后,将设备信息填充到listview中,点击listiew则请求配对…

BLE蓝牙的连接和配对过程

一 连接 同一款手机,为什么跟某些设备可以连接成功,而跟另外一些设备又连接不成功?同一个设备,为什么跟某些手机可以建立连接,而跟另外一些手机又无法建立连接?同一个手机,同一个设备&#xff…

BLE蓝牙的配对过程浅析

BLE蓝牙配对过程 在了解到Bluetooth协议的大概后,本篇文章简单的梳理一下BLE蓝牙的配对过程和配对过程的数据格式,对于后面理解蓝牙的集中配对模式及相关漏洞浅浅奠定一下基础。 和经典蓝牙一样,协议为处于连接状态的BLE设备,定…

蓝牙设备的连接与配对

蓝牙是一种短距离无线通信技术,它由爱立信公司于1994年创制,原本想替代连接电信设备的数据线,但是后来发现它也能用于移动设备之间的数据传输,所以蓝牙技术在手机上获得了长足发展。 因为手机内部的通讯芯片一般同时集成了2G/3G/4…

Android 蓝牙连接,蓝牙配对,自动连接蓝牙

趁热打铁,这篇文章写于刚写完蓝牙配对Demo,主要介绍配对蓝牙的具体编码步骤,开整! 首先上效果图,看一下是否符合读者现在的需求 主要核心代码没有想象中那么复杂,首先要去申请一下权限,不仅需要蓝牙权限…

蓝牙配对方式

4种蓝牙配对方式,通俗地说: 1.Numeric Comparison:配对双方都显示一个6位的数字,由用户来核对数字是否一致,一致即可配对。例如手机之间的配对。 2.Just Works:用于配对没有显示没有输入的设备,…

蓝牙的配对和连接的建立过程

蓝牙的建立过程是一个复杂的过程,即使有过相当一段工作和使用经验的人,如果不仔细去了解还是理解不全。 平时我们用蓝牙耳机听音乐,和不同的设备共享文件,打电话等,都有一个配对--连接--传输数据的过程。 配对&#…

蓝牙|标准蓝牙配对方式

蓝牙:BlueTooth,是一种无线技术标准,可实现固定设备、移动设备和楼宇个人域网之间的短距离数据交换,蓝牙又分为传统/标准蓝牙和BLE蓝牙。 在了解配对方式前,先了解设备的IOCapacity,IOCapcaity是由设备InputCapacity和OutputCapacity组合而成…

蓝牙学习八(配对与绑定)

1.简介 Paring(配对)和Bonding(绑定)是实现蓝牙射频通信安全的一种机制,有两点需要注意: Paring/bonding实现的是蓝牙链路层的安全,对应用层来说是完全透明的。也就是说,不管有没有…

蓝牙 - 配对和连接

什么是蓝牙配对? 蓝牙配对是为了连接设备的一种信息注册方法。通过在设备之间注册设备信息(配对),它们可以连接。要使用一个蓝牙设备,你必须首先将其与另一个蓝牙设备配对。配对有点像交换电话号码。类似于你必须与你…

Java 接口回调机制

日常开发中接口回调机制无处不在,刚开始用时却总是晕晕乎乎,网上也有很多相关的文章介绍,但总是没有看得太明白,今天端午假期正好花时间来总结一下,我们按如下顺序介绍 一、什么是接口回调 在应用开发中,接…

Android 接口回调

Android接口回调讲解 回调定义回调机制回调意义接口回调的实现步骤参考 网上看了一堆,感觉有点零散,我自己总结一下。 回调定义 正式定义 回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一…

理解Java接口回调

初步认识: 实现步骤: 1、创建一个回调接口。 2、创建一个回调对象实现回调接口。 3、创建一个控制器对象,将回调对象作为参数传给控制器对象,控制器对象负责检查某个场景是否出现或某个条件是否满足,当满足时&#…

Android 自定义接口回调

1.定义一个简单的接口回调 下面是定义一个简单的接口,实现的功能是,设置名字爱好,并且返回给主 Activity。 1.1 自定义一个接口 定义一个名字为 setNameListener() 的接口类: /*** author: wu* date: on 2018/10/23.* describ…

接口回调(笔记

接口回调讲解 回调定义回调机制回调意义接口回调的实现步骤参考 网上看了一堆,感觉有点零散,我自己总结一下。看评论区说存在很多问题,我读了一下,雀氏存在一些,非常感谢批评指正,我重新写一写。&#xff0…

接口回调与方法回调

1.1 接口回调 简介: 笔者查阅了大量资料,接口回调没有定义,可以理解为是一种设计思想。 其本质是将实现接口的类通过向上转型至接口类型,通过传入不同的子类,实现调用相应的子类重写的父类接口方法。 详情见&#xff…

Java接口回调详解

一.产生接口回调的场景 在现实生活中,产生接口回调的场景很简单,比如我主动叫你帮我做一件事,然后你做完这件事之后会通知我,"通知我"这个动作就是接口回调的动作.接口回调重在理解思就好.再举个例子用于下面的代码演示,老师让学生做课堂练习,学生做完练习后并告诉老…

java 接口回调的例子_java接口回调

java的接口回调原理网上已经有很多生动形象的例子说明了,在此总结一下个人的理解:类A调用类B的方法b(),类B再回调类A的方法a(),其中方法a()是定义在接口中的,由类A来实现。这是一个双向调用的过程,用下面的类图来加以说明。 Callback.png 1. 创建一个接口: public inter…

巧妙理解接口回调

接口回调目的和用法解析 一、为什么会有接口回调?什么是接口回调? 其实这两个问题是一个问题,知道了接口回调的原理自然就知道了为什么会有这么个东西。我们知道java中接口是不可以直接创建实例的,那么问题来了,假如…