Compare commits

..

1 Commits

Author SHA1 Message Date
aefa7ebca7 refactor: move bluetooth state to settings view model 2025-03-25 14:43:18 +01:00
8 changed files with 16 additions and 120 deletions

View File

@ -52,13 +52,6 @@ dependencies {
implementation(libs.androidx.navigation.compose) implementation(libs.androidx.navigation.compose)
implementation(libs.ktor.client.core) implementation(libs.ktor.client.core)
implementation(libs.ktor.client.cio) implementation(libs.ktor.client.cio)
implementation(libs.androidx.camera.core)
implementation(libs.androidx.camera.camera2)
implementation(libs.androidx.camera.lifecycle)
implementation(libs.androidx.camera.video)
implementation(libs.androidx.camera.view)
implementation(libs.androidx.camera.mlkit.vision)
implementation(libs.androidx.camera.extensions)
testImplementation(libs.junit) testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core) androidTestImplementation(libs.androidx.espresso.core)

View File

@ -1,17 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<application <application
android:allowBackup="true" android:allowBackup="true"

View File

@ -27,25 +27,18 @@ import com.example.tvcontroller.ui.theme.TVControllerTheme
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.core.app.ActivityCompat
import com.example.tvcontroller.services.BluetoothService import com.example.tvcontroller.services.BluetoothService
import com.example.tvcontroller.services.CameraService
import com.example.tvcontroller.services.DeviceService import com.example.tvcontroller.services.DeviceService
import com.example.tvcontroller.ui.views.CameraView
import com.example.tvcontroller.ui.views.SettingsView
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
private lateinit var bluetoothService: BluetoothService private lateinit var bluetoothService: BluetoothService
private lateinit var deviceService: DeviceService private lateinit var deviceService: DeviceService
private lateinit var cameraService: CameraService
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
bluetoothService = BluetoothService(this.applicationContext) bluetoothService = BluetoothService(this.applicationContext)
deviceService = DeviceService(this.applicationContext) deviceService = DeviceService(this.applicationContext)
cameraService = CameraService(this.applicationContext)
checkPermissions()
enableEdgeToEdge() enableEdgeToEdge()
setContent { setContent {
TVControllerTheme { TVControllerTheme {
@ -56,12 +49,6 @@ class MainActivity : ComponentActivity() {
} }
} }
} }
private fun checkPermissions() {
if (!cameraService.hasRequiredPermissions()) {
ActivityCompat.requestPermissions(this, CameraService.CAMERAX_PERMISSIONS, 0)
}
}
} }
@Composable @Composable
@ -119,13 +106,13 @@ fun TvControllerApp(
modifier = Modifier.padding(innerPadding) modifier = Modifier.padding(innerPadding)
) { ) {
composable(route = Screen.Camera.name) { composable(route = Screen.Camera.name) {
CameraView() CameraScreen()
} }
composable(route = Screen.Remote.name) { composable(route = Screen.Remote.name) {
RemoteScreen() RemoteScreen()
} }
composable(route = Screen.Settings.name) { composable(route = Screen.Settings.name) {
SettingsView( SettingsScreen(
deviceService = deviceService, deviceService = deviceService,
bluetoothService = bluetoothService bluetoothService = bluetoothService
) )
@ -135,6 +122,18 @@ fun TvControllerApp(
} }
} }
@Composable
fun CameraScreen(modifier: Modifier = Modifier) {
Column(
modifier = modifier
.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(text = "Camera Screen", modifier = modifier)
}
}
@Composable @Composable
fun RemoteScreen(modifier: Modifier = Modifier) { fun RemoteScreen(modifier: Modifier = Modifier) {
Column( Column(

View File

@ -1,4 +1,4 @@
package com.example.tvcontroller.ui.views package com.example.tvcontroller
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@ -16,14 +16,11 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel 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.BluetoothService
import com.example.tvcontroller.services.DeviceService import com.example.tvcontroller.services.DeviceService
@Composable @Composable
fun SettingsView( fun SettingsScreen(
deviceService: DeviceService, deviceService: DeviceService,
bluetoothService: BluetoothService bluetoothService: BluetoothService
) { ) {

View File

@ -1,19 +0,0 @@
package com.example.tvcontroller.services
import android.content.Context
import android.content.pm.PackageManager
class CameraService(private val context: Context) {
fun hasRequiredPermissions(): Boolean {
return CAMERAX_PERMISSIONS.all {
context.checkSelfPermission(it) == PackageManager.PERMISSION_GRANTED
}
}
companion object {
val CAMERAX_PERMISSIONS = arrayOf(
android.Manifest.permission.CAMERA,
android.Manifest.permission.RECORD_AUDIO
)
}
}

View File

@ -1,25 +0,0 @@
package com.example.tvcontroller.ui.components
import androidx.camera.view.LifecycleCameraController
import androidx.camera.view.PreviewView
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.viewinterop.AndroidView
import androidx.lifecycle.compose.LocalLifecycleOwner
@Composable
fun CameraPreview(
controller: LifecycleCameraController,
modifier: Modifier = Modifier
) {
val lifecycleOwner = LocalLifecycleOwner.current
AndroidView(
modifier = modifier,
factory = {
PreviewView(it).apply {
this.controller = controller
controller.bindToLifecycle(lifecycleOwner)
}
},
)
}

View File

@ -1,34 +0,0 @@
package com.example.tvcontroller.ui.views
import androidx.camera.view.CameraController
import androidx.camera.view.LifecycleCameraController
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import com.example.tvcontroller.ui.components.CameraPreview
@Composable
fun CameraView() {
val context = LocalContext.current
val controller = remember {
LifecycleCameraController(context).apply {
setEnabledUseCases(CameraController.VIDEO_CAPTURE)
}
}
Box(
modifier = Modifier
.fillMaxSize()
.padding(all = 16.dp),
) {
CameraPreview(controller = controller, modifier = Modifier.fillMaxSize())
}
}

View File

@ -1,6 +1,5 @@
[versions] [versions]
agp = "8.9.0" agp = "8.9.0"
cameraCore = "1.4.1"
kotlin = "2.0.0" kotlin = "2.0.0"
coreKtx = "1.10.1" coreKtx = "1.10.1"
junit = "4.13.2" junit = "4.13.2"
@ -13,13 +12,6 @@ composeBom = "2024.04.01"
navigationCompose = "2.8.4" navigationCompose = "2.8.4"
[libraries] [libraries]
androidx-camera-camera2 = { module = "androidx.camera:camera-camera2", version.ref = "cameraCore" }
androidx-camera-core = { module = "androidx.camera:camera-core", version.ref = "cameraCore" }
androidx-camera-extensions = { module = "androidx.camera:camera-extensions", version.ref = "cameraCore" }
androidx-camera-mlkit-vision = { module = "androidx.camera:camera-mlkit-vision", version.ref = "cameraCore" }
androidx-camera-view = { module = "androidx.camera:camera-view", version.ref = "cameraCore" }
androidx-camera-video = { module = "androidx.camera:camera-video", version.ref = "cameraCore" }
androidx-camera-lifecycle = { module = "androidx.camera:camera-lifecycle", version.ref = "cameraCore" }
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigationCompose" } androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigationCompose" }
junit = { group = "junit", name = "junit", version.ref = "junit" } junit = { group = "junit", name = "junit", version.ref = "junit" }