Heart rate monitoring via mobile app

NOVASOLUTIONS.TECHNOLOGY is engaged in the development, support and maintenance of iOS, Android, PWA mobile applications. We have extensive experience and expertise in publishing mobile applications in popular markets like Google Play, App Store, Amazon, AppGallery and others.
Development and support of all types of mobile applications:
Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1 servicesAll 1735 services
Heart rate monitoring via mobile app
Complex
~3-5 business days
FAQ
Our competencies:
Development stages
Latest works
  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1050
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    445

Heart Rate Monitoring Implementation via Mobile Application

Heart rate measurable three ways via phone: built-in camera (PPG via flash), Bluetooth GATT with external sensor (chest strap, smartwatch), or reading from platform storage (HealthKit, Health Connect — data from Apple Watch / Wear OS). Approach choice determines accuracy, latency and UX.

PPG via Camera: How it Works and Why Difficult

User places finger on camera with flash. Capillaries pulse — changes reflected red light. Analyze green channel (more hemoglobin sensitive) of each frame.

// iOS: AVCaptureVideoDataOutputSampleBufferDelegate
func captureOutput(_ output: AVCaptureOutput,
                   didOutput sampleBuffer: CMSampleBuffer,
                   from connection: AVCaptureConnection) {
    guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }

    CVPixelBufferLockBaseAddress(pixelBuffer, .readOnly)
    defer { CVPixelBufferUnlockBaseAddress(pixelBuffer, .readOnly) }

    let width = CVPixelBufferGetWidth(pixelBuffer)
    let height = CVPixelBufferGetHeight(pixelBuffer)
    let bytesPerRow = CVPixelBufferGetBytesPerRow(pixelBuffer)
    guard let buffer = CVPixelBufferGetBaseAddress(pixelBuffer) else { return }

    // Average green channel over center area
    var greenSum: Int64 = 0
    let startX = width / 3
    let startY = height / 3
    for y in startY..<(height * 2 / 3) {
        for x in startX..<(width * 2 / 3) {
            let pixel = buffer.advanced(by: y * bytesPerRow + x * 4)
            greenSum += Int64(pixel.load(fromByteOffset: 1, as: UInt8.self))
        }
    }
    let avgGreen = Double(greenSum) / Double((width / 3) * (height / 3))
    processPPGSample(avgGreen)
}

Then — FFT or Peak Detection on time series. At 30 fps, HR range 40–200 bpm → frequency 0.67–3.33 Hz. FFT on 5-second window (150 samples) gives sufficient resolution.

PPG problems:

  • Finger movement = artifacts 10× larger than pulse signal
  • Ambient light brightness affects baseline (needs normalization)
  • Accuracy ±5–10 bpm under ideal conditions, ±20+ on movement
  • iOS limits flash brightness — weak signal on some models

PPG suitable for "measure at rest, hold finger 30 seconds". For real-time monitoring during movement — need external sensor.

Bluetooth GATT: Heart Rate Profile

Standard BLE profile for pulse sensors (Polar H10, Wahoo TICKR, Garmin HRM):

  • Service UUID: 0x180D (Heart Rate)
  • Characteristic UUID: 0x2A37 (Heart Rate Measurement)

Data arrives via Notification. First byte — flags: bit 0 determines format (UINT8 or UINT16), bit 4 — RR-intervals presence.

override fun onCharacteristicChanged(
    gatt: BluetoothGatt,
    characteristic: BluetoothGattCharacteristic,
    value: ByteArray
) {
    val flag = value[0].toInt()
    val isUint16 = flag and 0x01 != 0
    val heartRate = if (isUint16) {
        ((value[2].toInt() and 0xFF) shl 8) or (value[1].toInt() and 0xFF)
    } else {
        value[1].toInt() and 0xFF
    }

    // RR-intervals (if present) — for HRV
    if (flag and 0x10 != 0) {
        var offset = if (flag and 0x08 != 0) 4 else 3 // skip energy if present
        while (offset + 1 < value.size) {
            val rrRaw = ((value[offset + 1].toInt() and 0xFF) shl 8) or (value[offset].toInt() and 0xFF)
            val rrMs = rrRaw * 1000 / 1024 // convert from 1/1024 s to milliseconds
            rrIntervals.add(rrMs)
            offset += 2
        }
    }
}

RR-intervals — basis for HRV (Heart Rate Variability) calculation. If product claims stress monitoring or recovery — can't do without RR.

Reading from HealthKit / Health Connect

For apps not doing direct measurement, only displaying:

iOS:

let query = HKAnchoredObjectQuery(
    type: HKQuantityType(.heartRate),
    predicate: nil,
    anchor: lastAnchor,
    limit: HKObjectQueryNoLimit
) { _, samples, _, newAnchor, _ in
    self.lastAnchor = newAnchor
    let bpmValues = (samples as? [HKQuantitySample])?.map {
        $0.quantity.doubleValue(for: HKUnit(from: "count/min"))
    } ?? []
}
healthStore.execute(query)

Data arrives with sources: Apple Watch Series 4+ gives heart rate every 5–15 minutes at rest, every second during workout.

Visualization

For realtime HR graph: ring buffer of last N values, update once per second. On iOS — Charts (DanielGindi) or Swift Charts (iOS 16+). On Android — MPAndroidChart or Compose Canvas with custom drawing.

Heart rate zones calculated from max heart rate (220 minus age or Karvonen formula with resting heart rate):

Zone % of Max Color
1 — recovery 50–60% Gray
2 — aerobic base 60–70% Blue
3 — aerobic 70–80% Green
4 — anaerobic threshold 80–90% Orange
5 — maximum 90–100% Red

Timeframes

PPG measurement via camera — 2–3 weeks (with algorithm part). Bluetooth GATT integration — 1–2 weeks. Reading from HealthKit/Health Connect with visualization — 5–8 days.