No announcement yet.

C# integration with Garmin Connect

  • Time
  • Show
Clear All
new posts

  • C# integration with Garmin Connect

    We were looking for a solution to taking and analysing information posted to Garmin connect for a project. Garmin have not released any sort of web service interface for garmin connect so quite a challenge to get that information. Listed below is the C# code (still a bit rough) that logs in to Garmin and uses the activity-search rest services to receive information:

    Login Method:

    private CookieContainer LoginGRMN(string loginURL,string userName,string password)
    CookieContainer cookiJar = new CookieContainer();
    string loginResponse = "";
    HttpWebRequest getLogin = (HttpWebRequest)HttpWebRequest.Create(loginURL.Replace("https://", "http://"));
    getLogin.Method = "GET";
    getLogin.CookieContainer = cookiJar;
    getLogin.KeepAlive = true;
    var getLoginResp = getLogin.GetResponse();

    HttpWebRequest httpRequest = (HttpWebRequest)HttpWebRequest.Create(loginURL);
    httpRequest.Method = "POST";
    httpRequest.ContentType = "application/x-www-form-urlencoded";
    httpRequest.CookieContainer = cookiJar;
    httpRequest.KeepAlive = true;

    string formData = string.Format("login=login&login%3AloginUsernameField={0}&login%3Apassword={1}&login%3AsignInButton= Sign+In&login%3ArememberMe=false&javax.faces.ViewState=j_id1", HttpUtility.UrlEncode(userName), HttpUtility.UrlEncode(password));

    byte[] bytedata = Encoding.ASCII.GetBytes(formData);
    httpRequest.ContentLength = bytedata.Length;
    Stream requestStream = httpRequest.GetRequestStream();
    requestStream.Write(bytedata, 0, bytedata.Length);

    HttpWebResponse logResponse = (HttpWebResponse)httpRequest.GetResponse();

    Encoding enc = System.Text.Encoding.GetEncoding(1252);
    StreamReader loResponseStream = new
    StreamReader(logResponse.GetResponseStream(), enc);

    loginResponse= loResponseStream.ReadToEnd();
    catch (Exception exp)
    throw new Exception("Error connecting to Garmin Connect for login", exp);
    if (loginResponse.Contains("login:loginUsernameField"))
    throw new Exception("Error logging in to Garmin Connect");

    return cookiJar;

    Search activities method using the JSON response:

    public List<Domain.IntegrationActivity> SearchActivities(Domain.ActivitySearchDetails activitySearch)
    //login to Garmin Connect
    var cookiJar= LoginGRMN(activitySearch.LoginURL, activitySearch.Username, activitySearch.Password);

    //load activities
    string url = activitySearch.ActionURL + "?beginTimestamp>" + activitySearch.FromDate.ToString("s");
    HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);

    req.CookieContainer = cookiJar;
    req.Method = "GET";
    var grmnResponse = req.GetResponse();

    Encoding enc = System.Text.Encoding.GetEncoding(1252);
    StreamReader loResponseStream = new
    StreamReader(grmnResponse.GetResponseStream(), enc);

    string grmnXML = loResponseStream.ReadToEnd();

    //deserialize the JSON response
    var reader = new JsonReader();
    dynamic output = reader.Read(grmnXML);

    if (!PropertyExists("results",output))
    throw new Exception("Error on Garmin Json response");

    //return object
    List<Domain.IntegrationActivity> returnAct = new List<Domain.IntegrationActivity>();
    foreach (dynamic activity in output.results.activities)
    DateTime captureDate = DateTime.Parse(activity.activity.uploadDate.display);

    Domain.IntegrationActivity retActivity = new Domain.IntegrationActivity()
    ActivityReference = activity.activity.activityId,
    CaptureDate =captureDate,
    Calories = PropertyExists("activitySummarySumEnergy", activity.activity) ? int.Parse(activity.activity.activitySummarySumEnergy.display) : 0,
    StartTime =PropertyExists("activitySummaryBeginTimestamp", activity.activity)? DateTime.Parse(activity.activity.activitySummaryBeginTimestamp.display): new DateTime(captureDate.Year,captureDate.Month,captureDate.Day,0,0,0),
    EndTime = PropertyExists("activitySummaryEndTimestamp", activity.activity) ? DateTime.Parse(activity.activity.activitySummaryEndTimestamp.display) : new DateTime(captureDate.Year, captureDate.Month, captureDate.Day, 0, 0, 0),
    Factors = new List<Domain.ActivityFactor>()

    //ADD other factors
    retActivity.Factors.Add(new Domain.ActivityFactor() { Name = "ActivityName", Value = PropertyExists("activityName",activity.activity)?activity.activity.activityName.value:"" });
    retActivity.Factors.Add(new Domain.ActivityFactor() { Name = "ActivityType", Value = PropertyExists("activityType", activity.activity) ? activity.activity.activityType.display : "" });
    retActivity.Factors.Add(new Domain.ActivityFactor() { Name = "Distance", Value = PropertyExists("activitySummarySumDistance", activity.activity) ? activity.activity.activitySummarySumDistance.value : "0" });
    retActivity.Factors.Add(new Domain.ActivityFactor() { Name = "Duration", Value = PropertyExists("activitySummarySumDuration", activity.activity) ? activity.activity.activitySummarySumDuration.minutesSeconds : "0" });
    retActivity.Factors.Add(new Domain.ActivityFactor() { Name = "AverageSpeed", Value = PropertyExists("activitySummaryWeightedMeanSpeed", activity.activity) ? activity.activity.activitySummaryWeightedMeanSpeed.withUnitAbbr : "0" });
    retActivity.Factors.Add(new Domain.ActivityFactor() { Name = "MaxHeartRate", Value = PropertyExists("activitySummaryMaxHeartRate", activity.activity) ? activity.activity.activitySummaryMaxHeartRate.value : "0" });
    retActivity.Factors.Add(new Domain.ActivityFactor() { Name = "MinHeartRate", Value = PropertyExists("activitySummaryMinHeartRate", activity.activity) ? activity.activity.activitySummaryMinHeartRate.value : "0" });
    retActivity.Factors.Add(new Domain.ActivityFactor() { Name = "AverageHeartRate", Value = PropertyExists("activitySummaryWeightedMeanHeartRate", activity.activity) ? activity.activity.activitySummaryWeightedMeanHeartRate.value : "0" });



    return returnAct;

    private bool PropertyExists(string name,ExpandoObject obj)
    return((IDictionary<String, Object>)obj).ContainsKey(name);

    Hope this helps someone


    Martin Naude

  • #2
    Interesting, thanks for posting. Am I right to assume your project references the DLLs in Garmin's API? I downloaded the API months ago but haven't had the chance to use it yet.

    For my personal project (also written in C#), I just export and use the TCX file and use this as my input data source.


    • #3
      please send me your code

      would you mind sharing your project file?
      email me to adammendoza => hotmail

      Adam J. Mendoza
      swim - bike - run
      I will love thee, O LORD, my strength.


      • #4
        With full credit to Martin Naude and his generous code sample above, I created a more complete utility based on it, which I've made public (and I plan to share the source code on GitHub for those interested). In the mean-time, I've described it on my blog:

        Garcon Utility

        David Jacobson


        • #5
          Thanks for this nice coding sample

          Thanks for sharing this sample. Trying to integrate this into my own test app I bumped into two (newbie) questions.

          1) What's this actionURL used?
          2) Where does the Domain.IntegrationActivity come from? I can't seem to find this class anywhere.

          Thanks in advance,


          • #6
            I want to get client garmin device data from health api using c# application. I try to use garmin connect dll but it did not worked. Also I have created a method to get request token as described in api document but I am getting error method not allowed even its POST request.

            Please suggest or provide some reference code in order to retrieve data.



            • #7
              Originally posted by Anusha View Post
              I want to get client garmin device data from health api using c# application. I try to use garmin connect dll but it did not worked. Also I have created a method to get request token as described in api document but I am getting error method not allowed even its POST request.

              Please suggest or provide some reference code in order to retrieve data.

              Currently the Connect REST API based on OAuth. So the way this thread mentioned are no more valid unless you have your own token and your customized POST/GET based on OAuth.