Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Exporting Trip Data from Chaser Windows Phone Strava App

0.00/5 (No votes)
5 Jul 2013 1  
This article explains how you can get the data for your last trip off of the Chaser Windows Phone App and convert it to GPX data so you can upload it manually to Strava.

Introduction

Strava stopped supporting their V1 & V2 APIs and is only allowing select partners to use their V3 APIs. Windows Phone does not have an official Strava app, so any apps being used stopped working without having another fully integrated option to upload your data directly to Strava from your phone.

I used a specific app called Chaser, and I had a ride recorded the day they turned off the V2 APIs. I did not want to lose this data, so I went out searching for a way to collect this data. The App had no way built in to do this. This article will explain how you can get the data off of your phone and in the correct format (.GPX) to upload correctly to Strava.

Many apps for the Windows Phone are only supported via 3rd parties. Unfortunately, this means that is likely that this happens to other apps as while. Some of the information in this post may be useful to you to grab the data off of your phone. The example of deserializing the JSON and serializing it to XML may possibly be useful to; although the implementation would be different; the same general paradigm would apply.

Background

There is no way to access the internal storage for Apps on a Windows Phone. In order to get the data off of the phone, I used Fiddler as a proxy to the phone. Using Fiddler as a proxy allows you to see all of the HTTP network traffic being sent to your cellphone. Since the Chaser app just sends a JSON blob containing all of the ride information to Strava without doing any verification of the authentication token first, you can easily get all of the data for the ride .

Once you get the data, it is in some non-standard format. There is a common GPS data format called .GPX. Many websites support GPX and the standard is published along with a schema. We will reformat the data into a .GPX file which you can then upload to Strava or any other site which takes .GPX data.

Steps to Set Up the Proxy

  1. Install Fiddler - If you don't already have Fiddler installed, you can use this link to install it on your desktop PC. I install the 4.0 version, but I think the other versions should work just as well.
  2. Configure Fiddler as a proxy and set Windows Phone to go through the proxy - There are some great instructions on how to do this at the fiddler website. These instructions worked just fine for me as well on Windows Phone 8. I had to have the desktop PC connected to Ethernet in order to get this to work, not sure if this will be the case for everyone.
  3. Launch Fiddler - Once you run fiddler, it will now be acting as the proxy and you should be able to see all the HTTP traffic from the phone on your computer. Go ahead and test it now by going to any webpage on your Windows Phone and make sure you can see the data in Fiddler.

Capturing the Data

  1. Try to upload the data - Once you have the phone setup as a proxy, you can go into the Chaser app and hit the Finish button, followed by the Upload button. Now that you have the proxy setup, you will see the packet containing your ride in Fiddler. All of the data is contained in a JSON blob.

    Image of Chaser Upload Screen

    Image of chaser upload screen
  2. Save the data - Copy paste the JSON blob from Fiddler to a text file. Depending on how you implement the code below, you can save this to a file, or pass it in as a string to convert it to .gpx.

    The data should look something like this:

    {"token": "XxxxXxxxxxx",
                                    "id": "2013-07-05T14:08:56",
                                    "activity_type":"Ride",
                                    "activity_name":"Jul Fri 5 14:07 2013",
                                    "type": "json",
                                    "data_fields": ["time", "latitude", "longitude"],
                                    "data": [["2013-07-04T00:10:28",47.63803872, -122.12497856],
    ["2013-07-04T00:10:38",47.63819225, -122.12509857],
    ["2013-07-04T00:10:43",47.6381939649582, -122.125069499016],
    ["2013-07-04T00:10:47",47.6381939649582, -122.125101685524],
    ["2013-07-04T00:11:10",47.63819442, -122.12514232],
    ["2013-07-04T00:11:11",47.6381948, -122.12514444],
    ["2013-07-04T00:11:12",47.63819501, -122.12514552],
    ["2013-07-04T00:11:13",47.6381971, -122.12514657],
    ["2013-07-04T00:11:14",47.6382686, -122.1252347],
    ["2013-07-04T00:11:15",47.63830859, -122.125289],
    ["2013-07-04T00:11:16",47.63832192, -122.12532939],
    ["2013-07-04T00:11:18",47.63833359, -122.12537187],
    ["2013-07-04T00:11:21",47.63834116, -122.12540437],
    ["2013-07-04T00:11:24",47.63834063, -122.12543642],
    ["2013-07-04T00:11:40",47.63834157, -122.12546144],
    ["2013-07-04T00:12:32",47.63834165, -122.12492476],
    ["2013-07-04T01:14:35",47.59522847, -122.30526577],
    ["2013-07-04T01:23:56",47.6166450977325, -122.307384610176],
    ["2013-07-04T01:24:04",47.6166558265686, -122.307406067848]] 
                                            }

The Code

  1. Create a serialization class from the .GPX schema:

    As I mentioned before, the .GPX schema is open and can be found at http://www.topografix.com/GPX/1/1/gpx.xsd. Visual Studio comes with a command prompt tool for creating serialization classes from a XSD. Download the XSD and then open a Visual Studio command prompt. You can run the tool with a command line like 'xsd /c gpx.xsd' and it will generate a class file gpx.cs. You can add this file to your project in Visual Studio and we will use this to convert the data into GPX file data.

  2. Deserialize the JSON blob

    Once you have the data saved, you will need to convert it to .GPX format. I wrote a quick little helper method in C# to do this.

Using Statements

using System;
using System.Collections.Generic;
using System.IO;
using System.Web.Script.Serialization;
using System.Xml.Serialization;

We use the JavaScriptSerializer class from the System.Web.Script.Serialization namespace, which requires you to add a reference to the System.Web.Extensions.dll as it is not referenced by default in C# projects. We also use the XmlSerializer class from the System.Xml.Serialization class.

Serializing the JSON Data

Serializing the JSON data is relatively straightforward with the JavaScriptSerializer class.

var serializer = new JavaScriptSerializer();
object obj = serializer.DeserializeObject(json);
Dictionary<string, object><string,> jsonDictionary = (Dictionary<string, object><string,>)obj;
</string,></string,>

This will create a loosely typed collection. Each item's key corresponds to the data in the JSON blob before the ':', whereas the object contained in the value is whatever is after the ':' for that object.

Creating the GPX Object

I downloaded a .GPX file from Strava to compare how the JSON blob maps to the GPX file. From doing this, I was able to determine the structure of the GPX object:

gpxType gpx = new gpxType();
gpx.creator = "Strava JSON to GPX convertor";
gpx.metadata = new metadataType();
gpx.metadata.author = new personType();
gpx.metadata.author.name = "Nigel Stuke"; 
gpx.version = "1.1";
gpx.trk = new trkType[1];
gpx.trk[0] = new trkType();
gpx.trk[0].name = "The name for this ride";
gpx.trk[0].trkseg = new trksegType[1];
gpx.trk[0].trkseg[0] = new trksegType(); 

This creates the object and instantiates some fields. Some of this data (activity name) could be extracted from the JSON data. But what we mostly care about is the GPS data.

Converting the Data

Looking at the JSON blob, we can see there are three values: "time", "latitude", and "longitude". We can easily take these values for each data point and plug them into the appropriate type in the GPX file.

object dataObject = jsonDictionary["data"];
object[] dataObjects = (object[])dataObject;
wptType[] waypoints = Array.ConvertAll(
    dataObjects,
    new Converter<object, wptType>(
        (waypointObject) =>
        {
            object[] waypointObjects = (object[])waypointObject;
            DateTime dateTime = Convert.ToDateTime(waypointObjects[0]);
            Decimal latitude = Convert.ToDecimal(waypointObjects[1]);
            Decimal longitude = Convert.ToDecimal(waypointObjects[2]);
            var waypoint = new wptType();
            waypoint.time = dateTime;
            waypoint.timeSpecified = true; 
            waypoint.lat = latitude;
            waypoint.lon = longitude;
            return waypoint;
        }));

gpx.trk[0].trkseg[0].trkpt = waypoints; 

This will gives us all the elements from the JSON blob converted to the right data point types for the .GPX format.

Now you have the data as a .GPX object, you can just simply serialize it to a .GPX file, or do whatever else you want with it. This will save you from having to discard your data; you can now import your data via your computer!

using (StreamWriter sw = new StreamWriter("output.gpx"))
{
    XmlSerializer serializer = new XmlSerializer(typeof(gpxType));
    serializer.Serialize(sw, gpx); 
}

In my case, I uploaded the new file and was able to see that the ride was plotted and imported correctly to Strava. Hopefully, you can use this pattern as well to capture data from your Windows Phone.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here