Phát triển trải nghiệm về các chỉ số sức khỏe bằng Health Connect

Nếu muốn tạo một ứng dụng quản lý các chỉ số sức khỏe của người dùng, bạn có thể dùng Health Connect để làm những việc như:

  • Đọc dữ liệu về các chỉ số sức khỏe như huyết áp, tần số tim và thân nhiệt từ các ứng dụng khác
  • Ghi dữ liệu Android vitals do ứng dụng hoặc thiết bị được kết nối của bạn ghi lại
  • Theo dõi xu hướng và cung cấp thông tin chi tiết về sức khoẻ dựa trên dữ liệu về các chỉ số sức khỏe

Hướng dẫn này mô tả cách làm việc với các kiểu dữ liệu chỉ số sức khỏe, bao gồm cả quyền, quy trình đọc và ghi, cũng như các phương pháp hay nhất.

Tổng quan: Xây dựng một trình theo dõi toàn diện về Vitals

Bạn có thể tạo một trải nghiệm theo dõi chỉ số sức khỏe toàn diện bằng Health Connect bằng cách làm theo các bước chính sau:

  • Yêu cầu các quyền thích hợp cho các loại dữ liệu về chỉ số sức khỏe.
  • Ghi dữ liệu về chỉ số sức khoẻ bằng các bản ghi như BloodPressureRecord, HeartRateRecord và các bản ghi khác về chỉ số sức khoẻ.
  • Đọc dữ liệu về chỉ số sức khỏe để hiển thị, phân tích hoặc đang đồng bộ hoá.
  • Sử dụng tính năng xử lý hàng loạt để ghi và đọc dữ liệu một cách hiệu quả.

Quy trình này cho phép khả năng tương tác với các ứng dụng Health Connect khác và xác minh quyền truy cập dữ liệu do người dùng kiểm soát.

Trước khi bắt đầu

Trước khi triển khai các tính năng về chỉ số quan trọng:

Khái niệm chính

Dữ liệu về chỉ số sức khỏe trong Health Connect được biểu thị bằng nhiều loại bản ghi, mỗi loại tương ứng với một chỉ số sinh lý cụ thể. Không giống như các phiên tập luyện, chỉ số sức khỏe thường được ghi lại dưới dạng dữ liệu tại một thời điểm hoặc dữ liệu theo khoảng thời gian.

Các loại dữ liệu về chỉ số sức khỏe

Dữ liệu về chỉ số sinh tồn được biểu thị bằng các loại bản ghi riêng lẻ. Sau đây là các loại phổ biến:

  • BloodPressureRecord: Biểu thị một chỉ số huyết áp, bao gồm huyết áp tâm thu và tâm trương, cũng như tư thế cơ thể.
  • HeartRateRecord: Đại diện cho một loạt các phép đo tần số tim.
  • RestingHeartRateRecord: Biểu thị một chỉ số đo lường duy nhất về tần số tim lúc nghỉ ngơi.
  • BodyTemperatureRecord: Biểu thị một chỉ số nhiệt độ cơ thể, bao gồm cả vị trí đo.
  • BloodGlucoseRecord: Biểu thị một chỉ số đường huyết, bao gồm cả mối quan hệ với bữa ăn và nguồn mẫu.
  • OxygenSaturationRecord: Đại diện cho một chỉ số độ bão hòa oxy.
  • RespiratoryRateRecord: Đại diện cho một phép đo nhịp thở.

Để xem danh sách đầy đủ các loại dữ liệu, hãy xem Các loại dữ liệu của Health Connect.

Điều cần cân nhắc khi phát triển ứng dụng

Dữ liệu về chỉ số sức khỏe có thể là dữ liệu nhạy cảm và các ứng dụng có thể cần ghi dữ liệu để phản hồi các phép đo từ cảm biến hoặc hoạt động đầu vào của người dùng, hoặc đồng bộ hoá dữ liệu từ một phần phụ trợ. Quyền là yếu tố quan trọng để xử lý dữ liệu về chỉ số sức khoẻ.

Quyền

Ứng dụng của bạn phải yêu cầu các quyền liên quan của Health Connect trước khi đọc hoặc ghi dữ liệu về chỉ số quan trọng. Các quyền phổ biến đối với chỉ số sức khoẻ bao gồm huyết áp, tần số tim, thân nhiệt, đường huyết, độ bão hòa oxy và nhịp thở. Trong đó có:

Sau đây là ví dụ về cách yêu cầu quyền đối với huyết áp, tần số tim và thân nhiệt:

Sau khi tạo một phiên bản ứng dụng, ứng dụng của bạn cần yêu cầu người dùng cấp quyền. Người dùng phải được phép cấp hoặc từ chối cấp quyền bất cứ lúc nào.

Để thực hiện việc này, hãy tạo một tập hợp quyền cho các kiểu dữ liệu bắt buộc. Trước tiên, bạn cần khai báo các quyền trong tập hợp này ở tệp kê khai Android.

// Create a set of permissions for required data types
val PERMISSIONS =
    setOf(
  HealthPermission.getReadPermission(BloodPressureRecord::class),
  HealthPermission.getWritePermission(BloodPressureRecord::class),
  HealthPermission.getReadPermission(HeartRateRecord::class),
  HealthPermission.getWritePermission(HeartRateRecord::class),
  HealthPermission.getReadPermission(BodyTemperatureRecord::class),
  HealthPermission.getWritePermission(BodyTemperatureRecord::class)
)

Hãy sử dụng getGrantedPermissions để xem ứng dụng của bạn đã được cấp các quyền cần thiết chưa. Nếu chưa, hãy sử dụng createRequestPermissionResultContract để yêu cầu các quyền đó. Thao tác này sẽ hiện màn hình các quyền của Health Connect.

// Create the permissions launcher
val requestPermissionActivityContract = PermissionController.createRequestPermissionResultContract()

val requestPermissions = registerForActivityResult(requestPermissionActivityContract) { granted ->
  if (granted.containsAll(PERMISSIONS)) {
    // Permissions successfully granted
  } else {
    // Lack of required permissions
  }
}

suspend fun checkPermissionsAndRun(healthConnectClient: HealthConnectClient) {
  val granted = healthConnectClient.permissionController.getGrantedPermissions()
  if (granted.containsAll(PERMISSIONS)) {
    // Permissions already granted; proceed with inserting or reading data
  } else {
    requestPermissions.launch(PERMISSIONS)
  }
}

Vì người dùng có thể cấp hoặc thu hồi quyền bất cứ lúc nào, nên ứng dụng của bạn cần kiểm tra quyền mỗi khi sử dụng và xử lý các trường hợp mất quyền.

Để yêu cầu cấp quyền, hãy gọi hàm checkPermissionsAndRun:

if (!granted.containsAll(PERMISSIONS)) {
    requestPermissions.launch(PERMISSIONS)
    // Check if required permissions are not granted, and return
  }
// Permissions already granted; proceed with inserting or reading data

Nếu chỉ cần yêu cầu quyền truy cập đối với một loại dữ liệu duy nhất, chẳng hạn như huyết áp, hãy chỉ thêm loại dữ liệu đó vào bộ quyền:

Quyền truy cập vào huyết áp được bảo vệ bằng các quyền sau:

  • android.permission.health.READ_BLOOD_PRESSURE
  • android.permission.health.WRITE_BLOOD_PRESSURE

Để thêm chức năng đo huyết áp vào ứng dụng, hãy bắt đầu bằng cách yêu cầu quyền cho kiểu dữ liệu BloodPressureRecord.

Dưới đây là quyền bạn cần khai báo để có thể ghi huyết áp:

<application>
  <uses-permission
android:name="android.permission.health.WRITE_BLOOD_PRESSURE" />
...
</application>

Để đọc huyết áp, bạn cần yêu cầu các quyền sau:

<application>
  <uses-permission
android:name="android.permission.health.READ_BLOOD_PRESSURE" />
...
</application>

Ghi dữ liệu về chỉ số sức khoẻ

Phần này mô tả cách ghi dữ liệu về dấu hiệu sinh tồn vào Health Connect. Dữ liệu về các chỉ số sức khỏe thường được ghi dưới dạng các bản ghi riêng lẻ. Nếu bạn đang ghi nhiều bản ghi cùng một lúc, chẳng hạn như đồng bộ hoá từ cảm biến hoặc phụ trợ, hãy sử dụng tính năng xử lý hàng loạt.

Ví dụ về cách viết BloodPressureRecord:

suspend fun writeBloodPressureRecord(healthConnectClient: HealthConnectClient) {
    val record = BloodPressureRecord(
        time = Instant.now(),
        zoneOffset = ZoneOffset.UTC,
        systolic = Pressure.millimetersOfMercury(120.0),
        diastolic = Pressure.millimetersOfMercury(80.0),
        bodyPosition = BloodPressureRecord.BODY_POSITION_SITTING_DOWN,
        measurementLocation = BloodPressureRecord.MEASUREMENT_LOCATION_LEFT_WRIST
    )
    healthConnectClient.insertRecords(listOf(record))
}

Viết theo lô

Nếu ứng dụng của bạn cần ghi nhiều điểm dữ liệu, chẳng hạn như đồng bộ hoá dữ liệu từ một thiết bị thông minh hoặc một dịch vụ phụ trợ, bạn nên ghi hàng loạt để cải thiện hiệu quả và giảm mức tiêu thụ pin. Health Connect có thể xử lý tối đa 1.000 bản ghi trong một yêu cầu ghi duy nhất.

Đoạn mã sau đây cho biết cách ghi hàng loạt nhiều bản ghi cùng lúc:

suspend fun writeBatchRecords(healthConnectClient: HealthConnectClient) {
    val bloodPressureRecord = BloodPressureRecord(
        time = Instant.now(),
        zoneOffset = ZoneOffset.UTC,
        systolic = Pressure.millimetersOfMercury(120.0),
        diastolic = Pressure.millimetersOfMercury(80.0),
        bodyPosition = BloodPressureRecord.BODY_POSITION_SITTING_DOWN,
        measurementLocation = BloodPressureRecord.MEASUREMENT_LOCATION_LEFT_WRIST
    )
    val heartRateRecord = HeartRateRecord(
        startTime = Instant.now().minusSeconds(60),
        startZoneOffset = ZoneOffset.UTC,
        endTime = Instant.now(),
        endZoneOffset = ZoneOffset.UTC,
        samples = listOf(HeartRateRecord.Sample(time = Instant.now().minusSeconds(30), beatsPerMinute = 80))
    )
    healthConnectClient.insertRecords(listOf(bloodPressureRecord, heartRateRecord))
}

Đọc dữ liệu về các chỉ số sức khỏe

Các ứng dụng có thể đọc dữ liệu về chỉ số sức khoẻ để hiển thị các số đo, phân tích xu hướng hoặc đồng bộ hoá dữ liệu với một máy chủ bên ngoài. Để đọc các chỉ số sức khỏe, hãy dùng ReadRecordsRequest với Loại Bản ghi cụ thể và lọc theo một phạm vi thời gian.

Ví dụ về cách đọc dữ liệu BloodPressureRecord:

suspend fun readBloodPressureRecords(
    healthConnectClient: HealthConnectClient,
    startTime: Instant,
    endTime: Instant
) {
    val response = healthConnectClient.readRecords(
        ReadRecordsRequest(
            recordType = BloodPressureRecord::class,
            timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
        )
    )

    for (record in response.records) {
        // Process each blood pressure record
        val systolic = record.systolic
        val diastolic = record.diastolic
    }
}

Nếu cần đồng bộ hoá dữ liệu về chỉ số sức khỏe với máy chủ phụ trợ hoặc cập nhật kho dữ liệu của ứng dụng bằng Health Connect, hãy sử dụng ChangeLogs. Điều này cho phép bạn truy xuất danh sách các bản ghi đã được chèn, cập nhật hoặc xoá kể từ một thời điểm cụ thể, hiệu quả hơn so với việc theo dõi các thay đổi theo cách thủ công hoặc đọc tất cả dữ liệu nhiều lần. Để biết thêm thông tin, hãy xem bài viết Đồng bộ hoá dữ liệu với Health Connect.

Các phương pháp hay nhất

Hãy làm theo các nguyên tắc này để cải thiện độ tin cậy của dữ liệu và trải nghiệm người dùng:

  • Tần suất ghi và xử lý hàng loạt: Để giảm chi phí đầu vào/đầu ra và duy trì thời lượng pin, hãy nhóm các điểm dữ liệu thành một lệnh gọi insertRecords duy nhất với các lô tối đa 1000 bản ghi, thay vì ghi từng điểm riêng lẻ.
    • Theo dõi trực tiếp: Để nhận thông tin cập nhật thường xuyên từ các cảm biến (chẳng hạn như máy đo đường huyết liên tục hoặc máy đo tần số tim), hãy ghi dữ liệu theo lô trong khoảng thời gian tối đa 15 phút để cân bằng giữa thông tin cập nhật theo thời gian thực và hiệu suất pin.
    • Đồng bộ hoá ở chế độ nền: Sử dụng WorkManager để ghi hoãn lại, chẳng hạn như đồng bộ hoá dữ liệu từ thiết bị đồng hành hoặc dịch vụ phụ trợ. Đặt khoảng thời gian là 15 phút cho các thao tác ghi hàng loạt.
  • Tránh ghi dữ liệu trùng lặp: Sử dụng mã ứng dụng Khi tạo bản ghi, hãy đặt một metadata.clientRecordId. Health Connect sử dụng thông tin này để xác định các bản ghi riêng biệt. Nếu bạn cố gắng ghi một bản ghi có clientRecordId đã tồn tại, Health Connect sẽ bỏ qua bản ghi trùng lặp hoặc cập nhật bản ghi hiện có thay vì tạo bản ghi mới. Đặt metadata.clientRecordId là cách hiệu quả nhất để ngăn chặn các bản sao trong quá trình đồng bộ hoá lại hoặc cài đặt lại ứng dụng.

    val record = BloodPressureRecord(
        time = Instant.now(),
        zoneOffset = ZoneOffset.UTC,
        systolic = Pressure.millimetersOfMercury(120.0),
        diastolic = Pressure.millimetersOfMercury(80.0),
        bodyPosition = BloodPressureRecord.BODY_POSITION_SITTING_DOWN,
        measurementLocation = BloodPressureRecord.MEASUREMENT_LOCATION_LEFT_WRIST,
        metadata = Metadata(
            // Use a unique ID from your own database
            clientRecordId = "bp_20240101_user123"
        )
    )
  • Kiểm tra dữ liệu hiện có: Trước khi đồng bộ hoá dữ liệu, hãy truy vấn Health Connect để tìm các bản ghi trong phạm vi thời gian đồng bộ hoá nhằm xem dữ liệu từ ứng dụng của bạn đã tồn tại hay chưa, để tránh trùng lặp hoặc ghi đè dữ liệu mới hơn.

  • Đưa ra lý do rõ ràng cho quyền: Sử dụng quy trình Permission.createIntent để giải thích lý do ứng dụng của bạn cần quyền truy cập vào dữ liệu sức khoẻ, chẳng hạn như "Để theo dõi xu hướng huyết áp và cung cấp thông tin chi tiết".

  • Căn chỉnh dấu thời gian với thông tin đo lường: Xác minh dấu thời gian của bản ghi một cách chính xác để phản ánh thời điểm thực hiện các thông tin đo lường. Đối với dữ liệu khoảng thời gian như HeartRateRecord, hãy xác minh rằng startTimeendTime là chính xác.

Thử nghiệm

Để xác minh tính chính xác của dữ liệu và trải nghiệm người dùng chất lượng cao, hãy làm theo các chiến lược kiểm thử này và tham khảo tài liệu chính thức về Kiểm thử các trường hợp sử dụng hàng đầu.

Công cụ xác minh

  • Hộp công cụ Health Connect: Sử dụng ứng dụng bổ trợ này để kiểm tra các bản ghi theo cách thủ công, xoá dữ liệu kiểm thử và mô phỏng các thay đổi đối với cơ sở dữ liệu. Đây là cách tốt nhất để xác minh rằng các bản ghi của bạn đang được lưu trữ đúng cách.
  • Kiểm thử đơn vị bằng FakeHealthConnectClient: Sử dụng thư viện kiểm thử để xác minh cách ứng dụng của bạn xử lý các trường hợp đặc biệt, chẳng hạn như thu hồi quyền hoặc ngoại lệ API mà không cần thiết bị thực.

Danh sách kiểm tra chất lượng

Kiến trúc điển hình

Việc triển khai các chỉ số sức khỏe thường bao gồm:

Thành phần Quản lý
Bộ điều khiển Vitals Đọc cảm biến/đầu vào
Logic xử lý theo lô
Lớp kho lưu trữ (bao gồm các thao tác trên Health Connect): Chèn bản ghi về chỉ số sức khoẻ
Đọc bản ghi về chỉ số sức khoẻ
Lớp giao diện người dùng (Màn hình): Số liệu đọc trực tiếp
Dữ liệu trong quá khứ
Biểu đồ và xu hướng

Khắc phục sự cố

Dấu hiệu Nguyên nhân có thể gây ra lỗi Độ phân giải
Thiếu các loại dữ liệu (Ví dụ: Huyết áp) Thiếu quyền ghi hoặc bộ lọc thời gian không chính xác. Kiểm tra để đảm bảo bạn đã yêu cầu và người dùng đã cấp quyền cho loại dữ liệu cụ thể. Xác minh rằng ReadRecordsRequest của bạn sử dụng TimeRangeFilter bao gồm thời gian đo lường. Xem phần Quyền.
Không ghi được bản ghi Đơn vị hoặc giá trị không chính xác nằm ngoài phạm vi hợp lệ. Health Connect xác thực các giá trị bản ghi. Ví dụ: giá trị huyết áp phải nằm trong phạm vi hợp lý về mặt sinh lý. Hãy xem tài liệu về kiểu dữ liệu để biết các đơn vị và phạm vi hợp lệ.
Các bản ghi trùng lặp xuất hiện Thiếu clientRecordId Chỉ định một clientRecordId duy nhất trong Metadata của mỗi bản ghi. Điều này cho phép Health Connect thực hiện việc loại bỏ dữ liệu trùng lặp nếu cùng một dữ liệu được ghi hai lần trong quá trình đồng bộ hoá lại. Xem Các phương pháp hay nhất.

Các bước gỡ lỗi thường gặp

  • Kiểm tra trạng thái Quyền: Luôn gọi getPermissionStatus() trước khi thử thực hiện thao tác đọc hoặc ghi. Người dùng có thể thu hồi quyền trong phần cài đặt hệ thống bất cứ lúc nào.