คู่มือนี้ครอบคลุมกระบวนการเขียนหรืออัปเดตข้อมูลใน Health Connect
จัดการค่า 0
ข้อมูลบางประเภท เช่น จำนวนก้าว ระยะทาง หรือแคลอรี อาจมีค่าเป็น 0
ให้เขียนค่าเป็น 0 เฉพาะเมื่อไม่มีการใช้งานจริงขณะที่ผู้ใช้สวมอุปกรณ์
 อย่าเขียนค่าเป็น 0 หากไม่ได้สวมอุปกรณ์ ข้อมูล
ขาดหายไป หรือแบตเตอรี่หมด ในกรณีเช่นนี้ ให้ละเว้นระเบียนเพื่อหลีกเลี่ยงข้อมูลที่ทำให้เข้าใจผิด
ตั้งค่าโครงสร้างข้อมูล
ก่อนที่จะเขียนข้อมูล เราต้องตั้งค่าระเบียนก่อน สำหรับข้อมูลมากกว่า 50 ประเภท แต่ละประเภทจะมีโครงสร้างของตัวเอง ดูรายละเอียดเพิ่มเติมเกี่ยวกับประเภทข้อมูลที่ใช้ได้ในข้อมูลอ้างอิง Jetpack
บันทึกพื้นฐาน
ประเภทข้อมูลจำนวนก้าวใน Health Connect จะบันทึกจำนวนก้าวที่ผู้ใช้เดินระหว่างการอ่าน จำนวนก้าวเป็นหน่วยวัดทั่วไป ในแพลตฟอร์มสุขภาพ การออกกำลังกาย และสุขภาวะ
ตัวอย่างต่อไปนี้แสดงวิธีตั้งค่าข้อมูลจำนวนก้าว
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)
    )
)
บันทึกที่มีหน่วยวัด
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.manualEntry(
        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.autoRecorded(
        device = Device(type = Device.TYPE_WATCH)
    ))
ขอสิทธิ์จากผู้ใช้
หลังจากสร้างอินสแตนซ์ไคลเอ็นต์แล้ว แอปของคุณต้องขอสิทธิ์จากผู้ใช้ ผู้ใช้ต้องได้รับอนุญาตให้ให้สิทธิ์หรือปฏิเสธสิทธิ์ได้ทุกเมื่อ
โดยให้สร้างชุดสิทธิ์สำหรับประเภทข้อมูลที่จำเป็น ตรวจสอบว่าได้ประกาศสิทธิ์ในชุดไว้ใน Android manifest ก่อน
// 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
ตัวอย่างต่อไปนี้แสดงวิธีเขียนข้อมูลการแทรกจำนวนก้าว
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
    }
}
อัปเดตข้อมูล
หากต้องการเปลี่ยนระเบียนอย่างน้อย 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() : 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
    }
}
หลังจากนั้น คุณจะเรียกใช้ฟังก์ชันเหล่านี้ในเทรดหลักได้
upsertSteps(healthConnectClient, pullStepsFromDatastore())
ตรวจสอบค่าในเวอร์ชันบันทึกของไคลเอ็นต์
หากกระบวนการแทรก/อัปเดตข้อมูลมี 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.manualEntry(
        clientRecordId = "Your supplied record ID",
        clientRecordVersion = 0L, // Your supplied record version
        device = Device(type = Device.TYPE_WATCH)
    )
)
Upsert จะไม่เพิ่ม version โดยอัตโนมัติเมื่อมีการเปลี่ยนแปลง
เพื่อป้องกันไม่ให้มีการเขียนทับข้อมูลโดยไม่คาดคิด ดังนั้นคุณจึงต้อง
ระบุค่าที่สูงขึ้นด้วยตนเอง
คำแนะนำทั่วไป
แอปต้องเขียนเฉพาะข้อมูลที่มาจากแหล่งที่มาของตัวเองไปยัง Health Connect
หากมีการนำเข้าข้อมูลในแอปจากแอปอื่น ความรับผิดชอบ จะตกอยู่กับแอปอื่นในการเขียนข้อมูลของตัวเองลงใน Health Connect
นอกจากนี้ คุณควรใช้ตรรกะที่จัดการข้อยกเว้นในการเขียน เช่น ข้อมูลอยู่นอกขอบเขต หรือข้อผิดพลาดของระบบภายใน คุณสามารถใช้ กลยุทธ์การหยุดชั่วคราวและลองอีกครั้งกับกลไกการตั้งเวลางานได้ หากการเขียนข้อมูลลงใน Health Connect ไม่สำเร็จในท้ายที่สุด ให้ตรวจสอบว่าแอปของคุณสามารถดำเนินการต่อจากจุดส่งออกนั้นได้ อย่าลืมบันทึกและรายงานข้อผิดพลาดเพื่อช่วยในการวินิจฉัย
เมื่อติดตามข้อมูล มีคำแนะนำ 2 ข้อที่คุณทำตามได้ ขึ้นอยู่กับวิธีที่แอปเขียนข้อมูล
การจัดการเขตเวลา
เมื่อเขียนบันทึกตามเวลา ให้หลีกเลี่ยงการตั้งค่าออฟเซ็ตเป็น zoneOffset.UTC
โดยค่าเริ่มต้น เนื่องจากอาจทำให้การประทับเวลาไม่ถูกต้องเมื่อผู้ใช้อยู่ใน
เขตเวลาอื่น ให้คำนวณออฟเซ็ตตามตำแหน่งจริงของอุปกรณ์แทน คุณเรียกเขตเวลาของอุปกรณ์ได้โดยใช้
ZoneId.systemDefault()
val endTime = Instant.now()
val startTime = endTime.minus(java.time.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(java.time.Duration.ofMinutes(minutesBetweenSamples)),
        startZoneOffset = zoneOffset,
        endTime = sampleTime,
        endZoneOffset = zoneOffset,
        count = Random.nextLong(1, 100),
        metadata = Metadata.unknownRecordingMethod(),
    )
    sampleTime = sampleTime.plus(java.time.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.autoRecorded(
        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 ครั้ง | 
| 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.144 ม. | 
| จำนวนชั้นที่เดินขึ้น | ชั้น | ทุกๆ 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 ครั้ง | 
| 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.144 ม. | 
| 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.autoRecorded(
      device = Device(type = Device.TYPE_WATCH)
    )
)
val bikeSession = ExerciseSessionRecord(
    startTime = bikeStartTime,
    endTime = bikeEndTime,
    exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_BIKING,
    metadata = Metadata.autoRecorded(
      device = Device(type = Device.TYPE_WATCH)
    )
)
val runSession = ExerciseSessionRecord(
    startTime = runStartTime,
    endTime = runEndTime,
    exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_RUNNING,
    metadata = Metadata.autoRecorded(
      device = Device(type = Device.TYPE_WATCH)
    )
)
healthConnectClient.insertRecords(listOf(swimSession, bikeSession, runSession))
จัดการข้อยกเว้น
Health Connect จะส่งข้อยกเว้นมาตรฐานสำหรับการดำเนินการ CRUD เมื่อพบปัญหา แอปของคุณควรตรวจจับและจัดการข้อยกเว้นแต่ละรายการเหล่านี้ตามความเหมาะสม
แต่ละเมธอดใน HealthConnectClient จะแสดงข้อยกเว้นที่อาจเกิดขึ้น
โดยทั่วไปแล้ว แอปควรจัดการข้อยกเว้นต่อไปนี้
| ข้อยกเว้น | คำอธิบาย | แนวทางปฏิบัติแนะนำ | 
|---|---|---|
| IllegalStateException | เกิดสถานการณ์ใดสถานการณ์หนึ่งต่อไปนี้ 
 | จัดการปัญหาที่อาจเกิดขึ้นกับอินพุตก่อนที่จะส่งคำขอ ควรกำหนดค่าให้กับตัวแปรหรือใช้เป็นพารามิเตอร์ภายในฟังก์ชันที่กำหนดเองแทนการใช้ในคำขอโดยตรง เพื่อให้คุณใช้กลยุทธ์การจัดการข้อผิดพลาดได้ | 
| IOException | มีปัญหาเกิดขึ้นเมื่ออ่านและเขียนข้อมูลจาก ดิสก์ | คำแนะนำต่อไปนี้จะช่วยให้คุณหลีกเลี่ยงปัญหานี้ได้ 
 | 
| RemoteException | เกิดข้อผิดพลาดภายในหรือในการสื่อสาร
กับบริการพื้นฐานที่ SDK เชื่อมต่อ เช่น แอปของคุณพยายามลบระเบียนที่มี uidที่ระบุ อย่างไรก็ตาม ระบบจะส่งข้อยกเว้น
หลังจากที่แอปพบว่าไม่มีบันทึก
เมื่อตรวจสอบบริการพื้นฐาน | คำแนะนำต่อไปนี้จะช่วยให้คุณหลีกเลี่ยงปัญหานี้ได้ 
 | 
| SecurityException | มีปัญหาเกิดขึ้นเมื่อคำขอต้องใช้สิทธิ์ที่ไม่ได้ให้ไว้ | หากต้องการหลีกเลี่ยงปัญหานี้ โปรดตรวจสอบว่าคุณได้ประกาศการใช้ประเภทข้อมูล Health Connect สำหรับแอปที่เผยแพร่แล้ว นอกจากนี้ คุณต้องประกาศสิทธิ์ของ Health Connect ในไฟล์ Manifest และในกิจกรรมของคุณ | 
