changes
This commit is contained in:
1 parent
471741aeb4
commit
f54948b1a2
7 files changed
+102
-169
No files matched your search
@@ -14,10 +14,9 @@ import android.os.Build
|
|||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.annotation.RequiresPermission
|
import androidx.annotation.RequiresPermission
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
|
import com.example.smart_watch_android.MainActivity
|
||||||
|
import com.example.smart_watch_android.ViewModel
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
@@ -28,63 +27,67 @@ import java.time.format.DateTimeFormatter
|
|||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import kotlin.time.Duration.Companion.milliseconds
|
import kotlin.time.Duration.Companion.milliseconds
|
||||||
|
|
||||||
class BleManager(private val context: Context) {
|
class BleManager(private val context: Context, val viewModel: ViewModel) {
|
||||||
val deviceAddress = "10:BD:A3:8F:01:0E"
|
|
||||||
|
//var deviceAddress = "10:BD:A3:8F:01:0E"
|
||||||
|
val devices = mutableListOf<Devices>()
|
||||||
|
|
||||||
val currentDate: LocalDate? = LocalDate.now()
|
val currentDate: LocalDate? = LocalDate.now()
|
||||||
val deviceUUIDs = DeviceUUIDs
|
private val deviceUUIDs = DeviceUUIDs
|
||||||
private var bluetoothGatt: BluetoothGatt? = null
|
private var bluetoothGatt: BluetoothGatt? = null
|
||||||
|
|
||||||
private var bluetoothManager: BluetoothManager? = null
|
private var bluetoothManager: BluetoothManager? = null
|
||||||
private var bluetoothAdapter: BluetoothAdapter? = null
|
private var bluetoothAdapter: BluetoothAdapter? = null
|
||||||
|
var deviceAddress: String = ""
|
||||||
|
val gattCallback = object : BluetoothGattCallback() {
|
||||||
|
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
|
override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
|
||||||
|
if (status == BluetoothGatt.GATT_SUCCESS) {
|
||||||
|
if (newState == BluetoothProfile.STATE_CONNECTED) {
|
||||||
|
Log.d("ESP32_BLE", "Connected! Start discoverServices()...")
|
||||||
|
gatt.discoverServices()
|
||||||
|
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
|
||||||
|
viewModel.setDeviceConection(false)
|
||||||
|
|
||||||
var isConnected by mutableStateOf(false)
|
gatt.close()
|
||||||
private set
|
bluetoothGatt = null
|
||||||
|
Log.d("ESP32_BLE", "Disconnected.")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.d("ESP32_BLE", "error in onConnectionStateChange! Status-Code: $status")
|
||||||
|
viewModel.setDeviceConection(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
|
||||||
|
if (status == BluetoothGatt.GATT_SUCCESS) {
|
||||||
|
viewModel.setDeviceConection(true)
|
||||||
|
Log.d("ESP32_BLE", "connected successfully.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data class Devices(
|
||||||
|
val deviceName: String,
|
||||||
|
val deviceMac: String
|
||||||
|
)
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.S)
|
||||||
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
fun init() {
|
fun init() {
|
||||||
|
checkAndRequestBluetoothPermissions()
|
||||||
bluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
|
bluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
|
||||||
bluetoothAdapter = bluetoothManager?.adapter
|
bluetoothAdapter = bluetoothManager?.adapter
|
||||||
|
|
||||||
if (bluetoothAdapter == null) return
|
|
||||||
|
|
||||||
try {
|
|
||||||
val device = bluetoothAdapter?.getRemoteDevice(deviceAddress)
|
|
||||||
if (device != null) {
|
|
||||||
val state = bluetoothManager!!.getConnectionState(device, BluetoothProfile.GATT)
|
|
||||||
if (state == BluetoothProfile.STATE_CONNECTED) {
|
|
||||||
Log.d("ESP32_BLE", "App restarted: device still connected. rebuild GATT-connection...")
|
|
||||||
connectToEsp32(deviceAddress)
|
|
||||||
} else {
|
|
||||||
isConnected = false
|
|
||||||
Log.d("ESP32_BLE", "App restarted: not connected.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Log.d("ESP32_BLE", "error while checking the status: ${e.message}")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
fun checkCurrentConnectionState(deviceAddress: String) {
|
fun getDeviceList(): List<Devices>{
|
||||||
if (bluetoothManager == null) return
|
bluetoothAdapter?.bondedDevices?.forEach { device ->
|
||||||
|
devices.add(Devices(deviceName = device.name, deviceMac = device.address))
|
||||||
try {
|
|
||||||
val device = bluetoothAdapter?.getRemoteDevice(deviceAddress)
|
|
||||||
if (device != null) {
|
|
||||||
val state = bluetoothManager!!.getConnectionState(device, BluetoothProfile.GATT)
|
|
||||||
if (state == BluetoothProfile.STATE_CONNECTED) {
|
|
||||||
isConnected = true
|
|
||||||
Log.d("ESP32_BLE", "App restarted: device still connected!")
|
|
||||||
} else {
|
|
||||||
isConnected = false
|
|
||||||
Log.d("ESP32_BLE", "App restarted: device not connected.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Log.d("ESP32_BLE", "error while checking the status: ${e.message}")
|
|
||||||
}
|
}
|
||||||
|
return devices
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
@RequiresApi(Build.VERSION_CODES.S)
|
@RequiresApi(Build.VERSION_CODES.S)
|
||||||
fun checkAndRequestBluetoothPermissions() {
|
fun checkAndRequestBluetoothPermissions() {
|
||||||
val permissions = arrayOf(
|
val permissions = arrayOf(
|
||||||
@@ -107,7 +110,7 @@ class BleManager(private val context: Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun connectToEsp32(deviceAddress: String) {
|
fun connectToEsp32() {
|
||||||
Log.d("ESP32_BLE", "connectToEsp32 started with address: $deviceAddress")
|
Log.d("ESP32_BLE", "connectToEsp32 started with address: $deviceAddress")
|
||||||
if (bluetoothAdapter == null) {
|
if (bluetoothAdapter == null) {
|
||||||
Log.d("ESP32_BLE", "error: Bluetooth is not supported!")
|
Log.d("ESP32_BLE", "error: Bluetooth is not supported!")
|
||||||
@@ -117,34 +120,6 @@ class BleManager(private val context: Context) {
|
|||||||
try {
|
try {
|
||||||
val device = bluetoothAdapter!!.getRemoteDevice(deviceAddress)
|
val device = bluetoothAdapter!!.getRemoteDevice(deviceAddress)
|
||||||
|
|
||||||
val gattCallback = object : BluetoothGattCallback() {
|
|
||||||
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
|
|
||||||
override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
|
|
||||||
if (status == BluetoothGatt.GATT_SUCCESS) {
|
|
||||||
if (newState == BluetoothProfile.STATE_CONNECTED) {
|
|
||||||
Log.d("ESP32_BLE", "Connected! Start discoverServices()...")
|
|
||||||
gatt.discoverServices()
|
|
||||||
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
|
|
||||||
isConnected = false
|
|
||||||
|
|
||||||
gatt.close()
|
|
||||||
bluetoothGatt = null
|
|
||||||
Log.d("ESP32_BLE", "Disconnected.")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.d("ESP32_BLE", "error in onConnectionStateChange! Status-Code: $status")
|
|
||||||
isConnected = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
|
|
||||||
if (status == BluetoothGatt.GATT_SUCCESS) {
|
|
||||||
isConnected = true
|
|
||||||
Log.d("ESP32_BLE", "connected successfully.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED) {
|
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED) {
|
||||||
bluetoothGatt = device.connectGatt(context, false, gattCallback)
|
bluetoothGatt = device.connectGatt(context, false, gattCallback)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
package com.example.smart_watch_android
|
|
||||||
|
|
||||||
import android.app.Notification
|
|
||||||
import android.app.NotificationChannel
|
|
||||||
import android.app.NotificationManager
|
|
||||||
import android.app.Service
|
|
||||||
import android.content.Intent
|
|
||||||
import android.os.IBinder
|
|
||||||
import androidx.core.app.NotificationCompat
|
|
||||||
|
|
||||||
class BluetoothForegroundService : Service() {
|
|
||||||
companion object {
|
|
||||||
const val CHANNEL_ID = "BluetoothServiceChannel"
|
|
||||||
const val NOTIFICATION_ID = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreate() {
|
|
||||||
super.onCreate()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
|
||||||
createNotificationChannel()
|
|
||||||
|
|
||||||
val notification: Notification = NotificationCompat.Builder(this, CHANNEL_ID)
|
|
||||||
.setContentTitle("Bluetooth connection active")
|
|
||||||
.setContentText("the app keeps the connection in the background.")
|
|
||||||
.setSmallIcon(android.R.drawable.stat_sys_data_bluetooth)
|
|
||||||
.build()
|
|
||||||
|
|
||||||
startForeground(NOTIFICATION_ID, notification)
|
|
||||||
return START_STICKY
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBind(intent: Intent?): IBinder? {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createNotificationChannel() {
|
|
||||||
val serviceChannel = NotificationChannel(
|
|
||||||
CHANNEL_ID,
|
|
||||||
"Bluetooth Service Channel",
|
|
||||||
NotificationManager.IMPORTANCE_LOW
|
|
||||||
)
|
|
||||||
val manager = getSystemService(NotificationManager::class.java)
|
|
||||||
manager?.createNotificationChannel(serviceChannel)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.example.smart_watch_android
|
package com.example.smart_watch_android
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
@@ -8,37 +9,41 @@ import androidx.activity.compose.setContent
|
|||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.annotation.RequiresPermission
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import com.example.smart_watch_android.BLE.BleManager
|
||||||
import com.example.smart_watch_android.Screens.AppNavigation
|
import com.example.smart_watch_android.Screens.AppNavigation
|
||||||
|
|
||||||
class MainActivity : ComponentActivity() {
|
class MainActivity : ComponentActivity() {
|
||||||
private val viewModel: MainViewModel by viewModels()
|
lateinit var bleManager: BleManager
|
||||||
|
private val viewModel: ViewModel by viewModels()
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.S)
|
@RequiresApi(Build.VERSION_CODES.S)
|
||||||
@androidx.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
viewModel.initBleManager(this)
|
bleManager = BleManager(this, viewModel)
|
||||||
viewModel.bleManager.checkAndRequestBluetoothPermissions()
|
bleManager.init()
|
||||||
enableEdgeToEdge()
|
enableEdgeToEdge()
|
||||||
setContent {
|
setContent {
|
||||||
MaterialTheme {
|
MaterialTheme {
|
||||||
Surface(
|
Surface(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
color = MaterialTheme.colorScheme.background
|
color = MaterialTheme.colorScheme.background
|
||||||
) {
|
) {
|
||||||
AppNavigation(bleManager = viewModel.bleManager)
|
AppNavigation(bleManager = bleManager, viewModel = viewModel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
startBluetoothService()
|
|
||||||
}
|
}
|
||||||
private fun startBluetoothService() {
|
|
||||||
val serviceIntent = Intent(this, BluetoothForegroundService::class.java)
|
|
||||||
|
|
||||||
startForegroundService(serviceIntent)
|
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
bleManager.disconnectEsp32()
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
package com.example.smart_watch_android
|
|
||||||
|
|
||||||
import android.Manifest
|
|
||||||
import android.app.Application
|
|
||||||
import android.content.Context
|
|
||||||
import androidx.annotation.RequiresPermission
|
|
||||||
import androidx.lifecycle.AndroidViewModel
|
|
||||||
import com.example.smart_watch_android.BLE.BleManager
|
|
||||||
|
|
||||||
class MainViewModel(
|
|
||||||
application: Application,
|
|
||||||
) : AndroidViewModel(application) {
|
|
||||||
|
|
||||||
lateinit var bleManager: BleManager
|
|
||||||
private set
|
|
||||||
|
|
||||||
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
|
|
||||||
fun initBleManager(activityContext: Context) {
|
|
||||||
if (!::bleManager.isInitialized) {
|
|
||||||
bleManager = BleManager(context = activityContext)
|
|
||||||
bleManager.init()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +1,25 @@
|
|||||||
package com.example.smart_watch_android.Screens
|
package com.example.smart_watch_android.Screens
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.R
|
|
||||||
import androidx.annotation.RequiresPermission
|
import androidx.annotation.RequiresPermission
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.DisposableEffect
|
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.navigation.NavController
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.composable
|
import androidx.navigation.compose.composable
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
import com.example.smart_watch_android.BLE.BleManager
|
import com.example.smart_watch_android.BLE.BleManager
|
||||||
import com.example.smart_watch_android.MainViewModel
|
import com.example.smart_watch_android.ViewModel
|
||||||
|
|
||||||
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
@Composable
|
@Composable
|
||||||
fun AppNavigation(bleManager: BleManager) {
|
fun AppNavigation(bleManager: BleManager, viewModel: ViewModel) {
|
||||||
val navController = rememberNavController()
|
val navController = rememberNavController()
|
||||||
|
val isConnected by viewModel.isDeviceConnected.collectAsState()
|
||||||
|
|
||||||
LaunchedEffect(bleManager.isConnected) {
|
LaunchedEffect(viewModel.isConnected) {
|
||||||
if (bleManager.isConnected) {
|
if (isConnected) {
|
||||||
navController.navigate("control_panel") {
|
navController.navigate("control_panel") {
|
||||||
popUpTo("connect") { inclusive = true }
|
popUpTo("connect") { inclusive = true }
|
||||||
}
|
}
|
||||||
@@ -29,7 +29,7 @@ fun AppNavigation(bleManager: BleManager) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val startDestination = if (bleManager.isConnected) {
|
val startDestination = if (isConnected) {
|
||||||
"control_panel"
|
"control_panel"
|
||||||
} else {
|
} else {
|
||||||
"connect"
|
"connect"
|
||||||
@@ -42,7 +42,8 @@ fun AppNavigation(bleManager: BleManager) {
|
|||||||
// Connect Screen
|
// Connect Screen
|
||||||
composable("connect") {
|
composable("connect") {
|
||||||
ConnectScreen(
|
ConnectScreen(
|
||||||
bleManager = bleManager
|
bleManager = bleManager,
|
||||||
|
viewModel = viewModel
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
package com.example.smart_watch_android.Screens
|
package com.example.smart_watch_android.Screens
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.annotation.RequiresPermission
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@@ -28,12 +31,14 @@ import androidx.compose.ui.graphics.Color
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import com.example.smart_watch_android.BLE.BleManager
|
import com.example.smart_watch_android.BLE.BleManager
|
||||||
|
import com.example.smart_watch_android.ViewModel
|
||||||
|
|
||||||
|
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
@Composable
|
@Composable
|
||||||
fun ConnectScreen(bleManager: BleManager) {
|
fun ConnectScreen(bleManager: BleManager, viewModel: ViewModel) {
|
||||||
var expanded by remember { mutableStateOf(false) }
|
var expanded by remember { mutableStateOf(false) }
|
||||||
var selectedDevice by remember { mutableStateOf("device") }
|
var selectedDevice by remember { mutableStateOf("device") }
|
||||||
val items = listOf("Option 1", "Option 2", "Option 3")
|
val devices = bleManager.getDeviceList()
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
@@ -53,11 +58,13 @@ fun ConnectScreen(bleManager: BleManager) {
|
|||||||
expanded = expanded,
|
expanded = expanded,
|
||||||
onDismissRequest = { expanded = false }
|
onDismissRequest = { expanded = false }
|
||||||
) {
|
) {
|
||||||
items.forEach { item ->
|
devices.forEach { item ->
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
text = { Text(item) },
|
text = { Text(item.deviceName) },
|
||||||
onClick = {
|
onClick = {
|
||||||
selectedDevice = item
|
selectedDevice = item.deviceName
|
||||||
|
bleManager.deviceAddress = item.deviceMac
|
||||||
|
Log.d("ConnectScreen", item.deviceMac)
|
||||||
expanded = false
|
expanded = false
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -67,8 +74,8 @@ fun ConnectScreen(bleManager: BleManager) {
|
|||||||
Spacer(modifier = Modifier.height(64.dp))
|
Spacer(modifier = Modifier.height(64.dp))
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
onClick = { bleManager.connectToEsp32(deviceAddress = "10:BD:A3:8F:01:0E") },
|
|
||||||
modifier = Modifier.size(400.dp),
|
modifier = Modifier.size(400.dp),
|
||||||
|
onClick = {bleManager.connectToEsp32() },
|
||||||
shape = CircleShape,
|
shape = CircleShape,
|
||||||
colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF5E18BE))
|
colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF5E18BE))
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.example.smart_watch_android
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
|
||||||
|
class ViewModel : ViewModel() {
|
||||||
|
var isConnected = MutableStateFlow(false)
|
||||||
|
|
||||||
|
val isDeviceConnected: StateFlow<Boolean> = isConnected.asStateFlow()
|
||||||
|
|
||||||
|
fun setDeviceConection(status: Boolean) {
|
||||||
|
isConnected.value = status
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user