Skip to content

Quick Start Guide for Android

The quickest and simplest way to kickstart your journey with the Android SDK is by downloading and experimenting with our sample code. Additionally, you should follow this quick start guide to swiftly create your first vital sign app with Android.

After you've completed this guide, we strongly recommend you to follow our Software Development Guide to guarantee accurate and reliable health reports generated by the Vitals™ SDK.

SDK Installation

Please follow the instructions in the Downloads page to install and integrate the Android SDK into your project.

Camera Setup

As outlined in Integrating Vitals™ Health Assessment (VHA), the first step is setup the camera. To begin, create a new project and follow the instructions below.

Camera Permission

When developing for Android, you need to allow the app to use the camera by specifying the following in the file AndroidManifest.xml:

xml
<uses-permission android:name="android.permission.CAMERA" />

After that, request camera permission by using these code in MainActivity.kt:

kotlin

import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import android.content.pm.PackageManager
import android.util.Log
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import android.Manifest

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        // ...
        
        // Add this at the end of onCreate()
        requestCameraPermission()
    }

    companion object {
        private const val TAG = "MainActivity"
        private const val REQUEST_CAMERA_PERMISSION_CODE = 10
        private const val CAMERA_PERMISSION = Manifest.permission.CAMERA
    }

    private fun requestCameraPermission() {
        val requestPermissionLauncher =
            registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted: Boolean ->
                if (isGranted) {
                    setupCamera()
                } else {
                    Log.d(TAG, "No camera permission.") // TODO: Handle error yourself
                }
            }

        when (PackageManager.PERMISSION_GRANTED) {
            ContextCompat.checkSelfPermission(this, CAMERA_PERMISSION) -> {
                setupCamera()
            }

            else -> {
                requestPermissionLauncher.launch(CAMERA_PERMISSION)
            }
        }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        when (requestCode) {
            REQUEST_CAMERA_PERMISSION_CODE -> {
                if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                    setupCamera()
                } else {
                    Log.d(TAG, "No camera permission.")
                }
                return
            }

            else -> {} // Ignore all other requests.
        }
    }

    private fun setupCamera() {
        // TODO: Will set this up in the next section.
    }
}

Vital Sign Camera

As described in Vital Sign Camera, in Vitals™ SDK, we provide a tailor-made camera component, named VitalSignCamera. To setup the VitalSignCamera, first, in your XML layout file activity_main.xml, add a FrameLayout for the camera preview.

xml
<FrameLayout
    android:id="@+id/vital_sign_camera"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Next, in MainActivity.kt, declare the VitalSignCamera property:

kotlin
private lateinit var camera: VitalSignCamera

Implement the VitalSignCameraEventHandler interface for accessing processing results such as face detected, the Conditions Check results, the scanning stage and remaining seconds, the health report, etc.

kotlin
class MainActivity : AppCompatActivity(), VitalSignCameraEventHandler {
    override fun onVideoFrameProcessed(result: ProcessFrameResult) {
        // TODO: Will implement this callback in later sections.
    }
}

Within the setupCamera function declared in the above "Camera Permission" section, create the VitalSignCamera using the method createVitalSignCamera, followed by calling configure to configure the camera. Lastly, bind the VitalSignCamera to the FrameLayout. For example:

kotlin
private fun setupCamera() {
    // Create the vital sign camera
    camera = createVitalSignCamera(this, lifecycle, this)

    // Configure the camera properties and the Vitals™ Cloud Service.
    camera.configure {
        isActive = true

        config = VitalSignEngineConfig().apply {
            serverId = ServerId.awsEnterpriseProd
            apiKey = "__YOUR_API_KEY__"
        }
    }

    // Bind camera to the FrameLayout
    findViewById<FrameLayout>(R.id.vital_sign_camera).addView(camera)
}

TIP

In the above example, the string __YOUR_API_KEY__ should be replaced by your own API Key. Please contact us to obtain your API Key, which is the credential for accessing the Vitals™ Cloud Service.

Run the app, you should be able to see the camera preview now. For more details on system and camera setup, please refer to Camera Setup.

Acquire Health Profile

As outlined in Integrating Vitals™ Health Assessment (VHA), user data and medical history data have to be gathered to obtain personalized health insights and enhance the accuracies of measurements.

You can provide the user information gathered by supplying them to the userInfo property in the camera.configure block. For example:

kotlin
private fun setupCamera() {
    // ...

    // Provide the user info to Vitals™ SDK
    camera.configure {
        // ...

        userInfo = UserInfo().apply {
            age = 25.0
            gender = Gender.Male
            userId = "__YOUR_USER_ID__"
        }
    }

    // ...
}

TIP

In the above example, the string __YOUR_USER_ID__ should be replaced by your own User ID. Please contact us to obtain your User ID, which specifies the subscription plan for the Vitals™ Cloud Service. The set of vital signs obtained from a scan varies depending on the licensed subscription plan, with each plan offering a unique set of vital signs.

For more details, please refer to the Acquire Health Profile page.

Scan Vital Signs

To start a scan, you can simply call the startScanning() API of the VitalSignCamera component.

First, create a start button in your XML layout file to initiate a scan.

xml
<Button
    android:id="@+id/start_button"
    android:layout_width="250dp"
    android:layout_height="50dp"
    android:text="Start Scanning" />

Setup the onClick listener, and call the startScanning() API.

kotlin
override fun onCreate(savedInstanceState: Bundle?) {
    // ...
    findViewById<Button>(R.id.start_button).setOnClickListener { 
        camera.startScanning() 
    }
}

After calling the API, the component will start scanning the face from the camera for about 30 seconds. And vital signs will be returned upon successful scan. You can log the scanning progress and observe any error by updating the onVideoFrameProcessed callback. This callback function delivers processing results at a rate of 30Hz per second (The rate depends on the frame rate of the camera).

kotlin
override fun onVideoFrameProcessed(result: ProcessFrameResult) {
    // Print the scanning stage & remaining seconds if the scan is in progress.
    if (result.healthResult.stage != GetHealthStage.idle) {
        Log.d(TAG, "Scanning Stage=${result.healthResult.stage}, Remaining Seconds=${result.healthResult.remainingTime}")
    }

    // Print error if any
    if (result.healthResult.error != null) {
        Log.d(TAG, "Error=${result.healthResult.error}")
    }
}

Run the app, with your face centered in the camera frame, click the "Start Scanning" button. Move your face out of the camera frame to simulate a "face lost" error. You should see something similar to this in your Logcat:

2025-01-10 10:50:12.144 17560-17773 MainActivity            ai.panoptic.wvs.androidsdksampleapp   D  Scanning Stage=collectingData, Remaining Seconds=22.919
2025-01-10 10:50:12.180 17560-17773 MainActivity            ai.panoptic.wvs.androidsdksampleapp   D  Scanning Stage=collectingData, Remaining Seconds=22.882
2025-01-10 10:50:12.251 17560-17773 MainActivity            ai.panoptic.wvs.androidsdksampleapp   D  Error=ai.panoptic.wvs.engine.VSException: face lost
2025-01-10 10:50:12.315 17560-17773 MainActivity            ai.panoptic.wvs.androidsdksampleapp   D  Error=ai.panoptic.wvs.engine.VSException: face lost

For more details on handling the scanning process, please refer to the Scan Vital Signs page.

Get & Display Health Results

The VitalSignCamera component returns the health results by the onVideoFrameProcessed callback function. In the example code below, it checks if the heart rate is ready, and display it in the Logcat if it is ready.

kotlin
// Update the onVideoFrameProcessed callback function
override fun onVideoFrameProcessed(result: ProcessFrameResult) {
    // ...

    // Obtain the heart rate result
    if (result.healthResult.health != null) {
        Log.d(TAG, "Heart Rate=${result.healthResult.health?.vitalSigns?.heartRate}")
    }
}

Run the app and perform the scan, after 30 seconds, you will be able to see the heart rate result like this:

2025-01-10 11:02:44.352 20011-20351 MainActivity            ai.panoptic.wvs.androidsdksampleapp   D  Scanning Stage=analyzingData, Remaining Seconds=0.099999905
2025-01-10 11:02:44.502 20011-20351 MainActivity            ai.panoptic.wvs.androidsdksampleapp   D  Scanning Stage=analyzingData, Remaining Seconds=0.06799984
2025-01-10 11:02:44.502 20011-20351 MainActivity            ai.panoptic.wvs.androidsdksampleapp   D  Heart Rate=81.22924984224709
2025-01-10 11:02:44.646 20011-20351 MainActivity            ai.panoptic.wvs.androidsdksampleapp   D  Heart Rate=81.22924984224709

There are more vital signs available in the Vitals™ SDK and we also provide health result interpretation guides. For more information, please refer to the Get & Display Health Result page.


🎉🎉🎉 Congratulations! 🎉🎉🎉

You have completed your first Vitals™ application!


WARNING

This guide only provides you the minimum viable product (MVP) using our Android SDK, there are still more features and more things to do to ensure an accurate and reliable measurements by our Vitals™ Cloud Service. For example: performing Conditions Check, using the Signal Quality metric, and more. Please refer to the Software Development Guide page, the sample code, or the API reference for further details.