Mục tiêu là các đích trong Google Fit ứng dụng mà người dùng có thể đặt cho bản thân. Nó giúp thúc đẩy người dùng duy trì hoạt động tập luyện hằng ngày. Trong hồ sơ của mình, người dùng có thể điều chỉnh số Bước và Điểm nhịp tim họ muốn nhắm đến mỗi ngày. Nền tảng Fit ghi lại mục tiêu và theo dõi mục tiêu hằng ngày của họ chống lại các từ khoá này.
Tạo trải nghiệm người dùng tốt hơn nhờ các mục tiêu
Ứng dụng của bạn có thể đọc mục tiêu của người dùng để theo dõi các mục tiêu cá nhân của họ. Điều này có thể giúp tạo ra trải nghiệm hấp dẫn hơn. Để bắt đầu, hãy sử dụng ứng dụng GoalsClient
để đọc mục tiêu về Số bước và Điểm nhịp tim của người dùng. Sau đó, hãy sử dụng ứng dụng HistoryClient
để kiểm tra xem người dùng đã gần đạt được mục tiêu đó hay chưa.
Dùng dữ liệu này để giúp người dùng chuyển đổi giữa Google Fit và ứng dụng của bạn một cách liền mạch và nhận được thông tin nhất quán trên cả hai ứng dụng về tiến trình của họ đối với mục tiêu thể chất của mình.
Thúc đẩy người dùng đạt được mục tiêu hằng ngày bằng cách cung cấp cho họ thông tin cập nhật và thông tin chi tiết liên quan đến tiến trình của họ.
Đọc một mục tiêu
Ví dụ sau đây trình bày cách tạo một khách hàng thể dục mới và nhận được
mục tiêu Điểm nhịp tim của người dùng hoặc null
nếu họ không đặt mục tiêu.
Kotlin
private val fitnessOptions: FitnessOptions by lazy { FitnessOptions.builder() .addDataType(DataType.TYPE_HEART_POINTS, FitnessOptions.ACCESS_READ) .build() } private val goalsReadRequest: GoalsReadRequest by lazy { GoalsReadRequest.Builder() .addDataType(DataType.TYPE_HEART_POINTS) .build() } private fun getGoogleAccount(): GoogleSignInAccount = GoogleSignIn.getAccountForExtension(requireContext(), fitnessOptions) private fun readGoals() { Fitness.getGoalsClient(requireContext(), getGoogleAccount()) .readCurrentGoals(goalsReadRequest) .addOnSuccessListener { goals -> // There should be at most one heart points goal currently. goals.firstOrNull()?.apply { // What is the value of the goal val goalValue = metricObjective.value Log.i(TAG, "Goal value: $goalValue") // How is the goal measured? Log.i(TAG, "Objective: $objective") // How often does the goal repeat? Log.i(TAG, "Recurrence: $recurrenceDetails") } } } private val Goal.objective: String get() = when (objectiveType) { OBJECTIVE_TYPE_DURATION -> "Duration (s): ${durationObjective.getDuration(TimeUnit.SECONDS)}" OBJECTIVE_TYPE_FREQUENCY -> "Frequency : ${frequencyObjective.frequency}" OBJECTIVE_TYPE_METRIC -> "Metric : ${metricObjective.dataTypeName} - ${metricObjective.value}" else -> "Unknown objective" } private val Goal.recurrenceDetails: String get() = recurrence?.let { val period = when (it.unit) { Recurrence.UNIT_DAY -> "days" Recurrence.UNIT_WEEK -> "weeks" Recurrence.UNIT_MONTH -> "months" else -> "Unknown" } "Every ${recurrence!!.count} $period" } ?: "Does not repeat"
Java
private final FitnessOptions fitnessOptions = FitnessOptions.builder() .addDataType(DataType.TYPE_HEART_POINTS, FitnessOptions.ACCESS_READ) .build(); private final GoalsReadRequest goalsReadRequest = new GoalsReadRequest.Builder() .addDataType(DataType.TYPE_HEART_POINTS) .build(); private GoogleSignInAccount getGoogleAccount() { GoogleSignIn.getAccountForExtension(getApplicationContext(), fitnessOptions); } private void readGoals() { Fitness.getGoalsClient(getApplicationContext(), getGoogleAccount()) .readCurrentGoals(goalsReadRequest) .addOnSuccessListener(goals -> { // There should be at most one heart points goal currently. Optional<Goal> optionalGoal = goals.stream().findFirst(); if (optionalGoal.isPresent()) { // What is the value of the goal double goalValue = optionalGoal.get().getMetricObjective().getValue(); Log.i(TAG, "Goal value: $goalValue"); // How is the goal measured? Log.i(TAG, "Objective: ${getObjective(optionalGoal.get())}"); // How often does the goal repeat? Log.i(TAG, "Recurrence: ${getRecurrenceDetails(optionalGoal.get())}"); } }); } private String getObjective(Goal goal) { switch (goal.getObjectiveType()) { case OBJECTIVE_TYPE_DURATION: return "Duration (s): ${goal.getDurationObjective().getDuration(TimeUnit.SECONDS)}"; case OBJECTIVE_TYPE_FREQUENCY: return "Frequency : ${goal.getFrequencyObjective().getFrequency()}"; case OBJECTIVE_TYPE_METRIC: return "Metric : ${goal.getMetricObjective().getDataTypeName()} - ${goal.getMetricObjective().getValue()}"; default: return "Unknown objective"; } } private String getRecurrenceDetails(Goal goal) { Goal.Recurrence recurrence = goal.getRecurrence(); if (recurrence == null) { return "Does not repeat"; } StringBuilder recurrenceMessage = new StringBuilder("Every ${recurrence.getCount()}"); switch (recurrence.getUnit()) { case UNIT_DAY: recurrenceMessage.append("days"); break; case UNIT_WEEK: recurrenceMessage.append("weeks"); break; case UNIT_MONTH: recurrenceMessage.append("months"); break; default: recurrenceMessage.delete(0, recurrenceMessage.length()); recurrenceMessage.append("Unknown"); break; } return recurrenceMessage.toString(); }
Kiểm tra tiến trình
Sau khi đã đạt được mục tiêu Điểm nhịp tim của người dùng, bạn có thể sử dụng
HistoryClient
để kiểm tra tiến trình của mình. Ví dụ sau đây cho biết cách kiểm tra số Điểm tim mà người dùng có.
Kotlin
val current = Calendar.getInstance() val request = DataReadRequest.Builder() .read(DataType.TYPE_HEART_POINTS) .setTimeRange( goal.getStartTime(current, TimeUnit.NANOSECONDS), goal.getEndTime(current, TimeUnit.NANOSECONDS), TimeUnit.NANOSECONDS ) .build() Fitness.getHistoryClient(requireContext(), getGoogleAccount()) .readData(request) .addOnSuccessListener { response -> val heartPointsSet = response.dataSets.first() val totalHeartPoints = heartPointsSet.dataPoints.sumBy { it.getValue(Field.FIELD_INTENSITY).asFloat().toInt() } Log.i(TAG, "Total heart points: $totalHeartPoints") }
Java
Calendar current = Calendar.getInstance(); DataReadRequest request = new DataReadRequest.Builder() .read(DataType.TYPE_HEART_POINTS) .setTimeRange( goal.getStartTime(current, TimeUnit.NANOSECONDS), goal.getEndTime(current, TimeUnit.NANOSECONDS), TimeUnit.NANOSECONDS ) .build(); Fitness.getHistoryClient(getApplicationContext(), getGoogleAccount()) .readData(request) .addOnSuccessListener(response -> { Optional<DataSet> heartPointsSet = response.getDataSets().stream().findFirst(); if (heartPointsSet.isPresent()) { int totalHeartPoints = 0; for (DataPoint dp : heartPointsSet.get().getDataPoints()) { totalHeartPoints += (int) dp.getValue(Field.FIELD_INTENSITY).asFloat(); } Log.i(TAG, "Total heart points: $totalHeartPoints"); } });
Tính tiến trình dưới dạng phần trăm
Nếu chia tổng số từ ví dụ kiểm tra tiến trình cho mục tiêu trong ví dụ đọc mục tiêu, bạn có thể tính tiến trình đạt được mục tiêu theo tỷ lệ phần trăm.
Kotlin
private fun calculateProgressPercentage(goal: Goal, response: DataReadResponse): Double { val goalValue = goal.metricObjective.value val currentTotal = response.dataSets.first().dataPoints.sumBy { it.getValue(Field.FIELD_INTENSITY).asFloat().toInt() } return (currentTotal.div(goalValue)).times(100.0) }
Java
private double calculateProgressPercentage(Goal goal, DataReadResponse response) { double goalValue = goal.getMetricObjective().getValue(); Optional<DataSet> firstDataSet = response.getDataSets().stream().findFirst(); if (!(firstDataSet.isPresent())) { return NaN; } double currentTotal = 0; for (DataPoint dp : firstDataSet.get().getDataPoints()) { currentTotal += (int)dp.getValue(Field.FIELD_INTENSITY).asFloat(); } return (currentTotal / goalValue) * 100.0; }