This guide shows how to install carp_mobile_sensing and configure a Flutter app on Android and iOS.
Install Package Add CAMS dependencies to pubspec.yaml and fetch packages.
Configure Android Configure permissions, services, and Gradle settings.
Configure iOS Add Info.plist keys and AppDelegate notification setup.
Validate Setup Build and verify permissions on physical devices.
1) Install the package
Add dependencies in pubspec.yaml:
environment :
sdk : ">=3.10.0 <4.0.0"
flutter : ">=3.19.0"
dependencies :
flutter :
sdk : flutter
carp_serializable : ^latest
carp_core : ^latest
carp_mobile_sensing : ^latest
Then run:
Use the example app as baseline:
/android/app/src/main/AndroidManifest.xml
/android/app/build.gradle.kts
/ios/Runner/Info.plist
/ios/Runner/AppDelegate.swift
2) Android configuration
Add required permissions
Include permissions for activity recognition, notifications, foreground execution, and battery behavior.
Configure plugin services/receivers
Enable desugaring in Gradle
Add isCoreLibraryDesugaringEnabled = true and the desugar dependency in android/app/build.gradle.kts.
Android manifest permissions
Add permissions for:
activity recognition
notifications (including scheduled notifications)
foreground/background execution
foreground service types used by flutter_background
< 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" />
FOREGROUND_SERVICE_SPECIAL_USE must be aligned with the service subtype description shown to users.
Android services/receivers
Inside <application>, declare both plugin services:
< 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 >
< 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 >
Android Gradle setup
In android/app/build.gradle.kts, enable desugaring and add dependency (required by local notifications):
android {
compileOptions {
isCoreLibraryDesugaringEnabled = true
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
}
dependencies {
coreLibraryDesugaring ( "com.android.tools:desugar_jdk_libs:2.1.4" )
}
Android ic_launcher.png
Both the flutter_local_notification and the flutter_background plugins use the ic_launcher.png as the icon for notifications. Hence, this icon should be added as a drawable resource to the the Android head project in the android/app/src/main/res/drawable/ folder. You typically copy the /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png icon.
3) iOS configuration
Add Info.plist permissions
Add motion permission for step tracking and optional file-sharing keys.
Configure notifications in AppDelegate
Register flutter_local_notifications callback and keep plugin registration.
Info.plist keys
Add motion permission for step tracking:
< key > NSMotionUsageDescription </ key >
< string > This application tracks your steps </ string >
Optional (used in example to expose files in Finder):
< key > UIFileSharingEnabled </ key >
< true />
< key > LSSupportsOpeningDocumentsInPlace </ key >
< true />
AppDelegate notification setup
For flutter_local_notifications , add plugin registrant callback:
import flutter_local_notifications
FlutterLocalNotificationsPlugin. setPluginRegistrantCallback { (registry) in
GeneratedPluginRegistrant. register ( with : registry)
}
if #available ( iOS 10.0 , * ) {
UNUserNotificationCenter. current (). delegate = self as UNUserNotificationCenterDelegate
}
Then keep:
GeneratedPluginRegistrant. register ( with : self )
4) Final checks
Refresh and resolve dependencies
flutter clean
flutter pub get
Build on each platform
flutter run -d android
flutter run -d ios
Verify runtime permissions
Grant notification and motion/activity permissions on device and confirm background behavior.
Important: Explicit plugin dependencies may be needed As discussed in Issue #530 , some projects may need to explicitly add plugin dependencies that CAMS uses transitively. If you see build/runtime plugin registration issues, add the required plugins directly in your app pubspec.yaml (for example flutter_local_notifications and flutter_background ) and run: flutter clean
flutter pub get