ব্যায়াম রুট যোগ করুন

ব্যায়াম রুট ব্যবহারকারীদের সংশ্লিষ্ট ব্যায়াম কার্যকলাপের জন্য একটি GPS রুট ট্র্যাক করতে এবং অন্যান্য অ্যাপের সাথে তাদের ওয়ার্কআউটের মানচিত্র শেয়ার করতে দেয়।

এই নির্দেশিকাটি ব্যবহারকারীর কাছ থেকে কীভাবে অনুমতি চাইতে হয় সে সম্পর্কে তথ্য প্রদান করে এবং অনুশীলন সেশনের অংশ হিসাবে অ্যাপগুলি কীভাবে রুট ডেটা লেখার অনুমতি পায় তাও রূপরেখা দেয়।

ব্যায়াম রুটের জন্য পঠন এবং লেখার কার্যকারিতার মধ্যে রয়েছে:

  1. অ্যাপগুলি ব্যায়াম রুটের জন্য একটি নতুন লেখার অনুমতি তৈরি করে।
  2. একটি রুটকে ক্ষেত্র হিসেবে রেখে একটি অনুশীলন সেশন লিখে সন্নিবেশ করানো হয়।
  3. পঠন:
    1. সেশন মালিকের জন্য, সেশন রিড ব্যবহার করে ডেটা অ্যাক্সেস করা হয়।
    2. একটি তৃতীয় পক্ষের অ্যাপ থেকে, একটি ডায়ালগের মাধ্যমে যা ব্যবহারকারীকে একটি রুটের এককালীন পঠন মঞ্জুর করতে দেয়।

যদি ব্যবহারকারীর লেখার অনুমতি না থাকে এবং রুট সেট না থাকে, তাহলে রুট আপডেট হয় না।

যদি আপনার অ্যাপের রুট লেখার অনুমতি থাকে এবং রুট ছাড়াই একটি সেশন অবজেক্ট পাস করে একটি সেশন আপডেট করার চেষ্টা করে, তাহলে বিদ্যমান রুটটি মুছে ফেলা হবে।

হেলথ কানেক্টের প্রাপ্যতা পরীক্ষা করুন

Health Connect ব্যবহার করার চেষ্টা করার আগে, আপনার অ্যাপটি যাচাই করে নেবে যে ব্যবহারকারীর ডিভাইসে Health Connect উপলব্ধ আছে কিনা। Health Connect সমস্ত ডিভাইসে আগে থেকে ইনস্টল নাও থাকতে পারে অথবা অক্ষম করা যেতে পারে। আপনি HealthConnectClient.getSdkStatus() পদ্ধতি ব্যবহার করে উপলব্ধতা পরীক্ষা করতে পারেন।

হেলথ কানেক্টের প্রাপ্যতা কীভাবে পরীক্ষা করবেন

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 ইনস্টল বা আপডেট করার জন্য নির্দেশ দিতে পারেন।

বৈশিষ্ট্যের প্রাপ্যতা

একজন ব্যবহারকারীর ডিভাইস Health Connect-এ পরিকল্পিত অনুশীলন সমর্থন করে কিনা তা নির্ধারণ করতে, ক্লায়েন্টে FEATURE_PLANNED_EXERCISE এর উপলব্ধতা পরীক্ষা করুন:

if (healthConnectClient
     .features
     .getFeatureStatus(
       HealthConnectFeatures.FEATURE_PLANNED_EXERCISE
     ) == HealthConnectFeatures.FEATURE_STATUS_AVAILABLE) {

  // Feature is available
} else {
  // Feature isn't available
}
আরও জানতে বৈশিষ্ট্যের উপলব্ধতা পরীক্ষা করুন দেখুন।

প্রয়োজনীয় অনুমতি

ব্যায়াম রুটে প্রবেশাধিকার নিম্নলিখিত অনুমতি দ্বারা সুরক্ষিত:

  • android.permission.health.READ_EXERCISE_ROUTES
  • android.permission.health.WRITE_EXERCISE_ROUTE
দ্রষ্টব্য: এই অনুমতি প্রকারের জন্য, READ_EXERCISE_ROUTES হল বহুবচন, যেখানে WRITE_EXERCISE_ROUTE হল একবচন।

আপনার অ্যাপে এক্সারসাইজ রুট ক্ষমতা যোগ করতে, ExerciseSession ডেটা টাইপের জন্য লেখার অনুমতি অনুরোধ করে শুরু করুন।

এক্সারসাইজ রুট লিখতে সক্ষম হওয়ার জন্য আপনাকে যে অনুমতিটি ঘোষণা করতে হবে তা এখানে:

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

ব্যায়াম রুট পড়ার জন্য, আপনাকে নিম্নলিখিত অনুমতিগুলির জন্য অনুরোধ করতে হবে:

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

আপনাকে একটি ব্যায়ামের অনুমতিও ঘোষণা করতে হবে, কারণ প্রতিটি রুট একটি ব্যায়াম সেশনের সাথে সম্পর্কিত (একটি সেশন = একটি ওয়ার্কআউট)।

অনুমতির জন্য অনুরোধ করতে, আপনার অ্যাপটি Health Connect-এর সাথে প্রথম সংযোগ করার সময় PermissionController.createRequestPermissionResultContract() পদ্ধতিটি ব্যবহার করুন। আপনি যে কয়েকটি অনুমতির জন্য অনুরোধ করতে চাইতে পারেন তা হল:

  • রুট ডেটা সহ স্বাস্থ্য এবং ফিটনেস ডেটা পড়ুন: HealthPermission.getReadPermission(ExerciseSessionRecord::class)
  • রুট ডেটা সহ স্বাস্থ্য এবং ফিটনেস ডেটা লিখুন: HealthPermission.getWritePermission(ExerciseSessionRecord::class)
  • ব্যায়াম রুটের ডেটা লিখুন: HealthPermission.PERMISSION_WRITE_EXERCISE_ROUTE

ব্যবহারকারীর কাছ থেকে অনুমতির অনুরোধ করুন

একটি ক্লায়েন্ট ইনস্ট্যান্স তৈরি করার পরে, আপনার অ্যাপটিকে ব্যবহারকারীর কাছ থেকে অনুমতি চাইতে হবে। ব্যবহারকারীদের যেকোনো সময় অনুমতি প্রদান বা অস্বীকার করার অনুমতি দিতে হবে।

এটি করার জন্য, প্রয়োজনীয় ডেটা টাইপের জন্য অনুমতিগুলির একটি সেট তৈরি করুন। নিশ্চিত করুন যে সেটের অনুমতিগুলি প্রথমে আপনার অ্যান্ড্রয়েড ম্যানিফেস্টে ঘোষণা করা হয়েছে।

// Create a set of permissions for required data types
val PERMISSIONS =
    setOf(
  HealthPermission.getReadPermission(ExerciseSessionRecord::class),
  HealthPermission.getWritePermission(ExerciseSessionRecord::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)
  }
}

যেহেতু ব্যবহারকারীরা যেকোনো সময় অনুমতি দিতে বা প্রত্যাহার করতে পারেন, তাই আপনার অ্যাপকে পর্যায়ক্রমে মঞ্জুরকৃত অনুমতিগুলি পরীক্ষা করতে হবে এবং অনুমতি হারিয়ে গেলে পরিস্থিতি মোকাবেলা করতে হবে।

একটি ব্যায়াম সেশন রেকর্ডে অন্তর্ভুক্ত তথ্য

প্রতিটি অনুশীলন সেশনের রেকর্ডে নিম্নলিখিত তথ্য থাকে:

  • ব্যায়ামের ধরণ , উদাহরণস্বরূপ, সাইকেল চালানো।
  • অনুশীলন রুট , যাতে অক্ষাংশ, দ্রাঘিমাংশ এবং উচ্চতার মতো তথ্য থাকে।

সমর্থিত সমষ্টি

ExerciseSessionRecord জন্য নিম্নলিখিত সমষ্টিগত মানগুলি উপলব্ধ:

ব্যবহারের উদাহরণ

নিম্নলিখিত কোড স্নিপেটগুলি দেখায় কিভাবে একটি অনুশীলন রুট পড়তে এবং লিখতে হয়।

ব্যায়ামের রুট পড়ুন

আপনার অ্যাপটি ব্যাকগ্রাউন্ডে চলার সময় অন্যান্য অ্যাপের তৈরি এক্সারসাইজ রুট ডেটা পড়তে পারে না।

যখন আপনার অ্যাপটি ব্যাকগ্রাউন্ডে চলে এবং অন্য অ্যাপ দ্বারা তৈরি একটি এক্সারসাইজ রুট পড়ার চেষ্টা করে, তখন Health Connect একটি ExerciseRouteResult.ConsentRequired প্রতিক্রিয়া প্রদান করে, এমনকি যদি আপনার অ্যাপটিতে সর্বদা এক্সারসাইজ রুট ডেটা অ্যাক্সেসের অনুমতি থাকে।

এই কারণে, আমরা দৃঢ়ভাবে সুপারিশ করছি যে ব্যবহারকারী যখন আপনার অ্যাপের UI-এর সাথে সক্রিয়ভাবে জড়িত থাকে, তখন আপনার অ্যাপের সাথে ইচ্ছাকৃত ব্যবহারকারীর মিথস্ক্রিয়ার মাধ্যমে রুটগুলির অনুরোধ করুন।

ব্যাকগ্রাউন্ড রিড সম্পর্কে আরও জানতে, ব্যাকগ্রাউন্ড রিডের উদাহরণ দেখুন।

নিম্নলিখিত কোড স্নিপেটটি দেখায় যে কীভাবে Health Connect-এ একটি সেশন পড়তে হয় এবং সেই সেশন থেকে একটি রুট অনুরোধ করতে হয়:

suspend fun readExerciseSessionAndRoute() {
    val endTime = Instant.now()
    val startTime = endTime.minus(Duration.ofHours(1))

    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()
    val recordId = exerciseRecord.metadata.id

    // 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.now()
    val sessionDuration = Duration.ofMinutes(20)
    val sessionEndTime = sessionStartTime.plus(sessionDuration)

    val exerciseRoute =
        if (grantedPermissions.contains(PERMISSION_WRITE_EXERCISE_ROUTE)) ExerciseRoute(
            listOf(
                ExerciseRoute.Location(
                    // Location times must be on or after the session start time
                    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(
                    // Location times must be before the session end time
                    time = sessionEndTime.minusSeconds(1),
                    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 = sessionStartTime,
        startZoneOffset = ZoneOffset.UTC,
        endTime = sessionEndTime,
        endZoneOffset = ZoneOffset.UTC,
        exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_BIKING,
        title = "Morning Bike Ride",
        exerciseRoute = exerciseRoute,
        metadata = Metadata.manualEntry(
            device = Device(type = Device.TYPE_PHONE)
        ),
    )
    val response = healthConnectClient.insertRecords(listOf(exerciseSessionRecord))
}

ব্যায়াম সেশন

ব্যায়াম সেশনে দৌড় থেকে শুরু করে ব্যাডমিন্টন যেকোনো কিছু অন্তর্ভুক্ত থাকতে পারে।

ব্যায়ামের সেশন লিখুন

একটি সেশন সহ একটি সন্নিবেশ অনুরোধ কীভাবে তৈরি করবেন তা এখানে দেওয়া হল:

suspend fun writeExerciseSession(healthConnectClient: HealthConnectClient) {
    healthConnectClient.insertRecords(
        listOf(
            ExerciseSessionRecord(
                startTime = START_TIME,
                startZoneOffset = START_ZONE_OFFSET,
                endTime = END_TIME,
                endZoneOffset = END_ZONE_OFFSET,
                exerciseType = ExerciseSessionRecord.ExerciseType.RUNNING,
                title = "My Run"
            ),
            // ... other records
        )
    )
}

একটি অনুশীলন সেশন পড়ুন

অনুশীলনের সময় কীভাবে পড়তে হয় তার একটি উদাহরণ এখানে দেওয়া হল:

suspend fun readExerciseSessions(
    healthConnectClient: HealthConnectClient,
    startTime: Instant,
    endTime: Instant
) {
    val response =
        healthConnectClient.readRecords(
            ReadRecordsRequest(
                ExerciseSessionRecord::class,
                timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
            )
        )
    for (exerciseRecord in response.records) {
        // Process each exercise record
        // Optionally pull in with other data sources of the same time range.
        val distanceRecord =
            healthConnectClient
                .readRecords(
                    ReadRecordsRequest(
                        DistanceRecord::class,
                        timeRangeFilter =
                            TimeRangeFilter.between(
                                exerciseRecord.startTime,
                                exerciseRecord.endTime
                            )
                    )
                )
                .records
    }
}

সাব-টাইপ ডেটা লিখুন

অধিবেশনগুলিতে ঐচ্ছিক উপ-প্রকারের তথ্যও অন্তর্ভুক্ত থাকতে পারে, যা অতিরিক্ত তথ্য দিয়ে অধিবেশনকে সমৃদ্ধ করে।

উদাহরণস্বরূপ, ব্যায়াম সেশনে ExerciseSegment , ExerciseLap এবং ExerciseRoute ক্লাস অন্তর্ভুক্ত থাকতে পারে:

val segments = listOf(
  ExerciseSegment(
    startTime = Instant.parse("2022-01-02T10:10:10Z"),
    endTime = Instant.parse("2022-01-02T10:10:13Z"),
    segmentType = ActivitySegmentType.BENCH_PRESS,
    repetitions = 373
  )
)

val laps = listOf(
  ExerciseLap(
    startTime = Instant.parse("2022-01-02T10:10:10Z"),
    endTime = Instant.parse("2022-01-02T10:10:13Z"),
    length = 0.meters
  )
)

ExerciseSessionRecord(
  exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_CALISTHENICS,
    startTime = Instant.parse("2022-01-02T10:10:10Z"),
    endTime = Instant.parse("2022-01-02T10:10:13Z"),
  startZoneOffset = ZoneOffset.UTC,
  endZoneOffset = ZoneOffset.UTC,
  segments = segments,
  laps = laps,
  route = route
)

একটি ব্যায়াম সেশন মুছুন

একটি ব্যায়াম সেশন মুছে ফেলার দুটি উপায় আছে:

  1. সময়সীমা অনুসারে।
  2. ইউআইডি দ্বারা।

সময়সীমা অনুসারে আপনি কীভাবে সাব-টাইপ ডেটা মুছে ফেলবেন তা এখানে দেওয়া হল:

suspend fun deleteExerciseSessionByTimeRange(
    healthConnectClient: HealthConnectClient,
    exerciseRecord: ExerciseSessionRecord,
) {
    val timeRangeFilter = TimeRangeFilter.between(exerciseRecord.startTime, exerciseRecord.endTime)
    healthConnectClient.deleteRecords(ExerciseSessionRecord::class, timeRangeFilter)
    // delete the associated distance record
    healthConnectClient.deleteRecords(DistanceRecord::class, timeRangeFilter)
}

আপনি UID দ্বারা উপ-প্রকারের ডেটাও মুছে ফেলতে পারেন। এটি করলে কেবল অনুশীলন সেশনটি মুছে যাবে, সংশ্লিষ্ট ডেটা নয়:

suspend fun deleteExerciseSessionByUid(
    healthConnectClient: HealthConnectClient,
    exerciseRecord: ExerciseSessionRecord,
) {
    healthConnectClient.deleteRecords(
        ExerciseSessionRecord::class,
        recordIdsList = listOf(exerciseRecord.metadata.id),
        clientRecordIdsList = emptyList()
    )
}