คู่มือนี้ใช้ได้กับ 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) ))
ขอสิทธิ์จากผู้ใช้
หลังจากสร้างอินสแตนซ์ไคลเอ็นต์แล้ว แอปของคุณต้องขอสิทธิ์จากผู้ใช้ ผู้ใช้ต้องได้รับอนุญาตให้ให้หรือปฏิเสธสิทธิ์ได้ทุกเมื่อ โดยให้สร้างชุดสิทธิ์สำหรับประเภทข้อมูลที่จำเป็น ตรวจสอบว่าได้ประกาศสิทธิ์ในชุดดังกล่าวใน Android manifest ก่อน
val permissions = setOf( HealthPermission.getReadPermission(HeartRateRecord::class), HealthPermission.getWritePermission(HeartRateRecord::class), HealthPermission.getReadPermission(StepsRecord::class), HealthPermission.getWritePermission(StepsRecord::class) )
getGrantedPermissions
เพื่อดูว่าแอปของคุณได้รับสิทธิ์ที่จำเป็นแล้วหรือไม่ หากไม่มี ให้ใช้
createRequestPermissionResultContract
เพื่อขอสิทธิ์เหล่านั้น ซึ่งจะแสดงหน้าจอขอสิทธิ์ของ Health Connect
val permissions = setOf( HealthPermission.getReadPermission(StepsRecord::class), HealthPermission.getWritePermission(StepsRecord::class), HealthPermission.getReadPermission(HeartRateRecord::class), HealthPermission.getWritePermission(HeartRateRecord::class) ) val requestPermissionsLauncher = rememberLauncherForActivityResult( contract = PermissionController.createRequestPermissionResultContract() ) { grantedPermissions -> if (grantedPermissions.containsAll(permissions)) { coroutineScope.launch { snackbarHostState.showSnackbar("Permissions granted!") } } else { coroutineScope.launch { snackbarHostState.showSnackbar("Permissions denied.") } } }
เขียนข้อมูล
เวิร์กโฟลว์ทั่วไปอย่างหนึ่งใน 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 แต่ละรายการจะมีรหัสที่ไม่ซ้ำกันซึ่งเชื่อมโยงอยู่
เพื่อใช้เป็นข้อมูลอ้างอิงในที่เก็บข้อมูลแอป
แอปของคุณระบุค่านี้ |
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 ในข้อมูลที่ดึงมาจาก ที่เก็บข้อมูลของแอป
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 ด้วยวิธีใดวิธีหนึ่งต่อไปนี้
- ซิงค์ข้อมูลกับ 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 pushes 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.048m 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 ด้วยวิธีใดวิธีหนึ่งต่อไปนี้
- ซิงค์ข้อมูลกับ 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.048m 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 - หลับลึก |
อัตราการเต้นของหัวใจขณะพัก |
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 และในกิจกรรมของคุณ |