Skip to content
CARP Docs
Ask AISystemLightDark
On this page

Installation

Add carp_polar_package to a CAMS app and configure Bluetooth on Android and iOS.

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

Setting up the Polar package takes four steps on top of the CARP Mobile Sensing (CAMS) setup:

  1. Add the packages

    flutter pub add carp_core carp_mobile_sensing carp_polar_package

    The package needs CAMS, so complete Installation for CAMS first.

    The package brings in the polar plugin, which adds the Polar BLE SDK to the Android and iOS builds. With CAMS 2.5.1, flutter pub add resolves polar 7.11.0 on Flutter 3.44 or later and 7.10.1 on earlier versions. Both include Polar BLE SDK 6.14.0.

    If your code imports package:polar/polar.dart, for example to use PolarDataType, also add the plugin as a direct dependency:

    flutter pub add polar
  2. Configure Android

    Add the Bluetooth and location permissions to android/app/src/main/AndroidManifest.xml, directly above the <application> element:

    android/app/src/main/AndroidManifest.xml
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN"
        android:usesPermissionFlags="neverForLocation" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

    The permissions serve these purposes:

    PermissionPurpose
    BLUETOOTH_SCANLets the Polar BLE SDK find the sensor on Android 12 or later. neverForLocation declares that the app does not derive location from the scan.
    BLUETOOTH_CONNECTLets the Polar BLE SDK connect to the sensor on Android 12 or later.
    ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATIONCAMS checks the location permission on every Android version before it connects to a Bluetooth device.

    Warning

    Do not limit the location permissions with android:maxSdkVersion. CAMS needs the location permission on every Android version.

    The polar plugin adds the legacy BLUETOOTH and BLUETOOTH_ADMIN permissions for Android 11 and earlier to the merged manifest. The Polar BLE SDK needs minSdk 24 or later, the default for new Flutter projects. The plugin downloads the SDK from the JitPack Maven repository.

  3. Configure iOS

    Add a Bluetooth usage description and the bluetooth-central background mode to ios/Runner/Info.plist, inside the <dict>:

    ios/Runner/Info.plist
    <key>NSBluetoothAlwaysUsageDescription</key>
    <string>This app connects to your Polar sensor to record your heart rate for a research study.</string>
    <key>UIBackgroundModes</key>
    <array>
      <string>bluetooth-central</string>
    </array>

    If UIBackgroundModes already exists, add the bluetooth-central string to it. The background mode keeps the connection to the sensor, and the data, flowing while the app is in the background. In Xcode, it is Uses Bluetooth LE accessories under Signing & Capabilities → Background Modes.

    CAMS requests the Bluetooth permission through the permission_handler plugin. If your iOS project uses CocoaPods, enable that permission in the post_install block of ios/Podfile:

    ios/Podfile
    post_install do |installer|
      installer.pods_project.targets.each do |target|
        flutter_additional_ios_build_settings(target)
        target.build_configurations.each do |config|
          config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
            '$(inherited)',
            'PERMISSION_BLUETOOTH=1',
          ]
        end
      end
    end

    If the list already exists, add only the PERMISSION_BLUETOOTH=1 line. With Swift Package Manager, permission_handler enables the permission by itself when Info.plist contains NSBluetoothAlwaysUsageDescription.

    The polar plugin supports both CocoaPods and Swift Package Manager, and it pulls in the Polar BLE SDK either way. Do not add PolarBleSdk to the project yourself. The SDK needs iOS 14.0 or later, which the CAMS minimum of 15.0 covers.

  4. Register the sampling package

    Register the package in main(), before you configure SmartPhoneClientManager:

    import 'package:carp_core/carp_core.dart' hide Smartphone;
    import 'package:carp_mobile_sensing/carp_mobile_sensing.dart';
    import 'package:carp_polar_package/carp_polar_package.dart';
    
    void main() {
      CarpMobileSensing.ensureInitialized();
      SamplingPackageRegistry().register(PolarSamplingPackage());
      // ... the rest of your app
    }

    Call CarpMobileSensing.ensureInitialized() before register(): registering a sampling package before CAMS is initialized throws a null check error.

    Registering makes the seven Polar measure types and the PolarDevice configuration known to CAMS, and adds the PolarDeviceManager that connects to the sensor. It also registers the Polar classes for JSON, so that CAMS can read protocols and data that contain them.

Troubleshooting

The analyzer reports that Smartphone is ambiguous

Hide Smartphone when you import carp_core. Both carp_core and carp_mobile_sensing define the class, and CAMS apps use the one in carp_mobile_sensing:

import 'package:carp_core/carp_core.dart' hide Smartphone;
The log says the permissions required to connect are missing

Call requestPermissions() on the Polar device manager before it connects, because CAMS does not ask for Bluetooth permissions by itself. On Android, also check that the manifest declares both location permissions without android:maxSdkVersion. See Request Bluetooth permissions.

Next step

Quickstart

Connect to a Polar sensor and print its heart rate and ECG.

Quick links

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