إضافة مسارات التمارين الرياضية

تتيح مسارات التمارين الرياضية للمستخدمين تتبُّع مسار نظام تحديد المواقع العالمي (GPS) لأنشطة التمارين الرياضية المرتبطة بها ومشاركة خرائط التمارين مع التطبيقات الأخرى.

يوضح هذا الدليل كيفية حصول التطبيقات على الإذن لكتابة بيانات المسار كجزء من جلسة تمرين.

في ما يلي ملخص موجز لوظيفة القراءة والكتابة لمسارات التمارين الرياضية:

  1. تنشئ التطبيقات إذنًا جديدًا لكتابة مسارات التمارين الرياضية.
  2. يحدث الإدراج عن طريق كتابة جلسة تمرين مع تحديد المسار كحقله.
  3. القراءة:
    1. بالنسبة إلى مالك الجلسة، يتم الوصول إلى البيانات باستخدام جلسة قراءة.
    2. من تطبيق تابع لجهة خارجية، من خلال مربّع حوار يسمح للمستخدم بمنح قراءة المسار مرة واحدة

الأذونات

تتضمّن مسارات التمارين الرياضية إذنًا بالكتابة في وقت التشغيل (android.permission.health.WRITE_EXERCISE_ROUTE).

لإضافة إمكانية مسار التمرين إلى تطبيقك، ابدأ بطلب أذونات الكتابة لنوع معين من البيانات.

طلب الحصول على إذن بالإصدار 14 من نظام التشغيل Android

طلب الحصول على إذن بالإصدار 14 من نظام التشغيل Android

طلب الحصول على إذن بالإصدار 13 من نظام التشغيل Android

طلب الحصول على إذن بالإصدار 13 من نظام التشغيل Android

عليك أيضًا الإعلان عن إذن التمرين، حيث يرتبط كل مسار بجلسة تمرين (جلسة واحدة = تمرين واحد).

إليك الإذن الذي تحتاج إلى الإقرار به لتتمكّن من كتابة مسارات التمارين الرياضية:

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

لقراءة مسارات التمارين الرياضية، تحتاج إلى طلب الأذونات التالية:

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

لطلب الأذونات، استخدِم طريقة PermissionController.createRequestPermissionResultContract() عند ربط تطبيقك بتطبيق Health Connect لأول مرة. عدة أذونات قد ترغب في طلبها هي:

  • قراءة البيانات الصحية، بما في ذلك بيانات المسارات: HealthPermission.getReadPermission(ExerciseSessionRecord::class)
  • كتابة البيانات الصحية، بما في ذلك بيانات المسارات: HealthPermission.getWritePermission(ExerciseSessionRecord::class)
  • كتابة بيانات مسار التمرين الرياضي: HealthPermission.PERMISSION_WRITE_EXERCISE_ROUTE

قراءة بيانات المسار وكتابتها

تدرج التطبيقات مسارًا عن طريق كتابة جلسة مع توجيه كحقل.

إذا لم يكن لدى المستخدم أذونات الكتابة ولم يتم ضبط المسار، لن يتم تعديل المسار.

إذا حصل التطبيق على إذن كتابة مسار وحاول تعديل جلسة من خلال تمرير كائن جلسة بدون مسار، سيتم حذف المسار الحالي.

عندما يحتاج تطبيقك إلى قراءة بيانات المسار التي يوفّرها تطبيق تابع لجهة خارجية، يظهر مربّع حوار يطلب من المستخدم السماح بعملية القراءة.

طلب مسار من جلسة

في ما يلي طريقة قراءة جلسة في Health Connect وطلب مسار من تلك الجلسة:

suspend fun readExerciseSessionAndRoute() {
    val grantedPermissions =
        healthConnectClient.permissionController.getGrantedPermissions()
    if (!grantedPermissions.contains(
          HealthPermission.getReadPermission(ExerciseSessionRecord::class))) {
        // The user doesn't allow the app to read exercise session data.
        return
    }

    val readResponse =
      healthConnectClient.readRecords(
        ReadRecordsRequest(
          ExerciseSessionRecord::class,
          TimeRangeFilter.between(startTime, endTime)
        )
      )
    val exerciseRecord = readResponse.records.first()

    // See https://developer.android.com/training/basics/intents/result#launch
    // for appropriately handling ActivityResultContract.
    val requestExerciseRouteLauncher = fragment.registerForActivityResul
    (ExerciseRouteRequestContract()) { exerciseRoute: ExerciseRoute? ->
            if (exerciseRoute != null) {
                displayExerciseRoute(exerciseRoute)
            } else {
                // Consent was denied
            }
        }

    val exerciseSessionRecord =
      healthConnectClient.readRecord(ExerciseSessionRecord::class, recordId).record

    when (val exerciseRouteResult = exerciseSessionRecord.exerciseRouteResult) {
        is ExerciseRouteResult.Data ->
            displayExerciseRoute(exerciseRouteResult.exerciseRoute)
        is ExerciseRouteResult.ConsentRequired ->
            requestExerciseRouteLauncher.launch(recordId)
        is ExerciseRouteResult.NoData -> Unit // No exercise route to show
        else -> Unit
    }
  }

  fun displayExerciseRoute(route: ExerciseRoute?) {
    val locations = route.route.orEmpty()
    for (location in locations) {
      // Handle location.
    }
  }

كتابة مسار من جلسة

يوضح الرمز البرمجي التالي كيفية تسجيل جلسة تتضمن مسارًا للتمرين:

suspend fun InsertExerciseRoute(healthConnectClient: HealthConnectClient) {
    val grantedPermissions =
        healthConnectClient.permissionController.getGrantedPermissions()
    if (!grantedPermissions.contains(
          getWritePermission(ExerciseSessionRecord::class))) {
        // The user doesn't allow the app to write exercise session data.
        return
    }

    val sessionStartTime = Instant.parse("2023-01-01T10:00:00.00Z")
    val sessionDuration = Duration.ofMinutes(20)

    val exerciseRoute =
      if (getPermissions.contains(PERMISSION_EXERCISE_ROUTE_WRITE) {
        ExerciseRoute(
          listOf(
            ExerciseRoute.Location(
              time = sessionStartTime
              latitude = 6.5483
              longitude = 0.5488
              horizontalAccuracy = Length.meters(2.0)
              verticalAccuracy = Length.meters(2.0),
              altitude = Length.meters(9.0)
            ),
            ExerciseRoute.Location(
              time = sessionStartTime.plus(sessionDuration)
              latitude = 6.4578
              longitude = 0.6577
              horizontalAccuracy = Length.meters(2.0)
              verticalAccuracy = Length.meters(2.0),
              altitude = Length.meters(9.2)
            )
          )
        )
      } else {
        // The user doesn't allow the app to write exercise route data.
        null
      }

    val exerciseSessionRecord =
        ExerciseSessionRecord(
            startTime = /* starting time in milliseconds */,
            startZoneOffset = ZoneOffset.UTC,
            endTime = sessionStartTime.plus(sessionDuration),
            endZoneOffset = ZoneOffset.UTC,
            exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_BIKING,
            title = "Morning Bike Ride",
            exerciseRoute = exerciseRoute
        )

    healthConnectClient.insertRecords(listOf(exerciseSessionRecord))
}