Android Studio: Easiest Way to get Access to Health Sensors/Data?

For my masters thesis I’m currently trying to develop a wearable App with Android Studio for my Samsung Galaxy Watch 4 Classic. With this App I want to simply display a few Vitalparameters like heartrate, stressvalue, breathe frequency etc. (the more, the better)

Therefore I’ve already tried several ways to get access to the heartrate at first.

With

<uses-permission android:name="com.samsung.android.health.permission.read" />
<uses-permission android:name="android.permission.BODY_SENSORS" />
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

in my manifest, I initialized the permission for it.

package com.example.test;

import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;

import com.example.test.databinding.ActivityVitalsBinding;
import com.samsung.android.sdk.healthdata.HealthDataStore;
import com.samsung.android.sdk.healthdata.HealthConstants;
import com.samsung.android.sdk.healthdata.HealthDataResolver;
import com.samsung.android.sdk.healthdata.HealthDataResolver.Filter;
import com.samsung.android.sdk.healthdata.HealthPermissionManager;
import com.samsung.android.sdk.healthdata.HealthResultHolder;
import com.samsung.android.sdk.healthdata.HealthResultHolder.ResultListener;

import java.util.Arrays;
import java.util.HashSet;


public class VitalsActivity extends Activity {

    private HealthDataStore healthDataStore;
    private ActivityVitalsBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = ActivityVitalsBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

       healthDataStore = new HealthDataStore(this, new HealthDataStore.ConnectionListener() {
        @Override
        public void onConnected() {
            System.out.println("Connected successfully");
        }

        @Override
        public void onConnectionFailed(HealthConnectionErrorResult healthConnectionErrorResult) {
            System.out.println("couldn't connect");
        }

        @Override
        public void onDisconnected() {

        }
    });
    healthDataStore.connectService();
    }

private void requestHeartRatePermission() {
    HealthPermissionManager.PermissionKey key =
            new HealthPermissionManager.PermissionKey(HealthConstants.HeartRate.HEALTH_DATA_TYPE, HealthPermissionManager.PermissionType.READ);

    HealthPermissionManager permissionManager = new HealthPermissionManager(healthDataStore);

    permissionManager.requestPermissions(new HashSet<HealthPermissionManager.PermissionKey>(Arrays.asList(key)))
            .setResultListener(new ResultListener<HealthPermissionManager.PermissionResult>() {
                @Override
                public void onResult(HealthPermissionManager.PermissionResult result) {
                    if (result.equals(true)) {
                        readHeartRateData();
                    } else {
                        System.out.println("access denied");
                    }
                }
            });
}

private void readHeartRateData() {
    HealthDataResolver resolver = new HealthDataResolver(healthDataStore, null);

    HealthDataResolver.ReadRequest request = new HealthDataResolver.ReadRequest.Builder()
            .setDataType(HealthConstants.HeartRate.HEALTH_DATA_TYPE)
            .build();

    resolver.read(request)
            .setResultListener(result -> {
                try (Cursor cursor = result.getResultCursor()) {
                    if (cursor != null && cursor.moveToFirst()) {
                        int heartRateIndex = cursor.getColumnIndex(HealthConstants.HeartRate.HEART_RATE);
                        if (heartRateIndex != -1) {
                            int heartRate = cursor.getInt(heartRateIndex);
                            System.out.println("current heartrate: " + heartRate);
                        } else {
                            System.out.println("couldn't find heartrate-column");
                        }
                    }
                } catch (Exception e) {
                    System.out.println("error while reading heartrate-data");
                }
            });
}

and that’s how I solved it. But it isn’t working at all.
I get the error:

E/HealthDataStore: disconnectService: Context instance is invalid
D/HealthDataStore: Trying to connect with Health Service fails (error code: 2)
D/HealthDataStore: Check SupportedDevice
D/HealthSDK-DeviceUtil: Server URL : https://hub.samsungapps.com/product/appCheck.as?appInfo=com.sec.android.app.shealth@0&deviceId=sdk_gwear_x86&mnc=260&csc=FAIL&openApi=30&mcc=310
D/HealthSDK-DeviceUtil: Downloading Samsung Health is unavailable (0)

so I’m currently looking for another way to get easy access to the needed values.
Can you help me out here?

If possible:
Since the App shall be useable without Smartphones, the solution also should be independent from any Smartphone. But if this is not possible, I’m also thankful for any other solution :).

Thanks in advance!

Samsung Health does not share much information in Wear3 but I’m told it will share more in the upcoming Wear4 One UI 5

On the Wear OS Based devices you need to use Health Services and Health Connect. (And Samsung Health settings must allow sharing data to Health Services)
See More in the Android Documentation

Ron
Samsung Developer Relations

Thank you for answering! I saw the Health Service-Examples but sadly they’re just in Kotlin. Is there a Java-Example as well?

Also and the most important question:
Is it possible to get the Vitals like Heartrate etc. without creating a Companion App since I only want to have a Wearable-App without a Smartphone-App?

Johannes

I forgot to mention that if you are in the US and maybe Europe now you can apply for Privileged Health Partnership and get access to most or all the data you wanted.

You don’t need a companion app you can store data on the device or even a web site.

Ron
Samsung Developer Relations

what data or sensors can I access if I am a partner?
I hope I have as detailed a response as possible because I am learning to develop an app

You don’t need to be a partners to access Sensors Data, you only need that to access Samsung Health App (Generally the partners are corporations that either make equipment like smart scales or Health and Fitness organizations)

You should see Android developer documentation for
Wear Health Services
Health Connect
Health Platform API

There are also some very useful code labs in the Android Documentation that you will find useful for a beginner and Samsung has some blogs that can help as well maybe for more experienced developers looking to use the health sensors

Android and Wear OS is generally developed in Kotlin

Ron
Samsung Developer Relations

1 Like

Currently, I can get sensor data by using SensorManager. However, some special sensors such as body temperature, blood pressure,… I can’t get them.

As per the documentation you provided. I see that Health Platform API is deprecated. And I have the following questions:

  1. Is there any way I can get data from special sensors like body temperature, blood pressure,…?
  2. Do I need to use Health Services and Health Connect to get special data?
  3. When using Health Services and Health Connect to get special data, do I need to be a partner?
  4. What data can I obtain when using Health Services and Health Connect? (I hope you can list specific data because I want to use that data to come up with new ideas for developing wearOS apps)

As per the documentation you provided. I see that Health Platform API is deprecated. And I have the following questions:

The Samsung Android Health Platform API was for Tizen based watches and Samsung has moved to Wear OS. It has no relevance to Watch4 Watch5 and newer. The Android Health Connect should be used for Wear API 3.0 and Wear API 3.3 (wear 4) as it unifies both Google Health and Samsung Health.

  1. Is there any way I can get data from special sensors like body temperature, blood pressure,…?

There is no way to get blood pressure.

Health Connect has several body temperature classes

  1. Do I need to use Health Services and Health Connect to get special data?

You can get some data other data you need to have your own algorithm

  1. When using Health Services and Health Connect to get special data, do I need to be a partner?

Note: If your app integrates with Health Connect, before going to production, you need to complete a form explaining what data types your app reads or writes, and how this data is used. For more information, see How do I request access to read or write data types?.

  1. What data can I obtain when using Health Services and Health Connect? (I hope you can list specific data because I want to use that data to come up with new ideas for developing wearOS apps)

see This page

This really needs to be on a Android Developer Discussion board but look at the Samsung Blogs and code labs as well as the Androidx Documentation

Ron
Samsung Developer Relations