JNI之Java实现蓝牙交互

蓝牙概述

蓝牙,是一种支持设备短距离通信(一般10m内)的无线电技术,能在包括移动电话、PDA、无线耳机、笔记本电脑、相关外设等众多设备之间,通过蓝牙设备之间的无线通信实现数据传输,实现数据传输,音频传输,文件传输,图片传输等多种应用的无线信息交换。利用“蓝牙”技术,能够有效地简化移动通信终端设备之间的通信,也能够成功地简化设备与因特网Internet之间的通信,从而数据传输变得更加迅速高效,为无线通信拓宽道路。蓝牙技术是一种无线数据和语音通信开放的全球规范,它是基于低成本的近距离无线连接,为固定和移动设备建立通信环境的一种特殊的近距离无线技术连接。目前,越来越多的企业采用蓝牙交互技术来实现自己的产品。

Java实现蓝牙交互的优势

Java是世界上最流行的编程语言之一。Java具有平台无关性、对象化编程、简单易用、可扩展性等特点,因此目前已广泛应用于企业和互联网领域。Java还提供了很好的蓝牙接口,可以帮助企业快速开发蓝牙交互应用。Java的蓝牙接口是基于JSR-82标准实现的,这个标准允许JAVA应用程序访问蓝牙网络的API。与其他大多数蓝牙接口不同,JSR-82可以在任意实现了JSR-82标准的蓝牙设备间进行通讯,这就保证了兼容性和灵活性。

蓝牙通信的原理

蓝牙技术规定每一对设备之间进行蓝牙通讯时,必须一个为主角色,另一为从角色,才能进行通信,通信时,必须由主端进行查找,发起配对,建链成功后,双方即可收发数据。

蓝牙主端设备发起呼叫,首先是查找,找出周围处于可被查找的蓝牙设备。主端设备找到从端蓝牙设备后,与从端蓝牙设备进行配对,此时需要输入从端设备的PIN码,也有设备不需要输入PIN码。

配对完成后,从端蓝牙设备会记录主端设备的信任信息,此时主端即可向从端设备发起呼叫,已配对的设备在下次呼叫时,不再需要重新配对。

Java蓝牙交互应用实例

导包

<dependency><groupId>net.sf.bluecove</groupId><artifactId>bluecove</artifactId><version>2.1.0</version>
</dependency>

BluetoothServer

public class BluetoothServer implements Runnable {//本机蓝牙设备private LocalDevice local = null;// 流连接private StreamConnection streamConnection = null;// 输入流private InputStream inputStream;private OutputStream outputStream;//接入通知private StreamConnectionNotifier notifier;//线程池private final static ExecutorService service = Executors.newCachedThreadPool();public String serverName;public String serverUUID;private OnServerListener mServerListener;public interface OnServerListener {void onConnected(InputStream inputStream, OutputStream outputStream);void onDisconnected();void onClose();}public BluetoothServer(String serverUUID, String serverName) {this.serverUUID = serverUUID;this.serverName = serverName;}public void start() {try {local = LocalDevice.getLocalDevice();if (!local.setDiscoverable(DiscoveryAgent.GIAC)) {System.out.println("请将蓝牙设置为可被发现");}/*** 作为服务端,被请求  ";name="+serverName;*/String url = "btspp://localhost:" +  serverUUID;notifier = (StreamConnectionNotifier) Connector.open(url);service.submit(this);} catch (IOException e) {System.out.println(e.getMessage());;}}public OnServerListener getServerListener() {return mServerListener;}public void setServerListener(OnServerListener mServerListener) {this.mServerListener = mServerListener;}@Overridepublic void run() {try {//阻塞的,等待设备连接streamConnection = notifier.acceptAndOpen();               inputStream = streamConnection.openInputStream();outputStream = streamConnection.openOutputStream();if (mServerListener != null) {mServerListener.onConnected(inputStream, outputStream);}} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();} finally {}}
}

BluetoothClient

public class BluetoothClient {private StreamConnection streamConnection;private OnDiscoverListener onDiscoverListener = null;private OnClientListener onClientListener = null;public interface OnClientListener {void onConnected(InputStream inputStream, OutputStream outputStream);void onConnectionFailed();void onDisconnected();void onClose();}public interface OnDiscoverListener {void onDiscover(RemoteDevice remoteDevice);}public BluetoothClient() {}public OnDiscoverListener getOnDiscoverListener() {return onDiscoverListener;}public void setOnDiscoverListener(OnDiscoverListener onDiscoverListener) {this.onDiscoverListener = onDiscoverListener;}public OnClientListener getClientListener() {return onClientListener;}public void setClientListener(OnClientListener onClientListener) {this.onClientListener = onClientListener;}public void find() throws IOException, InterruptedException {//附近所有的蓝牙设备,必须先执行 runDiscoverySet<RemoteDevice> devicesDiscovered = RemoteDeviceDiscovery.getDevices();       Iterator<RemoteDevice> itr = devicesDiscovered.iterator();//连接while (itr.hasNext()) {                                  RemoteDevice remoteDevice = itr.next();onDiscoverListener.onDiscover(remoteDevice);}}public void startClient(RemoteDevice remoteDevice, String serviceUUID) throws IOException, InterruptedException {String url = RemoteDeviceDiscovery.searchService(remoteDevice, serviceUUID);streamConnection = (StreamConnection) Connector.open(url);if (this.onClientListener != null) {this.onClientListener.onConnected(streamConnection.openInputStream(), streamConnection.openOutputStream());}}
}

RemoteDeviceDiscovery

public class RemoteDeviceDiscovery {public final static Set<RemoteDevice> devicesDiscovered = new HashSet<RemoteDevice>();public final static Vector<String> serviceFound = new Vector<String>();final static Object serviceSearchCompletedEvent = new Object();final static Object inquiryCompletedEvent = new Object();private static DiscoveryListener listener = new DiscoveryListener() {public void inquiryCompleted(int discType) {System.out.println("#" + "搜索完成");synchronized (inquiryCompletedEvent) {inquiryCompletedEvent.notifyAll();}}@Overridepublic void deviceDiscovered(RemoteDevice remoteDevice, DeviceClass deviceClass) {devicesDiscovered.add(remoteDevice);try {System.out.println("#发现设备" + remoteDevice.getFriendlyName(false));} catch (IOException e) {e.printStackTrace();}}@Overridepublic void servicesDiscovered(int transID, ServiceRecord[] servRecord) {for (int i = 0; i < servRecord.length; i++) {String url = servRecord[i].getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);if (url == null) {continue;}serviceFound.add(url);DataElement serviceName = servRecord[i].getAttributeValue(0x0100);if (serviceName != null) {System.out.println("service " + serviceName.getValue() + " found " + url);} else {System.out.println("service found " + url);}}System.out.println("#" + "servicesDiscovered");}@Overridepublic void serviceSearchCompleted(int arg0, int arg1) {System.out.println("#" + "serviceSearchCompleted");synchronized(serviceSearchCompletedEvent){serviceSearchCompletedEvent.notifyAll();}}};private static void findDevices() throws IOException, InterruptedException {devicesDiscovered.clear();synchronized (inquiryCompletedEvent) {LocalDevice ld = LocalDevice.getLocalDevice();System.out.println("#本机蓝牙名称:" + ld.getFriendlyName());boolean started = LocalDevice.getLocalDevice().getDiscoveryAgent().startInquiry(DiscoveryAgent.GIAC,listener);if (started) {System.out.println("#" + "等待搜索完成...");inquiryCompletedEvent.wait();LocalDevice.getLocalDevice().getDiscoveryAgent().cancelInquiry(listener);System.out.println("#发现设备数量:" + devicesDiscovered.size());}}}public static Set<RemoteDevice> getDevices() throws IOException, InterruptedException {findDevices();return devicesDiscovered;}public static String searchService(RemoteDevice btDevice, String serviceUUID) throws IOException, InterruptedException {UUID[] searchUuidSet = new UUID[] { new UUID(serviceUUID, false) };int[] attrIDs =  new int[] {// Service name0x0100 };synchronized(serviceSearchCompletedEvent) {System.out.println("search services on " + btDevice.getBluetoothAddress() + " " + btDevice.getFriendlyName(false));LocalDevice.getLocalDevice().getDiscoveryAgent().searchServices(attrIDs, searchUuidSet, btDevice, listener);serviceSearchCompletedEvent.wait();}if (serviceFound.size() > 0) {return serviceFound.elementAt(0);} else {return "";}}
}

测试

Bluetooth Server
@Test
public void test(){final String serverName = "Bluetooth Server Test";final String serverUUID = "1000110100001000800000805F9B34FB";  //根据需要自定义BluetoothServer server = new BluetoothServer(serverUUID, serverName);server.setServerListener(new BluetoothServer.OnServerListener() {@Overridepublic void onConnected(InputStream inputStream, OutputStream outputStream) {System.out.printf("Connected");//添加通信代码}@Overridepublic void onDisconnected() {}@Overridepublic void onClose() {}});server.start();
}
测试结果
Connected to the target VM, address: '127.0.0.1:8442', transport: 'socket'
Native Library intelbth_x64 not available
Native Library bluecove_x64 not available
BlueCove libraries not available
Disconnected from the target VM, address: '127.0.0.1:8442', transport: 'socket'

没有找到_64的包。

看看导包的版本

下载_64版本

官网:BlueCove - BlueCove JSR-82 project

下载地址:https://sourceforge.net/projects/bluecove/files/

ps:下面自己测试吧。

JNI,Java Native Interface,主要是通过读取其他底层语言的文件,转换成Java的类,操作设备。

另外还有连接打印机、pos机等,也是使用Java的JNI调用其他底层语言的文件,如打印机使用jacob读取dll文件、可实现无接触操作语音智能打印等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/24405.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【计算机视觉|语音分离】期望在嘈杂环境中聆听:一个用于语音分离的不依赖于讲话者的“音频-视觉模型”

本系列博文为深度学习/计算机视觉论文笔记&#xff0c;转载请注明出处 标题&#xff1a;Looking to Listen at the Cocktail Party: A Speaker-Independent Audio-Visual Model for Speech Separation 链接&#xff1a;Looking to listen at the cocktail party: a speaker-in…

【网络工程】网络流量分析工具 Wireshark

文章目录 第一章&#xff1a;WireShark介绍第二章&#xff1a;WireShark应用第三章&#xff1a;Wireshark 实战 第一章&#xff1a;WireShark介绍 Wireshark (前身 Ethereal)&#xff1a;它是一个强大的网络包分析工具 ! 此工具主要是用来捕获网络数据包的&#xff0c;并且自动…

zookeeper --- 基础篇

一、zookeeper简介 1.1、什么是zookeeper zookeeper官网&#xff1a;https://zookeeper.apache.org/ 大数据生态系统里的很多组件的命名都是某种动物或者昆虫&#xff0c;他是用来管 Hadoop&#xff08;大象&#xff09;、Hive(蜜蜂)、Pig(小 猪)的管理员。顾名思义就是管理…

zabbix触发器标签提取监控项子字符串实现对应告警恢复

0 实验环境 zabbix 6.0 1 监控项 1.1 监控项设置 通过zabbix agent自定义监控项&#xff0c;读取某文件内容模拟日志/trap告警&#xff0c;测试获取触发器标签中提取子字符串功能&#xff0c;以及相同标签的触发器自动恢复功能。 1.2 手工运行 手动触发之后&#xff0c;模…

在centos7上使用非编译方式安装ffmpeg

很多在centos7上安装ffmpeg的教程都需要使用编译方式的安装&#xff1b;编译时间较长而且需要配置; 后来搜索到可以通过加载rpm 源的方式实现快速便捷操作 第一种方式&#xff1a; 首先需要安装yum源&#xff1a; yum install epel-release yum install -y https://mirrors.…

echarts 图例组件legend配置

legend 图例组件展示不同系列的图表类型标记、颜色、和名称。可以通过点击来控制哪个系列不展示。对于饼图来说&#xff0c;控制哪个数据不展示。 $> echarts5.4.0简单画一个饼图作为示例,设置legend:{show:true}展示图例。 const options {legend: {show: true,},series…

Java List(列表)

List 是一个有序、可重复的集合&#xff0c;集合中每个元素都有其对应的顺序索引。List 集合允许使用重复元素&#xff0c;可以通过索引来访问指定位置的集合元素。List 集合默认按元素的添加顺序设置元素的索引&#xff0c;第一个添加到 List 集合中的元素的索引为 0&#xff…

ELK 企业级日志分析系统(ElasticSearch、Logstash 和 Kiabana 详解)

目录 一.ELK简介 1.1ELK的概述 1.2ELK的组成 1.2.1 ElasticSearch 1.2.2 Logstash 1.2.3 Kibana 1.2.4 小总结 1.3可以添加其他组件 1.4filebeat 结合 logstash 带来好处 1.5日志处理的步骤 二.Elasticsearch 2.1Elasticsearch概述 2.2Elasticsearch核心概念 2.2.1接近…

使用可视化docker浏览器,轻松实现分布式web自动化

01、前言 顺着docker的发展&#xff0c;很多测试的同学也已经在测试工作上使用docker作为环境基础去进行一些自动化测试&#xff0c;这篇文章主要讲述我们在docker中使用浏览器进行自动化测试如果可以实现可视化&#xff0c;同时可以对浏览器进行相关的操作。 02、开篇 首先…

【云原生】Docker中容器管理常用所有命令

1.docker 容器创建流程 2.容器运行本质 docker run [OPTIONS] IMAGE [COMMAND] [ARG...] 创建容器基本选项&#xff1a;--name&#xff1a;为容器命名 -i&#xff1a;交互式创建容器 -d&#xff1a;后台创建容器 -t&#xff1a;为容器分配伪终端 Docker 容器存在的意义就是为…

机器学习笔记之优化算法(六)线搜索方法(步长角度;非精确搜索;Glodstein Condition)

机器学习笔记之优化算法——线搜索方法[步长角度&#xff0c;非精确搜索&#xff0c;Glodstein Condition] 引言回顾&#xff1a; Armijo Condition \text{Armijo Condition} Armijo Condition关于 Armijo Condition \text{Armijo Condition} Armijo Condition的弊端 Glodstein…

jenkins准备

回到目录 jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具&#xff0c;主要用于持续、自动的构建/测试软件项目、监控外部任务的运行。Jenkins用Java语言编写&#xff0c;可在Tomcat等流行的servlet容器中运行&#xff0c;也可独立运行。通常与版本管理工具(SCM)、构…

【设计模式】单例模式

什么是单例模式&#xff1f; 保证一个类仅有一个实例&#xff0c;并提供一个访问它的全局访问点 单例模式的应用场景 1.整个程序的运行中只允许有一个类的实例&#xff1b; 2.需要频繁实例化然后销毁的对象。 3.创建对象时耗时过多或者耗资源过多&#xff0c;但又经常用到…

阿里云容器服务助力极氪荣获 FinOps 先锋实践者

作者&#xff1a;海迩 可信云评估是中国信息通信研究院下属的云计算服务和软件的专业评估体系&#xff0c;自 2013 年起历经十年发展&#xff0c;可信云服务评估体系已日臻成熟&#xff0c;成为政府支撑、行业规范、用户选型的重要参考。 2022 年 5 月国务院国资委制定印发《…

【云原生】K8S二进制搭建一

目录 一、环境部署1.1操作系统初始化 二、部署etcd集群2.1 准备签发证书环境在 master01 节点上操作在 node01与02 节点上操作 三、部署docker引擎四、部署 Master 组件4.1在 master01 节点上操 五、部署Worker Node组件 一、环境部署 集群IP组件k8s集群master01192.168.243.1…

ceil(),floor(),round()函数C++详解

ceil&#xff08;&#xff09; ceil()函数是这样的&#xff1a; double ceil(double x) ceil函数可以把x上取整。 例子&#xff1a; #include <bits/stdc.h> using namespace std; int main() {double a, b;cin >> a >> b;printf("ceil(%.2f) %.2…

消息队列项目(2)

我们使用 SQLite 来进行对 Exchange, Queue, Binding 的硬盘保存 对 Message 就保存在硬盘的文本中 SQLite 封装 这里是在 application.yaml 中来引进对 SQLite 的封装 spring:datasource:url: jdbc:sqlite:./data/meta.dbusername:password:driver-class-name: org.sqlite.…

自定义elementui的主题

通常情况下&#xff0c;我们使用elementui框架的时候默认组件的主题都是白色的&#xff0c;比如&#xff1a; 但是如果想自定义主题&#xff0c;改变主题颜色&#xff0c;以及各种默认颜色&#xff0c;其实也不难&#xff1a; 配置默认主题&#xff0c;选好后点击下载 在vu…

墨觉Run Plus耳机真的很好嘛?南卡、韶音、墨觉哪个好

随着近年来蓝牙耳机市场的快速变化&#xff0c;耳机的样式也在不断演变&#xff0c;从入耳式发展到无需入耳的骨传导耳机。骨传导耳机因其可以通过骨传导技术进行声音传输&#xff0c;无需贴合耳道即可实现耳机功能&#xff0c;因此备受市场欢迎。尤其是近两年&#xff0c;骨传…

关于简单C++函数在内存中的存储问题

举例 int main(){... }int data(){... }int add(){... } 在分段式存储管理时&#xff0c;根据人们的需求&#xff0c;人为分段存储 如图&#xff1a;