อ่านข้อมูลดิบ

ตัวอย่างต่อไปนี้แสดงวิธีอ่านข้อมูลดิบซึ่งเป็นส่วนหนึ่งของเวิร์กโฟลว์ทั่วไป

อ่านข้อมูล

Health Connect อนุญาตให้แอปอ่านข้อมูลจากที่เก็บข้อมูลเมื่อแอป ทำงานอยู่ในเบื้องหน้าและเบื้องหลัง

  • การอ่านในเบื้องหน้า: โดยปกติแล้ว คุณจะอ่านข้อมูลจาก Health Connect ได้เมื่อ แอปของคุณอยู่ในเบื้องหน้า ในกรณีเหล่านี้ คุณอาจพิจารณาใช้ บริการเบื้องหน้าเพื่อเรียกใช้การดำเนินการนี้ในกรณีที่ผู้ใช้หรือระบบวาง แอปของคุณไว้ในเบื้องหลังระหว่างการดำเนินการอ่าน

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

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

หากต้องการอ่านบันทึก ให้สร้าง ReadRecordsRequest และระบุ เมื่อโทรหา readRecords

ตัวอย่างต่อไปนี้แสดงวิธีอ่านข้อมูลจำนวนก้าวของผู้ใช้ภายใน ช่วงเวลาหนึ่ง ดูตัวอย่างเพิ่มเติมที่มี SensorManager ได้ในคู่มือข้อมูลจำนวนก้าว

val response = healthConnectClient.readRecords(
    ReadRecordsRequest(
        HeartRateRecord::class,
        timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
    )
)
response.records.forEach { record ->
    /* Process records */
}

นอกจากนี้ คุณยังอ่านข้อมูลในลักษณะที่รวบรวมได้โดยใช้ aggregate

suspend fun readStepsAggregate(startTime: Instant, endTime: Instant): Long {
    val response = healthConnectClient.aggregate(
        AggregateRequest(
            metrics = setOf(StepsRecord.COUNT_TOTAL),
            timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
        )
    )
    return response[StepsRecord.COUNT_TOTAL] ?: 0L
}

อ่านขั้นตอนบนอุปกรณ์เคลื่อนที่

ใน Android 14 (ระดับ API 34) และ SDK Extension เวอร์ชัน 20 ขึ้นไป Health Connect จะนับจำนวนก้าวในอุปกรณ์ หากแอปได้รับสิทธิ์ READ_STEPS Health Connect จะเริ่มบันทึกจำนวนก้าวจากอุปกรณ์ที่ใช้ Android และผู้ใช้จะเห็นข้อมูลจำนวนก้าวที่เพิ่มลงในรายการจำนวนก้าวของ Health Connect โดยอัตโนมัติ

หากต้องการตรวจสอบว่าการนับก้าวในอุปกรณ์พร้อมใช้งานหรือไม่ ให้ตรวจสอบว่าอุปกรณ์ ใช้ Android 14 (ระดับ API 34) และมี SDK Extension เวอร์ชัน 20 ขึ้นไป

val isStepTrackingAvailable =
    Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
        SdkExtensions.getExtensionVersion(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) >= 20

หากแอปอ่านจำนวนก้าวที่รวบรวมไว้โดยใช้ aggregate และไม่ได้กรองตาม DataOrigin ระบบจะรวมจำนวนก้าวในอุปกรณ์ไว้ในยอดรวมโดยอัตโนมัติ และไม่จำเป็นต้องทำการเปลี่ยนแปลงใดๆ สำหรับ การอัปเดตในเดือนมิถุนายน 2026

การเปลี่ยนแปลงการระบุแหล่งที่มาสำหรับขั้นตอนในอุปกรณ์

ตั้งแต่การอัปเดตเดือนมิถุนายน 2026 เป็นต้นไป ระบบจะระบุแหล่งที่มาของขั้นตอนที่ Health Connect ติดตามโดยกำเนิดเป็นชื่อแพ็กเกจสังเคราะห์ (SPN) เช่น com.android.healthconnect.phone.jd5bdd37e1a8d3667a05d0abebfc4a89e

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

SPN จะเฉพาะเจาะจงสำหรับอุปกรณ์และกำหนดขอบเขตตามแอปพลิเคชันเพื่อปกป้อง ความเป็นส่วนตัวของผู้ใช้

  • เสถียร: SPN สำหรับอุปกรณ์ปัจจุบันเสถียรสำหรับแอปพลิเคชันของคุณ
  • ระดับแอปพลิเคชัน: แอปพลิเคชันต่างๆ ในอุปกรณ์เดียวกันจะเห็น SPN ที่แตกต่างกันสำหรับข้อมูลจำนวนก้าวในอุปกรณ์

ค้นหาขั้นตอนในอุปกรณ์

เนื่องจาก SPN มีขอบเขตและเฉพาะเจาะจงสำหรับอุปกรณ์ คุณต้องไม่ฮาร์ดโค้ดค่า SPN แต่ให้ใช้ getCurrentDeviceDataSource() API เพื่อดึงข้อมูล SPN สำหรับอุปกรณ์ปัจจุบันแทน

แม้ว่าการนับก้าวในอุปกรณ์จะต้องใช้ SDK Extensions เวอร์ชัน 20 ขึ้นไป แต่ getCurrentDeviceDataSource() API จะพร้อมใช้งานใน Android 14 (ระดับ API 34) ที่มี SDK Extensions เวอร์ชัน 11 ขึ้นไป

getCurrentDeviceDataSource() API ยังไม่พร้อมใช้งานในไลบรารี Jetpack ของ Health Connect ตัวอย่างต่อไปนี้ใช้ Android Framework API แทน

import android.content.Context
import android.health.connect.HealthConnectManager

val healthConnectManager = context.getSystemService(HealthConnectManager::class.java)
val deviceDataSource = healthConnectManager?.getCurrentDeviceDataSource()
val currentDeviceSpn = deviceDataSource?.deviceDataOrigin?.packageName

หากแอปต้องอ่านจำนวนก้าวในอุปกรณ์ หรือหากแอปแสดงข้อมูลจำนวนก้าว ที่แยกตามแอปพลิเคชันหรืออุปกรณ์แหล่งที่มา คุณต้องค้นหาบันทึก ที่ DataOrigin เป็น android หรือ ตรงกับ SPN ของอุปกรณ์ หากแอปแสดงการระบุแหล่งที่มาสำหรับข้อมูลขั้นตอน ให้ใช้ metadata.device เพื่อระบุอุปกรณ์แหล่งที่มาสำหรับแต่ละระเบียน สำหรับขั้นตอนในอุปกรณ์ ที่ระบุโดย SPN ในข้อมูลรวม คุณสามารถใช้ข้อมูลเมตาของอุปกรณ์ เช่น model หรือ manufacturer จาก DeviceDataSource เพื่อการระบุแหล่งที่มา หรือใช้ ป้ายกำกับทั่วไป เช่น "โทรศัพท์ของคุณ" สำหรับขั้นตอนในอุปกรณ์

ตัวอย่างต่อไปนี้แสดงวิธีอ่านข้อมูลจำนวนก้าวที่รวบรวมไว้ในอุปกรณ์ โดยการกรองทั้ง android และ SPN ของอุปกรณ์ปัจจุบัน

import android.content.Context
import android.health.connect.HealthConnectManager
import android.os.Build
import android.os.ext.SdkExtensions
import androidx.health.connect.client.HealthConnectClient
import androidx.health.connect.client.records.StepsRecord
import androidx.health.connect.client.records.metadata.DataOrigin
import androidx.health.connect.client.request.AggregateRequest
import androidx.health.connect.client.time.TimeRangeFilter
import java.time.Instant

suspend fun readDeviceStepsByTimeRange(
    healthConnectClient: HealthConnectClient,
    context: Context,
    startTime: Instant,
    endTime: Instant
) {
    // 1. Check if SDK Extension 11+ is available for getCurrentDeviceDataSource()
    val isDataSourceApiAvailable = Build.VERSION.SDK_INT >= Build.VERSION_CODES.U &&
            SdkExtensions.getExtensionVersion(Build.VERSION_CODES.U) >= 11

    try {
        val healthConnectManager = context.getSystemService(HealthConnectManager::class.java)

        // 2. Safely fetch the package name only if API is available and data exists
        val currentDeviceSpn = if (isDataSourceApiAvailable) {
            healthConnectManager?.getCurrentDeviceDataSource()?.deviceDataOrigin?.packageName
        } else {
            null
        }

        val dataOriginFilters = mutableSetOf(DataOrigin("android"))

        // 3. Explicit null-safety check using .let
        currentDeviceSpn?.let {
            dataOriginFilters.add(DataOrigin(it))
        }

        val response = healthConnectClient.aggregate(
            AggregateRequest(
                metrics = setOf(StepsRecord.COUNT_TOTAL),
                timeRangeFilter = TimeRangeFilter.between(startTime, endTime),
                dataOriginFilter = dataOriginFilters
            )
        )

        val stepCount = response[StepsRecord.COUNT_TOTAL]

    } catch (e: Exception) {
        // Now this catch block only handles actual runtime exceptions, 
        // rather than Errors from missing methods.
    }
}

การนับก้าวในอุปกรณ์

  • การใช้เซ็นเซอร์: Health Connect ใช้เซ็นเซอร์ TYPE_STEP_COUNTER จาก SensorManager เซ็นเซอร์นี้ได้รับการเพิ่มประสิทธิภาพให้ใช้พลังงานต่ำ จึงเหมาะสําหรับ การติดตามจำนวนก้าวอย่างต่อเนื่องในเบื้องหลัง
  • ระดับความละเอียดของข้อมูล: โดยปกติแล้ว ระบบจะจัดกลุ่มข้อมูลจำนวนก้าวและเขียนลงในฐานข้อมูล Health Connect ไม่บ่อยกว่า 1 ครั้งต่อนาที เพื่อประหยัดแบตเตอรี่
  • การระบุแหล่งที่มา: ระบบจะระบุแหล่งที่มาของจำนวนก้าวที่ฟีเจอร์นี้บันทึกไว้ก่อนเดือนมิถุนายน 2026 ไปยังชื่อแพ็กเกจ android ใน DataOrigin หลังจากวันที่ดังกล่าว ระบบจะ ระบุแหล่งที่มาเป็น SPN เฉพาะอุปกรณ์ ดูการเปลี่ยนแปลงการระบุแหล่งที่มาสำหรับขั้นตอนในอุปกรณ์
  • การเปิดใช้งาน: กลไกการนับก้าวในอุปกรณ์จะทำงานก็ต่อเมื่อแอปพลิเคชันอย่างน้อย 1 รายการในอุปกรณ์ได้รับREAD_STEPS สิทธิ์ภายใน Health Connect

ตัวอย่างการอ่านในเบื้องหลัง

หากต้องการอ่านข้อมูลในเบื้องหลัง ให้ประกาศสิทธิ์ต่อไปนี้ในไฟล์ Manifest

<application>
  <uses-permission android:name="android.permission.health.READ_HEALTH_DATA_IN_BACKGROUND" />
...
</application>

ตัวอย่างต่อไปนี้แสดงวิธีอ่านข้อมูลจำนวนก้าวในเบื้องหลังสำหรับ ผู้ใช้ในช่วงเวลาหนึ่งๆ โดยใช้ WorkManager

class ScheduleWorker(appContext: Context, workerParams: WorkerParameters) :
    CoroutineWorker(appContext, workerParams) {

    override suspend fun doWork(): Result {
        val healthConnectClient = HealthConnectClient.getOrCreate(applicationContext)
        // Perform background read logic here
        return Result.success()
    }
}
fun enqueueBackgroundReadWorker(context: Context, healthConnectClient: HealthConnectClient) {
    if (healthConnectClient
            .features
            .getFeatureStatus(
                HealthConnectFeatures.FEATURE_READ_HEALTH_DATA_IN_BACKGROUND
            ) == HealthConnectFeatures.FEATURE_STATUS_AVAILABLE
    ) {

        val periodicWorkRequest = PeriodicWorkRequestBuilder<ScheduleWorker>(1, TimeUnit.HOURS)
            .build()

        WorkManager.getInstance(context).enqueueUniquePeriodicWork(
            "read_health_connect",
            ExistingPeriodicWorkPolicy.KEEP,
            periodicWorkRequest
        )
    }
}

พารามิเตอร์ ReadRecordsRequest มีค่าเริ่มต้น pageSize เป็น 1000 หากจำนวนระเบียนใน readResponse เดียวเกินpageSizeของคำขอ คุณต้องทำซ้ำ ในทุกหน้าของคำตอบเพื่อดึงข้อมูลระเบียนทั้งหมดโดยใช้ pageToken อย่างไรก็ตาม โปรดระมัดระวังเพื่อหลีกเลี่ยงปัญหาการจำกัดอัตรา

ตัวอย่างการอ่าน pageToken

ขอแนะนำให้ใช้ pageToken เพื่ออ่านบันทึกเพื่อดึงข้อมูลทั้งหมด ที่มีจากระยะเวลาที่ขอ

ตัวอย่างต่อไปนี้แสดงวิธีอ่านระเบียนทั้งหมดจนกว่าโทเค็นหน้าเว็บทั้งหมดจะหมด

val type = HeartRateRecord::class
val endTime = Instant.now()
val startTime = endTime.minus(Duration.ofDays(7))

try {
    var pageToken: String? = null
    do {
        val readResponse =
            healthConnectClient.readRecords(
                ReadRecordsRequest(
                    recordType = type,
                    timeRangeFilter = TimeRangeFilter.between(
                        startTime,
                        endTime
                    ),
                    pageToken = pageToken
                )
            )
        val records = readResponse.records
        // Do something with records
        pageToken = readResponse.pageToken
    } while (pageToken != null)
} catch (quotaError: IllegalStateException) {
    // Backoff
}
ดูข้อมูลเกี่ยวกับแนวทางปฏิบัติแนะนำเมื่ออ่านชุดข้อมูลขนาดใหญ่ได้ที่ วางแผนเพื่อหลีกเลี่ยงการจำกัดอัตราคำขอ

อ่านข้อมูลที่เขียนไว้ก่อนหน้านี้

หากแอปเคยเขียนบันทึกลงใน Health Connect มาก่อน แอปนั้นจะอ่านข้อมูลย้อนหลังได้ ซึ่งใช้ได้กับสถานการณ์ที่ แอปต้องซิงค์กับ Health Connect อีกครั้งหลังจากที่ผู้ใช้ติดตั้งแอปใหม่

โดยมีข้อจำกัดในการอ่านบางประการดังนี้

  • สำหรับ Android 14 ขึ้นไป

    • ไม่มีขีดจํากัดย้อนหลังสําหรับแอปที่อ่านข้อมูลของตัวเอง
    • จำกัด 30 วันสำหรับแอปที่อ่านข้อมูลอื่นๆ
  • สำหรับ Android 13 และต่ำกว่า

    • จำกัด 30 วันในการอ่านข้อมูลของแอป

คุณนำข้อจำกัดออกได้โดยขอสิทธิ์อ่าน

หากต้องการอ่านข้อมูลย้อนหลัง คุณต้องระบุชื่อแพ็กเกจเป็นออบเจ็กต์ DataOrigin ในพารามิเตอร์ dataOriginFilter ของ ReadRecordsRequest

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

try {
    val response =  healthConnectClient.readRecords(
        ReadRecordsRequest(
            recordType = HeartRateRecord::class,
            timeRangeFilter = TimeRangeFilter.between(startTime, endTime),
            dataOriginFilter = setOf(DataOrigin("com.my.package.name"))
        )
    )
    for (record in response.records) {
        // Process each record
    }
} catch (e: Exception) {
    // Run error handling here
}

อ่านตัวระบุอุปกรณ์ที่ไม่ซ้ำกัน (UDI)

สำหรับบันทึกที่มาจากอุปกรณ์ทางการแพทย์ แอปพลิเคชันการอ่านจะ ดึงส่วนตัวระบุอุปกรณ์ (DI) ของตัวระบุอุปกรณ์ที่ไม่ซ้ำกัน (UDI) จากข้อมูลเมตาของอุปกรณ์ได้ ดูคำแนะนำเกี่ยวกับวิธีประมวลผลข้อมูลนี้และจับคู่กับฐานข้อมูลด้านกฎระเบียบได้ในคู่มือข้อมูลเมตา

อ่านข้อมูลที่มีอายุมากกว่า 30 วัน

โดยค่าเริ่มต้น แอปพลิเคชันทั้งหมดจะอ่านข้อมูลจาก Health Connect ได้นานสูงสุด 30 วัน ก่อนที่จะมีการให้สิทธิ์ครั้งแรก

หากต้องการขยายสิทธิ์การอ่านนอกเหนือจากข้อจำกัดเริ่มต้น ให้ขอPERMISSION_READ_HEALTH_DATA_HISTORY ไม่เช่นนั้น หากไม่มีสิทธิ์นี้ การพยายามอ่านบันทึกที่เก่ากว่า 30 วันจะทำให้เกิดข้อผิดพลาด

ประวัติสิทธิ์ของแอปที่ถูกลบ

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

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

จัดการข้อยกเว้น

Health Connect จะส่งข้อยกเว้นมาตรฐานสำหรับการดำเนินการ CRUD เมื่อพบปัญหา แอปของคุณควรตรวจจับและจัดการข้อยกเว้นแต่ละรายการเหล่านี้ตามความเหมาะสม

แต่ละเมธอดใน HealthConnectClient จะแสดงข้อยกเว้นที่อาจเกิดขึ้น โดยทั่วไปแล้ว แอปควรจัดการข้อยกเว้นต่อไปนี้

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

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

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

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

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

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

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

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