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.hqwc.cn/news/54509.html

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

相关文章

中国政府版 Windows 10 开发完成,即将大规模推广

早在今年 3 月 20 日&#xff0c;就有媒体曝光中国政府专用 Windows 10 已经完成第一版。而就在今天微软在上海举办的发布会中&#xff0c;微软再次透露了中国政府版 Windows 10 的最新情况——已经开始试点测试。这就意味着政府版 Windows 10 或很快大规模推广。 据了解&#…

FFmpeg中硬解码后深度学习模型的图像处理dnn_processing(一)

ffmpeg 硬件解码 ffmpeg硬件解码可以使用最新的vulkan来做&#xff0c;基本上来说&#xff0c;不挑操作系统是比较重要的&#xff0c;如果直接使用cuda也是非常好的选择。 AVPixelFormat sourcepf AV_PIX_FMT_NV12;// AV_PIX_FMT_NV12;// AV_PIX_FMT_YUV420P;AVPixelFormat d…

【java安全】CommonsBeanUtils1

文章目录 【java安全】CommonsBeanUtils1前言Apache Commons BeanutilsBeanComparator如何调用BeanComparator#compare()方法&#xff1f;构造POC完整POC 调用链 【java安全】CommonsBeanUtils1 前言 在之前我们学习了java.util.PriorityQueue&#xff0c;它是java中的一个优…

计算机视觉与图形学-神经渲染专题-Seal-3D(基于NeRF的像素级交互式编辑)

摘要 随着隐式神经表示或神经辐射场 (NeRF) 的流行&#xff0c;迫切需要与隐式 3D 模型交互的编辑方法&#xff0c;以完成后处理重建场景和 3D 内容创建等任务。虽然之前的作品从不同角度探索了 NeRF 编辑&#xff0c;但它们在编辑灵活性、质量和速度方面受到限制&#xff0c;无…

海外媒体发稿:软文写作方法方式?一篇好的软文理应合理规划?

不同种类的软文会有不同的方式&#xff0c;下面小编就来来给大家分析一下&#xff1a; 方法一、要选定文章的突破点&#xff1a; 所说突破点就是这篇文章文章软文理应以什么样的视角、什么样的见解、什么样的语言设计理念、如何文章文章的标题来写。不同种类的传播效果&#…

ubuntu搭建wifi热点,共享网络(x86、arm相同)

目录 1 首先检查网络管理器服务是否开启 &#xff08;ubuntu需要界面&#xff09; 2 创建并配置需要共享的wifi 首先&#xff0c;明确下这篇文章说的是啥&#xff0c;是为了在ubuntu系统的电脑上&#xff0c;搭建一个wifi热点&#xff0c;供其他移动设备连接上网。就像你…

【Android】控件与布局入门 - 简易计算器

目录 1. 基础开发环境 2. 计算器的布局和相关按钮 3. 计算器的主要运算逻辑 4. APK 文件 5. 项目源码 1. 基础开发环境 JDK&#xff1a;JDK17 Android Studio&#xff1a;Android Studio Giraffe | 2022.3.1 Android SDK&#xff1a;Android API 34 Gradle: gradle-8.0-bi…

MySQL5.7源码编译Debug版本

编译环境Ubuntu22.04LTS 1 官方下载MySQL源码 https://dev.mysql.com/downloads/mysql/?spma2c6h.12873639.article-detail.4.68e61a14ghILh5 2 安装基础软件 cmakeclangpkg-configperl 参考&#xff1a;https://dev.mysql.com/doc/refman/5.7/en/source-installation-prere…

LeetCode-Java(05)

19. 删除链表的倒数第 N 个结点 两个方法&#xff0c;方法一是先走一遍链表得出链表长度&#xff0c;再走第二遍&#xff0c;找到倒数第n个数。方法二是双指针&#xff0c;首先快指针就比慢指针多走n步&#xff0c;然后这俩指针同步走&#xff0c;快指针走到头了&#xff0c;慢…

uni-app、H5实现瀑布流效果封装,列可以自定义

文章目录 前言一、效果二、使用代码三、核心代码总结 前言 最近做项目需要实现uni-app、H5实现瀑布流效果封装&#xff0c;网上搜索有很多的例子&#xff0c;但是代码都是不够完整的&#xff0c;下面来封装一个uni-app、H5都能用的代码。在小程序中&#xff0c;一个个item渲染…

redis缓存雪崩和缓存击穿

目录 缓存雪崩 解决方案&#xff1a; 缓存击穿 ​解决方案 缓存雪崩 缓存雪崩是指在同一时段大量的缓存key同时失效或者Redis服务宕机&#xff0c;导致大量请求到达数据库&#xff0c;带来巨大压力。 解决方案&#xff1a; u 给不同的 Key 的 TTL 添加随机值 u 利用 Redis …

【黑马头条之kafka及异步通知文章上下架】

本笔记内容为黑马头条项目的kafka及异步通知文章上下架部分 目录 一、kafka概述 二、kafka安装配置 三、kafka入门 四、kafka高可用设计 1、集群 2、备份机制(Replication&#xff09; 五、kafka生产者详解 1、发送类型 2、参数详解 六、kafka消费者详解 1、消费者…