Skip to content

Commit

Permalink
Fix #30 - Dump NMEA, Nav Messages, and Measurements to system Log
Browse files Browse the repository at this point in the history
* For Android 2.3 and higher (all versions we currently support), dump NMEA logs (using pre Android 7.0 NMEA Listener and Android 7.0 NMEA listener) to system output Log
 * For Android 7.0 and higher, dump Navigation Messages to system output Log
 * For Android 7.0 and higher, dump Measurements to system output Log
 * All of the above is configurable via Preferences - can turn dump on or off
  • Loading branch information
barbeau committed Oct 12, 2016
1 parent 3c8de87 commit f8c9951
Show file tree
Hide file tree
Showing 5 changed files with 226 additions and 15 deletions.
133 changes: 127 additions & 6 deletions GPSTest/src/main/java/com/android/gpstest/GpsTestActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,16 @@
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.GnssMeasurement;
import android.location.GnssMeasurementsEvent;
import android.location.GnssNavigationMessage;
import android.location.GnssStatus;
import android.location.GpsStatus;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.location.OnNmeaMessageListener;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
Expand All @@ -64,6 +67,10 @@

import java.util.ArrayList;

import static com.android.gpstest.util.GpsTestUtil.writeGnssMeasurementToLog;
import static com.android.gpstest.util.GpsTestUtil.writeNavMessageToLog;
import static com.android.gpstest.util.GpsTestUtil.writeNmeaToLog;

public class GpsTestActivity extends ActionBarActivity
implements LocationListener, android.support.v7.app.ActionBar.TabListener,
SensorEventListener {
Expand Down Expand Up @@ -91,6 +98,10 @@ public class GpsTestActivity extends ActionBarActivity

boolean mFaceTrueNorth;

boolean mWriteGnssMeasurementToLog;

boolean mWriteNmeaTimestampToLog;

String mTtff;

org.jraf.android.backport.switchwidget.Switch mSwitch; //GPS on/off switch
Expand All @@ -110,18 +121,22 @@ public class GpsTestActivity extends ActionBarActivity

private GpsStatus.Listener mLegacyStatusListener;

private GpsStatus.NmeaListener mLegacyNmeaListener;

/**
* Android N (7.0) and above status and listener
* Android N (7.0) and above status and listeners
*/
private GnssStatus mGnssStatus;

private GnssStatus.Callback mGnssStatusListener;

/**
* Android N (7.0) GnssMeasurements - for SNR
*/
private GnssMeasurementsEvent.Callback mGnssMeasurementsListener;
private GnssMeasurementsEvent.Callback mGnssMeasurementsListener; // For SNRs

private OnNmeaMessageListener mOnNmeaMessageListener;

private GnssNavigationMessage.Callback mGnssNavMessageListener;

// Listeners for Fragments
private ArrayList<GpsTestListener> mGpsTestListeners = new ArrayList<GpsTestListener>();

private Location mLastLocation;
Expand Down Expand Up @@ -262,7 +277,7 @@ protected void onResume() {
}

/**
* Check preferences to see how they should be initialized
* Check preferences to see how these componenets should be initialized
*/
SharedPreferences settings = Application.getPrefs();

Expand All @@ -271,6 +286,14 @@ protected void onResume() {
checkTimeAndDistance(settings);

checkTrueNorth(settings);

checkNmeaOutput(settings);

checkGnssMeasurementOutput(settings);

if (GpsTestUtil.isGnssStatusListenerSupported()) {
checkNavMessageOutput(settings);
}
}

@Override
Expand Down Expand Up @@ -344,6 +367,11 @@ public void onGnssMeasurementsReceived(GnssMeasurementsEvent event) {
for (GpsTestListener listener : mGpsTestListeners) {
listener.onGnssMeasurementsReceived(event);
}
if (mWriteGnssMeasurementToLog) {
for (GnssMeasurement m : event.getMeasurements()) {
writeGnssMeasurementToLog(m);
}
}
}

@Override
Expand Down Expand Up @@ -411,6 +439,70 @@ private void removeLegacyStatusListener() {
mLocationManager.removeGpsStatusListener(mLegacyStatusListener);
}

private void addNmeaListener() {
if (GpsTestUtil.isGnssStatusListenerSupported()) {
addNmeaListenerAndroidN();
} else {
addLegacyNmeaListener();
}
}

@RequiresApi(api = Build.VERSION_CODES.N)
private void addNmeaListenerAndroidN() {
if (mOnNmeaMessageListener == null) {
mOnNmeaMessageListener = new OnNmeaMessageListener() {
@Override
public void onNmeaMessage(String message, long timestamp) {
writeNmeaToLog(message, mWriteNmeaTimestampToLog ? timestamp : Long.MIN_VALUE);
}
};
}
mLocationManager.addNmeaListener(mOnNmeaMessageListener);
}

private void addLegacyNmeaListener() {
if (mLegacyNmeaListener == null) {
mLegacyNmeaListener = new GpsStatus.NmeaListener() {
@Override
public void onNmeaReceived(long timestamp, String nmea) {
writeNmeaToLog(nmea, mWriteNmeaTimestampToLog ? timestamp : Long.MIN_VALUE);
}
};
}
mLocationManager.addNmeaListener(mLegacyNmeaListener);
}

private void removeNmeaListener() {
if (GpsTestUtil.isGnssStatusListenerSupported()) {
mLocationManager.removeNmeaListener(mOnNmeaMessageListener);
} else {
mLocationManager.removeNmeaListener(mLegacyNmeaListener);
}
}

@RequiresApi(api = Build.VERSION_CODES.N)
private void addNavMessageListener() {
if (mGnssNavMessageListener == null) {
mGnssNavMessageListener = new GnssNavigationMessage.Callback() {
@Override
public void onGnssNavigationMessageReceived(GnssNavigationMessage event) {
writeNavMessageToLog(event);
}

@Override
public void onStatusChanged(int status) {

}
};
}
mLocationManager.registerGnssNavigationMessageCallback(mGnssNavMessageListener);
}

@RequiresApi(api = Build.VERSION_CODES.N)
private void removeNavMessageListener() {
mLocationManager.unregisterGnssNavigationMessageCallback(mGnssNavMessageListener);
}

/**
* Ask the user if they want to enable GPS
*/
Expand Down Expand Up @@ -484,6 +576,35 @@ private void checkTrueNorth(SharedPreferences settings) {
mFaceTrueNorth = settings.getBoolean(getString(R.string.pref_key_true_north), true);
}

private void checkGnssMeasurementOutput(SharedPreferences settings) {
mWriteGnssMeasurementToLog = settings
.getBoolean(getString(R.string.pref_key_measurement_output), false);
}

private void checkNmeaOutput(SharedPreferences settings) {
boolean logNmea = settings.getBoolean(getString(R.string.pref_key_nmea_output), true);
mWriteNmeaTimestampToLog = settings
.getBoolean(getString(R.string.pref_key_nmea_timestamp_output), true);

if (logNmea) {
addNmeaListener();
} else {
removeNmeaListener();
}
}

@RequiresApi(api = Build.VERSION_CODES.N)
private void checkNavMessageOutput(SharedPreferences settings) {
boolean logNavMessage = settings
.getBoolean(getString(R.string.pref_key_navigation_message_output), false);

if (logNavMessage) {
addNavMessageListener();
} else {
removeNavMessageListener();
}
}

@Override
protected void onDestroy() {
removeStatusListener();
Expand Down
44 changes: 44 additions & 0 deletions GPSTest/src/main/java/com/android/gpstest/util/GpsTestUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,23 @@
import android.content.res.Configuration;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.location.GnssMeasurement;
import android.location.GnssNavigationMessage;
import android.location.GnssStatus;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.Log;

public class GpsTestUtil {

private static final String NMEA_OUTPUT_TAG = "GpsOutputNmea";

private static final String MEASURE_OUTPUT_TAG = "GpsOutputMeasure";

private static final String NM_OUTPUT_TAG = "GpsOutputNm";

private static StringBuilder mNmeaOutput = new StringBuilder();

/**
* Returns the Global Navigation Satellite System (GNSS) for a satellite given the PRN. For
* Android 6.0.1 (API Level 23) and lower. Android 7.0 and higher should use
Expand Down Expand Up @@ -136,4 +148,36 @@ public static int dpToPixels(Context context, float dp) {
// Convert the dps to pixels, based on density scale
return (int) (dp * scale + 0.5f);
}

/**
* Outputs the provided nmea message and timestamp to log
*
* @param timestamp timestamp to write to the log, or Long.MIN_VALUE to not write a timestamp to
* log
*/
public static void writeNmeaToLog(String nmea, long timestamp) {
mNmeaOutput.setLength(0);
if (timestamp != Long.MIN_VALUE) {
mNmeaOutput.append(timestamp);
mNmeaOutput.append(",");
}
mNmeaOutput.append(nmea);
Log.d(NMEA_OUTPUT_TAG, mNmeaOutput.toString());
}

/**
* Outputs the provided GNSS navigation message to log
*/
@RequiresApi(api = Build.VERSION_CODES.N)
public static void writeNavMessageToLog(GnssNavigationMessage message) {
Log.d(NM_OUTPUT_TAG, message.toString());
}

/**
* Outputs the provided GNSS measurement to log
*/
@RequiresApi(api = Build.VERSION_CODES.N)
public static void writeGnssMeasurementToLog(GnssMeasurement measurement) {
Log.d(MEASURE_OUTPUT_TAG, measurement.toString());
}
}
6 changes: 6 additions & 0 deletions GPSTest/src/main/res/values/do_not_translate.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@
<string name="pref_key_keep_screen_on">keep_screen_on</string>
<string name="pref_key_true_north">true_north</string>

<string name="pref_key_android_monitor_category">android_monitor_category</string>
<string name="pref_key_nmea_output">nmea_output</string>
<string name="pref_key_nmea_timestamp_output">nmea_timestamp_output</string>
<string name="pref_key_measurement_output">measurement_output</string>
<string name="pref_key_navigation_message_output">navigation_message_output</string>

<string name="pref_key_about_category">about_category</string>
<string name="pref_key_showed_v2_tutorial">showed_v2_tutorial</string>
<string name="pref_key_analyze_gps_accuracy">analyze_gps_accuracy</string>
Expand Down
33 changes: 24 additions & 9 deletions GPSTest/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@

<!-- User tutorial -->
<string name="showcase_gps_on_off_title">Controls</string>
<string name="showcase_gps_on_off_message">&#8226; The On/Off switch starts/stops GPS\n&#8226;
The \"Share\" button sends a location (shown after getting a GPS fix)\n\n
<string name="showcase_gps_on_off_message">&#8226; The On/Off switch starts/stops GNSS\n&#8226;
The \"Share\" button sends a location (shown after getting a GNSS fix)\n\n
<i>(tap to dismiss)</i>
</string>

Expand All @@ -96,23 +96,24 @@
hold up the device
</string>

<string name="pref_gps_category_title">GPS</string>
<string name="pref_auto_start_gps_title">Auto-Start GPS</string>
<string name="pref_auto_start_gps_summary">Start GPS when the app starts</string>
<string name="pref_gps_category_title">GNSS</string>
<string name="pref_auto_start_gps_title">Auto-Start GNSS</string>
<string name="pref_auto_start_gps_summary">Start GNSS when the app starts</string>

<string name="pref_gps_min_time_title">Interval</string>
<string name="pref_gps_min_time_summary">Time between GPS fixes, in seconds</string>
<string name="pref_gps_min_time_summary">Time between GNSS fixes, in seconds</string>
<string name="pref_gps_min_time_dialog_title">Enter an interval, in seconds</string>
<string name="pref_gps_min_time_invalid_entry">Interval must be a number</string>

<string name="pref_gps_min_distance_title">Min. Distance</string>
<string name="pref_gps_min_distance_summary">Minimum distance between GPS fixes, in meters
<string name="pref_gps_min_distance_summary">Minimum distance between GNSS fixes, in meters
</string>
<string name="pref_gps_min_distance_dialog_title">Enter a min. distance, in meters</string>
<string name="pref_gps_min_distance_invalid_entry">Min. Distance must be a number</string>

<string name="pref_analyze_gps_accuracy_title">Analyze GPS Accuracy</string>
<string name="pref_analyze_gps_accuracy_summary">Use GPS Benchmark to measure GPS error</string>
<string name="pref_analyze_gps_accuracy_title">Analyze GNSS Accuracy</string>
<string name="pref_analyze_gps_accuracy_summary">Use GPS Benchmark to measure GNSS error
</string>

<string name="pref_display_category_title">Display</string>
<string name="pref_keep_screen_on_title">Keep Screen On</string>
Expand All @@ -121,6 +122,20 @@
<string name="pref_true_north_summary">Compass will face true north instead of magnetic north
</string>

<string name="pref_output_category_title">Android Monitor Output</string>
<string name="pref_nmea_output_title">NMEA</string>
<string name="pref_nmea_output_summary">Logs NMEA sentences to Android Studio</string>
<string name="pref_nmea_timestamp_output_title">NMEA Timestamp</string>
<string name="pref_nmea_timestamp_output_summary">Include NMEA timestamp in output</string>
<string name="pref_measurement_output_title">Measurements</string>
<string name="pref_measurement_output_summary">Logs GNSS measurements to Android Studio (Android
7.0 and up)
</string>
<string name="pref_navigation_message_output_title">Navigation Messages</string>
<string name="pref_navigation_message_output_summary">Logs GNSS navigation messages to Android
Studio (Android 7.0 and up)
</string>

<string name="pref_about_category_title">About</string>
<string name="pref_show_tutorial_title">Show tutorial</string>
<string name="pref_show_tutorial_summary">Shows instructions for using the app</string>
Expand Down
25 changes: 25 additions & 0 deletions GPSTest/src/main/res/xml/preferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,29 @@
android:summary="@string/pref_true_north_summary"
android:defaultValue="true"/>
</PreferenceCategory>

<PreferenceCategory
android:title="@string/pref_output_category_title"
android:key="@string/pref_key_android_monitor_category">
<CheckBoxPreference
android:key="@string/pref_key_nmea_output"
android:title="@string/pref_nmea_output_title"
android:summary="@string/pref_nmea_output_summary"
android:defaultValue="true"/>
<CheckBoxPreference
android:key="@string/pref_key_nmea_timestamp_output"
android:title="@string/pref_nmea_timestamp_output_title"
android:summary="@string/pref_nmea_timestamp_output_summary"
android:defaultValue="true"/>
<CheckBoxPreference
android:key="@string/pref_key_navigation_message_output"
android:title="@string/pref_navigation_message_output_title"
android:summary="@string/pref_navigation_message_output_summary"
android:defaultValue="false"/>
<CheckBoxPreference
android:key="@string/pref_key_measurement_output"
android:title="@string/pref_measurement_output_title"
android:summary="@string/pref_measurement_output_summary"
android:defaultValue="false"/>
</PreferenceCategory>
</PreferenceScreen>

0 comments on commit f8c9951

Please sign in to comment.