Health Connect, StepsRecord kullanılarak adım sayılarının kaydedilmesi için adım veri türünü sağlar. Adımlar, sağlık ve fitness takibinde temel bir ölçümdür.
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,
SensorManageruygulamasındakiTYPE_STEP_COUNTERsensö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,
androidpaket adıylaDataOriginiç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_STEPSizni verildiğinde etkin olur.
Health Connect'in kullanılabilirliğini kontrol etme
Uygulamanız, Health Connect'i kullanmaya çalışmadan önce kullanıcının cihazında Health Connect'in kullanılabilir olduğunu doğrulamalıdır. Health Connect bazı cihazlarda önceden yüklenmemiş veya devre dışı bırakılmış olabilir.
HealthConnectClient.getSdkStatus() yöntemini kullanarak kullanılabilirliği kontrol edebilirsiniz.
Health Connect'in kullanıma sunulup sunulmadığını kontrol etme
fun checkHealthConnectAvailability(context: Context) { val providerPackageName = "com.google.android.apps.healthdata" // Or get from HealthConnectClient.DEFAULT_PROVIDER_PACKAGE_NAME val availabilityStatus = HealthConnectClient.getSdkStatus(context, providerPackageName) if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE) { // Health Connect is not available. Guide the user to install/enable it. // For example, show a dialog. return // early return as there is no viable integration } if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED) { // Health Connect is available but requires an update. // Optionally redirect to package installer to find a provider, for example: val uriString = "market://details?id=$providerPackageName&url=healthconnect%3A%2F%2Fonboarding" context.startActivity( Intent(Intent.ACTION_VIEW).apply { setPackage("com.android.vending") data = Uri.parse(uriString) putExtra("overlay", true) putExtra("callerId", context.packageName) } ) return } // Health Connect is available, obtain a HealthConnectClient instance val healthConnectClient = HealthConnectClient.getOrCreate(context) // Issue operations with healthConnectClient }
getSdkStatus() tarafından döndürülen duruma bağlı olarak, gerekirse kullanıcıyı Google Play Store'dan Health Connect'i yüklemeye veya güncellemeye yönlendirebilirsiniz.
Gerekli izinler
Adımlara erişim aşağıdaki izinlerle korunur:
android.permission.health.READ_STEPSandroid.permission.health.WRITE_STEPS
Uygulamanıza adım sayma özelliği eklemek için öncelikle Steps veri türüyle ilgili izinleri isteyerek başlayın.
Adım yazabilmek için beyan etmeniz gereken izin aşağıda verilmiştir:
<application>
<uses-permission
android:name="android.permission.health.WRITE_STEPS" />
...
</application>
Adımları okumak için aşağıdaki izinleri istemeniz gerekir:
<application>
<uses-permission
android:name="android.permission.health.READ_STEPS" />
...
</application>
Kullanıcıdan izin isteyin
İstemci örneği oluşturduktan sonra uygulamanızın kullanıcıdan izin istemesi gerekir. Kullanıcıların izinleri istedikleri zaman vermesine veya reddetmesine izin verilmelidir.
Bunun için gerekli veri türleri için bir izin grubu oluşturun. Gruptaki izinlerin önce Android manifestinizde tanımlandığından emin olun.
// Create a set of permissions for required data types
val PERMISSIONS =
setOf(
HealthPermission.getReadPermission(StepsRecord::class),
HealthPermission.getWritePermission(StepsRecord::class)
)
Uygulamanıza gerekli izinlerin verilip verilmediğini görmek için getGrantedPermissions aracını kullanın. Aksi takdirde, bu izinleri istemek için createRequestPermissionResultContract seçeneğini kullanın. Bu işlem, Health Connect izinleri ekranını gösterir.
// Create the permissions launcher
val requestPermissionActivityContract = PermissionController.createRequestPermissionResultContract()
val requestPermissions = registerForActivityResult(requestPermissionActivityContract) { granted ->
if (granted.containsAll(PERMISSIONS)) {
// Permissions successfully granted
} else {
// Lack of required permissions
}
}
suspend fun checkPermissionsAndRun(healthConnectClient: HealthConnectClient) {
val granted = healthConnectClient.permissionController.getGrantedPermissions()
if (granted.containsAll(PERMISSIONS)) {
// Permissions already granted; proceed with inserting or reading data
} else {
requestPermissions.launch(PERMISSIONS)
}
}
Kullanıcılar izinleri istedikleri zaman verebilir veya iptal edebilir. Bu nedenle, uygulamanız izinleri kullanmadan önce her seferinde kontrol etmeli ve izinlerin kaybedildiği senaryoları ele almalıdır.
Adımlar kaydında yer alan bilgiler
Her StepsRecord aşağıdaki bilgileri içerir:
count: Zaman aralığında atılan adım sayısıdır (Longolarak).startTime: Ölçüm aralığının başlangıç zamanı.endTime: Ölçüm aralığının bitiş zamanı.startZoneOffset: Başlangıç zamanının saat dilimi farkı.endZoneOffset: Bitiş zamanının saat dilimi farkı.
Desteklenen toplamalar
StepsRecord için aşağıdaki toplu değerler kullanılabilir:
StepsCadenceRecord için aşağıdaki toplu değerler kullanılabilir:
Örnek kullanım
Aşağıdaki bölümlerde StepsRecord verilerinin nasıl okunacağı ve yazılacağı gösterilmektedir.
Adım verilerini yazma
Uygulamanız, StepsRecord örnekleri ekleyerek adım sayısı verilerini yazabilir. Aşağıdaki örnekte, bir kullanıcının attığı 1.000 adımın nasıl kaydedileceği gösterilmektedir:
val zoneOffset = ZoneOffset.systemDefault().rules.getOffset(startTime) val stepsRecord = StepsRecord( count = 120, startTime = startTime, endTime = endTime, startZoneOffset = zoneOffset, endZoneOffset = zoneOffset, metadata = Metadata( device = Device(type = Device.TYPE_WATCH), recordingMethod = Metadata.RECORDING_METHOD_AUTOMATICALLY_RECORDED ) ) healthConnectClient.insertRecords(listOf(stepsRecord))
Birleştirilmiş verileri okuma
Adım verilerini okumanın en yaygın yolu, belirli bir süre boyunca atılan toplam adımları toplamaktır. Aşağıdaki örnekte, belirli bir zaman aralığında bir kullanıcının toplam adım sayısının nasıl okunacağı gösterilmektedir:
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 }
Ham verileri okuma
Aşağıdaki örnekte, başlangıç ve bitiş zamanı arasındaki ham StepsRecord verilerinin nasıl okunacağı gösterilmektedir:
val response = healthConnectClient.readRecords( ReadRecordsRequest( StepsRecord::class, timeRangeFilter = TimeRangeFilter.between(startTime, endTime) ) ) response.records.forEach { record -> /* Process records */ }