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.rhkb.cn/news/77762.html

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

相关文章

【汇总】解决Ajax请求后端接口,返回ModelAndView页面不跳转

【汇总】解决Ajax请求后端接口&#xff0c;返回ModelAndView不跳转 问题发现问题解决方法一&#xff1a;直接跳转到指定URL&#xff08;推荐&#xff09;方法二&#xff1a;将返回的html内容&#xff0c;插入到页面某个元素中方法三&#xff1a;操作文档流方法四&#xff1a;使…

docker更换数据存储路径

1. 先停掉docker服务 sudo systemctl stop docker 可能会出现的问题&#xff1a; 这样会导致docker关闭失败,解决办法&#xff1a;systemctl stop docker.socket 确保docker关闭: 2.备份现在的 Docker 数据存储目录 /var/lib/docker(默认路径) mv /var/lib/docker /var/lib/…

在IDEA同一个窗口中同时打开多个独立项目

文章说明 本文主要说明如何在Intellij Idea中同时打开多个独立的Maven项目。 我在使用idea的时候&#xff0c;由于自己负责了很多项目&#xff0c;经常要在不通的代码之间切换来切换去。然后搜索代码的时候也只能搜到当前打开的这个项目。因为这个原因&#xff0c;一些小项目…

vscode无法连接远程服务器的可能原因:远程服务器磁盘爆了

vscode输入密码后一直等待&#xff0c;无法进入远程服务器终端&#xff1a; 同时Remote-SSH输出包含以下内容 在日志中的以下几个部分&#xff1a; [17:15:05.529] > wget download failed 这表明VS Code尝试在远程服务器上下载VS Code服务器时失败了。> Cannot write…

多模态学习

一、目标 三、多模态核心任务 题目&#xff1a;

(12)理解委托,反射,Type,EvenInfo,插件, 组合枚举,BindingFlags,扩展方法及重载,XML认识

一、复习委托事件 1、委托复习。 private delegate int MyDelegate(int a, int b); //1.定义委托类型private static void Main(string[] args){MyDelegate md new MyDelegate(AddDelegate);//2.声明委托变量int result md(1, 2);//3.调用委托Console.WriteLine(result);Cons…

教您一招解决找素材困难好的方法

创作视频内容时&#xff0c;找到合适的素材是至关重要的。然而&#xff0c;有时候寻找视频素材可能会变得困难。本文将分享一些实用的方法&#xff0c;帮助您轻松解决找视频素材困难的问题。 素材库和在线平台是寻找视频素材的首选方法。 利用专业的视频剪辑工具 在电脑上安…

【云原生】K8S二进制搭建二:部署CNI网络组件

目录 一、K8S提供三大接口1.1容器运行时接口CRI1.2云原生网络接口CNI1.3云原生存储接口CSI 二、Flannel网络插件2.1K8S中Pod网络通信2.2Overlay Network2.3VXLAN2.4Flannel 三、Flannel udp 模式的工作原理3.1ETCD 之 Flannel 提供说明 四、vxlan 模式4.1Flannel vxlan 模式的工…

计算机视觉(六)图像分类

文章目录 常见的CNNAlexnet1乘1的卷积 VGG网络Googlenet&#xff08;Inception V1、V2、V3&#xff09;全局平均池化总结 Resnet、ResnextResNet残差网络ResNeXt网络 应用案例VGGResnet 常见的CNN Alexnet DNN深度学习革命的开始 沿着窗口进行归一化。 1乘1的卷积 VGG网络…

Linux葵花宝典-无需自宫版

1. Linux简介 1.1 什么是Linux Linux&#xff0c;全称GNU/Linux&#xff0c;是一种免费使用和自由传播的类UNIX操作系统&#xff0c;其内核由Linus Torvalds于1991年10月5日首次发布&#xff0c;它主要受到Minix和Unix思想的启发&#xff0c;是一个基于POSIX的多用户、多任务、…

unraid docker桥接模式打不开页面,主机模式正常

unraid 80x86版filebrowser&#xff0c;一次掉电后&#xff0c;重启出现权限问题&#xff0c;而且filebrowser的核显驱动不支持amd的VA-API 因为用不上核显驱动&#xff0c;解压缩功能也用不上&#xff0c;官方版本的filebrowser还小巧一些&#xff0c;18m左右 安装的时候总是…

HDFS中的sequence file

sequence file序列化文件 介绍优缺点格式未压缩格式基于record压缩格式基于block压缩格式 介绍 sequence file是hadoop提供的一种二进制文件存储格式一条数据称之为record&#xff08;记录&#xff09;&#xff0c;底层直接以<key, value>键值对形式序列化到文件中 优…

浅析RabbitMQ死信队列

原文首发于公众号【CSJerry】 在现代分布式系统中&#xff0c;消息队列扮演着至关重要的角色。它们可以实现应用程序之间的异步通信&#xff0c;并确保数据的可靠传输和处理。而在这个领域中&#xff0c;RabbitMQ作为一种强大而受欢迎的消息队列解决方案&#xff0c;具备了高…

基于Jenkins+Python+Ubuntu+Docker的接口/UI自动化测试环境部署详细过程

基于JenkinsPythonUbuntuDocker的接口/UI自动化测试环境部署详细过程 1 Jenkins是什么&#xff1f;2 Jenkins目标是什么&#xff1f;3 什么是CI/CD?3.1 CI持续集成3.2 CD持续部署3.3 CD持续交付 4 Ubuntu环境4.1 环境需求4.2 实现思路 5 Ubuntu下安装Docker6 安装Jenkins6.1 拉…

idea如何加快创建Maven项目的速度

一、下载archetype-catalog.xml 下载archetype-catalog.xml的地址 二、配置 以下所说的配置都指全局配置。 配置Maven -DarchetypeCataloglocal -Dfile.encodinggbk

深度学习基础知识扫盲

深度学习 监督学习&#xff08;Supervised learning&#xff09;监督学习分类 无监督学习&#xff08;Non-supervised learning&#xff09;无监督学习的算法无监督学习使用场景 术语特征值特征向量特征工程&#xff08;Feature engineering&#xff09;特征缩放Sigmod functio…

使用Golang实现一套流程可配置,适用于广告、推荐系统的业务性框架——简单应用

在诸如广告、推荐等系统中&#xff0c;我们往往会涉及过滤、召回和排序等过程。随着系统业务变得复杂&#xff0c;代码的耦合和交错会让项目跌入难以维护的深渊。于是模块化设计是复杂系统的必备基础。这篇文章介绍的业务框架脱胎于线上多人协作开发、高并发的竞价广告系统&…

数据库操作系列-Mysql, Postgres常用sql语句总结

文章目录 1.如果我想要写一句sql语句&#xff0c;实现 如果存在则更新&#xff0c;否则就插入新数据&#xff0c;如何解决&#xff1f;MySQL数据库实现方案: ON DUPLICATE KEY UPDATE写法 Postgres数据库实现方案:方案1&#xff1a;方案2&#xff1a;关于更新&#xff1a;如何实…

前端js--扩展卡片

效果图 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><link rel"stylesheet" href"…

构建器/建造者/构建者模式(C++)

定义 将一个复杂对象的构建与其表示相分离,使得同样的构建过程(稳定)可以创建不同的表示(变化)。 应用场景 在软件系统中&#xff0c;有时候面临着“一个复杂对象”的创建工作&#xff0c;其通常由各个部分的子对象用一定的算法构成;由于需求的变化&#xff0c;这个复杂对象…