mirror of
https://github.com/aljazceru/Android-nRF-Toolbox.git
synced 2026-01-22 16:14:23 +01:00
Extract scanner to Common Libraries
This commit is contained in:
@@ -2,6 +2,7 @@ package no.nordicsemi.android.nrftoolbox
|
||||
|
||||
import android.app.Activity
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
@@ -14,70 +15,44 @@ import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.navigation.NavType
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import androidx.navigation.navArgument
|
||||
import no.nordicsemi.android.bps.view.BPSScreen
|
||||
import no.nordicsemi.android.cgms.view.CGMScreen
|
||||
import no.nordicsemi.android.csc.view.CSCScreen
|
||||
import no.nordicsemi.android.gls.view.GLSScreen
|
||||
import no.nordicsemi.android.hrs.view.HRSScreen
|
||||
import no.nordicsemi.android.hts.view.HTSScreen
|
||||
import no.nordicsemi.android.permission.bonding.view.BondingScreen
|
||||
import no.nordicsemi.android.permission.view.BluetoothNotAvailableScreen
|
||||
import no.nordicsemi.android.permission.view.BluetoothNotEnabledScreen
|
||||
import no.nordicsemi.android.permission.view.RequestPermissionScreen
|
||||
import no.nordicsemi.android.prx.view.PRXScreen
|
||||
import no.nordicsemi.android.rscs.view.RSCSScreen
|
||||
import no.nordicsemi.android.scanner.view.ScanDeviceScreen
|
||||
import no.nordicsemi.android.scanner.view.ScanDeviceScreenResult
|
||||
import no.nordicsemi.android.theme.view.CloseIconAppBar
|
||||
import no.nordicsemi.android.utils.exhaustive
|
||||
|
||||
@Composable
|
||||
internal fun HomeScreen() {
|
||||
val navController = rememberNavController()
|
||||
|
||||
val viewModel = hiltViewModel<NavigationViewModel>()
|
||||
val continueAction: () -> Unit = { viewModel.finish() }
|
||||
val state = viewModel.state.collectAsState().value
|
||||
|
||||
BackHandler { viewModel.navigateUp() }
|
||||
|
||||
NavHost(navController = navController, startDestination = NavDestination.HOME.id) {
|
||||
composable(NavDestination.HOME.id) { HomeView { viewModel.navigate(it) } }
|
||||
composable(NavDestination.CSC.id) { CSCScreen { viewModel.navigateUp() } }
|
||||
composable(NavDestination.HRS.id) { HRSScreen { viewModel.navigateUp() } }
|
||||
composable(NavDestination.HTS.id) { HTSScreen { viewModel.navigateUp() } }
|
||||
composable(NavDestination.GLS.id) { GLSScreen { viewModel.navigateUp() } }
|
||||
composable(NavDestination.BPS.id) { BPSScreen { viewModel.navigateUp() } }
|
||||
composable(NavDestination.PRX.id) { PRXScreen { viewModel.navigateUp() } }
|
||||
composable(NavDestination.RSCS.id) { RSCSScreen { viewModel.navigateUp() } }
|
||||
composable(NavDestination.CGMS.id) { CGMScreen { viewModel.navigateUp() } }
|
||||
composable(NavDestination.REQUEST_PERMISSION.id) { RequestPermissionScreen(continueAction) }
|
||||
composable(NavDestination.BLUETOOTH_NOT_AVAILABLE.id) { BluetoothNotAvailableScreen { viewModel.finish() } }
|
||||
composable(NavDestination.BLUETOOTH_NOT_ENABLED.id) {
|
||||
BluetoothNotEnabledScreen(continueAction)
|
||||
val activity = LocalContext.current as Activity
|
||||
BackHandler {
|
||||
if (navController.currentDestination?.navigatorName != NavDestination.HOME.id) {
|
||||
navController.popBackStack()
|
||||
} else {
|
||||
activity.finish()
|
||||
}
|
||||
composable(
|
||||
NavDestination.DEVICE_NOT_CONNECTED.id,
|
||||
arguments = listOf(navArgument("args") { type = NavType.StringType })
|
||||
) {
|
||||
ScanDeviceScreen(it.arguments?.getString(ARGS_KEY)!!) {
|
||||
when (it) {
|
||||
ScanDeviceScreenResult.OK -> viewModel.finish()
|
||||
ScanDeviceScreenResult.CANCEL -> viewModel.navigateUp()
|
||||
}.exhaustive
|
||||
}
|
||||
}
|
||||
composable(NavDestination.BONDING.id) { BondingScreen(continueAction) }
|
||||
}
|
||||
|
||||
LaunchedEffect(state) {
|
||||
navController.navigate(state.url)
|
||||
val goHome = { navController.navigate(NavDestination.HOME.id) }
|
||||
|
||||
NavHost(navController = navController, startDestination = NavDestination.HOME.id) {
|
||||
composable(NavDestination.HOME.id) { HomeView { goHome() } }
|
||||
composable(NavDestination.CSC.id) { CSCScreen { goHome() } }
|
||||
composable(NavDestination.HRS.id) { HRSScreen { goHome() } }
|
||||
composable(NavDestination.HTS.id) { HTSScreen { goHome() } }
|
||||
composable(NavDestination.GLS.id) { GLSScreen { goHome() } }
|
||||
composable(NavDestination.BPS.id) { BPSScreen { goHome() } }
|
||||
composable(NavDestination.PRX.id) { PRXScreen { goHome() } }
|
||||
composable(NavDestination.RSCS.id) { RSCSScreen { goHome() } }
|
||||
composable(NavDestination.CGMS.id) { CGMScreen { goHome() } }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,10 +11,5 @@ enum class NavDestination(val id: String, val pairingRequired: Boolean) {
|
||||
BPS("bps-screen", false),
|
||||
PRX("prx-screen", true),
|
||||
RSCS("rscs-screen", false),
|
||||
CGMS("cgms-screen", false),
|
||||
REQUEST_PERMISSION("request-permission", false),
|
||||
BLUETOOTH_NOT_AVAILABLE("bluetooth-not-available", false),
|
||||
BLUETOOTH_NOT_ENABLED("bluetooth-not-enabled", false),
|
||||
DEVICE_NOT_CONNECTED("device-not-connected/{$ARGS_KEY}", false),
|
||||
BONDING("bonding", false);
|
||||
CGMS("cgms-screen", false);
|
||||
}
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
package no.nordicsemi.android.nrftoolbox
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import no.nordicsemi.android.bps.repository.BPS_SERVICE_UUID
|
||||
import no.nordicsemi.android.cgms.repository.CGMS_UUID
|
||||
import no.nordicsemi.android.csc.service.CYCLING_SPEED_AND_CADENCE_SERVICE_UUID
|
||||
import no.nordicsemi.android.gls.repository.GLS_SERVICE_UUID
|
||||
import no.nordicsemi.android.hrs.service.HR_SERVICE_UUID
|
||||
import no.nordicsemi.android.hts.service.HT_SERVICE_UUID
|
||||
import no.nordicsemi.android.permission.tools.NordicBleScanner
|
||||
import no.nordicsemi.android.permission.tools.PermissionHelper
|
||||
import no.nordicsemi.android.permission.tools.ScannerStatus
|
||||
import no.nordicsemi.android.permission.viewmodel.BluetoothPermissionState
|
||||
import no.nordicsemi.android.prx.service.IMMEDIATE_ALERT_SERVICE_UUID
|
||||
import no.nordicsemi.android.rscs.service.RSCS_SERVICE_UUID
|
||||
import no.nordicsemi.android.service.SelectedBluetoothDeviceHolder
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class NavigationViewModel @Inject constructor(
|
||||
private val bleScanner: NordicBleScanner,
|
||||
private val permissionHelper: PermissionHelper,
|
||||
private val selectedDevice: SelectedBluetoothDeviceHolder
|
||||
): ViewModel() {
|
||||
|
||||
val state= MutableStateFlow(NavigationTarget(NavDestination.HOME))
|
||||
private var targetDestination = NavDestination.HOME
|
||||
|
||||
fun navigate(destination: NavDestination) {
|
||||
targetDestination = destination
|
||||
navigateToNextScreen()
|
||||
}
|
||||
|
||||
fun navigateUp() {
|
||||
targetDestination = NavDestination.HOME
|
||||
state.value = NavigationTarget(NavDestination.HOME)
|
||||
}
|
||||
|
||||
fun finish() {
|
||||
if (state.value.destination != targetDestination) {
|
||||
navigateToNextScreen()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getBluetoothState(): BluetoothPermissionState {
|
||||
return if (!permissionHelper.isRequiredPermissionGranted()) {
|
||||
BluetoothPermissionState.PERMISSION_REQUIRED
|
||||
} else when (bleScanner.getBluetoothStatus()) {
|
||||
ScannerStatus.NOT_AVAILABLE -> BluetoothPermissionState.BLUETOOTH_NOT_AVAILABLE
|
||||
ScannerStatus.DISABLED -> BluetoothPermissionState.BLUETOOTH_NOT_ENABLED
|
||||
ScannerStatus.ENABLED -> selectedDevice.device?.let {
|
||||
if (targetDestination.pairingRequired && selectedDevice.isBondingRequired()) {
|
||||
BluetoothPermissionState.BONDING_REQUIRED
|
||||
} else {
|
||||
BluetoothPermissionState.READY
|
||||
}
|
||||
} ?: BluetoothPermissionState.DEVICE_NOT_CONNECTED
|
||||
}
|
||||
}
|
||||
|
||||
private fun navigateToNextScreen() {
|
||||
val destination = when (getBluetoothState()) {
|
||||
BluetoothPermissionState.PERMISSION_REQUIRED -> NavDestination.REQUEST_PERMISSION
|
||||
BluetoothPermissionState.BLUETOOTH_NOT_AVAILABLE -> NavDestination.BLUETOOTH_NOT_AVAILABLE
|
||||
BluetoothPermissionState.BLUETOOTH_NOT_ENABLED -> NavDestination.BLUETOOTH_NOT_ENABLED
|
||||
BluetoothPermissionState.DEVICE_NOT_CONNECTED -> NavDestination.DEVICE_NOT_CONNECTED
|
||||
BluetoothPermissionState.BONDING_REQUIRED -> NavDestination.BONDING
|
||||
BluetoothPermissionState.READY -> targetDestination
|
||||
}
|
||||
|
||||
val args = if (destination == NavDestination.DEVICE_NOT_CONNECTED) {
|
||||
createServiceId(targetDestination)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
state.tryEmit(NavigationTarget(destination, args))
|
||||
}
|
||||
|
||||
private fun createServiceId(destination: NavDestination): String {
|
||||
return when (destination) {
|
||||
NavDestination.CSC -> CYCLING_SPEED_AND_CADENCE_SERVICE_UUID.toString()
|
||||
NavDestination.HRS -> HR_SERVICE_UUID.toString()
|
||||
NavDestination.HTS -> HT_SERVICE_UUID.toString()
|
||||
NavDestination.GLS -> GLS_SERVICE_UUID.toString()
|
||||
NavDestination.BPS -> BPS_SERVICE_UUID.toString()
|
||||
NavDestination.RSCS -> RSCS_SERVICE_UUID.toString()
|
||||
NavDestination.PRX -> IMMEDIATE_ALERT_SERVICE_UUID.toString()
|
||||
NavDestination.CGMS -> CGMS_UUID.toString()
|
||||
NavDestination.HOME,
|
||||
NavDestination.REQUEST_PERMISSION,
|
||||
NavDestination.BLUETOOTH_NOT_AVAILABLE,
|
||||
NavDestination.BLUETOOTH_NOT_ENABLED,
|
||||
NavDestination.BONDING,
|
||||
NavDestination.DEVICE_NOT_CONNECTED -> throw IllegalArgumentException("There is no serivce related to the destination: $destination")
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user