Hướng dẫn này tương thích với Health Connect phiên bản 1.1.0-alpha12.
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 endTime = Instant.now()
val startTime = endTime.minus(Duration.ofMinutes(15))
val stepsRecord = StepsRecord(
count = 120,
startTime = startTime,
endTime = endTime,
startZoneOffset = ZoneOffset.UTC,
endZoneOffset = ZoneOffset.UTC,
metadata = Metadata.autoRecorded(
device = Device(type = Device.TYPE_WATCH)
)
)
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 endTime = Instant.now()
val startTime = endTime.minus(Duration.ofMinutes(1))
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 = startTime,
endTime = endTime,
startZoneOffset = ZoneOffset.UTC,
endZoneOffset = ZoneOffset.UTC,
metadata = Metadata.manualEntry(
device = Device(type = Device.TYPE_PHONE)
)
)
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 endTime = Instant.now()
val startTime = endTime.minus(Duration.ofMinutes(5))
val heartRateRecord = HeartRateRecord(
startTime = startTime,
startZoneOffset = ZoneOffset.UTC,
endTime = endTime,
endZoneOffset = ZoneOffset.UTC,
// records 10 arbitrary data, to replace with actual data
samples = List(10) { index ->
HeartRateRecord.Sample(
time = startTime + Duration.ofSeconds(index.toLong()),
beatsPerMinute = 100 + index.toLong(),
)
},
metadata = Metadata.autoRecorded(
device = Device(type = Device.TYPE_WATCH)
))
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) {
val endTime = Instant.now()
val startTime = endTime.minus(Duration.ofMinutes(5))
try {
val stepsRecord = StepsRecord(
count = 120,
startTime = startTime,
endTime = endTime,
startZoneOffset = ZoneOffset.UTC,
endZoneOffset = ZoneOffset.UTC,
metadata = Metadata.autoRecorded(
device = Device(type = Device.TYPE_WATCH)
)
)
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)
}
healthConnectClient.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(
metadata = Metadata.autoRecorded(
clientRecordId = "Your client record ID",
device = Device(type = Device.TYPE_WATCH)
),
// Assign more parameters for this record
)
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 endTime = Instant.now()
val startTime = endTime.minus(Duration.ofMinutes(15))
val stepsRecord = StepsRecord(
count = 100L,
startTime = startTime,
startZoneOffset = ZoneOffset.UTC,
endTime = endTime,
endZoneOffset = ZoneOffset.UTC,
metadata = Metadata.manualEntry(
clientRecordId = "Your supplied record ID",
clientRecordVersion = 0L, // Your supplied record version
device = Device(type = Device.TYPE_WATCH)
)
)
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 để ghi dữ liệu
Các ứng dụng chỉ được ghi dữ liệu có nguồn chính chủ vào Health Connect.
Nếu dữ liệu trong ứng dụng của bạn được nhập từ một ứng dụng khác, thì ứng dụng đó có trách nhiệm ghi dữ liệu tương ứng vào Health Connect.
Bạn cũng nên triển khai logic giúp xử lý các trường hợp ngoại lệ của hoạt động ghi, chẳng hạn như dữ liệu nằm ngoài ranh giới hoặc lỗi hệ thống nội bộ. Bạn có thể áp dụng chiến lược thời gian đợi và chiến lược thử lại cho cơ chế lên lịch công việc. Nếu như cuối cùng không ghi được dữ liệu vào Health Connect, hãy đảm bảo rằng ứng dụng có thể vượt qua điểm xuất đó. Đừng quên ghi nhật ký và báo cáo lỗi để hỗ trợ hoạt động chẩn đoán.
Khi theo dõi dữ liệu, tuỳ vào cách ứng dụng của bạn ghi dữ liệu, bạn có thể làm theo một vài gợi ý sau đây.
Theo dõi thụ động
Hình thức này bao gồm cả những ứng dụng tiến hành theo dõi thụ động sức khoẻ hoặc hoạt động thể dục, chẳng hạn như liên tục ghi lại số bước hoặc nhịp tim ở chế độ nền.
Ứng dụng của bạn cần định kỳ ghi dữ liệu vào Health Connect theo những cách sau:
- Trong mỗi lần đồng bộ hoá, chỉ ghi dữ liệu mới và dữ liệu cập nhật được sửa đổi kể từ lần đồng bộ hoá gần nhất.
- Phân đoạn các yêu cầu lên tối đa 1.000 bản ghi cho mỗi yêu cầu ghi.
- Sử dụng
WorkManager
để lên lịch các tác vụ ở chế độ nền theo định kỳ, với khoảng thời gian ít nhất là 15 phút. Hạn chế để các tác vụ chỉ chạy khi thiết bị ở trạng thái rảnh và không bị yếu pin.
val constraints = Constraints.Builder() .requiresBatteryNotLow() .requiresDeviceIdle(true) .build() val writeDataWork = PeriodicWorkRequestBuilder<WriteDataToHealthConnectWorker>( 15, TimeUnit.MINUTES, 5, TimeUnit.MINUTES ) .setConstraints(constraints) .build()
Theo dõi chủ động
Hình thức này bao gồm những ứng dụng tiến hành hoạt động theo dõi dựa trên sự kiện (như tập thể dục và ngủ) hoặc dữ liệu do người dùng nhập thủ công (chẳng hạn như dinh dưỡng). Những bản ghi này được tạo khi ứng dụng chạy ở nền trước hoặc trong các sự kiện hiếm gặp khi ứng dụng được dùng vài lần trong một ngày.
Đảm bảo rằng ứng dụng của bạn không sử dụng Health Connect trong toàn bộ thời gian diễn ra sự kiện.
Dữ liệu phải được ghi vào Health Connect theo một trong 2 cách:
- Đồng bộ hoá dữ liệu với Health Connect sau khi sự kiện hoàn thành. Ví dụ: đồng bộ hoá dữ liệu khi người dùng kết thúc một phiên tập thể dục được theo dõi.
- Lên lịch cho tác vụ một lần bằng
WorkManager
để đồng bộ hoá dữ liệu vào lúc khác.
Các phương pháp hay nhất về mức độ chi tiết và tần suất ghi
Khi ghi dữ liệu vào Health Connect, hãy sử dụng độ phân giải phù hợp. Việc sử dụng độ phân giải phù hợp giúp giảm tải cho bộ nhớ, đồng thời vẫn duy trì dữ liệu nhất quán và chính xác. Độ phân giải dữ liệu bao gồm 2 yếu tố:
- Tần suất ghi: tần suất ứng dụng của bạn đẩy dữ liệu mới vào Health Connect. Ví dụ: ghi dữ liệu mới mỗi 15 phút.
- Độ chi tiết của dữ liệu được ghi: tần suất lấy mẫu dữ liệu được đẩy vào. Ví dụ: ghi mẫu nhịp tim mỗi 5 giây. Không phải loại dữ liệu nào cũng yêu cầu cùng một tốc độ lấy mẫu. Việc cập nhật dữ liệu số bước mỗi giây mang lại rất ít lợi ích, thay vào đó hãy dùng tần suất thấp hơn, chẳng hạn như 60 giây/lần. Tuy nhiên, tốc độ lấy mẫu càng cao thì người dùng càng có cái nhìn chi tiết hơn về dữ liệu sức khoẻ và hoạt động thể dục của họ. Tần suất lấy mẫu nên cân bằng giữa mức độ chi tiết và hiệu suất.
Ghi dữ liệu được theo dõi trong suốt cả ngày
Đối với dữ liệu được thu thập liên tục, chẳng hạn như số bước, ứng dụng của bạn phải ghi vào Health Connect ít nhất 15 phút một lần trong ngày.
Kiểu dữ liệu |
Đơn vị |
Dự kiến |
Ví dụ |
Các bước |
số bước |
Mỗi phút |
23:14 – 23:15 – 5 bước 23:16 – 23:17 – 22 bước 23:17 – 23:18 – 8 bước |
StepsCadence |
bước/phút |
Mỗi phút |
23:14 – 23:15 – 5 spm 23:16 – 23:17 – 22 spm 23:17 – 23:18 – 8 nhịp/phút |
Số lần đẩy xe lăn |
đẩy |
Mỗi phút |
23:14 – 23:15 – 5 lần đẩy 23:16 – 23:17 – 22 lần đẩy 23:17 – 23:18 – 8 lượt đẩy |
ActiveCaloriesBurned |
Calo |
15 phút một lần |
23:15 – 23:30 – 2 Calo 23:30 – 23:45 – 25 Calo 23:45 – 00:00 – 5 Calo |
TotalCaloriesBurned |
Calo |
15 phút một lần |
23:15 – 23:30 – 16 Calo 23:30 – 23:45 – 16 Calo 23:45 – 00:00 – 16 Calo |
Quãng đường |
km/phút |
Mỗi phút |
23:14-23:15 – 0,008 km 23:16 – 23:16 – 0,021 km 23:17 – 23:18 – 0,012 km |
ElevationGained |
m |
Mỗi phút |
20:36 – 20:37 – 3.048m 20:39 – 20:40 – 3.048m 23:23 – 23:24 – 9.144m |
Số tầng đã leo |
tầng |
Mỗi phút |
23:14 – 23:15 – 5 tầng 23:16 – 23:16 – 22 tầng 23:17 – 23:18 – 8 tầng |
HeartRate |
nhịp/ph |
Mỗi phút |
6:11 – 55 nhịp/phút |
HeartRateVariabilityRmssd |
mili giây |
Mỗi phút |
6:11 – 23 mili giây |
RespiratoryRate |
nhịp thở/phút |
Mỗi phút |
23:14 – 23:15 – 60 nhịp thở/phút 23:16 – 23:16 – 62 nhịp thở/phút 23:17 – 23:18 – 64 nhịp thở/phút |
OxygenSaturation |
% |
Mỗi giờ |
6:11 – 95,208% |
Ghi phiên
Dữ liệu phải được ghi vào Health Connect khi kết thúc bài tập thể dục hoặc giấc ngủ.
Cách hay nhất là bạn nên ghi mọi phiên giấc ngủ hoặc phiên tập thể dục bằng thiết bị ghi và siêu dữ liệu thích hợp, bao gồm cả RecordingMethod
.
Ít nhất, ứng dụng của bạn phải tuân theo hướng dẫn trong cột "dự kiến" bên dưới. Khi có thể, hãy làm theo hướng dẫn "tốt nhất".
Dữ liệu được theo dõi trong khi tập thể dục
Kiểu dữ liệu |
Đơn vị |
Dự kiến |
Trân trọng, |
Ví dụ |
Các bước |
số bước |
Mỗi phút |
Mỗi 1 giây |
23:14-23:15 – 5 bước 23:16 – 23:17 – 22 bước 23:17 – 23:18 – 8 bước |
StepsCadence |
bước/phút |
Mỗi phút |
Mỗi 1 giây |
23:14-23:15 – 35 nhịp/phút 23:16 – 23:17 – 37 nhịp/phút 23:17 – 23:18 – 40 nhịp/phút |
Số lần đẩy xe lăn |
đẩy |
Mỗi phút |
Mỗi 1 giây |
23:14-23:15 – 5 lần đẩy 23:16 – 23:17 – 22 lần đẩy 23:17 – 23:18 – 8 lượt đẩy |
CyclingPedalingCadence |
vòng/phút |
Mỗi phút |
Mỗi 1 giây |
23:14-23:15 – 65 vòng/phút 23:16 – 23:17 – 70 vòng/phút 23:17 – 23:18 – 68 vòng/phút |
Sức mạnh |
watt |
Mỗi phút |
Mỗi 1 giây |
23:14-23:15 – 250 watt 23:16 – 23:17 – 255 watt 23:17 – 23:18 – 245 watt |
Tốc độ |
km/phút |
Mỗi phút |
Mỗi 1 giây |
23:14-23:15 – 0,3 km/phút 23:16 – 23:17 – 0,4 km/phút 23:17 – 23:18 –0,4 km/phút |
Quãng đường |
km/m |
Mỗi phút |
Mỗi 1 giây |
23:14-23:15 – 0,008 km 23:16 – 23:16 – 0,021 km 23:17 – 23:18 – 0,012 km |
ActiveCaloriesBurned |
Calo |
Mỗi phút |
Mỗi 1 giây |
23:14-23:15 – 20 Calo 23:16 – 23:17 – 20 Calo 23:17 – 23:18 – 25 Calo |
TotalCaloriesBurned |
Calo |
Mỗi phút |
Mỗi 1 giây |
23:14-23:15 – 36 calo 23:16 – 23:17 – 36 Calo 23:17 – 23:18 – 41 Calo |
ElevationGained |
m |
Mỗi phút |
Mỗi 1 giây |
20:36 – 20:37 – 3.048m 20:39 – 20:40 – 3.048m 23:23 – 23:24 – 9.144m |
ExerciseRoutes |
lat/lng/alt |
Cứ 3 đến 5 giây |
Mỗi 1 giây |
|
HeartRate |
nhịp/ph |
Mỗi phút |
Mỗi 1 giây |
23:14-23:15 – 150 nhịp/phút 23:16 – 23:17 – 152 nhịp/phút 23:17 – 23:18 – 155 nhịp/phút |
Dữ liệu được theo dõi trong khi ngủ
Kiểu dữ liệu |
Đơn vị |
Mẫu dự kiến |
Ví dụ |
Giai đoạn ngủ |
giai đoạn |
Khoảng thời gian chi tiết cho mỗi giai đoạn ngủ |
23:46 – 23:50 – tỉnh táo 23:50 – 23:56 – ngủ nông 23:56 – 00:16 – ngủ sâu |
RestingHeartRate |
nhịp/ph |
Một giá trị hằng ngày (dự kiến là vào buổi sáng) |
6:11 – 60 nhịp/phút |
OxygenSaturation |
% |
Một giá trị hằng ngày (dự kiến là vào buổi sáng) |
6:11 – 95,208% |