Android蓝牙开发

article/2025/10/15 15:17:05

题引:

最近项目上涉及与硬件相关的功能,需要通过蓝牙进行消息收发。项目已完成,这里做下记录。

通信步骤:

1.初始化BluetoothAdapter.getDefaultAdapter()获取BluetoothAdapter对象
2.判断蓝牙是否开启bluetoothAdapter.isEnabled()
3.未开启,进行开启操作bluetoothAdapter.enable();有返回值,为true证明开启成功
4.注册蓝牙开关广播 BluetoothAdapter.ACTION_STATE_CHANGED  监听开关等状态
5.搜索蓝牙设备 bluetoothAdapter.startDiscovery();
6.点击对配,需要判断是是否有过配对,有则连接;无则配对
7.依据广播状态改变文字描述BluetoothDevice.ACTION_BOND_STATE_CHANGED
8.配对成功,自动连接需要开子线程device.getClass().getMethod("createRfcommSocket", new Class[]{int.class}).invoke(device, 1);
9.监听连接广播,成功开启子线程接收数据,失败点击重连 
10.开启子线程发送消息

1.开启或关闭蓝牙

1.1通过BluetoothAdapter.getDefaultAdapter();拿到蓝牙适配器,其中isEnabled()可直接返回当前蓝牙状态。

 /*** 获取蓝牙开关状态** @return true为开,false为关*/public boolean getBluetoothSwitchState() {if (bluetoothAdapter != null) {return bluetoothAdapter.isEnabled();}return false;}

1.2返回为false时,蓝牙处于关闭状态。通过bluetoothAdapter.enable();方法打开蓝牙,同样,bluetoothAdapter.disable();方法可关闭蓝牙。这两个方法均有返回值,可通过返回值判断是否开启成功!

    /*** 开启蓝牙设备** @return 开启是否成功*/public boolean startBlueTooth() {if (bluetoothAdapter == null) {return false;}return bluetoothAdapter.enable();}/*** 关闭蓝牙*/public void closeBlueToothDevice() {if (bluetoothAdapter == null) {return;}bluetoothAdapter.disable();}

1.3 注意:用户可将程序挂起,从设置页或下拉状态栏进行打开关闭蓝牙。如蓝牙关闭,此时APP需要通过广播进行监听,关闭则提示用户打开蓝牙,或退出程序。我讲所需要的广播先都提前写出!

receiver = new BluetoothReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); //监听蓝牙关闭和打开状态
filter.addAction(BluetoothDevice.ACTION_FOUND); //搜索发现设备
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); //搜索完毕
filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); //配对状态
filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);//蓝牙连接成功
filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); //蓝牙连接失败context.registerReceiver(receiver, filter);

 2. 设备搜索

2.1 蓝牙开启后,自动进行设备搜索

/*** 搜索蓝牙设备
*/
public void searchBluetooth() {if (bluetoothAdapter == null) {return;}bluetoothAdapter.startDiscovery();
}

2.2广播监听搜索到的设备,进行列表展示(单个设备引入第二个重要类BluetoothDevice)

注意:搜索到设备可能存在空值,或重复搜索。需要自己在adpter或list中筛选。

2.3蓝牙搜索会后自动停止,对应停止广播BluetoothAdapter.ACTION_DISCOVERY_FINISHED:可在停止后进行配对,若没有扫描到对应设备则再次进行重新搜索

3.蓝牙配对

3.1蓝牙连接分配对与连接两个过程,如果未配对,则必须先进行配对,如果之前配对成功,并且没有取消配对,可直接进行连接;有三个参数,可判断对应设备与当前设备之间的关联

3.2 假设之前配对成功,该设备device.getBondState()为BOND_BONDED,以此来判断是否配对 

/**
* 是否配对过
*
* @param device 设备信息
* @return true是 false否
*/
public boolean isPaired(BluetoothDevice device) {if (device.getBondState() == BluetoothDevice.BOND_BONDED) {return true;}return false;
}

3.3.1配过对直接连接,当前写未配对情况。配对代码:

/**
* 对蓝牙进行配对(反射调用,需自行刷新数据)
*
* @param device 设备信息
*/
public void pairBluetoothDevice(BluetoothDevice device) {try {Method method = BluetoothDevice.class.getMethod("createBond");method.invoke(device);} catch (Exception e) {LogUtils.error("pairBluetoothDeviceException : {}", e.getMessage());}
}

3.3.2 既然可以配对,当前可取消配对,将取消配对代码也给出:需要先判断下,之前是否配对成功,条件同3.2;

 /*** 取消该蓝牙配对(反射调用,需自行刷新数据)** @param device 设备信息*/public void canlePairBluetoothDevice(BluetoothDevice device) {try {Method method = BluetoothDevice.class.getMethod("removeBond");method.invoke(device);} catch (Exception e) {LogUtils.error("canlePairBluetoothDeviceException : {}", e.getMessage());}}

 3.4 配对状态通过广播监听,监听后,改变状态展示给用户

3.5 参照系统蓝牙配对成功后需要自己连接设备。失败则刷新adapter,更新至最新状态等待用户下一步操作。

4.蓝牙连接 

4.1蓝牙连接代码:(需要在子线程中操作)

 /*** 连接设备** @param device 设备信息*/public void connBluetoothDevice(BluetoothDevice device) {new Thread() {@Overridepublic void run() {super.run();try {mBluetoothSocket = (BluetoothSocket) device.getClass().getMethod("createRfcommSocket", new Class[]{int.class}).invoke(device, 1);if (mBluetoothSocket != null) {if (!mBluetoothSocket.isConnected()) {mBluetoothSocket.connect();}}} catch (Exception e) {LogUtils.error("connectException:{}", e.getMessage());mBluetoothSocket = null;}}}.start();}

4.2连接成功或失败在广播中进行监听

4.3成功,需要开启子线程进行数据接收操作,失败,自行处理;

/*** 接收消息** @param consumer 数据回调*/public void reviceMsg(Consumer<String> consumer) {if (mBluetoothSocket == null) {LogUtils.error("reviceMsg socket is null");return;}new Thread() {@Overridepublic void run() {super.run();while (true) {char [] buffer = new char[1024];try {InputStream is = mBluetoothSocket.getInputStream();InputStreamReader inputStreamReader = new InputStreamReader(is, "GBK");int read = inputStreamReader.read(buffer);String readStr = new String(buffer, 0, read);LogUtils.info("reviceMsg:Msg ={};",readStr);consumer.accept(readStr);
//                        is.close();
//                        bluetoothSocket.close();} catch (Exception e) {LogUtils.error("reviceMsgException: {}", e.getMessage());}}}}.start();}

 4.4 同理,连接成功也需要像对应设备发送消息,代码如下:

 /*** 发送消息** @param msg    数据*/public void sendMsg(int msg) {if (mBluetoothSocket == null) {LogUtils.error("sendMsg socket is null");return;}new Thread() {@Overridepublic void run() {super.run();try {byte[] buffer = Integer.toHexString(msg).getBytes();OutputStream outputStream = mBluetoothSocket.getOutputStream();outputStream.write(buffer);outputStream.flush();LogUtils.info("sendMsg msg = {}",Integer.toHexString(msg));} catch (Exception e) {LogUtils.error("sendMsgException : {}", e.getMessage());}}}.start();}

5.后记

至此,蓝牙通信功能基本实现,其中需要在清单文件配置权限,在此给出;目前还不知道怎么网CSDN放自己的代码类,回头知道了进行补齐!

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /><uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

6.补充

上面蓝牙开启时会弹出一个询问是否想要开启蓝牙,如果选择拒接是没有回调的。处理不友好,查阅资料发现有个带回调的开启蓝牙方法贴出:

    public void startBlueToothCallBack(Activity activity){if (bluetoothAdapter == null) {return;}if (!bluetoothAdapter.isEnabled()) {Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);activity.startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);}}

在onActivityResult中进行回调操作:

@Overrideprotected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {super.onActivityResult(requestCode, resultCode, data);if (requestCode == BluetoothUtils.getInstance().REQUEST_ENABLE_BT && resultCode == RESULT_OK) {//蓝牙已开启searchBluetooth();} else {finish();}}


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

相关文章

【Android】蓝牙开发——BLE(低功耗蓝牙)(附完整Demo)

目录 目录 前言 一、相关概念介绍 二、实战开发 三、项目演示 四、Demo案例源码地址 五、更新记录 1、2020/12/29 &#xff1a;修改 setupService()中错误 2、2021/05/14 &#xff1a;更新连接方法&#xff08;解决部分蓝牙设备连接失败的问题&#xff09; 3、2022/1…

【Bluetooth开发】蓝牙开发入门

BLE 蓝牙设备在生活中无处不在&#xff0c;但是我们也只是将其作为蓝牙模块进行使用&#xff0c;发送简单的AT命令实现数据收发。 那么&#xff0c;像对于一些复杂的使用场合&#xff1a;“车载蓝牙”、"智能手表"、“蓝牙音箱”等&#xff0c;我们不得不去了解底层…

【Bluetooth蓝牙开发】一、蓝牙开发入门

一、蓝牙开发入门 文章目录 一、蓝牙开发入门 1、蓝牙概念2、蓝牙发展历程3、蓝牙技术概述 3.1 Basic Rate(BR)3.2 Low Energy&#xff08;LE&#xff09; 4、常见蓝牙架构 4.1 SOC蓝牙单芯片方案4.2 SOC蓝牙MCU方案4.3 蓝牙host controller分开方案4.4 使用场景 5、参考文档 …

vs2012做ArcGIS二次开发前期准备

解压ArcGIS 1.双击ESRI 2.点击 一路next&#xff0c;自己选择安装路径&#xff0c;建议放在非系统盘 3.开始菜单-ArcGIS-License Server Administrator 4.点击“stop/停止"&#xff0c;再点击确定 5.将破解文件中的两个文件拷到D:\Program Files (x86)\ArcGIS\License10.…

arcgis 二次开发学习笔记(一):了解二次开发有关的软件及其之间的关系

【废话篇】今天是大三开学的第一天课&#xff0c;终于意识到我口中念念不忘却没付出实际行动的“考研”来了。考研目标现在为止还没有很明确&#xff0c;只是不甘屈于人后。周围太多生活得很辛苦的人&#xff0c;只是不愿意我这一辈子也为了有关qian的小事斤斤计较&#xff0c;…

Arcobjects for java:Arcgis二次开发入门,开发一个基本地图组件

一、目的 因学习需要&#xff0c;使用Java进行Arcgis二次开发。当前对arcgis进行二次开发使用的语言基本是C#&#xff0c;使用Java对Arcgis进行二次开发的很少。于是使用java在idea上进行Arcgis二次开发&#xff0c;给入门的同学做参考&#xff0c;我自己也处于入门阶段&#…

ArcGIS二次开发基础教程(00):基础界面设计

ArcGIS二次开发基础教程(00) : 基础界面设计 (开发环境&#xff1a;VS2010ArcEngine10.2C# &#xff1b;鉴于学习ArcGIS二次开发的同学都有一定的WinForm开发和ArcGIS软件使用基础&#xff0c;故此教程不再对一些基础内容作详细阐述&#xff09; 首先新建一个Windows窗体应用程…

【ArcGIS二次开发】TOCControl右键菜单功能实现

1、添加现有项 ①右击解决方案中的项目&#xff0c;添加TOCControlContextMenu中的LayerSelectable、LayerVisibility、RemoveLayer、ZoomToLayer ②点击菜单栏中的项目&#xff0c;添加引用ESRI.ArcGIS.ADF.Local ③修改RemoveLayer中的命名空间为项目名称EngineMapTest&#…

arcgis python实例_arcgis二次开发_arcgis二次开发python_arcgis二次开发实例

[1.rar] - QQ连连看的源码.单消秒杀挂机等功能喜欢的朋友请拿去研究 [qqCHAR.rar] - qq 验证码识别程序 可以叫准确的识别出qq登陆前的验证码 [1.rar] - 本书以Visualc作为开发语言&#xff0c;结合大量实例&#xff0c;详细介绍了利用Arcobjects组件进行GIS二次开发的方法和…

【ArcGIS二次开发】Engine界面搭建

1、新建窗体项目Windows Appplication(Engine) 2、添加menuStrip、statusStrip和ToolbarControl控件&#xff0c;并设置相应的Dock属性为Top和Right 3、用SplitContainer控件把显示区域分成三部分&#xff0c;并设置splitContatiner1的Orientation属性为Horizontal 4、添加TabC…

ArcGIS二次开发基础教程(02):地图导航和鹰眼

ArcGIS二次开发基础教程(02)&#xff1a;地图导航和鹰眼 地图导航&#xff08;主要是调用命令和工具&#xff09; 地图的放缩和漫游 if(axMapControl1.CurrentTool null) {ICommand icc;//地图放大ITool tool new ControlsMapZoomInToolClass();//地图缩小//ITool tool n…

arcgis java 二次开发_arcgis二次开发_cad二次开发_java arcgis二次开发

属性查询是GIS应用不可缺少的重要功能&#xff0c;尤其是在各种业务系统中&#xff0c;根据用户输入相应的查询条件&#xff0c;从属性要素中快速定位到用户感兴趣的要素&#xff0c;为业务应用提供了便利。本文就来聊一聊QGis二次开发中如何实现属性查询功能。 其实这个功能我…

AE+ArcGIS二次开发课程设计(基于C#)

AEArcGIS二次开发课程设计&#xff08;基于C#&#xff09; 1.工作内容2.程序功能介绍3.功能模块介绍3.1 实现【创建TIN】说明3.1.1 功能说明3.1.2 代码实现&#xff08;包含了所有主要的代码&#xff0c;库引用自行导入&#xff09; 3.2 实现【TIN坡度坡向分析】说明3.2.1 功能…

ArcGIS二次开发前言

ArcGIS二次开发前言 前言环境常见bug解决方案 前言 自毕业成为GIS开发工程师已有一年多的时间&#xff0c;时间很短&#xff0c;短到不过人一生中工作时限的3.75%&#xff0c;时间很长&#xff0c;长到收藏夹已经从零攒到了一千四百多条记录&#xff0c;OneNote上也记录了几十…

ArcGIS Engine二次开发

目录 1 前言 2 准备工作 2.1 License的加入 2.2 ToolStrip控件 2.3 MenuStrip控件 2.4 帮助文档的查看 3 数据加载 3.1 矢量数据的加载 3.2 栅格数据的加载 4 地图浏览功能 1 前言 这是一份关于ArcGIS Engine二次开发的一份报告总结&#xff0c;在这份报告中包含了简单的…

ArcGIS二次开发知识点总结

空间分析定义&#xff1a;空间分析是指分析具有空间坐标或相对位置的数据和过程的理论和方法&#xff0c;是对地理空间现象的定量研究&#xff0c;其目的在于提取并传输空间数据中隐含的空间信息。 叠置分析定义&#xff1a;是指将同一坐标系统下不同信息表达的两组或多组专题…

【ArcGIS Pro二次开发】(31):ArcGIS Pro中的多线程

ArcGIS Pro与旧的ArcGIS桌面应用程序的显著不同之处在于&#xff0c;它采用多线程架构&#xff0c;可以有效的发挥多核CPU的优势。这使得二次开发工具的性能变得更好&#xff0c;但也对开发工作带来了更多的难点和挑战。 一、多线程需要注意的问题 一般情况下&#xff0c;为了…

GIS二次开发:实验一 ArcGIS Engine 开发初步

实验一 ArcGIS Engine 开发初步 一、实验目的 掌握ArcGIS Engine的安装&#xff1b;熟悉ArcGIS Engine中几个常用的控件&#xff1b;搭建第一个简单的ArcGIS Engine 程序&#xff1b;通过ICommand接口添加地图浏览工具。 二、实验仪器与设备 计算机、visual studio 软件、A…

Arcgis二次开发软件安装(Arcgis10.2、VS2012、AE10.2)

目录 一、序言 二、Arcgis10.2安装 &#xff08;一&#xff09;安装ArcGIS License Manager 1.1 ArcGIS License Manager安装 1.2 ArcGIS License Manager配置 &#xff08;二&#xff09;安装ArcGIS Desktop 1.1ArcGIS Desktop安装 1.2.ArcGIS文件替换 1.3中文显示与…

StackPanel 实现从上往下+从右往左 排列+RenderTransform特效实例分析

StackPanel:将子元素排列到可沿水平或垂直放置的行。 参考资料&#xff1a; 1. StackPanel类 2. Silverlight学习笔记&#xff08;九&#xff09;——RenderTransform特效【五种基本变换】及【矩阵变换MatrixTransform】 3. MatrixTransform矩阵变换 stack表明StackPane…