داده های تناسب اندام را با استفاده از Recording API ضبط کنید

API ضبط در موبایل به برنامه شما اجازه می‌دهد تا داده‌های تناسب اندام را از دستگاه تلفن همراه به روشی با مصرف بهینه باتری ثبت کند. به عنوان مثال، از این API برای ثبت گام‌ها استفاده کنید، مشابه یک گام‌شمار که داده‌های شمارش گام را بازیابی می‌کند. این API بدون حساب کاربری است، به این معنی که برای استفاده از سرویس نیازی به حساب گوگل ندارد و داده‌ها در دستگاه ذخیره می‌شوند.

اگر برنامه شما علاوه بر گام‌های ثبت‌شده روی دستگاه، نیاز به خواندن سایر داده‌های سلامت و تناسب اندام از منابع مختلف دارد، ادغام با Health Connect گزینه بهتری است. Health Connect همچنین دسترسی به گام‌های ثبت‌شده روی دستگاه را به‌صورت بومی در اندروید ۱۴ (سطح API ۳۴) و بالاتر فراهم می‌کند.

این راهنما به شما نشان می‌دهد که چگونه از Recording API در موبایل برای تجربه‌های سلامت و تناسب اندام خود استفاده کنید.

برای مثال، به نمونه‌ی Recording API روی موبایل در گیت‌هاب مراجعه کنید.

جزئیات قابل توجه

چندین ویژگی قابل توجه و منحصر به فرد برای Recording API در موبایل وجود دارد:

  • به محض شروع یا تمدید اشتراک ضبط، داده‌های مربوط به آخرین اشتراک - تا 10 روز - قابل دسترسی هستند.
  • داده‌ها فقط زمانی در دسترس هستند که اشتراک فعالی وجود داشته باشد. اگر اشتراکی با فراخوانی unsubscribe حذف شود، داده‌های جمع‌آوری‌شده قابل دسترسی نخواهند بود.

انواع داده

API ضبط در موبایل می‌تواند انواع داده‌های زیر را ضبط کند:

شروع کنید

برای شروع، وابستگی زیر را به فایل build.gradle خود اضافه کنید:

کاتلین DSL

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

...

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

گرووی دی‌اس‌ال

apply plugin: 'com.android.application'

...

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

درخواست مجوز

برای ضبط داده‌ها با استفاده از Recording API در موبایل، برنامه شما باید مجوزهای زیر را درخواست کند :

  • android.permission.ACTIVITY_RECOGNITION

بررسی نسخه سرویس‌های Play را انجام دهید

برای استفاده از Recording API در موبایل، کاربر باید سرویس‌های گوگل پلی خود را به LOCAL_RECORDING_CLIENT_MIN_VERSION_CODE به‌روزرسانی کرده باشد. می‌توانید این مورد را با استفاده از متد isGooglePlayServicesAvailable بررسی کنید:

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

در غیر این صورت، اگر نسخه سرویس‌های گوگل پلی کاربر خیلی پایین باشد، سیستم خطای ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED را صادر می‌کند.

در داده‌های تناسب اندام مشترک شوید

برای درخواست جمع‌آوری داده‌های مراحل در پس‌زمینه، از متد subscribe استفاده کنید، همانطور که در قطعه کد زیر نشان داده شده است:

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

خواندن و پردازش داده‌های تناسب اندام

پس از اشتراک، داده‌ها را با استفاده از متد readData درخواست کنید. سپس، می‌توانید LocalDataPoints را از LocalDataSet حاصل با ایجاد LocalDataReadRequest ، همانطور که در قطعه کد زیر نشان داده شده است، به دست آورید:

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 به طور مداوم مجموعه داده‌های خود را به‌روزرسانی می‌کند. شما می‌توانید readData برای دریافت آخرین اعداد در هر زمانی استفاده کنید.

توجه داشته باشید که LocalRecordingClient حداکثر تا 10 روز داده را ذخیره می‌کند. برای کاهش خطر از دست دادن داده‌ها، می‌توانید از WorkManager برای جمع‌آوری دوره‌ای داده‌ها در پس‌زمینه استفاده کنید.

لغو اشتراک از داده‌های تناسب اندام

برای آزاد کردن منابع، باید مطمئن شوید که وقتی برنامه شما دیگر به داده‌های حسگر نیازی ندارد، از جمع‌آوری آنها انصراف دهید. برای لغو اشتراک، از متد unsubscribe استفاده کنید:

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