Wednesday, December 14, 2022
HomeProgrammingWell being Join Android API | Kodeco, the brand new raywenderlich.com

Well being Join Android API | Kodeco, the brand new raywenderlich.com


Learn to use the Well being Join Android API to create an app that reads and writes well being knowledge and manages well being permissions.

Well being Join is an Android API and Platform. For builders, it supplies a single interface for dealing with customers’ well being knowledge. For customers, it’s a central place to get an outline of well being knowledge and permissions granted to different apps.

On this tutorial, you’ll find out about Well being Join by making a pattern app — fitLogger. In doing so, you’ll study the next within the context of the Well being Join Android API:

  • Dealing with permissions
  • Writing knowledge
  • Studying knowledge

Getting Began

Organising an Emulator to Check the Well being Join API

Except you’re utilizing an actual system to construct and run this app, you’ll want an emulator with Play Retailer assist. To create an emulator, go to Instruments ▸ Machine Supervisor and click on Create system. From the listing of units, select a tool with an icon within the Play Retailer column.

A screenshot of AVD Manager

Throughout the subsequent steps choose a system picture, select an AVD title and click on End.

Downloading and Exploring the Starter Mission

Use the Obtain Supplies button on the prime or backside of this tutorial to obtain the starter venture. Open the venture in Android Studio Bumblebee (2021.1.1) or later. Go to Run ▸ Run ´app´.

A screenshot of the fitLogger sample application for Android Health Connect

To maintain the concentrate on Well being Join, the required format for this tutorial is created within the activity_main.xml file. You’ll join this format with the precise performance to learn and write the well being knowledge.

Introducing Well being Join

Many well being and health apps run on Android. Google Match is an identical app made by Google. These apps can acquire numerous knowledge and deal with permissions. Customers can use one app to retailer well being info and one other for health monitoring. With knowledge unfold amongst a number of apps, customers should go into many apps to get an outline. Additionally, privateness could be a fear when knowledge is on a number of apps.

Well being Join is an API and a platform. As an API, it helps builders use a single interface. As a platform, it helps customers have an outline of the whole lot in a single place.

A diagram showing how Android Health Connect works as both a platform and an API

Well being Join supplies the next options to builders and customers:

Privateness Controls

Android OS ensures shopper apps request permissions earlier than accessing knowledge or {hardware} on the system. Well being Join supplies built-in permission controls. Builders request permissions by way of the API, and customers can see the Well being Join app to evaluation permission requests and grant or deny permissions.

Customers can use the Well being Join app to find out which apps have permission to entry well being knowledge. If wanted, they will revoke these permissions by way of the app. Well being Join ensures that shopper apps can solely learn knowledge when the app is working within the foreground.

Storage

Well being Join supplies on-device storage, so all the info is in a central place. As a developer, it can save you the info utilizing the API and retrieve the info saved by one other app.

A person can use the platform to get an outline of well being and health knowledge. The platform may delete knowledge.

Knowledge Varieties

Well being Join presents an intensive vary of knowledge varieties to let customers observe sorts of health- and fitness-related knowledge. Varied apps can contribute or devour knowledge within the Android ecosystem by having unified knowledge varieties.

Key knowledge classes:

  • Exercise: This captures any exercise by a person, together with working, swimming, sleeping and meditation.
  • Physique Measurement: That is widespread knowledge associated to the physique, together with peak, weight and BMR (Basal Metabolic Fee).
  • Cycle Monitoring: Knowledge recorded right here embrace menstrual cycles and different associated knowledge factors.
  • Diet: Hydration and diet knowledge varieties, together with water, energy, sugar and magnesium.
  • Sleep: Interval knowledge associated to a person’s size and kind of sleep.
  • Vitals: Important details about the person’s basic well being, together with blood glucose, physique temperature and blood oxygen saturation is recorded beneath this class.

Well being Join APK

The Well being Join APK must be accessible on the shopper’s system. It accommodates the Permissions Administration and Knowledge Administration elements. It’s going to deal with requests despatched by any utility utilizing the Well being Join SDK.

Open the Play Retailer in your system or emulator. Should you’re utilizing a brand new emulator, signal into your Google account. Then, seek for Well being Join by Android and set up the app.

An animation showing how to install Android Health Connect application from the Google Play Store

Dealing with Dependencies

Now that you’ve an outline of Well being Join, it’s coding time!

Add the next dependency on the backside of the module’s construct.gradle file:


implementation 'androidx.well being:health-connect-client:1.0.0-alpha03'

By together with this SDK in your utility, you need to use the Well being Join API. Click on the construct button to obtain dependencies and recompile the venture.

Dealing with Permissions and Privateness Coverage

Earlier than you’ll be able to learn or write knowledge, you want to declare all of the permissions your app will use. Create a brand new useful resource file named health_permissions.xml beneath res/values. Add the next permissions:


<assets>
 <array title="health_permissions">
   <merchandise>androidx.well being.permission.Steps.READ</merchandise>
   <merchandise>androidx.well being.permission.Steps.WRITE</merchandise>
   <merchandise>androidx.well being.permission.TotalCaloriesBurned.READ</merchandise>
   <merchandise>androidx.well being.permission.TotalCaloriesBurned.WRITE</merchandise>
 </array>
</assets>

Every merchandise represents a permission your app will use.

Well being Join wants the shopper app to outline the coverage on dealing with privateness and knowledge.

Go to File â–¸ New â–¸ Exercise â–¸ Empty Exercise. Enter PrivacyPolicyActivity for Exercise Identify and click on End.

Open activity_privacy_policy.xml from the format listing and add the next code contained in the ConstraintLayout tag:


<TextView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:textSize="16sp"
    android:layout_margin="24dp"
    android:textual content="@string/privacy_policy" />

Add the next within the strings.xml file:


<string title="privacy_policy">Lorem ipsum dolor sit amet, consectetur adipiscing elit....</string>

Now, in AndroidManifest.xml, exchange the auto-generated component for PrivacyPolicyActivity with the next:


<exercise
 android:exported="true"
 android:title=".PrivacyPolicyActivity">
 <intent-filter>
   <motion android:title="androidx.well being.ACTION_SHOW_PERMISSIONS_RATIONALE"/>
 </intent-filter>
 <meta-data android:title="health_permissions" android:useful resource="@array/health_permissions" />
</exercise>

Right here’s what’s occurring:

  1. You created a brand new exercise PrivacyPolicyActivity.
  2. Within the format file for the exercise, you outlined a dummy privateness coverage.
  3. You then declared the exercise within the manifest so your app can deal with this intent and show a privateness coverage explaining how customers’ knowledge is dealt with.

Now, add the next features after onCreate inside MainActivity.kt:


personal enjoyable checkPermissionsAndRun() {
  // 1
  val shopper = HealthConnectClient.getOrCreate(this)

  // 2
  val permissionsSet = setOf(
    Permission.createWritePermission(StepsRecord::class),
    Permission.createReadPermission(StepsRecord::class),
    Permission.createWritePermission(TotalCaloriesBurnedRecord::class),
    Permission.createReadPermission(TotalCaloriesBurnedRecord::class),
  )

  // 3
  // Create the permissions launcher.
  val requestPermissionActivityContract = shopper
    .permissionController
    .createRequestPermissionActivityContract()

  val requestPermissions = registerForActivityResult(
    requestPermissionActivityContract
  ) { granted ->
    if (granted.containsAll(permissionsSet)) {
      // Permissions efficiently granted
      lifecycleScope.launch {
        onPermissionAvailable(shopper)
      }
    } else {
      Toast.makeText(
        this, "Permissions not granted", Toast.LENGTH_SHORT
      ).present()
    }
  }

  // 4
  lifecycleScope.launch {
    val granted = shopper.permissionController
      .getGrantedPermissions(permissionsSet)
    if (granted.containsAll(permissionsSet)) {
      // Permissions already granted
      onPermissionAvailable(shopper)
    } else {
      // Permissions not granted, request permissions.
      requestPermissions.launch(permissionsSet)
    }
  }
}

personal droop enjoyable onPermissionAvailable(shopper: HealthConnectClient) {
 // todo: learn knowledge
}

Word: Whereas importing dependencies, there are lots of import choices for Permission. Please select androidx.well being.join.shopper.permission.

Right here’s what’s occurring in checkPermissionsAndRun:

  1. You initially come up with a HealthConnectClient object. getOrCreate creates a brand new occasion or returns an current one if it’s accessible.
  2. Create a set of permissions with required knowledge varieties to request permissions inside your utility. Permissions in these units must be declared within the health_permissions useful resource array.
  3. Create a request permission launcher. On launch, customers might be prompted for permissions declared within the health_permissions useful resource array.
  4. Lastly, by way of HealthConnectClient, you test whether or not you’ve the required permissions. If permissions aren’t accessible, you request permissions by way of requestPermissions launcher.

onPermissionAvailable known as when you’ve all required permissions. At this level, it’s potential to learn or write knowledge.

Add the next after the closing utility tag inside AndroidManifest.xml:


 <queries>
   <package deal android:title="com.google.android.apps.healthdata" />
 </queries>

This checks whether or not Well being Join APK is put in.

Lastly, inside onCreate in MainActivity.kt, exchange // Your code with the next code:


if (HealthConnectClient.isAvailable(this)) {
    // Well being Join is obtainable
    checkPermissionsAndRun()
 } else {
    Toast.makeText(
      this, "Well being Join is just not accessible", Toast.LENGTH_SHORT
    ).present()
}

Right here’s what’s occurring:

  • Via HealthConnectClient, you test whether or not Well being Join is obtainable.
  • Whether it is accessible, you test required permissions.

You present a Toast to the person, if Well being Join isn’t accessible.

That’s it! You’ve built-in Well being Join within the app and might request all required permissions. Give it a strive by working the app.

An animation showing how to grant permissions in Android Health Connect

Writing Knowledge

Inserting Information

Add the next code after onPermissionAvailable.


personal enjoyable insertData(shopper: HealthConnectClient, steps: Lengthy, caloriesBurned: Double) {
  // 1
  val startTime = ZonedDateTime.now().minusSeconds(1).toInstant()
  val endTime = ZonedDateTime.now().toInstant()

  // 2
  val data = listOf(
   StepsRecord(
     depend = steps,
     startTime = startTime,
     endTime = endTime,
     startZoneOffset = null,
     endZoneOffset = null,
   ),
   TotalCaloriesBurnedRecord(
     power = Power.energy(caloriesBurned),
     startTime = startTime,
     endTime = endTime,
     startZoneOffset = null,
     endZoneOffset = null,
   )
  )

  // 3
  lifecycleScope.launch {
    val insertRecords = shopper.insertRecords(data)

    if (insertRecords.recordUidsList.isNotEmpty()) {
      runOnUiThread{
          Toast.makeText(
            this@MainActivity,
            "Information inserted efficiently",
            Toast.LENGTH_SHORT
          ).present()
        }
      }
    }
}

With this replace,

  1. You’re making a time vary with a begin and finish. You report the info in a small interval. This fashion you’ll be able to insert the info a number of instances in a day.
  2. Adopted by one other listing that accommodates StepsRecord and TotalCaloriesBurnedRecord data.
  3. Then lastly, you insert the created report by way of the HealthConnectClient occasion. recordUidsList accommodates the uids of inserted data. When the listing isn’t empty, you’re displaying a hit message to the person.

Now, on the finish of onCreate within the MainActivity.kt, add the next code:


val stepsEditText = findViewById<EditText>(R.id.stepsEditText)
val caloriesEditText = findViewById<EditText>(R.id.caloriesEditText)

findViewById<Button>(R.id.submit).setOnClickListener {
  val steps = stepsEditText.textual content.toString().toLong()
  val energy = caloriesEditText.textual content.toString().toDouble()

  val shopper = HealthConnectClient.getOrCreate(this)
  insertData(shopper, steps, energy)

  // clear enter fields after insertion and shut the keyboard
  stepsEditText.textual content.clear()
  caloriesEditText.textual content.clear()
  caloriesEditText.onEditorAction(EditorInfo.IME_ACTION_DONE)
}

Within the code above, when a person faucets Button, you learn enter values and save them with insertData(). You then clear enter fields and shut the keyboard.

Construct and Run

That’s all you want to do to jot down knowledge by way of the Well being Join API. Run the venture, enter values and faucet the button.

An animation to demo the input of steps and calories health data

Studying Knowledge

You’ll be able to learn knowledge in two methods utilizing HealthConnectClient.

  • ReadRecordsRequest: Learn data decided by time vary and different filters. You’ll use this methodology to learn the each day steps depend and energy consumption.
  • AggregateRequest: Learn aggregations for a given AggregateMetric. You’ll use this methodology to learn month-to-month step counts and caloric intakes.

Studying Knowledge by way of a ReadRecordsRequest

In MainActivity.kt, add the next after insertData():


personal droop enjoyable readDailyRecords(shopper: HealthConnectClient) {
  // 1
  val at the moment = ZonedDateTime.now()
  val startOfDay = at the moment.truncatedTo(ChronoUnit.DAYS)
  val timeRangeFilter = TimeRangeFilter.between(
    startOfDay.toLocalDateTime(),
    at the moment.toLocalDateTime()
  )

  // 2
  val stepsRecordRequest = ReadRecordsRequest(StepsRecord::class, timeRangeFilter)
  val numberOfStepsToday = shopper.readRecords(stepsRecordRequest)
    .data
    .sumOf { it.depend }
  val stepsTextView = findViewById<TextView>(R.id.stepsTodayValue)
  stepsTextView.textual content = numberOfStepsToday.toString()

  // 3
  val caloriesRecordRequest = ReadRecordsRequest(
    TotalCaloriesBurnedRecord::class,
    timeRangeFilter
  )
  val caloriesBurnedToday = shopper.readRecords(caloriesRecordRequest)
    .data
    .sumOf { it.power.inCalories }
  val caloriesTextView = findViewById<TextView>(R.id.caloriesTodayValue)
  caloriesTextView.textual content = caloriesBurnedToday.toString()
}

And now the breakdown:

  1. You create a TimeRangeFilter from the beginning of the day till now.
  2. You then create a ReadRecordRequest for StepsRecord. Via the HealthConnectClient occasion, you learn data and get the sum. You get the sum as a result of there could be many data for steps taken at the moment. Lastly, you show the each day steps depend.
  3. This is similar as Step 2, however the ReadRecordsRequest is for TotalCaloriesBurnedRecord.

Studying Knowledge by way of an AggregateRequest

Add the next methodology on the backside of MainActivity:


personal droop enjoyable readAggregatedData(shopper: HealthConnectClient) {
  // 1
  val at the moment = ZonedDateTime.now()
  val startOfDayOfThisMonth = at the moment.withDayOfMonth(1)
    .truncatedTo(ChronoUnit.DAYS)
  val elapsedDaysInMonth = Period.between(startOfDayOfThisMonth, at the moment)
    .toDays() + 1
  val timeRangeFilter = TimeRangeFilter.between(
    startOfDayOfThisMonth.toInstant(),
    at the moment.toInstant()
  )

  // 2
  val knowledge = shopper.mixture(
    AggregateRequest(
      metrics = setOf(
        StepsRecord.COUNT_TOTAL,
        TotalCaloriesBurnedRecord.ENERGY_TOTAL
      ),
      timeRangeFilter = timeRangeFilter,
    )
  )

  // 3
  val steps = knowledge[StepsRecord.COUNT_TOTAL] ?: 0
  val averageSteps = steps / elapsedDaysInMonth
  val stepsAverageTextView = findViewById<TextView>(R.id.stepsAverageValue)
  stepsAverageTextView.textual content = averageSteps.toString()

  // 4
  val caloriesBurned = knowledge[TotalCaloriesBurnedRecord.ENERGY_TOTAL]
      ?.inCalories ?: 0.0
  val averageCaloriesBurned = caloriesBurned / elapsedDaysInMonth
  val caloriesAverageTextView = findViewById<TextView>(
    R.id.caloriesAverageValue
  )
  caloriesAverageTextView.textual content = getString(R.string.format_calories_average)
      .format(averageCaloriesBurned)
}

Word: Whereas importing dependencies, there are lots of import choices for Period. Please select java.time.

Right here’s what’s occurring:

  1. You’re making a TimeRangeFilter from the beginning of the month till now. Additionally, you’re calculating the times elapsed within the month so you’ll be able to calculate the typical.
  2. You’re making an mixture request by way of HealthConnectClient with a set of measurements to get the full steps and energy inside a particular time vary. The good thing about aggregated knowledge is it contains primary aggregations or aggregating knowledge into buckets.
  3. You’re calculating averageSteps and updating the format.
  4. You’re calculating averageCaloriesBurned and updating the format. For a greater UI, you’re rounding the calorie values as much as two decimals.

Add the next within the strings.xml file.


<string title="format_calories_average">%.2f</string>

You’re nearly there. You now have features that learn knowledge, however you want to join a couple of ultimate dots.

Add one other methodology within the MainActivity.kt:


personal droop enjoyable readData(shopper: HealthConnectClient) {
  readDailyRecords(shopper)
  readAggregatedData(shopper)
}

This helper operate instructions each features you created above to learn knowledge.

Now, inside onPermissionAvailable, exchange // todo: learn knowledge with the next.


readData(shopper)

By doing so, you’ll be able to learn the info and replace the format as quickly as you’ve permissions accessible.

Lastly, add the next on the finish of the lifecycleScope.launch { block, inside insertData:


readData(shopper)

This may make sure you present up to date knowledge after a person inserts new knowledge.

Construct and Run

You’re achieved! Construct and run the app to see the outcome. Now you can write knowledge and likewise see your current knowledge.

An animation to demo displaying the total steps and calories health data entered today and the average this month

The place to Go From Right here?

Congratulations! You’ve realized about Well being Join by making a easy app. Now you’ve one much less excuse to get fitter and more healthy. Use the Obtain Supplies button on the prime or backside of this text to obtain the ultimate venture.

You’ll be able to take a couple of steps to enhance your app:

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments