zoukankan      html  css  js  c++  java
  • Android上的蓝牙通信功能的开发:BluetoothChat例程分析

    1.     概述

    Bluetooth 是几乎现在每部手机标准配备的功能,多用于耳机 mic 等设备与手机的连接,除此之外,还可以多部手机之间建立 bluetooth 通信,本文就通过 SDK 中带的一个聊天室的例程,来介绍一下 android 上的 Bluetooth 的开发。
    在 Android1.x 的时候,相关 API 非常不完善,还不能简单的使用 Bluetooth 开发,有一个开源项目可以帮助程序员使用、开发蓝牙,支持直接方法bluetooth 协议栈。在 Android2 以后,框架提供了一些官方 API 来进行蓝牙的通信,但目前的程序也比较不完善。本文主要讨论 Android2 后的Bluetooth 通信的 API 使用方法。
    首先看聊天室的效果图:
     

    2.     Bluetooth 通信 API 介绍2.1. Bluetooth 通信过程

    2.2. Bluetooth API 的主要方法

    BluetoothAdapter 类
    BluetoothAdapter.getDefaultAdapter() :得到本地默认的 BluetoothAdapter ,若返回为 null 则表示本地不支持蓝牙;
    isDiscovering() :返回设备是否正在发现周围蓝牙设备;
    cancelDiscovery() :取消正在发现远程蓝牙设备的过程;
    startDiscovery() :开始发现过程;
    getScanMode() :得到本地蓝牙设备的 Scan Mode ;
    getBondedDevices() :得到已配对的设备;
    isEnabled() :蓝牙功能是否启用。
    当发现蓝牙功能未启用时,如下调用设置启用蓝牙:
    if (! mBluetoothAdapter .isEnabled()) {
    
                Intent enableIntent = new Intent(BluetoothAdapter. ACTION_REQUEST_ENABLE );
                startActivityForResult(enableIntent, REQUEST_ENABLE_BT );
    
            }
    如果发现当前设备没有打开对外可见模式,则传递 Intent 来调用打开可发现模式,代码如下:
    Intent discoverableIntent = new Intent(BluetoothAdapter. ACTION_REQUEST_DISCOVERABLE );     
    discoverableIntent.putExtra(BluetoothAdapter. EXTRA_DISCOVERABLE_DURATION , 300);
     startActivity(discoverableIntent);
    BluetoothDevice 类,此为对应的远程蓝牙 Device
           createRfcommSocketToServiceRecord() :创建该 Device 的 socket 。
    BluetoothSocket 类
           connect() :请求连接蓝牙。
    getInputStream() :得到输入流,用于接收远程方信息。
    getOutputStream() :得到输出流,发送给远程方的信息。
    close() :关闭蓝牙连接。
    InputStream 类:
           read(byte[]) :以阻塞方式读取输入流。
    OutputStream 类:
           write(byte[]) :将信息写入该输出流,发送给远程。
    3.     BluetoothChat 例程分析
    Google 提供的关于 Bluetooth 开发的例程为 Bluetoothchat ,使用截图可见本文一开始。除去配置及 ui 定义等文件,主程序文件共三个:BluetoothChat.java 、 BluetoothChatService.java 以及 DeviceListActivity.java ,详细功能可见下面的描述。
    3.1. 整体调用关系序列图

    3.2. BluetoothChat.java
    例程的主 Activity 。 onCreate() 得到本地 BluetoothAdapter 设备,检查是否支持。 onStart() 中检查是否启用蓝牙,并请求启用,然后执行 setupChat()。 setupChat() 中先对界面中的控件进行初始化增加点击监听器等,然创建 BluetoothChatService 对象,该对象在整个应用过程中存在,并执行蓝牙连接建立、消息发送接受等实际的行为。
    3.3. BluetoothChatService.java
    public synchronized void start() :
    开启 mAcceptThread 线程,由于样例程序是仅 2 人的聊天过程,故之前先检测 mConnectThread 和 mConnectedThread 是否运行,运行则先退出这些线程。
    public synchronized void connect(BluetoothDevice device) :
    取消 CONNECTING 和 CONNECTED 状态下的相关线程,然后运行新的 mConnectThread 线程。
    public synchronized void connected(BluetoothSocket socket, BluetoothDevice device)
    开启一个 ConnectedThread 来管理对应的当前连接。之前先取消任意现存的 mConnectThread 、 mConnectedThread 、 mAcceptThread 线程,然后开启新 mConnectedThread ,传入当前刚刚接受的 socket 连接。最后通过 Handler 来通知 UI 连接 OK 。
    public synchronized void stop() :
    停止所有相关线程,设当前状态为 NONE 。
    public void write(byte[] out) :
    在 STATE_CONNECTED 状态下,调用 mConnectedThread 里的 write 方法,写入 byte 。
    private void connectionFailed() :
    连接失败的时候处理,通知 ui ,并设为 STATE_LISTEN 状态。
    private void connectionLost() :
    当连接失去的时候,设为 STATE_LISTEN 状态并通知 ui 。
    内部类:
    private class AcceptThread extends Thread :
    创建监听线程,准备接受新连接。使用阻塞方式,调用 BluetoothServerSocket.accept() 。提供 cancel 方法关闭 socket 。
    private class ConnectThread extends Thread :
    这是定义的连接线程,专门用来对外发出连接对方蓝牙的请求和处理流程。构造函数里通过 BluetoothDevice.createRfcommSocketToServiceRecord(),从待连接的 device 产生 BluetoothSocket. 然后在 run 方法中 connect ,成功后调用 BluetoothChatSevice 的 connected() 方法。定义 cancel() 在关闭线程时能够关闭相关 socket 。
    private class ConnectedThread extends Thread :
    这个是双方蓝牙连接后一直运行的线程。构造函数中设置输入输出流。 Run 方法中使用阻塞模式的 InputStream.read() 循环读取输入流, 然后 post 到UI 线程中更新聊天消息。也提供了 write() 将聊天消息写入输出流传输至对方,传输成功后回写入 UI 线程。最后 cancel() 关闭连接的 socket 。
    3.4. DeviceListActivity.java
    该类包含 UI 和操作的 Activity 类,作用是得到系统默认蓝牙设备的已配对设备列表,以及搜索出的未配对的新设备的列表。然后提供点击后发出连接设备请求的功能。
     
    除了 RFCOMM 通信外, Android 上关于 Bluetooth 的还有 SDP 、 GAP 、耳机设备连接等内容,本文还未涉及,将会随着蓝牙相关 API 在新版本中的进一步完善来学习使用。
  • 相关阅读:
    图片上传-下载-删除等图片管理的若干经验总结3-单一业务场景的完整解决方案
    图片上传-下载-删除等图片管理的若干经验总结2
    HDU 1195 Open the Lock
    HDU 1690 Bus System
    HDU 2647 Reward
    HDU 2680 Choose the best route
    HDU 1596 find the safest road
    POJ 1904 King's Quest
    CDOJ 889 Battle for Silver
    CDOJ 888 Absurdistan Roads
  • 原文地址:https://www.cnblogs.com/vus520/p/2598888.html
Copyright © 2011-2022 走看看