Các bản cập nhật dữ liệu thụ động phù hợp với những ứng dụng cần theo dõi dữ liệu Dịch vụ sức khoẻ ở chế độ nền. Các bản cập nhật này dùng trong các trường hợp sử dụng kéo dài nhiều giờ, nhiều ngày hoặc thậm chí lâu hơn. Nếu cần lưu trữ hoặc xử lý dữ liệu sức khoẻ khi ứng dụng không chạy cũng như người dùng không có hoạt động thể dục thể thao một cách rõ ràng, bạn nên dùng ứng dụng (client) thụ động của Dịch vụ sức khoẻ.
Để biết ví dụ về cách sử dụng dữ liệu thụ động, hãy xem Dữ liệu thụ động và Mục tiêu thụ động các mẫu trên GitHub.
Thêm phần phụ thuộc
Để thêm một phần phụ thuộc trên Dịch vụ sức khoẻ, bạn phải thêm kho lưu trữ Google Maven vào dự án. Để biết thêm thông tin, hãy xem Kho lưu trữ Maven của Google.
Trong tệp build.gradle
ở cấp mô-đun, hãy thêm phần phụ thuộc sau:
Groovy
dependencies { implementation "androidx.health:health-services-client:1.1.0-alpha03" }
Kotlin
dependencies { implementation("androidx.health:health-services-client:1.1.0-alpha03") }
Kiểm tra các chức năng
Trước khi đăng ký nhận thông tin cập nhật dữ liệu, hãy kiểm tra để đảm bảo rằng thiết bị có thể cung cấp loại dữ liệu mà ứng dụng của bạn cần. Việc kiểm tra các chức năng giúp bạn có thể bật hoặc tắt một số tính năng hoặc sửa đổi giao diện người dùng của ứng dụng để bù cho những tính năng không có.
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
}
Đăng ký nhận dữ liệu thụ động
Bạn có thể nhận dữ liệu thụ động thông qua một dịch vụ, lệnh gọi lại hoặc cả hai. Dịch vụ này cho phép ứng dụng của bạn nhận dữ liệu ở chế độ nền khi không có phần nào của ứng dụng xuất hiện ở nền trước. Khi bạn nhận được dữ liệu ở chế độ nền, dữ liệu đó sẽ được phân phối theo lô. Lệnh gọi lại nhận được dữ liệu với tốc độ nhanh hơn một chút, nhưng chỉ khi ứng dụng đang chạy và lệnh gọi lại đó được thông báo thành công.
Dù bạn sử dụng phương thức nào, trước tiên, hãy tạo PassiveListenerConfig
để xác định loại dữ liệu sẽ nhận như trong ví dụ sau:
val passiveListenerConfig = PassiveListenerConfig.builder()
.setDataTypes(setOf(DataType.HEART_RATE_BPM))
.build()
Để nhận dữ liệu bằng lệnh gọi lại, hãy xác định và đăng ký lệnh gọi lại như trong ví dụ sau:
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()
Việc sử dụng một dịch vụ cũng tương tự như vậy, nhưng thay vì tạo một lớp bắt nguồn từ PassiveListenerCallback
, hãy lấy dữ liệu từ PassiveListenerService
như trong ví dụ sau:
class PassiveDataService : PassiveListenerService() {
override fun onNewDataPointsReceived(dataPoints: DataPointContainer) {
// TODO: Do something with dataPoints
}
}
passiveMonitoringClient.setPassiveListenerServiceAsync(
PassiveDataService::class.java,
passiveListenerConfig
)
Tiếp theo, hãy khai báo dịch vụ trong tệp AndroidManifest.xml
. Cần có quyền truy cập Dịch vụ sức khoẻ để đảm bảo rằng chỉ Dịch vụ sức khoẻ mới có thể liên kết với dịch vụ này:
<service android:name=".PassiveDataService"
android:permission="com.google.android.wearable.healthservices.permission.PASSIVE_DATA_BINDING"
android:exported="true" />
Thời gian thông dịch
Dữ liệu bạn nhận được từ Dịch vụ sức khoẻ được phân theo lô. Do đó, bạn có thể nhận các điểm dữ liệu thuộc nhiều loại, hoặc nhiều điểm dữ liệu cùng loại, trong cùng một lô. Hãy sử dụng dấu thời gian có trong các đối tượng này thay vì thời gian mà ứng dụng nhận được để xác định thứ tự chính xác của các sự kiện.
Lấy dấu thời gian của từng DataPoint
, trước hết bằng cách tính toán dấu thời gian khởi động, như trong ví dụ sau:
val bootInstant =
Instant.ofEpochMilli(System.currentTimeMillis() - SystemClock.elapsedRealtime())
Sau đó, giá trị này có thể được truyền đến getStartInstant()
hoặc getEndInstant()
.
Khôi phục yêu cầu đăng ký sau khi khởi động
Yêu cầu đăng ký dữ liệu thụ động không được duy trì sau khi khởi động lại. Để nhận dữ liệu sau khi thiết bị khởi động lại, hãy tạo lại các yêu cầu đăng ký của bạn bằng cách sử dụng BroadcastReceiver
có vai trò nghe tin do hệ thống truyền ra về ACTION_BOOT_COMPLETED
.
Trong trình nhận, đừng tìm cách khôi phục trực tiếp các yêu cầu đăng ký. Thay vào đó, hãy uỷ quyền chức năng này cho một trình thực thi WorkManager
. Khi thiết bị khởi động, Dịch vụ sức khoẻ có thể mất ít nhất 10 giây để xác nhận yêu cầu đăng ký dữ liệu thụ động. Quá trình này có thể vượt quá thời gian thực thi cho phép của BroadcastReceiver
. Ngược lại, trình thực thi WorkManager
có giới hạn thực thi là 10 phút.
Đoạn mã sau đây minh hoạ các dạng của 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()
}
}
Để sắp xếp cho hệ thống thực thi đoạn mã này khi thiết bị khởi động, hãy thực hiện 2 thay đổi đối với tệp AndroidManifest.xml
.
Trước tiên, hãy thêm quyền sau đây ở dạng phần tử con của <manifest>
:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Tiếp theo, hãy thêm bộ lọc ý định của trình nhận sau đây làm phần tử con của <application>
:
<receiver
android:name=".StartupReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Trạng thái hoạt động
Ứng dụng (client) thụ động cũng có thể cung cấp thông tin cấp cao về trạng thái người dùng, chẳng hạn như liệu người dùng có đang ngủ hay không. Để nhận những thông tin cập nhật này, hãy làm theo các bước sau:
- Yêu cầu quyền
ACTIVITY_RECOGNITION
. - Gọi
setShouldUserActivityInfoBeRequested(true)
trong trình tạoPassiveListenerConfig
.
Ghi đè phương thức onUserActivityInfoReceived()
trong lệnh gọi lại hoặc dịch vụ, đồng thời sử dụng UserActivityInfo
được trả về như trong ví dụ sau:
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) {
// ...
}
}
Mục tiêu thụ động
Bạn có thể định cấu hình ứng dụng (client) thụ động để thông báo cho ứng dụng khi đạt được các mục tiêu thụ động, chẳng hạn như người dùng hoàn thành 10.000 bước trong 1 ngày.
Để làm việc này, hãy tạo một mục tiêu như trong ví dụ sau:
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)
}
Thêm mục tiêu này vào PassiveListenerConfig
như trong ví dụ sau:
val passiveListenerConfig = PassiveListenerConfig.builder()
.setDailyGoals(setOf(dailyStepsGoal))
.build()
Ghi đè phương thức onGoalCompleted()
trong lệnh gọi lại hoặc dịch vụ, đồng thời sử dụng PassiveGoal
được trả về như trong ví dụ sau:
override fun onGoalCompleted(goal: PassiveGoal) {
when (goal.dataTypeCondition.dataType) {
DataType.STEPS_DAILY -> {
// ...
}
}
}
Đề xuất cho bạn
- Lưu ý: văn bản có đường liên kết sẽ hiển thị khi JavaScript tắt
- Dữ liệu hoạt động và các bài tập thể dục
- Làm quen với thẻ thông tin
- Thêm màn hình chờ