Installation
Add carp_connectivity_package to a CAMS app and configure Android and iOS.
The package needs the CARP Mobile Sensing (CAMS) setup plus the permissions of the measures you collect:
| Measure | Android permissions | iOS keys and capabilities |
|---|---|---|
CONNECTIVITY | None | None |
WIFI | ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION | NSLocationWhenInUseUsageDescription, the Access Wi-Fi Information capability |
BLUETOOTH | BLUETOOTH_SCAN, BLUETOOTH_CONNECT; on Android 11 and lower also BLUETOOTH, BLUETOOTH_ADMIN and ACCESS_FINE_LOCATION | NSBluetoothAlwaysUsageDescription |
BEACON | BLUETOOTH_SCAN, ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION, ACCESS_BACKGROUND_LOCATION; on Android 11 and lower also BLUETOOTH and BLUETOOTH_ADMIN | NSBluetoothAlwaysUsageDescription, NSLocationWhenInUseUsageDescription, NSLocationAlwaysAndWhenInUseUsageDescription |
Set up the package in four steps:
Add the packages
The package runs on CAMS, so complete the CAMS setup in Installation first.
Note
By default, an app resolves
flutter_blue_plus2.x, which needs a commercial license for commercial use. When the app is built for Android, version 2.x also tries to send license telemetry. To keep the BSD-licensed 1.x, add it with a version constraint:Configure Android
Add the permissions that your measures need, as listed in the table above, to
android/app/src/main/AndroidManifest.xml. With all four measures, the manifest has these entries:android/app/src/main/AndroidManifest.xml Each entry has this purpose:
Entry Why ACCESS_FINE_LOCATION,ACCESS_COARSE_LOCATIONAndroid returns the Wi-Fi name and access point address only to apps with precise location, and beacon scanning needs precise location. On Android 11 and lower, flutter_blue_plusalso needs it to scan. Android asks for both permissions in one dialog.ACCESS_BACKGROUND_LOCATIONCAMS asks for location all the time for BEACONand starts the measure only when it is granted.BLUETOOTH_SCANBluetooth scanning on Android 12 or later. CAMS asks for it for BLUETOOTHandBEACON.BLUETOOTH_CONNECTflutter_blue_plusneeds it to scan on Android 12 or later, because it reads device names, and asks for it when a scan starts.BLUETOOTH,BLUETOOTH_ADMINBluetooth scanning on Android 11 and lower. The Android Beacon Library, which dchs_flutter_beaconuses, adds both to the merged manifest too.bluetooth_lefeatureTells Google Play that the app uses Bluetooth Low Energy but also installs on phones without it. The plugins add
ACCESS_NETWORK_STATEandACCESS_WIFI_STATEto the merged manifest themselves. The Android Beacon Library also addsACCESS_COARSE_LOCATION,FOREGROUND_SERVICE_LOCATIONandRECEIVE_BOOT_COMPLETED, even when the app does not collectBEACON.If the app does not collect
BEACON, you can addandroid:usesPermissionFlags="neverForLocation"toBLUETOOTH_SCANto declare that the app does not derive location from Bluetooth scans. Leave the flag off forBEACON: with it, Android filters some beacons out of the scan results, as Android's Bluetooth permissions guide explains.Configure iOS
Add the usage descriptions to
ios/Runner/Info.plist.NSBluetoothAlwaysUsageDescriptionis forBLUETOOTHandBEACON,NSLocationWhenInUseUsageDescriptionforWIFIandBEACON, andNSLocationAlwaysAndWhenInUseUsageDescriptionforBEACON:ios/Runner/Info.plist To read the Wi-Fi name and access point address, select Runner → Signing & Capabilities in Xcode, click + Capability and add Access Wi-Fi Information. A Personal Team, the free team of an Apple account, cannot add this capability.
Xcode adds the entitlement to
ios/Runner/Runner.entitlements:ios/Runner/Runner.entitlements CAMS asks for the iOS permissions through
permission_handler, which compiles in only the permissions that the app turns on. How you turn them on depends on how Flutter builds the iOS plugins: with Swift Package Manager, the default from Flutter 3.44, or with CocoaPods:Swift Package Manager CocoaPods permission_handlerturns on the permissions whose usage descriptions are inInfo.plist, so no other change is needed. After you change the keys, delete Xcode's derived data once so that Xcode reads them again:Turn on the Bluetooth and location permissions in the
post_installblock ofios/Podfile. Keep any other permissions that your app uses in the same list:ios/Podfile Register the sampling package
Register the package in
main(), before you configure the client:Call
CarpMobileSensing.ensureInitialized()beforeregister(): registering a sampling package before CAMS is initialized throws a null check error.Registering makes the four measure types and their data and configuration classes known to CAMS. It also adds the Wi-Fi and Bluetooth name hashing to the default privacy schema.
configure()restores the studies saved on the phone and needs these classes to read them.
Troubleshooting
Check that Bluetooth is on and that the participant granted the Bluetooth permissions. On Android 11 and lower, also check that precise location is granted and Location Services are on. Each failed scan window records an error whose message starts with Error scanning for bluetooth - .
Ask for location access in the app: CAMS does not ask for it on behalf of WIFI. See Location permission.
On Android, the participant must also allow precise location, and Location Services must be on. On iOS, the app also needs the Access Wi-Fi Information capability.
Next step
Quickstart
Build an app that collects all four measures and prints them.