两个手机进行蓝牙通信项目制作
2016-09-23 22:17
183 查看
最近,花了几天时间搞了一下蓝牙实现双机通信,在此分享一下自己的制作过程,及遇到的相关问题。首先这篇博文将结合各个部分进行详细的说明,有便于后期新人学习,同时利于个人的温习巩固。
项目关键点:
大的结构组织:
Activity, Service, Thread, BroadcastReceiver,
蓝牙模块所用到的点:
BluetoothDevice,
BluetoothSocket,
BluetoothServerSocket,
BluetoothAdapter,
数据流的点:
ObjectInputStream,
ObjectOutputStream 。
接下来,项目所用到重点知识进行一一详解:
Activity:(活动)
首先理解定义:包含用户界面的组件,主要用于和用户进行交互。
了解其生命周期:
主要分为三个生存期:
完整生存期:onCreate()和onDestroy()方法之间的过程。
可见生存期:onStart()和onStop()方法之间的过程。
前台生存期:onResume()和onPause()方法之间的过程。
项目所用到的onCreate(),onStart(),onStop()。
onCreate():活动的一些初始化,例如按钮,TextView的初始化等。
onStart():活动由可见到不可见时调用,主要在此开启Service。
onStop():活动不可见时,主要是在此停止Service。
Service:(服务)
服务实现后台运行,就算活动被关了,服务照样运行,Service运行在程序进程的主线程中。
项目所用到的服务的生命周期函数:
startService()启动服务
onCreate(),onDestroy();
onCreate()方法是在服务被创建的时候执行,
stopSelf()或者stopService()停止服务。
onDestroy();注销服务。
Thread(线程)
![](https://img-blog.csdn.net/20160926110745972?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
BroadcastReceiver(广播接收器)
http://blog.csdn.net/huangbiao86/article/details/6668525
BluetoothSocket(客户端套接字)
所谓Socket,网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。
建立网络通信连接至少要一对端口号(socket)。socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。(摘自百度百科)
BluetoothServerSocket(服务端套接字)
在服务器端,使用BluetoothServerSocket类创建一个监听服务端口,当一个连接被BluetoothServerSocket接受,会返回一个新的BluetoothSocket来管理该连接。客户端,使用一个单独的BluetoothSocket类去初始化一个外接连接和管理该连接。
使用的蓝牙端口是RFCOMM(面向连接,通过蓝牙模块进行数据流传输方式,也被称为串行端口规范SPP),
项目代码:
accept()方法是一个线程阻塞的,只有接受到客户端的连接,线程才会继续执行。
当然这个UUID是用代码自动生成的,只要客户端与服务端的UUID是一致的,两者就可以匹配成功。
在此注意一点,如果想让手机蓝牙APP连接单片机的蓝牙模块,UUID就是官方提供的通用码:
由于连接过程是属于耗时操作,所以上面的过程是在子线程中完成的。
BluetoothAdapter(蓝牙适配器)
首先讲一下Adapter,定义为将一个类的接口变换成客户端所期待的一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
BluetoothAdapter 可以初始化蓝牙设备的搜索,查询可匹配的设备集,使用一个已知的MAC地址来初始化一个BluetoothDevice类,创建一个BluetoothServerSocket类以监听其他设备对本机的连接请求。
IP地址专注于网络层,将数据包从一个网络转发到另外一个网络;而MAC地址专注于数据链路层,将一个数据帧从一个节点传送到相同链路的另一个节点。
具体代码的实现:
ObjectInputStream
ObjectOutputStream
两个类读写的对象需要实现Serializable接口,何为Serializable,java提供的通用数据保存和读取的接口。至于从什么地方读出来和保存到哪里去都被隐藏在函数参数的背后。任何类型只要实现了Serializable接口,就可以被保存到文件中,或者作为数据流通过网络发送到别的地方。也可以用管道来传输到系统的其他程序中。
可能有些问题,请看客们给与意见。
参考书籍 android的
《第一行代码》郭霖 著
《android经典项目开发实战》王翠萍 著
项目关键点:
大的结构组织:
Activity, Service, Thread, BroadcastReceiver,
蓝牙模块所用到的点:
BluetoothDevice,
BluetoothSocket,
BluetoothServerSocket,
BluetoothAdapter,
数据流的点:
ObjectInputStream,
ObjectOutputStream 。
接下来,项目所用到重点知识进行一一详解:
Activity:(活动)
首先理解定义:包含用户界面的组件,主要用于和用户进行交互。
了解其生命周期:
主要分为三个生存期:
完整生存期:onCreate()和onDestroy()方法之间的过程。
可见生存期:onStart()和onStop()方法之间的过程。
前台生存期:onResume()和onPause()方法之间的过程。
项目所用到的onCreate(),onStart(),onStop()。
onCreate():活动的一些初始化,例如按钮,TextView的初始化等。
onStart():活动由可见到不可见时调用,主要在此开启Service。
onStop():活动不可见时,主要是在此停止Service。
Service:(服务)
服务实现后台运行,就算活动被关了,服务照样运行,Service运行在程序进程的主线程中。
项目所用到的服务的生命周期函数:
startService()启动服务
onCreate(),onDestroy();
onCreate()方法是在服务被创建的时候执行,
stopSelf()或者stopService()停止服务。
onDestroy();注销服务。
Thread(线程)
BroadcastReceiver(广播接收器)
http://blog.csdn.net/huangbiao86/article/details/6668525
BluetoothSocket(客户端套接字)
所谓Socket,网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。
建立网络通信连接至少要一对端口号(socket)。socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。(摘自百度百科)
<span style="color:#330033;">socket = serverDevice.createRfcommSocketToServiceRecord(BluetoothTools.</span><span style="color: rgb(51, 0, 51); font-family: Arial, Helvetica, sans-serif;">RFCOMM_UUID</span><span style="color:#330033;">); socket.connect();</span>
BluetoothServerSocket(服务端套接字)
在服务器端,使用BluetoothServerSocket类创建一个监听服务端口,当一个连接被BluetoothServerSocket接受,会返回一个新的BluetoothSocket来管理该连接。客户端,使用一个单独的BluetoothSocket类去初始化一个外接连接和管理该连接。
使用的蓝牙端口是RFCOMM(面向连接,通过蓝牙模块进行数据流传输方式,也被称为串行端口规范SPP),
项目代码:
private BluetoothAdapter adapter; private BluetoothSocket socket;//用于通信的Socket private BluetoothServerSocket serverSocket; serverSocket=adapter.listenUsingRfcommWithServiceRecord("Server"RFCOMM_UUID); socket = serverSocket.accept();//接收到客户端的连接,转为BluetoothSocket进行通信
public static final UUID RFCOMM_UUID = UUID.fromString("36a274b5-be67-4782-a260-81586f26262a");代码说明:
accept()方法是一个线程阻塞的,只有接受到客户端的连接,线程才会继续执行。
当然这个UUID是用代码自动生成的,只要客户端与服务端的UUID是一致的,两者就可以匹配成功。
在此注意一点,如果想让手机蓝牙APP连接单片机的蓝牙模块,UUID就是官方提供的通用码:
<span style="white-space:pre"> </span>00001101-0000-1000-8000-00805F9B34FB
由于连接过程是属于耗时操作,所以上面的过程是在子线程中完成的。
BluetoothAdapter(蓝牙适配器)
首先讲一下Adapter,定义为将一个类的接口变换成客户端所期待的一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
BluetoothAdapter 可以初始化蓝牙设备的搜索,查询可匹配的设备集,使用一个已知的MAC地址来初始化一个BluetoothDevice类,创建一个BluetoothServerSocket类以监听其他设备对本机的连接请求。
IP地址专注于网络层,将数据包从一个网络转发到另外一个网络;而MAC地址专注于数据链路层,将一个数据帧从一个节点传送到相同链路的另一个节点。
具体代码的实现:
<span style="font-size:18px;">//搜索到的远程设备集合 private List<BluetoothDevice> discoveredDevices = new ArrayList<BluetoothDevice>(); //蓝牙适配器 private final BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();</span>
<span style="font-size:18px;"> bluetoothAdapter.enable();//打开蓝牙 bluetoothAdapter.startDiscovery();//开始搜索</span>接下来介绍一下广播事件:
BluetoothAdapter.ACTION_DISCOVERY_STARTED 开启对远程设备的搜索
BluetoothDevice.ACTION_FOUND 发现远程设备
BluetoothAdapter.ACTION_DISCOVERY_FINISHED 搜索结束
ObjectInputStream
ObjectOutputStream
两个类读写的对象需要实现Serializable接口,何为Serializable,java提供的通用数据保存和读取的接口。至于从什么地方读出来和保存到哪里去都被隐藏在函数参数的背后。任何类型只要实现了Serializable接口,就可以被保存到文件中,或者作为数据流通过网络发送到别的地方。也可以用管道来传输到系统的其他程序中。
<span style="font-size:18px;">dataIntent.putExtra(DATA,(Serializable)msg.obj); intent.getExtras().getSerializable(DATA);</span>
private ObjectInputStream inStream; //对象输入流 private ObjectOutputStream outStream;//对象输出流 this.outStream = new ObjectOutputStream(socket.getOutputStream()); this.inStream = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
<pre name="code" class="java">Object obj = inStream.readObject();//读取数据
<pre name="code" class="java">//写入一个可序列化的对象 public void writeObject(Object obj) { try { /* * Flush() 是清空,而不是刷新 * 主要用在IO中,即清空缓冲区数据,就是说你用读写流的时候, * 其实数据是先被读到了内存中,然后用数据写到文件中,当你 * 数据读完的时候不代表你的数据已经写完了,因为还有一部分 * 有可能会留在内存这个缓冲区中。这时候如果你调用了 Close() * 方法关闭了读写流,那么这部分数据就会丢失,所以应该在关闭 * 读写流之前先Flush(),先清空数据。 * */ outStream.flush(); outStream.writeObject(obj); outStream.flush(); } catch (IOException e) { e.printStackTrace(); } }
可能有些问题,请看客们给与意见。
参考书籍 android的
《第一行代码》郭霖 著
《android经典项目开发实战》王翠萍 著
相关文章推荐
- 如何使用XP自带超级终端及蓝牙方式与手机进行AT Command通信
- 树莓派3B使用板载蓝牙与手机蓝牙进行Socket通信(RFCOMM)
- 手机蓝牙通信设计(一) 项目搭建
- 两个java项目之间是如何进行通信的?
- 手机客户端和服务器通信时如何安全高效的进行身份验证?
- Android手机蓝牙与单片机蓝牙串通信开发经验总结
- 赛车游戏(一)通过蓝牙实现两个手机交互
- 《基于C/S模式的android手机与PC机通信系统的开发》项目
- 关于安卓手机做客户端pc做服务器进行Socket通信出现问题的解决案方
- 手机蓝牙通信设计(二) 练习移动应用程序
- 开发者称手机游戏项目动工前应先进行市场调查
- HTML5项目笔记8:使用HTML5 的跨域通信机制进行数据同步
- 手机与单片机通过蓝牙通信----手机控制灯
- 在S60第三版手机上通过USB线进行串行通信
- 蓝牙开发之从手机走向PC【2】——手机与手机之间的通信实现
- linux 用蓝牙和手机通信
- 【flex4.6将移动开发进行到底】第一章第一节建立手机项目
- 我用tcpdump对两个机器之间的通信进行抓包, 发现一个奇怪的问题
- 手机蓝牙通信设计(三) RFCOMM协议客户端+语音传送与接收
- linux 用蓝牙和手机通信