蓝牙设备的连接与配对

article/2025/10/8 10:50:44
蓝牙是一种短距离无线通信技术,它由爱立信公司于1994年创制,原本想替代连接电信设备的数据线,但是后来发现它也能用于移动设备之间的数据传输,所以蓝牙技术在手机上获得了长足发展。

因为手机内部的通讯芯片一般同时集成了2G/3G/4G、WIFI和蓝牙,所以蓝牙功能已经是智能手机的标配了。若想进行蓝牙方面的开发,需要在App工程的AndroidManifest.xml中补充下面的权限配置:
[html]  view plain copy
  1.     <!-- 蓝牙 -->  
  2.     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />  
  3.     <uses-permission android:name="android.permission.BLUETOOTH" />  
  4.     <!-- 如果Android6.0 蓝牙搜索不到设备,需要补充下面两个权限 -->  
  5.     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />  
  6.     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />  
与NFC类似,Android也提供了蓝牙模块的管理工具,名叫BluetoothAdapter,虽然通常把BluetoothAdapter翻译为“蓝牙适配器”,其实它干的是管理器的活。下面是BluetoothAdapter类常用的方法说明:
getDefaultAdapter : 获取默认的蓝牙适配器。该方法为静态方法。
getState : 获取蓝牙的开关状态。STATE_ON表示已开启,STATE_TURNING_ON表示正在开启,STATE_OFF表示已关闭,STATE_TURNING_OFF表示正在关闭。
enable : 启用蓝牙功能。
disable : 禁用蓝牙功能。
isEnabled : 判断蓝牙功能是否启用。返回true表示已启用,返回false表示未启用。
getBondedDevices : 获取已配对的设备集合。
getRemoteDevice : 根据设备地址获取远程的设备对象。
startDiscovery : 开始搜索周围的蓝牙设备。
cancelDiscovery : 取消搜索周围的蓝牙设备。
isDiscovering : 判断是否正在搜索周围的蓝牙设备。

接下来通过一个检测蓝牙设备并配对的例子,介绍如何在App开发中运用蓝牙技术。不要小看这个例子,简简单单的功能可得分成四个步骤:初始化、启用蓝牙、搜索蓝牙设备、与指定设备配对,下面分别进行详细说明:

一、初始化蓝牙适配器
如果仅仅是普通的蓝牙连接,则调用getDefaultAdapter获取蓝牙适配器就行了。初始化蓝牙适配器的代码示例如下:
[java]  view plain copy
  1. private BluetoothAdapter mBluetooth;  
  2. private void initBluetooth() {  
  3.     mBluetooth = BluetoothAdapter.getDefaultAdapter();  
  4.     if (mBluetooth == null) {  
  5.         Toast.makeText(this"本机未找到蓝牙功能", Toast.LENGTH_SHORT).show();  
  6.         finish();  
  7.     }  
  8. }  

二、启用蓝牙功能
虽然BluetoothAdapter提供了enable方法用于启用蓝牙功能,但是该方法并不允许外部发现本设备,所以等于没用。实际开发中要弹窗提示用户,是否允许其他设备检测到自身,弹窗代码如下所示:
[java]  view plain copy
  1.     // 弹出是否允许扫描蓝牙设备的选择对话框  
  2.     Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);  
  3.     startActivityForResult(intent, mOpenCode);  
蓝牙权限的选择对话框如下图所示:

由于选择弹窗上面可选择“允许”还是“拒绝”,因此代码中要重写onActivityResult函数,在该函数中判断蓝牙权限的选择结果。下面是判断权限选择的例子代码:
[java]  view plain copy
  1. private int mOpenCode = 1;  
  2. @Override  
  3. protected void onActivityResult(int requestCode, int resultCode, Intent intent) {  
  4.     super.onActivityResult(requestCode, resultCode, intent);  
  5.     if (requestCode == mOpenCode) {  
  6.         mHandler.postDelayed(mRefresh, 50); // 刷新蓝牙设备列表  
  7.         if (resultCode == RESULT_OK) {  
  8.             Toast.makeText(this"允许本地蓝牙被附近的其它蓝牙设备发现", Toast.LENGTH_SHORT).show();  
  9.         } else if (resultCode == RESULT_CANCELED) {  
  10.             Toast.makeText(this"不允许蓝牙被附近的其它蓝牙设备发现", Toast.LENGTH_SHORT).show();  
  11.         }  
  12.     }  
  13. }  

三、搜索周围的蓝牙设备
蓝牙功能打开之后,就能调用startDiscovery方法去搜索周围的蓝牙设备了。不过因为搜索动作是个异步的过程,startDiscovery方法并不直接返回搜索发现的设备结果,而是通过广播BluetoothDevice.ACTION_FOUND返回新发现的蓝牙设备。所以页面代码需要注册一个蓝牙搜索结果的广播接收器,在接收器中解析蓝牙设备信息,再把新设备添加到蓝牙设备列表。
下面是蓝牙搜索接收器的注册、注销,以及内部逻辑处理的代码例子:
[java]  view plain copy
  1.     private void beginDiscovery() {  
  2.         // 如果当前不是正在搜索,则开始新的搜索任务  
  3.         if (!mBluetooth.isDiscovering()) {  
  4.             mBluetooth.startDiscovery();  
  5.         }  
  6.     }  
  7.   
  8.     @Override  
  9.     protected void onStart() {  
  10.         super.onStart();  
  11.         //需要过滤多个动作,则调用IntentFilter对象的addAction添加新动作  
  12.         IntentFilter discoveryFilter = new IntentFilter();  
  13.         discoveryFilter.addAction(BluetoothDevice.ACTION_FOUND);  
  14.         //注册搜索结果的接收器  
  15.         registerReceiver(discoveryReceiver, discoveryFilter);  
  16.     }  
  17.   
  18.     @Override  
  19.     protected void onStop() {  
  20.         super.onStop();  
  21.         // 注销广播接收器  
  22.         unregisterReceiver(discoveryReceiver);  
  23.     }  
  24.   
  25.     // 蓝牙设备的搜索结果通过广播返回  
  26.     private BroadcastReceiver discoveryReceiver = new BroadcastReceiver() {  
  27.         @Override  
  28.         public void onReceive(Context context, Intent intent) {  
  29.             String action = intent.getAction();  
  30.             Log.d(TAG, "onReceive action=" + action);  
  31.             // 获得已经搜索到的蓝牙设备  
  32.             if (action.equals(BluetoothDevice.ACTION_FOUND)) {  
  33.                 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);  
  34.                 refreshDevice(device); // 将发现的蓝牙设备加入到设备列表  
  35.             }  
  36.         }  
  37.     };  
搜索到的蓝牙设备可能会有多个,每发现一个新设备都会收到一次发现广播,这样设备列表是动态刷新的。搜索完成的蓝牙设备列表界面如下图所示,其中左图为A手机的设备列表,右图为B手机的设备列表:



四、与指定的蓝牙设备配对
注意到新发现的设备状态是“未绑定”,这意味着当前手机并不能跟对方设备进行数据交互。只有新设备是“已绑定”状态,才能与当前手机传输数据。蓝牙设备的“未绑定”与“已绑定”,区别在于这两部设备之间是否成功配对了,而配对操作由BluetoothDevice类管理。下面是BluetoothDevice类的常用方法说明:
getName : 获取设备的名称。
getAddress : 获取设备的MAC地址。
getBondState : 获取设备的绑定状态。BOND_NONE表示未绑定,BOND_BONDING表示正在绑定,BOND_BONDED表示已绑定。
createBond : 建立该设备的配对信息。该方法为隐藏方法,需要通过反射调用。
removeBond : 移除该设备的配对信息。该方法为隐藏方法,需要通过反射调用。
从上面的方法说明可以看出,搜索获得新设备后,即可调用设备对象的createBond方法建立配对。但配对成功与否的结果同样不是立即返回的,因为系统会弹出配对确认框供用户选择,就像下面的两个界面截图那样,左图是A手机上的配对弹窗,右图是B手机上的配对弹窗。


只有用户在两部手机都选择了“配对”按钮,才算是双方正式搭配好了。由于配对请求需要在界面上手工确认,因此配对结果只能通过异步机制返回,此处的结果返回仍然采取广播形式,即系统会发出广播BluetoothDevice.ACTION_BOND_STATE_CHANGED通知App。故而前面第三步的广播接收器得增加过滤绑定状态的变更动作,接收器内部也要补充更新蓝牙设备的绑定状态了。修改后的广播接收器相关代码片段如下所示:
[java]  view plain copy
  1. @Override  
  2. protected void onStart() {  
  3.     super.onStart();  
  4.     //需要过滤多个动作,则调用IntentFilter对象的addAction添加新动作  
  5.     IntentFilter discoveryFilter = new IntentFilter();  
  6.     discoveryFilter.addAction(BluetoothDevice.ACTION_FOUND);  
  7.     // 增加绑定状态的变更动作  
  8.     discoveryFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);  
  9.     //注册搜索结果的接收器  
  10.     registerReceiver(discoveryReceiver, discoveryFilter);  
  11. }  
  12.   
  13.   
  14. // 蓝牙设备的搜索结果通过广播返回  
  15. private BroadcastReceiver discoveryReceiver = new BroadcastReceiver() {  
  16.     @Override  
  17.     public void onReceive(Context context, Intent intent) {  
  18.         String action = intent.getAction();  
  19.         Log.d(TAG, "onReceive action=" + action);  
  20.         // 获得已经搜索到的蓝牙设备  
  21.         if (action.equals(BluetoothDevice.ACTION_FOUND)) {  
  22.             BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);  
  23.             refreshDevice(device); // 将发现的蓝牙设备加入到设备列表  
  24.         } else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {  
  25.             BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);  
  26.             // 更新蓝牙设备的绑定状态  
  27.             if (device.getBondState() == BluetoothDevice.BOND_BONDING) {  
  28.                 tv_discovery.setText("正在配对" + device.getName());  
  29.             } else if (device.getBondState() == BluetoothDevice.BOND_BONDED) {  
  30.                 tv_discovery.setText("完成配对" + device.getName());  
  31.             } else if (device.getBondState() == BluetoothDevice.BOND_NONE) {  
  32.                 tv_discovery.setText("取消配对" + device.getName());  
  33.             }  
  34.         }  
  35.     }  
  36. };  
两部手机配对完毕,分别刷新自己的设备列表页面,将对方设备的绑定状态改为“已绑定”,然后它俩就可以眉目传情,传递小纸条什么的了。下面是更新状态后的设备列表界面,其中左图为A手机的设备列表,右图为B手机的设备列表:


http://chatgpt.dhexx.cn/article/u2a1h3uw.shtml

相关文章

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

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

蓝牙配对方式

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

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

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

蓝牙|标准蓝牙配对方式

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

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

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

蓝牙 - 配对和连接

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

Java 接口回调机制

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

Android 接口回调

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

理解Java接口回调

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

Android 自定义接口回调

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

接口回调(笔记

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

接口回调与方法回调

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

Java接口回调详解

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

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

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

巧妙理解接口回调

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

[Java]什么是接口回调?

什么是接口回调&#xff1f; 1&#xff0e;接口回调是什么[2]&#xff1f; 接口回调是指&#xff1a;可以把使用某一接口的类创建的对象的引用赋给该接口声明的接口变量&#xff0c;那么该接口变量就可以调用被类实现的接口的方法。实际上&#xff0c;当接口变量调用被类实现…

自定义动画animate

开发工具与关键技术&#xff1a;VS&#xff0c;MVC 作者&#xff1a;陈梅 撰写时间&#xff1a;2019年6月2 日 所有代码来源与老师教学 这次分享一个好玩的自定义动画效果&#xff0c;这次还是用jQuery做出来的小功能。这次我们先直接看最后已经布局好的效果。 把所想写的内容…

Android自定义动画专题一

Android自定义动画 在目前的移动端产品中&#xff0c;不管是app还是网页一个好看酷炫的页面总是会第一时间吸引人的眼球&#xff0c;那么对于android开发人员来说&#xff0c;要想实现一个好看的页面必然需要掌握自定义控件以及自定义动画这门技术。 1.Android原生动画 Androi…

百度地图添加自定义图标标注以及自定义动画效果

百度地图添加自定义图标标注以及自定义动画效果 1、添加自定义图标标注2、添加自定义动画效果2.1、标注对象marker的构成2.2、自定义动画效果实现过程2.3、最终实现效果 上次写的是添加自定义图标&#xff0c;但是用的是添加自定义覆盖物方法&#xff0c;结果不支持点聚合&…

Vue中如何进行自定义动画与动画效果设计

Vue中如何进行自定义动画与动画效果设计 在Vue中&#xff0c;动画效果是非常有用的&#xff0c;它可以使用户界面变得更加生动、有趣&#xff0c;从而提高用户体验。Vue提供了一套非常方便的动画系统&#xff0c;使得我们可以非常容易地实现动画效果。 在本文中&#xff0c;我…