Hello Health Data

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

Importing Library

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

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

Health Data Service Initialization

The health data service can be initialized with:

  • HealthDataService.initialize()

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));
        HealthDataService healthDataService = new HealthDataService();
        try {
            healthDataService.initialize(this);
        } catch (Exception e) {
            e.printStackTrace();
        }
Health Data Store Connection

If the health data service initialization succeeds, connect to the health data store with HealthDataStore.

// 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 is 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 in 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 required data permission value in manifest works with the permission request API. If you want to request data permission for reading step count, write its value in your application project’s manifest as the following example.

The declared data permission in manifest is checked when Samsung Health is initialized. 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 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));
        HealthDataService healthDataService = new HealthDataService();

        // initialize and 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.

Figure 11: Permission UI for reading step count

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.