ทํางานกับเป้าหมายการออกกําลังกาย

เป้าหมายคือเป้าหมายในแอป Google Fit ที่ผู้ใช้เลือกได้ด้วยตัวเอง ช่วยสร้างแรงจูงใจให้ผู้ใช้ใช้งานเป็นประจําทุกวัน จากภายในโปรไฟล์ ผู้ใช้จะปรับจํานวนก้าวและคะแนนคาร์ดิโอที่ต้องการกําหนดเป้าหมายในแต่ละวันได้ แพลตฟอร์ม Fit จะบันทึกเป้าหมายและติดตามกิจกรรมประจําวันเทียบกับเป้าหมายเหล่านี้

สร้างประสบการณ์ของผู้ใช้ที่ดียิ่งขึ้นด้วยเป้าหมาย

แอปสามารถอ่านเป้าหมายของผู้ใช้เพื่อติดตามเป้าหมายส่วนตัวของผู้ใช้ การดําเนินการนี้จะช่วยสร้างประสบการณ์ที่น่าสนใจยิ่งขึ้น เริ่มต้นโดยใช้ไคลเอ็นต์ GoalsClient เพื่ออ่านเป้าหมายจํานวนก้าวและคะแนนคาร์ดิโอของผู้ใช้ จากนั้นจึงใช้ไคลเอ็นต์ HistoryClient เพื่อตรวจสอบว่าผู้ใช้เข้าใกล้เป้าหมายเหล่านั้นมากน้อยแค่ไหน

ใช้ข้อมูลนี้เพื่อช่วยให้ผู้ใช้สลับใช้ระหว่าง Google Fit และแอปของคุณ และเข้าถึงข้อมูลที่สอดคล้องกันในทั้ง 2 แอปเกี่ยวกับความคืบหน้าในการบรรลุเป้าหมายการออกกําลังกาย

กระตุ้นผู้ใช้ให้บรรลุเป้าหมายรายวันโดยการให้ข้อมูลอัปเดตและข้อมูลเชิงลึกเกี่ยวกับความคืบหน้า

อ่านเป้าหมาย

ตัวอย่างต่อไปนี้แสดงวิธีสร้างไคลเอ็นต์ฟิตเนสใหม่และวิธีบรรลุเป้าหมายคะแนนคาร์ดิโอของผู้ใช้ หรือ null หากไม่ได้ตั้งค่าเป้าหมาย

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

ตรวจสอบความคืบหน้า

หลังจากมีเป้าหมายคะแนนคาร์ดิโอของผู้ใช้แล้ว คุณจะใช้ HistoryClient เพื่อตรวจสอบความคืบหน้าได้ ตัวอย่างต่อไปนี้แสดงวิธีตรวจสอบคะแนนคาร์ดิโอที่ผู้ใช้มี

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

คํานวณความคืบหน้าเป็นเปอร์เซ็นต์

หากหารจํานวนทั้งหมดจากตัวอย่างตรวจสอบความคืบหน้าด้วยเป้าหมายในตัวอย่างอ่านเป้าหมาย คุณจะคํานวณความคืบหน้าสู่เป้าหมายเป็นเปอร์เซ็นต์ได้

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