Search code examples
androidjsongpsgson

GSON serializing Location object differently between Android API 26 and API 28


I am having issues with the following code snippet working differently between an emulator instance running API 26 vs. one running API 28. Here is the code snippet that I am running to convert a GPS point data object to JSON.

GPSPointDataFinal dataFinal;
// bunch of code to put data into dataFinal

Gson gson = new GsonBuilder()
        .serializeNulls()
        .create();

String jsonFinalData = gson.toJson(dataFinal);

When I run this code section in the API 26 emulator, I get the following JSON output:

{"gpsData":[ 
  {"elevation":0.0,"location":{ 
    mAltitude":0.0,"mBearing":122.0,"mBearingAccuracyDegrees":0.0,"mElapsedRealtimeNanos":70951742958220,"mExtras":null,"mFieldsMask":14,"mHorizontalAccuracyMeters":20.0,"mLatitude":38.9264983,"mLongitude":-77.0151,"mProvider":"fused","mSpeed":0.0,"mSpeedAccuracyMetersPerSecond":0.0,"mTime":1575977406000,"mVerticalAccuracyMeters":0.0},
  "newSplit":false,"pointStatus":2,"time":{
    "year":2019,"month":11,"dayOfMonth":10,"hourOfDay":6,"minute":30,"second":6}
  }

Note that all of the location related data is in this JSON string. When I run the same code in the API 28 emulator, I get the folloiwng JSON output:

{"gpsData":[
  {"elevation":40.8,"location":{
    "mElapsedRealtimeNanos":9517448972700,"mProvider":"fused"},
  "newSplit":false,"pointStatus":2,"time":{
    "year":2019,"month":11,"dayOfMonth":10,"hourOfDay":6,"minute":32,"second":2}
  }

Note that none of the location data is in the JSON string. In both cases, I have stepped through the execution of the code and confirmed that there is data in the dataFinal object prior to executing the gson.toJson(dataFinal).

When debugging, I am seeing no GSON or JSON related entries in the logcat. Any idea what the cause of this is and how to resolve this?

For information, here are my classes:

public class GPSPointDataFinal {

private GregorianCalendar startTime;
private ArrayList<GPSPointData> gpsData;
private CollectGPSDataServiceStatus status;
private ArrayList<Integer> splitList;

public GregorianCalendar getStartTime() {
    return startTime;
}

public void setStartTime(GregorianCalendar startTime) {
    this.startTime = startTime;
}

public ArrayList<GPSPointData> getGpsData() {
    return gpsData;
}

public void setGpsData(ArrayList<GPSPointData> gpsData) {
    this.gpsData = gpsData;
}

public CollectGPSDataServiceStatus getStatus() {
    return status;
}

public void setStatus(CollectGPSDataServiceStatus status) {
    this.status = status;
}

public ArrayList<Integer> getSplitList() {
    return splitList;
}

public void setSplitList(ArrayList<Integer> splitList) {
    this.splitList = splitList;
}

}

public class GPSPointData {

private Location location;
private double elevation;
private GregorianCalendar time;
private int pointStatus;
private boolean newSplit;


public GPSPointData(Location location, GregorianCalendar time, int status) {
    this.location = location;
    this.elevation = elevation;
    this.time = time;
    this.pointStatus = status;
}

public GPSPointData() {
}

public Location getLocation() {
    return location;
}

public double getElevation() {
    return elevation;
}


public GregorianCalendar getTime() {
    return time;
}

public void setLocation(Location location) {
    this.location = location;
}

public void setElevation(double elevation) {
    this.elevation = elevation;
}

public void setTime(GregorianCalendar time) {
    this.time = time;
}

public int getPointStatus() {
    return pointStatus;
}

public void setPointStatus(int status) {
    this.pointStatus = status;
}

public boolean isNewSplit() {
    return newSplit;
}

public void setNewSplit(boolean newSplit) {
    this.newSplit = newSplit;
}
}

Solution

  • Based on the recommendations from Clownba0t above, the issue was resolved by pulling out the specific fields I needed from the Location object into my GPSPointData object and did not include the location object. When converted to JSON all of the fields are now included.