Android官网蓝牙样例BluetoothChat(蓝牙聊天室)解析

来源:互联网 发布:u盘数据丢失 编辑:程序博客网 时间:2024/06/05 19:54

首先给下下载地址:http://developer.Android.com/samples/BluetoothChat/index.html

前段时间做一个和蓝牙相关的项目,去Android的官网查资料看到这个蓝牙聊天室的例子,觉得对自己有用,研究了下,这里做个记录,如果能对别人有些帮助,当然最好。

看下Overview

This application allows two Android devices to carry out two-way text chat over Bluetooth. It demonstrates all the fundamental Bluetooth API capabilites, such as: (1) Scanning for other Bluetooth devices (2) Querying the local Bluetooth adapter for paired Bluetooth devices (3) Establishing RFCOMM channels/sockets (4) Connecting to a remote device (5) Transfering data over Bluetooth 

其实这个例子实现的就是两个安装了这个APP的Android可以进行“文字聊天”。

仔细看嘛,其实它就是把我们手机上原本就自带的蓝牙的查找,配对,建立连接重新实现了遍,然后加了个数据传输。。。

这部分的具体内容可以参见API Guides:

http://developer.android.com/guide/topics/connectivity/bluetooth.html#SettingUp

主要就是我下图画线的几部分:


我就不展开说了。。。

让我们回到这个Sample的源代码:

四个类,代码不多不少。不过其实我们大部分人都只是关心蓝牙通讯部分,其它并不太关心(反正我是。。),所以其实核心类就剩BluetoothChatService了。

好,那接下来的事情就是理一理这个通讯的过程了。

首先我们看看这个APP的界面:


我们可以看到信息传输是从我们按下这个SEND键开始的,那我们就从它开始顺藤摸瓜吧。

先在布局文件里找到了它的id是button_send,


然后用id在那几个类里ctrl+f下, 找到它的名字是:

mSendButton = (Button) view.findViewById(R.id.button_send);
接着Alt+F7(Find Usages),


成功发现目标,再次Alt+F7去sendMessage(message)方法里看下。

[java] view plain copy
  1. <span style="font-size:18px;">//汉字我加的  
  2. private void sendMessage(String message) {  
  3.         // Check that we're actually connected before trying anything(确保连上了)  
  4.         if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {  
  5.             Toast.makeText(getActivity(), R.string.not_connected, Toast.LENGTH_SHORT).show();  
  6.             return;  
  7.         }  
  8.   
  9.         // Check that there's actually something to send(确保有东西要发)  
  10.         if (message.length() > 0) {  
  11.             // Get the message bytes and tell the BluetoothChatService to write(将字符串变成字节流)  
  12.             byte[] send = message.getBytes();  
  13.             mChatService.write(send);//发送(通过老办法我们可以发现mChatService是BluetoothChatService的对象,显然我们要去看下这个类的write方法)  
  14.   
  15.             // Reset out string buffer to zero and clear the edit text field  
  16.             mOutStringBuffer.setLength(0);  
  17.             mOutEditText.setText(mOutStringBuffer);  
  18.         }  
  19.     }</span>  

在我们去看BluetoothChatService这个类的write方法之前,我们先对这个类大体上的把握下。

/** * This class does all the work for setting up and managing Bluetooth * connections with other devices. It has a thread that listens for * incoming connections, a thread for connecting with a device, and a * thread for performing data transmissions when connected. */
从这个类开始的注释我们可以知道它确实是核心类,和蓝牙相关的工作都是它做的。它开了三个线程,一个负责监听(用Java写过通过Socket客户端和服务器的通信的同学对此应该很了解,其实这个BluetoothChat就是装了它的device有时是客户端有时是服务器),一个负责连接(因为大家也知道蓝牙连接是需要一段时间的,如果不开个线程,搞不好就ANR了),还有个线程负责数据传输。如下图:



三个线程分别对应着BluetoothChatService的三个内部类。显然我们要找的write方法应该在ConnectedThread里。代码如下:

[java] view plain copy
  1. <span style="font-size:18px;">public void write(byte[] buffer) {  
  2.             try {  
  3.                 mmOutStream.write(buffer);  
  4.   
  5.                 // Share the sent message back to the UI Activity  
  6.                 mHandler.obtainMessage(Constants.MESSAGE_WRITE, -1, -1, buffer)  
  7.                         .sendToTarget();  
  8.             } catch (IOException e) {  
  9.                 Log.e(TAG, "Exception during write", e);  
  10.             }  
  11.         }</span>  
老方法找到mmOutStream的类是OutputStream,是Android SDK里的类,查下API Guides,有如下描述:

When you have successfully connected two (or more) devices, each one will have a connected BluetoothSocket. This is where the fun begins because you can share data between devices. Using the BluetoothSocket, the general procedure to transfer arbitrary data is simple:

Get the InputStream and OutputStream that handle transmissions through the socket, via getInputStream() and getOutputStream(), respectively.
Read and write data to the streams with read(byte[]) and write(byte[]).

其实可以发现和Java Socket那一套差不多的,具体大家去看API吧,我就不具体展开了。

好了数据现在发出去,现在接下来就是接受部分了:

通过mmInStream找到接受部分的代码如下(其实它也在ConnectedThread里,只不过这个ConnectedThread就是另一个remote device的ConnectedThread了):

[java] view plain copy
  1. <span style="font-size:18px;">// Keep listening to the InputStream while connected  
  2.             while (true) {  
  3.                 try {  
  4.                     // Read from the InputStream  
  5.                     bytes = mmInStream.read(buffer);  
  6.   
  7.                     // Send the obtained bytes to the UI Activity  
  8.                     mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, buffer)  
  9.                             .sendToTarget();  
  10.                 } catch (IOException e) {  
  11.                     Log.e(TAG, "disconnected", e);  
  12.                     connectionLost();  
  13.                     // Start the service over to restart listening mode  
  14.                     BluetoothChatService.this.start();  
  15.                     break;  
  16.                 }  
  17.             }</span>  

写过Java用Socket客户端和服务器通信的同学因该一看就懂了。其实不一样的就是通过Handler把数据传到UI线程里去,这部分知识我也不展开讲了,不会的同学自己去查资料吧。。


http://blog.csdn.net/u014285517/article/details/50074881


0 0