Java:PCは、Bluetoothデバイスに接続し、Bluetoothによって送信されたデータを受信するためのクライアントとして使用されます

ありがとう:(1)PCBluetooth開発  https://www.cnblogs.com/zeussbook/p/12827479.html

                                             https://blog.csdn.net/svizzera/article/details/77434917

           (2)データ読み取りの障害を解決する  https://blog.csdn.net/clliu_hust/article/details/80874272

1.Bluetoothプロセス

BluetoothクライアントSocketとSokcetのプロセスは同じですが、パラメーターが異なります。次のように:
1。クライアントBluetoothSokcetを作成します
2.接続を作成します
3.データの読み取りと書き込み
4.閉じる

 

2つ目は、jarパッケージをインポートすることです。

サードパーティのBluetoothbluecove.jarパッケージをインポートする必要があります。その中で、32ビットシステムと64ビットシステムは異なるパッケージをガイドするため、区別する必要があります。それ以外の場合は、エラーが報告されます。BlueCoveには、Apacheのcommons-ioパッケージも必要です。これはちなみに実行できます。

リンク:https 
://pan.baidu.com/s/1tFixZRIRaN4HdlslDlKhuQ抽出コード:rr12 

三、コード部分

3.1デバイス検索クラス

package com.jcsim;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: Jcsim
 * @Date: 2020/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
         */
        @Override
        public 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 服务记录
         */
        @Override
        public 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
         */
        @Override
        public 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.2Bluetoothクライアントクラス

package com.jcsim;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: Jcsim
 * @Date: 2020/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 {
        //附近所有的蓝牙设备,必须先执行 runDiscovery
        Set<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.3Bluetoothクライアントサービス

package com.jcsim;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: Jcsim
 * @Date: 2020/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() {

            @Override
            public void onDiscover(RemoteDevice remoteDevice) {
                remoteDevices.add(remoteDevice);
            }

        });

        client.setClientListener(new BluetoothClient.OnClientListener() {

            @Override
            public void onConnected(DataInputStream inputStream, OutputStream outputStream) {
                System.out.printf("Connected");
                // 开启线程读写蓝牙上接收和发送的数据。
                new Thread(new Runnable() {
                    @Override
                    public 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();

            }

            @Override
            public void onConnectionFailed() {
                System.out.printf("Connection failed");
            }

            @Override
            public void onDisconnected() {

            }

            @Override
            public 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();
        }
    }
}

 

 

4、データを読み取る

以前にデータを読み取ったとき、データは常に文字化けしているか、順序が狂っていました(文字のセグメントがいくつかのセグメントに分割されていました)。

文字化けした解決策:Bluetoothによって送信されるボーレートは通常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()を使用して、文字を1つずつ読み取り、それがターミネーターであるかどうかを判別し、ターミネーターに到達しない場合は読み取りと書き込みを続けます

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------------");
                            }

5、GitHubアドレス

https://github.com/jiancong952/bluetooth_java.git

おすすめ

転載: blog.csdn.net/weixin_38676276/article/details/111477921