Как архитектурно реализовать клиента HealthConnect внутри вспомогательного класса?

Я пытаюсь реализовать утилиты HealthConnect внутри вспомогательного класса, который обрабатывает использование объектов, обработку разрешений и доступность Health Connect на телефоне пользователя, однако у меня есть проблемы с поиском правильной архитектуры, которая элегантно обрабатывает все это. Вот код вспомогательного класса,:

      
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContract
import androidx.core.content.ContextCompat.startActivity
import androidx.health.connect.client.HealthConnectClient
import androidx.health.connect.client.PermissionController
import androidx.health.connect.client.permission.HealthPermission
import androidx.health.connect.client.records.HeartRateRecord
import androidx.health.connect.client.records.StepsRecord

class HealthConnectManager(val context: Context) {
    private val healthConnectClient by lazy { HealthConnectClient.getOrCreate(context) }

    // build 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)
        )

    init {
        checkAvailability()
    }

  private  fun checkAvailability() {
        if (HealthConnectClient.isProviderAvailable(context)) {
            // Health Connect is available and installed.
            healthConnectClient = HealthConnectClient.getOrCreate(context)
        } else {
            Toast.makeText(
                context, "Health Connect is not available", Toast.LENGTH_SHORT
            ).show()
            val uri = Uri.parse("market://details?id=com.google.android.apps.healthdata")
            val gpIntent = Intent(Intent.ACTION_VIEW, uri)
            context.startActivity(gpIntent)
        }
    }

    suspend fun hasAllPermissions(permissions: Set<HealthPermission>): Boolean {
        return permissions == hcClient.permissionController.getGrantedPermissions(
            permissions
        )
    }

    fun requestPermissionsActivityContract(): ActivityResultContract<Set<HealthPermission>, Set<HealthPermission>> {
        return PermissionController.createRequestPermissionResultContract()
    }

}

Мой план состоит в том, чтобы сделать HealthConnectManagerObject в тех местах, где мне нужен Healthconnect, например, в Mainactivity:

      class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val hcManager = HealthConnectManager(this)

    }

}

Теперь у меня есть несколько проблем. Как мне создать экземпляр HealthConnectClient, только если HealthConnect установлен (см. функцию) В моем коде я создаю экземпляр дважды, один раз как член класса и один раз в указанной функции. Еще одна проблема, которую я не могу решить, - это обработка разрешений. Функции и не работают в этом вспомогательном классе, отчасти потому, что синтаксис еще не на 100% правильный (это из документации), а отчасти потому, что его нужно вызывать в действии, которого у меня нет в этом классе. Должен ли я дать этому классу в конструкторе действие в дополнение к контексту?

Я попытался позвонить вив контексте, который дан этому классу, однако ему нужна активность. Я не уверен, как это реализовать. Проблема в том, что не так много ссылок на Health Connect, потому что он все еще находится в бета-версии (в этом случае документация не очень полезна)

Если у вас есть лучшее предложение, как реализовать это, я бы с радостью его принял.

заранее спасибо

1 ответ

Вы всегда можете создать экземпляр своего менеджера, независимо от того, установлено ли приложение Health Connect на устройстве вашего пользователя. HC SDK работает отдельно от внутренней работы самого приложения. Экземпляр HC SDK, который находится в вашем приложении, в основном взаимодействует с приложением HC через IPC. Теоретически у вас может бытьHealthConnectClientпеременная объявлена ​​где угодно, вам просто нужно убедиться, что HC доступен черезcheckAvailabilityперед вызовом любого из других вызовов его методов. Если HC недоступен, корректно обработайте эти случаи и отразите состояние в пользовательском интерфейсе.

Что касается архитектуры, сделайте свой HealthConnectManager синглтоном. Воспользуйтесь преимуществами библиотек внедрения зависимостей, таких как Hilt&Dagger для Android: https://developer.android.com/training/dependency-injection/hilt-android.

Другие вопросы по тегам