ตัวอย่างต่อไปนี้แสดงวิธีอ่านข้อมูลดิบซึ่งเป็นส่วนหนึ่งของเวิร์กโฟลว์ทั่วไป
อ่านข้อมูล
Health Connect อนุญาตให้แอปอ่านข้อมูลจาก Datastore เมื่อแอปอยู่ในเบื้องหน้าและเบื้องหลัง
การอ่านในเบื้องหน้า: โดยปกติแล้ว คุณจะอ่านข้อมูลจาก 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 }
อ่านจำนวนก้าวในอุปกรณ์เคลื่อนที่
Health Connect จะนับจำนวนก้าวในอุปกรณ์ด้วย Android 14 (ระดับ API 34) และ SDK Extension เวอร์ชัน 20 ขึ้นไป หากแอปใดได้รับสิทธิ์ 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 Extension เวอร์ชัน 20 ขึ้นไป แต่ getCurrentDeviceDataSource() API ก็พร้อมใช้งานใน Android 14 (ระดับ API 34) ที่มี SDK Extension เวอร์ชัน 11 ขึ้นไป
getCurrentDeviceDataSource() API ยังไม่พร้อมใช้งานในไลบรารี Health Connect Jetpack ตัวอย่างต่อไปนี้ใช้ 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() } }
@OptIn(ExperimentalFeatureAvailabilityApi::class) 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 เริ่มต้นเป็น 1,000
หากจำนวนบันทึกใน 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 }
อ่านข้อมูลที่มีอายุมากกว่า 30 วัน
โดยค่าเริ่มต้น แอปพลิเคชันทั้งหมดจะอ่านข้อมูลจาก Health Connect ได้นานสูงสุด 30 วันก่อนวันที่ได้รับสิทธิ์ครั้งแรก
หากต้องการขยายสิทธิ์อ่านให้เกินข้อจำกัด
เริ่มต้น ให้ขอ
PERMISSION_READ_HEALTH_DATA_HISTORY
ไม่เช่นนั้น การพยายามอ่านบันทึกที่มีอายุมากกว่า 30 วันจะทำให้เกิดข้อผิดพลาด
ประวัติสิทธิ์ของแอปที่ถูกลบ
หากผู้ใช้ลบแอปของคุณ ระบบจะเพิกถอนสิทธิ์ทั้งหมด รวมถึงสิทธิ์ประวัติ หากผู้ใช้ติดตั้งแอปของคุณอีกครั้งและให้สิทธิ์อีกครั้ง ข้อจำกัดเริ่มต้นเดียวกันจะมีผล และแอปของคุณจะอ่านข้อมูลจาก Health Connect ได้นานสูงสุด 30 วันก่อนวันที่ใหม่นั้น
เช่น สมมติว่าผู้ใช้ลบแอปของคุณในวันที่ 10 พฤษภาคม 2023 จากนั้นติดตั้งแอปอีกครั้งในวันที่ 15 พฤษภาคม 2023 และให้สิทธิ์อ่าน วันที่เร็วที่สุดที่แอปของคุณจะอ่านข้อมูลได้โดยค่าเริ่มต้นคือ15 เมษายน 2023
จัดการข้อยกเว้น
Health Connect จะแสดงข้อยกเว้นมาตรฐานสำหรับการดำเนินการ CRUD เมื่อพบปัญหา แอปของคุณควรตรวจจับและจัดการข้อยกเว้นแต่ละรายการเหล่านี้ตามความเหมาะสม
แต่ละเมธอดใน HealthConnectClient จะแสดงข้อยกเว้นที่อาจเกิดขึ้น
โดยทั่วไปแล้ว แอปของคุณควรจัดการข้อยกเว้นต่อไปนี้
| ข้อยกเว้น | คำอธิบาย | แนวทางปฏิบัติแนะนำ |
|---|---|---|
IllegalStateException
| เกิดสถานการณ์ใดสถานการณ์หนึ่งต่อไปนี้
| จัดการปัญหาที่อาจเกิดขึ้นกับอินพุตก่อนที่จะส่งคำขอ เราขอแนะนำให้กำหนดค่าให้กับตัวแปรหรือใช้ตัวแปรเป็นพารามิเตอร์ภายในฟังก์ชันที่กำหนดเองแทนที่จะใช้ตัวแปรในคำขอโดยตรง เพื่อให้คุณใช้กลยุทธ์การจัดการข้อผิดพลาดได้ |
IOException
| เกิดปัญหาในการอ่านและเขียนข้อมูลจากดิสก์ | วิธีหลีกเลี่ยงปัญหานี้มีดังนี้
|
RemoteException
| เกิดข้อผิดพลาดภายในหรือในการสื่อสารกับบริการพื้นฐานที่ SDK เชื่อมต่ออยู่ เช่น แอปของคุณพยายามลบบันทึกที่มี uid ที่กำหนด อย่างไรก็ตาม ระบบจะแสดงข้อยกเว้นหลังจากที่แอปพบว่าบันทึกไม่มีอยู่เมื่อตรวจสอบในบริการพื้นฐาน
| วิธีหลีกเลี่ยงปัญหานี้มีดังนี้
|
SecurityException
| เกิดปัญหาเมื่อคำขอต้องใช้สิทธิ์ที่ไม่ได้ให้ไว้ | วิธีหลีกเลี่ยงปัญหานี้คือตรวจสอบว่าคุณได้ ประกาศการใช้ประเภทข้อมูล Health Connect สำหรับแอปที่เผยแพร่แล้ว นอกจากนี้ คุณต้องประกาศสิทธิ์ Health Connect ในไฟล์ Manifest และ ในกิจกรรมของคุณ |