คู่มือนี้ใช้ได้กับ Health Connect เวอร์ชัน 1.1.0-alpha12
คู่มือนี้ครอบคลุมกระบวนการเขียนหรืออัปเดตข้อมูลใน Health Connect
จัดการค่า 0
ข้อมูลบางประเภท เช่น จำนวนก้าว ระยะทาง หรือแคลอรี อาจมีค่าเป็น 0
ให้เขียนค่าเป็น 0 เฉพาะเมื่อไม่มีการใช้งานจริงขณะที่ผู้ใช้สวมอุปกรณ์
อย่าเขียนค่าเป็น 0 หากไม่ได้สวมอุปกรณ์ ข้อมูล
ขาดหายไป หรือแบตเตอรี่หมด ในกรณีเช่นนี้ ให้ละเว้นระเบียนเพื่อหลีกเลี่ยงข้อมูลที่ทำให้เข้าใจผิด
ตั้งค่าโครงสร้างข้อมูล
ก่อนที่จะเขียนข้อมูล เราต้องตั้งค่าระเบียนก่อน สำหรับข้อมูลมากกว่า 50 ประเภท แต่ละประเภทจะมีโครงสร้างของตัวเอง ดูรายละเอียดเพิ่มเติมเกี่ยวกับประเภทข้อมูลที่ใช้ได้ในข้อมูลอ้างอิง Jetpack
บันทึกพื้นฐาน
ประเภทข้อมูลจำนวนก้าวใน Health Connect จะบันทึกจำนวนก้าวที่ผู้ใช้เดินระหว่างการอ่าน จำนวนก้าวเป็นหน่วยวัดทั่วไป ในแพลตฟอร์มสุขภาพ การออกกำลังกาย และสุขภาวะ
ตัวอย่างต่อไปนี้แสดงวิธีตั้งค่าข้อมูลจำนวนก้าว
val zoneOffset = ZoneOffset.systemDefault().rules.getOffset(startTime) val stepsRecord = StepsRecord( count = 120, startTime = startTime, endTime = endTime, startZoneOffset = zoneOffset, endZoneOffset = zoneOffset, metadata = Metadata( device = Device(type = Device.TYPE_WATCH), recordingMethod = Metadata.RECORDING_METHOD_AUTOMATICALLY_RECORDED ) ) healthConnectClient.insertRecords(listOf(stepsRecord))
บันทึกที่มีหน่วยวัด
Health Connect สามารถจัดเก็บค่าพร้อมกับหน่วยวัดเพื่อความแม่นยำ ตัวอย่างหนึ่งคือประเภทข้อมูลโภชนาการ ซึ่งมีข้อมูลมากมายและ ครอบคลุม ซึ่งประกอบด้วยฟิลด์สารอาหารที่ไม่บังคับที่หลากหลายตั้งแต่คาร์โบไฮเดรตทั้งหมดไปจนถึงวิตามิน จุดข้อมูลแต่ละจุดแสดงสารอาหาร ที่อาจได้รับจากการรับประทานอาหารหรือรายการอาหาร
ในประเภทข้อมูลนี้ สารอาหารทั้งหมดจะแสดงในหน่วยมวล ขณะที่ energy จะแสดงในหน่วยพลังงาน
ตัวอย่างต่อไปนี้แสดงวิธีตั้งค่าข้อมูลโภชนาการสำหรับผู้ใช้ที่กินกล้วย
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( device = Device(type = Device.TYPE_PHONE) ) )
บันทึกที่มีข้อมูลซีรีส์
Health Connect สามารถจัดเก็บรายการข้อมูลชุด ตัวอย่างหนึ่งคือประเภทข้อมูลอัตราการเต้นของหัวใจที่บันทึกตัวอย่างการเต้นของหัวใจเป็นชุด ซึ่งตรวจพบระหว่างการอ่านค่า
ในข้อมูลประเภทนี้ พารามิเตอร์ samples จะแสดงด้วยรายการ
ตัวอย่างอัตราการเต้นของหัวใจ แต่ละตัวอย่างจะมีค่า beatsPerMinute
และค่า time
ตัวอย่างต่อไปนี้แสดงวิธีตั้งค่าข้อมูลชุดอัตราการเต้นของหัวใจ
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( device = Device(type = Device.TYPE_WATCH) ))
ขอสิทธิ์จากผู้ใช้
หลังจากสร้างอินสแตนซ์ไคลเอ็นต์แล้ว แอปของคุณต้องขอสิทธิ์จากผู้ใช้ ผู้ใช้ต้องได้รับอนุญาตให้ให้หรือปฏิเสธสิทธิ์ได้ทุกเมื่อ
โดยให้สร้างชุดสิทธิ์สำหรับประเภทข้อมูลที่จำเป็น ตรวจสอบว่าได้ประกาศสิทธิ์ในชุดไว้ในไฟล์ Manifest ของ Android ก่อน
// Create a set of permissions for required data types
val PERMISSIONS =
setOf(
HealthPermission.getReadPermission(HeartRateRecord::class),
HealthPermission.getWritePermission(HeartRateRecord::class),
HealthPermission.getReadPermission(StepsRecord::class),
HealthPermission.getWritePermission(StepsRecord::class)
)
ใช้ getGrantedPermissions เพื่อดูว่าแอปของคุณได้รับสิทธิ์ที่จำเป็นแล้วหรือไม่ หากไม่มี ให้ใช้ createRequestPermissionResultContract เพื่อขอสิทธิ์เหล่านั้น ซึ่งจะแสดงหน้าจอขอสิทธิ์ของ 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)
}
}
เนื่องจากผู้ใช้สามารถให้หรือเพิกถอนสิทธิ์ได้ทุกเมื่อ แอปของคุณจึงต้อง ตรวจสอบสิทธิ์ทุกครั้งก่อนที่จะใช้สิทธิ์ และจัดการสถานการณ์ที่ สิทธิ์หายไป
เขียนข้อมูล
เวิร์กโฟลว์ทั่วไปอย่างหนึ่งใน Health Connect คือการเขียนข้อมูล หากต้องการเพิ่มระเบียน
ให้ใช้ insertRecords
ตัวอย่างต่อไปนี้แสดงวิธีเขียนข้อมูลเพื่อแทรกจำนวนก้าว
val zoneOffset = ZoneOffset.systemDefault().rules.getOffset(startTime) val stepsRecord = StepsRecord( count = 120, startTime = startTime, endTime = endTime, startZoneOffset = zoneOffset, endZoneOffset = zoneOffset, metadata = Metadata( device = Device(type = Device.TYPE_WATCH), recordingMethod = Metadata.RECORDING_METHOD_AUTOMATICALLY_RECORDED ) ) healthConnectClient.insertRecords(listOf(stepsRecord))
อัปเดตข้อมูล
หากต้องการเปลี่ยนระเบียนอย่างน้อย 1 รายการ โดยเฉพาะเมื่อต้องการซิงค์ที่เก็บข้อมูลของแอปกับข้อมูลจาก Health Connect คุณสามารถอัปเดตข้อมูลได้ การอัปเดตข้อมูลที่มีอยู่ทำได้ 2 วิธี โดยขึ้นอยู่กับตัวระบุที่ใช้ค้นหาระเบียน
ข้อมูลเมตา
คุณควรตรวจสอบคลาส Metadata ก่อนเนื่องจากจำเป็นเมื่อ
อัปเดตข้อมูล เมื่อสร้างแล้ว Record แต่ละรายการใน Health Connect จะมีช่อง
metadata พร็อพเพอร์ตี้ต่อไปนี้เกี่ยวข้องกับการซิงค์
| พร็อพเพอร์ตี้ | คำอธิบาย |
|---|---|
id
|
Record ทุกรายการใน Health Connect มีค่า id
ที่ไม่ซ้ำกันHealth Connect จะสร้างข้อมูลนี้โดยอัตโนมัติ เมื่อแทรกระเบียนใหม่ |
lastModifiedTime
|
Record ยังติดตามเวลาที่มีการแก้ไขระเบียนครั้งล่าสุดด้วย
Health Connect จะป้อนข้อมูลนี้โดยอัตโนมัติ |
clientRecordId
|
Record แต่ละรายการจะมีรหัสที่ไม่ซ้ำกันซึ่งเชื่อมโยงอยู่
เพื่อใช้เป็นข้อมูลอ้างอิงใน Datastore ของแอป
แอปของคุณระบุค่านี้ |
clientRecordVersion
|
ในกรณีที่ระเบียนมี clientRecordId คุณสามารถใช้
clientRecordVersion เพื่ออนุญาตให้ข้อมูล
ซิงค์กับเวอร์ชันในพื้นที่เก็บข้อมูลของแอป
ได้แอปของคุณระบุค่านี้ |
อัปเดตหลังจากอ่านตามช่วงเวลา
หากต้องการอัปเดตข้อมูล ให้เตรียมระเบียนที่จำเป็นก่อน ทำการเปลี่ยนแปลงระเบียนหากจำเป็น จากนั้นโทรหา updateRecords เพื่อทำการเปลี่ยนแปลง
ตัวอย่างต่อไปนี้แสดงวิธีอัปเดตข้อมูล ด้วยเหตุนี้ ระเบียนแต่ละรายการ จึงมีการปรับค่าออฟเซ็ตโซนเป็น 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 } }
อัปเดต/แทรกผ่านรหัสระเบียนลูกค้า
หากคุณใช้ค่ารหัสระเบียนไคลเอ็นต์และเวอร์ชันระเบียนไคลเอ็นต์ที่ไม่บังคับ
เราขอแนะนำให้ใช้ insertRecords แทน updateRecords
ฟังก์ชัน insertRecords มีความสามารถในการอัปเดต/แทรกข้อมูล
หากมีข้อมูลใน Health Connect ตามชุดรหัสบันทึกของลูกค้าที่ระบุ ระบบจะเขียนทับข้อมูลดังกล่าว ไม่เช่นนั้น ระบบจะเขียนเป็นข้อมูลใหม่
สถานการณ์นี้มีประโยชน์เมื่อใดก็ตามที่คุณต้องการซิงค์ข้อมูลจากที่เก็บข้อมูลของแอปไปยัง Health Connect
ตัวอย่างต่อไปนี้แสดงวิธีดำเนินการ Upsert ในข้อมูลที่ดึงมาจาก พื้นที่เก็บข้อมูลของแอป
suspend fun pullStepsFromDatastore(startTime: Instant, endTime: Instant) : 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( clientRecordId = "Your client record ID", device = Device(type = Device.TYPE_WATCH) ), startTime = startTime, startZoneOffset = startTime.atZone(ZoneId.of("PST")).offset, endTime = endTime, endZoneOffset = endTime.atZone(ZoneId.of("PST")).offset, count = 120 ) appStepsRecords.add(sr) // ... return appStepsRecords } suspend fun upsertSteps( healthConnectClient: HealthConnectClient, newStepsRecords: ArrayList<StepsRecord> ) { try { healthConnectClient.insertRecords(newStepsRecords) } catch (e: Exception) { // Run error handling here } }
หลังจากนั้น คุณจะเรียกใช้ฟังก์ชันเหล่านี้ในเทรดหลักได้
upsertSteps(healthConnectClient, pullStepsFromDatastore( startTime = startTime, endTime = endTime ))
ตรวจสอบค่าในเวอร์ชันบันทึกของไคลเอ็นต์
หากกระบวนการแทรก/อัปเดตข้อมูลมี Client Record Version, Health
Connect จะทำการตรวจสอบการเปรียบเทียบในค่า clientRecordVersion
หากเวอร์ชันจากข้อมูลที่แทรกสูงกว่า
เวอร์ชันจากข้อมูลที่มีอยู่ ระบบจะดำเนินการอัปเดต/แทรก ไม่เช่นนั้น กระบวนการจะ
ไม่สนใจการเปลี่ยนแปลงและค่าจะยังคงเหมือนเดิม
หากต้องการรวมการกำหนดเวอร์ชันไว้ในข้อมูล คุณต้องระบุ
Metadata.clientRecordVersion ที่มีค่า Long ตามตรรกะการกำหนดเวอร์ชัน
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( clientRecordId = "Your supplied record ID", clientRecordVersion = 0L, // Your supplied record version device = Device(type = Device.TYPE_WATCH) ) )
Upsert จะไม่เพิ่ม version โดยอัตโนมัติเมื่อมีการเปลี่ยนแปลง
เพื่อป้องกันไม่ให้มีการเขียนทับข้อมูลโดยไม่คาดคิด ด้วยเหตุนี้ คุณจึงต้อง
ระบุค่าที่สูงขึ้นด้วยตนเอง
คําแนะนําทั่วไป
แอปของคุณควรเขียนข้อมูลจากบุคคลที่หนึ่งที่รองรับทั้งหมด คุณเลือกให้แอปเขียนข้อมูลที่ได้จากแหล่งที่มาของบุคคลที่สามได้ (ไม่บังคับ) อย่างไรก็ตาม หากแอปของคุณอ่านข้อมูลจาก Health Connect ข้อมูลนั้นไม่ควร เขียนกลับลงใน Health Connect
เมื่อเขียนข้อมูลที่นำเข้าหรือได้มาจากแหล่งที่มาอื่น คุณควรระบุแหล่งที่มาและข้อมูลเมตาของอุปกรณ์ต้นทางอย่างถูกต้อง โดยคุณต้องระบุข้อมูลเมตาต่อไปนี้สำหรับบันทึกที่เป็นลายลักษณ์อักษรแต่ละรายการ
recordingMethod: สำหรับข้อมูลที่บันทึกโดยอัตโนมัติหรือด้วยตนเอง เรา คาดหวังว่าจะมีการอัปเดตวิธีการบันทึกให้สอดคล้องกับประเภทกิจกรรม ที่บันทึกไว้ ดังนี้RECORDING_METHOD_AUTOMATICALLY_RECORDED: หากระบบบันทึกข้อมูลโดยอัตโนมัติ เช่น ฟิตเนสแบนด์ตรวจพบโดยอัตโนมัติว่าผู้ใช้ไปวิ่งRECORDING_METHOD_ACTIVELY_RECORDED: หากผู้ใช้เริ่มกิจกรรมใหม่ เช่น ปั่นจักรยานบนอุปกรณ์ที่สวมใส่ได้RECORDING_METHOD_MANUAL_ENTRY: หากผู้ใช้ป้อนข้อมูลด้วยตนเอง
device.type: คุณต้องระบุประเภทอุปกรณ์จากประเภทDeviceที่รองรับdevice.manufacturer: ผู้ผลิตอุปกรณ์ เช่น "Fitbit"device.model: รุ่นของอุปกรณ์ เช่น "Charge 3"
การตั้งค่าข้อมูลเมตาอย่างถูกต้องเป็นสิ่งสำคัญอย่างยิ่งต่อความโปร่งใสของข้อมูล และช่วยให้ ผู้ใช้เข้าใจว่าข้อมูลสุขภาพของตนมาจากที่ใด ดูรายละเอียดทั้งหมดได้ในคู่มือข้อมูลเมตาของ Health Connect
หากมีการนำเข้าข้อมูลในแอปจากแอปอื่น ความรับผิดชอบ จะตกอยู่กับแอปอื่นในการเขียนข้อมูลของตัวเองลงใน Health Connect
นอกจากนี้ คุณควรใช้ตรรกะที่จัดการข้อยกเว้นในการเขียน เช่น ข้อมูลอยู่นอกขอบเขต หรือข้อผิดพลาดของระบบภายใน คุณสามารถใช้กลยุทธ์ Backoff และลองอีกครั้งกับกลไกการตั้งเวลางานได้ หากการเขียนข้อมูลลงใน Health Connect ไม่สำเร็จในท้ายที่สุด ให้ตรวจสอบว่าแอปของคุณสามารถดำเนินการต่อจากจุดส่งออกนั้นได้ อย่าลืมบันทึกและรายงานข้อผิดพลาดเพื่อช่วยในการวินิจฉัย
เมื่อติดตามข้อมูล มีคำแนะนำ 2 ข้อที่คุณทำตามได้โดยขึ้นอยู่กับวิธีที่แอปเขียนข้อมูล
การจัดการเขตเวลา
เมื่อเขียนบันทึกตามเวลา ให้หลีกเลี่ยงการตั้งค่าออฟเซ็ตเป็น zoneOffset.UTC
โดยค่าเริ่มต้น เนื่องจากอาจทำให้การประทับเวลาไม่ถูกต้องเมื่อผู้ใช้อยู่ใน
เขตเวลาอื่น ให้คำนวณออฟเซ็ตตามตำแหน่งจริงของอุปกรณ์แทน คุณเรียกเขตเวลาของอุปกรณ์ได้โดยใช้
ZoneId.systemDefault()
val endTime = Instant.now() val startTime = endTime.minus(Duration.ofDays(1)) val stepsRecords = mutableListOf<StepsRecord>() var sampleTime = startTime val minutesBetweenSamples = 15L while (sampleTime < endTime) { // Get the default ZoneId then convert it to an offset val zoneOffset = ZoneOffset.systemDefault().rules.getOffset(sampleTime) stepsRecords += StepsRecord( startTime = sampleTime.minus(Duration.ofMinutes(minutesBetweenSamples)), startZoneOffset = zoneOffset, endTime = sampleTime, endZoneOffset = zoneOffset, count = Random.nextLong(1, 100), metadata = Metadata(), ) sampleTime = sampleTime.plus(Duration.ofMinutes(minutesBetweenSamples)) } healthConnectClient.insertRecords( stepsRecords )
ดูรายละเอียดเพิ่มเติมได้ในเอกสารประกอบสำหรับ ZoneId
เขียนความถี่และระดับรายละเอียด
เมื่อเขียนข้อมูลไปยัง Health Connect ให้ใช้ความละเอียดที่เหมาะสม การใช้ความละเอียดที่เหมาะสมจะช่วยลดภาระการจัดเก็บข้อมูล ในขณะที่ยังคงรักษาข้อมูลให้สอดคล้องและแม่นยำ ความละเอียดของข้อมูลครอบคลุม 2 สิ่งต่อไปนี้
- ความถี่ในการเขียน: ความถี่ที่แอปพลิเคชันของคุณเขียนข้อมูลใหม่ลงใน Health Connect
- เขียนข้อมูลบ่อยที่สุดเท่าที่จะทำได้เมื่อมีข้อมูลใหม่ พร้อมกับ คำนึงถึงประสิทธิภาพของอุปกรณ์
- เพื่อไม่ให้ส่งผลเสียต่ออายุการใช้งานแบตเตอรี่และประสิทธิภาพด้านอื่นๆ ช่วงเวลาระหว่างการเขียนสูงสุดควรอยู่ที่ 15 นาที
- ระดับความละเอียดของข้อมูลที่เขียน: ความถี่ในการสุ่มตัวอย่างข้อมูล
- เช่น เขียนตัวอย่างอัตราการเต้นของหัวใจทุกๆ 5 วินาที
- ข้อมูลแต่ละประเภทไม่จำเป็นต้องมีอัตราการสุ่มตัวอย่างเดียวกัน การอัปเดตข้อมูลจำนวนก้าวทุกวินาทีแทบไม่มีประโยชน์ เมื่อเทียบกับการอัปเดตที่ถี่น้อยกว่า เช่น ทุก 60 วินาที
- อัตราการสุ่มตัวอย่างที่สูงขึ้นอาจช่วยให้ผู้ใช้เห็นข้อมูลสุขภาพและการออกกำลังกายของตนเองได้ละเอียดยิ่งขึ้น ความถี่ของอัตราการสุ่มตัวอย่างควรมีความสมดุลระหว่างรายละเอียดและประสิทธิภาพ
หลักเกณฑ์เพิ่มเติม
เมื่อเขียนข้อมูล ให้ทำตามหลักเกณฑ์ต่อไปนี้
- ในการซิงค์แต่ละครั้ง ให้เขียนเฉพาะข้อมูลใหม่และข้อมูลที่อัปเดตซึ่งมีการแก้ไขตั้งแต่ การซิงค์ครั้งล่าสุด
- แบ่งคำขอเป็นกลุ่มๆ โดยมีระเบียนไม่เกิน 1,000 รายการต่อคำขอเขียน
- จำกัดไม่ให้งานทำงานได้เฉพาะเมื่ออุปกรณ์ไม่ได้ใช้งานและแบตเตอรี่ไม่เหลือน้อย
- สำหรับงานในเบื้องหลัง ให้ใช้ WorkManager เพื่อกำหนดเวลางานเป็นระยะ โดยมีระยะเวลาสูงสุด 15 นาที
โค้ดต่อไปนี้ใช้ WorkManager เพื่อกำหนดเวลางานในเบื้องหลังเป็นระยะ โดยมี
ระยะเวลาสูงสุด 15 นาที และช่วงเวลาที่ยืดหยุ่น 5 นาที การกำหนดค่านี้ตั้งค่าโดยใช้คลาส PeriodicWorkRequest.Builder
val constraints = Constraints.Builder()
.requiresBatteryNotLow()
.requiresDeviceIdle(true)
.build()
val writeDataWork = PeriodicWorkRequestBuilder<WriteDataToHealthConnectWorker>(
15,
TimeUnit.MINUTES,
5,
TimeUnit.MINUTES
)
.setConstraints(constraints)
.build()
การติดตามที่ใช้งานอยู่
ซึ่งรวมถึงแอปที่ทำการติดตามตามเหตุการณ์ เช่น การออกกำลังกายและการนอนหลับ หรือข้อมูลจากผู้ใช้ด้วยตนเอง เช่น โภชนาการ ระบบจะสร้างบันทึกเหล่านี้เมื่อแอป อยู่ในเบื้องหน้า หรือในเหตุการณ์ที่เกิดขึ้นไม่บ่อยนักซึ่งมีการใช้งานแอป 2-3 ครั้งต่อวัน
ตรวจสอบว่าแอปไม่ได้เปิด Health Connect ไว้ตลอด ระยะเวลาของกิจกรรม
ต้องเขียนข้อมูลไปยัง Health Connect ด้วยวิธีใดวิธีหนึ่งใน 2 วิธีต่อไปนี้
- ซิงค์ข้อมูลกับ Health Connect หลังจากกิจกรรมเสร็จสมบูรณ์ เช่น ซิงค์ ข้อมูลเมื่อผู้ใช้สิ้นสุดเซสชันการออกกำลังกายที่ติดตาม
- กำหนดเวลางานแบบครั้งเดียวโดยใช้
WorkManagerเพื่อซิงค์ข้อมูลในภายหลัง
แนวทางปฏิบัติแนะนำสำหรับระดับความละเอียดและความถี่ในการเขียน
เมื่อเขียนข้อมูลไปยัง Health Connect ให้ใช้ความละเอียดที่เหมาะสม การใช้ความละเอียดที่เหมาะสมจะช่วยลดภาระการจัดเก็บข้อมูล ในขณะที่ยังคงรักษาข้อมูลให้สอดคล้องและแม่นยำ ความละเอียดของข้อมูลครอบคลุม 2 สิ่งต่อไปนี้
ความถี่ในการเขียน: ความถี่ที่แอปพลิเคชันของคุณพุชข้อมูลใหม่ไปยัง Health Connect เขียนข้อมูลบ่อยที่สุดเท่าที่จะทำได้เมื่อมีข้อมูลใหม่ พร้อมใช้งาน โดยคำนึงถึงประสิทธิภาพของอุปกรณ์ เพื่อไม่ให้ส่งผลเสียต่ออายุการใช้งานแบตเตอรี่และประสิทธิภาพด้านอื่นๆ ช่วงเวลาสูงสุด ระหว่างการเขียนควรอยู่ที่ 15 นาที
ระดับความละเอียดของข้อมูลที่เขียน: ความถี่ในการสุ่มตัวอย่างข้อมูลที่พุชเข้ามา เช่น เขียนตัวอย่างอัตราการเต้นของหัวใจทุกๆ 5 วินาที ข้อมูลบางประเภท ไม่จำเป็นต้องมีอัตราการสุ่มตัวอย่างเดียวกัน การอัปเดตข้อมูลจำนวนก้าวทุกวินาทีแทบไม่มีประโยชน์ เมื่อเทียบกับการอัปเดตที่ถี่น้อยกว่า เช่น ทุก 60 วินาที อย่างไรก็ตาม อัตราการสุ่มตัวอย่างที่สูงขึ้นอาจช่วยให้ผู้ใช้เห็นข้อมูลสุขภาพและการออกกำลังกายของตนเองได้ละเอียดและละเอียดยิ่งขึ้น ความถี่ของอัตราการสุ่มตัวอย่างควรสร้างสมดุลระหว่างรายละเอียดและประสิทธิภาพ
สร้างโครงสร้างระเบียนสำหรับข้อมูลซีรีส์
สำหรับประเภทข้อมูลที่ใช้ชุดตัวอย่าง เช่น HeartRateRecord คุณควรจัดโครงสร้างระเบียนให้ถูกต้อง แทนที่จะสร้างบันทึกเดียวที่ยาวตลอดทั้งวันและอัปเดตอยู่ตลอดเวลา คุณควรสร้างบันทึกขนาดเล็กหลายรายการ โดยแต่ละรายการแสดงช่วงเวลาที่เฉพาะเจาะจง
เช่น สำหรับข้อมูลอัตราการเต้นของหัวใจ คุณควรสร้าง HeartRateRecord ใหม่
ทุกนาที แต่ละระเบียนจะมีเวลาเริ่มต้นและเวลาสิ้นสุดที่ครอบคลุมนาทีนั้นๆ และจะมีตัวอย่างอัตราการเต้นของหัวใจทั้งหมดที่บันทึกไว้ในนาทีนั้นๆ
ในระหว่างการซิงค์กับ Health Connect เป็นประจำ (เช่น ทุก 15 นาที) แอปของคุณควรเขียนบันทึก 1 นาทีทั้งหมดที่สร้างขึ้นตั้งแต่การซิงค์ครั้งก่อน ซึ่งจะช่วยให้บันทึกมีขนาดที่จัดการได้และปรับปรุง ประสิทธิภาพของการค้นหาและการประมวลผลข้อมูล
ตัวอย่างต่อไปนี้แสดงวิธีสร้าง HeartRateRecord เป็นเวลา 1 นาที
ซึ่งมีตัวอย่างหลายรายการ
val startTime = Instant.now().truncatedTo(ChronoUnit.MINUTES) val endTime = startTime.plus(Duration.ofMinutes(1)) val heartRateRecord = HeartRateRecord( startTime = startTime, startZoneOffset = ZoneOffset.UTC, endTime = endTime, endZoneOffset = ZoneOffset.UTC, // Create a new record every minute, containing a list of samples. samples = listOf( HeartRateRecord.Sample( time = startTime + Duration.ofSeconds(15), beatsPerMinute = 80, ), HeartRateRecord.Sample( time = startTime + Duration.ofSeconds(30), beatsPerMinute = 82, ), HeartRateRecord.Sample( time = startTime + Duration.ofSeconds(45), beatsPerMinute = 85, ) ), metadata = Metadata( device = Device(type = Device.TYPE_WATCH) ))
เขียนข้อมูลที่ตรวจสอบตลอดทั้งวัน
สำหรับข้อมูลที่รวบรวมอย่างต่อเนื่อง เช่น จำนวนก้าว แอปพลิเคชันควร เขียนข้อมูลลงใน Health Connect บ่อยที่สุดเท่าที่จะเป็นไปได้เมื่อมีข้อมูลใหม่ เพื่อหลีกเลี่ยงผลกระทบด้านลบต่ออายุการใช้งานแบตเตอรี่และประสิทธิภาพด้านอื่นๆ ช่วงเวลาสูงสุดระหว่างการเขียนควรอยู่ที่ 15 นาที
ประเภทข้อมูล |
หน่วย |
คาดการณ์ |
ตัวอย่าง |
ขั้นตอน |
ขั้นตอน |
ทุกๆ 1 นาที |
23:14 - 23:15 - 5 ขั้นตอน 23:16 - 23:17 - 22 ขั้นตอน 23:17 - 23:18 - 8 ขั้นตอน |
StepsCadence |
ก้าว/นาที |
ทุกๆ 1 นาที |
23:14 - 23:15 - 5 spm 23:16 - 23:17 - 22 spm 23:17 - 23:18 - 8 spm |
การทำวีลแชร์พุช |
พุช |
ทุกๆ 1 นาที |
23:14 - 23:15 - 5 ครั้ง 23:16 - 23:17 - 22 ครั้ง 23:17 - 23:18 - 8 pushes |
ActiveCaloriesBurned |
แคลอรี่ |
ทุก 15 นาที |
23:15 - 23:30 - 2 แคลอรี่ 23:30 - 23:45 - 25 แคลอรี่ 23:45 - 00:00 - 5 แคลอรี่ |
TotalCaloriesBurned |
แคลอรี่ |
ทุก 15 นาที |
23:15 - 23:30 - 16 แคลอรี่ 23:30 - 23:45 - 16 แคลอรี่ 23:45 - 00:00 - 16 แคลอรี่ |
ระยะทาง |
กม./นาที |
ทุกๆ 1 นาที |
23:14-23:15 - 0.008 กม. 23:16 - 23:16 - 0.021 กม. 23:17 - 23:18 - 0.012 กม. |
ElevationGained |
ม. |
ทุกๆ 1 นาที |
20:36 - 20:37 - 3.048 ม. 20:39 - 20:40 - 3.048 ม. 23:23 - 23:24 - 9.144m |
จำนวนชั้นที่เดินขึ้น |
ชั้น |
ทุกๆ 1 นาที |
23:14 - 23:15 - 5 ชั้น 23:16 - 23:16 - 22 ชั้น 23:17 - 23:18 - 8 ชั้น |
HeartRate |
bpm |
4 ครั้งต่อนาที |
06:11:15 น. - 55 bpm 06:11:30 น. - 56 bpm 06:11:45 - 56 bpm 06:12:00 น. - 55 bpm |
HeartRateVariabilityRmssd |
มิลลิวินาที |
ทุกๆ 1 นาที |
06:11 น. - 23 มิลลิวินาที |
RespiratoryRate |
ครั้ง/นาที |
ทุกๆ 1 นาที |
23:14 - 23:15 - 60 ครั้ง/นาที 23:16 - 23:16 - 62 ครั้ง/นาที 23:17 - 23:18 - 64 ครั้ง/นาที |
ความอิ่มตัวของออกซิเจน |
% |
ทุกๆ 1 ชั่วโมง |
6:11 - 95.208% |
ควรเขียนข้อมูลลงใน Health Connect เมื่อสิ้นสุดการออกกำลังกายหรือเซสชันการนอนหลับ สำหรับการติดตามที่ใช้งานอยู่ เช่น การออกกำลังกายและการนอนหลับ หรือข้อมูลจากผู้ใช้ด้วยตนเอง เช่น โภชนาการ ระบบจะสร้างบันทึกเหล่านี้เมื่อแอปอยู่เบื้องหน้า หรือในกรณีที่พบได้ยากซึ่งมีการใช้งาน 2-3 ครั้งต่อวัน
ตรวจสอบว่าแอปไม่ได้เรียกใช้ Health Connect ตลอดระยะเวลาของกิจกรรม
ต้องเขียนข้อมูลไปยัง Health Connect ด้วยวิธีใดวิธีหนึ่งใน 2 วิธีต่อไปนี้
- ซิงค์ข้อมูลกับ Health Connect หลังจากกิจกรรมเสร็จสมบูรณ์ เช่น ซิงค์ ข้อมูลเมื่อผู้ใช้สิ้นสุดเซสชันการออกกำลังกายที่ติดตาม
- ตั้งเวลางานแบบครั้งเดียวโดยใช้ WorkManager เพื่อซิงค์ข้อมูลในภายหลัง
เซสชันการออกกำลังกายและการนอนหลับ
อย่างน้อยที่สุด แอปพลิเคชันของคุณควรปฏิบัติตามคำแนะนำในคอลัมน์คาดการณ์ ในตารางที่ 2 หากเป็นไปได้ ให้ทำตามคำแนะนำในคอลัมน์ดีที่สุด
ตารางต่อไปนี้แสดงวิธีเขียนข้อมูลขณะออกกำลังกาย
ประเภทข้อมูล |
หน่วย |
คาดการณ์ |
ขอแสดงความนับถือ |
ตัวอย่าง |
ขั้นตอน |
ขั้นตอน |
ทุกๆ 1 นาที |
ทุกๆ 1 วินาที |
23:14-23:15 - 5 ขั้นตอน 23:16 - 23:17 - 22 ขั้นตอน 23:17 - 23:18 - 8 ขั้นตอน |
StepsCadence |
ก้าว/นาที |
ทุกๆ 1 นาที |
ทุกๆ 1 วินาที |
23:14-23:15 - 35 spm 23:16 - 23:17 - 37 spm 23:17 - 23:18 - 40 spm |
การทำวีลแชร์พุช |
พุช |
ทุกๆ 1 นาที |
ทุกๆ 1 วินาที |
23:14-23:15 - 5 ครั้ง 23:16 - 23:17 - 22 pushes 23:17 - 23:18 - 8 pushes |
CyclingPedalingCadence |
rpm |
ทุกๆ 1 นาที |
ทุกๆ 1 วินาที |
23:14-23:15 - 65 รอบต่อนาที 23:16 - 23:17 - 70 รอบต่อนาที 23:17 - 23:18 - 68 รอบต่อนาที |
กำลังไฟ |
วัตต์ |
ทุกๆ 1 นาที |
ทุกๆ 1 วินาที |
23:14-23:15 - 250 วัตต์ 23:16 - 23:17 - 255 วัตต์ 23:17 - 23:18 - 245 วัตต์ |
ความเร็ว |
กม./นาที |
ทุกๆ 1 นาที |
ทุกๆ 1 วินาที |
23:14-23:15 - 0.3 กม./นาที 23:16 - 23:17 - 0.4 กม./นาที 23:17 - 23:18 -0.4 กม./นาที |
ระยะทาง |
กม./ม. |
ทุกๆ 1 นาที |
ทุกๆ 1 วินาที |
23:14-23:15 - 0.008 กม. 23:16 - 23:16 - 0.021 กม. 23:17 - 23:18 - 0.012 กม. |
ActiveCaloriesBurned |
แคลอรี่ |
ทุกๆ 1 นาที |
ทุกๆ 1 วินาที |
23:14-23:15 - 20 แคลอรี่ 23:16 - 23:17 - 20 แคลอรี่ 23:17 - 23:18 - 25 แคลอรี่ |
TotalCaloriesBurned |
แคลอรี่ |
ทุกๆ 1 นาที |
ทุกๆ 1 วินาที |
23:14-23:15 - 36 แคลอรี่ 23:16 - 23:17 - 36 แคลอรี่ 23:17 - 23:18 - 41 แคลอรี่ |
ElevationGained |
ม. |
ทุกๆ 1 นาที |
ทุกๆ 1 วินาที |
20:36 - 20:37 - 3.048 ม. 20:39 - 20:40 - 3.048 ม. 23:23 - 23:24 - 9.144m |
ExerciseRoutes |
lat/lng/alt |
ทุก 3-5 วินาที |
ทุกๆ 1 วินาที |
|
HeartRate |
bpm |
4 ครั้งต่อนาที |
ทุกๆ 1 วินาที |
23:14-23:15 - 150 bpm |
ตารางที่ 3 แสดงวิธีเขียนข้อมูลในระหว่างหรือหลังเซสชันการนอนหลับ
ประเภทข้อมูล |
หน่วย |
ตัวอย่างที่คาดไว้ |
ตัวอย่าง |
การแบ่งระยะการนอนหลับ |
เก็บพักไว้ |
ระยะเวลาแบบละเอียดต่อระยะการนอนหลับ |
23:46 - 23:50 - ตื่น 23:50 - 23:56 - หลับตื้น 23:56 - 00:16 - หลับลึก |
RestingHeartRate |
bpm |
ค่ารายวันเดียว (คาดว่าจะได้รับในตอนเช้า) |
06:11 น. - 60 bpm |
ความอิ่มตัวของออกซิเจน |
% |
ค่ารายวันเดียว (คาดว่าจะได้รับในตอนเช้า) |
6:11 - 95.208% |
มหกรรมกีฬา
แนวทางนี้ใช้โครงสร้างและประเภทข้อมูลที่มีอยู่ และจะตรวจสอบ ความเข้ากันได้กับการติดตั้งใช้งาน Health Connect และเครื่องมืออ่านข้อมูลในปัจจุบัน ซึ่งเป็นแนวทางที่แพลตฟอร์มฟิตเนสใช้กันโดยทั่วไป
นอกจากนี้ เซสชันแต่ละรายการ เช่น การว่ายน้ำ การปั่นจักรยาน และการวิ่ง จะไม่ได้ลิงก์โดยค่าเริ่มต้นภายใน Health Connect และโปรแกรมอ่านข้อมูลต้องอนุมานความสัมพันธ์ระหว่างเซสชันเหล่านี้ตามความใกล้เคียงของเวลา การเปลี่ยนผ่านระหว่างเซ็กเมนต์ เช่น จากว่ายน้ำไปปั่นจักรยาน จะไม่แสดงอย่างชัดเจน
ตัวอย่างต่อไปนี้แสดงวิธีเขียนข้อมูลสำหรับการแข่งขันไตรกีฬา
val swimStartTime = Instant.parse("2024-08-22T08:00:00Z") val swimEndTime = Instant.parse("2024-08-22T08:30:00Z") val bikeStartTime = Instant.parse("2024-08-22T08:40:00Z") val bikeEndTime = Instant.parse("2024-08-22T09:40:00Z") val runStartTime = Instant.parse("2024-08-22T09:50:00Z") val runEndTime = Instant.parse("2024-08-22T10:20:00Z") val swimSession = ExerciseSessionRecord( startTime = swimStartTime, endTime = swimEndTime, exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_SWIMMING_OPEN_WATER, metadata = Metadata( device = Device(type = Device.TYPE_WATCH) ), startZoneOffset = null, endZoneOffset = null, ) val bikeSession = ExerciseSessionRecord( startTime = bikeStartTime, endTime = bikeEndTime, exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_BIKING, metadata = Metadata( device = Device(type = Device.TYPE_WATCH) ), startZoneOffset = null, endZoneOffset = null, ) val runSession = ExerciseSessionRecord( startTime = runStartTime, endTime = runEndTime, exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_RUNNING, metadata = Metadata( device = Device(type = Device.TYPE_WATCH) ), startZoneOffset = null, endZoneOffset = null, ) healthConnectClient.insertRecords(listOf(swimSession, bikeSession, runSession))
จัดการข้อยกเว้น
Health Connect จะแสดงข้อยกเว้นมาตรฐานสำหรับการดำเนินการ CRUD เมื่อพบปัญหา แอปของคุณควรตรวจจับและจัดการข้อยกเว้นแต่ละรายการเหล่านี้ตามความเหมาะสม
แต่ละเมธอดใน HealthConnectClient จะแสดงข้อยกเว้นที่อาจเกิดขึ้น
โดยทั่วไปแล้ว แอปควรจัดการข้อยกเว้นต่อไปนี้
| ข้อยกเว้น | คำอธิบาย | แนวทางปฏิบัติแนะนำ |
|---|---|---|
IllegalStateException
| เกิดสถานการณ์ใดสถานการณ์หนึ่งต่อไปนี้
| จัดการปัญหาที่อาจเกิดขึ้นกับอินพุตก่อนที่จะส่งคำขอ ควรกำหนดค่าให้กับตัวแปรหรือใช้เป็นพารามิเตอร์ภายในฟังก์ชันที่กำหนดเองแทนการใช้ในคำขอโดยตรง เพื่อให้คุณใช้กลยุทธ์การจัดการข้อผิดพลาดได้ |
IOException
| พบปัญหาในการอ่านและเขียนข้อมูลจาก ดิสก์ | คำแนะนำต่อไปนี้จะช่วยให้คุณหลีกเลี่ยงปัญหานี้ได้
|
RemoteException
| เกิดข้อผิดพลาดภายในหรือในการสื่อสาร
กับบริการพื้นฐานที่ SDK เชื่อมต่อ เช่น แอปของคุณพยายามลบระเบียนที่มี uid ที่ระบุ อย่างไรก็ตาม ระบบจะส่งข้อยกเว้น
หลังจากที่แอปพบว่าไม่มีบันทึก
เมื่อเช็คอินบริการพื้นฐาน
| คำแนะนำต่อไปนี้จะช่วยให้คุณหลีกเลี่ยงปัญหานี้ได้
|
SecurityException
| มีปัญหาเกิดขึ้นเมื่อคำขอต้องใช้สิทธิ์ที่ไม่ได้ให้ไว้ | หากต้องการหลีกเลี่ยงปัญหานี้ โปรดตรวจสอบว่าคุณได้ประกาศการใช้ประเภทข้อมูล Health Connect สำหรับแอปที่เผยแพร่แล้ว นอกจากนี้ คุณต้องประกาศสิทธิ์ของ Health Connect ในไฟล์ Manifest และในกิจกรรมของคุณ |