Skip to content
CARP Docs
Ask AISystemLightDark
On this page

CARP Mobile Sensing

CARP Mobile Sensing (CAMS) is a Flutter framework for adding digital phenotyping and mobile sensing to health apps.

Copy MarkdownOpen inOpen in GitHubView as MarkdownOpen in Scira AIOpen in ChatGPTOpen in ClaudeOpen in Cursor

Warning

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. Use it to build custom mobile sensing apps that you can adapt to very different health domains.

pub.devAPI referenceGitHub

Features

CAMS is built on a flexible engineering architecture that supports:

  • cross-platform (Android and iOS) support
  • persistent sampling state management
  • multiple wearable and device integrations
  • configurable data sampling and transformation
  • pluggable data management and upload strategies

What you can collect

Onboard phone sensors

Movement data (IMU), location, nearby devices, steps, screen events and many other measures.

Wearable devices

Smartwatches (for example Apple Watch), heart rate monitors (for example Polar), ECG monitors, glucose monitors, iBeacons and other devices.

User-generated data

Surveys, questionnaires, ecological momentary assessments (EMAs), audio, video and sound from participants.

Cognitive assessment

14 predefined cognitive assessment tools, such as trail-making, reaction time, recall, flanker and object tracking tests.

See Measure types for the full list of measures and the sampling packages that provide them.

Requirements

CAMS runs on Android and iOS.

ComponentRequirement
Dart SDK>=3.10.0 <4.0.0
Flutter>=3.38.1
iOSMinimum deployment target 15.0
AndroidCore library desugaring enabled in Gradle

Installation covers the full Android and iOS setup.

How it works

Adding sampling to a Flutter app takes three steps:

  1. Define a study protocol

    Create a SmartphoneStudyProtocol that defines which measures to collect from which devices.

  2. Create and configure the runtime

    Configure the SmartPhoneClientManager and add the study protocol to it.

  3. Start data sampling

    Access the stream of collected measurements, use them in the app and control the execution of data sampling.

Example

This protocol samples step counts, ambient light, screen events and battery events, and stores the measurements in a local SQLite database:

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 database
final 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();

Minimal example

You can configure the client manager, add the protocol and start sampling in a single statement:

SmartPhoneClientManager().configure().then(
  (_) => SmartPhoneClientManager()
      .addStudyFromProtocol(
        SmartphoneStudyProtocol.local(
          name: 'Tracking steps, light, screen, and battery',
          measures: [
            Measure(type: SensorSamplingPackage.STEP_EVENT),
            Measure(type: SensorSamplingPackage.AMBIENT_LIGHT),
            Measure(type: DeviceSamplingPackage.SCREEN_EVENT),
            Measure(type: DeviceSamplingPackage.BATTERY_STATE),
          ],
        ),
      )
      .then(
        (study) => SmartPhoneClientManager()
            .tryDeployment(study.studyDeploymentId, study.deviceRoleName)
            .then((_) => SmartPhoneClientManager().resume()),
      ),
);

Persistent sampling

Once a study is defined (through a protocol), added, deployed and resumed, CAMS saves its entire state persistently across app restarts. You do not need to restore studies or restart data sampling when the app is closed and restarted, even when the OS kills it. See background sensing.

Next steps

Installation

Add the package and configure Android and iOS.

Quickstart

Build a Flutter app that collects step, battery and app lifecycle data.

Using CAMS

End-to-end flow from protocol definition to runtime data streams.

Documentation map

Software architecture

Runtime, infrastructure and plugin layers, and how a study is executed.

Domain model

Study protocols, triggers, tasks, measures, devices and measurements.

Measure types

Supported measure types across built-in and external sampling packages.

Data managers

File, SQLite, Firebase and CAWS storage and upload options.

App task model

User-facing tasks, queueing, notifications and execution lifecycle.

Data transformation and privacy

Output transformations and privacy schemas for collected data.

Extending CAMS

Add custom triggers, probes, data managers and transformer schemas.

Best practices

Android and iOS setup recommendations, permissions and troubleshooting.

Quick links

Page · DocumentationCARP DocumentationPage · DocumentationIntroductionPage · DocumentationQuickstartPage · DocumentationTerminologyPage · DocumentationArchitecture