Ham verileri okuma

Aşağıdaki örnekte, yaygın iş akışının bir parçası olarak ham verilerin nasıl okunacağı gösterilmektedir.

Verileri okuma

Health Connect, uygulamaların ön planda ve arka planda çalışırken veri deposundaki verileri okumasına olanak tanır:

  • Ön planda okuma: Uygulamanız ön plandayken Health Connect'teki verileri normalde okuyabilirsiniz. Bu gibi durumlarda, kullanıcı veya sistem okuma işlemi sırasında uygulamanızı arka plana yerleştirirse bu işlemi çalıştırmak için ön plan hizmeti kullanmayı düşünebilirsiniz.

  • Arka planda okuma: Kullanıcıdan ek izin isteyerek, kullanıcı veya sistem uygulamanızı arka plana yerleştirdikten sonra verileri okuyabilirsiniz. Tam arka planda okuma örneğini inceleyin.

Health Connect'teki Adımlar veri türü, bir kullanıcının okumalar arasında attığı adım sayısını yakalar. Adım sayısı, sağlık, fitness ve sağlıklı yaşam platformlarında ortak bir ölçümü temsil eder. Health Connect, adım sayısı verilerini okumanıza ve yazmanıza olanak tanır.

Kayıtları okumak için bir ReadRecordsRequest oluşturun ve readRecords işlevini çağırırken bunu sağlayın.

Aşağıdaki örnekte, belirli bir süre içinde bir kullanıcının adım sayısı verilerinin nasıl okunacağı gösterilmektedir. SensorManager ile ilgili daha kapsamlı bir örnek için adım sayısı veri kılavuzuna bakın.

val response = healthConnectClient.readRecords(
    ReadRecordsRequest(
        HeartRateRecord::class,
        timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
    )
)
response.records.forEach { record ->
    /* Process records */
}

Ayrıca aggregate kullanarak verilerinizi toplu şekilde okuyabilirsiniz.

suspend fun readStepsAggregate(startTime: Instant, endTime: Instant): Long {
    val response = healthConnectClient.aggregate(
        AggregateRequest(
            metrics = setOf(StepsRecord.COUNT_TOTAL),
            timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
        )
    )
    return response[StepsRecord.COUNT_TOTAL] ?: 0L
}

Mobil cihazdaki adımları okuma

Android 14 (API düzeyi 34) ve SDK Uzantısı sürüm 20 veya sonraki sürümlerde Health Connect, cihaz üzerinde adım sayma özelliği sunar. Herhangi bir uygulamaya READ_STEPS izni verildiyse Health Connect, Android destekli cihazdaki adımları kaydetmeye başlar ve kullanıcılar, adım verilerinin Health Connect Adımlar girişlerine otomatik olarak eklendiğini görür.

Cihaz üzerinde adım sayma özelliğinin kullanılabilir olup olmadığını kontrol etmek için cihazda Android 14 (API düzeyi 34) sürümünün yüklü olduğundan ve SDK uzantısı sürümünün en az 20 olduğundan emin olun:

val isStepTrackingAvailable =
    Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
        SdkExtensions.getExtensionVersion(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) >= 20

Uygulamanız, aggregate kullanarak toplanmış adım sayılarını okuyor ve DataOrigin'ye göre filtrelemiyorsa cihaz üzerindeki adımlar otomatik olarak toplama dahil edilir ve Haziran 2026 güncellemesi için herhangi bir değişiklik yapılması gerekmez.

Cihaz üzerinde yapılan adımlar için ilişkilendirme değişikliği

Haziran 2026 güncellemesinden itibaren, Health Connect tarafından yerel olarak izlenen adımlar com.android.healthconnect.phone.jd5bdd37e1a8d3667a05d0abebfc4a89e gibi bir Sentetik Paket Adı (SPN) ile ilişkilendirilecek.

Daha önce, yerleşik adımlar android paket adıyla ilişkilendiriliyordu. Haziran 2026'dan önce kaydedilen geçmiş adım verileri android paket adını korur.

SPN'ler cihaza özeldir ve kullanıcı gizliliğini korumak için uygulama bazında kapsamlandırılır:

  • Kararlı: Geçerli cihazın SPN'si uygulamanız için kararlıdır.
  • Uygulama Kapsamlı: Aynı cihazdaki farklı uygulamalar, cihaz üzerinde adım verileri için farklı SPN'ler görür.

Cihaz üzerindeki adımlarla ilgili sorgu

SPN'ler kapsamlı ve cihaza özel olduğundan SPN değerlerini sabit kodlamamalısınız. Bunun yerine, mevcut cihazın SPN'sini almak için getCurrentDeviceDataSource() API'yi kullanın.

Cihaz üzerinde adım sayma özelliği için SDK uzantısı sürümü 20 veya sonraki sürümler gerekirken getCurrentDeviceDataSource() API, SDK uzantısı sürümü 11 veya sonraki sürümlerin yüklü olduğu Android 14'te (API düzeyi 34) kullanılabilir.

getCurrentDeviceDataSource() API, Health Connect Jetpack kitaplığında henüz kullanılamamaktadır. Aşağıdaki örneklerde bunun yerine Android Framework API'si kullanılmaktadır:

import android.content.Context
import android.health.connect.HealthConnectManager

val healthConnectManager = context.getSystemService(HealthConnectManager::class.java)
val deviceDataSource = healthConnectManager?.getCurrentDeviceDataSource()
val currentDeviceSpn = deviceDataSource?.deviceDataOrigin?.packageName

Uygulamanızın cihaz üzerinde adımları okuması gerekiyorsa veya adım verilerini kaynak uygulamaya ya da cihaza göre ayrılmış şekilde gösteriyorsa DataOrigin değerinin android olduğu ya da cihazın SPN'siyle eşleştiği kayıtları sorgulamanız gerekir. Uygulamanız adım verileri için ilişkilendirme gösteriyorsa tek tek kayıtların kaynak cihazını belirlemek için metadata.device kullanın. Toplu verilerde SPN ile tanımlanan cihaz üzerinde adımlar için ilişkilendirme amacıyla DeviceDataSource'den model veya manufacturer gibi cihaz meta verilerini kullanabilir ya da cihaz üzerinde adımlar için "Telefonunuz" gibi genel bir etiket kullanabilirsiniz.

Aşağıdaki örnekte, hem android hem de mevcut cihaz SPN'si için filtreleme yaparak cihaz üzerinde toplanan adım sayısı verilerinin nasıl okunacağı gösterilmektedir:

import android.content.Context
import android.health.connect.HealthConnectManager
import android.os.Build
import android.os.ext.SdkExtensions
import androidx.health.connect.client.HealthConnectClient
import androidx.health.connect.client.records.StepsRecord
import androidx.health.connect.client.records.metadata.DataOrigin
import androidx.health.connect.client.request.AggregateRequest
import androidx.health.connect.client.time.TimeRangeFilter
import java.time.Instant

suspend fun readDeviceStepsByTimeRange(
    healthConnectClient: HealthConnectClient,
    context: Context,
    startTime: Instant,
    endTime: Instant
) {
    // 1. Check if SDK Extension 11+ is available for getCurrentDeviceDataSource()
    val isDataSourceApiAvailable = Build.VERSION.SDK_INT >= Build.VERSION_CODES.U &&
            SdkExtensions.getExtensionVersion(Build.VERSION_CODES.U) >= 11

    try {
        val healthConnectManager = context.getSystemService(HealthConnectManager::class.java)

        // 2. Safely fetch the package name only if API is available and data exists
        val currentDeviceSpn = if (isDataSourceApiAvailable) {
            healthConnectManager?.getCurrentDeviceDataSource()?.deviceDataOrigin?.packageName
        } else {
            null
        }

        val dataOriginFilters = mutableSetOf(DataOrigin("android"))

        // 3. Explicit null-safety check using .let
        currentDeviceSpn?.let {
            dataOriginFilters.add(DataOrigin(it))
        }

        val response = healthConnectClient.aggregate(
            AggregateRequest(
                metrics = setOf(StepsRecord.COUNT_TOTAL),
                timeRangeFilter = TimeRangeFilter.between(startTime, endTime),
                dataOriginFilter = dataOriginFilters
            )
        )

        val stepCount = response[StepsRecord.COUNT_TOTAL]

    } catch (e: Exception) {
        // Now this catch block only handles actual runtime exceptions, 
        // rather than Errors from missing methods.
    }
}

Cihaz Üzerinde Adım Sayma

  • Sensör Kullanımı: Health Connect, SensorManager uygulamasındaki TYPE_STEP_COUNTER sensörünü kullanır. Bu sensör, düşük güç tüketimi için optimize edilmiştir. Bu nedenle, arka planda sürekli adım takibi için idealdir.
  • Veri Ayrıntı Düzeyi: Pil ömrünü korumak için adım verileri genellikle gruplandırılır ve Health Connect veritabanına dakikada en fazla bir kez yazılır.
  • İlişkilendirme: Bu özellik tarafından Haziran 2026'dan önce kaydedilen adımlar, android paket adıyla DataOrigin içinde ilişkilendirilir. Bu tarihten sonra, cihaza özel bir SPN ile ilişkilendirilirler. Cihaz üzerinde gerçekleştirilen adımlarda ilişkilendirme değişikliği başlıklı makaleyi inceleyin.
  • Etkinleştirme: Cihazdaki adım sayma mekanizması yalnızca cihazda en az bir uygulamaya Health Connect'te READ_STEPS izni verildiğinde etkin olur.

Arka planda okuma örneği

Verileri arka planda okumak için manifest dosyanızda aşağıdaki izni bildirin:

<application>
  <uses-permission android:name="android.permission.health.READ_HEALTH_DATA_IN_BACKGROUND" />
...
</application>

Aşağıdaki örnekte, WorkManager kullanılarak belirli bir süre içinde bir kullanıcının adım sayısı verilerinin arka planda nasıl okunacağı gösterilmektedir:

class ScheduleWorker(appContext: Context, workerParams: WorkerParameters) :
    CoroutineWorker(appContext, workerParams) {

    override suspend fun doWork(): Result {
        val healthConnectClient = HealthConnectClient.getOrCreate(applicationContext)
        // Perform background read logic here
        return Result.success()
    }
}
@OptIn(ExperimentalFeatureAvailabilityApi::class)
fun enqueueBackgroundReadWorker(context: Context, healthConnectClient: HealthConnectClient) {
    if (healthConnectClient
            .features
            .getFeatureStatus(
                HealthConnectFeatures.FEATURE_READ_HEALTH_DATA_IN_BACKGROUND
            ) == HealthConnectFeatures.FEATURE_STATUS_AVAILABLE
    ) {

        val periodicWorkRequest = PeriodicWorkRequestBuilder<ScheduleWorker>(1, TimeUnit.HOURS)
            .build()

        WorkManager.getInstance(context).enqueueUniquePeriodicWork(
            "read_health_connect",
            ExistingPeriodicWorkPolicy.KEEP,
            periodicWorkRequest
        )
    }
}

ReadRecordsRequest parametresinin varsayılan pageSize değeri 1000'dir. Tek bir readResponse içindeki kayıt sayısı, isteğin pageSize değerini aşıyorsa pageToken kullanarak tüm kayıtları almak için yanıtın tüm sayfalarını yinelemeniz gerekir. Ancak sıklık sınırlamasıyla ilgili sorunlardan kaçınmak için dikkatli olun.

pageToken okuma örneği

İstenen dönemdeki tüm verileri almak için kayıtları okumak üzere pageToken kullanılması önerilir.

Aşağıdaki örnekte, tüm sayfa jetonları tükenene kadar tüm kayıtların nasıl okunacağı gösterilmektedir:

val type = HeartRateRecord::class
val endTime = Instant.now()
val startTime = endTime.minus(Duration.ofDays(7))

try {
    var pageToken: String? = null
    do {
        val readResponse =
            healthConnectClient.readRecords(
                ReadRecordsRequest(
                    recordType = type,
                    timeRangeFilter = TimeRangeFilter.between(
                        startTime,
                        endTime
                    ),
                    pageToken = pageToken
                )
            )
        val records = readResponse.records
        // Do something with records
        pageToken = readResponse.pageToken
    } while (pageToken != null)
} catch (quotaError: IllegalStateException) {
    // Backoff
}
Büyük veri kümelerini okurken en iyi uygulamalar hakkında bilgi edinmek için Sıklık sınırlamasıyla karşılaşmayı önleme planı başlıklı makaleyi inceleyin.

Daha önce yazılan verileri okuma

Daha önce Health Connect'e kayıt yazmış olan uygulamalar geçmiş verileri okuyabilir. Bu, kullanıcının uygulamayı yeniden yüklemesinden sonra uygulamanın Health Connect ile yeniden senkronize olması gereken senaryolar için geçerlidir.

Okumayla ilgili bazı kısıtlamalar vardır:

  • Android 14 ve sonraki sürümler için

    • Bir uygulamanın kendi verilerini okumasıyla ilgili geçmiş sınırlama yoktur.
    • Bir uygulamanın diğer verileri okumasıyla ilgili 30 günlük sınır.
  • Android 13 ve önceki sürümler için

    • Uygulamaların herhangi bir veriyi okumasıyla ilgili 30 günlük sınır.

Kısıtlamalar, okuma izni isteğinde bulunarak kaldırılabilir.

Geçmiş verileri okumak için paket adını ReadRecordsRequest parametresinin dataOriginFilter parametresinde DataOrigin nesnesi olarak belirtmeniz gerekir.

Aşağıdaki örnekte, kalp atış hızı kayıtları okunurken paket adının nasıl belirtileceği gösterilmektedir:

try {
    val response =  healthConnectClient.readRecords(
        ReadRecordsRequest(
            recordType = HeartRateRecord::class,
            timeRangeFilter = TimeRangeFilter.between(startTime, endTime),
            dataOriginFilter = setOf(DataOrigin("com.my.package.name"))
        )
    )
    for (record in response.records) {
        // Process each record
    }
} catch (e: Exception) {
    // Run error handling here
}

30 günden eski verileri okuma

Varsayılan olarak, tüm uygulamalar herhangi bir izin ilk kez verilmeden önceki 30 güne kadar olan Health Connect verilerini okuyabilir.

Okuma izinlerini varsayılan kısıtlamaların ötesine genişletmeniz gerekiyorsa PERMISSION_READ_HEALTH_DATA_HISTORY isteğinde bulunun. Aksi takdirde, bu izin olmadan 30 günden eski kayıtları okuma girişimi hatayla sonuçlanır.

Silinen bir uygulamanın izin geçmişi

Bir kullanıcı uygulamanızı silerse geçmiş izni de dahil olmak üzere tüm izinler iptal edilir. Kullanıcı uygulamanızı yeniden yükleyip tekrar izin verirse aynı varsayılan kısıtlamalar geçerli olur ve uygulamanız, Health Connect'teki verileri bu yeni tarihten önceki 30 gün boyunca okuyabilir.

Örneğin, kullanıcının uygulamanızı 10 Mayıs 2023'te sildiğini, 15 Mayıs 2023'te yeniden yüklediğini ve okuma izni verdiğini varsayalım. Uygulamanızın varsayılan olarak veri okuyabileceği en erken tarih 15 Nisan 2023'tür.

İstisnaları işleme

Health Connect, bir sorunla karşılaşıldığında CRUD işlemleri için standart istisnalar oluşturur. Uygulamanız bu istisnaların her birini uygun şekilde yakalayıp işlemelidir.

HealthConnectClient üzerindeki her yöntemde oluşturulabilecek istisnalar listelenir. Genel olarak uygulamanız aşağıdaki istisnaları işlemelidir:

Tablo 1: Health Connect istisnaları ve önerilen en iyi uygulamalar
İstisna Açıklama Önerilen en iyi uygulama
IllegalStateException Aşağıdaki senaryolardan biri gerçekleşti:

  • Health Connect hizmeti kullanılamıyor.
  • İstek geçerli bir yapı değil. Örneğin, Instant nesnesinin timeRangeFilter için kullanıldığı, belirli aralıklarla oluşturulan gruplardaki toplu istek.

İstek göndermeden önce girişlerle ilgili olası sorunları ele alın. Tercihen, hata işleme stratejileri uygulayabilmek için değişkenlere değer atayın veya bunları isteklerinizde doğrudan kullanmak yerine özel bir işlevde parametre olarak kullanın.
IOException Diskten veri okuma ve diske veri yazma sırasında sorunlar oluşuyor. Bu sorunu önlemek için aşağıdaki önerilerden yararlanabilirsiniz:

  • Kullanıcı girişlerini yedekleyin.
  • Toplu yazma işlemleri sırasında oluşan sorunları çözebilme Örneğin, işlemin sorunu aştığından ve kalan işlemleri gerçekleştirdiğinizden emin olun.
  • İstek sorunlarını gidermek için yeniden deneme ve geri çekilme stratejileri uygulayın.

RemoteException SDK'nın bağlandığı temel hizmette veya bu hizmetle iletişim kurulurken hatalar oluştu.

Örneğin, uygulamanız belirli bir uid ile kaydı silmeye çalışıyor. Ancak, temel hizmette kontrol yapıldıktan sonra kaydın mevcut olmadığı anlaşılınca istisna oluşturulur.
Bu sorunu önlemek için aşağıdaki önerilerden yararlanabilirsiniz:

  • Uygulamanızın veri deposu ile Health Connect arasında düzenli senkronizasyonlar yapın.
  • İstek sorunlarını gidermek için yeniden deneme ve geri çekilme stratejileri uygulayın.

SecurityException İstekler, verilmeyen izinler gerektirdiğinde sorunlar oluşur. Bunu önlemek için yayınlanmış uygulamanızda Health Connect veri türlerinin kullanımını beyan ettiğinizden emin olun. Ayrıca, Health Connect izinlerini manifest dosyasında ve etkinliğinizde beyan etmeniz gerekir.