700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Java:PC端作为客户端连接蓝牙设备并接收蓝牙发送的数据

Java:PC端作为客户端连接蓝牙设备并接收蓝牙发送的数据

时间:2020-10-09 10:26:45

相关推荐

Java:PC端作为客户端连接蓝牙设备并接收蓝牙发送的数据

感谢:(1)PC端蓝牙开发/zeussbook/p/12827479.html

/svizzera/article/details/77434917

(2)解决数据读取乱序/clliu_hust/article/details/80874272

一、蓝牙流程

蓝牙客户端Socket的与Sokcet流程是一样的,只不过参数不同而已。如下:

1、创建客户端蓝牙Sokcet

2、创建连接

3、读写数据

4、关闭

二、导入jar包

需要导入第三方的蓝牙bluecove.jar包。其中32位系统和64位系统所导的包不同,需要区分。否则会报错。BlueCove还需要Apache的commons-io包,这个顺便下就可以的。

PS:如果启动报错:bluecove native library version mismatch,可尝试把commons-io包去掉。

链接:/s/1tFixZRIRaN4HdlslDlKhuQ

提取码:rr12

三、代码部分

3.1设备查找类

package com.jcsim;/*** Created with IntelliJ IDEA.** @Author: Jcsim* @Date: /11/25 15:15* @Description:设备查找类*/import java.io.IOException;import java.util.HashSet;import java.util.Set;import java.util.Vector;import javax.bluetooth.DataElement;import javax.bluetooth.DeviceClass;import javax.bluetooth.DiscoveryAgent;import javax.bluetooth.DiscoveryListener;import javax.bluetooth.LocalDevice;import javax.bluetooth.RemoteDevice;import javax.bluetooth.ServiceRecord;import javax.bluetooth.UUID;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();}}/*** 发现设备* @param remoteDevice* @param deviceClass*/@Overridepublic void deviceDiscovered(RemoteDevice remoteDevice, DeviceClass deviceClass) {devicesDiscovered.add(remoteDevice);try {System.out.println("#发现设备" + remoteDevice.getFriendlyName(false)+" 设备地址:"+remoteDevice.getBluetoothAddress());} catch (IOException e) {e.printStackTrace();}}/*** 发现服务* @param transID id* @param servRecord 服务记录*/@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");}/*** 服务搜索已完成* @param arg0* @param arg1*/@Overridepublic void serviceSearchCompleted(int arg0, int arg1) {System.out.println("#" + "serviceSearchCompleted");synchronized(serviceSearchCompletedEvent){serviceSearchCompletedEvent.notifyAll();}}};/*** 查找设备* @throws IOException* @throws InterruptedException*/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());}}}/*** 获取设备* @return* @throws IOException* @throws InterruptedException*/public static Set<RemoteDevice> getDevices() throws IOException, InterruptedException {findDevices();return devicesDiscovered;}/*** 查找服务* @param btDevice* @param serviceUUID* @return* @throws IOException* @throws InterruptedException*/public static String searchService(RemoteDevice btDevice, String serviceUUID) throws IOException, InterruptedException {UUID[] searchUuidSet = new UUID[] { new UUID(serviceUUID, false) };int[] attrIDs = new int[] {0x0100 // Service name};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 "";}}}

3.2蓝牙客户端类

package com.jcsim;/*** Created with IntelliJ IDEA.** @Author: Jcsim* @Date: /11/25 15:14* @Description:蓝牙客户端类*/import java.io.DataInputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.Set;import javax.bluetooth.BluetoothConnectionException;import javax.bluetooth.RemoteDevice;import javax.microedition.io.Connector;import javax.microedition.io.StreamConnection;public class BluetoothClient {private StreamConnection streamConnection;//流连接private OnDiscoverListener onDiscoverListener = null;//发现监听private OnClientListener onClientListener = null;//客户端监听/*** 客户端监听*/public interface OnClientListener {void onConnected(DataInputStream inputStream, OutputStream outputStream);void onConnectionFailed();void onDisconnected();void onClose();}/*** 发现监听*/public interface OnDiscoverListener {void onDiscover(RemoteDevice remoteDevice);}/*** 无参构造函数*/public BluetoothClient() {}/*** 查找所有* @throws IOException* @throws InterruptedException*/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);}}/*** 启动连接* @param remoteDevice* @throws IOException* @throws InterruptedException*/public void startClient(RemoteDevice remoteDevice) throws IOException, InterruptedException {// String url = RemoteDeviceDiscovery.searchService(remoteDevice, serviceUUID);// System.out.println("url=="+url);// 1 为通道;authenticate=true;encrypt=true表示需要验证pin码// btspp://<蓝牙设备地址>:<通道号>String url = "btspp://"+remoteDevice.getBluetoothAddress()+":1;authenticate=true;encrypt=true";try{streamConnection = (StreamConnection) Connector.open(url);if (this.onClientListener != null) {this.onClientListener.onConnected(streamConnection.openDataInputStream(), streamConnection.openOutputStream());}else{System.out.println("请打开蓝牙");}} catch (BluetoothConnectionException e){e.printStackTrace();System.out.println("蓝牙连接错误,请查看蓝牙是否打开。");}catch (Exception e){e.printStackTrace();}}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;}}

3.3 蓝牙客户端业务类

package com.jcsim;/*** Created with IntelliJ IDEA.** @Author: Jcsim* @Date: /11/25 15:17* @Description:蓝牙客户端业务类*/import javax.bluetooth.RemoteDevice;import javax.microedition.io.ConnectionNotFoundException;import java.io.DataInputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Vector;public class BluetoothClientService {public static void main(String[] argv) {final String serverUUID = "1000110100001000800000805F9B34FB"; //需要与服务端相同BluetoothClient client = new BluetoothClient();Vector<RemoteDevice> remoteDevices = new Vector<>();Boolean isConnect = false;client.setOnDiscoverListener(new BluetoothClient.OnDiscoverListener() {@Overridepublic void onDiscover(RemoteDevice remoteDevice) {remoteDevices.add(remoteDevice);}});client.setClientListener(new BluetoothClient.OnClientListener() {@Overridepublic void onConnected(DataInputStream inputStream, OutputStream outputStream) {System.out.printf("Connected");// 开启线程读写蓝牙上接收和发送的数据。new Thread(new Runnable() {@Overridepublic void run() {try {System.out.println("客户端开始监听...");// System.out.println("接收连接");// System.out.println("开始读数据...");SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");while (true) {byte[] buffer = new byte[1024];int bytes=0;int ch;// inputStream.read(buffer)while ((ch = inputStream.read()) != '\n') {// 读数据。//String s = new String(buffer);//System.out.println("===========start=============");//System.out.println(s.trim());//System.out.println("------------end------------");//Thread.sleep(1000);if(ch!=-1){buffer[bytes] = (byte) ch;bytes++;}}buffer[bytes] = (byte)'\n';bytes++;String s = new String(buffer);System.out.println("===========start=============");System.out.println(df.format(new Date())+"->"+s.trim());System.out.println("------------end------------");// inputStream.close();// onClose();}} catch (Exception e) {e.printStackTrace();}}}).start();}@Overridepublic void onConnectionFailed() {System.out.printf("Connection failed");}@Overridepublic void onDisconnected() {}@Overridepublic void onClose() {}});try {client.find();if (remoteDevices.size() > 0 ) {for(int i=0;i<remoteDevices.size();i++){System.out.println("第"+i+"个地址为:"+remoteDevices.get(i).getBluetoothAddress());if( "所要连接的蓝牙的地址".equals(remoteDevices.get(i).getBluetoothAddress())){isConnect = true;client.startClient(remoteDevices.get(i));break;}}if (!isConnect){System.out.println("请打开传感器蓝牙设备。");}//System.out.println("remoteDevices.firstElement="+remoteDevices.firstElement());}else {System.out.println("附件没有蓝牙设备");}} catch (ConnectionNotFoundException e){System.out.println("当前蓝牙不在线");e.printStackTrace();} catch (InterruptedException | IOException e) {e.printStackTrace();}}}

四、读数据

之前读取数据的时候,一直乱码或乱序(一段字符被分成几段)。

乱码解决方法:蓝牙发送的波特率问题,一般为9600。

乱序:使用InputStream读取时不能和串口一样设置一个结束符(串口的结束符一般是换行符'\r\n'),于是线程读取就很随机性了,你不知道它在什么时候就读完一刀下去,你的字符串就不完整了。

旧方法(乱序):

while (true) {byte[] buffer = new byte[1024];// while (inputStream.read(buffer) != -1) {// 读数据。String s = new String(buffer);System.out.println("===========start=============");System.out.println(s.trim());System.out.println("------------end------------");Thread.sleep(1000);}// inputStream.close();// onClose();}

乱序解决方法:使用InputStream.read()逐个读取字符,判读是不是结束符,如果没到结束符就一直读取写入

SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");while (true) {byte[] buffer = new byte[1024];int bytes = 0; //字符串长度int ch; // 读取字符的变量while ((ch = inputStream.read()) != '\n') {// 读数据。if(ch!=-1){buffer[bytes] = (byte) ch; // 将读取到的字符写入bytes++;}}buffer[bytes] = (byte)'\n'; //最后加上一个换行bytes++;String s = new String(buffer);System.out.println("===========start=============");System.out.println(df.format(new Date())+"->"+s.trim());System.out.println("------------end------------");}

五、GitHub地址

/jiancong952/bluetooth_java.git

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。