最近一直在做关于Android串口通信的数据同步上传,写下这篇文章也算是记录一下过程。文章纯属是自己的感受,不代表阐述一定正确。Android串口通信是开发Android比较重要的一个模块,通过串口传输的数据一般具有数据量大、实时性强、数据格式固定等特点,串口通信大多以字节数组的形式相互传送,通过串口的输入输出流写入读出。
通过串口通信接收到的数据,Android端首先会进行解析处理,解析之后需要通过UI呈现解析后的信息,同时也需要将数据同步到服务器以便后续操作。基于java面向对象的思想,我们可以把从串口接收的数据封装成一个数据类,这样操作简单、效率更高。
数据的上传的格式与服务器的搭建有关,我所开发的服务器的通讯协议,是以字节数组的形式上传数据。服务器端与客户端的通信协议采用面向连接的TCP协议,使用Socket通信,下面贴出流程图:
说明:
1. 客户端每向服务器端发送一次数据,即与服务器端建立一次TCP连接、发送数据、接收响应数据、断开当前TCP连接的过程。安卓端将这一系列过程封装成一个方法,只需要给这个方法传入相应的发送帧(字节数组)即可完成相应的上传功能。
2. 考虑服务器的延时响应,当向服务器写入字节帧后,采取超时响应接收处理,设置等待服务器响应的时间为30s,在这30s内客户端一旦接收到响应数据,则提前结束等待,并返回响应数据,断开连接;反之,若30s内客户端始终未接收到响应,则说明本次帧发送出错(可能原因有多种,如帧格式不正确,数据校验出错等等),这种情况下30s后才会断开连接,并返回数据为null。
3. 数据发送过程中若服务器出现瞬时中断现象的容错处理,一旦客户端和服务器建立Socket连接后,客户端接下来的操作都具备异常捕获机制,若在写入数据过程中出错,经过异常捕获会将是否中断标志设置为true,关闭本次连接后会启动重连;若客户端写入数据成功,在等待服务器响应的时间里服务器出现中断,采用在等待时间内向服务器发送测试数据
socket.sendUrgentData(0xFF);的方法,默认情况下,服务器端没有打开紧急数据处理,不影响正常通信,测试方法返回服务器是否中断的判断,一旦中断,设置中断标志为true,并立即结束本次连接,启动重连。
客户端发送的帧数据需要一些转换工作,下面贴出一些基本类型转换成字节数组的方法:
short类型转字节数组
public static byte[] unsignedShortToByte2(short s) {
byte[] array = new byte[2];
array[0] =((byte) (s >> 8 & 0xFF));
array[1] = ((byte) (s & 0xFF));
return array;
}
int类型转字节数组
public static byte[] intToByte4(int i) {
byte[] array = new byte[4];
array[0] = (byte) (i >> 24 & 0xFF);
array[1] = (byte) (i >> 16 & 0xFF);
array[2] = (byte) (i >> 8 & 0xFF);
array[3] = (byte) (i & 0xFF);
return array;
}
float类型转字节数组
public static byte[] floatToByte4(float fvalue){
int ivalue = Float.floatToIntBits(fvalue);
return intToByte4(ivalue);
}
long类型转字节数组
public static byte[] longToBytes(long x) {
ByteBuffer buffer = ByteBuffer.allocate(8);
buffer.putLong(0, x);
return buffer.array();
}