API ghi trên thiết bị di động

Ghi lại API trên thiết bị di động cho phép ứng dụng của bạn ghi lại các bước từ thiết bị di động theo cách tiết kiệm pin. API này không có tài khoản, nghĩa là không yêu cầu Tài khoản Google để sử dụng dịch vụ và dữ liệu được lưu trữ trên thiết bị.

Hướng dẫn này cho bạn biết cách sử dụng API ghi trên thiết bị di động khi trải nghiệm về sức khoẻ và thể hình.

Chi tiết đáng chú ý

Có một số tính năng đáng chú ý của riêng API bản ghi trên thiết bị di động:

  • Sau khi gói thuê bao ghi lại bắt đầu, dữ liệu sẽ được lưu trữ trên thiết bị trong tối đa 10 ngày.
  • Dữ liệu chỉ có sẵn khi có một gói thuê bao đang hoạt động. Nếu bạn xoá gói thuê bao bằng cách gọi unsubscribe, thì bạn sẽ không thể truy cập vào dữ liệu về số bước đã thu thập.

Kiểu dữ liệu

API ghi lại trên thiết bị di động có thể ghi lại các loại dữ liệu sau đây:

Bắt đầu

Để bắt đầu, hãy thêm phần phụ thuộc sau vào tệp build.gradle:

Kotlin DSL

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

...

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

DSL hấp dẫn

apply plugin: 'com.android.application'

...

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

Yêu cầu cấp quyền

Để ghi dữ liệu bằng API ghi lại trên thiết bị di động, ứng dụng của bạn cần yêu cầu quyền sau đây:

  • android.permission.ACTIVITY_RECOGNITION

Đăng ký nhận dữ liệu về hoạt động thể dục

Để yêu cầu thu thập dữ liệu về số bước, quãng đường hoặc lượng calo trong nền, hãy sử dụng phương thức subscribe như minh hoạ trong đoạn mã sau:

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

Đọc và xử lý dữ liệu về thể chất

Sau khi đăng ký, hãy yêu cầu dữ liệu bằng phương thức readData. Sau đó, bạn có thể nhận DataPoint từ DataSet thu được bằng cách tạo DataReadRequest như minh hoạ trong đoạn mã sau:

val endTime = LocalDateTime.now().atZone(ZoneId.systemDefault())
val startTime = endTime.minusWeeks(1)
val readRequest =
  DataReadRequest.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(DataType.AGGREGATE_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: DataSet) {
  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.getStartTimeString()}")
    Log.i(TAG,"\tEnd: ${dp.getEndTimeString()}")
    for (field in dp.dataType.fields) {
      Log.i(TAG,"\tField: ${field.name.toString()} Value: ${dp.getValue(field)}")
    }
  }
}

LocalRecordingClient liên tục cập nhật hoạt động thu thập dữ liệu. Bạn có thể sử dụng readData để lấy số liệu mới nhất bất cứ lúc nào.

Xin lưu ý rằng LocalRecordingClient lưu trữ dữ liệu trong tối đa 10 ngày. Để giảm nguy cơ mất dữ liệu, bạn có thể sử dụng WorkManager để thu thập dữ liệu định kỳ ở chế độ nền.

Huỷ đăng ký nhận dữ liệu về hoạt động thể dục

Để giải phóng tài nguyên, bạn nên đảm bảo huỷ đăng ký khỏi hoạt động thu thập dữ liệu cảm biến khi ứng dụng của bạn không còn cần đến nữa. Để huỷ đăng ký, hãy sử dụng phương thức unsubscribe:

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