Ghi dữ liệu

Hướng dẫn này trình bày quy trình ghi hoặc cập nhật dữ liệu trong Health Connect.

Thiết lập cấu trúc dữ liệu

Trước khi ghi dữ liệu, chúng ta cần thiết lập bản ghi. Trong số hơn 50 loại dữ liệu, mỗi loại đều có cấu trúc riêng tương ứng. Vui lòng xem Tài liệu tham khảo về Jetpack để biết thêm thông tin chi tiết về các loại dữ liệu có thể dùng.

Bản ghi cơ bản

Loại dữ liệu về Số bước trong Health Connect ghi lại số bước người dùng đi được giữa các lần đọc. Số bước chính là cách đo lường phổ biến trên các nền tảng về sức khoẻ, hoạt động thể chất và sức khoẻ tinh thần.

Ví dụ sau đây cho thấy cách thiết lập dữ liệu số bước:

val stepsRecord = StepsRecord(
    count = 120,
    startTime = START_TIME,
    endTime = END_TIME,
    startZoneOffset = START_ZONE_OFFSET,
    endZoneOffset = END_ZONE_OFFSET
)

Bản ghi có đơn vị đo lường

Health Connect có thể lưu trữ các giá trị kèm theo đơn vị đo lường để mang lại sự chính xác. Ví dụ: loại dữ liệu Dinh dưỡng rất rộng lớn và toàn diện. Loại dữ liệu này bao gồm nhiều trường không bắt buộc về dinh dưỡng, từ tổng lượng carbohydrate đến vitamin. Mỗi điểm dữ liệu biểu thị những chất dinh dưỡng có thể tiêu thụ trong bữa ăn hoặc món ăn.

Trong loại dữ liệu này, tất cả các chất dinh dưỡng được biểu thị bằng đơn vị Mass, còn energy được biểu thị bằng đơn vị Energy.

Ví dụ sau đây cho biết cách thiết lập dữ liệu dinh dưỡng khi người dùng ăn một quả chuối:

val banana = NutritionRecord(
    name = "banana",
    energy = 105.0.kilocalories,
    dietaryFiber = 3.1.grams,
    potassium = 0.422.grams,
    totalCarbohydrate = 27.0.grams,
    totalFat = 0.4.grams,
    saturatedFat = 0.1.grams,
    sodium = 0.001.grams,
    sugar = 14.0.grams,
    vitaminB6 = 0.0005.grams,
    vitaminC = 0.0103.grams,
    startTime = START_TIME,
    endTime = END_TIME,
    startZoneOffset = START_ZONE_OFFSET,
    endZoneOffset = END_ZONE_OFFSET
)

Bản ghi có dữ liệu theo chuỗi

Health Connect có thể lưu trữ danh sách dữ liệu theo chuỗi. Ví dụ: loại dữ liệu Nhịp tim ghi lại một loạt mẫu nhịp tim được phát hiện giữa các lần đọc.

Trong loại dữ liệu này, tham số samples được biểu thị bằng một danh sách mẫu Nhịp tim. Mỗi mẫu đều chứa một giá trị beatsPerMinute và một giá trị time.

Ví dụ sau đây trình bày cách thiết lập dữ liệu theo chuỗi về nhịp tim:

val heartRateRecord = HeartRateRecord(
    startTime = START_TIME,
    startZoneOffset = START_ZONE_OFFSET,
    endTime = END_TIME,
    endZoneOffset = END_ZONE_OFFSET,
    // records 10 arbitrary data, to replace with actual data
    samples = List(10) { index ->
        HeartRateRecord.Sample(
            time = START_TIME + Duration.ofSeconds(index.toLong()),
            beatsPerMinute = 100 + index.toLong(),
        )
    }
)

Ghi dữ liệu

Ghi dữ liệu là một trong những quy trình công việc phổ biến trong Health Connect. Để thêm bản ghi, hãy dùng insertRecords.

Ví dụ sau đây cho thấy cách ghi dữ liệu chèn số bước:

suspend fun insertSteps(healthConnectClient: HealthConnectClient) {
    try {
        val stepsRecord = StepsRecord(
            count = 120,
            startTime = START_TIME,
            endTime = END_TIME,
            startZoneOffset = START_ZONE_OFFSET,
            endZoneOffset = END_ZONE_OFFSET
        )
        healthConnectClient.insertRecords(listOf(stepsRecord))
    } catch (e: Exception) {
        // Run error handling here
    }
}

Cập nhật dữ liệu

Nếu cần thay đổi một hoặc nhiều bản ghi, đặc biệt là khi cần đồng bộ hoá kho dữ liệu ứng dụng của bạn với dữ liệu từ Health Connect, bạn có thể cập nhật dữ liệu của mình. Có 2 cách cập nhật dữ liệu hiện có, tuỳ thuộc vào giá trị nhận dạng dùng để tìm bản ghi.

Siêu dữ liệu

Trước tiên, bạn cần kiểm tra lớp Metadata vì điều này là cần thiết khi cập nhật dữ liệu. Khi được tạo, mỗi Record trong Health Connect có một trường metadata. Các thuộc tính sau có liên quan đến quá trình đồng bộ hoá:

Thuộc tính Nội dung mô tả
id Mỗi Record trong Health Connect đều có một giá trị id duy nhất.
Health Connect sẽ tự động điền giá trị nàykhi chèn một bản ghi mới.
lastModifiedTime Mỗi Record cũng có thông tin về lần sửa đổi bản ghi gần đây nhất.
Health Connect sẽ tự động điền thông tin này.
clientRecordId Mỗi Record có thể có một mã nhận dạng duy nhất liên kết với bản ghi đó để làm tệp đối chiếu trong kho dữ liệu ứng dụng của bạn.
Ứng dụng của bạn cung cấp giá trị này.
clientRecordVersion Khi một bản ghi có clientRecordId, bạn có thể dùng clientRecordVersion để dữ liệu luôn đồng bộ với phiên bản trong kho dữ liệu ứng dụng của bạn.
Ứng dụng của bạn cung cấp giá trị này.

Cập nhật thông qua mã bản ghi

Để cập nhật dữ liệu, trước tiên, hãy chuẩn bị các bản ghi cần thiết. Thực hiện mọi thay đổi đối với bản ghi, nếu cần. Sau đó, hãy gọi updateRecords để thực hiện các thay đổi.

Ví dụ sau đây cho thấy cách cập nhật dữ liệu. Vì mục đích này, mỗi bản ghi sẽ được điều chỉnh giá trị chênh lệch múi giờ thành PST.

suspend fun updateSteps(
    healthConnectClient: HealthConnectClient,
    prevRecordStartTime: Instant,
    prevRecordEndTime: Instant
) {
    try {
        val request = healthConnectClient.readRecords(
            ReadRecordsRequest(
                recordType = StepsRecord::class,
                timeRangeFilter = TimeRangeFilter.between(
                    prevRecordStartTime,
                    prevRecordEndTime
                )
            )
        )

        val newStepsRecords = arrayListOf<StepsRecord>()
        for (record in request.records) {
            // Adjusted both offset values to reflect changes
            val sr = StepsRecord(
                count = record.count,
                startTime = record.startTime,
                startZoneOffset = record.startTime.atZone(ZoneId.of("PST")).offset,
                endTime = record.endTime,
                endZoneOffset = record.endTime.atZone(ZoneId.of("PST")).offset,
                metadata = record.metadata
            )
            newStepsRecords.add(sr)
        }

        client.updateRecords(newStepsRecords)
    } catch (e: Exception) {
        // Run error handling here
    }
}

Cập nhật và chèn thông qua mã bản ghi máy khách

Nếu đang dùng các giá trị không bắt buộc là Mã bản ghi máy khách và Phiên bản bản ghi máy khách, bạn nên sử dụng insertRecords thay vì updateRecords.

Hàm insertRecords có khả năng cập nhật và chèn dữ liệu. Nếu tồn tại dữ liệu trong Health Connect dựa trên bộ Mã bản ghi máy khách đã cho, thì dữ liệu đó sẽ bị ghi đè. Nếu không, dữ liệu sẽ được ghi dưới dạng dữ liệu mới. Trường hợp này rất có ích bất cứ khi nào bạn cần đồng bộ hoá dữ liệu từ kho dữ liệu ứng dụng của mình với Health Connect.

Ví dụ sau đây cho thấy cách cập nhật và chèn dữ liệu lấy từ kho dữ liệu ứng dụng:

suspend fun pullStepsFromDatastore() : ArrayList<StepsRecord> {
    val appStepsRecords = arrayListOf<StepsRecord>()
    // Pull data from app datastore
    // ...
    // Make changes to data if necessary
    // ...
    // Store data in appStepsRecords
    // ...
    var sr = StepsRecord(
        // Assign parameters for this record
        metadata = Metadata(
            clientRecordId = cid
        )
    )
    appStepsRecords.add(sr)
    // ...
    return appStepsRecords
}

suspend fun upsertSteps(
    healthConnectClient: HealthConnectClient,
    newStepsRecords: ArrayList<StepsRecord>
) {
    try {
        healthConnectClient.insertRecords(newStepsRecords)
    } catch (e: Exception) {
        // Run error handling here
    }
}

Sau đó, bạn có thể gọi các hàm này trong luồng chính.

upsertSteps(healthConnectClient, pullStepsFromDatastore())

Kiểm tra giá trị trong Phiên bản bản ghi máy khách

Nếu quá trình cập nhật và chèn dữ liệu bao gồm cả Phiên bản bản ghi máy khách, thì Health Connect sẽ thực hiện các phép kiểm tra so sánh trong giá trị clientRecordVersion. Nếu phiên bản của dữ liệu được chèn cao hơn phiên bản của dữ liệu hiện có, thì quá trình cập nhật và chèn dữ liệu sẽ xảy ra. Nếu không, quá trình này sẽ bỏ qua sự thay đổi và giữ nguyên giá trị.

Để đưa quá trình lập phiên bản vào dữ liệu, bạn cần cung cấp cho Metadata.clientRecordVersion giá trị Long dựa trên logic lập phiên bản.

val sr = StepsRecord(
    count = count,
    startTime = startTime,
    startZoneOffset = startZoneOffset,
    endTime = endTime,
    endZoneOffset = endZoneOffset,
    metadata = Metadata(
        clientRecordId = cid,
        clientRecordVersion = version
    )
)

Quá trình cập nhật và chèn dữ liệu sẽ không tự động tăng version mỗi khi có các thay đổi để tránh mọi trường hợp ngoài dự kiến của việc ghi đè dữ liệu. Do đó, bạn phải cung cấp giá trị cao hơn theo cách thủ công.

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

Sau khi xây dựng xong logic, hãy cân nhắc làm theo các phương pháp hay nhất khi ghi hoặc cập nhật dữ liệu.