BLE Cardiac Monitor

This application connects to a Bluetooth Low Energy (BLE) heart monitor and displays the data in real time and also stores the data in a SQLite database for later retrieval. It requires a BLE monitor, not a classic Bluetooth heart monitor, and BLE requires Android 4.3.1 (API 18, Jellybean). BLE aims to keeps the data transfer low by transmitting as little data as possible and as infrequently as possible, which in turn keeps the battery drain low. This is perfectly fine for the information from a heart monitor, where the information is produced on the order of once per second, but would not be adequate for, say, streaming music or for streaming a complete electrocardiogram (ECG).

As of Android 6.0 (API 23, Marshmallow) Android requires Location permission to scan for Bluetooth devices, and if not granted, it will find no devices, even if it appears to work. If the permission is not granted, BLE Cardiac Monitor will prompt you to allow this permission once when it starts, and then will show a notice each time you try to scan for devices. If you also check "Don't ask again", there will be no prompt, just the notice. You can always change the permission for the BLE Explorer app manually in Settings.

Most BLE heart monitors implement the standard BLE Heart Rate Profile, which includes both the heart rate (HR) and the RR interval (RR or R-R). The R-R interval is the time between the sharp peaks in an ECG. (The various peaks or waves in an ECG are labeled P, Q, R, S, T, U, V, etc. The sharp, high value is the R peak, and is the easiest to detect.) If the HR is 60 beats per min, then the R-R interval averages 1 sec or 1000 ms. However, it varies from beat to beat, often in a regular pattern, and in the case of arrhythmia's can be irregular. There is, in fact, a whole science of heart rate variability (HRV). Check out Wikipedia, for example. The R-R values give you much more information than the HR. Most BLE heart monitor sports apps only monitor the HR. This one allows you to monitor both.

The database is kept on the internal SD card in a directory named BLE Cardiac Monitor, where it is visible to the user. Sessions can also be saved to there as comma-separated-value (CSV) files, and the database can also be saved to and restored from CSV files, which are also located there. You can back everything up by copying this directory to a safe place. There are also SQLite database managers on most platforms, so you can access the database away from your device as well and do your own things with the data, either from the database or the CSV files.

The interface consists of five screens:

BLE Cardiac Monitor Main Screen

This is the main screen. It shows the device name, address, state, battery level, current heart rate and R-R value, and status messages (when they are available). It has the following menu items.


Brings up the Plot screen.

Connect or Disconnect

If there is a valid device, you can connect or disconnect it via this item. The data collection is run via an Android service. When the service is running, there should be a notification icon in the title bar, whether the app interface is showing or not. In normal circumstances, the service runs in the background whenever the app has been started and not exited via the Back button.

The app collects data and adds to the database only when connected. If the device is connected when you exit the app, it will try to reconnect again when you restart. If it was disconnected manually via this item, then it will not automatically try to reconnect on a restart. Use this feature to avoid collecting data when you do not want to, for example, while you are examining sessions.

Session Manager

Brings up the Session Manager with a list of sessions in the database and allows you to do things with them.

Select Device

Brings up the BLE Device Scan screen, where you can search for and select a heart monitor device.

Get Battery Level

The app attempts to get the battery level when it connects, but doesn't automatically update it. Sometimes the level is not available then. Use this item to force an update.


Brings up this page.


Brings up the Settings screen.

BLE Device Scan

This screen scans for BLE devices and displays a list of the ones found. You click on one to select it. The app remembers the last device, whether connected or not, so you may not need this screen often. It has the following menu items.

Scan or Stop

Starts or stops the scan. The scan lasts for 10 sec if not stopped manually.


The Session Manager is where you manage the sessions. You can plot them and delete or save them in several ways.

A session consists of data entries with the same start time. A session starts and the start time is set when the Start item on the main screen is selected or automatically on a restart when the Stop button had not been pressed before the last exit via the Back button. It ends when the Stop item is selected, the app exits via the Back button, or something external happens (losing the connection, for example) that causes it to stop.

The session manager shows a list of the sessions with a checkbox before each item. The start time and duration are shown as well. Tapping an item in the list toggles the checked state. Multiple items can be selected, but some menu items, such as Plot, require that one and only one be selected. Most menu items operate only on the checked sessions. Saving and restoring the database ignore any check marks.

Note that typically the data are sent from the monitor device about once a second. There is one HR value and there may be anywhere from none to several RR values in this interval, depending on the heart rate (a faster rate means more RR values). The RR values do not have a timestamp other than the one for the entire data packet. Therefore, determining the time at which the R peaks occurred is subject to some error. This is a limitation of the BLE specification, not the app. The intervals and the time of the packet should be accurate. The app makes intelligent guesses to keep the RR intervals in a packet correct and the intervals between packets reasonable.

These are the menu items.


Plots the checked session. Only one can be checked for this option. If this session is still in progress, the plot will not update with any newer values. It will, however, show all the current values, and hence may be for a longer period than the duration shown, which was calculated when the list was created.


Refreshes the list. Check boxes will be cleared. If a session is still in progress, the duration of that session should change.


Deletes the checked sessions. This action can not be undone.

Save Sessions

Save the checked session as separate CSV files. The name is of the form BCM-yyyy-MM-dd-HH-mm-ss.csv, and the values correspond to the start time. The delimiter is a comma. The values are a timestamp, the HR value, and a space-separated list of RR values. The RR values are integers in units of 1/1024 sec, which is the raw data from the device.

Save as Combined Session

This is the same as Save Sessions except that all sessions are saved in a single file with a name of the form BCM-yyyy-MM-dd-HH-mm-ss-Combined.csv, and the values correspond to the start time. There is a blank line between sessions.

Save Sessions As GPX

Save the checked session as separate GPX files. The name is of the form BCM-yyyy-MM-dd-HH-mm-ss.gpx, and the values correspond to the start time. The session is saved as a track. All the trackpoints have latitude, longitude, and elevation equal to 0. The HR is in a Garmin TrackPointExtension. Applications that read GPX files with HR should be able to read the HR values as a function of time.

Check All

A convenience method to check all sessions.

Check None

A convenience method to uncheck all sessions.

Save Database

This is similar to saving a session except that all the data in the database are saved. It ignores any check marks. The name is of the form BCMDatabase-yyyy-mm-dd-hh-mm-ss.csv, and the values correspond to the time the file was created. The delimiter is a comma. The values are the time, the start time, the HR value, and a space-separated list of RR values. The times are an integer representing the time as the Java Date class stores it. The RR values are integers in units of 1/1024 sec, which is the raw data from the device.

Restore Database

The database can be restored from one of the files created by Save Database. You will be given a list of available saved database files in the app's data directory. This operation will cause all the current data in the database to be lost.

HR and RR Plot

Plotting is available in two ways. From the Main Screen, Plot gives an updating plot of values in real time as they are accumulated. All values for the last n seconds are shown. The plot interval, n, can be set in Settings. From the Session Manager, Plot gives a plot of the values of the checked session at the time Plot was selected. If a session is still in progress, later values will not be seen in this case.

The plot can be zoomed using the usual two-finger gesture and panned with one finger. A double-click will restore it. The plot auto-scales to fit the data. If there are a lot of data, it make take a while for these operations to happen.

There are two menu items.


Recalculates the data in the plot and restores any zooming or panning.

View Info

Displays some information about the plot and the screen. This is primarily for debugging purposes.


The Settings screen allows you to set if HR and/or RR axes are shown or not. You can also set the time interval for real-time plots. These settings are saved between sessions.


The plotting uses AndroidPlot.