J2ME 蓝牙 串口 连接PC

本文介绍了一个蓝牙客户端的Java实现,该客户端能够搜索并连接到其他蓝牙设备。代码详细展示了如何利用Java蓝牙API进行设备搜索、服务查询及数据传输。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package BTClient;



//这是别人的代码 具体在那拷贝的 我忘记了,这不是我的原创,只是我学习半个月 才搞懂的 发上来 大家可以参考一下

//对象主要调用两个方法 搜索 发送

import java.io.*;

import java.util.*;

import javax.bluetooth.*;

import javax.bluetooth.UUID;

import javax.microedition.io.*;

  ////////////////////////////////////////////////////////////////////////////////////////////////////

public class BTClient implements DiscoveryListener, Runnable {

    					//接口 DiscoveryListener

    public static final String uuidString = "0123456789ABCDEF0123456789ABCDEF";

    public static UUID uuid;

    private LocalDevice localDevice;// 本地设备实例

    String localBTAddress;// 本地蓝牙地址

    String localBTName;// 蓝牙名称

 

    DiscoveryAgent discoveryAgent;// 发现代理

    Thread th;

    Thread readWorkTh;

    Thread writeWorkTh;

    StreamConnection conn;

    boolean exitFlag;

    boolean BTReady;//状态标记

    DataInputStream in;

    DataOutputStream out;

    String sendText = "";

    Hashtable remoteDevices = new Hashtable();// 存储找到的远程设备  哈什表java.util.Hashtable



    String url = null;

    ServiceRecord serviceRecord;

    ////////////////////////////////////////////////////////////////////////////////////////////////////

    public BTClient() {

   

        th = new Thread(this);

        th.start();   

    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////   

    public void run() {

        if (!initBT()) {       

            return; //返回

        }

        try {

      

            // 等待启动服务搜索,看清下面的search()搜索这里先暂停它

            synchronized (this) {

            	//代码块中的代码必须获得对象 syncObject (如前所述,可以是类实例或类)的锁才能执行!

	

                try {

                    wait();//会释放这个锁,让其它线程有机会运行。

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

            }////

            if (exitFlag)

                return;//返回

            search();

             ///////////////////////////// /////////////////////////////

            // 等待URL准备好

            synchronized (this) { //等到被唤醒后 再继续运行

                try {

                    wait();//会释放这个锁,让其它线程有机会运行。

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

            }////

            if (exitFlag)

                return;//返回

            conn = (StreamConnection) Connector.open(url);

            in = conn.openDataInputStream();

            out = conn.openDataOutputStream();

            readWorkTh = new ReadWorkThread();

            readWorkTh.start();

            writeWorkTh = new WriteWorkThread();

            writeWorkTh.start();

       

            BTReady = true;

        } catch (IOException e) {

   

            return;//返回

        } catch (SecurityException e) {

       

            return;//返回

        }

        th = null;//Thread为空

    }

  ////////////////////////////////////////////////////////////////////////////////////////////////////



    public boolean initBT() {   //初始化蓝牙-文文风  这很简单 初始化就可以了主要是地址!

        boolean success = false;

        try {

            uuid = new UUID(uuidString, false);// 我们的UUID

            // 取得本地设备实例

            localDevice = LocalDevice.getLocalDevice();

            // 记录蓝牙地址

            localBTAddress = localDevice.getBluetoothAddress();

            // 记录蓝牙名称

            localBTName = localDevice.getFriendlyName();

            localDevice.setDiscoverable(DiscoveryAgent.GIAC);

            // 取得蓝牙代理

            discoveryAgent = localDevice.getDiscoveryAgent();

            success = true;

        } catch (Exception e) {

            System.err.println("初始化蓝牙设备失败:" + e);

        }

        return success;

    }

   ////////////////////////////////////////////////////////////////////////////////////////////////////   

    public void search() {// 搜索设备,搜索服务

        try {    //remoteDevices哈什表

            // 清除remoteDevices

            remoteDevices.clear();

            // 将缓存的和已知的蓝牙设备加入cacheDevices++preDevices==remoteDevices

            RemoteDevice[] cacheDevices = discoveryAgent.retrieveDevices(DiscoveryAgent.CACHED);  

             // class RemoteDevice//缓存的

                     

            if (cacheDevices != null) {

                for (int i = 0; i < cacheDevices.length; i++) {

                    remoteDevices.put(cacheDevices[i].getBluetoothAddress(), cacheDevices[i]);

                     //哈什表      

                }

            }

            RemoteDevice[] preDevices = discoveryAgent.retrieveDevices(DiscoveryAgent.PREKNOWN);  

            // class RemoteDevice//已知的

                    

            if (preDevices != null) {

                for (int i = 0; i < preDevices.length; i++) {

                    remoteDevices.put(cacheDevices[i].getBluetoothAddress(),cacheDevices[i]);

                         //哈什表     这里好像写错了 应该是preDevices

                }

            }

            // 在缓存的和已知的设备上查询“服务”,函数定义在下面

            searchServices(remoteDevices);

            if (serviceRecord != null)// 找到返回

                return;

            // 开始搜索设备

            discoveryAgent.startInquiry(DiscoveryAgent.GIAC, this);//这里的this是指本类.当然我们要在本类实现DiscoveryListener接口. 

            // 在搜索到的设备上查询服务

             searchServices(remoteDevices);//去下面看看这个函数的实现

             remoteDevices.clear();

        } catch (BluetoothStateException e) {

            e.printStackTrace();

        }

        if (serviceRecord != null) {

            notify(); //叫醒谁??应该是下一个  就是上面等待URL的那个块,运行到这里 数据已经获取了 可以连接了

        } else {

         

        }

    }

   ////////////////////////////////////////////////////////////////////////////////////////////////////   

    private void searchServices(Hashtable remotes) throws BluetoothStateException   //根据hash表查询设备

    {// 搜索服务

        // 创建我们感兴趣的UUID数组,我这里只搜索可以提供-蓝牙串口-的设备

        	UUID[] UUIDs = new UUID[1];

        //UUIDs[1] = new UUID(uuidString, false);// 我们的UUID

        	UUIDs[0] = new UUID(0x0003);// 必须支持RFCOMM

        // 取出每一个设备查询

        for (Enumeration e = remotes.keys(); e.hasMoreElements();) {

            String key = (String) e.nextElement(); //我们用到了哈什表 这里要转换为remotes类型  

            RemoteDevice remoteDevice = (RemoteDevice) remotes.get(key);

            

            //看清楚了 这是remoteDevice 不是remoteDevices!!!!讨厌

            // 查询服务-使用发现代理 到这里不用管它了 它会自动调用回调函数的 可以去休息了

            

            discoveryAgent.searchServices(null, UUIDs, remoteDevice, this);

        }//这是循环尾 到这里了

    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////  

    public void deviceDiscovered(RemoteDevice device, DeviceClass cod) {  //如果搜索到了有新设备,它会调用deviceDiscoverd()方法接收! 

        // 记录找到的设备

        remoteDevices.put(device.getBluetoothAddress(), device);

    }  //哈什表 

    		//发现服务

   ////////////////////////////////////////////////////////////////////////////////////////////////////   		

    public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {

        // 发现感兴趣的服务,这里直接使用第一个

        if (servRecord == null || servRecord.length == 0) {

            url = null;

            serviceRecord = null;

            return;

        }

        // 取得感兴趣的连接URL,这里直接使用第一个,其它的不要了,我用直接写入的。不要学我啊

        //给大家看个例子 btspp://00195D0F4245:3;authenticate=false;encrypt=false;master=false

        //把地址改一下就可以用了,用不了 自己看参数呀  通道数我的机器有 2 3 7 你的电脑也许不是这些 

        serviceRecord = servRecord[0];   //服务记录是个接口

        url = serviceRecord.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);

    }

  ////////////////////////////////////////////////////////////////////////////////////////////////////    

       public void inquiryCompleted(int discType) {  //设备查询完成

        try {

            searchServices(remoteDevices);  //开始查询服务了,

        } catch (BluetoothStateException e) {

            e.printStackTrace();

        }

        remoteDevices.clear();//这里清空哈什表,释放资源,以后不用了,其实不用也是可以的。

    }

    

 

   ////////////////////////////////////////////////////////////////////////////////////////////////////   

    public void serviceSearchCompleted(int transID, int respCode) {//服务查询完成

        synchronized (this) {  //同步

            notifyAll();

            //服务查询完成后 会叫醒所有线程。

        }

    }

   

  ////////////////////////////////////////////////////////////////////////////////////////////////////    

    public void close() {

        try {

            exitFlag = true;

            synchronized (this) {

                notify(); //这也有唤醒 但是不知道具体做什么用的?请教一下

            }

            if (writeWorkTh != null) {

                synchronized (writeWorkTh) {

                    writeWorkTh.notify();  //这也有唤醒,请教!

                }

            }

            if (in != null) {

                in.close();

            }

            if (out != null) {

                out.close();

            }

            if (conn != null)

                conn.close();

            if (readWorkTh != null) {

                readWorkTh.join();

            }

            if (writeWorkTh != null)

                writeWorkTh.join();

            if (th != null)

                th.join();

        } catch (IOException e) {

            e.printStackTrace();

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

    }

  ////////////////////////////////////////////////////////////////////////////////////////////////////    

    public void send(String str) {  ////发送信息 外部对象会调用此方法

        if (writeWorkTh == null)

            return;

        sendText = str;

        synchronized (writeWorkTh) {

            writeWorkTh.notify(); //指定线程唤醒 别睡了 干活了

        }

    }

  ////////////////////////////////////////////////////////////////////////////////////////////////////    

    class ReadWorkThread extends Thread {

        public void run() {

            try {

                while (!exitFlag) {

                    String str = in.readUTF();

                    if (str != null) {

                   

                    }

                }

            } catch (IOException e) {

 

                   

            }

        }

    }

  ////////////////////////////////////////////////////////////////////////////////////////////////////

  ////////////////////////////////////////////////////////////////////////////////////////////////////    

    class WriteWorkThread extends Thread {

        public void run() {

            try {

                while (!exitFlag) {

                    synchronized (this) {////

                        try {

                            wait();//这等待一下 

                        } catch (InterruptedException e) {

                            e.printStackTrace();

                        }

                        if (exitFlag)// 可能因为关闭操作被打断

                            break;

                        if (sendText != null)

                            out.writeUTF(sendText);

                    }////

                }

            } catch (IOException e) {

         

                

            }

        }

    }

  ////////////////////////////////////////////////////////////////////////////////////////////////////    

    public void startSearch() {  ////搜索 同样 外部对象会调用此方法

        synchronized (this) {

            notifyAll();//这里是全部唤醒 

        }

    }

}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值