เขียนข้อมูล

คู่มือนี้ใช้ได้กับ Health Connect เวอร์ชัน 1.1.0-alpha12

คู่มือนี้ครอบคลุมกระบวนการเขียนหรืออัปเดตข้อมูลใน 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 สิ่งต่อไปนี้

  1. ความถี่ในการเขียน: ความถี่ที่แอปพลิเคชันของคุณพุชข้อมูลใหม่ไปยัง Health Connect เขียนข้อมูลบ่อยที่สุดเท่าที่จะทำได้เมื่อมีข้อมูลใหม่ พร้อมใช้งาน โดยคำนึงถึงประสิทธิภาพของอุปกรณ์ เพื่อไม่ให้ส่งผลเสียต่ออายุการใช้งานแบตเตอรี่และประสิทธิภาพด้านอื่นๆ ช่วงเวลาสูงสุด ระหว่างการเขียนควรอยู่ที่ 15 นาที

  2. ระดับความละเอียดของข้อมูลที่เขียน: ความถี่ในการสุ่มตัวอย่างข้อมูลที่พุชเข้ามา เช่น เขียนตัวอย่างอัตราการเต้นของหัวใจทุกๆ 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: คำแนะนำในการเขียนข้อมูล

ประเภทข้อมูล

หน่วย

คาดการณ์

ตัวอย่าง

จำนวนก้าว

จำนวนก้าว

ทุกๆ 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 หากเป็นไปได้ ให้ทำตามคำแนะนำในคอลัมน์ดีที่สุด

ตารางต่อไปนี้แสดงวิธีเขียนข้อมูลระหว่างการออกกำลังกาย

ตารางที่ 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 แสดงวิธีเขียนข้อมูลในระหว่างหรือหลังเซสชันการนอนหลับ

ตารางที่ 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 จะแสดงข้อยกเว้นที่อาจเกิดขึ้น โดยทั่วไปแล้ว แอปควรจัดการข้อยกเว้นต่อไปนี้

ตารางที่ 1: ข้อยกเว้นของ Health Connect และแนวทางปฏิบัติแนะนำ
ข้อยกเว้น คำอธิบาย แนวทางปฏิบัติแนะนำ
IllegalStateException เกิดสถานการณ์ใดสถานการณ์หนึ่งต่อไปนี้

  • บริการ Health Connect ไม่พร้อมใช้งาน
  • คำขอไม่ใช่โครงสร้างที่ถูกต้อง เช่น คำขอแบบรวมใน ที่เก็บข้อมูลเป็นระยะๆ ซึ่งใช้Instantออบเจ็กต์สำหรับtimeRangeFilter

จัดการปัญหาที่อาจเกิดขึ้นกับอินพุตก่อนที่จะส่งคำขอ ควรกำหนดค่าให้กับตัวแปรหรือใช้เป็นพารามิเตอร์ภายในฟังก์ชันที่กำหนดเองแทนการใช้ในคำขอโดยตรง เพื่อให้คุณใช้กลยุทธ์การจัดการข้อผิดพลาดได้
IOException มีปัญหาเกิดขึ้นเมื่ออ่านและเขียนข้อมูลจาก ดิสก์ คำแนะนำต่อไปนี้จะช่วยให้คุณหลีกเลี่ยงปัญหานี้ได้

  • สำรองข้อมูลที่ผู้ใช้ป้อน
  • สามารถจัดการปัญหาที่เกิดขึ้นระหว่างการดำเนินการเขียนแบบกลุ่ม เช่น ตรวจสอบว่ากระบวนการดำเนินการต่อจากปัญหาและดำเนินการที่เหลือ
  • ใช้กลยุทธ์การลองใหม่และการหยุดชั่วคราวเพื่อจัดการปัญหาคำขอ

RemoteException เกิดข้อผิดพลาดภายในหรือในการสื่อสาร กับบริการพื้นฐานที่ SDK เชื่อมต่อ

เช่น แอปของคุณพยายามลบระเบียนที่มี uid ที่ระบุ อย่างไรก็ตาม ระบบจะส่งข้อยกเว้น หลังจากที่แอปพบว่าไม่มีบันทึก เมื่อตรวจสอบบริการพื้นฐาน
คำแนะนำต่อไปนี้จะช่วยให้คุณหลีกเลี่ยงปัญหานี้ได้

  • ซิงค์ที่เก็บข้อมูลของแอปกับ Health Connect เป็นประจำ
  • ใช้กลยุทธ์การลองใหม่และการหยุดชั่วคราวเพื่อจัดการปัญหาคำขอ

SecurityException มีปัญหาเกิดขึ้นเมื่อคำขอต้องใช้สิทธิ์ที่ไม่ได้ให้ไว้ หากต้องการหลีกเลี่ยงปัญหานี้ โปรดตรวจสอบว่าคุณได้ประกาศการใช้ประเภทข้อมูล Health Connect สำหรับแอปที่เผยแพร่แล้ว นอกจากนี้ คุณต้องประกาศสิทธิ์ของ Health Connect ในไฟล์ Manifest และในกิจกรรมของคุณ