`
melord
  • 浏览: 145835 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

J2ME 蓝牙搜索与连接

 
阅读更多
import java.io.IOException;
import java.util.Vector;

import javax.bluetooth.BluetoothStateException;
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;
import javax.microedition.io.Connection;
import javax.microedition.io.Connector;

/**
 * 蓝牙设备搜索及服务搜索类<BR>
 * 
 * 
 * @author Administrator
 * @version V1.0
 */
public final class BlueTooth implements DiscoveryListener , Runnable
{

    /**
     * 准备
     */
    public static final int STATUS_READY = 0x01;
    /**
     * 设备搜索中
     */
    public static final int STATUS_DEV_SEARCHING = 0x02;
    /**
     * 设备搜索完成
     */
    public static final int STATUS_DEV_SEARCH_FINISH = 0x03;
    /**
     * 设备搜索失败
     */
    public static final int STATUS_DEV_SEARCH_ERROR = 0x04;
    /**
     * 服务搜索中
     */
    public static final int STATUS_SER_SEARCHING = 0x10;
    /**
     * 服务搜索完成
     */
    public static final int STATUS_SER_SEARCH_FINISH = 0x11;
    /**
     * 服务搜索失败
     */
    public static final int STATUS_SER_SEARCH_ERROR = 0x12;
    /**
     * 创建与服务的连接中
     */
    public static final int STATUS_CONNECTING = 0x20;
    /**
     * 创建服务连接成功
     */
    public static final int STATUS_CONNECT_OK = 0x21;
    /**
     * 创建服务连接失败
     */
    public static final int STATUS_CONNECT_FAIL = 0x22;
    /**
     * 单实例
     */
    private static BlueTooth instance = new BlueTooth();

    /**
     * 本地设备
     */
    protected LocalDevice localDevice;
    /**
     * 设备搜索代理
     */
    protected DiscoveryAgent discoveryAgent;

    /**
     * 搜索到的设备列表
     */
    protected Vector remoteDeviceVector = new Vector();
    /**
     * 搜索到的服务信息列表
     */
    protected Vector serviceInfoVector = new Vector();
    /**
     * 搜索到的服务列表
     */
    protected Vector serviceRecordVector = new Vector();

    /**
     * 
     */
    // protected int connectType = 0;
    /**
     * 状态
     */
    protected int status = 0;

    /**
     * 是否支持蓝牙
     */
    protected boolean supportJSR82 = false;

    /**
     * 对象锁,控制设备搜索和服务搜索
     */
    private Object bluelock = new Object();

    /**
     * 过滤器
     */
    private Filter filter;

    /**
     * 预设设备
     */
    private String expectDevice;

    /**
     * 构造子
     */
    private BlueTooth()
    {
        try
        {
            Class.forName("javax.bluetooth.LocalDevice");
            supportJSR82 = true;
        }
        catch (Exception ex)
        {
            supportJSR82 = false;
        }
        try
        {
            // 获得本地设备
            localDevice = LocalDevice.getLocalDevice();
            // 获得本地设备代理
            discoveryAgent = localDevice.getDiscoveryAgent();
        }
        catch (Exception e)
        {
            supportJSR82 = false;
        }
    }

    /**
     * 获取单实例
     * 
     * @return 静态单实例
     */
    public static BlueTooth getInstance()
    {
        return instance;
    }

    /**
     * 搜索蓝牙设备
     * 
     * @return 搜索到的蓝牙设备
     */
    public Vector findDevices()
    {
        remoteDeviceVector.removeAllElements();
        try
        {
            // 启动搜索代理发现设备并与DiscoveryListener注册回调
            discoveryAgent.startInquiry(DiscoveryAgent.GIAC, this);
            // 设备搜索状态
            setStatus(STATUS_DEV_SEARCHING);
            // 设备搜索过程是异步的,这里需要同步搜索过程
            // 设备搜索完毕会通知主线程继续运行

            synchronized (bluelock)
            {
                // 加上while,break纯粹是为了规避findbugs检查
                while (status >= STATUS_READY && status < STATUS_DEV_SEARCH_FINISH)
                {
                    try
                    {
                        bluelock.wait();
                        // break;
                    }
                    catch (Exception e)
                    {
                        break;
                    }
                }
            }
        }
        catch (BluetoothStateException e)
        {
            setStatus(STATUS_DEV_SEARCH_ERROR);
        }
        return remoteDeviceVector;
    }

    /**
     * 获取手机匹配装置列表中的蓝牙设备集合
     * 
     * @return 搜索到的蓝牙设备
     */
    public Vector findDeviceInCache()
    {
        Vector vector = new Vector();
        RemoteDevice[] rds = discoveryAgent.retrieveDevices(DiscoveryAgent.CACHED);
        if (rds != null)
        {
            for (int i = 0; i < rds.length; i++)
            {
                vector.addElement(rds[i]);
            }

        }
        rds = discoveryAgent.retrieveDevices(DiscoveryAgent.PREKNOWN);
        if (rds != null)
        {
            for (int i = 0; i < rds.length; i++)
            {
                vector.addElement(rds[i]);
            }

        }
        return vector;
    }

    /**
     * 取消正在执行的设备搜索
     */
    public void cancelFindDevices()
    {
        if (status == STATUS_DEV_SEARCHING)
        {
            discoveryAgent.cancelInquiry(this);
        }
    }

    /**
     * 蓝牙设备发现时的回调方法<BR>
     * 每发现一个蓝牙装置,此方法将被调用一次。
     * 
     * @param btDevice 搜索到的蓝牙装置
     * @param cod 服务类,远程蓝牙装置的主设备类或附设备类
     * @see javax.bluetooth.DiscoveryListener#deviceDiscovered(javax.bluetooth.RemoteDevice,
     *      javax.bluetooth.DeviceClass)
     */

    public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod)
    {
        if (filter != null && !filter.match(btDevice))
        {
            return;
        }
        else
        {
            remoteDeviceVector.addElement(btDevice);
        }
        if (expectDevice != null && expectDevice.equals(btDevice.getBluetoothAddress()))
        {
            discoveryAgent.cancelInquiry(this);
        }
    }

    /**
     * 设备搜索结束时的回调方法<BR>
     * 
     * 
     * @param discType 搜索请求结束类型; 为INQUIRY_COMPLETED, INQUIRY_TERMINATED, 或INQUIRY_ERROR
     * @see javax.bluetooth.DiscoveryListener#inquiryCompleted(int)
     */

    public void inquiryCompleted(int discType)
    {
        if (discType == INQUIRY_COMPLETED)
        {
            setStatus(STATUS_DEV_SEARCH_FINISH);
        }
        else if (discType == INQUIRY_ERROR)
        {
            setStatus(STATUS_DEV_SEARCH_ERROR);
        }
        // 蓝牙搜索执行完毕,通知主线程继续
        synchronized (bluelock)
        {
            bluelock.notifyAll();
        }
    }

    /**
     * 搜索蓝牙设备提供的服务
     * 
     * @param device 远程蓝牙设备
     * @param uuids 搜索服务UUID数组
     * @return 搜索到的服务集合
     */
    public Vector findServices(RemoteDevice device, UUID[] uuids)
    {
        serviceInfoVector.removeAllElements();
        serviceRecordVector.removeAllElements();
        try
        {
            discoveryAgent.searchServices(new int[] {0x100 }, uuids, device, this);
            setStatus(STATUS_SER_SEARCHING);
        }
        catch (BluetoothStateException e)
        {
            setStatus(STATUS_SER_SEARCH_ERROR);
        }

        synchronized (bluelock)
        {
            // 加上while,break纯粹是为了规避findbugs检查
            while (status > STATUS_DEV_SEARCHING && status <= STATUS_SER_SEARCHING)
            {
                try
                {
                    bluelock.wait();
                    // break;
                }
                catch (InterruptedException e)
                {
                    break;
                }
            }
        }
        return serviceRecordVector;
    }

    /**
     * 搜索服务时找到服务的回调方法<BR>
     * [功能详细描述]
     * 
     * @param transID 服务搜索事务ID
     * @param servRecord 搜索到的服务记录数组
     * @see javax.bluetooth.DiscoveryListener#servicesDiscovered(int, javax.bluetooth.ServiceRecord[])
     */

    public void servicesDiscovered(int transID, ServiceRecord[] servRecord)
    {
        if (servRecord != null)
        {
            for (int i = 0; i < servRecord.length; i++)
            {
                DataElement serviceNameElement = servRecord[i].getAttributeValue(0x0100);
                String serviceName = (serviceNameElement.getValue().toString()).trim();
                ServiceInfo info = new ServiceInfo();
                info.name = serviceName;
                serviceInfoVector.addElement(info);
                serviceRecordVector.addElement(servRecord[i]);
            }
        }
    }

    /**
     * 搜索服务结束回调方法<BR>
     * 结束包含正常结束,手动终止或错误
     * 
     * @param transID 搜索事务ID
     * @param respCode 搜索响应码
     * @see javax.bluetooth.DiscoveryListener#serviceSearchCompleted(int, int)
     */

    public void serviceSearchCompleted(int transID, int respCode)
    {
        switch (respCode)
        {
            case DiscoveryListener.SERVICE_SEARCH_COMPLETED:
            case DiscoveryListener.SERVICE_SEARCH_DEVICE_NOT_REACHABLE:
            case DiscoveryListener.SERVICE_SEARCH_NO_RECORDS:
            case DiscoveryListener.SERVICE_SEARCH_TERMINATED:
            {
                setStatus(STATUS_SER_SEARCH_FINISH);
                break;
            }
            case DiscoveryListener.SERVICE_SEARCH_ERROR:
            {
                setStatus(STATUS_SER_SEARCH_ERROR);
                break;
            }
            default:
            {
                setStatus(STATUS_SER_SEARCH_FINISH);
                break;
            }
        }
        synchronized (bluelock)
        {
            bluelock.notifyAll();
        }
    }

    /**
     * 线程run方法<BR>
     * 搜索设备
     * 
     * @see java.lang.Runnable#run()
     */
    public void run()
    {
        if (supportJSR82)
        {
            findDevices();
        }
    }

    /**
     * 根据服务URL创建连接
     * 
     * @param url 从ServiceRecord中获取的服务URL
     * @return 创建的连接
     * @exception IOException 当创建连接失败时,抛出IO异常
     */
    public Connection getConnection(String url) throws IOException
    {
        Connection conn = null;
        try
        {
            setStatus(STATUS_CONNECTING);
            conn = Connector.open(url);
            setStatus(STATUS_CONNECT_OK);
            // RemoteDevice rd = RemoteDevice.getRemoteDevice(conn);
        }
        catch (IOException e)
        {
            setStatus(STATUS_CONNECT_FAIL);
            throw e;
        }
        return conn;
    }

    /**
     * 根据服务记录创建连接
     * 
     * @param service 搜索记录
     * @return 创建的连接
     * @exception IOException 当创建连接失败时,抛出IO异常
     */
    public Connection getConnection(ServiceRecord service) throws IOException
    {
        String url = service.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
        return getConnection(url);
    }

    // -----------------> getter & setter

    /**
     * 获取搜索到的蓝牙设备列表<br />
     * 如果要获取最终的设备列表,需要在status=STATUS_DEV_SEARCH_FINISH时,再调用此方法
     * 
     * @return 搜索到的蓝牙设备列表
     */
    public Vector getRemoteDeviceVector()
    {
        return remoteDeviceVector;
    }

    /**
     * 获取搜索到的服务列表
     * 
     * @return 搜索到的ServiceRecord列表
     */
    public Vector getServiceRecordVector()
    {
        return serviceRecordVector;
    }

    /**
     * 获取搜索到的服务信息列表
     * 
     * @return 搜索到的ServiceRecord信息列表
     */
    public Vector getServiceInfoVector()
    {
        return serviceInfoVector;
    }

    /**
     * 获取当前状态
     * 
     * @return 状态
     */
    public int getStatus()
    {
        return status;
    }

    /**
     * 设置状态
     * 
     * @param status 要设置的状态
     */
    public void setStatus(int status)
    {
        this.status = status;
    }

    /**
     * 判断是否支持jsr82规范
     * 
     * @return 是否支持蓝牙
     */
    public boolean isSupportJSR82()
    {
        return supportJSR82;
    }

    /**
     * 设置搜索过滤器
     * 
     * @param filter 搜索设备时的过滤器
     */
    public void setFilter(Filter filter)
    {
        this.filter = filter;
    }

    /**
     * 获取设备过滤器
     * 
     * @return 设备过滤器
     */
    public Filter getFilter()
    {
        return filter;
    }

    /**
     * 设备搜索过滤器<BR>
     * 如果符合匹配条件,则将搜索到的设备加入搜索结果集合当中
     * 
     * @author Adminstrator
     * @version V1.0
     */
    public static abstract class Filter
    {
        /**
         * 判断设备是否符合过滤规则
         * 
         * @param device 搜索到的设备
         * @return 是否符合过滤规则
         */
        public abstract boolean match(RemoteDevice device);
    }
}
分享到:
评论

相关推荐

    J2ME蓝牙编程 J2ME蓝牙编程

    **J2ME蓝牙编程详解** Java 2 Micro Edition (J2ME) 是一种Java平台,专为嵌入式设备和移动设备设计,如早期的智能手机和平板电脑。它提供了丰富的功能,包括支持无线通信,其中就包括蓝牙(Bluetooth)编程。在...

    j2me 手机蓝牙聊天系统

    在J2ME手机蓝牙聊天系统中,蓝牙作为传输媒介,使得手机之间可以建立连接并进行数据通信,无需物理线缆连接。 **J2ME架构**:J2ME包含配置(Configurations)和配置文件(Profiles)。在这个聊天系统中,可能使用了...

    j2me手机蓝牙OBEX传文件代码

    简单j2me蓝牙OBEX传文件代码 http://blog.csdn.net/xiaoxiao108/archive/2011/03/10/6237233.aspx 最近想写一手机程序实现以下功能,在蓝牙的有效距离内,如果有其他手机的蓝牙设置为可见状态,自己的手机自动向其他...

    J2ME蓝牙实战入门.doc

    《J2ME蓝牙实战入门》文档主要介绍了如何利用Java Micro Edition (J2ME)平台中的JSR82规范来开发蓝牙应用。JSR82,全称为Java APIs for Bluetooth Wireless Technology,提供了一套API,使得开发者能够在支持蓝牙的...

    J2ME蓝牙五子棋游戏源代码

    【J2ME蓝牙五子棋游戏源代码】是一款专为移动设备设计的、基于Java Micro Edition(J2ME)平台的轻量级游戏。这款五子棋游戏利用了J2ME提供的蓝牙通信功能,使玩家可以通过手机之间的蓝牙连接进行对战,增加了游戏的...

    j2me 蓝牙编程

    《J2ME蓝牙编程》这一主题深入探讨了在移动设备上开发Java蓝牙应用程序的技术与实践。J2ME(Java 2 Micro Edition)是Sun Microsystems为嵌入式和移动设备设计的Java平台版本,它提供了轻量级的Java运行环境,特别...

    J2ME蓝牙游戏的对战分析

    总结,J2ME蓝牙游戏的对战分析涉及了移动游戏开发的基础知识,如J2ME环境、用户界面设计、游戏循环,以及蓝牙通信技术,包括设备发现、连接建立和数据交换。五子棋游戏的实现则具体展示了如何结合这些技术,构建一个...

    很不错的蓝牙开发Demo/j2me蓝牙_客户端_服务端_类.rar

    这个名为"j2me蓝牙_客户端_服务端_类.rar"的压缩包文件包含了一个基于Java ME(J2ME)平台的蓝牙开发示例,涵盖了客户端、服务端以及相关的类。下面我们将深入探讨这些知识点。 首先,Java ME(Java 2 Micro ...

    J2ME蓝牙五子棋游戏源代码.7z

    《J2ME蓝牙五子棋游戏源代码解析》 J2ME(Java 2 Micro Edition)是...总之,J2ME蓝牙五子棋游戏源代码是学习移动设备编程和蓝牙通信的宝贵素材,它将理论知识与实际应用紧密结合,对于提升Java ME开发技能大有裨益。

    J2ME手机蓝牙聊天

    总的来说,“J2ME手机蓝牙聊天”项目是一个实践性强、涵盖技术点丰富的课程设计,不仅涉及J2ME的基础编程,还涵盖了蓝牙通信的原理与应用。通过这个项目,开发者不仅可以深入理解J2ME平台,还能掌握蓝牙通信的核心...

    J2ME移动开发平台搭建步骤.rar_J2ME 蓝牙_j2me_java平台_开发平台

    总之,J2ME移动开发平台的搭建涉及Java SDK的安装、IDE的选择与配置,以及蓝牙功能的开发API学习。通过这个过程,你将能够创建并测试自己的J2ME应用程序,尤其是具备蓝牙通信功能的项目。记得实践是检验真理的唯一...

    j2me手机蓝牙通讯

    总之,J2ME手机蓝牙通讯的核心在于正确使用JSR-82提供的API,实现设备发现、服务搜索、连接建立、数据传输以及连接管理。通过熟练掌握这些步骤,开发者可以构建出功能完善的蓝牙应用,满足手机与各种蓝牙设备间的...

    基于 j2me 的蓝牙五子棋

    最后,文档"蓝牙五子棋.doc"可能包含了项目的详细设计、源代码注释或者测试报告,这些资料对于理解整个项目和学习J2ME蓝牙编程具有很大的帮助。 总的来说,基于J2ME的蓝牙五子棋项目是一个结合了基础编程、蓝牙通信...

    j2me做得蓝牙五子棋

    总的来说,J2ME蓝牙五子棋项目展示了如何利用Java技术在移动设备上实现一个互动的、通过蓝牙连接的双人游戏。它涉及到了移动编程的多个方面,包括UI设计、游戏逻辑实现、设备间通信等,对于学习J2ME和蓝牙编程的...

    蓝牙J2ME象棋``

    1. **蓝牙API**:J2ME中的JSR-82(Java API for Bluetooth Wireless Technology)提供了与蓝牙设备交互的接口,包括搜索设备、建立连接、传输数据等。 2. **线程管理**:游戏逻辑和蓝牙通信通常需要在不同的线程中...

    手机蓝牙遥控小车 手机J2ME蓝牙API

    这个项目的核心是通过手机上的Java ME (Java 2 Micro Edition)平台,利用其提供的蓝牙API,实现与小车的无线通信。下面将详细阐述相关知识点。 1. **Java ME**:Java ME是Java在嵌入式设备和移动设备上的应用开发...

    J2ME手机蓝牙点菜系统

    1. **蓝牙连接管理**:如何使用J2ME API进行蓝牙设备的搜索、连接和断开。 2. **数据交换**:如何编码和解码点菜信息,以及如何通过蓝牙接口进行数据传输。 3. **用户界面**:如何设计简单的图形用户界面(GUI)以...

    j2me写的蓝牙五子棋

    《J2ME编写的蓝牙五子棋:源码解析与技术要点》 J2ME,全称Java 2 Micro Edition,是Java平台的一个版本,专为嵌入式设备和移动设备设计,如早期的智能手机和平板电脑。在移动通信领域,J2ME曾广泛应用于开发各种...

Global site tag (gtag.js) - Google Analytics