关于单位...当心!在我的 Android 2.2 手机上,Location.getSpeed() 返回KNOTS中的速度,而不是 Android 开发人员文档中所述的 m/s :(
网上还有其他几篇关于此的帖子。
在我的 Android 应用程序中,我有一个类可以将 NMEA 数据记录到文件中。
package log.nmea;
import android.location.GpsStatus;
import android.location.LocationManager;
import android.os.Environment;
import android.util.Log;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.regex.Pattern;
/**
* NMEA logging... just write NMEA stuff to file on SD card
*
* @author Frank van der Hulst
*/
public class NmeaLog {
private static BufferedWriter logWriter = null;
private static FileWriter fstream = null;
private static File logFile;
private static LocationManager locationManager = null;
// Default pattern is to log any message starting with $GP
private static final Pattern pattern = Pattern.compile("^$GP\\w+,");
private static final String LOGNAME = "NmeaLog";
private static GpsStatus.NmeaListener nmeaListener = new GpsStatus.NmeaListener() {
public void onNmeaReceived(long timestamp, String nmea) {
Log.d(LOGNAME, "onNmeaReceived(" + nmea + ")");
if (logWriter == null)
return;
if (!pattern.matcher(nmea).matches())
return;
Log.d(LOGNAME, "onNmeaReceived appending");
try {
logWriter.append(timestamp + "," + nmea);
} catch (IOException ex) {
Log.e(LOGNAME, ex.getMessage());
}
}
};
/**
* Initialise NMEA log file & open for writing
*
* @param filepath
* @param append
* @param lm
*/
public static void open(String filepath, boolean append, LocationManager lm) {
if (logWriter != null)
return; // Already open
// Check SD card is available
String SDCardStatus = Environment.getExternalStorageState();
if (!SDCardStatus.equals(Environment.MEDIA_MOUNTED)) {
Log.e(LOGNAME, "SD card error: " + SDCardStatus);
return;
}
// SD card is OK... try to create/open file
logFile = new File(filepath);
if (logFile == null || logFile.isDirectory()) {
Log.e(LOGNAME, filepath + " cannot be opened");
return;
}
locationManager = lm;
if (!locationManager.addNmeaListener(nmeaListener)) {
Log.e(LOGNAME, "Failed to add NMEA listener");
return;
}
Log.d(LOGNAME, "opening " + filepath);
try {
fstream = new FileWriter(logFile, append);
logWriter = new BufferedWriter(fstream, 1024);
} catch (Exception ex) {
Log.e(LOGNAME, "Open failed: " + ex.getMessage());
return;
}
Log.d(LOGNAME, "NMEA listener added successfully");
}
/**
* Close log file. The file can be reopened, so don't null locationManager
*/
public static void close() {
Log.d(LOGNAME, "close()");
try {
locationManager.removeNmeaListener(nmeaListener);
logWriter.close();
} catch (Exception ex) {
Log.e(LOGNAME, "Close error: " + ex.getMessage());
}
logWriter = null;
}
}
下面是一个将这些文件播放到模拟器的常规 Java 类。在调试 GPS 应用程序时非常有用。
package sendgps;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Date;
import util.Log;
import util.OSSpecific;
import util.Util;
/**
*
* @author Frank van der Hulst
*/
public class SendGPS {
private static Socket socket;
private static OutputStreamWriter w;
private static BufferedReader r;
private static final String NMEA_dir = "/home/frank/NetBeansProjects/SendGPS/";
@SuppressWarnings("UseOfSystemOutOrSystemErr")
private static void write(String s) throws IOException, InterruptedException {
// System.out.println("writing '" + s + "'");
w.append(s).append("\r\n");
w.flush();
String result = r.readLine();
if (!result.equals("OK")) {
System.out.println(s + " -> " + result);
}
}
@SuppressWarnings("UseOfSystemOutOrSystemErr")
private static void read() throws IOException {
while (r.ready()) {
System.out.print((char) r.read());
}
}
@SuppressWarnings({"SleepWhileInLoop", "UseOfSystemOutOrSystemErr", "deprecation"})
public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException {
socket = new Socket("localhost", 5554);
final String filename = NMEA_dir + "nmea.log";
socket.setKeepAlive(true);
r = new BufferedReader(new InputStreamReader(socket.getInputStream()));
w = new OutputStreamWriter(socket.getOutputStream());
Thread.sleep(100);
read(); // Remove initial prompt
String[] lines = Util.getFileContents(filename);
long prevTimestamp = 0;
for (int line_num = 0; line_num < lines.length; line_num++) {
String[] parts = lines[line_num].split(",", 2); // Separate timestamp from NMEA string
if (parts[1].isEmpty()) {
continue;
}
long timestamp = Long.parseLong(parts[0]);
// System.out.println(timestamp + ", "+ prevTimestamp);
if (timestamp != prevTimestamp) {
if (prevTimestamp != 0) {
int interval = (int) (timestamp - prevTimestamp);
// interval /= 10;
// System.out.print("Sleep: " + interval);
if (interval > 50) {
Thread.sleep(interval - 50);
}
}
prevTimestamp = timestamp;
}
if (parts[1].startsWith("$GPGGA") || parts[1].startsWith("$GPRMC")) {
// Replace hhmmss.ss timestamp at field 1 with current time
Date now = new Date();
String[] data = parts[1].split(",", 3);
parts[1] = data[0] + "," + now.getHours() + "" + now.getMinutes() + "" + now.getSeconds() + "," + data[2];
}
write("geo nmea " + parts[1]);
System.out.println(parts[1]);
}
socket.close();
}
}