stdgps.java
来自「A Java Framework for connecting to and e」· Java 代码 · 共 366 行
JAVA
366 行
package com.libGPS4j2me.devices.StdGPS;
import com.libGPS4j2me.devices.StdGPS.DataRecord;
import com.libGPS4j2me.devices.StdGPS.exceptions.EmptyBufferException;
import com.libGPS4j2me.devices.StdGPS.exceptions.ParseException;
import com.libGPS4j2me.devices.StdGPS.exceptions.UnsupportedTypeException;
import com.libGPS4j2me.devices.StdGPS.log.Logger;
import com.libGPS4j2me.devices.StdGPS.parser.Parser;
import com.libGPS4j2me.GPS;
import java.io.IOException;
import java.util.Vector;
import java.io.InputStreamReader;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
/**
* Main class for communication with serial GPS receiver. Use this class to access StdGPS
* receiver from other classes.
*
*
* @author Loreto Parisi
* @version 1.0
*/
public class StdGPS extends GPS implements Runnable {
/** A human-readable description of the GPS-unit. */
protected String description;
protected boolean isPosition;
protected boolean isTime;
protected boolean isDate;
/** A vector containing references to all the GarminListeners. */
protected Vector StdGPSListeners;
/**
* Time in ms to wait until resume to receive.
*/
private static final long RECEIVE_BREAK = 2000;
/**
* Time in ms to wait until retry to read() the stream.
*/
private static final long READ_BREAK = 500;
/**
* Character which indicates end of line in data send by serial device.
*/
private static final int LINE_DELIMITER = 13;
/**
* Buffers parsed record.
*/
private DataRecordBuffer buffer;
/**
* Connection to serial device.
*/
private StreamConnection connection;
/**
* Input reader to read data send by serial device.
*/
private InputStreamReader reader;
/**
* Receiving happens in separate thread.
*/
private Thread runner;
/**
* URL used to connect to serial device.
*/
private String url;
/**
* Creates new GPS serial receiver.
*
* @param url
* URL of serial device to connect to.
*/
public StdGPS(String url) {
this.url = url;
this.buffer = new DataRecordBuffer();
StdGPSListeners = new Vector();
isPosition = false;
isDate = false;
isTime = false;
}
/**
* Establishes a serial connection (specified in url) and
* opens an input stream.
*
* @throws IOException
* If error occurs while establishing bluetooth connection or
* opening input stream
*/
private synchronized void connect() throws IOException {
connection = (StreamConnection) Connector.open(url, Connector.READ);
reader = new InputStreamReader(connection.openInputStream());
}
/**
* Closes input stream and bluetooth connection as well as sets the
* corresponding objects to null.
*/
private synchronized void disconnect() {
try {
if (reader != null)
reader.close();
if (connection != null)
connection.close();
} catch (IOException e) {
// Ignore.
}
reader = null;
connection = null;
}
/**
*
* @return The currently stored record.
* @throws EmptyBufferException
* If no record has been stored yet.
*/
public DataRecord getRecord() throws EmptyBufferException {
return buffer.getRecord();
}
/**
* @return True, if connected and input stream opened
*/
public synchronized boolean isConnected() {
return connection != null && reader != null;
}
/**
* Reads in records sent by the StdGPS receiver. When a supported record has
* been received notifies to Listeners.
*/
public void run() {
// Marker that indicates start of one cycle of records.
int startType = Parser.TYPE_START;
// Type of currently parsed record.
int type = Parser.TYPE_NA;
// Storage.
DataRecord record = new DataRecord();
while (Thread.currentThread() == runner) {
try {
// If not connected try to connect again.
if (!isConnected())
connect();
// Verify that the GPS stream is ready to be read
if(!reader.ready()) {
try {
Thread.sleep(READ_BREAK);
} catch(InterruptedException ie) {}
continue;
}
String output = new String();
int input;
// Read one line and try to parse it. If successfull put parsed
// record in buffer.
while ((input = reader.read()) != LINE_DELIMITER)
output += (char) input;
//output = output.substring(1, output.length() - 1);
try {
log("Parsing NMEA:" + output);
type = Parser.parse(output, record);
buffer.putRecord(record);
}
// Is being thrown when a record is parsed that has an
// unsupported type.
catch (UnsupportedTypeException ue) {
// Type is not supported.
log("Type exception: " + ue.getMessage());
type = Parser.TYPE_NA;
}
// Error while parsing (supported) record.
catch (ParseException pe) {
log("Parse exception: " + pe.getMessage());
pe.printStackTrace();
}
// Examine only if valid type was parsed.
if (type != Parser.TYPE_NA) {
// notify DataRecord avaiable
log("FireDataRecord.");
fireDataRecord(record);
firePositionData(new PositionDataRecord(record));
fireTimeData(new TimeDataRecord(record));
// Reset storage
record = new DataRecord();
if (type == startType) {
disconnect();
// Reset start marker.
startType = Parser.TYPE_START;
// Reset startType and storage.
record = new DataRecord();
try {
Thread.sleep(RECEIVE_BREAK);
} catch (InterruptedException e) {
log("Exception: " + e.getMessage());
}
}
// Set start marker.
else if (startType == Parser.TYPE_START) {
startType = type;
}
}
try {
//artificial wait
Thread.sleep(RECEIVE_BREAK);
} catch (InterruptedException e) {}
// close GPS connection
log("Disconnecting...");
disconnect();
}
// Most severe type of exception. Either thrown while connecting or
// while reading. Wait some time before continuing.
catch (IOException ie) {
try {
Thread.sleep(RECEIVE_BREAK);
} catch (InterruptedException e) {
log("IO exception: " + e.getMessage());
}
ie.printStackTrace();
}
}
}
/**
* Starts receving of data (if not yet started).
*/
public void start() {
if (runner == null) {
runner = new Thread(this);
runner.start();
}
}
/**
* Utility function for debug purposes.
*/
private void log(String message) {
System.out.println("StdGPS: " + message);
System.out.flush();
}
/** Makes a request for accessing Position data to the GPS.
* Data will be returned to all listeners through the IGPSlistener-interface.
*/
public void requestPosition() {
isPosition = true;
if (runner == null) {
runner = new Thread(this);
runner.start();
}
}
/** Makes a request for accessing Time data to the GPS.
* Data will be returned to all listeners through the IGPSlistener-interface.
*/
public void requestTime() {
isTime = true;
if (runner == null) {
runner = new Thread(this);
runner.start();
}
}
/** Makes a request for accessing Date data to the GPS.
* Data will be returned to all listeners through the IGPSlistener-interface.
*/
public void requestDate() {
isDate = true;
if (runner == null) {
runner = new Thread(this);
runner.start();
}
}
/** Stops communication with GPS.
*
*/
public void shutdown(boolean b) {
runner = null;
disconnect();
}
/**
* Requests a descriptive string from the GPS. Should be formatted for human-reading.
* The string should be constructed by every GPS-implementation upon startup.
* Not implemented here. Not to use here.
*/
public String getDescription() { return null; }
/**
* Asks the GPS to transmit all the waypoints in it's memory. The result will be returned through the WaypointListener-interface.
* Throws a FeatureNotSupportException if it isn't possible to do this on the GPS.
* Not implemented here. Not to use here.
*/
public void requestWaypoints() {}
/**
* Asks the GPS to transmit all the waypoints in it's memory. The result will be returned through the WaypointListener-interface.
* Throws a FeatureNotSupportException if it isn't possible to do this on the GPS.
* Not implemented here. Not to use.
*/
public void requestTracks() {}
/**
* Asks the GPS to either start or stop transmitting data periodically. <br/>
* The data will be the that which is accessible through the IGPSlistener-interface.
* Throws a FeatureNotSupportException if it isn't possible to do this on the GPS.
* Not implemented here. Not to use here.
*/
public void setAutoTransmit(boolean t) {}
/**
* Adds the specified StdGPSListener to receive all packets sent from the GPS.
*/
public void addStdGPSListener(StdGPSListener l) {
// Only allow a listener to be registered once.
if (StdGPSListeners.contains(l))
return;
StdGPSListeners.addElement(l);
return;
}
/**
* Removes the specified StdGPSListener from the list of listeners.
*/
public void removeStdGPSListener(StdGPSListener l) {
while (StdGPSListeners.removeElement(l)) {}
return;
}
/**
* Goes through the list of StdGPSListeners and transmits r to them.
*/
protected void fireDataRecord(DataRecord r) {
for (int i = 0 ; i < StdGPSListeners.size() ; i++) {
((StdGPSListener) StdGPSListeners.elementAt(i)).DataRecordReceived(r);
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?