Introduction to the CARP Mobile Sensing (CAMS) framework
This documentation is for CARP Mobile Sensing API level 2.x.
The CARP Mobile Sensing (CAMS) Flutter package carp_mobile_sensing is a framework for adding digital phenotyping capabilities to mobile health apps.The overall goal of CAMS is to help developers build custom mobile sensing applications that can be adapted to very different health domains.CAMS focuses on a flexible engineering architecture that supports:
The code listing below shows a simple Dart example of how to add sampling to a Flutter app. This basic example illustrates how sampling is configured, deployed, initialized, and used in three basic steps;
1
Define Study Protocol
Create a SmartphoneStudyProtocol which defines what measures to collect from different devices.
2
Create and Configure Runtime
Configure the SmartPhoneClientManager and add the study protocol to it.
3
Start Data Sampling
Access the collected stream of measurements and use them in the app and control the execution of the data sampling.
Below is a simple example of how to set up a protocol that samples step counts, ambient light, screen events, and battery events.
import 'package:carp_core/carp_core.dart' hide Smartphone;import 'package:carp_mobile_sensing/carp_mobile_sensing.dart';// Create a protocol collecting steps, light, and screen and battery events// from the phone and store collected measurements in a local SQLite databasefinal phone = Smartphone();final protocol = SmartphoneStudyProtocol( ownerId: 'AB', name: 'Tracking steps, light, screen, and battery', dataEndPoint: SQLiteDataEndPoint(), ) ..addPrimaryDevice(phone) ..addTaskControl( DelayedTrigger(delay: const Duration(seconds: 10)), BackgroundTask( measures: [ Measure(type: SensorSamplingPackage.STEP_EVENT), Measure(type: SensorSamplingPackage.AMBIENT_LIGHT), Measure(type: DeviceSamplingPackage.SCREEN_EVENT), Measure(type: DeviceSamplingPackage.BATTERY_STATE), ], ), phone, );// Create and configure a client manager for this phone.await SmartPhoneClientManager().configure();// Create a study based on the protocol.var study = await SmartPhoneClientManager().addStudyFromProtocol(protocol);// Deploy the study.await SmartPhoneClientManager().tryDeployment( study.studyDeploymentId, study.deviceRoleName,);// Resume sampling.SmartPhoneClientManager().resume();// Listening on the measurements stream.SmartPhoneClientManager().measurements.listen((measurement) { // Do something with the measurement, e.g. print the json. print(toJsonString(measurement));});// Pause sampling.SmartPhoneClientManager().pause();// Resume sampling again.SmartPhoneClientManager().resume();// Dispose the client. Can not be used anymore.SmartPhoneClientManager().dispose();
In the example above, the client manager is configured, the protocol is added, and sampling is started. This can actually be done in one line of code, like this:
CAMS support persistent sampling. This implies that once a study is defined (via a protocol), added, deployed, and resumed, its entire state is persistently saved across app restart.Hence, when using CAMS in an app you do not need to consider restoring studies and restarting data sampling when the app is closed and restarted, even when killed by the OS.Read more on background sensing in the Best Practice page.