Поправки по графикам
This commit is contained in:
parent
62205d27a0
commit
bd10b5b6b6
|
|
@ -1,4 +1,3 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ android {
|
||||||
applicationId "llc.arma.ble"
|
applicationId "llc.arma.ble"
|
||||||
minSdk 24
|
minSdk 24
|
||||||
targetSdk 33
|
targetSdk 33
|
||||||
versionCode 4
|
versionCode 5
|
||||||
versionName "1.2.1"
|
versionName "1.2.2"
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
vectorDrawables {
|
vectorDrawables {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package llc.arma.ble.app.ui.screen.inspection.accelerometer
|
package llc.arma.ble.app.ui.screen.inspection.accelerometer
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.material.ExperimentalMaterialApi
|
||||||
|
import androidx.compose.material.ModalBottomSheetValue
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.DisposableEffect
|
import androidx.compose.runtime.DisposableEffect
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
|
@ -32,6 +34,7 @@ enum class SheetPage {
|
||||||
MEASURE, POWER, WRITE, HISTORY, ACCEL_MODE_EDIT, SPECTRE_MODE_EDIT, SPECTRE_EDIT, FREQUENCY_EDIT, AXIS_EDIT, FFT_MODE_EDIT
|
MEASURE, POWER, WRITE, HISTORY, ACCEL_MODE_EDIT, SPECTRE_MODE_EDIT, SPECTRE_EDIT, FREQUENCY_EDIT, AXIS_EDIT, FFT_MODE_EDIT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterialApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun AccelerometerScreen(
|
fun AccelerometerScreen(
|
||||||
ble: Ble.Accelerometer,
|
ble: Ble.Accelerometer,
|
||||||
|
|
@ -42,6 +45,7 @@ fun AccelerometerScreen(
|
||||||
|
|
||||||
val bottomDialog = rememberBottomDialogState()
|
val bottomDialog = rememberBottomDialogState()
|
||||||
|
|
||||||
|
|
||||||
LaunchedEffect(ble){
|
LaunchedEffect(ble){
|
||||||
viewModel.setEvent(AccelerometerContract.Event.OnBleChanged(ble))
|
viewModel.setEvent(AccelerometerContract.Event.OnBleChanged(ble))
|
||||||
}
|
}
|
||||||
|
|
@ -50,6 +54,15 @@ fun AccelerometerScreen(
|
||||||
mutableStateOf<SheetPage?>(null)
|
mutableStateOf<SheetPage?>(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LaunchedEffect(
|
||||||
|
key1 = bottomDialog.sheetState?.currentValue,
|
||||||
|
block = {
|
||||||
|
if(bottomDialog.sheetState?.currentValue == ModalBottomSheetValue.Hidden) {
|
||||||
|
sheetPage = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
LaunchedEffect(sheetPage) {
|
LaunchedEffect(sheetPage) {
|
||||||
|
|
|
||||||
|
|
@ -86,47 +86,6 @@ fun AccelSpectreEdit(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
) {
|
) {
|
||||||
|
|
||||||
Box(
|
|
||||||
modifier = Modifier.padding(
|
|
||||||
vertical = 8.dp,
|
|
||||||
horizontal = 8.dp
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
|
|
||||||
Row(
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
modifier = Modifier
|
|
||||||
.clip(RoundedCornerShape(16.dp))
|
|
||||||
.clickable {
|
|
||||||
onEvent(AccelerometerContract.Event.OnAccelViewModeEdit(next = AccelerometerContract.Event.OnAccelViewModeEdit.Next.SPECTRE))
|
|
||||||
}
|
|
||||||
.padding(8.dp)
|
|
||||||
) {
|
|
||||||
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.weight(1f)
|
|
||||||
) {
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = "Accel view mode"
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
color = MaterialTheme.colorScheme.secondary,
|
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
|
||||||
text = accelMode.localized
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Rounded.KeyboardArrowDown,
|
|
||||||
contentDescription = null
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier.padding(
|
modifier = Modifier.padding(
|
||||||
vertical = 8.dp,
|
vertical = 8.dp,
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,9 @@ import com.patrykandpatrick.vico.compose.chart.scroll.rememberChartScrollState
|
||||||
import com.patrykandpatrick.vico.core.axis.AxisPosition
|
import com.patrykandpatrick.vico.core.axis.AxisPosition
|
||||||
import com.patrykandpatrick.vico.core.axis.formatter.AxisValueFormatter
|
import com.patrykandpatrick.vico.core.axis.formatter.AxisValueFormatter
|
||||||
import com.patrykandpatrick.vico.core.entry.ChartEntry
|
import com.patrykandpatrick.vico.core.entry.ChartEntry
|
||||||
|
import com.patrykandpatrick.vico.core.entry.FloatEntry
|
||||||
|
import com.patrykandpatrick.vico.core.extension.sumByFloat
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import llc.arma.ble.domain.common.ProgressState
|
import llc.arma.ble.domain.common.ProgressState
|
||||||
|
|
@ -82,23 +85,67 @@ fun AccelerometerHistory(
|
||||||
|
|
||||||
val title = when(state){
|
val title = when(state){
|
||||||
is AccelerometerHistoryContract.State.Display -> {
|
is AccelerometerHistoryContract.State.Display -> {
|
||||||
when (state.loadingHistoryState) {
|
if (state.previousHistory !== null) {
|
||||||
is ProgressState.Finished -> "${fftMode.localized} (${state.loadingHistoryState.data.size})"
|
"${fftMode.localized} (${state.previousHistory.size})"
|
||||||
else -> fftMode.localized
|
}else {
|
||||||
|
fftMode.localized
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AccelerometerHistoryContract.State.Exception -> fftMode.localized
|
AccelerometerHistoryContract.State.Exception -> fftMode.localized
|
||||||
}
|
}
|
||||||
|
|
||||||
Text(
|
Row(
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
|
||||||
|
Text(
|
||||||
|
modifier = Modifier.padding(end = 16.dp),
|
||||||
text = title,
|
text = title,
|
||||||
style = MaterialTheme.typography.titleLarge
|
style = MaterialTheme.typography.titleLarge
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(state is AccelerometerHistoryContract.State.Display) {
|
||||||
|
|
||||||
|
when (state.loadingHistoryState) {
|
||||||
|
is ProgressState.Indeterminate -> {
|
||||||
|
|
||||||
|
CircularProgressIndicator(
|
||||||
|
modifier = Modifier.size(16.dp),
|
||||||
|
strokeWidth = 2.dp,
|
||||||
|
strokeCap = StrokeCap.Round,
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
is ProgressState.Progress -> {
|
||||||
|
|
||||||
|
val progressAnimDuration = 1500
|
||||||
|
val progressAnimation by animateFloatAsState(
|
||||||
|
targetValue = state.loadingHistoryState.value,
|
||||||
|
animationSpec = tween(
|
||||||
|
durationMillis = progressAnimDuration,
|
||||||
|
easing = FastOutSlowInEasing
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
CircularProgressIndicator(
|
||||||
|
modifier = Modifier.size(16.dp),
|
||||||
|
strokeWidth = 2.dp,
|
||||||
|
strokeCap = StrokeCap.Round,
|
||||||
|
progress = progressAnimation,
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
IconButton(
|
IconButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
viewModel.setEvent(AccelerometerHistoryContract.Event.OnRefreshHistory(ble.serial, accelMode, fftAxis, fftMode, frequency, accelScale))
|
viewModel.setEvent(AccelerometerHistoryContract.Event.OnStart(ble.serial, accelMode, fftAxis, fftMode, frequency, accelScale))
|
||||||
},
|
},
|
||||||
enabled = when(state){
|
enabled = when(state){
|
||||||
is AccelerometerHistoryContract.State.Display -> state.loadingHistoryState is ProgressState.Finished
|
is AccelerometerHistoryContract.State.Display -> state.loadingHistoryState is ProgressState.Finished
|
||||||
|
|
@ -128,6 +175,13 @@ fun AccelerometerHistory(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val axisValueFormatter = AxisValueFormatter<AxisPosition.Horizontal.Bottom> { value, chartValues ->
|
||||||
|
(chartValues.chartEntryModel.entries.firstOrNull()
|
||||||
|
?.getOrNull(value.toInt()) as? AccelerometerEntry)
|
||||||
|
?.frequency?.let { String.format("%.1f", (it.toFloat() / 256f)) }
|
||||||
|
.orEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Display(
|
fun Display(
|
||||||
|
|
@ -139,11 +193,19 @@ fun Display(
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
) {
|
) {
|
||||||
|
|
||||||
when (state.loadingHistoryState) {
|
val data = if(state.loadingHistoryState is ProgressState.Finished){
|
||||||
|
state.loadingHistoryState.data
|
||||||
|
} else {
|
||||||
|
state.previousHistory
|
||||||
|
}
|
||||||
|
|
||||||
is ProgressState.Finished -> {
|
val producer = remember {
|
||||||
|
ChartEntryModelProducer(listOf<FloatEntry>())
|
||||||
|
}
|
||||||
|
|
||||||
if(state.loadingHistoryState.data.isEmpty()){
|
if(data != null){
|
||||||
|
|
||||||
|
if(data.isEmpty()){
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
modifier = Modifier.align(Alignment.Center),
|
modifier = Modifier.align(Alignment.Center),
|
||||||
|
|
@ -152,39 +214,22 @@ fun Display(
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
val producer = remember(state.loadingHistoryState.data) {
|
LaunchedEffect(data){
|
||||||
state.loadingHistoryState.data.mapIndexed { index, measurePoint ->
|
producer.setEntries(
|
||||||
|
data.mapIndexed { index, measurePoint ->
|
||||||
AccelerometerEntry(measurePoint.frequency, index.toFloat(), measurePoint.value)
|
AccelerometerEntry(measurePoint.frequency, index.toFloat(), measurePoint.value)
|
||||||
}.let {
|
|
||||||
ChartEntryModelProducer(it)
|
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
|
|
||||||
val axisValueFormatter =
|
|
||||||
AxisValueFormatter<AxisPosition.Horizontal.Bottom> { value, chartValues ->
|
|
||||||
(chartValues.chartEntryModel.entries.firstOrNull()
|
|
||||||
?.getOrNull(value.toInt()) as? AccelerometerEntry)
|
|
||||||
?.frequency?.let { String.format("%.1f", (it.toFloat() / 256f)) }
|
|
||||||
.orEmpty()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val lineChart = columnChart(
|
val lineChart = columnChart(
|
||||||
spacing = 1.5.dp
|
spacing = 1.5.dp
|
||||||
)
|
)
|
||||||
|
|
||||||
LaunchedEffect(state.loadingHistoryState.data){
|
|
||||||
lineChart.bounds
|
|
||||||
lineChart.setBounds(
|
|
||||||
left = lineChart.bounds.left / 20,
|
|
||||||
top = lineChart.bounds.top,
|
|
||||||
right = lineChart.bounds.right / 20,
|
|
||||||
bottom = lineChart.bounds.bottom,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
val scrollState = rememberChartScrollState()
|
val scrollState = rememberChartScrollState()
|
||||||
|
|
||||||
Chart(
|
Chart(
|
||||||
|
diffAnimationSpec = tween(0),
|
||||||
isZoomEnabled = true,
|
isZoomEnabled = true,
|
||||||
chartScrollState = scrollState,
|
chartScrollState = scrollState,
|
||||||
chart = lineChart,
|
chart = lineChart,
|
||||||
|
|
@ -199,13 +244,10 @@ fun Display(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
/*LaunchedEffect(scrollState.maxValue) {
|
|
||||||
scrollState.scrollBy(scrollState.maxValue)
|
|
||||||
}*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} else {
|
||||||
|
when (state.loadingHistoryState) {
|
||||||
is ProgressState.Indeterminate -> {
|
is ProgressState.Indeterminate -> {
|
||||||
|
|
||||||
CircularProgressIndicator(
|
CircularProgressIndicator(
|
||||||
|
|
@ -232,7 +274,8 @@ fun Display(
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -286,6 +329,7 @@ class AccelerometerHistoryContract {
|
||||||
sealed class State : ViewState {
|
sealed class State : ViewState {
|
||||||
|
|
||||||
data class Display(
|
data class Display(
|
||||||
|
val previousHistory : List<Ble.Accelerometer.MeasurePoint>?,
|
||||||
val loadingHistoryState : ProgressState<List<Ble.Accelerometer.MeasurePoint>>
|
val loadingHistoryState : ProgressState<List<Ble.Accelerometer.MeasurePoint>>
|
||||||
) : State()
|
) : State()
|
||||||
|
|
||||||
|
|
@ -306,10 +350,12 @@ class AccelerometerHistoryViewModel @Inject constructor(
|
||||||
private val getAccelerometerSpectreBySerial: GetAccelerometerSpectreBySerial
|
private val getAccelerometerSpectreBySerial: GetAccelerometerSpectreBySerial
|
||||||
) : BaseViewModel<AccelerometerHistoryContract.State, AccelerometerHistoryContract.Event, AccelerometerHistoryContract.Effect>() {
|
) : BaseViewModel<AccelerometerHistoryContract.State, AccelerometerHistoryContract.Event, AccelerometerHistoryContract.Effect>() {
|
||||||
|
|
||||||
|
private var job: Job? = null
|
||||||
private var lastSerial: String? = null
|
private var lastSerial: String? = null
|
||||||
|
|
||||||
override fun setInitialState() = AccelerometerHistoryContract.State.Display(
|
override fun setInitialState() = AccelerometerHistoryContract.State.Display(
|
||||||
ProgressState.Indeterminate
|
loadingHistoryState = ProgressState.Indeterminate,
|
||||||
|
previousHistory = null
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun handleEvents(event: AccelerometerHistoryContract.Event) {
|
override fun handleEvents(event: AccelerometerHistoryContract.Event) {
|
||||||
|
|
@ -323,6 +369,7 @@ class AccelerometerHistoryViewModel @Inject constructor(
|
||||||
state: AccelerometerHistoryContract.State,
|
state: AccelerometerHistoryContract.State,
|
||||||
event: AccelerometerHistoryContract.Event.OnStart
|
event: AccelerometerHistoryContract.Event.OnStart
|
||||||
) {
|
) {
|
||||||
|
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
|
|
||||||
if(state is AccelerometerHistoryContract.State.Display) {
|
if(state is AccelerometerHistoryContract.State.Display) {
|
||||||
|
|
@ -332,10 +379,28 @@ class AccelerometerHistoryViewModel @Inject constructor(
|
||||||
lastSerial = event.serial
|
lastSerial = event.serial
|
||||||
|
|
||||||
setState {
|
setState {
|
||||||
AccelerometerHistoryContract.State.Display(ProgressState.Indeterminate)
|
AccelerometerHistoryContract.State.Display(
|
||||||
|
loadingHistoryState = ProgressState.Indeterminate,
|
||||||
|
previousHistory = when(state.loadingHistoryState){
|
||||||
|
is ProgressState.Finished -> state.loadingHistoryState.data
|
||||||
|
is ProgressState.Indeterminate -> null
|
||||||
|
is ProgressState.Progress -> null
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
getAccelerometerSpectreBySerial(
|
} else {
|
||||||
|
setState {
|
||||||
|
AccelerometerHistoryContract.State.Display(
|
||||||
|
loadingHistoryState = ProgressState.Indeterminate,
|
||||||
|
previousHistory = null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
job?.cancel()
|
||||||
|
job = getAccelerometerSpectreBySerial(
|
||||||
serial = event.serial,
|
serial = event.serial,
|
||||||
accelMode = event.accelMode,
|
accelMode = event.accelMode,
|
||||||
fftAxis = event.fftAxis,
|
fftAxis = event.fftAxis,
|
||||||
|
|
@ -343,10 +408,29 @@ class AccelerometerHistoryViewModel @Inject constructor(
|
||||||
frequency = event.frequency,
|
frequency = event.frequency,
|
||||||
accelScale = event.accelScale
|
accelScale = event.accelScale
|
||||||
).onEach {
|
).onEach {
|
||||||
|
|
||||||
|
val currentState = viewState.value
|
||||||
|
|
||||||
|
Log.d("currentState", currentState.toString())
|
||||||
|
|
||||||
|
|
||||||
|
if(currentState is AccelerometerHistoryContract.State.Display) {
|
||||||
|
|
||||||
it.fold(
|
it.fold(
|
||||||
onSuccess = {
|
onSuccess = {
|
||||||
setState {
|
setState {
|
||||||
AccelerometerHistoryContract.State.Display(it)
|
|
||||||
|
AccelerometerHistoryContract.State.Display(
|
||||||
|
loadingHistoryState = it,
|
||||||
|
previousHistory = when (it) {
|
||||||
|
is ProgressState.Finished -> {
|
||||||
|
it.data
|
||||||
|
}
|
||||||
|
is ProgressState.Indeterminate -> currentState.previousHistory
|
||||||
|
is ProgressState.Progress -> currentState.previousHistory
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onFailure = {
|
onFailure = {
|
||||||
|
|
@ -355,12 +439,11 @@ class AccelerometerHistoryViewModel @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}.launchIn(this)
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}.launchIn(this)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -369,7 +452,7 @@ class AccelerometerHistoryViewModel @Inject constructor(
|
||||||
state: AccelerometerHistoryContract.State,
|
state: AccelerometerHistoryContract.State,
|
||||||
event: AccelerometerHistoryContract.Event.OnRefreshHistory
|
event: AccelerometerHistoryContract.Event.OnRefreshHistory
|
||||||
) {
|
) {
|
||||||
viewModelScope.launch {
|
/*viewModelScope.launch {
|
||||||
|
|
||||||
setState {
|
setState {
|
||||||
AccelerometerHistoryContract.State.Display(ProgressState.Indeterminate)
|
AccelerometerHistoryContract.State.Display(ProgressState.Indeterminate)
|
||||||
|
|
@ -397,7 +480,7 @@ class AccelerometerHistoryViewModel @Inject constructor(
|
||||||
)
|
)
|
||||||
}.launchIn(this)
|
}.launchIn(this)
|
||||||
|
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -381,7 +381,7 @@ class AccelerometerMeasureViewModel @Inject constructor(
|
||||||
z = ((9806.65f / (Short.MAX_VALUE / 2)) * it.z) * (accelScale.k / 2)
|
z = ((9806.65f / (Short.MAX_VALUE / 2)) * it.z) * (accelScale.k / 2)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}.takeLast(10)
|
||||||
AccelerometerMeasureContract.State.Display(dataList)
|
AccelerometerMeasureContract.State.Display(dataList)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -579,63 +579,9 @@ class BleRepositoryImpl @Inject constructor(
|
||||||
|
|
||||||
if (checkPermission()) {
|
if (checkPermission()) {
|
||||||
|
|
||||||
writeCharacteristic(
|
gatt = it.connectGatt(app, false, ReadAccelerometerSpectreCallback(
|
||||||
device = it,
|
app, accelScale, accelMode, fftAxis, fftMode, frequency
|
||||||
serviceId = serviceUUID,
|
) {
|
||||||
characteristicId = accelerometerReadUUID,
|
|
||||||
writeData = byteArrayOf(
|
|
||||||
4,
|
|
||||||
accelMode.sendData,
|
|
||||||
accelScale.sendData,
|
|
||||||
fftMode.sendData,
|
|
||||||
fftAxis.sendData,
|
|
||||||
frequency.sendData,
|
|
||||||
1
|
|
||||||
)
|
|
||||||
).onFailure {
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
|
||||||
send(Result.failure(BleException.PermissionDenied))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = false
|
|
||||||
|
|
||||||
while (result.not()){
|
|
||||||
|
|
||||||
writeCharacteristic(
|
|
||||||
device = it,
|
|
||||||
serviceId = serviceUUID,
|
|
||||||
characteristicId = accelerometerReadUUID,
|
|
||||||
writeData = byteArrayOf(4, 0)
|
|
||||||
).onFailure {
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
|
||||||
send(Result.failure(BleException.PermissionDenied))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
readCharacteristic(
|
|
||||||
device = it,
|
|
||||||
serviceId = serviceUUID,
|
|
||||||
characteristicId = accelerometerReadUUID
|
|
||||||
).fold(
|
|
||||||
onSuccess = { readData ->
|
|
||||||
Log.d("read", readData.joinToString(", "))
|
|
||||||
if(readData.isNotEmpty() && readData.first() == (0).toByte()){
|
|
||||||
result = true
|
|
||||||
} else {
|
|
||||||
delay(200)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onFailure = {
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
|
||||||
send(Result.failure(BleException.PermissionDenied))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
gatt = it.connectGatt(app, false, ReadAccelerometerSpectreCallback(app) {
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
send(it)
|
send(it)
|
||||||
}
|
}
|
||||||
|
|
@ -919,8 +865,6 @@ class BleRepositoryImpl @Inject constructor(
|
||||||
) {
|
) {
|
||||||
super.onServicesDiscovered(gatt, status)
|
super.onServicesDiscovered(gatt, status)
|
||||||
|
|
||||||
Log.d("read", "onServicesDiscovered $status")
|
|
||||||
|
|
||||||
if (status == BluetoothGatt.GATT_SUCCESS) {
|
if (status == BluetoothGatt.GATT_SUCCESS) {
|
||||||
|
|
||||||
gatt.services?.firstOrNull { service ->
|
gatt.services?.firstOrNull { service ->
|
||||||
|
|
@ -1068,8 +1012,6 @@ class BleRepositoryImpl @Inject constructor(
|
||||||
) {
|
) {
|
||||||
super.onServicesDiscovered(gatt, status)
|
super.onServicesDiscovered(gatt, status)
|
||||||
|
|
||||||
Log.d("write", "onServicesDiscovered $status")
|
|
||||||
|
|
||||||
if (status == BluetoothGatt.GATT_SUCCESS) {
|
if (status == BluetoothGatt.GATT_SUCCESS) {
|
||||||
|
|
||||||
gatt.services?.firstOrNull { service ->
|
gatt.services?.firstOrNull { service ->
|
||||||
|
|
@ -1114,8 +1056,6 @@ class BleRepositoryImpl @Inject constructor(
|
||||||
) {
|
) {
|
||||||
super.onCharacteristicWrite(gatt, characteristic, status)
|
super.onCharacteristicWrite(gatt, characteristic, status)
|
||||||
|
|
||||||
Log.d("write", "onCharacteristicWrite $status")
|
|
||||||
|
|
||||||
if (checkPermission()) {
|
if (checkPermission()) {
|
||||||
|
|
||||||
gatt.close()
|
gatt.close()
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,8 @@ class ReadAccelerometerCallback(
|
||||||
) {
|
) {
|
||||||
super.onServicesDiscovered(gatt, status)
|
super.onServicesDiscovered(gatt, status)
|
||||||
|
|
||||||
|
Log.d("accel", "onServicesDiscovered")
|
||||||
|
|
||||||
if(status == BluetoothGatt.GATT_SUCCESS){
|
if(status == BluetoothGatt.GATT_SUCCESS){
|
||||||
|
|
||||||
gatt.getService(serviceUUID)?.getCharacteristic(accelerometerReadUUID)?.let {
|
gatt.getService(serviceUUID)?.getCharacteristic(accelerometerReadUUID)?.let {
|
||||||
|
|
@ -80,11 +82,9 @@ class ReadAccelerometerCallback(
|
||||||
fftMode.sendData,
|
fftMode.sendData,
|
||||||
fftAxis.sendData,
|
fftAxis.sendData,
|
||||||
frequency.sendData,
|
frequency.sendData,
|
||||||
2
|
1
|
||||||
)
|
)
|
||||||
|
|
||||||
Log.d("payload", payload.joinToString(" - "))
|
|
||||||
|
|
||||||
gatt.writeCharacteristic(it, payload)
|
gatt.writeCharacteristic(it, payload)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -107,14 +107,14 @@ class ReadAccelerometerCallback(
|
||||||
) {
|
) {
|
||||||
super.onCharacteristicWrite(gatt, characteristic, status)
|
super.onCharacteristicWrite(gatt, characteristic, status)
|
||||||
|
|
||||||
|
Log.d("accel", "request written")
|
||||||
|
|
||||||
if(status == BluetoothGatt.GATT_SUCCESS){
|
if(status == BluetoothGatt.GATT_SUCCESS){
|
||||||
|
|
||||||
gatt.getService(serviceUUID)?.getCharacteristic(accelerometerReadUUID)?.let {
|
gatt.getService(serviceUUID)?.getCharacteristic(accelerometerReadUUID)?.let {
|
||||||
|
|
||||||
if (checkPermission()) {
|
if (checkPermission()) {
|
||||||
|
|
||||||
Log.d("write", "enable notifications")
|
|
||||||
|
|
||||||
gatt.setCharacteristicNotification(it, true)
|
gatt.setCharacteristicNotification(it, true)
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
|
@ -162,6 +162,8 @@ class ReadAccelerometerCallback(
|
||||||
value: ByteArray,
|
value: ByteArray,
|
||||||
){
|
){
|
||||||
|
|
||||||
|
Log.d("accel", "notification")
|
||||||
|
|
||||||
val data = value.toList().chunked(2).map {
|
val data = value.toList().chunked(2).map {
|
||||||
it.toByteArray().get2byteShortAt(0)
|
it.toByteArray().get2byteShortAt(0)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import android.app.Application
|
||||||
import android.bluetooth.BluetoothGatt
|
import android.bluetooth.BluetoothGatt
|
||||||
import android.bluetooth.BluetoothGattCallback
|
import android.bluetooth.BluetoothGattCallback
|
||||||
import android.bluetooth.BluetoothGattCharacteristic
|
import android.bluetooth.BluetoothGattCharacteristic
|
||||||
|
import android.bluetooth.BluetoothGattDescriptor
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
|
@ -13,8 +14,14 @@ import llc.arma.ble.domain.Result
|
||||||
import llc.arma.ble.domain.common.BleException
|
import llc.arma.ble.domain.common.BleException
|
||||||
import llc.arma.ble.domain.common.ProgressState
|
import llc.arma.ble.domain.common.ProgressState
|
||||||
import llc.arma.ble.domain.model.Ble
|
import llc.arma.ble.domain.model.Ble
|
||||||
|
import llc.arma.ble.domain.usecase.AccelScale
|
||||||
|
import llc.arma.ble.domain.usecase.AccelViewMode
|
||||||
|
import llc.arma.ble.domain.usecase.FftAxis
|
||||||
|
import llc.arma.ble.domain.usecase.FftFrequency
|
||||||
|
import llc.arma.ble.domain.usecase.FftViewMode
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
import java.nio.ByteOrder.LITTLE_ENDIAN
|
import java.nio.ByteOrder.LITTLE_ENDIAN
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
fun ByteArray.get2byteShortAt(idx: Int): Int {
|
fun ByteArray.get2byteShortAt(idx: Int): Int {
|
||||||
val shorts = ShortArray(1)
|
val shorts = ShortArray(1)
|
||||||
|
|
@ -22,11 +29,21 @@ fun ByteArray.get2byteShortAt(idx: Int): Int {
|
||||||
return shorts[0].toInt()//(this[0].toInt() + (this[1].toInt() shl 8)).toShort()
|
return shorts[0].toInt()//(this[0].toInt() + (this[1].toInt() shl 8)).toShort()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class ReadAccelerometerSpectreCallback(
|
class ReadAccelerometerSpectreCallback(
|
||||||
private val app: Application,
|
private val app: Application,
|
||||||
|
private val accelScale: AccelScale,
|
||||||
|
private val accelMode: AccelViewMode,
|
||||||
|
private val fftAxis: FftAxis,
|
||||||
|
private val fftMode: FftViewMode,
|
||||||
|
private val frequency: FftFrequency,
|
||||||
private val onResult: (Result<ProgressState<List<Ble.Accelerometer.MeasurePoint>>, BleException>) -> Unit
|
private val onResult: (Result<ProgressState<List<Ble.Accelerometer.MeasurePoint>>, BleException>) -> Unit
|
||||||
) : BluetoothGattCallback() {
|
) : BluetoothGattCallback() {
|
||||||
|
|
||||||
|
enum class Property {
|
||||||
|
DATA_SIZE, PACKAGE
|
||||||
|
}
|
||||||
|
|
||||||
private fun ByteArray.get4byteUIntAt(idx: Int) =
|
private fun ByteArray.get4byteUIntAt(idx: Int) =
|
||||||
((this[idx + 3].toUInt() and 0xFFu) shl 24) or
|
((this[idx + 3].toUInt() and 0xFFu) shl 24) or
|
||||||
((this[idx + 2].toUInt() and 0xFFu) shl 16) or
|
((this[idx + 2].toUInt() and 0xFFu) shl 16) or
|
||||||
|
|
@ -50,13 +67,17 @@ class ReadAccelerometerSpectreCallback(
|
||||||
) {
|
) {
|
||||||
super.onConnectionStateChange(gatt, status, newState)
|
super.onConnectionStateChange(gatt, status, newState)
|
||||||
|
|
||||||
|
Log.d("spectre", "onConnectionStateChange")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(status == BluetoothGatt.GATT_SUCCESS){
|
if(status == BluetoothGatt.GATT_SUCCESS){
|
||||||
|
|
||||||
if(newState == BluetoothGatt.STATE_CONNECTED){
|
if(newState == BluetoothGatt.STATE_CONNECTED){
|
||||||
|
|
||||||
if (checkPermission()) {
|
if (checkPermission()) {
|
||||||
gatt.discoverServices()
|
gatt.discoverServices()
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
onResult(Result.failure(BleException.UnexpectedResponse))
|
onResult(Result.failure(BleException.UnexpectedResponse))
|
||||||
gatt.close()
|
gatt.close()
|
||||||
|
|
@ -77,22 +98,41 @@ class ReadAccelerometerSpectreCallback(
|
||||||
status: Int
|
status: Int
|
||||||
) {
|
) {
|
||||||
super.onServicesDiscovered(gatt, status)
|
super.onServicesDiscovered(gatt, status)
|
||||||
Log.d("read", "discover ${status}")
|
Log.d("spectre", "onServicesDiscovered")
|
||||||
if(status == BluetoothGatt.GATT_SUCCESS){
|
if(status == BluetoothGatt.GATT_SUCCESS){
|
||||||
gatt.getService(serviceUUID)?.getCharacteristic(accelerometerHistoryReadUUID)?.let {
|
enableNotifications(gatt)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun enableNotifications(
|
||||||
|
gatt: BluetoothGatt
|
||||||
|
){
|
||||||
|
|
||||||
|
gatt.getService(serviceUUID)?.getCharacteristic(accelerometerReadUUID)?.let {
|
||||||
|
|
||||||
if (checkPermission()) {
|
if (checkPermission()) {
|
||||||
|
|
||||||
Log.d("read", "discovered")
|
gatt.setCharacteristicNotification(it, true)
|
||||||
|
|
||||||
readProperty = Property.DATA_SIZE
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
gatt.writeCharacteristic(it, byteArrayOf(2))
|
gatt.writeDescriptor(it.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb")),
|
||||||
|
BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE)
|
||||||
|
} else {
|
||||||
|
val descriptor = it.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"))
|
||||||
|
descriptor.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
|
||||||
|
gatt.writeDescriptor(descriptor)
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d("spectre", "enable notification")
|
||||||
|
|
||||||
|
onResult(Result.success(ProgressState.Indeterminate))
|
||||||
|
resultAccelerometerPackage.clear()
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
onResult(Result.failure(BleException.PermissionDenied))
|
onResult(Result.failure(BleException.PermissionDenied))
|
||||||
gatt.close()
|
gatt.close()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
@ -103,12 +143,7 @@ class ReadAccelerometerSpectreCallback(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//private var lastMeasureSystemTime: Long? = null
|
|
||||||
|
|
||||||
private var initialValue: Long? = null
|
private var initialValue: Long? = null
|
||||||
//private var bleRealTime: Long? = null
|
|
||||||
private var frequencyInterval: Long? = null
|
private var frequencyInterval: Long? = null
|
||||||
|
|
||||||
private val resultAccelerometerPackage: MutableList<Float> = mutableListOf()
|
private val resultAccelerometerPackage: MutableList<Float> = mutableListOf()
|
||||||
|
|
@ -127,6 +162,42 @@ class ReadAccelerometerSpectreCallback(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("Deprecated in Java")
|
||||||
|
override fun onCharacteristicChanged(
|
||||||
|
gatt: BluetoothGatt,
|
||||||
|
characteristic: BluetoothGattCharacteristic
|
||||||
|
) {
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
super.onCharacteristicChanged(gatt, characteristic)
|
||||||
|
onCommonCharacteristicChanged(gatt, characteristic, characteristic.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCharacteristicChanged(
|
||||||
|
gatt: BluetoothGatt,
|
||||||
|
characteristic: BluetoothGattCharacteristic,
|
||||||
|
value: ByteArray
|
||||||
|
) {
|
||||||
|
super.onCharacteristicChanged(gatt, characteristic, value)
|
||||||
|
onCommonCharacteristicChanged(gatt, characteristic, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onCommonCharacteristicChanged(
|
||||||
|
gatt: BluetoothGatt,
|
||||||
|
characteristic: BluetoothGattCharacteristic,
|
||||||
|
value: ByteArray,
|
||||||
|
){
|
||||||
|
|
||||||
|
if(characteristic.uuid == accelerometerReadUUID) {
|
||||||
|
Log.d("spectre", "changed")
|
||||||
|
readProperty = Property.DATA_SIZE
|
||||||
|
gatt.getService(serviceUUID).getCharacteristic(accelerometerHistoryReadUUID)?.let {
|
||||||
|
gatt.writeCharacteristic(it, byteArrayOf(2))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCharacteristicRead(
|
override fun onCharacteristicRead(
|
||||||
gatt: BluetoothGatt,
|
gatt: BluetoothGatt,
|
||||||
characteristic: BluetoothGattCharacteristic,
|
characteristic: BluetoothGattCharacteristic,
|
||||||
|
|
@ -144,6 +215,8 @@ class ReadAccelerometerSpectreCallback(
|
||||||
status: Int
|
status: Int
|
||||||
){
|
){
|
||||||
|
|
||||||
|
Log.d("spectre", "onCharacteristicRead")
|
||||||
|
|
||||||
if(status == BluetoothGatt.GATT_SUCCESS){
|
if(status == BluetoothGatt.GATT_SUCCESS){
|
||||||
when(readProperty){
|
when(readProperty){
|
||||||
Property.DATA_SIZE -> {
|
Property.DATA_SIZE -> {
|
||||||
|
|
@ -209,6 +282,7 @@ class ReadAccelerometerSpectreCallback(
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
onResult(
|
onResult(
|
||||||
Result.success(
|
Result.success(
|
||||||
ProgressState.Finished(
|
ProgressState.Finished(
|
||||||
|
|
@ -221,7 +295,9 @@ class ReadAccelerometerSpectreCallback(
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
gatt.close()
|
|
||||||
|
start(gatt)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -247,6 +323,7 @@ class ReadAccelerometerSpectreCallback(
|
||||||
gatt.readCharacteristic(characteristic)
|
gatt.readCharacteristic(characteristic)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
onResult(
|
onResult(
|
||||||
Result.success(
|
Result.success(
|
||||||
ProgressState.Finished(
|
ProgressState.Finished(
|
||||||
|
|
@ -259,7 +336,9 @@ class ReadAccelerometerSpectreCallback(
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
gatt.close()
|
|
||||||
|
start(gatt)
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
onResult(Result.failure(BleException.UnexpectedResponse))
|
onResult(Result.failure(BleException.UnexpectedResponse))
|
||||||
|
|
@ -285,7 +364,12 @@ class ReadAccelerometerSpectreCallback(
|
||||||
status: Int
|
status: Int
|
||||||
) {
|
) {
|
||||||
super.onCharacteristicWrite(gatt, characteristic, status)
|
super.onCharacteristicWrite(gatt, characteristic, status)
|
||||||
if(status == BluetoothGatt.GATT_SUCCESS){
|
|
||||||
|
Log.d("spectre", "request written $readProperty")
|
||||||
|
|
||||||
|
if(readProperty !== null) {
|
||||||
|
|
||||||
|
if (status == BluetoothGatt.GATT_SUCCESS) {
|
||||||
|
|
||||||
if (checkPermission()) {
|
if (checkPermission()) {
|
||||||
|
|
||||||
|
|
@ -302,10 +386,66 @@ class ReadAccelerometerSpectreCallback(
|
||||||
onResult(Result.failure(BleException.UnexpectedResponse))
|
onResult(Result.failure(BleException.UnexpectedResponse))
|
||||||
gatt.close()
|
gatt.close()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkPermission(): Boolean {
|
override fun onMtuChanged(gatt: BluetoothGatt?, mtu: Int, status: Int) {
|
||||||
|
super.onMtuChanged(gatt, mtu, status)
|
||||||
|
Log.d("spectre", "mtu $mtu")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDescriptorWrite(
|
||||||
|
gatt: BluetoothGatt,
|
||||||
|
descriptor: BluetoothGattDescriptor,
|
||||||
|
status: Int
|
||||||
|
) {
|
||||||
|
|
||||||
|
Log.d("spectre", "descriptor written")
|
||||||
|
super.onDescriptorWrite(gatt, descriptor, status)
|
||||||
|
start(gatt)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun start(
|
||||||
|
gatt: BluetoothGatt,
|
||||||
|
){
|
||||||
|
|
||||||
|
Log.d("spectre", "start")
|
||||||
|
|
||||||
|
gatt.getService(serviceUUID)?.getCharacteristic(accelerometerReadUUID)?.let {
|
||||||
|
|
||||||
|
if (checkPermission()) {
|
||||||
|
|
||||||
|
val payload = byteArrayOf(
|
||||||
|
4,
|
||||||
|
accelMode.sendData,
|
||||||
|
accelScale.sendData,
|
||||||
|
fftMode.sendData,
|
||||||
|
fftAxis.sendData,
|
||||||
|
frequency.sendData,
|
||||||
|
2
|
||||||
|
)
|
||||||
|
readProperty = null
|
||||||
|
gatt.writeCharacteristic(it, payload)
|
||||||
|
|
||||||
|
onResult(Result.success(ProgressState.Indeterminate))
|
||||||
|
resultAccelerometerPackage.clear()
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
onResult(Result.failure(BleException.PermissionDenied))
|
||||||
|
gatt.close()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkPermission(): Boolean {
|
||||||
|
|
||||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
ActivityCompat.checkSelfPermission(app, Manifest.permission.BLUETOOTH_CONNECT) ==
|
ActivityCompat.checkSelfPermission(app, Manifest.permission.BLUETOOTH_CONNECT) ==
|
||||||
|
|
@ -320,7 +460,7 @@ class ReadAccelerometerSpectreCallback(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun BluetoothGatt.writeCharacteristic(
|
private fun BluetoothGatt.writeCharacteristic(
|
||||||
characteristic: BluetoothGattCharacteristic,
|
characteristic: BluetoothGattCharacteristic,
|
||||||
data: ByteArray
|
data: ByteArray
|
||||||
): Result<Unit, BleException>{
|
): Result<Unit, BleException>{
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,6 @@ class ReadHistoryCallback(
|
||||||
value: ByteArray,
|
value: ByteArray,
|
||||||
status: Int
|
status: Int
|
||||||
){
|
){
|
||||||
Log.d("read", value[0].toString())
|
|
||||||
|
|
||||||
if(status == BluetoothGatt.GATT_SUCCESS){
|
if(status == BluetoothGatt.GATT_SUCCESS){
|
||||||
when(readProperty){
|
when(readProperty){
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue