Hello Health Data

The following sections give you fundamentals for developing the Samsung Health's partner app. Check first the development environment for Samsung Health's partner apps.

Importing Library

Add the following library to the “libs” folder in your created application project.

  • samsung-health-data-a.b.c.aar

Health Data Store Connection

Add a <queries> element in your app manifest.

<manifest . . . >
    <queries>
        <package android:name="com.sec.android.app.shealth" />
    </queries> 
</manifest>

Connect to the health data store with HealthDataStore.

public class MainActivity extends Activity {

            public static final String APP_TAG = "SimpleHealth";
        
            private static MainActivity mInstance = null;
            private HealthDataStore mStore;
            private HealthConnectionErrorResult mConnError;
            private Set<PermissionKey> mKeySet;
        
            @Override
            public void onCreate(Bundle savedInstanceState) {
                // ...
        
                mInstance = this;
                mKeySet = new HashSet<PermissionKey>();
                mKeySet.add(new PermissionKey(HealthConstants.StepCount.HEALTH_DATA_TYPE, PermissionType.READ));
                // Create a HealthDataStore instance and set its listener
                mStore = new HealthDataStore(this, mConnectionListener);
                // Request the connection to the health data store
                mStore.connectService();
            }

You can end the health data store connection when the activity is destroyed.

@Override
            public void onDestroy() {
                mStore.disconnectService();
                super.onDestroy();
            }

The connection result is sent to HealthDataStore.ConnectionListener. If it succeeds, acquiring data permission or querying data will be available.

private final HealthDataStore.ConnectionListener mConnectionListener = new HealthDataStore.ConnectionListener() {

            @Override
            public void onConnected() {
                Log.d(APP_TAG, "Health data service is connected.");
                HealthPermissionManager pmsManager = new HealthPermissionManager(mStore);
    
                try {
                    // Check whether the permissions that this application needs are acquired
                    // Request the permission for reading step counts if it is not acquired
    
                    // Get the current step count and display it if data permission is required
                    // ...
                } catch (Exception e) {
                    Log.e(APP_TAG, e.getClass().getName() + " - " + e.getMessage());
                    Log.e(APP_TAG, "Permission setting fails.");
                }
            }
    
            @Override
            public void onConnectionFailed(HealthConnectionErrorResult error) {
                Log.d(APP_TAG, "Health data service is not available.");
                showConnectionFailureDialog(error);
            }
    
            @Override
            public void onDisconnected() {
                Log.d(APP_TAG, "Health data service is disconnected.");
            }
        };

The connection to the health data store can fail and you can check its error result through onConnectionFailed(). If there is an error, an application checks whether the health framework provides a solution with hasResolution() and calls resolve().

If the health framework provides its solution, resolve() makes an application move to one of the following page without a dialog message:

  • App market's Samsung Health page to install or update it

  • Device's Settings page to make Samsung Health available

  • Samsung Health user's agreement page

An application needs to show a proper message for each error case and call resolve().

private void showConnectionFailureDialog(HealthConnectionErrorResult error) {
        
                AlertDialog.Builder alert = new AlertDialog.Builder(this);
                mConnError = error;
                String message = "Connection with Samsung Health is not available";
        
                if (mConnError.hasResolution()) {
                    switch(error.getErrorCode()) {
                    case HealthConnectionErrorResult.PLATFORM_NOT_INSTALLED:
                        message = "Please install Samsung Health";
                        break;
                    case HealthConnectionErrorResult.OLD_VERSION_PLATFORM:
                        message = "Please upgrade Samsung Health";
                        break;
                    case HealthConnectionErrorResult.PLATFORM_DISABLED:
                        message = "Please enable Samsung Health";
                        break;
                    case HealthConnectionErrorResult.USER_AGREEMENT_NEEDED:
                        message = "Please agree with Samsung Health policy";
                        break;
                    default:
                        message = "Please make Samsung Health available";
                        break;
                    }
                }
        
                alert.setMessage(message);
        
                alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        if (mConnError.hasResolution()) {
                            mConnError.resolve(mInstance);
                        }
                    }
                });
        
                if (error.hasResolution()) {
                    alert.setNegativeButton("Cancel", null);
                }
        
                alert.show();
            }

See the health data store for more information.

Permission Request

The meta-data element for the required data permission value in manifest works with the permission request API. If you want to request data permission for reading the step count, write its value in your application project's manifest as the following example.

See privacy check flow in privacy.

<application
        
            <meta-data
                android:name="com.samsung.android.health.permission.read"
                android:value="com.samsung.health.step_count" />
        
        </application>

Create a permission key set and add a permission key for reading the step count.

public class MainActivity extends Activity {
        
            private Set<PermissionKey> mKeySet;
        
            @Override
            public void onCreate(Bundle savedInstanceState) {
                // ...
        
                mKeySet = new HashSet<PermissionKey>();
                mKeySet.add(new PermissionKey(HealthConstants.StepCount.HEALTH_DATA_TYPE, PermissionType.READ));
        
                // connect to health data store
            }

And call HealthPermissionManager.requestPermissions() with its listener.

private final HealthDataStore.ConnectionListener mConnectionListener = new HealthDataStore.ConnectionListener() {
        
                @Override
                public void onConnected() {
                    Log.d(APP_TAG, "Health data service is connected.");
                    HealthPermissionManager pmsManager = new HealthPermissionManager(mStore);
        
                    try {
                        // Check whether the permissions that this application needs are acquired
                        Map<PermissionKey, Boolean> resultMap = pmsManager.isPermissionAcquired(mKeySet);
        
                        if (resultMap.containsValue(Boolean.FALSE)) {
                            // Request the permission for reading step counts if it is not acquired
                            pmsManager.requestPermissions(mKeySet, MainActivity.this).setResultListener(mPermissionListener);
                        } else {
                            // Get the current step count and display it
                            // ...
                        }
                    } catch (Exception e) {
                        Log.e(APP_TAG, e.getClass().getName() + " - " + e.getMessage());
                        Log.e(APP_TAG, "Permission setting fails.");
                    }
                }
                // ...
            };

If requestPermissions() is called successfully, the permission UI is popped up to the user.

The user's permission information is saved by selecting "DONE" after the user allows each data permission. And it is received through HealthResultHolder.ResultListener.

private final HealthResultHolder.ResultListener<PermissionResult> mPermissionListener =
                new HealthResultHolder.ResultListener<PermissionResult>() {
        
                @Override
                public void onResult(PermissionResult result) {
                    Log.d(APP_TAG, "Permission callback is received.");
                    Map<PermissionKey, Boolean> resultMap = result.getResultMap();
        
                    if (resultMap.containsValue(Boolean.FALSE)) {
                        // Requesting permission fails
                    } else {
                        // Get the current step count and display it
                    }
                }
            };
        }

See the health permission manager for more information.