AI-generated Key Takeaways
-
The Sensors API enables real-time access to raw sensor data from a device and connected wearables, offering functionalities to list data sources, register data listeners, and manage these listeners.
-
Developers can identify available data sources, such as step count, using
SensorsClient.findDataSources
, with the option to filter by data type and device for targeted data retrieval. -
Real-time data updates can be received by attaching a listener using
SensorsClient.add
, defining data types, sources, and sampling rates, for immediate data processing or visualization within the app. -
To stop data updates, developers can detach a listener using
SensorsClient.remove
, ceasing the flow of raw sensor data to the specified listener, freeing resources, and halting real-time processing. -
It is important to note that sensor data is not automatically stored; the Recording API is recommended for background data recording, while the Sensors API is best suited for immediate display and processing of sensor data.
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."));