Access raw sensor data

Stay organized with collections Save and categorize content based on your preferences.

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

  • List data sources that are available on the device and on companion devices.
  • Register listeners to receive raw sensor data.
  • Unregister listeners so that they no longer receive raw sensor data.

List available data sources

To obtain a list of all available data sources on the device and on companion devices, use the SensorsClient.findDataSources method:

Kotlin

private val fitnessOptions = FitnessOptions.builder().addDataType(DataType.TYPE_STEP_COUNT_DELTA).build()

// Note: Fitness.SensorsApi.findDataSources() requires the
// ACCESS_FINE_LOCATION permission.
Fitness.getSensorsClient(requireContext(), GoogleSignIn.getAccountForExtension(requireContext(), fitnessOptions))
    .findDataSources(
        DataSourcesRequest.Builder()
            .setDataTypes(DataType.TYPE_STEP_COUNT_DELTA)
            .setDataSourceTypes(DataSource.TYPE_RAW)
            .build())
    .addOnSuccessListener { dataSources ->
        dataSources.forEach {
            Log.i(TAG, "Data source found: ${it.streamIdentifier}")
            Log.i(TAG, "Data Source type: ${it.dataType.name}")

            if (it.dataType == DataType.TYPE_STEP_COUNT_DELTA) {
                Log.i(TAG, "Data source for STEP_COUNT_DELTA found!")

                ...
            }
        }
    }
    .addOnFailureListener { e ->
        Log.e(TAG, "Find data sources request failed", e)
    }

Java

FitnessOptions fitnessOptions = FitnessOptions.builder().addDataType(DataType.TYPE_STEP_COUNT_DELTA).build();

// Note: Fitness.SensorsApi.findDataSources() requires the
// ACCESS_FINE_LOCATION permission.
Fitness.getSensorsClient(getApplicationContext(), GoogleSignIn.getAccountForExtension(getApplicationContext(), fitnessOptions))
        .findDataSources(
                new DataSourcesRequest.Builder()
                        .setDataTypes(DataType.TYPE_STEP_COUNT_DELTA)
                        .setDataSourceTypes(DataSource.TYPE_RAW)
                        .build())
        .addOnSuccessListener(dataSources -> {
            dataSources.forEach(dataSource -> {
                Log.i(TAG, "Data source found: ${it.streamIdentifier}");
                Log.i(TAG, "Data Source type: ${it.dataType.name}");

                if (dataSource.getDataType() == DataType.TYPE_STEP_COUNT_DELTA) {
                    Log.i(TAG, "Data source for STEP_COUNT_DELTA found!");
                    ...
                }
            })})
        .addOnFailureListener(e ->
            Log.e(TAG, "Find data sources request failed", e));

To get information about the device for a data source, use the DataSource.getDevice method. The device information is useful to distinguish from similar sensors on different devices, show the device information from a sensor to the user, or process data differently based on the device. For example, you might be interested in reading data specifically from the sensor on a wearable device but not from the same type of sensor on a phone.

To get a Device instance for the device that's running your activity, use the Device.getLocalDevice method. This is useful when you want to check whether a data source is on the same device that your app is running on.

Add a listener

To add a listener to receive raw data of a particular fitness data type or from a specific data source, use the SensorsClient.add method:

Kotlin

val listener = OnDataPointListener { dataPoint ->
        for (field in dataPoint.dataType.fields) {
            val value = dataPoint.getValue(field)
            Log.i(TAG, "Detected DataPoint field: ${field.name}")
            Log.i(TAG, "Detected DataPoint value: $value")
        }
    }

Fitness.getSensorsClient(this, GoogleSignIn.getAccountForExtension(this, fitnessOptions))
    .add(
        SensorRequest.Builder()
            .setDataSource(dataSource) // Optional but recommended for custom
            // data sets.
            .setDataType(dataType) // Can't be omitted.
            .setSamplingRate(10, TimeUnit.SECONDS)
            .build(),
        listener
    )
    .addOnSuccessListener {
    	Log.i(TAG, "Listener registered!")
    }
    .addOnFailureListener {
    	Log.e(TAG, "Listener not registered.", task.exception)
    }

Java

OnDataPointListener listener = dataPoint -> {
    for (Field field : dataPoint.getDataType().getFields()) {
        Value value = dataPoint.getValue(field);
        Log.i(TAG, "Detected DataPoint field: ${field.getName()}");
        Log.i(TAG, "Detected DataPoint value: $value");
    }
};
Fitness.getSensorsClient(this, GoogleSignIn.getAccountForExtension(this, fitnessOptions))
        .add(
                new SensorRequest.Builder()
                        .setDataSource(dataSource) // Optional but recommended
                        // for custom data sets.
                        .setDataType(dataType) // Can't be omitted.
                        .setSamplingRate(10, TimeUnit.SECONDS)
                        .build(),
                listener
        )
        .addOnSuccessListener(unused ->
                Log.i(TAG, "Listener registered!"))
        .addOnFailureListener(task ->
    Log.e(TAG, "Listener not registered.", task.getCause()));
}

Remove a listener

To remove a listener from raw data updates, use the SensorsClient.remove method:

Kotlin

Fitness.getSensorsClient(this, GoogleSignIn.getAccountForExtension(this, fitnessOptions))
    .remove(listener)
    .addOnSuccessListener {
    	Log.i(TAG, "Listener was removed!")
    }
    .addOnFailureListener {
    	Log.i(TAG, "Listener was not removed.")
    }

Java

Fitness.getSensorsClient(this, GoogleSignIn.getAccountForExtension(this, fitnessOptions))
        .remove(listener)
        .addOnSuccessListener(unused ->
                Log.i(TAG, "Listener was removed!"))
        .addOnFailureListener(e ->
                Log.i(TAG, "Listener was not removed."));