תיעוד נתוני כושר באמצעות Recording API

‫Recording API בנייד מאפשר לאפליקציה שלכם לתעד נתוני כושר ממכשיר נייד בצורה חסכונית בסוללה. לדוגמה, אפשר להשתמש ב-API הזה כדי לתעד צעדים, בדומה למד צעדים שאוסף נתונים של מספר הצעדים. ה-API הזה לא דורש חשבון, כלומר לא צריך חשבון Google כדי להשתמש בשירות, והנתונים מאוחסנים במכשיר.

במדריך הזה נראה לכם איך להשתמש ב-Recording API בנייד בחוויות של בריאות וכושר.

אפשר לראות דוגמה ב-GitHub בRecording API on mobile sample.

פרטים שכדאי לדעת

יש כמה תכונות חשובות שייחודיות ל-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 Services

כדי להשתמש ב-Recording API בנייד, המשתמש צריך לעדכן את Google Play Services לגרסה 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 Services שמותקנת אצל המשתמש נמוכה מדי, המערכת תציג חריגה מסוג ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED.

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

Read and Process Fitness Data

אחרי ההרשמה, שולחים בקשה לנתונים באמצעות שיטת 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)
  }