diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index cd71aa1..57a7af3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -5,8 +5,10 @@
+
+
diff --git a/app/src/main/java/com/example/tvcontroller/MainActivity.kt b/app/src/main/java/com/example/tvcontroller/MainActivity.kt
index a9b9183..06ba3e0 100644
--- a/app/src/main/java/com/example/tvcontroller/MainActivity.kt
+++ b/app/src/main/java/com/example/tvcontroller/MainActivity.kt
@@ -30,6 +30,7 @@ import androidx.compose.ui.res.painterResource
import androidx.core.app.ActivityCompat
import com.example.tvcontroller.services.BluetoothService
import com.example.tvcontroller.services.CameraService
+import com.example.tvcontroller.services.ControllerService
import com.example.tvcontroller.services.DeviceService
import com.example.tvcontroller.ui.views.CameraView
import com.example.tvcontroller.ui.views.SettingsView
@@ -39,19 +40,22 @@ class MainActivity : ComponentActivity() {
private lateinit var bluetoothService: BluetoothService
private lateinit var deviceService: DeviceService
private lateinit var cameraService: CameraService
+ private lateinit var controllerService: ControllerService
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
bluetoothService = BluetoothService(this.applicationContext)
deviceService = DeviceService(this.applicationContext)
cameraService = CameraService(this.applicationContext)
+ controllerService = ControllerService(bluetoothService)
checkPermissions()
enableEdgeToEdge()
setContent {
TVControllerTheme {
TvControllerApp(
- bluetoothService = bluetoothService,
- deviceService = deviceService
+ deviceService = deviceService,
+ controllerService = controllerService,
+ bluetoothService = bluetoothService
)
}
}
@@ -61,14 +65,18 @@ class MainActivity : ComponentActivity() {
if (!cameraService.hasRequiredPermissions()) {
ActivityCompat.requestPermissions(this, CameraService.CAMERAX_PERMISSIONS, 0)
}
+ if (!bluetoothService.hasRequiredPermissions()) {
+ ActivityCompat.requestPermissions(this, BluetoothService.BLUETOOTH_PERMISSIONS, 0)
+ }
}
}
@Composable
fun TvControllerApp(
navController: NavHostController = rememberNavController(),
- bluetoothService: BluetoothService,
- deviceService: DeviceService
+ deviceService: DeviceService,
+ controllerService: ControllerService,
+ bluetoothService: BluetoothService
) {
val backStackEntry by navController.currentBackStackEntryAsState()
val currentScreen = Screen.valueOf(backStackEntry?.destination?.route ?: Screen.Camera.name)
@@ -112,24 +120,23 @@ fun TvControllerApp(
)
}
}) { innerPadding ->
- Column {
- NavHost(
- navController = navController,
- startDestination = Screen.Camera.name,
- modifier = Modifier.padding(innerPadding)
- ) {
- composable(route = Screen.Camera.name) {
- CameraView()
- }
- composable(route = Screen.Remote.name) {
- RemoteScreen()
- }
- composable(route = Screen.Settings.name) {
- SettingsView(
- deviceService = deviceService,
- bluetoothService = bluetoothService
- )
- }
+ NavHost(
+ navController = navController,
+ startDestination = Screen.Camera.name,
+ modifier = Modifier.padding(innerPadding)
+ ) {
+ composable(route = Screen.Camera.name) {
+ CameraView()
+ }
+ composable(route = Screen.Remote.name) {
+ RemoteScreen()
+ }
+ composable(route = Screen.Settings.name) {
+ SettingsView(
+ deviceService = deviceService,
+ controllerService = controllerService,
+ bluetoothService = bluetoothService
+ )
}
}
}
diff --git a/app/src/main/java/com/example/tvcontroller/SettingsViewModel.kt b/app/src/main/java/com/example/tvcontroller/SettingsViewModel.kt
index 2d9bfa9..e67f7a5 100644
--- a/app/src/main/java/com/example/tvcontroller/SettingsViewModel.kt
+++ b/app/src/main/java/com/example/tvcontroller/SettingsViewModel.kt
@@ -1,18 +1,22 @@
package com.example.tvcontroller
-import android.bluetooth.BluetoothAdapter
+import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
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.ControllerService
import com.example.tvcontroller.services.DeviceService
+import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
class SettingsViewModel(
private val deviceService: DeviceService,
+ controllerService: ControllerService,
private val bluetoothService: BluetoothService
) : ViewModel() {
var serverAddress by mutableStateOf(deviceService.getServerAddress())
@@ -23,16 +27,20 @@ class SettingsViewModel(
private set
var connectionState by mutableStateOf(Settings.ConnectionState.Unregistered)
private set
- var bluetoothEnabled by mutableStateOf(bluetoothService.isBluetoothEnabled())
+ var controllerConnectionState by mutableIntStateOf(controllerService.connectionState)
private set
+ var activeView by mutableStateOf(MAIN_SETTINGS_VIEW)
+
+ var scannedDevices = bluetoothService.scannedDevices
+ var pairedDevices = bluetoothService.pairedDevices
init {
updateConnectionState()
viewModelScope.launch {
updateDeviceInfo()
}
- bluetoothService.onBluetoothStateChanged {
- bluetoothEnabled = it == BluetoothAdapter.STATE_ON
+ controllerService.onConnectionStateChanged {
+ controllerConnectionState = it
}
}
@@ -45,6 +53,11 @@ class SettingsViewModel(
}
}
+ fun connectController() {
+ //Log.i("SettingsScreen", "Connect controller")
+ //controllerService.connect()
+ }
+
private fun updateConnectionState() {
connectionState = if (deviceService.getToken().isEmpty()) {
Settings.ConnectionState.Unregistered
@@ -76,14 +89,26 @@ class SettingsViewModel(
registrationCode = code
}
+ fun startBluetoothScan() {
+ bluetoothService.startDiscovery()
+ }
+
+ fun stopBluetoothScan() {
+ bluetoothService.stopDiscovery()
+ }
+
companion object {
+ const val MAIN_SETTINGS_VIEW = 0
+ const val CONNECT_CONTROLLER_VIEW = 1
+
fun provideFactory(
deviceService: DeviceService,
- bluetoothService: BluetoothService,
+ controllerService: ControllerService,
+ bluetoothService: BluetoothService
) = object : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun create(modelClass: Class): T {
- return SettingsViewModel(deviceService, bluetoothService) as T
+ return SettingsViewModel(deviceService, controllerService, bluetoothService) as T
}
}
}
diff --git a/app/src/main/java/com/example/tvcontroller/data/BluetoothDevice.kt b/app/src/main/java/com/example/tvcontroller/data/BluetoothDevice.kt
new file mode 100644
index 0000000..4943680
--- /dev/null
+++ b/app/src/main/java/com/example/tvcontroller/data/BluetoothDevice.kt
@@ -0,0 +1,27 @@
+package com.example.tvcontroller.data
+
+import android.util.Log
+
+class BluetoothDevice(name: String?, address: String?) {
+ private var _name: String? = name
+ private var _address: String? = address
+
+ fun getName(): String {
+ return if (_name.isNullOrEmpty()) getAddress() else _name!!
+ }
+
+ fun getAddress(): String {
+ return if (_address == null) "" else _address!!
+ }
+
+ companion object {
+ fun fromBluetoothDevice(device: android.bluetooth.BluetoothDevice): BluetoothDevice {
+ try {
+ return BluetoothDevice(device.name, device.address)
+ } catch (e: SecurityException) {
+ Log.e("BluetoothDevice", "Error creating BluetoothDevice", e)
+ }
+ return BluetoothDevice(null, null)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/tvcontroller/services/BluetoothService.kt b/app/src/main/java/com/example/tvcontroller/services/BluetoothService.kt
index 6fe8601..094db04 100644
--- a/app/src/main/java/com/example/tvcontroller/services/BluetoothService.kt
+++ b/app/src/main/java/com/example/tvcontroller/services/BluetoothService.kt
@@ -6,17 +6,53 @@ import android.content.Context
import android.content.Intent
import android.content.BroadcastReceiver
import android.content.IntentFilter
+import android.content.pm.PackageManager
+import android.os.Build
+import android.util.Log
import androidx.core.content.ContextCompat.getSystemService
+import com.example.tvcontroller.data.BluetoothDevice
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.update
class BluetoothService(private val context: Context) {
private var bluetoothManager: BluetoothManager =
getSystemService(context, BluetoothManager::class.java)!!;
private var bluetoothAdapter: BluetoothAdapter = bluetoothManager.adapter
- private var bluetoothStateReceiver: BroadcastReceiver? = null
private var bluetoothStateChangedCallbacks: MutableList<(Int) -> Unit> = mutableListOf()
+ private val _scannedDevices = MutableStateFlow>(emptyList())
+ var scannedDevices: StateFlow> = _scannedDevices.asStateFlow()
+ private val _pairedDevices = MutableStateFlow>(emptyList())
+ var pairedDevices: StateFlow> = _pairedDevices.asStateFlow()
+
+ private var bluetoothStateReceiver: BroadcastReceiver? = object : BroadcastReceiver() {
+ override fun onReceive(context: Context, intent: Intent) {
+ val state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR)
+ bluetoothStateChangedCallbacks.forEach { it(state) }
+ }
+ }
+ private var foundDeviceReceiver: BroadcastReceiver? = object : BroadcastReceiver() {
+ override fun onReceive(context: Context, intent: Intent) {
+ val device = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ intent.getParcelableExtra(
+ android.bluetooth.BluetoothDevice.EXTRA_DEVICE,
+ android.bluetooth.BluetoothDevice::class.java
+ )
+ } else {
+ intent.getParcelableExtra(android.bluetooth.BluetoothDevice.EXTRA_DEVICE)
+ }
+ if (device != null) {
+ val newDevice = BluetoothDevice.fromBluetoothDevice(device)
+ Log.i("BluetoothService", "Found device: $newDevice")
+ _scannedDevices.update { devices -> if (newDevice in devices) devices else devices + newDevice }
+ }
+ }
+ }
init {
registerBluetoothStateReceiver()
+ updatePairedDevices()
}
fun isBluetoothEnabled(): Boolean {
@@ -24,32 +60,9 @@ class BluetoothService(private val context: Context) {
}
private fun registerBluetoothStateReceiver() {
- bluetoothStateReceiver = object : BroadcastReceiver() {
- override fun onReceive(context: Context, intent: Intent) {
- val state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR)
- bluetoothStateChangedCallbacks.forEach { it(state) }
- when (state) {
- BluetoothAdapter.STATE_ON -> {
- // Handle Bluetooth turned on
- println("SIGNAL: Bluetooth is enabled")
- }
- BluetoothAdapter.STATE_OFF -> {
- // Handle Bluetooth turned off
- println("SIGNAL: Bluetooth is disabled")
- }
- BluetoothAdapter.STATE_TURNING_ON -> {
- // Handle Bluetooth turning on
- println("SIGNAL: Bluetooth is turning on")
- }
- BluetoothAdapter.STATE_TURNING_OFF -> {
- // Handle Bluetooth turning off
- println("SIGNAL: Bluetooth is turning off")
- }
- }
- }
- }
-
- context.registerReceiver(bluetoothStateReceiver, IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED))
+ context.registerReceiver(
+ bluetoothStateReceiver, IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)
+ )
}
fun onBluetoothStateChanged(callback: (Int) -> Unit) {
@@ -62,5 +75,69 @@ class BluetoothService(private val context: Context) {
fun cleanUp() {
context.unregisterReceiver(bluetoothStateReceiver)
+ context.unregisterReceiver(foundDeviceReceiver)
+ }
+
+ fun updatePairedDevices() {
+ try {
+ _pairedDevices.update {
+ bluetoothAdapter.bondedDevices.toList()
+ .map { device -> BluetoothDevice.fromBluetoothDevice(device) }
+ }
+ } catch (e: SecurityException) {
+ println("Error updating paired devices: $e")
+ }
+ }
+
+ fun startDiscovery() {
+ try {
+ if (bluetoothAdapter.isDiscovering) return
+
+ Log.i("BluetoothService", "Starting discovery")
+ context.registerReceiver(
+ foundDeviceReceiver,
+ IntentFilter(android.bluetooth.BluetoothDevice.ACTION_FOUND)
+ )
+ updatePairedDevices()
+ bluetoothAdapter.startDiscovery()
+ } catch (e: SecurityException) {
+ println("Error starting discovery: $e")
+ Log.e("BluetoothService", "Error starting discovery: $e")
+ }
+ }
+
+ fun stopDiscovery() {
+ context.unregisterReceiver(foundDeviceReceiver)
+ try {
+ bluetoothAdapter.cancelDiscovery()
+ } catch (e: SecurityException) {
+ println("Error stopping discovery: $e")
+ }
+ }
+
+ fun hasRequiredPermissions(): Boolean {
+ return BLUETOOTH_PERMISSIONS.all {
+ context.checkSelfPermission(it) == PackageManager.PERMISSION_GRANTED
+ }
+ }
+
+ fun getBluetoothState(): Int {
+ return bluetoothAdapter.state
+ }
+
+ companion object {
+ val BLUETOOTH_PERMISSIONS = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ arrayOf(
+ android.Manifest.permission.BLUETOOTH,
+ android.Manifest.permission.BLUETOOTH_CONNECT,
+ android.Manifest.permission.BLUETOOTH_SCAN,
+ android.Manifest.permission.BLUETOOTH_ADMIN
+ )
+ } else {
+ arrayOf(
+ android.Manifest.permission.BLUETOOTH,
+ android.Manifest.permission.BLUETOOTH_ADMIN
+ )
+ }
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/tvcontroller/services/ControllerService.kt b/app/src/main/java/com/example/tvcontroller/services/ControllerService.kt
new file mode 100644
index 0000000..a3c45d1
--- /dev/null
+++ b/app/src/main/java/com/example/tvcontroller/services/ControllerService.kt
@@ -0,0 +1,40 @@
+package com.example.tvcontroller.services
+
+import android.bluetooth.BluetoothAdapter
+
+class ControllerService(bluetoothService: BluetoothService) {
+ private var connectionStateChangedListener: MutableList<(Int) -> Unit> = mutableListOf()
+
+ var connectionState = BLUETOOTH_DISABLED
+ private set
+
+ init {
+ handleBluetoothStateChanged(bluetoothService.getBluetoothState())
+ bluetoothService.onBluetoothStateChanged {
+ handleBluetoothStateChanged(it)
+ }
+ }
+
+ fun onConnectionStateChanged(callback: (Int) -> Unit) {
+ connectionStateChangedListener.add(callback)
+ }
+
+ private fun setConnectionState(state: Int) {
+ connectionState = state
+ connectionStateChangedListener.forEach { it(state) }
+ }
+
+ private fun handleBluetoothStateChanged(state: Int) {
+ when (state) {
+ BluetoothAdapter.STATE_OFF -> setConnectionState(BLUETOOTH_DISABLED)
+ else -> setConnectionState(NOT_PAIRED)
+ }
+ }
+
+ companion object {
+ const val BLUETOOTH_DISABLED = 0
+ const val NOT_PAIRED = 1
+ const val NOT_CONNECTED = 2
+ const val CONNECTED = 3
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/tvcontroller/ui/views/SettingsView.kt b/app/src/main/java/com/example/tvcontroller/ui/views/SettingsView.kt
index a64c9a8..b9ab6be 100644
--- a/app/src/main/java/com/example/tvcontroller/ui/views/SettingsView.kt
+++ b/app/src/main/java/com/example/tvcontroller/ui/views/SettingsView.kt
@@ -1,10 +1,15 @@
package com.example.tvcontroller.ui.views
+import android.annotation.SuppressLint
+import android.bluetooth.BluetoothDevice
+import android.util.Log
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.MaterialTheme
@@ -12,6 +17,7 @@ import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
@@ -20,77 +26,124 @@ 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.ControllerService
import com.example.tvcontroller.services.DeviceService
+import kotlinx.coroutines.flow.toList
@Composable
fun SettingsView(
deviceService: DeviceService,
+ controllerService: ControllerService,
bluetoothService: BluetoothService
) {
- val viewModel =
- viewModel(factory = SettingsViewModel.provideFactory(deviceService, bluetoothService))
+ val viewModel = viewModel(
+ factory = SettingsViewModel.provideFactory(
+ deviceService, controllerService, bluetoothService
+ )
+ )
- Column(
- modifier = Modifier
- .padding(16.dp, 16.dp)
- .verticalScroll(rememberScrollState()),
- verticalArrangement = Arrangement.spacedBy(8.dp)
- ) {
- Text(
- text = stringResource(id = R.string.settings_title),
- style = MaterialTheme.typography.displaySmall
- )
- Spacer(modifier = Modifier.padding(8.dp))
- Text(
- text = stringResource(id = R.string.server_settings_heading),
- style = MaterialTheme.typography.headlineSmall
- )
- Text(
- text = stringResource(id = R.string.server_connection_label) + ": " + getConnectionStateString(
- viewModel.connectionState
- ),
- style = MaterialTheme.typography.bodyMedium
- )
- OutlinedTextField(
- modifier = Modifier.fillMaxWidth(),
- value = viewModel.serverAddress,
- onValueChange = viewModel::onServerAddressChanged,
- label = { Text(stringResource(id = R.string.server_address_label)) }
- )
- OutlinedTextField(
- modifier = Modifier.fillMaxWidth(),
- value = viewModel.deviceName,
- onValueChange = viewModel::onDeviceNameChanged,
- label = { Text(stringResource(id = R.string.device_name_label)) }
- )
- OutlinedTextField(
- modifier = Modifier.fillMaxWidth(),
- value = viewModel.registrationCode,
- onValueChange = viewModel::onRegistrationCodeChanged,
- label = { Text(stringResource(id = R.string.registration_code_label)) }
- )
- OutlinedButton(onClick = { viewModel.connect() }, modifier = Modifier.fillMaxWidth()) {
+ @Composable
+ fun MainSettingsView() {
+ Column(
+ modifier = Modifier
+ .padding(16.dp, 16.dp)
+ .verticalScroll(rememberScrollState()),
+ verticalArrangement = Arrangement.spacedBy(8.dp)
+ ) {
Text(
- stringResource(id = R.string.connect_button_label)
+ text = stringResource(id = R.string.settings_title),
+ style = MaterialTheme.typography.displaySmall
)
- }
- Spacer(modifier = Modifier.padding(8.dp))
- Text(
- text = stringResource(id = R.string.controller_settings_heading),
- style = MaterialTheme.typography.headlineSmall
- )
- if (viewModel.bluetoothEnabled) {
+ Spacer(modifier = Modifier.padding(8.dp))
Text(
- text = "Controller settings: Bluetooth is enabled.",
- style = MaterialTheme.typography.bodyMedium
- )
- } else {
- Text(
- text = "Bluetooth is disabled. Please enable it in settings.",
+ text = stringResource(id = R.string.server_settings_heading),
+ style = MaterialTheme.typography.headlineSmall
+ )
+ Text(
+ text = stringResource(id = R.string.server_connection_label) + ": " + getConnectionStateString(
+ viewModel.connectionState
+ ), style = MaterialTheme.typography.bodyMedium
+ )
+ OutlinedTextField(
+ modifier = Modifier.fillMaxWidth(),
+ value = viewModel.serverAddress,
+ onValueChange = viewModel::onServerAddressChanged,
+ label = { Text(stringResource(id = R.string.server_address_label)) })
+ OutlinedTextField(
+ modifier = Modifier.fillMaxWidth(),
+ value = viewModel.deviceName,
+ onValueChange = viewModel::onDeviceNameChanged,
+ label = { Text(stringResource(id = R.string.device_name_label)) })
+ OutlinedTextField(
+ modifier = Modifier.fillMaxWidth(),
+ value = viewModel.registrationCode,
+ onValueChange = viewModel::onRegistrationCodeChanged,
+ label = { Text(stringResource(id = R.string.registration_code_label)) })
+ OutlinedButton(onClick = { viewModel.connect() }, modifier = Modifier.fillMaxWidth()) {
+ Text(
+ stringResource(id = R.string.connect_button_label)
+ )
+ }
+ Spacer(modifier = Modifier.padding(8.dp))
+ Text(
+ text = stringResource(id = R.string.controller_settings_heading),
+ style = MaterialTheme.typography.headlineSmall
+ )
+ Text(
+ text = "Controller status: " + getControllerConnectionStateString(viewModel.controllerConnectionState) + ".",
style = MaterialTheme.typography.bodyMedium
)
+ OutlinedButton(
+ onClick = { viewModel.activeView = SettingsViewModel.CONNECT_CONTROLLER_VIEW },
+ enabled = viewModel.controllerConnectionState != ControllerService.BLUETOOTH_DISABLED && viewModel.controllerConnectionState != ControllerService.CONNECTED,
+ modifier = Modifier.fillMaxWidth()
+ ) {
+ Text(
+ stringResource(id = R.string.connect_button_label)
+ )
+ }
}
}
+
+ @SuppressLint("MissingPermission")
+ @Composable
+ fun ConnectControllerView() {
+ viewModel.startBluetoothScan()
+ val pairedDevices = viewModel.pairedDevices.collectAsState()
+ val scannedDevices = viewModel.scannedDevices.collectAsState()
+ Column(
+ modifier = Modifier
+ .padding(16.dp, 16.dp)
+ .verticalScroll(rememberScrollState()),
+ verticalArrangement = Arrangement.spacedBy(8.dp)
+ ) {
+ Text(
+ text = stringResource(id = R.string.connect_controller_title),
+ style = MaterialTheme.typography.displaySmall
+ )
+ Spacer(modifier = Modifier.padding(8.dp))
+ Text(
+ text = stringResource(id = R.string.paired_devices_label),
+ style = MaterialTheme.typography.headlineSmall
+ )
+ pairedDevices.value.forEach { device ->
+ Text(text = device.getName())
+ }
+ Spacer(modifier = Modifier.padding(8.dp))
+ Text(
+ text = stringResource(id = R.string.scanned_devices_label),
+ style = MaterialTheme.typography.headlineSmall
+ )
+ scannedDevices.value.forEach { device ->
+ Text(text = device.getName())
+ }
+ }
+ }
+
+ when (viewModel.activeView) {
+ SettingsViewModel.MAIN_SETTINGS_VIEW -> MainSettingsView()
+ SettingsViewModel.CONNECT_CONTROLLER_VIEW -> ConnectControllerView()
+ }
}
@Composable
@@ -100,3 +153,14 @@ fun getConnectionStateString(state: Settings.ConnectionState): String {
Settings.ConnectionState.Registered -> stringResource(id = R.string.connection_state_registered)
}
}
+
+@Composable
+fun getControllerConnectionStateString(state: Int): String {
+ return when (state) {
+ ControllerService.BLUETOOTH_DISABLED -> stringResource(id = R.string.controller_state_bluetooth_disabled)
+ ControllerService.NOT_PAIRED -> stringResource(id = R.string.controller_state_not_paired)
+ ControllerService.NOT_CONNECTED -> stringResource(id = R.string.controller_state_not_connected)
+ ControllerService.CONNECTED -> stringResource(id = R.string.controller_state_connected)
+ else -> "Unknown"
+ }
+}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 8c4600f..70f2331 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -13,4 +13,11 @@
Server address
unregistered
registered
+ Bluetooth is turned off
+ Not paired
+ Not connected
+ Connected
+ Paired devices
+ Scanned devices
+ Connect controller
\ No newline at end of file