This is the official repository of Polar's software development kit. With this SDK you are able to develop your own Android and iOS applications for sensors and watches made by Polar.
The SDK API uses ReactiveX. You can read more about ReactiveX from their website reactivex
- Features
- Project structure
- Android getting started
- iOS getting started
- Migration Guides
- Collaboration
- License
- Third-party code and licenses
Polar 360 is a new stylish wearable that is designed for individuals but made for business. It can be customized by companies and integrated into their own applications and solutions. It is a device designed to increase general well-being and to make the lives of end users healthier and happier.
- Heart rate as beats per minute.
- Acceleration: 50Hz, 16bit resolution, Range 8G
- PP interval (milliseconds) representing cardiac pulse-to-pulse interval extracted from PPG signal.
- PP interval is highly sensitive to movement and shall be used only at rest.
- Skin temperature: 1Hz, 2Hz, 4Hz options, 32 bit resolution
- Battery level
- SDK mode
- Acceleration: 12Hz, 25Hz, 50Hz, 100Hz, 200Hz, 400Hz, 16bit resolution, Range: 2G, 4G, 8G, 16G
- Offline recording
- 24/7 Steps counting
- Sleep duration and sleep stages
- Firmware update
- Setting user's physical info
- Deleting data from device
Most accurate Heart rate sensor in the markets. The H10 is used in the Getting started section of this page. Store page
- Heart rate as beats per minute and RR Interval in ms.
- Heart rate broadcast.
- Electrocardiography (ECG) data in µV with sample rate 130Hz.
- Accelerometer data with sample rates of 25Hz, 50Hz, 100Hz and 200Hz and range of 2G, 4G and 8G. Axis specific acceleration data in mG.
- Start and stop of internal recording and request for internal recording status. Recording supports RR, HR with one second sampletime or HR with five second sampletime.
- List, read and remove for stored internal recording (sensor supports only one recording at the time).
Reliable high quality heart rate chest strap. Store page
- Heart rate as beats per minute and RR Interval in ms.
- Heart rate broadcast.
Optical heart rate sensor is a rechargeable device that measures user’s heart rate with LED technology. Store page
- Heart rate as beats per minute.
- Heart rate broadcast.
- Photoplethysmograpy (PPG) values.
- PP interval (milliseconds) representing cardiac pulse-to-pulse interval extracted from PPG signal.
PP interval is highly sensitive to movement and shall be used only at rest. When the algorithm is enabled, the heart rate is computed from the PP interval every 5 seconds. If movement is detected, the heart rate is fixed to the last reliable value. To ensure that the heart rate is accurately computed, please check the “blocker” flag in the PPG packet.
- Accelerometer data with sample rate of 52Hz and range of 8G. Axis specific acceleration data in mG.
- Gyroscope data with sample rate of 52Hz and ranges of 2000dps. Axis specific gyroscope data in dps.
- Magnetometer data with sample rates of 10Hz, 20Hz, 50HZ and 100Hz and range of +/-50 Gauss. Axis specific magnetometer data in Gauss.
- SDK mode from version 1.1.5 onwards.
- Offline recording from version 2.1.0 onwards.
Optical heart rate sensor is a rechargeable device that measures user’s heart rate with LED technology. Store page
- Heart rate as beats per minute.
- Heart rate broadcast.
- Photoplethysmograpy (PPG) values.
- PP interval (milliseconds) representing cardiac pulse-to-pulse interval extracted from PPG signal.
- Accelerometer data with samplerate of 50Hz and range of 8G. Axis specific acceleration data in mG.
Fitness and wellness watch. Store page
- SDK compatibility added to Ignite 3 in firmware update 2.0.14.
- Heart rate as beats per minute.
- Heart rate broadcast.
- PP interval (milliseconds) representing cardiac pulse-to-pulse interval extracted from PPG signal.
- Accelerometer data with sample rate of 50 Hz and range of 8 G. Axis specific acceleration data in mG.
Polar Vantage V3 is a premium fitness and wellness watch. Store page
Polar Grit X2 Pro is a premium outdoor watch. Store page
- Heart rate as beats per minute.
- Heart rate broadcast.
- PP interval (milliseconds) representing cardiac pulse-to-pulse interval extracted from PPG signal.
- Accelerometer data with sample rate of 50 Hz and range of 8 G. Axis specific acceleration data in mG.
Fitness and wellness watch.
Pacer: Store page
Pacer Pro: Store page
- Heart rate as beats per minute.
- Heart rate broadcast.
- PP interval (milliseconds) representing cardiac pulse-to-pulse interval extracted from PPG signal.
PP interval is highly sensitive to movement and shall be used only at rest.
- Accelerometer data with sample rate of 50 Hz and range of 8 G. Axis specific acceleration data in mG.
- SDK mode from version 2.0 onwards.
- polar-sdk-ios contains source documentation for the iOS SDK source
- polar-sdk-android contains source documentation for the Android SDK source
- demos contains Android ecg demo application
- examples contains both android and ios example app utilizing most of the features from sdk
- documentation contains documentation related to SDK
Detailed documentation: Documentation
- In
build.gradle
make sure the minSdk is set to 24 or higher.
android {
...
defaultConfig {
...
minSdk 24
}
}
- Add the JitPack repository to your repositories settings
...
repositories {
...
maven { url 'https://jitpack.io' }
...
}
}
- Add the dependency to Polar BLE SDK library. Also you will need the dependencies to RxJava to use the Polar BLE SDK Library
dependencies {
implementation 'com.github.polarofficial:polar-ble-sdk:${sdk_version}'
implementation 'io.reactivex.rxjava3:rxjava:3.1.6'
implementation 'io.reactivex.rxjava3:rxandroid:3.0.2'
}
- Finally, to let the SDK use the bluetooth it needs Bluetooth related permissions. On your application
AndroidManifest.xml
following permissions need to be listed:
<!-- Polar SDK needs Bluetooth scan permission to search for BLE devices. Polar BLE SDK doesn't use the scan
to decide the location so "neverForLocation" permission flag can be used.-->
<uses-permission
android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation"
tools:targetApi="s" />
<!-- Polar SDK needs Bluetooth connect permission to connect for found BLE devices.-->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!-- Allows Polar SDK to connect to paired bluetooth devices. Legacy Bluetooth permission,
which is needed on devices with API 30 (Android Q) or older. -->
<uses-permission
android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />
<!-- Allows Polar SDK to discover and pair bluetooth devices. Legacy Bluetooth permission,
which is needed on devices with API 30 (Android Q) or older. -->
<uses-permission
android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30" />
<!-- Polar SDK needs the fine location permission to get results for Bluetooth scan. Request
fine location permission on devices with API 30 (Android Q). Note, if your application
needs location for other purposes than bluetooth then remove android:maxSdkVersion="30"-->
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION"
android:maxSdkVersion="30" />
<!-- The coarse location permission is needed, if fine location permission is requested. Request
coarse location permission on devices with API 30 (Android Q). Note, if your application
needs location for other purposes than bluetooth then remove android:maxSdkVersion="30" -->
<uses-permission
android:name="android.permission.ACCESS_COARSE_LOCATION"
android:maxSdkVersion="30" />
<!-- Allow Polar SDK to check and download firmware updates. -->
<uses-permission android:name="android.permission.INTERNET" />
On your application you must request for the permissions. Here is the example how could you request the needed permissions for the SDK:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
requestPermissions(arrayOf(Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT), PERMISSION_REQUEST_CODE)
} else {
requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), PERMISSION_REQUEST_CODE)
}
} else {
requestPermissions(arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION), PERMISSION_REQUEST_CODE)
}
See the example folder for the full project.
- Load the default api implementation and add callback.
// NOTICE in this code snippet all the features are enabled.
// You may enable only the features you are interested
val api: PolarBleApi = PolarBleApiDefaultImpl.defaultImplementation(applicationContext,
setOf(PolarBleApi.PolarBleSdkFeature.FEATURE_HR,
PolarBleApi.PolarBleSdkFeature.FEATURE_POLAR_SDK_MODE,
PolarBleApi.PolarBleSdkFeature.FEATURE_BATTERY_INFO,
PolarBleApi.PolarBleSdkFeature.FEATURE_POLAR_H10_EXERCISE_RECORDING,
PolarBleApi.PolarBleSdkFeature.FEATURE_POLAR_OFFLINE_RECORDING,
PolarBleApi.PolarBleSdkFeature.FEATURE_POLAR_ONLINE_STREAMING,
PolarBleApi.PolarBleSdkFeature.FEATURE_POLAR_DEVICE_TIME_SETUP,
PolarBleApi.PolarBleSdkFeature.FEATURE_DEVICE_INFO)
)
)
api.setApiCallback(object : PolarBleApiCallback() {
override fun blePowerStateChanged(powered: Boolean) {
Log.d("MyApp", "BLE power: $powered")
}
override fun deviceConnected(polarDeviceInfo: PolarDeviceInfo) {
Log.d("MyApp", "CONNECTED: ${polarDeviceInfo.deviceId}")
}
override fun deviceConnecting(polarDeviceInfo: PolarDeviceInfo) {
Log.d("MyApp", "CONNECTING: ${polarDeviceInfo.deviceId}")
}
override fun deviceDisconnected(polarDeviceInfo: PolarDeviceInfo) {
Log.d("MyApp", "DISCONNECTED: ${polarDeviceInfo.deviceId}")
}
override fun bleSdkFeatureReady(identifier: String, feature: PolarBleApi.PolarBleSdkFeature) {
Log.d(TAG, "Polar BLE SDK feature $feature is ready")
}
override fun disInformationReceived(identifier: String, uuid: UUID, value: String) {
Log.d("MyApp", "DIS INFO uuid: $uuid value: $value")
}
override fun batteryLevelReceived(identifier: String, level: Int) {
Log.d("MyApp", "BATTERY LEVEL: $level")
}
})
- Request permissions
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
requestPermissions(arrayOf(Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT), PERMISSION_REQUEST_CODE)
} else {
requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), PERMISSION_REQUEST_CODE)
}
} else {
requestPermissions(arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION), PERMISSION_REQUEST_CODE)
}
// callback is invoked after granted or denied permissions
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
}
- Cleanup functionality when desired, e.g.
public override fun onDestroy() {
super.onDestroy()
api.shutDown()
}
- Connect to a Polar device using
api.connectToDevice(<DEVICE_ID>)
where <DEVICE_ID> is the deviceID printed to your sensor, usingapi.autoConnectToDevice(-50, null, null).subscribe()
to connect nearby device orapi.searchForDevice()
to scan and then select the device
Detailed documentation: Documentation. Minimum iOS version is 14.
- Xcode 12.x
- Swift 5.x
- RxSwift 6.0 or above
- Swift Protobuf 1.18.0 or above
If you use CocoaPods to manage your dependencies, add PolarBleSdk to your Podfile
:
# Podfile
use_frameworks!
target 'YOUR_TARGET_NAME' do
pod 'PolarBleSdk', '~> 5.0'
end
Add PolarBleSdk as a dependency to your Package.swift
manifest
dependencies: [
.package(name: "PolarBleSdk", url: "https://github.com/polarofficial/polar-ble-sdk.git", .upToNextMajor(from: "5.0.0"))
]
or alternatively use XCode package manager to add Swift package to your project.
If you use Cathage to manage your dependencies, add PolarBleSdk to your Cartfile
github "polarofficial/polar-ble-sdk" ~> 5.0
$ carthage update --use-xcframeworks
- In your project target settings enable Background Modes, add Uses Bluetooth LE accessories
- In your project target property list add the key NSBluetoothAlwaysUsageDescription
See the example folder for the full project
deviceId
is your Polar device's id.
This is not required if you are using automatic connection.
- Import needed packages.
import PolarBleSdk
import RxSwift
- Load the default api implementation and implement desired protocols.
class MyController: UIViewController,
PolarBleApiObserver,
PolarBleApiPowerStateObserver,
PolarBleApiDeviceInfoObserver,
PolarBleApiDeviceFeaturesObserver,
PolarBleApiDeviceHrObserver {
// NOTICE only FEATURE_HR is enabled, to enable more features like battery info
// e.g. PolarBleApiDefaultImpl.polarImplementation(DispatchQueue.main, features: Features.hr.rawValue |
// Features.batteryStatus.rawValue)
// batteryLevelReceived callback is invoked after connection
var api = PolarBleApiDefaultImpl.polarImplementation(DispatchQueue.main, features: Features.hr.rawValue)
var deviceId = "0A3BA92B" // TODO replace this with your device id
override func viewDidLoad() {
super.viewDidLoad()
api.observer = self
api.deviceHrObserver = self
api.powerStateObserver = self
api.deviceFeaturesObserver = self
api.deviceInfoObserver = self
}
func deviceConnecting(_ polarDeviceInfo: PolarDeviceInfo) {
print("DEVICE CONNECTING: \(polarDeviceInfo)")
}
func deviceConnected(_ polarDeviceInfo: PolarDeviceInfo) {
print("DEVICE CONNECTED: \(polarDeviceInfo)")
}
func deviceDisconnected(_ polarDeviceInfo: PolarDeviceInfo) {
print("DISCONNECTED: \(polarDeviceInfo)")
}
func batteryLevelReceived(_ identifier: String, batteryLevel: UInt) {
print("battery level updated: \(batteryLevel)")
}
func disInformationReceived(_ identifier: String, uuid: CBUUID, value: String) {
print("dis info: \(uuid.uuidString) value: \(value)")
}
func hrValueReceived(_ identifier: String, data: PolarHrData) {
print("HR notification: \(data.hr) rrs: \(data.rrs)")
}
func hrFeatureReady(_ identifier: String) {
print("HR READY")
}
func ftpFeatureReady(_ identifier: String) {
print("FTP ready")
}
func streamingFeaturesReady(_ identifier: String, streamingFeatures: Set<DeviceStreamingFeature>) {
for feature in streamingFeatures {
print("Feature \(feature) is ready.")
}
}
func blePowerOn() {
print("BLE ON")
}
func blePowerOff() {
print("BLE OFF")
}
}
- Connect to a Polar device using
api.connectToDevice(id)
,api.startAutoConnectToDevice(_ rssi: Int, service: CBUUID?, polarDeviceType: String?)
to connect nearby device orapi.searchForDevice()
to scan and select the device
If you wish to collaborate with Polar commercially, click here
You may use, copy and modify the SDK as long as you include the original copyright and license notice in any copy of the software/source and you comply with the license terms. You are allowed to use the SDK for the development of software for your private as well as for commercial use for as long as you use the SDK in compliance with the license terms.
By exploiting the SDK, you indicate your acceptance of License.
Third-party code and licenses used in Polar BLE SDK see license listing ThirdPartySoftwareListing