داده ها را بنویسید

این راهنما فرآیند نوشتن یا به‌روزرسانی داده‌ها در Health Connect را پوشش می‌دهد.

مدیریت مقادیر صفر

برخی از انواع داده‌ها مانند گام‌ها، مسافت یا کالری ممکن است مقدار 0 داشته باشند. فقط زمانی مقادیر صفر را بنویسید که نشان‌دهنده عدم فعالیت واقعی کاربر در حین استفاده از دستگاه باشد. اگر دستگاه استفاده نشده، داده‌ها از بین رفته یا باتری آن تمام شده است، مقادیر صفر را ننویسید. در چنین مواردی، برای جلوگیری از گمراهی داده‌ها، رکورد را حذف کنید.

تنظیم ساختار داده

قبل از نوشتن داده‌ها، ابتدا باید رکوردها را تنظیم کنیم. برای بیش از ۵۰ نوع داده، هر کدام ساختار مربوط به خود را دارند. برای جزئیات بیشتر در مورد انواع داده‌های موجود، به مرجع Jetpack مراجعه کنید.

سوابق پایه

نوع داده Steps در Health Connect تعداد گام‌هایی را که کاربر بین اندازه‌گیری‌ها برداشته است، ثبت می‌کند. تعداد گام‌ها نشان‌دهنده یک معیار مشترک در پلتفرم‌های سلامت، تناسب اندام و تندرستی است.

مثال زیر نحوه تنظیم داده‌های شمارش گام‌ها را نشان می‌دهد:

val endTime = Instant.now()
val startTime = endTime.minus(Duration.ofMinutes(15))

val stepsRecord = StepsRecord(
    count = 120,
    startTime = startTime,
    endTime = endTime,
    startZoneOffset = ZoneOffset.UTC,
    endZoneOffset = ZoneOffset.UTC,
    metadata = Metadata.autoRecorded(
        device = Device(type = Device.TYPE_WATCH)
    )
)

سوابق با واحدهای اندازه‌گیری

Health Connect می‌تواند مقادیر را به همراه واحدهای اندازه‌گیری آنها ذخیره کند تا دقت لازم را ارائه دهد. یک نمونه، نوع داده Nutrition است که گسترده و جامع است. این نوع داده شامل طیف گسترده‌ای از فیلدهای مواد مغذی اختیاری از کل کربوهیدرات‌ها گرفته تا ویتامین‌ها است. هر نقطه داده نشان دهنده مواد مغذی است که به طور بالقوه به عنوان بخشی از یک وعده غذایی یا ماده غذایی مصرف شده‌اند.

در این نوع داده، تمام مواد مغذی با واحد جرم (Mass) نمایش داده می‌شوند، در حالی که energy با واحد انرژی (Energy) نمایش داده می‌شود.

مثال زیر نحوه تنظیم داده‌های تغذیه‌ای برای کاربری که موز خورده است را نشان می‌دهد:

val endTime = Instant.now()
val startTime = endTime.minus(Duration.ofMinutes(1))

val banana = NutritionRecord(
    name = "banana",
    energy = 105.0.kilocalories,
    dietaryFiber = 3.1.grams,
    potassium = 0.422.grams,
    totalCarbohydrate = 27.0.grams,
    totalFat = 0.4.grams,
    saturatedFat = 0.1.grams,
    sodium = 0.001.grams,
    sugar = 14.0.grams,
    vitaminB6 = 0.0005.grams,
    vitaminC = 0.0103.grams,
    startTime = startTime,
    endTime = endTime,
    startZoneOffset = ZoneOffset.UTC,
    endZoneOffset = ZoneOffset.UTC,
    metadata = Metadata.manualEntry(
        device = Device(type = Device.TYPE_PHONE)
    )
)

رکوردهایی با داده‌های سری

Health Connect می‌تواند فهرستی از داده‌های سری را ذخیره کند. یک نمونه، نوع داده ضربان قلب است که مجموعه‌ای از نمونه‌های ضربان قلب را که بین قرائت‌ها شناسایی می‌شوند، ثبت می‌کند.

در این نوع داده، پارامترهای samples با لیستی از نمونه‌های ضربان قلب نمایش داده می‌شوند. هر نمونه شامل یک مقدار beatsPerMinute و یک مقدار time است.

مثال زیر نحوه تنظیم داده‌های سری ضربان قلب را نشان می‌دهد:

val endTime = Instant.now()
val startTime = endTime.minus(Duration.ofMinutes(5))

val heartRateRecord = HeartRateRecord(
    startTime = startTime,
    startZoneOffset = ZoneOffset.UTC,
    endTime = endTime,
    endZoneOffset = ZoneOffset.UTC,
    // records 10 arbitrary data, to replace with actual data
    samples = List(10) { index ->
        HeartRateRecord.Sample(
            time = startTime + Duration.ofSeconds(index.toLong()),
            beatsPerMinute = 100 + index.toLong(),
        )
    },
    metadata = Metadata.autoRecorded(
        device = Device(type = Device.TYPE_WATCH)
    ))

درخواست مجوز از کاربر

پس از ایجاد یک نمونه کلاینت، برنامه شما باید از کاربر درخواست مجوز کند. کاربران باید بتوانند در هر زمانی مجوزها را اعطا یا رد کنند.

برای انجام این کار، مجموعه‌ای از مجوزها را برای انواع داده‌های مورد نیاز ایجاد کنید. مطمئن شوید که مجوزهای موجود در مجموعه ابتدا در مانیفست اندروید شما تعریف شده‌اند.

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

از آنجا که کاربران می‌توانند در هر زمانی مجوزها را اعطا یا لغو کنند، برنامه شما باید به صورت دوره‌ای مجوزهای اعطا شده را بررسی کند و سناریوهایی را که در آنها مجوز از دست می‌رود، مدیریت کند.

نوشتن داده

یکی از گردش‌های کاری رایج در Health Connect نوشتن داده‌ها است. برای اضافه کردن رکوردها، insertRecords استفاده کنید.

مثال زیر نحوه نوشتن تعداد مراحل درج داده را نشان می‌دهد:

suspend fun insertSteps(healthConnectClient: HealthConnectClient) {
    val endTime = Instant.now()
    val startTime = endTime.minus(Duration.ofMinutes(5))
    try {
        val stepsRecord = StepsRecord(
            count = 120,
            startTime = startTime,
            endTime = endTime,
            startZoneOffset = ZoneOffset.UTC,
            endZoneOffset = ZoneOffset.UTC,
            metadata = Metadata.autoRecorded(
                device = Device(type = Device.TYPE_WATCH)
            )
        )
        healthConnectClient.insertRecords(listOf(stepsRecord))
    } catch (e: Exception) {
        // Run error handling here
    }
}

به‌روزرسانی داده‌ها

اگر نیاز به تغییر یک یا چند رکورد دارید، به خصوص زمانی که نیاز به همگام‌سازی پایگاه داده برنامه خود با داده‌های Health Connect دارید، می‌توانید داده‌های خود را به‌روزرسانی کنید. دو روش برای به‌روزرسانی داده‌های موجود وجود دارد که به شناسه مورد استفاده برای یافتن رکوردها بستگی دارد.

فراداده

بررسی کلاس Metadata در ابتدا ارزشمند است زیرا این کلاس هنگام به‌روزرسانی داده‌ها ضروری است. در هنگام ایجاد، هر Record در Health Connect دارای یک فیلد metadata است. ویژگی‌های زیر مربوط به همگام‌سازی هستند:

خواص توضیحات
id هر Record در Health Connect یک مقدار id منحصر به فرد دارد.
Health Connect هنگام وارد کردن یک رکورد جدید، این مورد را به طور خودکار پر می‌کند.
lastModifiedTime هر Record همچنین آخرین باری که رکورد تغییر کرده است را ثبت می‌کند.
Health Connect به طور خودکار این را پر می‌کند.
clientRecordId هر Record می‌تواند یک شناسه منحصر به فرد مرتبط با خود داشته باشد تا به عنوان مرجع در پایگاه داده برنامه شما عمل کند.
برنامه شما این مقدار را ارائه می‌دهد.
clientRecordVersion در جایی که یک رکورد دارای clientRecordId است، clientRecordVersion می‌تواند برای همگام‌سازی داده‌ها با نسخه موجود در پایگاه داده برنامه شما استفاده شود.
برنامه شما این مقدار را ارائه می‌دهد.

به‌روزرسانی پس از خواندن بر اساس محدوده زمانی

برای به‌روزرسانی داده‌ها، ابتدا رکوردهای مورد نیاز را آماده کنید. در صورت لزوم، هرگونه تغییری را در رکوردها اعمال کنید. سپس، تابع updateRecords را برای اعمال تغییرات فراخوانی کنید.

مثال زیر نحوه به‌روزرسانی داده‌ها را نشان می‌دهد. برای این منظور، مقادیر آفست منطقه هر رکورد در PST تنظیم می‌شود.

suspend fun updateSteps(
    healthConnectClient: HealthConnectClient,
    prevRecordStartTime: Instant,
    prevRecordEndTime: Instant
) {
    try {
        val request = healthConnectClient.readRecords(
            ReadRecordsRequest(
                recordType = StepsRecord::class, timeRangeFilter = TimeRangeFilter.between(
                    prevRecordStartTime, prevRecordEndTime
                )
            )
        )

        val newStepsRecords = arrayListOf<StepsRecord>()
        for (record in request.records) {
            // Adjusted both offset values to reflect changes
            val sr = StepsRecord(
                count = record.count,
                startTime = record.startTime,
                startZoneOffset = record.startTime.atZone(ZoneId.of("PST")).offset,
                endTime = record.endTime,
                endZoneOffset = record.endTime.atZone(ZoneId.of("PST")).offset,
                metadata = record.metadata
            )
            newStepsRecords.add(sr)
        }

        healthConnectClient.updateRecords(newStepsRecords)
    } catch (e: Exception) {
        // Run error handling here
    }
}

از طریق شناسه رکورد مشتری ثبت نام کنید

اگر از مقادیر اختیاری Client Record ID و Client Record Version استفاده می‌کنید، توصیه می‌کنیم به جای updateRecords از insertRecords استفاده کنید.

تابع insertRecords قابلیت درج داده‌ها را دارد. اگر داده‌ها بر اساس مجموعه شناسه‌های رکورد کلاینت داده شده در Health Connect وجود داشته باشند، رونویسی می‌شوند. در غیر این صورت، به عنوان داده‌های جدید نوشته می‌شوند. این سناریو هر زمان که نیاز به همگام‌سازی داده‌ها از پایگاه داده برنامه خود با Health Connect داشته باشید، مفید است.

مثال زیر نحوه‌ی انجام عملیات درج (upsert) روی داده‌های دریافت شده از مخزن داده‌ی برنامه را نشان می‌دهد:

suspend fun pullStepsFromDatastore() : ArrayList<StepsRecord> {
    val appStepsRecords = arrayListOf<StepsRecord>()
    // Pull data from app datastore
    // ...
    // Make changes to data if necessary
    // ...
    // Store data in appStepsRecords
    // ...
    var sr = StepsRecord(
        metadata = Metadata.autoRecorded(
            clientRecordId = "Your client record ID",
            device = Device(type = Device.TYPE_WATCH)
        ),
        // Assign more parameters for this record
    )
    appStepsRecords.add(sr)
    // ...
    return appStepsRecords
}

suspend fun upsertSteps(
    healthConnectClient: HealthConnectClient,
    newStepsRecords: ArrayList<StepsRecord>
) {
    try {
        healthConnectClient.insertRecords(newStepsRecords)
    } catch (e: Exception) {
        // Run error handling here
    }
}

پس از آن، می‌توانید این توابع را در نخ اصلی خود فراخوانی کنید.

upsertSteps(healthConnectClient, pullStepsFromDatastore())

بررسی ارزش در نسخه رکورد مشتری

اگر فرآیند درج داده‌ها شامل نسخه رکورد کلاینت باشد، Health Connect بررسی‌های مقایسه‌ای را در مقادیر clientRecordVersion انجام می‌دهد. اگر نسخه داده‌های درج شده بالاتر از نسخه داده‌های موجود باشد، درج انجام می‌شود. در غیر این صورت، فرآیند تغییر را نادیده می‌گیرد و مقدار ثابت می‌ماند.

برای گنجاندن نسخه‌بندی در داده‌هایتان، باید بر اساس منطق نسخه‌بندی خود، به Metadata.clientRecordVersion مقداری از نوع Long بدهید.

val endTime = Instant.now()
val startTime = endTime.minus(Duration.ofMinutes(15))

val stepsRecord = StepsRecord(
    count = 100L,
    startTime = startTime,
    startZoneOffset = ZoneOffset.UTC,
    endTime = endTime,
    endZoneOffset = ZoneOffset.UTC,
    metadata = Metadata.manualEntry(
        clientRecordId = "Your supplied record ID",
        clientRecordVersion = 0L, // Your supplied record version
        device = Device(type = Device.TYPE_WATCH)
    )
)

Upsertها هر زمان که تغییری ایجاد شود، به طور خودکار version افزایش نمی‌دهند و از هرگونه موارد غیرمنتظره رونویسی داده‌ها جلوگیری می‌کنند. با این کار، شما باید به صورت دستی مقدار بالاتری را به آن اختصاص دهید.

راهنمایی عمومی

برنامه‌ها فقط باید داده‌های خود را در Health Connect بنویسند.

اگر داده‌های برنامه شما از برنامه دیگری وارد شده باشد، مسئولیت نوشتن داده‌های خود در Health Connect بر عهده برنامه دیگر است.

همچنین ایده خوبی است که منطقی را پیاده‌سازی کنید که استثنائات نوشتن مانند خارج شدن داده‌ها از محدوده یا خطای داخلی سیستم را مدیریت کند. می‌توانید استراتژی‌های backoff و retry خود را روی یک مکانیزم زمان‌بندی کار اعمال کنید. اگر نوشتن در Health Connect در نهایت ناموفق بود، مطمئن شوید که برنامه شما می‌تواند از آن نقطه خروجی عبور کند. فراموش نکنید که خطاها را ثبت و گزارش کنید تا به تشخیص کمک کند.

هنگام ردیابی داده‌ها، بسته به نحوه نوشتن داده‌ها در برنامه‌تان، چند پیشنهاد وجود دارد که می‌توانید دنبال کنید.

مدیریت منطقه زمانی

هنگام نوشتن رکوردهای مبتنی بر زمان، از تنظیم پیش‌فرض آفست‌ها روی zoneOffset.UTC خودداری کنید، زیرا این امر می‌تواند منجر به ثبت نادرست مهرهای زمانی در زمانی شود که کاربران در مناطق دیگری هستند. در عوض، آفست را بر اساس موقعیت واقعی دستگاه محاسبه کنید. می‌توانید منطقه زمانی دستگاه را با استفاده از ZoneId.systemDefault() بازیابی کنید.

val endTime = Instant.now()
val startTime = endTime.minus(java.time.Duration.ofDays(1))
val stepsRecords = mutableListOf<StepsRecord>()
var sampleTime = startTime
val minutesBetweenSamples = 15L
while (sampleTime < endTime) {
    // Get the default ZoneId then convert it to an offset
    val zoneOffset = ZoneOffset.systemDefault().rules.getOffset(sampleTime)
    stepsRecords += StepsRecord(
        startTime = sampleTime.minus(java.time.Duration.ofMinutes(minutesBetweenSamples)),
        startZoneOffset = zoneOffset,
        endTime = sampleTime,
        endZoneOffset = zoneOffset,
        count = Random.nextLong(1, 100),
        metadata = Metadata.unknownRecordingMethod(),
    )
    sampleTime = sampleTime.plus(java.time.Duration.ofMinutes(minutesBetweenSamples))
}
healthConnectClient.insertRecords(
    stepsRecords
)

برای جزئیات بیشتر به مستندات ZoneId مراجعه کنید.

فرکانس و جزئیات را بنویسید

هنگام نوشتن داده‌ها در Health Connect، از وضوح مناسب استفاده کنید. استفاده از وضوح مناسب به کاهش بار ذخیره‌سازی کمک می‌کند، در حالی که همچنان داده‌های سازگار و دقیق را حفظ می‌کند. وضوح داده‌ها شامل دو چیز است:

  • تعداد دفعات نوشتن : برنامه شما هر چند وقت یکبار داده‌های جدید را در Health Connect می‌نویسد.
    • وقتی داده‌های جدید در دسترس هستند، تا حد امکان داده‌ها را مرتباً بنویسید، ضمن اینکه به عملکرد دستگاه نیز توجه داشته باشید.
    • برای جلوگیری از تأثیر منفی بر عمر باتری و سایر جنبه‌های عملکرد، حداکثر فاصله بین نوشتن‌ها باید ۱۵ دقیقه باشد.
  • جزئیات داده‌های نوشته شده : داده‌ها هر چند وقت یکبار نمونه‌برداری شده‌اند.
    • برای مثال، هر ۵ ثانیه یک بار نمونه‌های ضربان قلب را بنویسید.
    • هر نوع داده‌ای به نرخ نمونه‌برداری یکسانی نیاز ندارد. به‌روزرسانی داده‌های شمارش گام در هر ثانیه، در مقایسه با یک ریتم کمتر مثلاً هر ۶۰ ثانیه، مزیت کمی دارد.
    • نرخ نمونه‌برداری بالاتر می‌تواند به کاربران نگاه دقیق‌تر و جزئی‌تری به داده‌های سلامت و تناسب اندامشان بدهد. فرکانس‌های نرخ نمونه‌برداری باید تعادلی بین جزئیات و عملکرد برقرار کنند.

دستورالعمل‌های اضافی

هنگام نوشتن داده‌ها، این دستورالعمل‌ها را دنبال کنید:

  • در هر همگام‌سازی، فقط داده‌های جدید و داده‌های به‌روزرسانی‌شده‌ای که از آخرین همگام‌سازی تغییر یافته‌اند را بنویسید.
  • درخواست‌های تکه‌ای حداکثر تا ۱۰۰۰ رکورد در هر درخواست نوشتن.
  • وظایف را طوری محدود کنید که فقط زمانی که دستگاه بیکار است و باتری آن خالی نیست، اجرا شوند.
  • برای وظایف پس‌زمینه، از WorkManager برای زمان‌بندی وظایف دوره‌ای، با حداکثر مدت زمان ۱۵ دقیقه، استفاده کنید.

کد زیر از WorkManager برای زمان‌بندی وظایف پس‌زمینه به صورت دوره‌ای، با حداکثر دوره زمانی ۱۵ دقیقه و فاصله زمانی انعطاف‌پذیر ۵ دقیقه، استفاده می‌کند. این پیکربندی با استفاده از کلاس PeriodicWorkRequest.Builder تنظیم شده است.

val constraints = Constraints.Builder()
    .requiresBatteryNotLow()
    .requiresDeviceIdle(true)
    .build()

val writeDataWork = PeriodicWorkRequestBuilder<WriteDataToHealthConnectWorker>(
        15,
        TimeUnit.MINUTES,
        5,
        TimeUnit.MINUTES
    )
    .setConstraints(constraints)
    .build()

ردیابی فعال

این شامل برنامه‌هایی می‌شود که ردیابی مبتنی بر رویداد مانند ورزش و خواب یا ورودی دستی کاربر مانند تغذیه را انجام می‌دهند. این سوابق زمانی ایجاد می‌شوند که برنامه در پیش‌زمینه است یا در موارد نادری که چند بار در روز استفاده می‌شود.

مطمئن شوید که برنامه شما Health Connect را در تمام مدت رویداد در حال اجرا نگه نمی‌دارد.

داده‌ها باید به یکی از دو روش زیر در Health Connect نوشته شوند:

  • همگام‌سازی داده‌ها با Health Connect پس از اتمام رویداد. برای مثال، وقتی کاربر یک جلسه ورزشی پیگیری‌شده را به پایان می‌رساند، داده‌ها همگام‌سازی می‌شوند.
  • با استفاده از WorkManager یک کار تک‌مرحله‌ای را برنامه‌ریزی کنید تا داده‌ها بعداً همگام‌سازی شوند.

بهترین شیوه‌ها برای جزئیات و فراوانی نوشتن‌ها

هنگام نوشتن داده‌ها در Health Connect، از وضوح مناسب استفاده کنید. استفاده از وضوح مناسب به کاهش بار ذخیره‌سازی کمک می‌کند، در حالی که همچنان داده‌های سازگار و دقیق را حفظ می‌کند. وضوح داده‌ها شامل دو چیز است:

  1. فرکانس نوشتن : برنامه شما چند وقت یکبار داده‌های جدید را به Health Connect ارسال می‌کند. در صورت وجود داده‌های جدید، داده‌ها را تا حد امکان به طور مکرر بنویسید، ضمن اینکه به عملکرد دستگاه نیز توجه داشته باشید. برای جلوگیری از تأثیر منفی بر عمر باتری و سایر جنبه‌های عملکرد، حداکثر فاصله بین نوشتن‌ها باید ۱۵ دقیقه باشد.

  2. جزئیات داده‌های نوشته شده : داده‌هایی که وارد می‌شوند، چند وقت یکبار نمونه‌برداری شده‌اند. به عنوان مثال، نمونه‌های ضربان قلب را هر ۵ ثانیه بنویسید. همه انواع داده‌ها به نرخ نمونه‌برداری یکسانی نیاز ندارند. به‌روزرسانی داده‌های شمارش گام در هر ثانیه، در مقایسه با ریتم کمتر مثلاً هر ۶۰ ثانیه، مزیت کمی دارد. با این حال، نرخ نمونه‌برداری بالاتر می‌تواند به کاربران نگاهی دقیق‌تر و جزئی‌تر به داده‌های سلامت و تناسب اندام خود ارائه دهد. فرکانس‌های نرخ نمونه‌برداری باید تعادلی بین جزئیات و عملکرد برقرار کنند.

رکوردهای ساختاری برای داده‌های سری

برای انواع داده‌هایی که از یک سری نمونه استفاده می‌کنند، مانند HeartRateRecord ، ساختاردهی صحیح رکوردهایتان بسیار مهم است. به جای ایجاد یک رکورد واحد در طول روز که دائماً به‌روزرسانی می‌شود، باید چندین رکورد کوچک‌تر ایجاد کنید که هر کدام نشان‌دهنده یک بازه زمانی خاص باشند.

برای مثال، برای داده‌های ضربان قلب، باید برای هر دقیقه یک HeartRateRecord جدید ایجاد کنید. هر رکورد دارای زمان شروع و زمان پایان در آن دقیقه خواهد بود و شامل تمام نمونه‌های ضربان قلب ثبت شده در آن دقیقه خواهد بود.

در طول همگام‌سازی‌های منظم با Health Connect (مثلاً هر ۱۵ دقیقه)، برنامه شما باید تمام رکوردهای یک دقیقه‌ای که از زمان همگام‌سازی قبلی ایجاد شده‌اند را بنویسد. این کار رکوردها را در اندازه قابل مدیریت نگه می‌دارد و عملکرد پرس‌وجو و پردازش داده‌ها را بهبود می‌بخشد.

مثال زیر نحوه ایجاد یک HeartRateRecord برای یک دقیقه، شامل چندین نمونه را نشان می‌دهد:

val startTime = Instant.now().truncatedTo(ChronoUnit.MINUTES)
val endTime = startTime.plus(Duration.ofMinutes(1))

val heartRateRecord = HeartRateRecord(
    startTime = startTime,
    startZoneOffset = ZoneOffset.UTC,
    endTime = endTime,
    endZoneOffset = ZoneOffset.UTC,
    // Create a new record every minute, containing a list of samples.
    samples = listOf(
        HeartRateRecord.Sample(
            time = startTime + Duration.ofSeconds(15),
            beatsPerMinute = 80,
        ),
        HeartRateRecord.Sample(
            time = startTime + Duration.ofSeconds(30),
            beatsPerMinute = 82,
        ),
        HeartRateRecord.Sample(
            time = startTime + Duration.ofSeconds(45),
            beatsPerMinute = 85,
        )
    ),
    metadata = Metadata.autoRecorded(
        device = Device(type = Device.TYPE_WATCH)
    ))

نوشتن داده‌ها در طول روز تحت نظارت است

برای داده‌هایی که به صورت مداوم جمع‌آوری می‌شوند، مانند مراحل، برنامه شما باید تا حد امکان و در صورت وجود داده‌های جدید، به طور مرتب به Health Connect بنویسد. برای جلوگیری از تأثیر منفی بر عمر باتری و سایر جنبه‌های عملکرد، حداکثر فاصله بین نوشتن‌ها باید ۱۵ دقیقه باشد.

جدول ۱: راهنمایی برای نوشتن داده‌ها

نوع داده

واحد

مورد انتظار

مثال

مراحل

مراحل

هر ۱ دقیقه

۲۳:۱۴ - ۲۳:۱۵ - ۵ قدم

۲۳:۱۶ - ۲۳:۱۷ - ۲۲ قدم

۲۳:۱۷ - ۲۳:۱۸ - ۸ مرحله

استپس‌کادنس

گام/دقیقه

هر ۱ دقیقه

۲۳:۱۴ - ۲۳:۱۵ - ۵ بعد از ظهر

۲۳:۱۶ - ۲۳:۱۷ - ۲۲ شب

۲۳:۱۷ - ۲۳:۱۸ - ۸ شب

هل دادن ویلچر

هل می‌دهد

هر ۱ دقیقه

۲۳:۱۴ - ۲۳:۱۵ - ۵ هل دادن

۲۳:۱۶ - ۲۳:۱۷ - ۲۲ هل دادن

۲۳:۱۷ - ۲۳:۱۸ - ۸ هل دادن

کالری فعال سوزانده شده

کالری

هر ۱۵ دقیقه

۲۳:۱۵ - ۲۳:۳۰ - ۲ کالری

۲۳:۳۰ - ۲۳:۴۵ - ۲۵ کالری

۲۳:۴۵ - ۰۰:۰۰ - ۵ کالری

کل کالری سوزانده شده

کالری

هر ۱۵ دقیقه

۲۳:۱۵ - ۲۳:۳۰ - ۱۶ کالری

۲۳:۳۰ - ۲۳:۴۵ - ۱۶ کالری

۲۳:۴۵ - ۰۰:۰۰ - ۱۶ کالری

فاصله

کیلومتر/دقیقه

هر ۱ دقیقه

۲۳:۱۴-۲۳:۱۵ - ۰.۰۰۸ کیلومتر

۲۳:۱۶ - ۲۳:۱۶ - ۰.۰۲۱ کیلومتر

۲۳:۱۷ - ۲۳:۱۸ - ۰.۰۱۲ کیلومتر

ارتفاع به دست آمده

متر

هر ۱ دقیقه

۲۰:۳۶ - ۲۰:۳۷ - ۳.۰۴۸ دقیقه

۲۰:۳۹ - ۲۰:۴۰ - ۳.۰۴۸ دقیقه

۲۳:۲۳ - ۲۳:۲۴ - ۹.۱۴۴ متر

طبقات بالا رفته

کف

هر ۱ دقیقه

۲۳:۱۴ - ۲۳:۱۵ - ۵ طبقه

۲۳:۱۶ - ۲۳:۱۶ - ۲۲ طبقه

۲۳:۱۷ - ۲۳:۱۸ - ۸ طبقه

ضربان قلب

ضربان

۴ بار در دقیقه

۶:۱۱:۱۵ صبح - ۵۵ ضربه در دقیقه

۶:۱۱:۳۰ صبح - ۵۶ ضربه در دقیقه

۶:۱۱:۴۵ صبح - ۵۶ ضربه در دقیقه

۶:۱۲:۰۰ صبح - ۵۵ ضربه در دقیقه

تغییرپذیری ضربان قلبRMSSD

ام‌اس

هر ۱ دقیقه

۶:۱۱ صبح - ۲۳ میلی‌ثانیه

نرخ تنفس

تعداد تنفس/دقیقه

هر ۱ دقیقه

۲۳:۱۴ - ۲۳:۱۵ - ۶۰ نفس در دقیقه

۲۳:۱۶ - ۲۳:۱۶ - ۶۲ نفس در دقیقه

۲۳:۱۷ - ۲۳:۱۸ - ۶۴ نفس در دقیقه

اشباع اکسیژن

%

هر ۱ ساعت

۶:۱۱ - ۹۵.۲۰۸٪

داده‌ها باید در پایان جلسه تمرین یا خواب در Health Connect ثبت شوند. برای ردیابی فعال، مانند ورزش و خواب، یا ورودی دستی کاربر مانند تغذیه، این سوابق زمانی ایجاد می‌شوند که برنامه در پیش‌زمینه است، یا در موارد نادر که چند بار در روز استفاده می‌شود.

مطمئن شوید که برنامه شما Health Connect را در تمام مدت رویداد در حال اجرا نگه نمی‌دارد.

داده‌ها باید به یکی از دو روش زیر در Health Connect نوشته شوند:

  • همگام‌سازی داده‌ها با Health Connect پس از اتمام رویداد. برای مثال، وقتی کاربر یک جلسه ورزشی پیگیری‌شده را به پایان می‌رساند، داده‌ها همگام‌سازی می‌شوند.
  • با استفاده از WorkManager، یک کار تک‌مرحله‌ای را برنامه‌ریزی کنید تا داده‌ها بعداً همگام‌سازی شوند.

جلسات ورزش و خواب

حداقل، درخواست شما باید از راهنمایی‌های ستون « موارد مورد انتظار» در جدول ۲ پیروی کند. در صورت امکان، از راهنمایی‌های ستون «بهترین» پیروی کنید.

جدول زیر نحوه نوشتن داده‌ها در طول یک تمرین را نشان می‌دهد:

جدول ۲: راهنمایی برای نوشتن داده‌ها در طول یک جلسه تمرین

نوع داده

واحد

مورد انتظار

بهترین

مثال

مراحل

مراحل

هر ۱ دقیقه

هر ۱ ثانیه

۲۳:۱۴-۲۳:۱۵ - ۵ مرحله

۲۳:۱۶ - ۲۳:۱۷ - ۲۲ قدم

۲۳:۱۷ - ۲۳:۱۸ - ۸ مرحله

استپس‌کادنس

گام/دقیقه

هر ۱ دقیقه

هر ۱ ثانیه

۲۳:۱۴-۲۳:۱۵ - ۳۵ شب

۲۳:۱۶ - ۲۳:۱۷ - ۳۷ شب

۲۳:۱۷ - ۲۳:۱۸ - ۴۰ دقیقه بعد از ظهر

هل دادن ویلچر

هل می‌دهد

هر ۱ دقیقه

هر ۱ ثانیه

۲۳:۱۴-۲۳:۱۵ - ۵ فشار

۲۳:۱۶ - ۲۳:۱۷ - ۲۲ هل دادن

۲۳:۱۷ - ۲۳:۱۸ - ۸ هل دادن

دوچرخه‌سواری رکاب زدن

دور در دقیقه

هر ۱ دقیقه

هر ۱ ثانیه

۲۳:۱۴-۲۳:۱۵ - ۶۵ دور در دقیقه

۲۳:۱۶ - ۲۳:۱۷ - ۷۰ دور در دقیقه

۲۳:۱۷ - ۲۳:۱۸ - ۶۸ دور در دقیقه

قدرت

وات

هر ۱ دقیقه

هر ۱ ثانیه

۲۳:۱۴-۲۳:۱۵ - ۲۵۰ وات

۲۳:۱۶ - ۲۳:۱۷ - ۲۵۵ وات

۲۳:۱۷ - ۲۳:۱۸ - ۲۴۵ وات

سرعت

کیلومتر/دقیقه

هر ۱ دقیقه

هر ۱ ثانیه

۲۳:۱۴-۲۳:۱۵ - ۰.۳ کیلومتر در دقیقه

۲۳:۱۶ - ۲۳:۱۷ - ۰.۴ کیلومتر در دقیقه

۲۳:۱۷ - ۲۳:۱۸ -۰.۴ کیلومتر در دقیقه

فاصله

کیلومتر/متر

هر ۱ دقیقه

هر ۱ ثانیه

۲۳:۱۴-۲۳:۱۵ - ۰.۰۰۸ کیلومتر

۲۳:۱۶ - ۲۳:۱۶ - ۰.۰۲۱ کیلومتر

۲۳:۱۷ - ۲۳:۱۸ - ۰.۰۱۲ کیلومتر

کالری فعال سوزانده شده

کالری

هر ۱ دقیقه

هر ۱ ثانیه

۲۳:۱۴-۲۳:۱۵ - ۲۰ کالری

۲۳:۱۶ - ۲۳:۱۷ - ۲۰ کالری

۲۳:۱۷ - ۲۳:۱۸ - ۲۵ کالری

کل کالری سوزانده شده

کالری

هر ۱ دقیقه

هر ۱ ثانیه

۲۳:۱۴-۲۳:۱۵ - ۳۶ کالری

۲۳:۱۶ - ۲۳:۱۷ - ۳۶ کالری

۲۳:۱۷ - ۲۳:۱۸ - ۴۱ کالری

ارتفاع به دست آمده

متر

هر ۱ دقیقه

هر ۱ ثانیه

۲۰:۳۶ - ۲۰:۳۷ - ۳.۰۴۸ دقیقه

۲۰:۳۹ - ۲۰:۴۰ - ۳.۰۴۸ دقیقه

۲۳:۲۳ - ۲۳:۲۴ - ۹.۱۴۴ متر

مسیرهای تمرین

عرض/طول/عرض جغرافیایی

هر ۳-۵ ثانیه

هر ۱ ثانیه

ضربان قلب

ضربان

۴ بار در دقیقه

هر ۱ ثانیه

۲۳:۱۴-۲۳:۱۵ - ۱۵۰ ضربه در دقیقه

جدول ۳ نحوه نوشتن داده‌ها را در طول یا بعد از یک جلسه خواب نشان می‌دهد:

جدول ۳: راهنمایی برای نوشتن داده‌ها در طول یا بعد از جلسه خواب

نوع داده

واحد

نمونه‌های مورد انتظار

مثال

مرحله بندی خواب

مرحله

دوره زمانی دانه‌بندی‌شده در هر مرحله از خواب

۲۳:۴۶ - ۲۳:۵۰ - بیدار

۲۳:۵۰ - ۲۳:۵۶ - خواب سبک

۲۳:۵۶ - ۰۰:۱۶ - خواب عمیق

ضربان قلب در حالت استراحت

ضربان

مقدار روزانه واحد (انتظار می‌رود اولین چیزی که صبح‌ها مصرف می‌شود)

۶:۱۱ صبح - ۶۰ ضربه در دقیقه

اشباع اکسیژن

%

مقدار روزانه واحد (انتظار می‌رود اولین چیزی که صبح‌ها مصرف می‌شود)

۶:۱۱ - ۹۵.۲۰۸٪

رویدادهای چند ورزشی

این رویکرد از انواع و ساختارهای داده موجود استفاده می‌کند و سازگاری با پیاده‌سازی‌ها و خوانندگان داده فعلی Health Connect را تأیید می‌کند. این یک رویکرد رایج است که توسط پلتفرم‌های تناسب اندام اتخاذ می‌شود.

علاوه بر این، جلسات جداگانه مانند شنا، دوچرخه‌سواری و دویدن ذاتاً در Health Connect به هم مرتبط نیستند و خوانندگان داده‌ها باید رابطه بین این جلسات را بر اساس نزدیکی زمانی آنها استنباط کنند. انتقال بین بخش‌ها، مانند شنا به دوچرخه‌سواری، به صراحت نمایش داده نمی‌شود.

مثال زیر نحوه نوشتن داده‌ها برای یک مسابقه سه‌گانه را نشان می‌دهد:

val swimStartTime = Instant.parse("2024-08-22T08:00:00Z")
val swimEndTime = Instant.parse("2024-08-22T08:30:00Z")
val bikeStartTime = Instant.parse("2024-08-22T08:40:00Z")
val bikeEndTime = Instant.parse("2024-08-22T09:40:00Z")
val runStartTime = Instant.parse("2024-08-22T09:50:00Z")
val runEndTime = Instant.parse("2024-08-22T10:20:00Z")

val swimSession = ExerciseSessionRecord(
    startTime = swimStartTime,
    endTime = swimEndTime,
    exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_SWIMMING_OPEN_WATER,
    metadata = Metadata.autoRecorded(
      device = Device(type = Device.TYPE_WATCH)
    )
)

val bikeSession = ExerciseSessionRecord(
    startTime = bikeStartTime,
    endTime = bikeEndTime,
    exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_BIKING,
    metadata = Metadata.autoRecorded(
      device = Device(type = Device.TYPE_WATCH)
    )
)

val runSession = ExerciseSessionRecord(
    startTime = runStartTime,
    endTime = runEndTime,
    exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_RUNNING,
    metadata = Metadata.autoRecorded(
      device = Device(type = Device.TYPE_WATCH)
    )
)

healthConnectClient.insertRecords(listOf(swimSession, bikeSession, runSession))

مدیریت استثنائات

Health Connect هنگام مواجهه با مشکل، استثنائات استانداردی را برای عملیات CRUD ایجاد می‌کند. برنامه شما باید هر یک از این استثنائات را به طور مناسب دریافت و مدیریت کند.

هر متد در HealthConnectClient ، استثنائاتی را که می‌توانند رخ دهند، فهرست می‌کند. به طور کلی، برنامه شما باید استثنائات زیر را مدیریت کند:

جدول ۱: استثنائات Health Connect و بهترین شیوه‌های پیشنهادی
استثنا توضیحات بهترین شیوه توصیه شده
IllegalStateException یکی از سناریوهای زیر رخ داده است:

  • سرویس Health Connect در دسترس نیست.
  • درخواست دارای ساختار معتبری نیست. برای مثال، یک درخواست تجمیعی در بازه‌های زمانی متناوب که در آن از یک شیء Instant برای timeRangeFilter استفاده شده است.

قبل از انجام درخواست، ابتدا مشکلات احتمالی مربوط به ورودی‌ها را برطرف کنید. ترجیحاً، به جای استفاده مستقیم از متغیرها در درخواست‌های خود، مقادیری را به آنها اختصاص دهید یا از آنها به عنوان پارامتر در یک تابع سفارشی استفاده کنید تا بتوانید استراتژی‌های مدیریت خطا را اعمال کنید.
IOException هنگام خواندن و نوشتن داده‌ها از دیسک، مشکلاتی وجود دارد. برای جلوگیری از این مشکل، چند پیشنهاد ارائه می‌شود:

  • از هرگونه ورودی کاربر نسخه پشتیبان تهیه کنید.
  • قادر به مدیریت هرگونه مشکلی که در طول عملیات نوشتن انبوه رخ می‌دهد، باشید. به عنوان مثال، مطمئن شوید که فرآیند از مشکل عبور کرده و عملیات باقی مانده را انجام می‌دهد.
  • برای رسیدگی به مشکلات درخواست، از استراتژی‌های تلاش مجدد و عقب‌نشینی استفاده کنید.

RemoteException خطاهایی در داخل یا در ارتباط با سرویس اصلی که SDK به آن متصل می‌شود، رخ داده است.

برای مثال، برنامه شما سعی دارد یک رکورد با uid مشخص را حذف کند. با این حال، این استثنا پس از آن رخ می‌دهد که برنامه با بررسی سرویس مربوطه متوجه می‌شود که رکورد مورد نظر وجود ندارد.
برای جلوگیری از این مشکل، چند پیشنهاد ارائه می‌شود:

  • همگام‌سازی‌های منظمی بین پایگاه داده برنامه خود و Health Connect انجام دهید.
  • برای رسیدگی به مشکلات درخواست، از استراتژی‌های تلاش مجدد و عقب‌نشینی استفاده کنید.

SecurityException وقتی درخواست‌ها نیاز به مجوزهایی دارند که اعطا نمی‌شوند، مشکلاتی پیش می‌آید. برای جلوگیری از این، مطمئن شوید که از انواع داده Health Connect برای برنامه منتشر شده خود استفاده کرده‌اید . همچنین، باید مجوزهای Health Connect را در فایل مانیفست و در activity خود اعلام کنید.