This example create a study protocol that collects steps, light, and screen and battery events from the phone, stores this in the local SQLite database. Data sampling “starts” after a delay of 10 seconds.
You can use the local constructor if you’re make a “local” protocol that (i) only collects simple measures in the background, (ii) only uses the phone as a device, (ii) only have one participant, and (iv) stores data locally in the SQLite database
// Use the on-phone deployment service.DeploymentService deploymentService = SmartphoneDeploymentService();// Create a study deployment using the protocol.var status = await deploymentService.createStudyDeployment(protocol);
The SmartPhoneClientManager is a singleton and can always be accessed by SmartPhoneClientManager().
The most simple configuration of the client manager is:
await SmartPhoneClientManager().configure();
However, the client manager can be configured in different ways:
registration: unique device registration for this phone.
deploymentService: deployment backend (default is local SmartphoneDeploymentService).
dataCollectorFactory: custom collector factory (default uses the standard DeviceController).
enableNotifications: show task notifications (true by default).
enableBackgroundMode: run sampling in background (true by default, Android only).
backgroundNotificationTitle / backgroundNotificationText: text for Android background notification.
askForPermissions: request package permissions automatically (true by default).
Default
Customized
final client = SmartPhoneClientManager();await client.configure();
final client = SmartPhoneClientManager();await client.configure( deploymentService: deploymentService, enableNotifications: true, enableBackgroundMode: true, backgroundNotificationTitle: 'CAMS is running', backgroundNotificationText: 'Collecting sensing data in background', askForPermissions: false, // app handles permissions manually);
Set askForPermissions: false when your app needs a custom permission flow or staged consent screens.
Once the client is configured, you can deploy studies to it. This is done by getting a study deployment from the deployment service, based on the protocol. In order to do this, we need to configure the client to use this deployment service. If the protocol has been added as shown above, this will add and deploy the study on the client:
// Use the on-phone deployment service.DeploymentService deploymentService = SmartphoneDeploymentService();// Create a study deployment using a protocol.var status = await deploymentService.createStudyDeployment(protocol);// Create and configure a client manager to use the deploymentService.SmartPhoneClientManager client = SmartPhoneClientManager();await client.configure(deploymentService: deploymentService);// Add a study based on the deployed protocol to the clientfinal study = await client.addStudy( SmartphoneStudy( studyDeploymentId: status.studyDeploymentId, deviceRoleName: phone.roleName, ),);/// Deploy the study to the client.SmartPhoneClientManager().tryDeployment( study.studyDeploymentId, study.deviceRoleName,);
This will configure the client manager and add a new study based on the specified protocol. However, if using the local SmartphoneDeploymentService, deploying and adding a study based on a protocol can be written more compact like this:
// 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,);
Data sampling can be controlled by the resume and pause methods:
// Resume data sampling for all studies added to the client.SmartPhoneClientManager().resume();// .. and pause all data sampling for all studies again.SmartPhoneClientManager().pause();
Calling resume() or pause() on the client manager will resume or pause all studies added to the client. If you want more fine-grained control over each study, you can control each study using its SmartphoneStudyController:
You can stop a study by calling stop which will permanently stop the study - once stopped, and study cannot be (re)started. Call dispose to dispose of the client - typically in the Flutter dispose method.
// Permanently stop the study.// This will mark the study as stopped and remove it from the client manager.SmartPhoneClientManager().stopStudy( study.studyDeploymentId, study.deviceRoleName,);// Dispose of the client (e.g. in Flutter dispose())client.dispose();
If you just want to run one local protocol, you can use this compact style:
All sampling data is available in the measurements stream. This stream is available on both controller and client:
// Listening on the measurements stream. client.measurements.listen((measurement) { // Do something with the measurement, e.g. print the json. print(toJsonString(measurement)); });
Since it is a standard Dart Stream, you can subscribe, filter, map, etc. as needed.
Subscription example
Filter example
Map example
// subscribe to the stream of measurementsvar subscription = controller?.measurements.listen((Measurement measurement) { // do something w. the measurement ...});... // Cancel the subscription.await subscription?.cancel();