Mobil cihazlarda Kayıt API'sı

Mobil cihazlarda Recording API, uygulamanızın adım sayısının verilerini alan bir adım sayıcıya benzer şekilde, mobil cihazdan adım sayısını pil tasarrufu sağlayacak şekilde kaydetmesine olanak tanır. Bu API hesapsızdır. Yani hizmeti kullanmak için Google Hesabı gerekmez ve veriler cihaz üzerinde depolanır.

Bu kılavuzda, sağlık ve fitness deneyimlerinizde mobil cihazlarda Recording API'yi nasıl kullanacağınız gösterilmektedir.

Önemli ayrıntılar

Mobil cihazlarda Recording API'ye özgü birkaç önemli özellik vardır:

  • Kayıt aboneliği başladıktan veya yenilendikten sonra, en son abonelikten itibaren 10 güne kadar olan verilere erişilebilir.
  • Veriler yalnızca etkin bir abonelik olduğunda kullanılabilir. unsubscribe çağrısı yapılarak kaldırılan aboneliklere ait toplanan adım verilerine erişilemez.

Veri türleri

Mobil cihazlarda Recording API aşağıdaki veri türlerini kaydedebilir:

Başlayın

Başlamak için build.gradle dosyanıza aşağıdaki bağımlılığı ekleyin:

Kotlin DSL

plugin {
  id("com.android.application")
}

...

dependencies {
  implementation("com.google.android.gms:play-services-fitness:21.2.0")
}

Groovy DSL

apply plugin: 'com.android.application'

...

dependencies {
  implementation 'com.google.android.gms:play-services-fitness:21.2.0'
}

İzin isteme

Mobil cihazlarda Recording API'yi kullanarak veri kaydetmek için uygulamanızın aşağıdaki izni istemesi gerekir:

  • android.permission.ACTIVITY_RECOGNITION

Play Hizmetleri sürüm kontrolünü gerçekleştirme

Kayıt API'sini mobil cihazlarda kullanmak için kullanıcının Google Play Hizmetleri'ni LOCAL_RECORDING_CLIENT_MIN_VERSION_CODE sürümüne güncellemesi gerekir. Bunu isGooglePlayServicesAvailable yöntemini kullanarak kontrol edebilirsiniz:

val hasMinPlayServices = isGooglePlayServicesAvailable(context, LocalRecordingClient.LOCAL_RECORDING_CLIENT_MIN_VERSION_CODE)

if(hasMinPlayServices != ConnectionResult.SUCCESS) {
  // Prompt user to update their device's Google Play services app and return
}

// Continue with Recording API functions

Aksi takdirde, kullanıcının Google Play Hizmetleri sürümü çok düşükse sistem bir ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED istisnası oluşturur.

Fitness Verilerine Abone Olma

Adım verilerinin arka planda toplanmasını istemek için aşağıdaki kod snippet'inde gösterildiği gibi subscribe yöntemini kullanın:

val localRecordingClient = FitnessLocal.getLocalRecordingClient(this)
// Subscribe to steps data
localRecordingClient.subscribe(LocalDataType.TYPE_STEP_COUNT_DELTA)
  .addOnSuccessListener {
    Log.i(TAG, "Successfully subscribed!")
  }
  .addOnFailureListener { e ->
    Log.w(TAG, "There was a problem subscribing.", e)
  }

Fitness Verilerini Okuma ve İşleme

Abone olduktan sonra readData yöntemini kullanarak verileri isteyin. Ardından, aşağıdaki kod snippet'inde gösterildiği gibi bir LocalDataReadRequest oluşturarak elde edilen LocalDataSet öğesinden LocalDataPoints elde edebilirsiniz:

val endTime = LocalDateTime.now().atZone(ZoneId.systemDefault())
val startTime = endTime.minusWeeks(1)
val readRequest =
  LocalDataReadRequest.Builder()
    // The data request can specify multiple data types to return,
    // effectively combining multiple data queries into one call.
    // This example demonstrates aggregating only one data type.
    .aggregate(LocalDataType.TYPE_STEP_COUNT_DELTA)
    // Analogous to a "Group By" in SQL, defines how data should be
    // aggregated. bucketByTime allows bucketing by time span.
    .bucketByTime(1, TimeUnit.DAYS)
    .setTimeRange(startTime.toEpochSecond(), endTime.toEpochSecond(), TimeUnit.SECONDS)
    .build()

  localRecordingClient.readData(readRequest).addOnSuccessListener { response ->
    // The aggregate query puts datasets into buckets, so flatten into a
    // single list of datasets.
    for (dataSet in response.buckets.flatMap { it.dataSets }) {
      dumpDataSet(dataSet)
    }
  }
  .addOnFailureListener { e ->
    Log.w(TAG,"There was an error reading data", e)
  }

fun dumpDataSet(dataSet: LocalDataSet) {
  Log.i(TAG, "Data returned for Data type: ${dataSet.dataType.name}")
  for (dp in dataSet.dataPoints) {
    Log.i(TAG,"Data point:")
    Log.i(TAG,"\tType: ${dp.dataType.name}")
    Log.i(TAG,"\tStart: ${dp.getStartTime(TimeUnit.HOURS)}")
    Log.i(TAG,"\tEnd: ${dp.getEndTime(TimeUnit.HOURS)}")
    for (field in dp.dataType.fields) {
      Log.i(TAG,"\tLocalField: ${field.name.toString()} LocalValue: ${dp.getValue(field)}")
    }
  }
}

LocalRecordingClient, veri koleksiyonunu sürekli olarak günceller. İstediğiniz zaman en son sayıları almak için readData simgesini kullanabilirsiniz.

LocalRecordingClient'ün en fazla 10 günlük veri depoladığını unutmayın. Veri kaybetme riskini azaltmak için arka planda verileri düzenli olarak toplamak üzere WorkManager'ı kullanabilirsiniz.

Fitness verilerinin aboneliğinden çıkma

Kaynakları boşaltmak için uygulamanız artık sensör verilerine ihtiyaç duymadığında sensör verisi toplama aboneliğinizi iptal etmeniz gerekir. Abonelikten çıkmak için unsubscribe yöntemini kullanın:

val localRecordingClient = FitnessLocal.getLocalRecordingClient(this)
// Unsubscribe from steps data
localRecordingClient.unsubscribe(LocalDataType.TYPE_STEP_COUNT_DELTA)
  .addOnSuccessListener {
    Log.i(TAG, "Successfully unsubscribed!")
  }
  .addOnFailureListener { e ->
    Log.w(TAG, "There was a problem unsubscribing.", e)
  }