Understanding the core of Aarogya Setu-Bluetooth

Niharika Arora
Jun 19, 2020 · 6 min read

Aarogya Setu is a mobile application developed by the Government of India to connect essential health services with the people of India in our combined fight against COVID-19. Do visit this link for more details.

AarogyaSetu started with an idea of automatic contact tracing. Proximity logging within an app addresses a key limitation of manual contact tracing: it is dependent on a person’s memory and is therefore limited to the contacts that a person is acquainted with and remembers having met.

For contact tracing, we had two options to go with: Bluetooth or GPS.

Bluetooth vs GPS:

Bluetooth was chosen because it is able to classify close contacts with a significantly lower false-positive rate than GPS. Given that GPS accuracy decreases in indoor environments, entire shopping malls or skyscrapers would be within the margin of error of a single GPS point.

So, with an idea that is more scalable, accurate and less resource-intensive, we created an app which:

  • Can help us in tracing the nearby contacts through Bluetooth.
  • Consumes low battery power.
  • Performs continuous.
  • Is compatible with both Android and iOS.


Permissions required:

"android.permission.BLUETOOTH","android.permission.BLUETOOTH_ADMIN", "android.permission.ACCESS_COARSE_LOCATION"

Note: Some of the devices (above 6.0) requires location permission to use Bluetooth. You can read more here.

BLE works with advertisement and scanning. The device in the central role scans, looking for advertisement, and the device in the peripheral role makes the advertisement.

Advertising Over BLE

Advertising Settings :

The AdvertiseSettings provide a way to adjust advertising preferences for each Bluetooth LE advertisement instance.

Advertising Data:

This is the data to be advertised as well as the scan response data for active scans.

  • setIncludeDeviceName: We are setting an 8 bytes(+2 bytes header) unique id as Bluetooth name for distinguishing a packet during the scan. So, we have made this flag true.
  • addServiceUuid: Setting a 16 bytes(+2 bytes header) UUID that is used for identifying our packets when they are advertised.

So now, we know how all 31 bytes are getting consumed. For more clarification on byte structure, please check this class.

GATT server:

Reason for implementing:

As per the iOS limitation, iOS is not able to scan if it goes in background. So, we found that making advertisement connectable through GATT can actually minimize this limitation by pinging the devices for connection and getting the unique id from there so that the app remains active and the connection breaks only if the device goes too far. Furthermore, you don't need to worry about multiple connections at the same time.GATT itself handles it for a good number of connections.

Scanning through BLE

Scan Filter:

  • setServiceUUID: We are filtering using the Service UUID which we sent in our advertisement packet.


  • setScanMode: We are setting the scan mode based on the number of unique scans/interval and changing it accordingly to provide lower power consumption. The scan mode can be one of ScanSettings#SCAN_MODE_LOW_POWER, ScanSettings#SCAN_MODE_BALANCED or ScanSettings#SCAN_MODE_LOW_LATENCY.
  • setMatchMode(Added in API level 23): We have set it MATCH_MODE_STICKY (For sticky mode, a higher threshold of signal strength and sightings is required before reporting by h/w)
  • setPhy(Added in API level 26): Setting the Physical Layer to use during this scan. This is used only if ScanSettings.Builder#setLegacy is set to false. To improve scan performance, we have used PHY_LE_1M channel for scanning. Read more about it here.


In onScanResult,

  • We get out scanResult from which we parse the device name, RSSI and txPower(Added in API 26).
  • Change the scan and advertisement mode for the device accordingly.
  • Store the scanResult in our local storage i.e database.

Also, we are checking the duplicacy of a scan record within a few seconds before we add it to our local storage.

Android 7.0 introduced a BLE scan timeout, where any scan running for 30 minutes or more is effectively stopped automatically and can only resume “opportunistically”. So we are starting the scan again after an interval.

Adaptive Scanning

App to scan continuously

Bluetooth Vulnerabilities

That’s all from my side for this article. :-)

Originally published here.

We have tried to make the most out of the Bluetooth and we are constantly improving.

Check out my talk on Understanding the BLE in integration in AarogyaSetu:

Here is the link for Slides:


You can find the source code here:

I request everyone to download the Aarogya Setu app and be part of this fight against the COVID-19 pandemic.

Thank You!!

Please feel free to share your views and feedback in the comments section below. You can also reach out to me on LinkedIn and Twitter.

मैं सुरक्षित, हम सुरक्षित, भारत सुरक्षित!


Aarogya Setu


Aarogya Setu is a Govt of India effort to build a holistic contact tracing application for the safety and timely help of Indian Citizens

Niharika Arora

Written by

Google Developer Expert for Android | Senior Android Engineer @ 1mg | Know more here: https://thedroidlady.com/


Aarogya Setu is a Govt of India effort to build a holistic contact tracing application for the safety and timely help of Indian Citizens