refactor: move bluetooth state to settings view model

This commit is contained in:
Fritz Heiden 2025-03-25 14:43:18 +01:00
parent 0c1f4801c3
commit e3623cb128
5 changed files with 25 additions and 40 deletions

View File

@ -1,13 +1,11 @@
package com.example.tvcontroller
import android.bluetooth.BluetoothAdapter
import android.content.ContentValues.TAG
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
@ -30,11 +28,9 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.res.painterResource
import androidx.core.app.ActivityCompat
import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.tvcontroller.services.BluetoothService
import com.example.tvcontroller.services.CameraService
import com.example.tvcontroller.services.DeviceService
import com.example.tvcontroller.ui.AppViewModel
import com.example.tvcontroller.ui.views.CameraView
import com.example.tvcontroller.ui.views.SettingsView
@ -43,13 +39,10 @@ class MainActivity : ComponentActivity() {
private lateinit var bluetoothService: BluetoothService
private lateinit var deviceService: DeviceService
private lateinit var cameraService: CameraService
private val appViewModel by viewModels<AppViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
bluetoothService = BluetoothService(this.applicationContext)
bluetoothService.onBluetoothStateChanged { state -> appViewModel.setBluetoothEnabled(state == BluetoothAdapter.STATE_ON) }
appViewModel.setBluetoothEnabled(bluetoothService.isBluetoothEnabled())
deviceService = DeviceService(this.applicationContext)
cameraService = CameraService(this.applicationContext)
checkPermissions()
@ -57,7 +50,6 @@ class MainActivity : ComponentActivity() {
setContent {
TVControllerTheme {
TvControllerApp(
appViewModel = appViewModel,
bluetoothService = bluetoothService,
deviceService = deviceService
)
@ -75,8 +67,7 @@ class MainActivity : ComponentActivity() {
@Composable
fun TvControllerApp(
navController: NavHostController = rememberNavController(),
appViewModel: AppViewModel = viewModel(),
bluetoothService: BluetoothService? = null,
bluetoothService: BluetoothService,
deviceService: DeviceService
) {
val backStackEntry by navController.currentBackStackEntryAsState()
@ -134,7 +125,10 @@ fun TvControllerApp(
RemoteScreen()
}
composable(route = Screen.Settings.name) {
SettingsView(appViewModel = appViewModel, deviceService = deviceService)
SettingsView(
deviceService = deviceService,
bluetoothService = bluetoothService
)
}
}
}

View File

@ -1,15 +1,20 @@
package com.example.tvcontroller
import android.bluetooth.BluetoothAdapter
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.example.tvcontroller.services.BluetoothService
import com.example.tvcontroller.services.DeviceService
import kotlinx.coroutines.launch
class SettingsViewModel(private val deviceService: DeviceService) : ViewModel() {
class SettingsViewModel(
private val deviceService: DeviceService,
private val bluetoothService: BluetoothService
) : ViewModel() {
var serverAddress by mutableStateOf(deviceService.getServerAddress())
private set
var deviceName by mutableStateOf(android.os.Build.MANUFACTURER + " " + android.os.Build.MODEL)
@ -18,12 +23,17 @@ class SettingsViewModel(private val deviceService: DeviceService) : ViewModel()
private set
var connectionState by mutableStateOf(Settings.ConnectionState.Unregistered)
private set
var bluetoothEnabled by mutableStateOf(bluetoothService.isBluetoothEnabled())
private set
init {
updateConnectionState()
viewModelScope.launch {
updateDeviceInfo()
}
bluetoothService.onBluetoothStateChanged {
bluetoothEnabled = it == BluetoothAdapter.STATE_ON
}
}
fun connect() {
@ -69,10 +79,11 @@ class SettingsViewModel(private val deviceService: DeviceService) : ViewModel()
companion object {
fun provideFactory(
deviceService: DeviceService,
bluetoothService: BluetoothService,
) = object : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return SettingsViewModel(deviceService) as T
return SettingsViewModel(deviceService, bluetoothService) as T
}
}
}

View File

@ -1,7 +0,0 @@
package com.example.tvcontroller.ui
import com.example.tvcontroller.Screen
data class AppUiState(
val currentScreen: Screen = Screen.Settings,
)

View File

@ -1,16 +0,0 @@
package com.example.tvcontroller.ui
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
class AppViewModel() : ViewModel() {
private var isBluetoothEnabled = mutableStateOf(false)
fun setBluetoothEnabled(enabled: Boolean) {
isBluetoothEnabled.value = enabled
}
fun isBluetoothEnabled(): Boolean {
return isBluetoothEnabled.value
}
}

View File

@ -19,13 +19,16 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.tvcontroller.R
import com.example.tvcontroller.Settings
import com.example.tvcontroller.SettingsViewModel
import com.example.tvcontroller.services.BluetoothService
import com.example.tvcontroller.services.DeviceService
import com.example.tvcontroller.ui.AppViewModel
@Composable
fun SettingsView(deviceService: DeviceService, appViewModel: AppViewModel) {
fun SettingsView(
deviceService: DeviceService,
bluetoothService: BluetoothService
) {
val viewModel =
viewModel<SettingsViewModel>(factory = SettingsViewModel.Companion.provideFactory(deviceService))
viewModel<SettingsViewModel>(factory = SettingsViewModel.provideFactory(deviceService, bluetoothService))
Column(
modifier = Modifier
@ -76,7 +79,7 @@ fun SettingsView(deviceService: DeviceService, appViewModel: AppViewModel) {
text = stringResource(id = R.string.controller_settings_heading),
style = MaterialTheme.typography.headlineSmall
)
if (appViewModel.isBluetoothEnabled()) {
if (viewModel.bluetoothEnabled) {
Text(
text = "Controller settings: Bluetooth is enabled.",
style = MaterialTheme.typography.bodyMedium