J2ME 蓝牙 串口 连接PC

来源:互联网 发布:java json转字符串 编辑:程序博客网 时间:2024/05/02 06:06
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();//这里是全部唤醒         }    }}