ExerciseClient ile egzersiz kaydetme

Sağlık Hizmetleri, ExerciseClient üzerinden egzersiz uygulamaları için birinci sınıf destek sağlar. ExerciseClient sayesinde uygulamanız bir egzersizin ne zaman devam ettiğini kontrol edebilir, egzersiz hedefleri ekleyebilir ve egzersiz durumu, egzersiz etkinlikleri veya istenen diğer metrikler hakkında güncelleme alabilir. Daha fazla bilgi için Sağlık Hizmetleri'nin desteklediği egzersiz türlerinin tam listesine bakın.

GitHub'daki Alıştırma örneğine bakın.

Bağımlılıklar ekleme

Health Services'e bağımlılık eklemek için Google Maven deposunu projenize eklemeniz gerekir. Daha fazla bilgi için Google'ın Maven deposuna bakın.

Ardından, 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-alpha05"
}

Kotlin

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

Uygulama yapısı

Sağlık Hizmetleri ile bir egzersiz uygulaması oluştururken aşağıdaki uygulama yapısını kullanın:

Antrenmana hazırlanırken ve antrenman sırasında aktiviteniz çeşitli nedenlerle durdurulabilir. Kullanıcı başka bir uygulamaya geçebilir veya kadrana geri dönebilir. Sistem, etkinliğinizin üstünde bir şey gösterebilir veya ekran, belirli bir süre boyunca işlem yapılmadığında kapanabilir. Antrenmanın tamamının doğru şekilde çalışmasını sağlamak için ExerciseClient ile birlikte sürekli çalışan bir ForegroundService kullanın.

ForegroundService kullanarak Devam Eden Etkinlik API'sini kullanarak kadranlarınızda bir gösterge gösterebilir ve kullanıcının antrenmana hızlıca dönmesini sağlayabilirsiniz.

Ön plan hizmetinizde konum verilerini uygun şekilde istemeniz önemlidir. Manifest dosyanızda gerekli ön plan hizmet türlerini ve izinleri belirtin:

<manifest ...>
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <application ...>
    
      <!-- If your app is designed only for devices that run Wear OS 4
           or lower, use android:foregroundServiceType="location" instead. -->
      <service
          android:name=".MyExerciseSessionRecorder"
          android:foregroundServiceType="health|location">
      </service>
      
    </application>
</manifest>

Antrenman öncesi aktiviteniz için prepareExercise() çağrısını içeren AmbientLifecycleObserver, antrenman aktiviteniz için ise AmbientLifecycleObserver çağrısını kullanın. Ancak, egzersiz sırasında ekranı ortam modunda güncellemeyin. Bunun nedeni, Sağlık Hizmetleri'nin cihaz ekranı ortam modundayken güç tasarrufu yapmak için egzersiz verilerini gruplandırması ve bu nedenle gösterilen bilgilerin güncel olmayabilmesidir. Antrenmanlar sırasında kullanıcı için anlamlı olan verileri gösterin. Güncel bilgileri veya boş bir ekran gösterin.

Özellikleri kontrol etme

Her ExerciseType, metrikler ve egzersiz hedefleri için belirli veri türlerini destekler. Cihazlara göre değişebileceğinden, bu özellikleri başlangıçta kontrol edin. Cihazlar belirli bir egzersiz türünü veya otomatik duraklatma gibi belirli bir işlevi desteklemeyebilir. Ayrıca, bir cihazın özellikleri zaman içinde değişebilir (ör. yazılım güncellemesinden sonra).

Uygulama başlatılırken cihaz özelliklerini sorgulayın ve aşağıdakileri saklayıp işleyin:

  • Platformun desteklediği egzersizler.
  • Her egzersiz için desteklenen özellikler.
  • Her alıştırma için desteklenen veri türleri.
  • Bu veri türlerinin her biri için gereken izinler.

Ne tür metrikler isteyebileceğinizi, hangi egzersiz hedeflerini yapılandırabileceğinizi ve bu tür için hangi diğer özelliklerin kullanılabildiğini görmek üzere istediğiniz egzersiz türüyle birlikte ExerciseCapabilities.getExerciseTypeCapabilities() simgesini kullanın. Bu durum aşağıdaki örnekte gösterilmektedir:

val healthClient = HealthServices.getClient(this /*context*/)
val exerciseClient = healthClient.exerciseClient
lifecycleScope.launch {
    val capabilities = exerciseClient.getCapabilitiesAsync().await()
    if (ExerciseType.RUNNING in capabilities.supportedExerciseTypes) {
        runningCapabilities =
            capabilities.getExerciseTypeCapabilities(ExerciseType.RUNNING)
    }
}

Döndürülen ExerciseTypeCapabilities içinde, supportedDataTypes, veri isteğinde bulunabileceğiniz veri türlerini listeler. Bu durum cihaza göre değişir. Bu nedenle, desteklenmeyen bir DataType istememeye dikkat edin. Aksi takdirde isteğiniz başarısız olabilir.

Egzersizin, oluşturmak istediğiniz bir egzersiz hedefini destekleyip destekleyemeyeceğini belirlemek için supportedGoals ve supportedMilestones alanlarını kullanın.

Uygulamanız kullanıcının otomatik duraklatma özelliğini kullanmasına izin veriyorsa supportsAutoPauseAndResume kullanarak bu işlevin cihaz tarafından desteklenip desteklenmediğini kontrol etmeniz gerekir. ExerciseClient, cihazda desteklenmeyen istekleri reddeder.

Aşağıdaki örnekte HEART_RATE_BPM veri türü, STEPS_TOTAL hedef özelliği ve otomatik duraklatma işlevi için destek kontrol edilmektedir:

// Whether we can request heart rate metrics.
supportsHeartRate = DataType.HEART_RATE_BPM in runningCapabilities.supportedDataTypes

// Whether we can make a one-time goal for aggregate steps.
val stepGoals = runningCapabilities.supportedGoals[DataType.STEPS_TOTAL]
supportsStepGoals = 
    (stepGoals != null && ComparisonType.GREATER_THAN_OR_EQUAL in stepGoals)

// Whether auto-pause is supported.
val supportsAutoPause = runningCapabilities.supportsAutoPauseAndResume

Egzersiz durumu güncellemelerine kaydolun

Egzersiz güncellemeleri bir dinleyiciye gönderilir. Uygulamanız aynı anda yalnızca tek bir dinleyiciyi kaydedebilir. Aşağıdaki örnekte gösterildiği gibi, antrenmana başlamadan önce dinleyicinizi ayarlayın. Dinleyiciniz yalnızca uygulamanızın sahip olduğu egzersizlerle ilgili güncellemeler alır.

val callback = object : ExerciseUpdateCallback {
    override fun onExerciseUpdateReceived(update: ExerciseUpdate) {
        val exerciseStateInfo = update.exerciseStateInfo
        val activeDuration = update.activeDurationCheckpoint
        val latestMetrics = update.latestMetrics
        val latestGoals = update.latestAchievedGoals
    }

    override fun onLapSummaryReceived(lapSummary: ExerciseLapSummary) {
        // For ExerciseTypes that support laps, this is called when a lap is marked.
    }

    override fun onAvailabilityChanged(
        dataType: DataType<*, *>,
        availability: Availability
    ) {
        // Called when the availability of a particular DataType changes.
        when {
            availability is LocationAvailability -> // Relates to Location/GPS.
            availability is DataTypeAvailability -> // Relates to another DataType.
        }
    }
}
exerciseClient.setUpdateCallback(callback)

Egzersizin kullanım süresini yönetme

Sağlık Hizmetleri, cihazdaki tüm uygulamalarda aynı anda en fazla bir egzersizi destekler. Bir egzersiz izlenirken farklı bir uygulama yeni bir egzersizi izlemeye başlarsa ilk egzersiz sonlandırılır.

Egzersizinize başlamadan önce aşağıdakileri yapın:

  • Bir egzersizin izlenip izlenmediğini kontrol edin ve buna göre hareket edin. Örneğin, önceki bir egzersizi geçersiz kılmadan ve yeni bir egzersizi izlemeye başlamadan önce kullanıcıdan onay isteyin.

Aşağıdaki örnekte, getCurrentExerciseInfoAsync ile mevcut bir egzersizin nasıl kontrol edileceği gösterilmektedir:

lifecycleScope.launch {
    val exerciseInfo = exerciseClient.getCurrentExerciseInfoAsync().await()
    when (exerciseInfo.exerciseTrackedStatus) {
        OTHER_APP_IN_PROGRESS -> // Warn user before continuing, will stop the existing workout.
        OWNED_EXERCISE_IN_PROGRESS -> // This app has an existing workout.
        NO_EXERCISE_IN_PROGRESS -> // Start a fresh workout.
    }
}

İzinler

ExerciseClient kullanırken uygulamanızın gerekli izinleri isteyip koruduğundan emin olun. Uygulamanız LOCATION verilerini kullanıyorsa uygulamanızın bu veriler için de gerekli izinleri istediğinden ve koruduğundan emin olun.

Tüm veri türleri için prepareExercise() veya startExercise() işlevini çağırmadan önce aşağıdakileri yapın:

  • AndroidManifest.xml dosyanızda istenen veri türleri için uygun izinleri belirtin.
  • Kullanıcının gerekli izinleri verdiğini doğrulayın. Daha fazla bilgi için Uygulama izinleri isteme başlıklı makaleyi inceleyin. Gerekli izinler henüz verilmemişse Sağlık Hizmetleri isteği reddeder.

Konum verileri için aşağıdaki ek adımları uygulayın:

Antrenmana hazırlanma

GPS veya kalp atış hızı gibi bazı sensörlerin ısınması kısa sürebilir veya kullanıcı antrenmanına başlamadan önce verilerini görmek isteyebilir. İsteğe bağlı prepareExerciseAsync() yöntemi, bu sensörlerin ısınmasını ve antrenman zamanlayıcısı başlatılmadan veri alınmasını sağlar. activeDuration bu hazırlık süresinden etkilenmez.

prepareExerciseAsync() numaralı telefonu aramadan önce aşağıdakileri kontrol edin:

  • Platform genelindeki konum ayarını kontrol edin. Kullanıcı, ana Ayarlar menüsünden bu ayarı kontrol eder. Bu ayar, uygulama düzeyindeki izin kontrolünden farklıdır.

    Ayar kapalıysa kullanıcıya konum erişimini reddettiğini bildirin ve uygulamanız konum erişimi gerektiriyorsa bu ayarı etkinleştirmesini isteyin.

  • Uygulamanızın vücut sensörleri (API düzeyi 35 veya daha düşük) ya da nabız (API düzeyi 36 ve üzeri), hareket tanıma ve hassas konum için çalışma zamanında izinlere sahip olduğunu onaylayın. Eksik izinler için kullanıcıdan çalışma zamanında izin isteğinde bulunun ve yeterli bağlam bilgisi sağlayın. Kullanıcı belirli bir izin vermezse prepareExerciseAsync() çağrısından bu izinle ilişkili veri türlerini kaldırın. Hazırlama çağrısı, özellikle egzersize başlamadan önce sabit bir kalp atış hızı veya GPS düzeltmesi elde etmek için olduğundan, vücut sensörü (API düzeyi 36 ve üzeri için kalp atış hızı) veya konum izinleri verilmemişse prepareExerciseAsync() çağrısını yapmayın. Uygulama, adıma dayalı mesafe, tempo, hız ve bu izinleri gerektirmeyen diğer metrikleri almaya devam edebilir.

prepareExerciseAsync() adresine yaptığınız aramanın başarılı sonuç vermesi için aşağıdakileri yapın:

  • Hazırlan çağrısını içeren antrenman öncesi etkinlik için AmbientLifecycleObserver simgesini kullanın.
  • Ön plan hizmetinizden prepareExerciseAsync()'i arayın. Bir hizmette değilse ve etkinlik yaşam döngüsüne bağlıysa sensör hazırlığı gereksiz yere sonlandırılabilir.
  • Kullanıcı antrenman öncesi etkinlikten ayrılırsa sensörleri kapatmak ve güç kullanımını azaltmak için endExercise() işlevini çağırın.

Aşağıdaki örnekte prepareExerciseAsync() işlevinin nasıl çağrılacağı gösterilmektedir:

val warmUpConfig = WarmUpConfig(
    ExerciseType.RUNNING,
    setOf(
        DataType.HEART_RATE_BPM,
        DataType.LOCATION
    )
)
// Only necessary to call prepareExerciseAsync if body sensor (API level 35
// or lower), heart rate (API level 36+), or location permissions are given.
exerciseClient.prepareExerciseAsync(warmUpConfig).await()

// Data and availability updates are delivered to the registered listener.

Uygulama PREPARING durumundayken sensör kullanılabilirlik durumu güncellemeleri onAvailabilityChanged() aracılığıyla ExerciseUpdateCallback'te yayınlanır. Bu bilgiler daha sonra kullanıcıya sunularak antrenmana başlayıp başlamayacağına karar vermesi sağlanabilir.

Antrenmanı başlatma

Bir alıştırmaya başlamak istediğinizde alıştırma türünü, metrik almak istediğiniz veri türlerini ve alıştırma hedeflerini veya aşamalarını yapılandırmak için bir ExerciseConfig oluşturun.

Egzersiz hedefleri bir DataType ve bir koşuldan oluşur. Egzersiz hedefleri, kullanıcı belirli bir mesafe koştuğunda olduğu gibi bir koşul karşılandığında tetiklenen tek seferlik bir hedeftir. Bir egzersiz hedefi de ayarlanabilir. Egzersiz aşamaları birden çok kez tetiklenebilir (ör. kullanıcı, belirlenen mesafenin belirli bir noktasını her geçtiğinde).

Aşağıdaki örnekte her türden bir hedefin nasıl oluşturulacağı gösterilmektedir:

const val CALORIES_THRESHOLD = 250.0
const val DISTANCE_THRESHOLD = 1_000.0 // meters

suspend fun startExercise() {
    // Types for which we want to receive metrics.
    val dataTypes = setOf(
        DataType.HEART_RATE_BPM,
        DataType.CALORIES_TOTAL,
        DataType.DISTANCE
    )

    // Create a one-time goal.
    val calorieGoal = ExerciseGoal.createOneTimeGoal(
        DataTypeCondition(
            dataType = DataType.CALORIES_TOTAL,
            threshold = CALORIES_THRESHOLD,
            comparisonType = ComparisonType.GREATER_THAN_OR_EQUAL
        )
    )

    // Create a milestone goal. To make a milestone for every kilometer, set the initial
    // threshold to 1km and the period to 1km.
    val distanceGoal = ExerciseGoal.createMilestone(
        condition = DataTypeCondition(
            dataType = DataType.DISTANCE_TOTAL,
            threshold = DISTANCE_THRESHOLD,
            comparisonType = ComparisonType.GREATER_THAN_OR_EQUAL
        ),
        period = DISTANCE_THRESHOLD
    )

    val config = ExerciseConfig(
        exerciseType = ExerciseType.RUNNING,
        dataTypes = dataTypes,
        isAutoPauseAndResumeEnabled = false,
        isGpsEnabled = true,
        exerciseGoals = mutableListOf<ExerciseGoal<Double>>(calorieGoal, distanceGoal)
    )
    exerciseClient.startExerciseAsync(config).await()
}

Tüm egzersizler için turları da işaretleyebilirsiniz. Sağlık Hizmetleri, tur süresi boyunca toplanan metrikleri içeren bir ExerciseLapSummary sağlar.

Önceki örnekte, konum verileri istenirken doğru olması gereken isGpsEnabled değerinin kullanımı gösterilmektedir. Ancak GPS'yi kullanmak diğer metriklerde de yardımcı olabilir. ExerciseConfig, mesafeyi DataType olarak belirtirse varsayılan olarak mesafeyi tahmin etmek için adımlar kullanılır. İsteğe bağlı olarak GPS'yi etkinleştirerek mesafeyi tahmin etmek için konum bilgileri kullanılabilir.

Antrenmanı duraklatma, devam ettirme ve sonlandırma

pauseExerciseAsync() veya endExerciseAsync() gibi uygun bir yöntem kullanarak antrenmanları duraklatabilir, devam ettirebilir ve sonlandırabilirsiniz.

Bilgi kaynağı olarak ExerciseUpdate adresindeki durumu kullanın. Egzersiz, pauseExerciseAsync() çağrısı döndürüldüğünde değil, bu durum ExerciseUpdate mesajına yansıtıldığında duraklatılmış olarak kabul edilir. Bu, özellikle kullanıcı arayüzü durumları söz konusu olduğunda dikkate alınması gereken önemli bir noktadır. Kullanıcı duraklat düğmesine basarsa duraklat düğmesini devre dışı bırakın ve Sağlık Hizmetleri'nden pauseExerciseAsync() numaralı telefonu arayın. ExerciseUpdate.exerciseStateInfo.state simgesini kullanarak Sağlık Hizmetleri'nin duraklatılmış duruma ulaşmasını bekleyin ve ardından düğmeyi devam ettirme konumuna getirin. Bunun nedeni, Sağlık Hizmetleri durum güncellemelerinin düğmeye basmaktan daha uzun sürmesidir. Bu nedenle, tüm kullanıcı arayüzü değişikliklerini düğmeye basma işlemlerine bağlarsanız kullanıcı arayüzü, Sağlık Hizmetleri durumuyla senkronize olmayabilir.

Aşağıdaki durumlarda bunu göz önünde bulundurun:

  • Otomatik duraklatma etkin: Antrenman, kullanıcı etkileşimi olmadan duraklatılabilir veya başlatılabilir.
  • Başka bir uygulama antrenman başlatırsa: Antrenmanınız kullanıcı etkileşimi olmadan sonlandırılabilir.

Uygulamanızın antrenmanı başka bir uygulama tarafından sonlandırılırsa uygulamanız bu sonlandırmayı sorunsuz bir şekilde ele almalıdır:

  • Kullanıcının ilerlemesinin silinmemesi için kısmi antrenman durumunu kaydedin.
  • Devam Eden Etkinlik simgesini kaldırın ve kullanıcıya antrenmanın başka bir uygulama tarafından sonlandırıldığını bildiren bir bildirim gönderin.

Ayrıca, devam eden bir egzersiz sırasında izinlerin iptal edildiği durumları da ele alın. Bu, isEnded durumu kullanılarak AUTO_END_PERMISSION_LOST değerine sahip bir ExerciseEndReason ile gönderilir. Bu durumu, sonlandırma durumuna benzer şekilde ele alın: Kısmi durumu kaydedin, Devam Eden Etkinlik simgesini kaldırın ve kullanıcıya ne olduğuyla ilgili bir bildirim gönderin.

Aşağıdaki örnekte, feshi doğru şekilde nasıl kontrol edeceğinizi görebilirsiniz:

val callback = object : ExerciseUpdateCallback {
    override fun onExerciseUpdateReceived(update: ExerciseUpdate) {
        if (update.exerciseStateInfo.state.isEnded) {
            // Workout has either been ended by the user, or otherwise terminated
        }
        ...
    }
    ...
}

Etkin süreyi yönetme

Bir uygulama, egzersiz sırasında antrenmanın etkin süresini gösterebilir. Uygulamanın, Sağlık Hizmetleri'nin ve cihazın Mikro Denetleyici Birimi'nin (MCU) (egzersiz takibi yapan düşük güçlü işlemci) aynı etkin süreye sahip olması ve senkronize olması gerekir. Bunu yönetmenize yardımcı olmak için Sağlık Hizmetleri, uygulamanın zamanlayıcısını başlatabileceği bir ana nokta sağlayan bir ActiveDurationCheckpoint gönderir.

Etkin süre MCU'dan gönderildiği ve uygulamaya ulaşması biraz zaman alabileceği için ActiveDurationCheckpoint iki özellik içerir:

  • activeDuration: Egzersizin etkin olduğu süre
  • time: Etkin sürenin hesaplandığı zaman

Bu nedenle, uygulamada bir egzersizin etkin süresi aşağıdaki denklem kullanılarak ActiveDurationCheckpoint'ten hesaplanabilir:

(now() - checkpoint.time) + checkpoint.activeDuration

Bu, MCU'da hesaplanan etkin süre ile uygulamaya ulaşması arasındaki küçük farkı hesaba katar. Bu, uygulamada bir kronometre başlatmak ve uygulamanın zamanlayıcısının Health Services ve MCU'daki zamanla mükemmel şekilde uyumlu olmasını sağlamak için kullanılabilir.

Egzersiz duraklatılmışsa uygulama, hesaplanan süre kullanıcı arayüzünde gösterilen süreyi geçene kadar kullanıcı arayüzündeki zamanlayıcıyı yeniden başlatmayı bekler. Bunun nedeni, duraklatma sinyalinin Health Services'e ve MCU'ya hafif bir gecikmeyle ulaşmasıdır. Örneğin, uygulama t=10 saniyede duraklatılırsa Health Services, PAUSED güncellemesini t=10,2 saniyeye kadar uygulamaya yayınlamayabilir.

ExerciseClient'taki verilerle çalışma

Uygulamanızın kaydettiği veri türleriyle ilgili metrikler ExerciseUpdate mesajlarında yayınlanır.

İşlemci, mesajları yalnızca etkin durumdayken veya maksimum raporlama süresine (ör. 150 saniyede bir) ulaşıldığında gönderir. activeDuration ile bir kronometreyi ilerletmek için ExerciseUpdate sıklık değerini kullanmayın. Bağımsız bir kronometrenin nasıl uygulanacağına dair örnek için GitHub'daki Alıştırma örneğine bakın.

Kullanıcı bir antrenmana başladığında ExerciseUpdate mesajları saniyede bir gibi sıklıkta gönderilebilir. Kullanıcı antrenmanı başlattığında ekran kapanabilir. Bu durumda Sağlık Hizmetleri, ana işlemciyi uyandırmamak için verileri daha seyrek gönderebilir ancak yine de aynı sıklıkta örnekleyebilir. Kullanıcı ekrana baktığında, gruplandırılma sürecindeki tüm veriler hemen uygulamanıza gönderilir.

Gruplandırma hızını kontrol etme

Bazı senaryolarda, ekran kapalıyken uygulamanızın belirli veri türlerini alma sıklığını kontrol etmek isteyebilirsiniz. BatchingMode nesnesi, uygulamanızın veri yayınlarını daha sık almak için varsayılan gruplandırma davranışını geçersiz kılmasına olanak tanır.

Gruplandırma hızını yapılandırmak için aşağıdaki adımları uygulayın:

  1. Belirli bir BatchingMode tanımının cihaz tarafından desteklenip desteklenmediğini kontrol edin:

    // Confirm BatchingMode support to control heart rate stream to phone.
    suspend fun supportsHrWorkoutCompanionMode(): Boolean {
        val capabilities = exerciseClient.getCapabilities()
        return BatchingMode.HEART_RATE_5_SECONDS in
                capabilities.supportedBatchingModeOverrides
    }
    
  2. Aşağıdaki kod snippet'inde gösterildiği gibi, ExerciseConfig nesnesinin belirli bir BatchingMode kullanması gerektiğini belirtin.

    val config = ExerciseConfig(
        exerciseType = ExerciseType.WORKOUT,
        dataTypes = setOf(
            DataType.HEART_RATE_BPM,
            DataType.TOTAL_CALORIES
        ),
        // ...
        batchingModeOverrides = setOf(BatchingMode.HEART_RATE_5_SECONDS)
    )
    
  3. İsteğe bağlı olarak, egzersiz süresince belirli bir gruplandırma davranışının devam etmesini sağlamak yerine egzersiz sırasında BatchingMode'ü dinamik olarak yapılandırabilirsiniz:

    val desiredModes = setOf(BatchingMode.HEART_RATE_5_SECONDS)
    exerciseClient.overrideBatchingModesForActiveExercise(desiredModes)
    
  4. Özelleştirilmiş BatchingMode öğesini temizlemek ve varsayılan davranışa dönmek için exerciseClient.overrideBatchingModesForActiveExercise() öğesine boş bir küme gönderin.

Zaman damgaları

Her veri noktasının zaman noktası, cihazın açılmasından sonraki süreyi temsil eder. Bunu bir zaman damgasına dönüştürmek için aşağıdakileri yapın:

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

Bu değer daha sonra her veri noktası için getStartInstant() veya getEndInstant() ile kullanılabilir.

Veri doğruluğu

Bazı veri türlerinde her veri noktasıyla ilişkili doğruluk bilgileri olabilir. Bu, accuracy mülkünde gösterilir.

HrAccuracy ve LocationAccuracy sınıfları sırasıyla HEART_RATE_BPM ve LOCATION veri türleri için doldurulabilir. Mevcut olduğunda, her veri noktasının uygulamanız için yeterli doğrulukta olup olmadığını belirlemek üzere accuracy mülkünü kullanın.

Verileri depolama ve yükleme

Sağlık Hizmetleri'nden iletilen verileri korumak için Room'u kullanın. Veri yükleme işlemi, Work Manager gibi bir mekanizma kullanılarak alıştırmanın sonunda gerçekleşir. Bu sayede, veri yüklemeyle ilgili ağ çağrıları egzersiz bitene kadar ertelenir. Böylece egzersiz sırasında güç tüketimi en aza indirilir ve çalışma basitleştirilir.

Entegrasyon kontrol listesi

Sağlık Hizmetleri'nin ExerciseClient özelliğini kullanan uygulamanızı yayınlamadan önce, kullanıcı deneyiminizde yaygın olarak karşılaşılan bazı sorunların yaşanmaması için aşağıdaki yapılacaklar listesine göz atın. Şunları onaylayın:

  • Uygulamanız, her çalıştırıldığında egzersiz türünün ve cihazın özelliklerini kontrol eder. Böylece, belirli bir cihazın veya egzersizin uygulamanızın ihtiyaç duyduğu veri türlerinden birini desteklemediğini algılayabilirsiniz.
  • Gerekli izinleri isteyip korur ve bunları manifest dosyanızda belirtirsiniz. Uygulamanız, prepareExerciseAsync() işlevini çağırmadan önce çalışma zamanında istenen izinlerin verildiğini onaylar.
  • Uygulamanız, getCurrentExerciseInfoAsync() iznini aşağıdaki durumlarda kullanmak için kullanıyor:
    • Bir egzersiz zaten izleniyor ve uygulamanız önceki egzersizi geçersiz kılıyor.
    • Başka bir uygulama egzersizinizi sonlandırdı. Bu durum, kullanıcı uygulamayı yeniden açtığında başka bir uygulamanın devraldığı için egzersizin durdurulduğunu açıklayan bir mesajla karşılaştığında ortaya çıkabilir.
  • LOCATION verilerini kullanıyorsanız:
    • Uygulamanız, hazırlık görüşmesi dahil olmak üzere egzersiz süresince ilgili foregroundServiceType ile ForegroundService oluşturur.
    • isProviderEnabled(LocationManager.GPS_PROVIDER) kullanarak cihazda GPS'nin etkin olup olmadığını kontrol edin ve gerekirse kullanıcıdan konum ayarlarını açmasını isteyin.
    • Düşük gecikmeli konum verileri almanın büyük önem taşıdığı zorlu kullanım alanları için Fused Location Provider'ı (FLP) entegre edebilir ve verilerini ilk konum düzeltmesi olarak kullanabilirsiniz. Sağlık Hizmetleri'nden daha kararlı konum bilgileri alınabilirse FLP yerine bu bilgileri kullanın.
  • Uygulamanız veri yükleme gerektiriyorsa veri yüklemeyle ilgili tüm ağ çağrıları, alıştırma sona erene kadar ertelenebilir. Aksi takdirde, uygulamanız egzersiz boyunca gerekli ağ çağrılarını az miktarda yapar.