Android应用开发笔记(11):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 在新版本中的进一步完善来学习使用。

发布了56 篇原创文章 · 获赞 6 · 访问量 51万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览