การอัปเดตข้อมูลแบบพาสซีฟเหมาะสำหรับแอปที่ต้องตรวจสอบข้อมูลของบริการด้านสุขภาพ ในเบื้องหลัง โดยมีไว้สำหรับกรณีการใช้งานที่กินเวลาหลายชั่วโมง หลายวัน หรือนานกว่านั้น หากต้องการจัดเก็บหรือประมวลผลข้อมูลสุขภาพและการออกกำลังกายเมื่อ แอปไม่ได้ทำงานและผู้ใช้ไม่ได้ออกกำลังกายอย่างชัดเจน ให้ใช้ไคลเอ็นต์แบบพาสซีฟของบริการด้านสุขภาพ
ดูตัวอย่างการใช้ข้อมูลแบบพาสซีฟได้ในตัวอย่างข้อมูลแบบพาสซีฟ และ เป้าหมายแบบพาสซีฟ ใน GitHub
เพิ่มทรัพยากร Dependency
หากต้องการเพิ่มการอ้างอิงในบริการด้านสุขภาพ คุณต้องเพิ่มที่เก็บ Maven ของ Google ลงในโปรเจ็กต์ ดูข้อมูลเพิ่มเติมได้ที่ ที่เก็บ Maven ของ Google
เพิ่มทรัพยากร Dependency ต่อไปนี้ในไฟล์ build.gradle
ระดับโมดูล
ดึงดูด
dependencies { implementation "androidx.health:health-services-client:1.1.0-alpha05" }
Kotlin
dependencies { implementation("androidx.health:health-services-client:1.1.0-alpha05") }
ตรวจสอบความสามารถ
ก่อนลงทะเบียนเพื่อรับการอัปเดตข้อมูล ให้ตรวจสอบว่าอุปกรณ์สามารถให้ข้อมูลประเภท ที่แอปของคุณต้องการได้ การตรวจสอบความสามารถช่วยให้คุณเปิดหรือปิดใช้ ฟีเจอร์บางอย่าง หรือแก้ไข UI ของแอปเพื่อชดเชยฟีเจอร์ที่ ไม่พร้อมใช้งานได้
val healthClient = HealthServices.getClient(this /*context*/)
val passiveMonitoringClient = healthClient.passiveMonitoringClient
lifecycleScope.launchWhenCreated {
val capabilities = passiveMonitoringClient.capabilities.await()
// Supported types for passive data collection
supportsHeartRate =
DataType.HEART_RATE_BPM in capabilities.supportedDataTypesPassiveMonitoring
// Supported types for PassiveGoals
supportsStepsGoal =
DataType.STEPS_DAILY in capabilities.supportedDataTypesPassiveGoals
}
ลงทะเบียนเพื่อรับข้อมูลแบบพาสซีฟ
คุณรับข้อมูลแบบพาสซีฟได้ผ่านบริการ, การเรียกกลับ หรือทั้ง 2 อย่าง บริการช่วยให้แอปรับข้อมูลในเบื้องหลังได้เมื่อไม่มีส่วนใดของ แอปแสดงในเบื้องหน้า เมื่อคุณได้รับข้อมูลในเบื้องหลัง ระบบจะ ส่งข้อมูลเป็นชุด การเรียกกลับจะได้รับข้อมูลในอัตราที่เร็วกว่าเล็กน้อย แต่ เฉพาะในขณะที่แอปทำงานอยู่และมีการแจ้งเตือนการเรียกกลับสำเร็จเท่านั้น
ไม่ว่าคุณจะใช้วิธีใดก็ตาม ให้สร้างPassiveListenerConfig
ก่อนเพื่อกำหนดประเภทข้อมูลที่จะรับ ดังตัวอย่างต่อไปนี้
val passiveListenerConfig = PassiveListenerConfig.builder()
.setDataTypes(setOf(DataType.HEART_RATE_BPM))
.build()
หากต้องการรับข้อมูลโดยใช้การเรียกกลับ ให้กำหนดและลงทะเบียนการเรียกกลับ ดังที่แสดงใน ตัวอย่างต่อไปนี้
val passiveListenerCallback: PassiveListenerCallback = object : PassiveListenerCallback {
override fun onNewDataPointsReceived(dataPoints: DataPointContainer) {
// TODO: Do something with dataPoints
}
}
passiveMonitoringClient.setPassiveListenerCallback(
passiveListenerConfig,
passiveListenerCallback
)
// To remove the listener
passiveMonitoringClient.clearPassiveListenerCallbackAsync()
การใช้บริการจะคล้ายกัน แต่ให้สร้างคลาสที่ได้มาจาก PassiveListenerService
แทนที่จะสร้างจาก
PassiveListenerCallback
ดังที่แสดงใน
ตัวอย่างต่อไปนี้
class PassiveDataService : PassiveListenerService() {
override fun onNewDataPointsReceived(dataPoints: DataPointContainer) {
// TODO: Do something with dataPoints
}
}
passiveMonitoringClient.setPassiveListenerServiceAsync(
PassiveDataService::class.java,
passiveListenerConfig
)
จากนั้นประกาศบริการในไฟล์ AndroidManifest.xml
ต้องมีสิทธิ์ Health
Services ซึ่งจะยืนยันว่ามีเพียง Health Services เท่านั้นที่เชื่อมโยงกับบริการได้
<service android:name=".PassiveDataService"
android:permission="com.google.android.wearable.healthservices.permission.PASSIVE_DATA_BINDING"
android:exported="true" />
ล่ามเวลา
ข้อมูลที่คุณได้รับจากบริการด้านสุขภาพจะได้รับการจัดกลุ่มเป็นชุด คุณจึงอาจได้รับจุดข้อมูล ประเภทต่างๆ หรือจุดข้อมูลหลายจุดประเภทเดียวกันในชุดเดียวกัน ใช้การประทับเวลาที่รวมอยู่ในออบเจ็กต์เหล่านี้แทนเวลาที่แอปได้รับเพื่อกำหนดลำดับเหตุการณ์ที่ถูกต้อง
รับการประทับเวลาสำหรับแต่ละ DataPoint
โดยคำนวณการประทับเวลาการเริ่มต้นก่อน
ดังที่แสดงในตัวอย่างต่อไปนี้
val bootInstant =
Instant.ofEpochMilli(System.currentTimeMillis() - SystemClock.elapsedRealtime())
จากนั้นจะส่งค่านี้ไปยัง
getStartInstant()
หรือ
getEndInstant()
กู้คืนการลงทะเบียนหลังการบูต
การลงทะเบียนข้อมูลแบบพาสซีฟจะไม่คงอยู่เมื่อรีบูต หากต้องการรับข้อมูลหลังจากรีสตาร์ทอุปกรณ์ ให้สร้างการลงทะเบียนใหม่โดยใช้ BroadcastReceiver
ที่รอฟังการออกอากาศของระบบ ACTION_BOOT_COMPLETED
ในเครื่องรับ อย่าพยายามกู้คืนการลงทะเบียนโดยตรง แต่ให้มอบหมายฟังก์ชันนี้ให้กับผู้ปฏิบัติงาน WorkManager
แทน เมื่ออุปกรณ์เริ่มต้นทำงาน บริการด้านสุขภาพอาจใช้เวลา 10 วินาทีขึ้นไปในการ
รับทราบคำขอลงทะเบียนข้อมูลแบบพาสซีฟ และอาจเกิน
เวลาดำเนินการที่อนุญาตของ BroadcastReceiver
ในทางตรงกันข้าม WorkManager
Worker มีขีดจำกัดการดำเนินการ 10 นาที
ข้อมูลโค้ดต่อไปนี้แสดงลักษณะของ BroadcastReceiver
class StartupReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action != Intent.ACTION_BOOT_COMPLETED) return
// TODO: Check permissions first
WorkManager.getInstance(context).enqueue(
OneTimeWorkRequestBuilder<RegisterForPassiveDataWorker>().build()
)
}
}
class RegisterForPassiveDataWorker(
private val appContext: Context,
workerParams: WorkerParameters
) : Worker(appContext, workerParams) {
override fun doWork(): Result {
runBlocking {
HealthServices.getClient(appContext)
.passiveMonitoringClient
.setPassiveListenerCallback(...)
}
return Result.success()
}
}
หากต้องการให้ระบบเรียกใช้โค้ดนี้เมื่ออุปกรณ์เริ่มระบบ ให้ทำการเปลี่ยนแปลง 2 อย่างในไฟล์ AndroidManifest.xml
ก่อนอื่น ให้เพิ่มสิทธิ์ต่อไปนี้เป็นสิทธิ์ย่อยของ <manifest>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
จากนั้นเพิ่มตัวกรอง Intent ของตัวรับต่อไปนี้เป็นองค์ประกอบย่อยของ <application>
<receiver
android:name=".StartupReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
สถานะกิจกรรม
ไคลเอ็นต์แบบพาสซีฟยังให้ข้อมูลระดับสูงเกี่ยวกับสถานะของผู้ใช้ได้ด้วย เช่น ผู้ใช้กำลังนอนหลับอยู่หรือไม่ หากต้องการรับข้อมูลอัปเดตเหล่านี้ ให้ทำตามขั้นตอนต่อไปนี้
- ขอสิทธิ์
ACTIVITY_RECOGNITION
- เรียกใช้
setShouldUserActivityInfoBeRequested(true)
ในเครื่องมือสร้างPassiveListenerConfig
ลบล้างเมธอด onUserActivityInfoReceived()
ในการเรียกกลับหรือบริการ
และใช้ UserActivityInfo
ที่ส่งคืน ดังที่แสดงในตัวอย่างต่อไปนี้
override fun onUserActivityInfoReceived(info: UserActivityInfo) {
val stateChangeTime: Instant = info.stateChangeTime // may be in the past!
val userActivityState: UserActivityState = info.userActivityState
if (userActivityState == UserActivityState.USER_ACTIVITY_ASLEEP) {
// ...
}
}
เป้าหมายแบบพาสซีฟ
คุณสามารถกำหนดค่าไคลเอ็นต์แบบพาสซีฟให้แจ้งเตือนแอปเมื่อบรรลุเป้าหมายแบบพาสซีฟ เช่น ผู้ใช้เดินครบ 10,000 ก้าวใน 1 วัน
โดยให้สร้างเป้าหมายตามตัวอย่างต่อไปนี้
val dailyStepsGoal by lazy {
val condition = DataTypeCondition(
dataType = DataType.STEPS_DAILY,
threshold = 10_000, // Trigger every 10000 steps
comparisonType = ComparisonType.GREATER_THAN_OR_EQUAL
)
PassiveGoal(condition)
}
เพิ่มเป้าหมายนี้ลงใน PassiveListenerConfig
ตามที่แสดงในตัวอย่างต่อไปนี้
val passiveListenerConfig = PassiveListenerConfig.builder()
.setDailyGoals(setOf(dailyStepsGoal))
.build()
ลบล้างเมธอด onGoalCompleted()
ในการเรียกกลับหรือบริการ
และใช้ PassiveGoal
ที่ส่งคืน ดังที่แสดงในตัวอย่างต่อไปนี้
override fun onGoalCompleted(goal: PassiveGoal) {
when (goal.dataTypeCondition.dataType) {
DataType.STEPS_DAILY -> {
// ...
}
}
}
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- ข้อมูลและแบบฝึกหัดที่ใช้งานอยู่
- เริ่มต้นใช้งานไทล์
- เพิ่มหน้าจอเริ่มต้น