İçeriğe geç
Tüm yazılar

2026'da Android'de Health Connect: local-first'ten vazgeçmeden veri okuyup yazmak

Android'in Health Connect API'sine 2026 için pratik bir rehber — izinler, arka planda okuma ve local-first uygulamaların bunu neden gerçek değil, isteğe bağlı bir katman olarak görmesi gerektiği.

MFKAPPS 4 dk okuma

Health Connect, Android’in artık sağlık ve fitness uygulamalarından kendi kapalı deposunu tutmak yerine okuyup yazmasını beklediği, cihaz üzerinde çalışan bir veri deposu. Local-first bir uygulama için dürüst bir soru doğuruyor: burası veri yayınlanacak bir yer mi, veri okunacak bir yer mi, yoksa ikisi de mi — ve ikisinden birine evet demek, doğruluk kaynağını, cihazda tutacağına söz verdiğin yerden sessizce uzaklaştırıyor mu. API’nin senden gerçekte ne istediğine ve benim bu konuda nereye çizgi çektiğime bakalım.

Health Connect ne, ne değil

Health Connect sistem seviyesinde bir veri deposu, bir bulut servisi değil. Kayıtlar — adımlar, su tüketimi, kilo, uyku seansları — Android’in erişimine aracılık ettiği yerel bir veritabanında yaşıyor ve kullanıcının onayladığı herhangi bir uygulama bu veritabanı üzerinden okuma ya da yazma yapabiliyor. Çekiciliği de burada: bir su takibi uygulaması ile bir fitness uygulaması, her biri ayrı ve eksik bir sayı tutmak yerine tek bir su tüketimi toplamını paylaşabiliyor. Ama aynı zamanda risk de burada. Uygulaman oraya yazdığı an, kullanıcının okuma izni verdiği başka her uygulama da o veriyi görebiliyor. Health Connect’e dokunduğun anda local-first hiçbir anlam ifade etmiyor değil, ama daha dar bir anlam ifade ediyor: veri hâlâ cihazdan hiç çıkmıyor, ama artık sadece sana görünür olmaktan çıkıyor.

Health Connect uygulaması önceden yüklü gelmeyen telefonlarda, istemci kütüphanesi ilk istekte Play Store’dan bir kurulum ister. Bu başarısızlık yolu için bütçe ayır — yeni bir cihaz ya da sadeleştirilmiş bir ROM, API’yi kullanılamaz bırakabilir ve izin isteğinin çökme değil, gerçek bir yedek planı olması gerekir.

2026 izin modeli

Sağlık izinleri, ActivityCompat.requestPermissions anlamında çalışma zamanı izinleri değil — kendi diyaloğun üzerinden değil, Health Connect uygulamasının sahip olduğu özel bir gerekçe ekranı üzerinden yönlendiriliyorlar. Niyetini manifest’te bildirir, sonra bir sözleşme (contract) başlatırsın:

val requestPermissions = registerForActivityResult(
    PermissionController.createRequestPermissionResultContract()
) { granted ->
    if (HealthPermission.getWritePermission(HydrationRecord::class) in granted) {
        // proceed
    }
}

requestPermissions.launch(
    setOf(
        HealthPermission.getWritePermission(HydrationRecord::class),
        HealthPermission.getReadPermission(HydrationRecord::class),
    )
)

Dönen sonuç kümesi sana yalnızca neyin verildiğini söylüyor, bir şeyin neden reddedildiğini asla söylemiyor — ne “kalıcı olarak reddedildi” bayrağı var, ne de inceleyebileceğin bir gerekçe. Beklediğin bir izin dönen kümede yoksa doğru hamle, dünkü onayın hâlâ geçerli olduğunu varsaymak değil, her okuma veya yazmadan önce PermissionController.getGrantedPermissions() ile kontrol edip zarifçe geri çekilmek. Kullanıcılar Health Connect izinlerini istedikleri an, tamamen uygulamanın yaşam döngüsünün dışında, sistem ayarlarından geri alabiliyor ve bir sonraki API çağrın, izin hiç verilmemiş gibi başarısız oluyor.

Bir kayıt yazmak ve okumak

Bir HydrationRecord, bir zaman aralığı ve bir hacim değerinden oluşan, yazan uygulamanın kendi meta verisine bağlı bir değer:

val record = HydrationRecord(
    startTime = Instant.now(),
    startZoneOffset = ZoneOffset.systemDefault().rules.getOffset(Instant.now()),
    endTime = Instant.now(),
    endZoneOffset = ZoneOffset.systemDefault().rules.getOffset(Instant.now()),
    volume = Volume.milliliters(250.0),
)

healthConnectClient.insertRecords(listOf(record))

Geri okuma, tam tablo taraması değil, bir zaman aralığı sorgusu — senden “her şeyi” değil, bir pencere istemen bekleniyor:

val response = healthConnectClient.readRecords(
    ReadRecordsRequest(
        recordType = HydrationRecord::class,
        timeRangeFilter = TimeRangeFilter.between(
            startOfToday, Instant.now()
        ),
    )
)

Her kayıt bir metadata.dataOrigin taşıyor, böylece kendi yazdıklarını bir fitness takip cihazının ya da başka bir uygulamanın yazdıklarından ayırt edebiliyorsun — birden fazla kaynaktan “bugünün toplamını” topladığın ve çift saymak istemediğin anda işe yarayan bir şey.

Arka planda okuma ayrı bir izin ister

Uygulaman ön planda değilken Health Connect verisi okumak, kayıt başına verilen izne ek olarak PERMISSION_READ_HEALTH_DATA_IN_BACKGROUND gerektiriyor ve Android bunu, gerekçe ekranında kendi satırını hak edecek kadar hassas kabul ediyor. Kullanım senaryon “uygulama açıldığında bir kez senkronize et” ise bunu atla; sadece gerçek bir arka plan işi için iste — kullanıcı uygulamayı açmadan önce sayısını hesaplaması gereken bir widget ya da günlük bir özet bildirimi gibi. İhtiyacın olmadığında istemek teknik olarak başarısız olmuyor; sadece izin ekranını, özelliğin hak ettiğinden daha uzun ve daha ürkütücü hale getiriyor — ki bu da tam olarak izni tamamen kaybetmene mal olan türden bir şey.

Bunu neden isteğe bağlı, katma değerli veri olarak ele alıyorum

Hydrame gibi bir uygulama için Health Connect tek bir nedenle cazip: başka bir yerde de antrenman kaydeden bir kullanıcı, birbiriyle çelişen iki sayı yerine tek bir doğru su tüketimi sayısına kavuşuyor. Ama yanlış bir nedenle de cazip — “Health Connect’e senkronize et”in sessizce “Health Connect artık doğruluk kaynağı” haline gelmesine izin vermek çok kolay, ki bu noktada uygulamanın kendi yerel veritabanı sapabilen bir önbelleğe dönüşüyor ve hiçbir şeyin cihazdan çıkmadığı sözü, başka bir uygulamaya okuma izni verildikçe her seferinde biraz daha bulanıklaşıyor. Benim gerçekten göndereceğim sürüm, Health Connect’i aynı yerel kaydın tek yönlü bir yayını olarak ele alıyor, uygulamanın çalışması için bağımlı olduğu bir okuma yolu olarak asla — Health Connect uygulamasını tamamen kaldır, temel deneyim bunu fark etmemeli.

Kontrol listesi

Health Connect’i bağlamadan önce: kullanılabilirliği kontrol et ve uygulamanın eksik olduğu durumu ele al, yalnızca kullandığın belirli kayıt izinlerini iste, önbelleğe alınmış üç ekran önceki bir “evet”e güvenmek yerine her erişimden önce verilen izinleri yeniden kontrol et, arka plan okumalarını gerçek arka plan işleriyle sınırla ve Health Connect’e yayın mı yapıyorsun yoksa ona bağımlı mısın buna baştan karar ver — çünkü API ikisine de seve seve izin verir ve yalnızca biri, local-first bir uygulamayı verisinin gerçekte nerede yaşadığı konusunda dürüst tutar.