Improve views

This commit is contained in:
Sylwester Zieliński
2021-12-02 13:22:26 +01:00
parent 10b0573d6e
commit 4d15ada6eb
14 changed files with 80 additions and 19 deletions

View File

@@ -28,6 +28,7 @@ import android.app.PendingIntent
import android.content.Intent import android.content.Intent
import android.os.Build import android.os.Build
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
private const val CHANNEL_ID = "FOREGROUND_BLE_SERVICE" private const val CHANNEL_ID = "FOREGROUND_BLE_SERVICE"
@@ -91,6 +92,7 @@ abstract class ForegroundBleService : BleProfileService() {
.setContentTitle(getString(R.string.app_name)) .setContentTitle(getString(R.string.app_name))
.setContentText(getString(messageResId, manager.bluetoothDevice?.name ?: "Device")) .setContentText(getString(messageResId, manager.bluetoothDevice?.name ?: "Device"))
.setSmallIcon(R.mipmap.ic_launcher) .setSmallIcon(R.mipmap.ic_launcher)
.setColor(ContextCompat.getColor(this, R.color.md_theme_primary))
.setContentIntent(pendingIntent) .setContentIntent(pendingIntent)
.build() .build()
} }

View File

@@ -11,6 +11,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
@@ -32,6 +33,7 @@ fun SectionTitle(
Image( Image(
painter = painterResource(id = resId), painter = painterResource(id = resId),
contentDescription = null, contentDescription = null,
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onSecondary),
modifier = Modifier modifier = Modifier
.background( .background(
color = MaterialTheme.colorScheme.secondary, color = MaterialTheme.colorScheme.secondary,
@@ -63,6 +65,7 @@ fun SectionTitle(
Icon( Icon(
imageVector = icon, imageVector = icon,
contentDescription = null, contentDescription = null,
tint = MaterialTheme.colorScheme.onSecondary,
modifier = Modifier modifier = Modifier
.background( .background(
color = MaterialTheme.colorScheme.secondary, color = MaterialTheme.colorScheme.secondary,

View File

@@ -1,20 +1,27 @@
package no.nordicsemi.android.theme.view package no.nordicsemi.android.theme.view
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import no.nordicsemi.android.material.you.Card import no.nordicsemi.android.material.you.Card
@Composable @Composable
fun ScreenSection(content: @Composable () -> Unit) { fun ScreenSection(content: @Composable () -> Unit) {
Card( Card(
backgroundColor = MaterialTheme.colorScheme.background, backgroundColor = MaterialTheme.colorScheme.secondaryContainer,
shape = RoundedCornerShape(4.dp), shape = RoundedCornerShape(16.dp),
elevation = 0.dp, elevation = 0.dp,
) { ) {
Column { Column(
modifier = Modifier.fillMaxWidth().padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
content() content()
} }
} }

View File

@@ -26,6 +26,7 @@ import android.bluetooth.BluetoothGatt
import android.bluetooth.BluetoothGattCharacteristic import android.bluetooth.BluetoothGattCharacteristic
import android.content.Context import android.content.Context
import android.util.Log import android.util.Log
import dagger.hilt.android.qualifiers.ApplicationContext
import no.nordicsemi.android.ble.common.callback.bps.BloodPressureMeasurementDataCallback import no.nordicsemi.android.ble.common.callback.bps.BloodPressureMeasurementDataCallback
import no.nordicsemi.android.ble.common.callback.bps.IntermediateCuffPressureDataCallback import no.nordicsemi.android.ble.common.callback.bps.IntermediateCuffPressureDataCallback
import no.nordicsemi.android.ble.common.profile.bp.BloodPressureTypes import no.nordicsemi.android.ble.common.profile.bp.BloodPressureTypes
@@ -34,6 +35,8 @@ import no.nordicsemi.android.bps.data.BPSDataHolder
import no.nordicsemi.android.log.LogContract import no.nordicsemi.android.log.LogContract
import no.nordicsemi.android.service.BatteryManager import no.nordicsemi.android.service.BatteryManager
import java.util.* import java.util.*
import javax.inject.Inject
import javax.inject.Singleton
/** Blood Pressure service UUID. */ /** Blood Pressure service UUID. */
val BPS_SERVICE_UUID = UUID.fromString("00001810-0000-1000-8000-00805f9b34fb") val BPS_SERVICE_UUID = UUID.fromString("00001810-0000-1000-8000-00805f9b34fb")
@@ -44,7 +47,11 @@ private val BPM_CHARACTERISTIC_UUID = UUID.fromString("00002A35-0000-1000-8000-0
/** Intermediate Cuff Pressure characteristic UUID. */ /** Intermediate Cuff Pressure characteristic UUID. */
private val ICP_CHARACTERISTIC_UUID = UUID.fromString("00002A36-0000-1000-8000-00805f9b34fb") private val ICP_CHARACTERISTIC_UUID = UUID.fromString("00002A36-0000-1000-8000-00805f9b34fb")
internal class BPSManager(context: Context, private val dataHolder: BPSDataHolder) : BatteryManager(context) { @Singleton
internal class BPSManager @Inject constructor(
@ApplicationContext context: Context,
private val dataHolder: BPSDataHolder
) : BatteryManager(context) {
private var bpmCharacteristic: BluetoothGattCharacteristic? = null private var bpmCharacteristic: BluetoothGattCharacteristic? = null
private var icpCharacteristic: BluetoothGattCharacteristic? = null private var icpCharacteristic: BluetoothGattCharacteristic? = null

View File

@@ -1,8 +1,10 @@
package no.nordicsemi.android.bps.view package no.nordicsemi.android.bps.view
import android.util.Log
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@@ -16,9 +18,10 @@ import no.nordicsemi.android.bps.data.BPSData
@Composable @Composable
internal fun BPSContentView(state: BPSData, onEvent: (BPSScreenViewEvent) -> Unit) { internal fun BPSContentView(state: BPSData, onEvent: (BPSScreenViewEvent) -> Unit) {
Column( Column(
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.padding(16.dp)
) { ) {
Spacer(modifier = Modifier.height(16.dp)) Log.d("AAATESTAAA", "state: $state")
BPSSensorsReadingView(state = state) BPSSensorsReadingView(state = state)

View File

@@ -2,6 +2,7 @@ package no.nordicsemi.android.bps.view
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
@@ -16,6 +17,16 @@ fun BPSScreen(finishAction: () -> Unit) {
val state = viewModel.state.collectAsState().value val state = viewModel.state.collectAsState().value
val isScreenActive = viewModel.isActive.collectAsState().value val isScreenActive = viewModel.isActive.collectAsState().value
LaunchedEffect("connect") {
viewModel.connectDevice()
}
LaunchedEffect(isScreenActive) {
if (!isScreenActive) {
finishAction()
}
}
BPSView(state) { viewModel.onEvent(it) } BPSView(state) { viewModel.onEvent(it) }
} }

View File

@@ -13,11 +13,14 @@ import no.nordicsemi.android.bps.data.BPSData
import no.nordicsemi.android.theme.view.BatteryLevelView import no.nordicsemi.android.theme.view.BatteryLevelView
import no.nordicsemi.android.theme.view.KeyValueField import no.nordicsemi.android.theme.view.KeyValueField
import no.nordicsemi.android.theme.view.ScreenSection import no.nordicsemi.android.theme.view.ScreenSection
import no.nordicsemi.android.theme.view.SectionTitle
@Composable @Composable
internal fun BPSSensorsReadingView(state: BPSData) { internal fun BPSSensorsReadingView(state: BPSData) {
ScreenSection { ScreenSection {
Column { Column {
SectionTitle(resId = R.drawable.ic_records, title = "Records")
Spacer(modifier = Modifier.height(16.dp))
KeyValueField(stringResource(id = R.string.bps_systolic), state.displaySystolic()) KeyValueField(stringResource(id = R.string.bps_systolic), state.displaySystolic())
Spacer(modifier = Modifier.height(4.dp)) Spacer(modifier = Modifier.height(4.dp))
KeyValueField(stringResource(id = R.string.bps_diastolic), state.displayDiastolic()) KeyValueField(stringResource(id = R.string.bps_diastolic), state.displayDiastolic())

View File

@@ -2,14 +2,18 @@ package no.nordicsemi.android.bps.viewmodel
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import no.nordicsemi.android.bps.data.BPSDataHolder import no.nordicsemi.android.bps.data.BPSDataHolder
import no.nordicsemi.android.bps.repository.BPSManager
import no.nordicsemi.android.bps.view.BPSScreenViewEvent import no.nordicsemi.android.bps.view.BPSScreenViewEvent
import no.nordicsemi.android.bps.view.DisconnectEvent import no.nordicsemi.android.bps.view.DisconnectEvent
import no.nordicsemi.android.service.SelectedBluetoothDeviceHolder
import no.nordicsemi.android.theme.viewmodel.CloseableViewModel import no.nordicsemi.android.theme.viewmodel.CloseableViewModel
import no.nordicsemi.android.utils.exhaustive import no.nordicsemi.android.utils.exhaustive
import javax.inject.Inject import javax.inject.Inject
@HiltViewModel @HiltViewModel
internal class BPSViewModel @Inject constructor( internal class BPSViewModel @Inject constructor(
private val bpsManager: BPSManager,
private val deviceHolder: SelectedBluetoothDeviceHolder,
private val dataHolder: BPSDataHolder private val dataHolder: BPSDataHolder
) : CloseableViewModel() { ) : CloseableViewModel() {
@@ -21,8 +25,18 @@ internal class BPSViewModel @Inject constructor(
}.exhaustive }.exhaustive
} }
fun connectDevice() {
deviceHolder.device?.let {
bpsManager.connect(it)
.useAutoConnect(false)
.retry(3, 100)
.enqueue()
}
}
private fun onDisconnectButtonClick() { private fun onDisconnectButtonClick() {
finish() finish()
deviceHolder.forgetDevice()
dataHolder.clear() dataHolder.clear()
} }
} }

View File

@@ -3,6 +3,9 @@ package no.nordicsemi.android.csc.view
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@@ -14,6 +17,7 @@ import androidx.compose.ui.unit.dp
import no.nordicsemi.android.csc.R import no.nordicsemi.android.csc.R
import no.nordicsemi.android.csc.data.CSCData import no.nordicsemi.android.csc.data.CSCData
import no.nordicsemi.android.theme.view.ScreenSection import no.nordicsemi.android.theme.view.ScreenSection
import no.nordicsemi.android.theme.view.SectionTitle
import no.nordicsemi.android.theme.view.SelectItemRadioGroup import no.nordicsemi.android.theme.view.SelectItemRadioGroup
@Composable @Composable
@@ -23,7 +27,8 @@ internal fun CSCContentView(state: CSCData, onEvent: (CSCViewEvent) -> Unit) {
} }
Column( Column(
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.padding(horizontal = 16.dp)
) { ) {
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
@@ -49,6 +54,10 @@ private fun SettingsSection(state: CSCData, onEvent: (CSCViewEvent) -> Unit) {
Column( Column(
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
) { ) {
SectionTitle(icon = Icons.Default.Settings, title = stringResource(R.string.csc_settings))
Spacer(modifier = Modifier.height(16.dp))
WheelSizeView(state, onEvent) WheelSizeView(state, onEvent)
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))

View File

@@ -13,10 +13,15 @@ import no.nordicsemi.android.csc.data.CSCData
import no.nordicsemi.android.theme.view.BatteryLevelView import no.nordicsemi.android.theme.view.BatteryLevelView
import no.nordicsemi.android.theme.view.KeyValueField import no.nordicsemi.android.theme.view.KeyValueField
import no.nordicsemi.android.theme.view.ScreenSection import no.nordicsemi.android.theme.view.ScreenSection
import no.nordicsemi.android.theme.view.SectionTitle
@Composable @Composable
internal fun SensorsReadingView(state: CSCData) { internal fun SensorsReadingView(state: CSCData) {
ScreenSection { ScreenSection {
SectionTitle(resId = R.drawable.ic_records, title = "Records")
Spacer(modifier = Modifier.height(16.dp))
Column { Column {
KeyValueField(stringResource(id = R.string.csc_field_speed), state.displaySpeed()) KeyValueField(stringResource(id = R.string.csc_field_speed), state.displaySpeed())
Spacer(modifier = Modifier.height(4.dp)) Spacer(modifier = Modifier.height(4.dp))

View File

@@ -12,6 +12,8 @@
<string name="csc_field_wheel_size">Wheel size</string> <string name="csc_field_wheel_size">Wheel size</string>
<string name="csc_settings">Settings</string>
<string-array name="wheel_entries"> <string-array name="wheel_entries">
<item>60&#8211;622</item> <item>60&#8211;622</item>
<item>50&#8211;622</item> <item>50&#8211;622</item>

View File

@@ -3,6 +3,7 @@ package no.nordicsemi.android.hrs.view
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@@ -20,7 +21,8 @@ import no.nordicsemi.android.theme.view.SectionTitle
@Composable @Composable
internal fun HRSContentView(state: HRSData, onEvent: (HRSScreenViewEvent) -> Unit) { internal fun HRSContentView(state: HRSData, onEvent: (HRSScreenViewEvent) -> Unit) {
Column( Column(
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.padding(horizontal = 16.dp)
) { ) {
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))

View File

@@ -1,9 +1,6 @@
package no.nordicsemi.android.hts.view package no.nordicsemi.android.hts.view
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@@ -19,7 +16,7 @@ import no.nordicsemi.android.theme.view.*
@Composable @Composable
internal fun HTSContentView(state: HTSData, onEvent: (HTSScreenViewEvent) -> Unit) { internal fun HTSContentView(state: HTSData, onEvent: (HTSScreenViewEvent) -> Unit) {
Column( Column(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize().padding(horizontal = 16.dp),
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
) { ) {
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))

View File

@@ -8,11 +8,7 @@ import no.nordicsemi.android.scanner.view.OnCancelButtonClick
import no.nordicsemi.android.scanner.view.OnDeviceSelected import no.nordicsemi.android.scanner.view.OnDeviceSelected
import no.nordicsemi.android.scanner.view.ScanDevicesViewEvent import no.nordicsemi.android.scanner.view.ScanDevicesViewEvent
import no.nordicsemi.android.service.SelectedBluetoothDeviceHolder import no.nordicsemi.android.service.SelectedBluetoothDeviceHolder
import no.nordicsemi.android.support.v18.scanner.BluetoothLeScannerCompat import no.nordicsemi.android.support.v18.scanner.*
import no.nordicsemi.android.support.v18.scanner.ScanCallback
import no.nordicsemi.android.support.v18.scanner.ScanFilter
import no.nordicsemi.android.support.v18.scanner.ScanResult
import no.nordicsemi.android.support.v18.scanner.ScanSettings
import no.nordicsemi.android.theme.viewmodel.CloseableViewModel import no.nordicsemi.android.theme.viewmodel.CloseableViewModel
import no.nordicsemi.android.utils.exhaustive import no.nordicsemi.android.utils.exhaustive
import javax.inject.Inject import javax.inject.Inject
@@ -58,7 +54,7 @@ class ScanDevicesViewModel @Inject constructor(
val settings: ScanSettings = ScanSettings.Builder() val settings: ScanSettings = ScanSettings.Builder()
.setLegacy(false) .setLegacy(false)
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.setReportDelay(5000) .setReportDelay(500)
.setUseHardwareBatchingIfSupported(true) .setUseHardwareBatchingIfSupported(true)
.build() .build()