Verileri arka planda izleme

Pasif veri güncellemeleri, Sağlık Hizmetleri'ni izlemesi gereken uygulamalar için uygundur arka planda çalışır. Saatler, günler veya zaman dilimlerini kapsayan kullanım alanları için tasarlanmıştır. daha da uzun. Uygulamanız kullanılamadığında sağlık verilerini depolamanız veya işlemeniz gerekiyorsa çalışıyorsa ve kullanıcı açık bir şekilde herhangi bir egzersiz yapmamışsa Sağlık Hizmeti'nin pasif istemcisi.

Pasif veri kullanımı örnekleri için bkz. Pasif Veriler ve Pasif Hedefler örnekleri inceleyin.

Bağımlılıkları ekleme

Sağlık Hizmetleri'ne bağımlılık eklemek için Google Maven deposunu eklemeniz gerekir projenize ekleyin. Daha fazla bilgi için bkz. Google'ın Maven deposu.

Modül düzeyindeki build.gradle dosyanıza aşağıdaki bağımlılığı ekleyin:

Groovy

dependencies {
    implementation "androidx.health:health-services-client:1.1.0-alpha04"
}

Kotlin

dependencies {
    implementation("androidx.health:health-services-client:1.1.0-alpha04")
}

Özellikleri kontrol edin

Veri güncellemelerine kaydolmadan önce cihazın, veri güncelleme özelliği en değerli verilerdir. Özellikleri kontrol ederek etkinleştirebilir veya devre dışı bırakabilirsiniz veya uygulamanızın kullanıcı arayüzünü değiştirmek ya da kullanmak mevcut değil.

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
}

Pasif verilere kaydolma

Pasif verileri bir hizmet, geri arama veya her ikisi üzerinden alabilirsiniz. CEVAP hizmeti, cihazınızın hiçbir parçası olmadığında uygulamanızın arka planda veri almasına olanak tanır. Uygulama ön planda görünür. Arka planda veri aldığınızda gruplar halinde teslim edilir. Geri çağırma, verileri biraz daha hızlı bir şekilde alır, ancak yalnızca uygulama çalışırken ve geri çağırma başarıyla bilgilendirildiğinde.

Hangi yöntemi kullanırsanız kullanın önce bir PassiveListenerConfig oluşturun Aşağıdaki örnekte gösterildiği gibi, hangi veri türlerinin alınacağını belirler:

val passiveListenerConfig = PassiveListenerConfig.builder()
    .setDataTypes(setOf(DataType.HEART_RATE_BPM))
    .build()

Geri çağırma kullanarak veri almak için geri çağırmayı aşağıda gösterildiği gibi tanımlayıp kaydedin: aşağıdaki örneği inceleyin:

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()

Bir hizmet de benzer şekilde kullanılır ancak sistemden türetilmiş bir sınıf oluşturmak yerine PassiveListenerCallback, aşağıda gösterildiği gibi PassiveListenerService parametresinden türetilir aşağıdaki örneği inceleyin:

class PassiveDataService : PassiveListenerService() {
    override fun onNewDataPointsReceived(dataPoints: DataPointContainer) {
        // TODO: Do something with dataPoints
    }
}

passiveMonitoringClient.setPassiveListenerServiceAsync(
    PassiveDataService::class.java,
    passiveListenerConfig
)

Sonra, AndroidManifest.xml dosyanızda hizmeti tanımlayın. Sağlık durumu gerekli Yalnızca Sağlık Hizmetleri'nin bağlanabilmesini sağlayan Hizmetler izni ekleme:

<service android:name=".PassiveDataService"
    android:permission="com.google.android.wearable.healthservices.permission.PASSIVE_DATA_BINDING"
    android:exported="true" />

Zamanı yorumlama

Sağlık Hizmetleri'nden aldığınız veriler toplu olarak işlendiğinden veri alabilirsiniz Aynı türde farklı veri noktalarından veya aynı türde birden fazla veri noktasında grubudur. Zaman yerine bu nesnelerin içine eklenen zaman damgalarını kullanın doğru sıralamayı belirlemek için uygulamanız tarafından alındı.

Önce başlatma zaman damgasını hesaplayarak her DataPoint için zaman damgaları elde edin. aşağıdaki örnekte gösterildiği gibi:

val bootInstant =
    Instant.ofEpochMilli(System.currentTimeMillis() - SystemClock.elapsedRealtime())

Bu değer, daha sonra getStartInstant() veya getEndInstant().

Başlatma sonrasında kayıtları geri yükleme

Pasif veri kayıtları, yeniden başlatmalar sırasında devam etmez. Şu andan itibaren veri almak için: yeniden başlatılmasını istiyorsanız, şunu içeren bir BroadcastReceiver kullanarak kayıtlarınızı yeniden oluşturun: şunu dinler: ACTION_BOOT_COMPLETED veya sistem yayını.

Alıcıda, kayıtları doğrudan geri yüklemeye çalışmayın. Bunun yerine bu işlevi bir WorkManager çalışanına devredebilirsiniz. Sağlık Hizmetleri'nin başlatılması 10 saniye veya daha uzun sürebilir pasif veri kaydı isteğini onaylar ve bu istek BroadcastReceiver için izin verilen yürütme süresi. Buna karşılık WorkManager çalışanların 10 dakikalık yürütme sınırı.

Aşağıdaki snippet'te BroadcastReceiver görünümü gösterilmektedir:

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()
   }
}

Cihaz başlatıldığında sistemin bu kodu yürütmesini sağlamak için AndroidManifest.xml dosyasında iki değişiklik yapılır.

İlk olarak aşağıdaki izni <manifest> alt öğesi olarak ekleyin:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

İkinci olarak, aşağıdaki "alıcı niyeti" filtresini <application> alt öğesi olarak ekleyin:

<receiver
    android:name=".StartupReceiver"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

Etkinlik durumu

Pasif istemci, kullanıcı durumu hakkında üst düzey bilgiler de sağlayabilir. Örneğin: değişiklikler yapın. Bu güncellemeleri almak için aşağıdaki adımları izleyin:

  1. ACTIVITY_RECOGNITION izni isteyin.
  2. setShouldUserActivityInfoBeRequested(true) adlı iş ortağını şu numaradan arayın: PassiveListenerConfig oluşturucu.

Geri çağırma veya hizmetinizde onUserActivityInfoReceived() yöntemini geçersiz kılın ve aşağıdaki örnekte gösterildiği gibi, döndürülen UserActivityInfo öğesinden yararlanın:

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) {
        // ...
    }
}

Pasif hedefler

Pasif istemciler, pasif hedefler olduğunda uygulamayı bilgilendirecek şekilde yapılandırabilirsiniz. ulaşıldığı anlamına gelir. Örneğin, kullanıcı günde 10.000 adım tamamladığında.

Bunun için, aşağıdaki örnekte gösterildiği gibi bir hedef oluşturun:

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)
}

Bu hedefi aşağıda gösterildiği gibi PassiveListenerConfig sayfanıza ekleyin örnek:

val passiveListenerConfig = PassiveListenerConfig.builder()
    .setDailyGoals(setOf(dailyStepsGoal))
    .build()

Geri çağırma veya hizmetinizde onGoalCompleted() yöntemini geçersiz kılın ve aşağıdaki örnekte gösterildiği gibi, döndürülen PassiveGoal öğesinden yararlanın:

override fun onGoalCompleted(goal: PassiveGoal) {
    when (goal.dataTypeCondition.dataType) {
        DataType.STEPS_DAILY -> {
            // ...
        }
    }
}
. ziyaret edin.