API ضبط در موبایل

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

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

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

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

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

انواع داده ها

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

شروع کنید

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

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

درخواست مجوزها

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

  • android.permission.ACTIVITY_RECOGNITION

یک بررسی نسخه خدمات Play انجام دهید

برای استفاده از Recording API در تلفن همراه، کاربر باید خدمات Google Play را به 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

در غیر این صورت، اگر نسخه خدمات Google Play کاربر خیلی کم باشد، سیستم یک استثنا ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED ایجاد می کند.

در Fitness Data مشترک شوید

برای درخواست جمع آوری پس زمینه داده های مراحل، از روش 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 درخواست کنید. سپس، همانطور که در قطعه کد زیر نشان داده شده است، می توانید با ایجاد یک LocalDataReadRequest ، LocalDataPoints را از LocalDataSet به دست آورید:

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