diff --git a/GPSTest/src/main/java/com/android/gpstest/GpsStatusFragment.java b/GPSTest/src/main/java/com/android/gpstest/GpsStatusFragment.java index 61be540ca..ff38548b2 100644 --- a/GPSTest/src/main/java/com/android/gpstest/GpsStatusFragment.java +++ b/GPSTest/src/main/java/com/android/gpstest/GpsStatusFragment.java @@ -290,7 +290,7 @@ public void onNmeaMessage(String message, long timestamp) { mAltitudeMslView.setText(getString(R.string.gps_altitude_msl_value, altitudeMsl)); } } - if (message.startsWith("$GNGSA")) { + if (message.startsWith("$GNGSA") || message.startsWith("$GPGSA")) { DilutionOfPrecision dop = GpsTestUtil.getDop(message); if (dop != null && mNavigating) { showDopViews(); diff --git a/GPSTest/src/main/java/com/android/gpstest/util/GpsTestUtil.java b/GPSTest/src/main/java/com/android/gpstest/util/GpsTestUtil.java index 21c07ef34..62e6ab806 100644 --- a/GPSTest/src/main/java/com/android/gpstest/util/GpsTestUtil.java +++ b/GPSTest/src/main/java/com/android/gpstest/util/GpsTestUtil.java @@ -223,16 +223,17 @@ public static Double getAltitudeMeanSeaLevel(String nmeaSentence) { } /** - * Given a $GPGSA NMEA sentence, return the dilution of precision, or null if dilution of + * Given a $GNGSA or $GPGSA NMEA sentence, return the dilution of precision, or null if dilution of * precision can't be parsed. * * Example inputs are: - * $GNGSA,A,2,67,68,69,79,84,,,,,,,,1.3,1.0,0.8,2*3A + * $GPGSA,A,3,03,14,16,22,23,26,,,,,,,3.6,1.8,3.1*38 + * $GNGSA,A,3,03,14,16,22,23,26,,,,,,,3.6,1.8,3.1,1*3B * - * Example outputs would be: - * PDOP is 1.3, HDOP is 1.0, and VDOP is 0.8 + * Example output is: + * PDOP is 3.6, HDOP is 1.8, and VDOP is 3.1 * - * @param nmeaSentence a $GNGSA NMEA sentence + * @param nmeaSentence a $GNGSA or $GPGSA NMEA sentence * @return the dilution of precision, or null if dilution of precision can't be parsed */ public static DilutionOfPrecision getDop(String nmeaSentence) { @@ -241,15 +242,28 @@ public static DilutionOfPrecision getDop(String nmeaSentence) { final int VDOP_INDEX = 17; String[] tokens = nmeaSentence.split(","); - if (nmeaSentence.startsWith("$GNGSA")) { + if (nmeaSentence.startsWith("$GNGSA") || nmeaSentence.startsWith("$GPGSA")) { String pdop = tokens[PDOP_INDEX]; String hdop = tokens[HDOP_INDEX]; String vdop = tokens[VDOP_INDEX]; + + // See https://github.com/barbeau/gpstest/issues/71#issuecomment-263169174 + if (vdop.contains("*")) { + vdop = vdop.split("\\*")[0]; + } + if (!TextUtils.isEmpty(pdop) && !TextUtils.isEmpty(hdop) && !TextUtils.isEmpty(vdop)) { - return new DilutionOfPrecision(Double.valueOf(pdop), Double.valueOf(hdop), - Double.valueOf(vdop)); + DilutionOfPrecision dop = null; + try { + dop = new DilutionOfPrecision(Double.valueOf(pdop), Double.valueOf(hdop), + Double.valueOf(vdop)); + } catch (NumberFormatException e) { + // See https://github.com/barbeau/gpstest/issues/71#issuecomment-263169174 + Log.e(TAG, "Invalid DOP values in NMEA: " + nmeaSentence); + } + return dop; } else { - Log.w(TAG, "Couldn't parse DOP from NMEA: " + nmeaSentence); + Log.w(TAG, "Empty DOP values in NMEA: " + nmeaSentence); return null; } } else { diff --git a/GPSTest/src/test/java/com/android/gpstest/GpsTestUtilTest.java b/GPSTest/src/test/java/com/android/gpstest/GpsTestUtilTest.java index 42f2217cf..edaf893dc 100644 --- a/GPSTest/src/test/java/com/android/gpstest/GpsTestUtilTest.java +++ b/GPSTest/src/test/java/com/android/gpstest/GpsTestUtilTest.java @@ -47,12 +47,55 @@ public void testGetAltitudeFromNmea() { @Test public void testGetDopFromNmea() { DilutionOfPrecision dop; - final String sentence = "$GNGSA,A,2,67,68,69,79,84,,,,,,,,1.3,1.0,0.8,2*3A"; - dop = GpsTestUtil.getDop(sentence); + // LG G5 w/ Android 6.0.1 + final String s1 = "$GNGSA,A,2,67,68,69,79,84,,,,,,,,1.3,1.0,0.8,2*3A"; + + // LG G5 w/ Android 7.0 + final String s2 = "$GPGSA,A,3,03,14,16,22,23,26,,,,,,,3.6,1.8,3.1*38"; + final String s3 = "$GNGSA,A,3,03,14,16,22,23,26,,,,,,,3.6,1.8,3.1,1*3B"; + + // From http://aprs.gids.nl/nmea/#gsa + final String s4 = "$GPGSA,A,3,,,,,,16,18,,22,24,,,3.6,2.1,2.2*3C"; + final String s5 = "$GPGSA,A,3,19,28,14,18,27,22,31,39,,,,,1.7,1.0,1.3*35"; + + // From http://www.gpsinformation.org/dale/nmea.htm#GSA + final String s6 = "$GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39"; + + dop = GpsTestUtil.getDop(s1); assertEquals(1.3d, dop.getPositionDop()); assertEquals(1.0d, dop.getHorizontalDop()); assertEquals(0.8d, dop.getVerticalDop()); + + dop = GpsTestUtil.getDop(s2); + + assertEquals(3.6d, dop.getPositionDop()); + assertEquals(1.8d, dop.getHorizontalDop()); + assertEquals(3.1d, dop.getVerticalDop()); + + dop = GpsTestUtil.getDop(s3); + + assertEquals(3.6d, dop.getPositionDop()); + assertEquals(1.8d, dop.getHorizontalDop()); + assertEquals(3.1d, dop.getVerticalDop()); + + dop = GpsTestUtil.getDop(s4); + + assertEquals(3.6d, dop.getPositionDop()); + assertEquals(2.1d, dop.getHorizontalDop()); + assertEquals(2.2d, dop.getVerticalDop()); + + dop = GpsTestUtil.getDop(s5); + + assertEquals(1.7d, dop.getPositionDop()); + assertEquals(1.0d, dop.getHorizontalDop()); + assertEquals(1.3d, dop.getVerticalDop()); + + dop = GpsTestUtil.getDop(s6); + + assertEquals(2.5d, dop.getPositionDop()); + assertEquals(1.3d, dop.getHorizontalDop()); + assertEquals(2.1d, dop.getVerticalDop()); } }