基于 Android 蓝牙聊天系统的设计与实现

这个课题是当初大二的时候参加校创新项目的题目,过去很久了,最近在准备面试就重新把知识整理一遍

蓝牙的基本介绍与实现

蓝牙,是一种支持设备短距离通信(一般10m内,且无阻隔媒介)的无线电技术。能在包括移动电话、PDA、无线耳机、笔记本电脑等众多设备之间进行无线信息交换。利用"蓝牙"技术,能够有效地简化移动通信终端设备之间的通信,也能够成功地简化设备与Internet之间的通信,这样数据传输变得更加迅速高效,为无线通信拓宽道路。

正式开发Android 蓝牙时,需要在Android项目中的AndroidManifest.xml中添加对应权限

<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> 
<uses-permission android:name="android.permission.BLUETOOTH" /> 

  

    名

    用

BluetoothAdapter

本地蓝牙设备的适配类,所有的蓝牙

操作都要通过该类完成

BluetoothClass

用于描述远端设备的类型,特点等信息

BluetoothDevice

蓝牙设备类,代表了蓝牙通讯过程中的远端设备

BluetoothServerSocket

蓝牙设备服务端,类似ServerSocket

BluetoothSocket

蓝牙设备客户端,类似Socket

BluetoothClass.Device

蓝牙关于设备信息

BluetoothClass.Device.Major

蓝牙设备管理

BluetoothClass.Service

蓝牙相关服务

其中BluetoothAdapter是一个非常重要的适配类,它包含打开蓝牙、关闭蓝牙、蓝牙状态、搜索蓝牙等重要方法,如表10-8所示。

 下面是BluetoothAdapter适配类包含的方法

    法

    用

getDefaultAdapter

得到默认蓝牙适配器

getRemoteDevice

得到指定蓝牙的BluetoothDevice

isEnabled

蓝牙是否开启

getState

得到蓝牙状态

enable

打开蓝牙

Disable

关闭蓝牙

getAddress

得到蓝牙适配器地址

getName

得到蓝牙的名字

setName

设置蓝牙的名字

getScanMode

得到当前蓝牙的扫描模式

setScanMode

设置当前蓝牙的设置模式

startDiscovery

开始搜索蓝牙设备

cancelDiscovery

取消搜索蓝牙设备

isDiscovering

是否允许被搜索

getBondedDevices

得到BluetoothDevice集合到本地适配器

listenUsingRfcommWithServiceRecord

创建一个监听,安全记录蓝牙

RFCOMM蓝牙套接字

checkBluetoothAddress

检查蓝牙地址是否正确

Android操作蓝牙不是很困难,主要就是打开蓝牙、关闭蓝牙、搜索蓝牙、蓝牙客户端、蓝牙服务器等。蓝牙客户端、服务器和Socket基础中讲解的差不多,但蓝牙中是用BluetoothSocket和BluetoothServerSocket两个类来操作。

关于Android在操作蓝牙过程中的几个要点和操作方式如下。

1.打开蓝牙的方式有两种

Intent enabler = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);  
startActivityForResult(enabler, REQUEST_ENABLE);  
BluetoothAdapter _bluetooth = BluetoothAdapter.getDefaultAdapter();  
_bluetooth.enable();  

第一种方式Android系统会弹出一个提示框,提示用户是否开启蓝牙设备。第二种方式不会提示,会直接打开蓝牙设备,在运用当中视情况而定,有些情况需要友好提示,有些情况则可直接打开使用。

2.使设备能够被搜索

基于安全性考虑,设置开启可被搜索后,Android系统就会默认给出120秒的时间,其他远程设备在这120秒内可以搜索到它:

Intent enabler = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);  
startActivityForResult(enabler, REQUEST_DISCOVERABLE);  

3.搜索蓝牙设备

BluetoothAdapter _bluetooth = BluetoothAdapter.getDefaultAdapter()  
_bluetooth.startDiscovery();  

4.关闭蓝牙设备

BluetoothAdapter _bluetooth = BluetoothAdapter.getDefaultAdapter();  
_bluetooth.disable (); 

5.创建蓝牙客户端

BluetoothSocket socket= device.createRfcommSocketToServiceRecord(UUID.fromString(UUID号));  
socket.connect(); 

6.创建蓝牙服务器

BluetoothServerSocket _serverSocket=_bluetooth.listenUsingRfcommWithServiceRecord(服务器名称, UUID.fromString(UUID号));  
BluetoothSocket socket = _serverSocket.accept();  
InputStream inputStream = socket.getInputStream();  

看到_serverSocket.accept()大家想到前面Socket章节所讲到的ServerSocket也有这个方法,原理上它们其实是一样的,都是阻塞等待客户端的数据,如果客户端没有数据过来,它将一直阻塞在此处。

在上述几个重要步骤方法中,最重要的是蓝牙客户端和服务器,这两个操作是在商业应用中和日常使用中最频繁的,例如,利用蓝牙传递数据、游戏、聊天等。目前市场上出现很多关于利用蓝牙技术做的聊天工具和传输数据文件的应用,它们都是采用BluetoothSocket和BluetoothServerSocket技术。

另外还有一点注意,蓝牙和WiFi都是比较耗电的功能模块,所以,在不使用蓝牙的情况下,建议关闭它。

蓝牙的基本操作和代码实现

代码部分就实现打开蓝牙、关闭蓝牙、搜索蓝牙、允许搜索。目前唯一比较复杂的地方就是如何建立蓝牙客户端和蓝牙服务器。

下面看看代码是如何实现蓝牙服务器和蓝牙客户端的,代码如下,代码来源EX_10_05:

服务器端:

………………………………省略部分代码…………………………..  
        setTitle("蓝牙服务端");  
        // 声明变量  
        BluetoothAdapter bluetooth = null;//本地蓝牙设备
  
        BluetoothServerSocket serverSocket = null;// 蓝牙设备Socket服务端
  
        BluetoothSocket socket = null;// 蓝牙设备Socket客户端
  
        OutputStream os = null;// 蓝牙输出流
  
        InputStream is = null;// 蓝牙输入流
  
        try {  
            // 1.得到本地设备  
            bluetooth = BluetoothAdapter.getDefaultAdapter();
  
            // 2.创建蓝牙Socket服务器  
            serverSocket = bluetooth.
listenUsingRfcommWithServiceRecord("btspp",         
UUID.fromString("00000000-2527-eef3-ffff-ffffe3160865"));  
            // 3.阻塞等待Socket客户端请求  
            socket = serverSocket.accept();
  
            if (socket != null) {  
                // 4.处理输出流  
                os = socket.getOutputStream();
  
                os.write("我是服务器!".getBytes());  
                if (os != null) {  
                    os.flush();  
                    os.close();  
                }  
                // 5.处理输入流  
                is = socket.getInputStream();
  
                byte[] bytes = new byte[is.available()];
  
                is.read(bytes);  
                System.out.println("服务器端读取客户端传输的数据时:" + new String(bytes));  
                if (is != null)  
                    is.close();  
                if (socket != null)  
                    socket.close();  
                if (serverSocket != null)  
                    serverSocket.close();  
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  

客户端开发:

………………………………省略部分代码…………………………..  
        setTitle("蓝牙客户端");  
        //声明变量  
        BluetoothAdapter bluetooth = null;//本地蓝牙设备
  
        BluetoothDevice device = null;//远程蓝牙设备
  
        BluetoothSocket socket = null;//蓝牙Socket客户端
  
        OutputStream os = null;//输出流
  
        InputStream is = null;//输入流
  
        try {  
            //1.得到本地蓝牙设备的默认适配器  
            bluetooth = BluetoothAdapter.getDefaultAdapter();
  
            //2.通过本地蓝牙设备得到远程蓝牙设备  
            device = bluetooth.getRemoteDevice("A0:75:91:E0:88:D3");
  
            //3.根据UUID 创建并返回一个BluetoothSocket     
            socket = device.createRfcommSocketToServiceRecord(UUID
  
                    .fromString("00000000-2527-eef3-ffff-ffffe3160865"));  
            if (socket != null) {  
                // 连接  
                socket.connect();  
                //4处理客户端输出流  
                os = socket.getOutputStream();
  
                os.write("我是客户端!".getBytes());  
                os.flush();  
                os.close();  
                //5处理客户端输入流  
                is = socket.getInputStream();
  
                byte[] b = new byte[is.available()];
  
                is.read(b);  
                System.out.println("客户端接收到服务器传输的数据::" + new String(b));  
                is.close();  
                socket.close();  
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  

  

代码解释:

测试代码时,需要手动打开蓝牙并自行配置好蓝牙客户端和服务器,也就是蓝牙配对。代码中注意服务器端和客户端的UUID:00000000-2527-eef3-ffff-ffffe3160865,两个地方一定要一样,另外客户端代码中的bluetooth.getRemoteDevice("A0:75:91:E0:88:D3")是通过服务器端的地址获取远程蓝牙服务器。

从代码角度看其实都很简单,读者要多练并且多灵活运用。如果前期读者对Socket的学习过关的话,学习蓝牙Socket编程是非常轻松的。由于BluetoothSocket支持OutputStream和InputStream,所以,可以利用它们相互传输任何数据。

项目实施思路

研究意义与目的:

随着移动智能设备(智能手机、PDA广泛使用,通过设备的移动带来机会式连接搭建临时网络,在没有基础设施网络环境下,使得各种移动智能设备通信成为可能。并且移动设备是由人携带,不仅具有一定的移动性,而且还具有一定的社会特性,我们称之为移动社会网络。

  校园移动社会网络是针对校园环境下,学生携带手机、PDA等设备搭建临时网络,学生之间通常因为具有相似的兴趣或者固定班级通过间歇性连接进行通信。考虑传输成本,学生之间可避免使用3/4G而选择蓝牙通信方式。该方式通过间歇性连接进行点对点通信,且传输性能依赖于学生行为的社会特性(如相似的兴趣、爱好、活动等)。因此开发校园移动社会网络系统具有较强的实用价值,体现出具有快捷、人性化功率、低成本的特点。

同类研究工作:

目前移动社会网络是国内外研究的热点,人们越来越多通过手持移动设备进行相互通信,逐步形成移动社会网络。虽然移动社会网络节点移动频繁,链路呈现间歇性连接,网络拓扑变化快,但是由于移动社会网络具有较强的社会特性。人类的行为具有一定的规律性和周期性。学生通常白天集中在固定教师上课,晚上同宿舍的同学通常集中呆在宿舍,社团成员在固定的时间参加会议和活动。因此利用社会特性和人类周期性规律可优化移动社会网络系统设计。

研究者首先对移动社会网络进行了社区发现社区结构分析,分析了社会特性对移动机会网络路由的作用。随后研究者从社会的中心性、相似性和友好性方面设计移动社会网络单播路由提高了路由性能。此外,研究者发现移动社会网络中节点的移动行为具有时间周期变化特性移动机会网络具有一定的动态社会特性。研究者也对移动社会网络社会特性正面和负面作用进行分析研究。正面效应如节点之间连接相对稳定,而负面效应如节点存在自私性行为。可见,移动社会网络的社会特性得到了国内外研究者的广泛关注。

 蓝牙技术是一种无线技术标准,实现固定设备、移动设备等短距离数据交换。蓝牙技术最初是电信巨头爱立信公司创建,是目前使用最广泛的无线通讯协议,近距离无线通讯的技术标准。装有蓝牙适配器的移动设备周期性地扫描附近的设备,然后进行蓝牙配对,再次返回一个信号说明设备配对成功。目前蓝牙特殊兴趣小组的成员已经超过2500家,几乎覆盖全球各行各业,包括通信厂商、网络厂商等。从2000年初,蓝牙芯片发售以来,目前已经有500多种蓝牙产品被推向市场。目前蓝牙技术还在断完善中,SIG正在发布蓝牙协议2.0版,采用自适应调频技术来进一步提高抗干扰性能,拓宽蓝牙技术在工业控制和无线LAN中的应用。

 Android是一个开源的软件系统,一个庞大的软件,拥有非常多源代码,目前用户的采用的手机或者PDA设备大部分都是基于Android平台。课题的校园移动社会网络基于Android平台,利用蓝牙技术实现间歇性的连接通信,可以实现低功率和低成本的校园无线网络通信系统。

 由于移动社会网络是近几年兴起的新型网络,目前基于Android的校园移动社会网络通信系统设计还处于待开发的阶段,本课题要求基于Android平台手机,实现校园移动社会网络系统。主要内容包括:

1、基于Android手机蓝牙技术、搭建校园移动社会网络。

2、开发应用程序,记录校园移动社会网络的连接行为、传输内容等信息。

3、实现对网络连接行为、传输内容等信息的统计,并进行社会特性统计分析。

参考文献:     

[1] Wei K, Liang X, Xu K. A survey of social-aware routing protocols in delay tolerant networks: applications, taxonomy and design-related issues [J]. Communications Surveys & Tutorials, 2014, 16(1): 556-578.

[2] Mei A, Morabito G, Santi P, et al. Social-aware stateless forwarding in pocket switched networks [C]. IEEE International conference on Computer Communications. Shanghai: IEEE Computer Society, 2011: 251-255.

[3] Wang Y, Wu J. On exploiting transient social contact patterns for data forwarding in delay-tolerant networks [J]. IEEE Transactons on mobile computing, 2013, 12 (1):151–165.

[4]Roy A, Acharya T, Dasbit S. Energy-Aware Social-Based Multicast in Delay-Tolerant Networks[C].IEEE 82nd Vehicular Technology Conference. Boston: IEEE Computer Society, 2015,1-5.

[5] Shang C, Wong B, Chen X, et al. Community and Social Feature-Based Multicast in Opportunistic Mobile Social Networks[C]. IEEE 24th International Conference on Computer Communication and Networks. Las Vegas: IEEE Computer Society, 2015:1-8

[6]周欢, 任东, 徐守志,. 移动机会网络中能量有效的接触探测研究[J]. 电子与信息学报, 2015, 37(6):1285-1290.

[7]罗富财. 基于Android平台的蓝牙通信系统的研究与实现[D]. 华北电力大学, 2013.

[8]熊小军, 万辉勇, 陈泓屹. 基于Android的低功耗蓝牙通讯研究与实现[J]. 科技广场, 2015(7):122-127.

[9]吴志霞, 陈平, 石凤贵. 基于Android平台蓝牙通信测试案例设计及实现[J]. 科技广场, 2016(5).

[10]徐叶菡, 史文婷, 陈茜. 基于BLEAndroid的蓝牙通信系统设计与实践[J]. 现代制造, 2016(12):168-169.

猜你喜欢

转载自www.cnblogs.com/wuyepeng/p/9753185.html