Skip to content
CARP Docs
Ask AISystemLightDark
On this page

Installation

Add carp_mobile_sensing to a Flutter app and configure Android and iOS.

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

Install carp_mobile_sensing, configure the Android and iOS host projects, and verify the setup on a physical device.

Use the example app as a baseline

Use these files of the example app as a baseline:

  • /android/app/src/main/AndroidManifest.xml
  • /android/app/build.gradle.kts
  • /ios/Runner/Info.plist
  • /ios/Runner/AppDelegate.swift

Install the package

Add the dependencies to pubspec.yaml:

pubspec.yaml
environment:
  sdk: ">=3.10.0 <4.0.0"
  flutter: ">=3.38.1"

dependencies:
  flutter:
    sdk: flutter
  carp_serializable: ^latest
  carp_core: ^latest
  carp_mobile_sensing: ^latest

Then fetch the packages:

flutter pub get

Configure Android

Configure permissions, the services and receivers of the flutter_background and flutter_local_notifications plugins, and the Gradle settings.

  1. Add the required permissions

    Add permissions for:

    • activity recognition
    • notifications, including scheduled notifications
    • foreground and background execution
    • battery behavior
    • the foreground service types used by flutter_background
    android/app/src/main/AndroidManifest.xml
    <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION"/>
    
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
    <uses-permission android:name="android.permission.USE_EXACT_ALARM" />
    <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"
            android:maxSdkVersion="32" />
    
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
    
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />

    Note

    FOREGROUND_SERVICE_SPECIAL_USE must be aligned with the service subtype description shown to users.

  2. Declare the plugin services and receivers

    Inside <application>, declare the service for flutter_background:

    android/app/src/main/AndroidManifest.xml
    <service
        android:name="de.julianassmann.flutter_background.IsolateHolderService"
        android:exported="false"
        android:foregroundServiceType="dataSync|specialUse">
        <property android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
            android:value="Collection of data while app is in background."/>
    </service>

    Then declare the service and receivers for flutter_local_notifications:

    android/app/src/main/AndroidManifest.xml
    <service
        android:name="com.dexterous.flutterlocalnotifications.ForegroundService"
        android:exported="false"
        android:stopWithTask="false"/>
    
    <receiver android:exported="false" android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver" />
    
    <receiver android:exported="false" android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
            <action android:name="android.intent.action.QUICKBOOT_POWERON" />
            <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
        </intent-filter>
    </receiver>
  3. Enable core library desugaring

    flutter_local_notifications requires core library desugaring. Enable it and add the desugaring dependency:

    android/app/build.gradle.kts
    android {
      compileOptions {
        isCoreLibraryDesugaringEnabled = true
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
      }
    }
    
    dependencies {
      coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.4")
    }
  4. Add the notification icon

    Both flutter_local_notifications and flutter_background use ic_launcher.png as the notification icon. Add it as a drawable resource in android/app/src/main/res/drawable/. Typically, you copy /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png.

Configure iOS

Warning

CAMS requires iOS 15.0 or newer. Set the minimum deployment target to 15.0 in Xcode (Runner → General → Minimum Deployments), otherwise the iOS build fails.

  1. Add the Info.plist keys

    Add the motion permission used for step tracking:

    ios/Runner/Info.plist
    <key>NSMotionUsageDescription</key>
    <string>This application tracks your steps</string>

    Optionally, expose the app's files in Finder, as the example app does:

    ios/Runner/Info.plist
    <key>UIFileSharingEnabled</key>
    <true/>
    <key>LSSupportsOpeningDocumentsInPlace</key>
    <true/>

    You need UIFileSharingEnabled to access stored data files through Finder (see Data managers).

  2. Configure notifications in AppDelegate

    For flutter_local_notifications, register the plugin registrant callback:

    ios/Runner/AppDelegate.swift
    import flutter_local_notifications
    
    FlutterLocalNotificationsPlugin.setPluginRegistrantCallback { (registry) in
      GeneratedPluginRegistrant.register(with: registry)
    }
    if #available(iOS 10.0, *) {
      UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate
    }

    Keep the existing plugin registration:

    ios/Runner/AppDelegate.swift
    GeneratedPluginRegistrant.register(with: self)

Verify the setup

  1. Refresh and resolve dependencies

    flutter clean
    flutter pub get
  2. Build on each platform

    Build on physical devices:

    flutter run -d android
    flutter run -d ios
  3. Verify runtime permissions

    Grant the notification and motion/activity permissions on the device and confirm the background behavior.

Troubleshooting

Plugin registration errors

As discussed in issue #530, some projects may need to explicitly add plugin dependencies that CAMS uses transitively.

If you see build or runtime plugin registration issues, add the required plugins, for example flutter_local_notifications and flutter_background, directly to your app's pubspec.yaml and run:

flutter clean
flutter pub get

For more platform setup and build issues, see Best practices.

Next steps

Using CAMS

Define a study protocol, deploy it and start sampling.

Quickstart

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

Quick links

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