ExerciseClient ile egzersiz kaydetme

Sağlık Hizmetleri, ExerciseClient aracılığıyla egzersiz uygulamaları için destek sağlar. ExerciseClient ile uygulamanız, egzersizin ne zaman yapılacağını kontrol edebilir, egzersiz hedefleri ekleyebilir ve egzersiz durumu, egzersiz etkinlikleri veya diğer metrikler hakkında güncellemeler alabilir. Daha fazla bilgi için Sağlık Hizmetleri'nin desteklediği egzersiz türlerinin tam listesine bakın.

GitHub'daki Exercise sample (Egzersiz örneği) bölümüne bakın.

Bağımlılık ekleme

Sağlık Hizmetleri'ne bağımlılık eklemek için projenize Google Maven deposunu 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ı

Health Services ile 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 saat yüzüne dönebilir. Sistem, etkinliğinizin üzerinde bir şey gösterebilir veya ekran, belirli bir süre etkinlik olmadığında kapanabilir. Tüm antrenman boyunca doğru ç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 kullanabilir ve kol saati yüzeylerinizde bir gösterge görüntüleyebilirsiniz. Böylece kullanıcılar egzersize hızlıca geri dönebilir.

Ön plan hizmetinizde konum verilerini uygun şekilde istemeniz gerekir. Manifest dosyanızda gerekli ön plan hizmeti 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>

prepareExercise() araması içeren antrenman öncesi aktiviteniz ve antrenman aktiviteniz için AmbientLifecycleObserver kullanın. Ancak egzersiz sırasında veya ortam modundayken ekranı güncellememelisiniz. Bunun nedeni, cihaz ekranı ortam modundayken Sağlık Hizmetleri'nin güç tasarrufu için egzersiz verilerini toplu olarak işlemesidir. Bu nedenle, gösterilen bilgiler güncel olmayabilir. Egzersiz sırasında, kullanıcı için anlamlı verileri gösterin. Güncel bilgileri veya boş bir ekranı görüntüleyebilirsiniz.

Özellikleri kontrol etme

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

Uygulama başlatıldığında 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.

Hangi metrikleri isteyebileceğinizi, hangi egzersiz hedeflerini yapılandırabileceğinizi ve bu tür için hangi özelliklerin kullanılabildiğini görmek üzere seçtiğ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ürleri listelenir. 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ızda kullanıcının otomatik duraklatma özelliğini kullanmasına izin veriliyorsa supportsAutoPauseAndResume kullanarak bu işlevin cihaz tarafından desteklendiğ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şlevinin desteklenip desteklenmediği 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 kaydolma

Egzersiz güncellemeleri dinleyiciye iletilir. Uygulamanız aynı anda yalnızca tek bir dinleyici kaydedebilir. Aşağıdaki örnekte gösterildiği gibi, egzersize 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)

Egzersiz ömrünü 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.

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

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

Aşağıdaki örnekte, getCurrentExerciseInfoAsync ile mevcut bir alıştırmanın 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 istediğinden ve koruduğundan emin olun. Uygulamanız LOCATION verilerini kullanıyorsa uygulamanızın bu veriler için de uygun izinleri istediğinden ve koruduğundan emin olun.

Tüm veri türleri için prepareExercise() veya startExercise() numaralarını aramadan ö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 izni isteme başlıklı makaleyi inceleyin. Health Services, gerekli izinler verilmemişse 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 bir süre alabilir ya da kullanıcı, antrenmanına başlamadan önce verilerini görmek isteyebilir. İsteğe bağlı prepareExerciseAsync() yöntemi, bu sensörlerin ısınmasına ve egzersiz için zamanlayıcıyı başlatmadan verilerin alınmasına olanak tanır. activeDuration bu hazırlık süresinden etkilenmez.

prepareExerciseAsync() numarasına aramadan önce şunları kontrol edin:

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

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

  • Uygulamanızın vücut sensörleri (API düzeyi 35 veya daha düşük), nabız (API düzeyi 36 ve üzeri), hareket tanıma ve ayrıntılı konum için çalışma zamanı izinlerine sahip olduğunu onaylayın. Eksik izinler için kullanıcıdan çalışma zamanı izinleri isteyin ve yeterli bağlam sağlayın. Kullanıcı belirli bir izni vermezse prepareExerciseAsync() çağrısından bu izinle ilişkili veri türlerini kaldırın. Ne vücut sensörü (API düzeyi 36 ve üzeri sürümlerde kalp atış hızı) ne de konum izinleri verilmediyse prepareExerciseAsync() işlevini çağırmayın. Çünkü hazırlık çağrısı, egzersize başlamadan önce kararlı bir kalp atış hızı veya GPS düzeltmesi elde etmek için özel olarak kullanılır. Uygulama, bu izinleri gerektirmeyen adım tabanlı mesafe, tempo, hız ve diğer metrikleri almaya devam edebilir.

prepareExerciseAsync() ile yaptığınız görüşmenin başarılı olacağını doğrulamak için aşağıdakileri yapın:

  • Hazırlık çağrısını içeren antrenman öncesi etkinlik için AmbientLifecycleObserver kullanın.
  • Ön plan hizmetinizden prepareExerciseAsync() işlevini çağırı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 etkinliğinden uzaklaşı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 durumuna geldiğinde, sensör kullanılabilirliği güncellemeleri onAvailabilityChanged() üzerinden ExerciseUpdateCallback ile gönderilir. Bu bilgiler daha sonra kullanıcıya sunulur. Kullanıcı, antrenmanına başlayıp başlamayacağına bu bilgilere göre karar verebilir.

Antrenmanı başlatma

Bir egzersize başlamak istediğinizde ExerciseConfig oluşturarak egzersiz türünü, metrik almak istediğiniz veri türlerini ve egzersiz hedeflerini ya da kilometre taşlarını yapılandırın.

Egzersiz hedefleri bir DataType ve bir koşuldan oluşur. Egzersiz hedefleri, bir koşul karşılandığında (ör. kullanıcının belirli bir mesafeyi koşması) tetiklenen tek seferlik hedeflerdir. Egzersiz kilometre taşı da ayarlayabilirsiniz. Egzersiz kilometre taşları birden çok kez tetiklenebilir. Örneğin, kullanıcı belirlenen mesafeyi her geçtiğinde tetiklenebilir.

Aşağıdaki örnekte her türden bir hedef oluşturma işlemi 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, ExerciseLapSummary süresince toplanan metriklerle birlikte ExerciseLapSummary sağlar.

Önceki örnekte, konum verileri istenirken doğru olması gereken isGpsEnabled kullanımı gösterilmektedir. Ancak GPS kullanmak diğer metrikler için de faydalı olabilir. ExerciseConfig, mesafeyi DataType olarak belirtiyorsa bu durumda mesafe tahmini için varsayılan olarak adımlar kullanılır. İsteğe bağlı olarak GPS'yi etkinleştirerek mesafeyi tahmin etmek için konum bilgilerini kullanabilirsiniz.

Antrenmanı duraklatma, devam ettirme ve bitirme

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

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

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

  • Otomatik duraklatma etkinleştirilmişse: 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 egzersizi başka bir uygulama tarafından sonlandırılırsa uygulamanız sonlandırmayı sorunsuz bir şekilde yönetmelidir:

  • Kullanıcının ilerlemesinin silinmemesi için kısmi antrenman durumunu kaydetme
  • Devam Eden Etkinlik simgesini kaldırın ve kullanıcıya, egzersizinin 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 durumu da ele alın. Bu, isEnded durumu kullanılarak gönderilir ve AUTO_END_PERMISSION_LOST ExerciseEndReason içerir. Bu durumu fesih durumuyla 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, fesih durumunun nasıl doğru şekilde kontrol edileceği gösterilmektedir:

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

Etkinlik süresini yönetme

Bir egzersiz sırasında uygulama, antrenmanın aktif süresini gösterebilir. Uygulama, Sağlık Hizmetleri ve cihazın mikro denetleyici birimi (MCU) (egzersiz takibinden sorumlu düşük güçlü işlemci) aynı etkin süreyle senkronize olmalıdır. Bunu yönetmeye yardımcı olmak için Sağlık Hizmetleri, uygulamanın zamanlayıcısını başlatabileceği bir tutturma noktası sağlayan bir ActiveDurationCheckpoint gönderir.

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

  • activeDuration: Egzersizin ne kadar süredir etkin olduğu
  • time: Etkin süre hesaplandığında

Bu nedenle, uygulamada bir egzersizin aktif süresi aşağıdaki denklem kullanılarak ActiveDurationCheckpoint değerinden hesaplanabilir:

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

Bu, etkin sürenin MCU'da hesaplanması ile uygulamaya ulaşması arasındaki küçük farkı açıklar. Bu fark, uygulamada bir kronometre başlatmak ve uygulamanın zamanlayıcısının, Sağlık Hizmetleri ile MCU'daki zamanla mükemmel şekilde senkronize olmasını sağlamak için kullanılabilir.

Egzersiz duraklatılırsa uygulama, kullanıcı arayüzünde zamanlayıcıyı yeniden başlatmak için kullanıcı arayüzünde gösterilen sürenin geçmesini bekler. Bunun nedeni, duraklatma sinyalinin Health Services 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 iletmeyebilir.

ExerciseClient'tan gelen verilerle çalışma

Uygulamanızın kaydolduğu veri türleriyle ilgili metrikler ExerciseUpdate mesajlarıyla gönderilir.

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

Kullanıcı egzersize başladığında ExerciseUpdate iletileri sık sık (ör. her saniyede bir) gönderilebilir. Kullanıcı egzersize başladığında ekran kapanabilir. Ardından, ana işlemciyi uyandırmamak için Sağlık Hizmetleri verileri daha seyrek olarak iletebilir ancak aynı sıklıkta örneklemeye devam edebilir. Kullanıcı ekrana baktığında, toplu işleme alınan tüm veriler anında uygulamanıza teslim edilir.

Toplu işleme 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, veri teslimatlarını daha sık almak için uygulamanızın varsayılan toplu işleme davranışını geçersiz kılmasına olanak tanır.

Örneğin, kol saatinden mobil cihaza sürekli olarak nabız akışı yapılması.

Toplu işleme hızını yapılandırmak için aşağıdaki adımları tamamlayın:

  1. İlgili BatchingMode tanımı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 boyunca belirli bir toplu işleme davranışının devam etmesi yerine, egzersiz sırasında BatchingMode cihazını dinamik olarak yapılandırabilirsiniz:

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

Zaman damgaları

Her veri noktasının zaman noktası, cihazın başlatılmasından bu yana geçen süreyi gösterir. Bunu 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 birlikte kullanılabilir.

Veri doğruluğu

Bazı veri türlerinde her veri noktasıyla ilişkili doğruluk bilgileri olabilir. Bu, accuracy özelliğiyle 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 bir veri noktasının uygulamanız için yeterli doğrulukta olup olmadığını belirlemek üzere accuracy özelliğini kullanın.

Verileri depolama ve yükleme

Health Services'ten sağlanan verileri kalıcı hale getirmek 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üklemek için yapılan ağ çağrılarının egzersiz bitene kadar ertelendiği doğrulanır. Böylece egzersiz sırasında güç tüketimi en aza indirilir ve işler kolaylaştırılır.

Entegrasyon kontrol listesi

Health Services'i kullanan uygulamanızı yayınlamadan önce ExerciseClient, kullanıcı deneyiminizin bazı yaygın sorunlardan kaçındığını doğrulamak için aşağıdaki kontrol listesine bakın. Şunları onaylayın:

  • Uygulamanız, her çalıştığında egzersiz türünün ve cihazın özelliklerini kontrol eder. Bu sayede, belirli bir cihazın veya egzersizin uygulamanızın ihtiyaç duyduğu veri türlerinden birini desteklemediğini tespit edebilirsiniz.
  • Gerekli izinleri isteyip korur ve bunları manifest dosyanızda belirtirsiniz. prepareExerciseAsync() işlevi çağrılmadan önce uygulamanız, çalışma zamanı izinlerinin verildiğini onaylar.
  • Uygulamanız, aşağıdaki durumlarda işlemleri gerçekleştirmek için getCurrentExerciseInfoAsync() kullanıyor:
    • Zaten bir egzersiz 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 yaşanabilir. Kullanıcıya, başka bir uygulama devraldığı için egzersizin durdurulduğunu açıklayan bir mesaj gösterilir.
  • LOCATION verilerini kullanıyorsanız:
    • Uygulamanız, egzersiz süresince (hazırlık görüşmesi dahil) ilgili foregroundServiceType ile ForegroundService bağlantısını korur.
    • isProviderEnabled(LocationManager.GPS_PROVIDER) kullanarak cihazda GPS'in etkinleştirildiğini kontrol eder ve gerekirse kullanıcıyı konum ayarlarını açmaya yönlendirir.
    • Konum verilerinin düşük gecikmeyle alınmasının büyük önem taşıdığı zorlu kullanım alanlarında Fused Location Provider'ı (FLP) entegre etmeyi ve verilerini ilk konum düzeltmesi olarak kullanmayı düşünebilirsiniz. Sağlık Hizmetleri'nden daha kararlı konum bilgileri alındığında, FLP yerine bu bilgileri kullanın.
  • Uygulamanız veri yükleme gerektiriyorsa veri yüklemek için yapılan tüm ağ çağrıları, egzersiz sona erene kadar ertelenir. Aksi takdirde, uygulama boyunca gerekli ağ çağrıları seyrek olarak yapılır.