מעקב אחר הצעדים

‫Health Connect מספקת סוג נתונים של צעדים לתיעוד של מספר הצעדים באמצעות StepsRecord. נתוני הצעדים הם מדד בסיסי למעקב אחרי הבריאות והכושר.

קריאה של נתוני הצעדים בנייד

ב-Android 14 (רמת API‏ 34) ובגרסה 20 ומעלה של SDK Extension,‏ Health Connect מספק ספירת צעדים במכשיר. אם אפליקציה כלשהי קיבלה את ההרשאה READ_STEPS, ‏ Health Connect מתחיל לתעד את הצעדים מהמכשיר עם Android, והמשתמשים רואים את נתוני הצעדים שנוספו אוטומטית לרשומות צעדים ב-Health Connect.

כדי לבדוק אם ספירת הצעדים במכשיר זמינה, צריך לוודא שבמכשיר פועלת מערכת Android 14 (רמת API‏ 34) ושיש בו לפחות SDK extension גרסה 20. אפשר להשתמש בקוד הבא:

val isStepTrackingAvailable =
    Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
        SdkExtensions.getExtensionVersion(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) >= 20

הצעדים בנייד שנרשמים על ידי Health Connect מקבלים את הערך android בשדה DataOrigin, שהוא שם החבילה. אם האפליקציה שלכם פשוט קוראת את מספר הצעדים המצטבר באמצעות aggregate ולא מסננת לפי DataOrigin, הצעדים שנמדדו במכשיר נכללים אוטומטית בסכום הכולל.

אם האפליקציה צריכה לקרוא את הנתונים של הצעדים שנמדדו במכשיר, או אם היא מציגה נתוני צעדים שמפורטים לפי אפליקציית המקור או המכשיר, אפשר לשלוח שאילתה לגבי רשומות שבהן הערך של DataOrigin הוא android. אם האפליקציה מציגה שיוך לנתוני שלבים, צריך לשייך נתונים מחבילת Android למכשיר הנוכחי. אפשר לעשות זאת באמצעות תווית כמו 'הטלפון שלך', אחזור שם המכשיר באמצעות Settings.Global.getString(resolver, Settings.Global.DEVICE_NAME) או בדיקת השדה Device במטא-נתונים של הרשומה.

הדוגמה הבאה מראה איך לקרוא נתונים מצטברים של מספר צעדים בנייד באמצעות סינון לפי android מקור הנתונים:

suspend fun readStepsByTimeRange(
    healthConnectClient: HealthConnectClient,
    startTime: Instant,
    endTime: Instant
) {
    try {
        val response = healthConnectClient.aggregate(
            AggregateRequest(
                metrics = setOf(StepsRecord.COUNT_TOTAL),
                timeRangeFilter = TimeRangeFilter.between(startTime, endTime),
                dataOriginFilter = setOf(DataOrigin("android"))
            )
        )
        // The result may be null if no data is available in the time range
        val stepCount = response[StepsRecord.COUNT_TOTAL]
    } catch (e: Exception) {
        // Run error handling here
    }
}

ספירת צעדים במכשיר

הסבר מפורט על התכונה 'ספירת צעדים במכשיר':

  • שימוש בחיישנים: אפליקציית Health Connect משתמשת בחיישן TYPE_STEP_COUNTER של SensorManager. החיישן הזה מותאם לצריכת חשמל נמוכה, ולכן הוא אידיאלי למעקב רציף אחרי צעדים ברקע.
  • גרנולריות הנתונים: כדי לחסוך בחיי הסוללה, נתוני הצעדים בדרך כלל נכתבים למסד הנתונים של Health Connect בקבוצות, בתדירות של פעם בדקה לכל היותר.
  • שיוך: כמו שצוין קודם, כל השלבים שתועדו על ידי התכונה הזו במכשיר משויכים לשם החבילה android ב-DataOrigin.
  • הפעלה: מנגנון ספירת הצעדים במכשיר פעיל רק אם לפחות אפליקציה אחת במכשיר קיבלה את ההרשאה READ_STEPS ב-Health Connect.

בדיקת הזמינות של Health Connect

לפני שמנסים להשתמש ב-Health Connect, האפליקציה צריכה לוודא שהשירות זמין במכשיר של המשתמש. יכול להיות שאפליקציית Health Connect לא מותקנת מראש בחלק מהמכשירים או שהיא מושבתת. אפשר לבדוק את הזמינות באמצעות ה-method‏ HealthConnectClient.getSdkStatus().

איך בודקים אם אפליקציית Health Connect זמינה

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(), תוכלו להנחות את המשתמש להתקין או לעדכן את Health Connect מחנות Google Play, אם יש צורך בכך.

הרשאות נדרשות

הגישה לנתוני הצעדים מוגנת על ידי ההרשאות הבאות:

  • android.permission.health.READ_STEPS
  • android.permission.health.WRITE_STEPS

כדי להוסיף לאפליקציה אפשרות של צעדים, צריך קודם לבקש הרשאות לסוג הנתונים Steps.

זו ההרשאה שצריך להצהיר עליה כדי שיהיה אפשר לכתוב נתונים של צעדים:

<application>
  <uses-permission
android:name="android.permission.health.WRITE_STEPS" />
...
</application>

כדי לקרוא את השלבים, צריך לבקש את ההרשאות הבאות:

<application>
  <uses-permission
android:name="android.permission.health.READ_STEPS" />
...
</application>

בקשת הרשאות מהמשתמש

אחרי שיוצרים מופע של לקוח, האפליקציה צריכה לבקש הרשאות מהמשתמש. צריך לאפשר למשתמשים להעניק או לדחות הרשאות בכל שלב.

כדי לעשות זאת, יוצרים קבוצת הרשאות לסוגי הנתונים הנדרשים. קודם צריך לוודא שההרשאות בקבוצה מוצהרות במניפסט של Android.

// Create a set of permissions for required data types
val PERMISSIONS =
    setOf(
  HealthPermission.getReadPermission(StepsRecord::class),
  HealthPermission.getWritePermission(StepsRecord::class)
)

אפשר להשתמש ב-getGrantedPermissions כדי לבדוק אם האפליקציה כבר קיבלה את ההרשאות הנדרשות. אם לא, משתמשים ב-createRequestPermissionResultContract כדי לבקש את ההרשאות האלה. הפעולה הזו תציג את מסך ההרשאות של Health Connect.

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

המשתמשים יכולים לתת או לבטל הרשאות בכל שלב, ולכן האפליקציה צריכה לבדוק אם ההרשאות ניתנו בכל פעם לפני שהיא משתמשת בהן, ולטפל במקרים שבהם הרשאה כלשהי בוטלה.

המידע שכלול ברשומה של שלבים

כל StepsRecord מכיל את הפרטים הבאים:

  • count: מספר הצעדים שנמדדו במרווח הזמן, כערך Long.
  • startTime: שעת ההתחלה של מרווח המדידה.
  • endTime: שעת הסיום של מרווח המדידה.
  • startZoneOffset: ההסטה מאזור הזמן של שעת ההתחלה.
  • endZoneOffset: ההפרש מאזור הזמן של שעת הסיום.

צבירות נתמכות

הערכים המצטברים הבאים זמינים עבור StepsRecord:

הערכים המצטברים הבאים זמינים עבור StepsCadenceRecord:

דוגמאות לשימוש

בקטעים הבאים מוסבר איך לקרוא ולכתוב נתונים של StepsRecord.

כתיבה של נתוני הצעדים

האפליקציה יכולה לכתוב נתונים של מספר הצעדים על ידי הוספה של מופעים של StepsRecord בדוגמה הבאה אפשר לראות איך מתעדים 1,000 צעדים שמשתמש עשה:

suspend fun writeStepsData(
    healthConnectClient: HealthConnectClient,
    startTime: Instant,
    endTime: Instant,
    startZoneOffset: ZoneOffset,
    endZoneOffset: ZoneOffset
) {
    try {
        val stepsRecord = StepsRecord(
            startTime = startTime,
            startZoneOffset = startZoneOffset,
            endTime = endTime,
            endZoneOffset = endZoneOffset,
            count = 1000
        )
        healthConnectClient.insertRecords(listOf(stepsRecord))
    } catch (e: Exception) {
        // Run error handling
    }
}

קריאת נתונים נצברים

הדרך הנפוצה ביותר לקרוא נתוני צעדים היא לצבור את סך הצעדים לאורך תקופת זמן מסוימת. בדוגמה הבאה אפשר לראות איך קוראים את ספירת השלבים הכוללת של משתמש בטווח זמן מסוים:

suspend fun readStepsAggregate(
    healthConnectClient: HealthConnectClient,
    startTime: Instant,
    endTime: Instant
) {
    try {
        val response = healthConnectClient.aggregate(
            AggregateRequest(
                metrics = setOf(StepsRecord.COUNT_TOTAL),
                timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
            )
        )
        // The result may be null if no data is available in the time range
        val stepCount = response[StepsRecord.COUNT_TOTAL]
    } catch (e: Exception) {
        // Run error handling here
    }
}

קריאת נתונים גולמיים

בדוגמה הבאה אפשר לראות איך קוראים נתוני StepsRecord גולמיים בין שעת התחלה לשעת סיום:

suspend fun readStepsRaw(
    healthConnectClient: HealthConnectClient,
    startTime: Instant,
    endTime: Instant
) {
    try {
        val response = healthConnectClient.readRecords(
            ReadRecordsRequest(
                recordType = StepsRecord::class,
                timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
            )
        )
        for (record in response.records) {
            // Process each record
        }
    } catch (e: Exception) {
        // Run error handling here
    }
}