Google Fit

Getting Started

Google Fit is an open ecosystem that allows developers to upload fitness data to a central repository where users can access their data from different devices and apps in one location:

  • Fitness apps can store data from either wearable or sensor.
  • Fitness apps can access data created by any app.
  • User's fitness data is persisted when they upgrade their fitness devices.

Note: The Google Fit app uses the Google Fit platform which is included in Google Play services. Your fitness or wellness app can use the Google Fit platform without requiring users to install the Google Fit app.

In most cases when you want to integrate Google Fit features into your project, you already have Google Play Services enabled and configured up. If not, please, follow Google Play Services Getting Started guide. As Google Fit is a part of Google Play Services, the basic app configuration setup is the same. So, please, make sure, that your Google API Console is properly set up and all the plugin settings are ready to go.

Enable the Google Fit API in Android Native Settings Inspector window (please, see the screenshot below). All the required application tags will be added to your main AndroidManifest.xml file.

From this point you are ready to start programming your in-game logic for Google Fit.

Google Fit Login

To use the Google Fit APIs, you need a Google Account. If you already have an account, then you have all set. You may also want to create a separate Google Account for testing purposes.

Google Fit is available on Android devices with Google Play services 7.0 or higher. Devices running Android 2.3 or higher that have the Google Play Store app automatically receive updates to Google Play services.

To check which version of Google Play services is installed on your device, go to Settings > Apps > Google Play services.

Before you can invoke methods from the Google Fit APIs, you have to connect to the appropriate fitness service or services which are the parts of Google Play services. The following APIs are available for you:

For more information on these APIs see the Android APIs Overview.

Note: Existing apps that were developed on versions prior to Google Play services 7.0 and use the Fitness.API,are still compatible with devices on Google Play services 7.0. However, we strongly suggest updating your app to take advantage of the reduced memory requirements with newer API.

When your app requests a connection to the service, it specifies the scope of access that it needs. Google Fit asks the user to grant permission to your app to access their fitness data. For more information about scopes and authorization see Authorization.

Create the API client as follows:

  1. Add all the needed APIs:
    SA.Fitness.Connection.Instance.AddApi (SA.Fitness.LoginApi.SENSORS_API);
    SA.Fitness.Connection.Instance.AddApi (SA.Fitness.LoginApi.RECORDING_API);

     

  2. Add all the required scopes:
    SA.Fitness.Connection.Instance.AddScope (SA.Fitness.LoginScope.SCOPE_LOCATION_READ);
    SA.Fitness.Connection.Instance.AddScope (SA.Fitness.LoginScope.SCOPE_ACTIVITY_READ);
    SA.Fitness.Connection.Instance.AddScope (SA.Fitness.LoginScope.SCOPE_ACTIVITY_READ_WRITE);
  3. Subscribe to connection finished callback to check the status of the connection and make any decision further:
    SA.Fitness.Connection.Instance.OnConnectionFinished += Fit_OnConnectionFinished;
    
    void Fit_OnConnectionFinished(SA.Fitness.ConnectionResult result)
    {
    	Debug.Log ("Fitness connection result: " + result.IsSucceeded);
    }

     
  4. Make the Google Fit Connect call. The result callback will be fired when the connection will be finished. The full code for Google Fit connection is following:
SA.Fitness.Connection.Instance.AddApi (SA.Fitness.LoginApi.SENSORS_API);
SA.Fitness.Connection.Instance.AddApi (SA.Fitness.LoginApi.RECORDING_API);
SA.Fitness.Connection.Instance.AddScope (SA.Fitness.LoginScope.SCOPE_LOCATION_READ);
SA.Fitness.Connection.Instance.AddScope (SA.Fitness.LoginScope.SCOPE_ACTIVITY_READ);
SA.Fitness.Connection.Instance.AddScope (SA.Fitness.LoginScope.SCOPE_ACTIVITY_READ_WRITE);
SA.Fitness.Connection.Instance.OnConnectionFinished += Fit_OnConnectionFinished;
SA.Fitness.Connection.Instance.Connect ();

void Fit_OnConnectionFinished(SA.Fitness.ConnectionResult result)
{
	Debug.Log ("Fitness connection result: " + result.IsSucceeded);
	if (!result.IsSucceeded) {
		Debug.Log ("Google Fit Connection FAIL! Result: " + result.Error.Code + " " + result.Error.Message);
	} else {
        //Google Fit connection success
	}
}

Sensors API

The Sensors API lets you read raw sensor data in your app in real time. Use this API to:

  • List data sources available on the device and on companion devices.
  • Register listeners to receive raw sensor data.
  • Unregister listeners to stop receiving raw sensor data.

The Sensors API does not automatically store sensor readings in the fitness store, and sensor registrations created with the Sensors API are not persisted when the system restarts. Typically, you use the Recording API to record data in the background with persistent subscriptions, and you use the Sensors API to display or process sensor readings in real time. In many cases you use both of these APIs in your app.

Important: For best practices while managing user data, see Responsible use of Google Fit.

To obtain a list of all available data sources on the device and on companion devices, use the SA.Fitness.Sensors.Instance.RequestSensors method:

SA.Fitness.SensorRequest.Builder builder = new SA.Fitness.SensorRequest.Builder ()
			.AddDataType (SA.Fitness.DataType.TYPE_LOCATION_SAMPLE)
				.AddDataType (SA.Fitness.DataType.TYPE_LOCATION_TRACK)
				.AddDataType (SA.Fitness.DataType.TYPE_STEP_COUNT_DELTA)
				.AddDataType (SA.Fitness.DataType.TYPE_DISTANCE_DELTA)
				.AddDataSourceType (SA.Fitness.DataSourceType.RAW)
				.AddDataSourceType (SA.Fitness.DataSourceType.DERIVED);
		SA.Fitness.SensorRequest request = builder.Build ();
		request.OnRequestFinished += Request_OnRequestFinished;
		SA.Fitness.Sensors.Instance.RequestSensors (request);

void Request_OnRequestFinished (SA.Fitness.SensorRequestResult result)
	{
		Debug.Log ("Request_OnRequestFinished " + result.Id);
		if (result.IsSucceeded) {
			dataSources = result.DataSources;
		}
	}

To add a listener to receive raw data of a particular fitness data type or from a specific data source, use the SA.Fitness.Sensors.Instance.RegisterSensorListener  method:

private void registerSensorsListeners() {
		int index = 1;
		foreach (SA.Fitness.DataSource source in dataSources) {
			Debug.Log ("Data Source #" + index);
			Debug.Log (source.DataSourceType);
			Debug.Log (source.AppPackageName);
			Debug.Log (source.DataType);
			Debug.Log (source.Device);
			Debug.Log (source.Name);
			Debug.Log (source.StreamId);
			Debug.Log (source.StreamName);
			
			SA.Fitness.SensorListener.Builder builder = new SA.Fitness.SensorListener.Builder ()
				.SetDataType (source.DataType)
					.SetSamplingRate (5U, SA.Fitness.TimeUnit.Seconds);
			SA.Fitness.SensorListener listener = builder.Build ();
			listener.OnRegisterSuccess += Listener_OnRegisterSuccess;
			listener.OnRegisterFail += Listener_OnRegisterFail;
			listener.OnDataPointReceived += Listener_OnDataPointReceived;
			SA.Fitness.Sensors.Instance.RegisterSensorListener (listener);
			
			index++;
		}
	}

void Listener_OnRegisterSuccess (int id)
	{
		Debug.Log ("[Listener_OnRegisterSuccess] " + id.ToString());
	}
	
	void Listener_OnRegisterFail (int id)
	{
		Debug.Log ("[Listener_OnRegisterFail] " + id.ToString());
	}
	
	void Listener_OnDataPointReceived (int id, SA.Fitness.DataPoint dataPoint)
	{
		Debug.Log ("[Listener_OnDataPointReceived] id " + id.ToString() + " dataPoint type: " + dataPoint.DataType.Value);
		Debug.Log ("FIELDS: " + dataPoint.Fields.Count.ToString() + "#");
		foreach (KeyValuePair<string, object> pair in dataPoint.Fields) {
			Debug.Log ("key:" + pair.Key + " value:" + pair.Value.ToString());
		}
	}

Recording API

The Recording API enables your app to request automated storage of sensor data in a battery- efficient manner by creating subscriptions. A subscription is associated with an Android app and consists of a fitness data type or a specific data source.

You can create multiple subscriptions for different data types or data sources in your app. Google Fit stores fitness data from active subscriptions even when your app is not running and restores these subscriptions when the system restarts.

The recorded data is available in the user's fitness history. If you also want to show the data in your app in real time, you need to use the Sensors API together with the Recording API. To record fitness data with session metadata, you can use the Sessions API.

Important: For best practices while managing user data, see Responsible use of Google Fit.

To get a list of the active subscriptions for your app, use the SA.Fitness.Recording.Instance.ListSubscriptions method:

private void listSubscriptions() {
	//List subscriptions
	SA.Fitness.SubscriptionsRequest.Builder builder = new SA.Fitness.SubscriptionsRequest.Builder();
	SA.Fitness.SubscriptionsRequest request = builder.Build ();
	request.OnRequestFinished += Request_OnRequestFinished1;
	SA.Fitness.Recording.Instance.ListSubscriptions (request);
}

void Request_OnRequestFinished1 (SA.Fitness.SubscriptionsRequestResult result)
{
	Debug.Log ("SubscriptionsRequest.ListSubscriptions " + result.IsSucceeded);
	if (result.IsSucceeded) {
		foreach (SA.Fitness.Subscription sub in result.Subscriptions) {
			Debug.Log ("Subscription: " + sub.DataType.Value);
		}
	}
}

To request background collection of sensor data in your app, use the SA.Fitness.Recording.Instance.Subscribe method:

private void subscribe() {
	//Subscribe
	SA.Fitness.SubscribeRequest.Builder builder = new SA.Fitness.SubscribeRequest.Builder();
	builder.SetDataType (SA.Fitness.DataType.TYPE_ACTIVITY_SAMPLES);
	SA.Fitness.SubscribeRequest request = builder.Build ();
	request.OnSubscribeFinished += Request_OnSubscribeFinished;
	SA.Fitness.Recording.Instance.Subscribe(request);
}

void Request_OnSubscribeFinished (SA.Common.Models.Result result)
{
	Debug.Log ("Request_OnSubscribeFinished " + result.IsSucceeded);
}

To stop collecting sensor data in your app, use the SA.Fitness.Recording.Instance.Unsubscribe method:

private void unsubscribe() {
	//Unsubscribe
	SA.Fitness.UnsubscribeRequest.Builder builder = new SA.Fitness.UnsubscribeRequest.Builder();
	builder.SetDataType (SA.Fitness.DataType.TYPE_ACTIVITY_SAMPLES);
	SA.Fitness.UnsubscribeRequest request = builder.Build ();
	request.OnUnsubscribeFinished += Request_OnUnsubscribeFinished;
	SA.Fitness.Recording.Instance.Unsubscribe (request);
}

void Request_OnUnsubscribeFinished (SA.Common.Models.Result result)
{
	Debug.Log ("[Request_OnUnsubscribeFinished] " + result.IsSucceeded);
}