ym88659208ym87991671
Получение данных об окружении устройства | Документация для разработчиков

Получение данных об окружении устройства

Обновлено 27 июня 2023

С помощью интерфейса EnvironmentInfoRepository приложение может получать информацию о состоянии устройства:

  • включен ли детский режим;
  • в каком состоянии находится экран (активен, заставка, включен режим сна);
  • подключен ли HDMI;
  • заблокированы камера и микрофон или нет;
  • какая версия StarOS.

В демо-приложении использование интерфейса продемонстрировано на вкладке ENV.

Информация о состоянии устройства

Соответствующий код вы найдете классах EnvironmentInfoFragment.kt и EnvironmentInfoViewModel.kt:

EnvironmentInfoFragment.kt
/src/main/ru/sberdevices/pub/demoapp/ui/environmentinfo/EnvironmentInfoFragment.kt
package ru.sberdevices.pub.demoapp.ui.environmentinfo

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.flow.collect
import org.koin.androidx.viewmodel.ext.android.viewModel
import ru.sberdevices.services.pub.demoapp.databinding.FragmentEnvironmentInfoBinding

class EnvironmentInfoFragment : Fragment() {

private lateinit var viewBinding: FragmentEnvironmentInfoBinding
private val viewModel by viewModel<EnvironmentInfoViewModel>()

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
viewBinding = FragmentEnvironmentInfoBinding.inflate(layoutInflater, container, false)
return viewBinding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

lifecycleScope.launchWhenCreated {
viewModel.starOsVersionFlow.collect { viewBinding.environmentInfoVersionText.text = it ?: "old os" }
}

lifecycleScope.launchWhenCreated {
viewModel.deviceTypeFlow.collect { viewBinding.environmentInfoDeviceTypeText.text = it?.name ?: "old os" }
}

lifecycleScope.launchWhenCreated {
viewModel.screenStateFlow.collect {
viewBinding.environmentInfoDreamStateText.text = it?.dreamState?.name ?: "old os"
viewBinding.environmentInfoNoScreenModeEnabledText.text =
it?.isNoScreenModeEnabled?.toString() ?: "old os"
}
}

lifecycleScope.launchWhenCreated {
viewModel.userSettingsInfo.collect {
viewBinding.environmentInfoChildModeEnabledText.text = it?.isChildModeEnabled?.toString() ?: "old os"
viewBinding.environmentInfoDeviceLockModeText.text = it?.deviceLockMode?.name ?: "old os"
}
}

lifecycleScope.launchWhenCreated {
viewModel.cameraStateFlow.collect {
viewBinding.cameraStateText.text = it?.name ?: "old os"
}
}

lifecycleScope.launchWhenCreated {
viewModel.micStateFlow.collect {
viewBinding.microphoneStateText.text = it?.name ?: "old os"
}
}

lifecycleScope.launchWhenCreated {
viewModel.isCameraCovered.collect {
viewBinding.cameraCoveredStateText.text = "${it ?: "old os"}"
}
}

viewBinding.assistantServiceText.text = "${viewModel.assistantServiceVersion ?: "unsupported"}"
viewBinding.micCameraStateServiceText.text = "${viewModel.micCameraStateServiceVersion ?: "unsupported"}"
viewBinding.payLibServiceText.text = "${viewModel.paylibServiceVersion ?: "unsupported"}"
viewBinding.messagingServiceText.text = "${viewModel.messagingServiceVersion ?: "unsupported"}"
viewBinding.envInfoServiceText.text = "${viewModel.environmentInfoServiceVersion ?: "unsupported"}"
}

companion object {
fun newInstance() = EnvironmentInfoFragment()
}
}
EnvironmentInfoViewModel.kt
/src/main/ru/sberdevices/pub/demoapp/ui/environmentinfo/EnvironmentInfoViewModel.kt
package ru.sberdevices.pub.demoapp.ui.environmentinfo

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.emitAll
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.shareIn
import ru.sberdevices.messaging.Messaging
import ru.sberdevices.services.assistant.PublicAssistantLib
import ru.sberdevices.services.mic.camera.state.MicCameraStateRepository
import ru.sberdevices.services.paylib.PayLib
import ru.sberdevices.services.published.environment.info.EnvironmentInfoRepository
import ru.sberdevices.services.published.environment.info.models.ScreenState
import ru.sberdevices.services.published.environment.info.models.UserSettingsInfo

class EnvironmentInfoViewModel(
private val environmentInfoRepository: EnvironmentInfoRepository,
private val micCameraStateRepository: MicCameraStateRepository,
assistantLib: PublicAssistantLib,
payLib: PayLib,
messaging: Messaging,
) : ViewModel() {

val starOsVersionFlow = flow {
emit(
checkVersionAndInvoke(
getServiceVersion = environmentInfoRepository::getVersion,
minServiceVersion = 1,
valueIfIncompatible = null,
getValueIfCompatible = environmentInfoRepository::getStarOsVersion
)
)
}.shareIn(viewModelScope, SharingStarted.WhileSubscribed(), 1)

val deviceTypeFlow = flow {
emit(
checkVersionAndInvoke(
getServiceVersion = environmentInfoRepository::getVersion,
minServiceVersion = 1,
valueIfIncompatible = null,
getValueIfCompatible = environmentInfoRepository::getDeviceType
)
)
}.shareIn(viewModelScope, SharingStarted.WhileSubscribed(), 1)

val screenStateFlow = flow {
emitAll(checkVersionAndInvoke(
getServiceVersion = environmentInfoRepository::getVersion,
minServiceVersion = 1,
valueIfIncompatible = flowOf<ScreenState?>(null),
getValueIfCompatible = { environmentInfoRepository.screenStateFlow }
))
}.shareIn(viewModelScope, SharingStarted.WhileSubscribed(), 1)

val userSettingsInfo = flow {
emitAll(checkVersionAndInvoke(
getServiceVersion = environmentInfoRepository::getVersion,
minServiceVersion = 1,
valueIfIncompatible = flowOf<UserSettingsInfo?>(null),
getValueIfCompatible = { environmentInfoRepository.userSettingsInfo }
))
}.shareIn(viewModelScope, SharingStarted.WhileSubscribed(), 1)

val cameraStateFlow = flow {
emitAll(checkVersionAndInvoke(
getServiceVersion = micCameraStateRepository::getVersion,
minServiceVersion = 1,
valueIfIncompatible = flowOf<MicCameraStateRepository.State?>(null),
getValueIfCompatible = { micCameraStateRepository.cameraState }
))
}.shareIn(viewModelScope, SharingStarted.WhileSubscribed(), 1)

val micStateFlow = flow {
emitAll(checkVersionAndInvoke(
getServiceVersion = micCameraStateRepository::getVersion,
minServiceVersion = 1,
valueIfIncompatible = flowOf<MicCameraStateRepository.State?>(null),
getValueIfCompatible = { micCameraStateRepository.micState }
))
}.shareIn(viewModelScope, SharingStarted.WhileSubscribed(), 1)

val isCameraCovered = flow {
emitAll(checkVersionAndInvoke(
getServiceVersion = micCameraStateRepository::getVersion,
minServiceVersion = 1,
valueIfIncompatible = flowOf<Boolean?>(null),
getValueIfCompatible = { micCameraStateRepository.isCameraCovered }
))
}.shareIn(viewModelScope, SharingStarted.WhileSubscribed(), 1)

val assistantServiceVersion = assistantLib.getVersion()
val micCameraStateServiceVersion = micCameraStateRepository.getVersion()
val environmentInfoServiceVersion = environmentInfoRepository.getVersion()
val paylibServiceVersion = payLib.getVersion()
val messagingServiceVersion = messaging.getVersion()

private suspend fun <T> checkVersionAndInvoke(
getServiceVersion: () -> Int?,
minServiceVersion: Int,
valueIfIncompatible: T,
getValueIfCompatible: suspend () -> T
): T {
val version = getServiceVersion() ?: return valueIfIncompatible
return if (version >= minServiceVersion) {
getValueIfCompatible()
} else {
valueIfIncompatible
}
}
}

Особенности детского режима

Детский режим работы устройства ограничивает доступ к неподходящему контенту в приложениях. Такой режим можно реализовать следующими способами:

  • Если устройство работает в детском режиме, то в приложении становится доступен только детский профиль с соответствующим контентом. В таком профиле пользователь не может оплачивать покупки или переключиться на взрослый профиль. Пример сообщения, которое вы можете показать пользователям при работе в детском режиме: «Доступны только детские профили, так как включен детский режим».
  • Если устройство работает в детском режиме, то в приложении нельзя запустить контент 18+ независимо от включенного профиля. Поверх карточек с таким контентом отображается текст: «18+ Включен детский режим».
ПАО Сбербанк использует cookie для персонализации сервисов и удобства пользователей.
Вы можете запретить сохранение cookie в настройках своего браузера.