java web 通信_Java Web_Java通信

本文介绍如何使用Java通信API 3.0与串口硬件交互,特别是读取蓝牙GPS接收器的数据。通过列出可用串口、打开连接、设置参数和事件监听,实现了从GPS接收器获取经纬度信息并将其解析和保存到文件。代码示例展示了SerialDemo程序的使用,包括端口选择、数据读取和解析过程。
摘要由CSDN通过智能技术生成

Java通信

Java通信3.0API是一个Java的扩展,有利于发展独立于平台的通信应用,如智能卡,嵌入式系统,销售点设备,金融服务设备,传真机,调制解调器,显示终端,以及机器人设备的技术。

Java通信API(也被称为javax.comm)提供的应用程序访问到RS- 232硬件(串口)和有限的访问IEEE- 1284并行端口,SPP模式。

Java提供了CommunicationAPI(包含于javax.comm包中)用于通过与机器无关的方式,控制各种外部设备。Communications API,是标准的Java的扩展部分,它在JavaAPI中是没有附带的。

目前3.0可用于Sparc结构下的Solaris系统和x86以及x86下的Linux系统的API的实现。

成功下载解压后,目录下有3个文件:

comm.jar:拷贝到%JAVA_HOME%\jre\lib\ext

javax.comm.properties:拷贝到%JAVA_HOME%\jre\lib\

win32com.dll:拷贝到%JAVA_HOME%\jre\lib\ext

注:%JAVA_HOME%:jdk的路径

Java的这个扩展类就不做详细介绍了,网上可以搜索到很多相关资料。下面我所做的是一个基于JAVA读取蓝牙GPS接收器中的数据。在我们下载的完整的2.0版本的API中的samples中提供了一些简单的实例,这里我采用了其中的SerialDemo,这个实例做了一个UI窗口,可以显示获取到的信息,设置各个参数,打开/关闭端口等功能。可以说这个实例将我所要做的大部分主要功能都已做好,我只需在这个实例的基础上来获得坐标位置并保存即可。

1f11ae189f74c3fb3071c45c59e718cd.png

以下只截取部分主要代码:

1. 列举出本机所有可用串口

void listPortChoices() {

CommPortIdentifier portId;

Enumeration en = CommPortIdentifier.getPortIdentifiers();

//iterate through the ports. while (en.hasMoreElements()) {

portId = (CommPortIdentifier) en.nextElement();

//如果端口的类型是串行口的话,将端口的名称添加到下拉框中。 if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {

portChoice.addItem(portId.getName());

}

}

//设置下拉框的选择项 portChoice.select(parameters.getPortName());

}

2. 打开连接

public void openConnection() throws SerialConnectionException {

//获取一个要打开的端口CommPortIdentifier对象。 try {

portId = CommPortIdentifier.getPortIdentifier(parameters.getPortName());

} catch (NoSuchPortException e) {

throw new SerialConnectionException(e.getMessage());

}

//打开CommPortIdentifier对象代表端口。//公开征集一个比较长的30秒超时,让不同的应用程序reliquish的端口,如果用户想要的。

try {

sPort = (SerialPort)portId.open("SerialDemo", 30000);

} catch (PortInUseException e) {

throw new SerialConnectionException(e.getMessage());

}

//Set the parameters of the connection. If they won't set, close the//port before throwing an exception.//设置连接参数。如果他们将不会设置,在抛出异常之前关闭该端口。 try {

setConnectionParameters();

} catch (SerialConnectionException e) {

sPort.close();

throw e;

}

//打开连接的输入和输出流。如果他们不打开,关闭端口抛出异常前。 try {

os = sPort.getOutputStream();

is = sPort.getInputStream();

} catch (IOException e) {

sPort.close();

throw new SerialConnectionException("Error opening i/o streams");

}

//创建一个新的KeyHandler响应messageAreaOut。添加KeyHandler keyListener messageAreaOut。 keyHandler = new KeyHandler(os);

messageAreaOut.addKeyListener(keyHandler);

//为串行端口添加一个事件侦听器。 try {

sPort.addEventListener(this);

} catch (TooManyListenersException e) {

sPort.close();

throw new SerialConnectionException("too many listeners added");

}

//notifyOnDataAvailable设置为true,允许事件驱动的输入。 sPort.notifyOnDataAvailable(true);

//设置notifyOnBreakInterrup允许事件驱动的中断处理。 sPort.notifyOnBreakInterrupt(true);

//设置接收超时,允许打破轮询循环在输入处理。 try {

sPort.enableReceiveTimeout(30);

} catch (UnsupportedCommOperationException e) {

}

//添加所有权监听器,让所有权的事件处理。 portId.addPortOwnershipListener(this);

open = true;

}

3. 事件侦听器监听到数据

public void serialEvent(SerialPortEvent e) {

//创建一个StringBuffer和int接收输入数据。 StringBuffer inputBuffer = new StringBuffer();

int newData = 0;

//确定事件的类型。 switch (e.getEventType()) {

//DATA_AVAILABLE端口缓冲区读取数据,直到返回-1。如果\r是代替\n收到正确的换行处理。 case SerialPortEvent.DATA_AVAILABLE:

while (newData != -1) {

try {

newData = is.read();

if (newData == -1) {

break;

}

if ('\r' == (char)newData) {

inputBuffer.append('\n');

} else {

inputBuffer.append((char)newData);

}

} catch (IOException ex) {

System.err.println(ex);

return;

}

}

//附加收到的数据来messageAreaIn。 messageAreaIn.append(new String(inputBuffer));

//在这里我截取读入的数据,传送到ParseData()这个类中。 String inString=new String(inputBuffer);

new ParseData().parse(inString);

break;

//If break event append BREAK RECEIVED message.//如果中断事件追加BREAK收到的消息。 case SerialPortEvent.BI:

messageAreaIn.append("\n--- BREAK RECEIVED ---\n");

}

4. ParseData()

import java.io.IOException;

public class ParseData {

String xString="";

String yString="";

String timeStr="";

String state="";

//分析接口 public boolean parse(String sentence)

{

String rawData = sentence;

try

{

if (!(rawData.length()>0))

{

return false;

}

sentence = sentence.substring(1, sentence.indexOf('*') - 1);

String[] words =getWords(sentence);

if (words[0].equals("GPGGA")) {

return parseGPGGA(words);

}else if (words[0].equals("GPRMC")) {

return false;

}else if (words[0].equals("GPGSA")) {

return false;

}else if (words[0].equals("GPGSV")) {

return false;

}else {

return false;

}

}

catch (Exception e)

{

e.printStackTrace();

return false;

}

}

public boolean parseGPGGA(String[] words)

{

//取经纬度 if (words[6].length() > 0)

{

timeStr=getTimeFormat(words[1]);

yString=getYformat(words[2]);

xString=getXformat(words[4]);

state=words[6];

String gpsString="时间:"+timeStr+"\n状态:"+state+"\n北纬:"+yString+"\n东经:"+xString+"\n";

try {

new FileOutput().file(gpsString);

} catch (IOException e) {

e.printStackTrace();

}

return true;

}else {

return false;

}

}

//拆分字符串为字符串数组 public String[] getWords(String str){

String[] words=str.split(",");

return words;

}

//时间 public String getTimeFormat(String str){

int t1=Integer.parseInt(str.substring(0, 2))+8;

String t2=str.substring(2, 4);

String t3=str.substring(4, str.length());

return String.valueOf(t1)+"点"+t2+"分"+t3+"秒";

}

//东经 public String getXformat(String str){

double a1=Double.valueOf(str.substring(0, 3));

double a2=Double.valueOf(str.substring(3, str.length()));

double aa1=a2/60;

return String.valueOf(a1+aa1);

}

//北纬 public String getYformat(String str){

double b1=Double.valueOf(str.substring(0, 2));

double b2=Double.valueOf(str.substring(2, str.length()));

double bb1=b2/60;

return String.valueOf(b1+bb1);

}

}

5. FileOutput()

import java.io.*;

class FileOutput {

public void file(String str) throws IOException {

byte b[];

//获取当前类文件所在路径 String classPath=Class.class.getResource("/").getPath().substring(1);

classPath=classPath.substring(0, classPath.lastIndexOf("/"));

String parentPath=classPath.substring(0, classPath.lastIndexOf("/"));

//处理文件路径乱码问题 parentPath = java.net.URLDecoder.decode(parentPath, "utf-8");

File f = new File(parentPath + "/gpsdata.txt");

f.createNewFile();

b = str.getBytes();

//追加内容//FileOutputStream fos = new FileOutputStream(f, true);//覆盖内容 FileOutputStream fos = new FileOutputStream(f);

fos.write(b);

fos.close(); }

}

注:

1. UI窗口中根据设备选择设置端口及波特率,点击“Open Port”打开端口,读取数据。

2. 4种常用的NMEA0183标准格式说明

$GPGGA,012440.00,3202.1798,N,11849.0763,E,1,05,2.7,40.2,M,0.5,M,,*6F..

1 时间: 01+8=9点24分40.00秒

2 纬度:北纬32度02.1798分

3 经度:东经118度49.0763分

4 定位: 1=(定位sps模式) 0=(未定位)

5 应用卫星数: 05个

6 HDOP: 2.7米

7 海拔: 40.2

8 海拔单位: M=(米)

9 WGS84水准面划分: 0.5

10 WGS84水准面划分单位M(米)

11

12 校验位: 6F

$GPRMC,013946.00,A,3202.1855,N,11849.0769,E,0.05,218.30,111105,4.5,W,A*20..

01 时间01时39分46.00秒

02 定位状态A=可用V=警告(不可用)

03 纬度:北纬(N) 32度02.1855分

04 经度:东经(E) 118度49.0769分

05 相对位移速度: 0.05 knots

06 相对位移方向: 218.30度

07 日期: 11日11月05年(日日月月年年)

08

09

10 检查位

$GPGSA,A,3,01,03,14,20,,,,,,,,,2.6,2.5,1.0*35..

01 模式2: A=自动M=手动

02 模式1: 1=未定位2=二维定位3=三维定位

03 卫星编号: 01到32

04 PDOP-位置精度稀释: (2.6) 0.5--99.9

05 HDOP-水平经度稀释: (2.6) 0.5--99.9

06 VDOP-垂直经度稀释: (1.0) 0.5--99.9

07 检验位35

$GPGSV,2,1,08,01,62,160,42,03,23,189,42,06,23,049,32,14,24,150,35*78..

01 天空中收到讯号的卫星总数

02 定位的卫星总数

03 天空中卫星总数

04 (01,62,160,42)分别是卫星编号01-32,卫星仰角00-90度,卫星方位角000-359度,讯号噪声比00-99dB

以下类似(03,23,189,42) (06,23,049,32) (14,24,150,35)

05 Checksum检查位*78

附加:

/**

*获得本机串行和并行端口号

*/

import javax.comm.*;

import java.util.Enumeration;

public class GpsText

{

public static void main(String args[]){

Enumeration ports;

System.out.println("Verifying Build Environment");

try{

ports=CommPortIdentifier.getPortIdentifiers();

if(ports==null){

System.out.println("No comm ports found!");

return;

}

while(ports.hasMoreElements()){

System.out.println("Here is a prot ["+((CommPortIdentifier)ports.nextElement()).getName()+"]");

}

}catch(Exception e){

System.out.println("Failed to enumerate ports ["+e.getMessage()+"]");

e.printStackTrace();

}

System.out.println("Complete");

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值