Fix bug GATT_FAILURE
This commit is contained in:
parent
ce95316494
commit
0d7019a7be
|
|
@ -37,6 +37,7 @@ import kotlin.random.nextInt
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.rounded.Refresh
|
import androidx.compose.material.icons.rounded.Refresh
|
||||||
import androidx.compose.ui.graphics.StrokeCap
|
import androidx.compose.ui.graphics.StrokeCap
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import com.patrykandpatrick.vico.compose.chart.scroll.rememberChartScrollState
|
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
|
||||||
|
|
@ -73,7 +74,7 @@ fun TemperatureHistory(
|
||||||
viewModel.setEvent(TemperatureHistoryContract.Event.LoadHistory(ble.serial))
|
viewModel.setEvent(TemperatureHistoryContract.Event.LoadHistory(ble.serial))
|
||||||
}
|
}
|
||||||
|
|
||||||
Column() {
|
Column {
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier.padding(horizontal = 12.dp),
|
modifier = Modifier.padding(horizontal = 12.dp),
|
||||||
|
|
@ -90,7 +91,10 @@ fun TemperatureHistory(
|
||||||
onClick = {
|
onClick = {
|
||||||
viewModel.setEvent(TemperatureHistoryContract.Event.LoadHistory(ble.serial))
|
viewModel.setEvent(TemperatureHistoryContract.Event.LoadHistory(ble.serial))
|
||||||
},
|
},
|
||||||
enabled = state.loadingHistoryState is ProgressState.Finished
|
enabled = when(state){
|
||||||
|
is TemperatureHistoryContract.State.Display -> state.loadingHistoryState is ProgressState.Finished
|
||||||
|
TemperatureHistoryContract.State.Exception -> true
|
||||||
|
}
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Rounded.Refresh,
|
imageVector = Icons.Rounded.Refresh,
|
||||||
|
|
@ -102,6 +106,19 @@ fun TemperatureHistory(
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
when(state){
|
||||||
|
is TemperatureHistoryContract.State.Display -> Display(state = state)
|
||||||
|
TemperatureHistoryContract.State.Exception -> Exception()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun Display(
|
||||||
|
state: TemperatureHistoryContract.State.Display
|
||||||
|
) {
|
||||||
when (state.loadingHistoryState) {
|
when (state.loadingHistoryState) {
|
||||||
is ProgressState.Finished -> {
|
is ProgressState.Finished -> {
|
||||||
|
|
||||||
|
|
@ -190,6 +207,24 @@ fun TemperatureHistory(
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun Exception(
|
||||||
|
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(8.dp)
|
||||||
|
.fillMaxWidth()
|
||||||
|
.aspectRatio(2f),
|
||||||
|
){
|
||||||
|
|
||||||
|
Text(
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
text = "Во время загрузки произошла ошибка",
|
||||||
|
modifier = Modifier.align(Alignment.Center)
|
||||||
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -205,9 +240,15 @@ class TemperatureHistoryContract {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class State(
|
sealed class State : ViewState {
|
||||||
|
|
||||||
|
data class Display(
|
||||||
val loadingHistoryState : ProgressState<List<Ble.Thermometer.MeasurePoint>>
|
val loadingHistoryState : ProgressState<List<Ble.Thermometer.MeasurePoint>>
|
||||||
) : ViewState
|
) : State()
|
||||||
|
|
||||||
|
object Exception : State()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
sealed class Effect : ViewSideEffect {
|
sealed class Effect : ViewSideEffect {
|
||||||
|
|
||||||
|
|
@ -222,7 +263,7 @@ class TemperatureHistoryViewModel @Inject constructor(
|
||||||
private val getTemperatureHistoryBySerial: GetTemperatureHistoryBySerial
|
private val getTemperatureHistoryBySerial: GetTemperatureHistoryBySerial
|
||||||
) : BaseViewModel<TemperatureHistoryContract.State, TemperatureHistoryContract.Event, TemperatureHistoryContract.Effect>() {
|
) : BaseViewModel<TemperatureHistoryContract.State, TemperatureHistoryContract.Event, TemperatureHistoryContract.Effect>() {
|
||||||
|
|
||||||
override fun setInitialState() = TemperatureHistoryContract.State(
|
override fun setInitialState() = TemperatureHistoryContract.State.Display(
|
||||||
ProgressState.Indeterminate
|
ProgressState.Indeterminate
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -239,18 +280,20 @@ class TemperatureHistoryViewModel @Inject constructor(
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
|
|
||||||
setState {
|
setState {
|
||||||
TemperatureHistoryContract.State(ProgressState.Indeterminate)
|
TemperatureHistoryContract.State.Display(ProgressState.Indeterminate)
|
||||||
}
|
}
|
||||||
|
|
||||||
getTemperatureHistoryBySerial(event.serial).onEach {
|
getTemperatureHistoryBySerial(event.serial).onEach {
|
||||||
it.fold(
|
it.fold(
|
||||||
onSuccess = {
|
onSuccess = {
|
||||||
setState {
|
setState {
|
||||||
TemperatureHistoryContract.State(it)
|
TemperatureHistoryContract.State.Display(it)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onFailure = {
|
onFailure = {
|
||||||
|
setState {
|
||||||
|
TemperatureHistoryContract.State.Exception
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}.launchIn(this)
|
}.launchIn(this)
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,12 @@ import android.Manifest
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.bluetooth.*
|
import android.bluetooth.*
|
||||||
import android.bluetooth.le.ScanCallback
|
import android.bluetooth.le.ScanCallback
|
||||||
|
import android.bluetooth.le.ScanFilter
|
||||||
import android.bluetooth.le.ScanResult
|
import android.bluetooth.le.ScanResult
|
||||||
import android.bluetooth.le.ScanSettings
|
import android.bluetooth.le.ScanSettings
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import android.util.Log
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.channels.awaitClose
|
import kotlinx.coroutines.channels.awaitClose
|
||||||
|
|
@ -25,6 +27,7 @@ import java.util.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
import kotlin.coroutines.resume
|
import kotlin.coroutines.resume
|
||||||
|
import kotlin.coroutines.suspendCoroutine
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class BleRepositoryImpl @Inject constructor(
|
class BleRepositoryImpl @Inject constructor(
|
||||||
|
|
@ -316,7 +319,15 @@ class BleRepositoryImpl @Inject constructor(
|
||||||
((this[idx + 1].toUInt() and 0xFFu) shl 8) or
|
((this[idx + 1].toUInt() and 0xFFu) shl 8) or
|
||||||
(this[idx].toUInt() and 0xFFu)
|
(this[idx].toUInt() and 0xFFu)
|
||||||
|
|
||||||
deviceCache[serial]?.device?.let { device ->
|
findDeviceBySerial(serial).fold(
|
||||||
|
onSuccess = {
|
||||||
|
return@fold it
|
||||||
|
},
|
||||||
|
onFailure = {
|
||||||
|
emit(Result.failure(it))
|
||||||
|
return@flow
|
||||||
|
}
|
||||||
|
).let { device ->
|
||||||
|
|
||||||
emit(Result.success(ProgressState.Indeterminate))
|
emit(Result.success(ProgressState.Indeterminate))
|
||||||
|
|
||||||
|
|
@ -330,7 +341,7 @@ class BleRepositoryImpl @Inject constructor(
|
||||||
val countDataArray = readCharacteristic(
|
val countDataArray = readCharacteristic(
|
||||||
device = device,
|
device = device,
|
||||||
serviceId = UUID.fromString("a77db03a-9bc4-11ed-a8fc-0242ac120002"),
|
serviceId = UUID.fromString("a77db03a-9bc4-11ed-a8fc-0242ac120002"),
|
||||||
characteristicId = UUID.fromString("0000b2d8-0000-1000-8000-00805f9b34fb"),
|
characteristicId = UUID.fromString("0000b2d8-0000-1000-8000-00805f9b34fb")
|
||||||
).fold(
|
).fold(
|
||||||
onFailure = {
|
onFailure = {
|
||||||
emit(Result.failure(it))
|
emit(Result.failure(it))
|
||||||
|
|
@ -355,7 +366,7 @@ class BleRepositoryImpl @Inject constructor(
|
||||||
val firstPackageResponse = readCharacteristic(
|
val firstPackageResponse = readCharacteristic(
|
||||||
device = device,
|
device = device,
|
||||||
serviceId = UUID.fromString("a77db03a-9bc4-11ed-a8fc-0242ac120002"),
|
serviceId = UUID.fromString("a77db03a-9bc4-11ed-a8fc-0242ac120002"),
|
||||||
characteristicId = UUID.fromString("0000b2d8-0000-1000-8000-00805f9b34fb"),
|
characteristicId = UUID.fromString("0000b2d8-0000-1000-8000-00805f9b34fb")
|
||||||
).fold(
|
).fold(
|
||||||
onFailure = {
|
onFailure = {
|
||||||
emit(Result.failure(it))
|
emit(Result.failure(it))
|
||||||
|
|
@ -397,7 +408,7 @@ class BleRepositoryImpl @Inject constructor(
|
||||||
val readResponse = readCharacteristic(
|
val readResponse = readCharacteristic(
|
||||||
device = device,
|
device = device,
|
||||||
serviceId = UUID.fromString("a77db03a-9bc4-11ed-a8fc-0242ac120002"),
|
serviceId = UUID.fromString("a77db03a-9bc4-11ed-a8fc-0242ac120002"),
|
||||||
characteristicId = UUID.fromString("0000b2d8-0000-1000-8000-00805f9b34fb"),
|
characteristicId = UUID.fromString("0000b2d8-0000-1000-8000-00805f9b34fb")
|
||||||
).fold(
|
).fold(
|
||||||
onFailure = {
|
onFailure = {
|
||||||
emit(Result.failure(it))
|
emit(Result.failure(it))
|
||||||
|
|
@ -406,6 +417,8 @@ class BleRepositoryImpl @Inject constructor(
|
||||||
onSuccess = { return@fold it }
|
onSuccess = { return@fold it }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(readResponse[0] == 251.toByte()) {
|
||||||
|
|
||||||
dataCount = readResponse[1].toUByte()
|
dataCount = readResponse[1].toUByte()
|
||||||
|
|
||||||
temperatureDataArray = readResponse.toList().subList(2, readResponse.size)
|
temperatureDataArray = readResponse.toList().subList(2, readResponse.size)
|
||||||
|
|
@ -418,8 +431,20 @@ class BleRepositoryImpl @Inject constructor(
|
||||||
|
|
||||||
emit(Result.success(ProgressState.Progress(totalDataSize.toFloat() / temperaturePackage.size.toFloat())))
|
emit(Result.success(ProgressState.Progress(totalDataSize.toFloat() / temperaturePackage.size.toFloat())))
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
emit(Result.failure(BleException.UnexpectedResponse))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
readCharacteristic(
|
||||||
|
device = device,
|
||||||
|
serviceId = UUID.fromString("a77db03a-9bc4-11ed-a8fc-0242ac120002"),
|
||||||
|
characteristicId = UUID.fromString("0000b2d8-0000-1000-8000-00805f9b34fb")
|
||||||
|
)
|
||||||
|
|
||||||
emit(
|
emit(
|
||||||
Result.success(
|
Result.success(
|
||||||
ProgressState.Finished(
|
ProgressState.Finished(
|
||||||
|
|
@ -433,6 +458,10 @@ class BleRepositoryImpl @Inject constructor(
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
emit(Result.failure(BleException.UnexpectedResponse))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -559,14 +588,19 @@ class BleRepositoryImpl @Inject constructor(
|
||||||
characteristicId: UUID
|
characteristicId: UUID
|
||||||
): Result<ByteArray, BleException> = suspendCancellableCoroutine {
|
): Result<ByteArray, BleException> = suspendCancellableCoroutine {
|
||||||
|
|
||||||
|
var result: ByteArray? = null
|
||||||
|
var bleGatt: BluetoothGatt? = null
|
||||||
|
|
||||||
val callback = object : BluetoothGattCallback() {
|
val callback = object : BluetoothGattCallback() {
|
||||||
|
|
||||||
override fun onConnectionStateChange(
|
override fun onConnectionStateChange(
|
||||||
gatt: BluetoothGatt?,
|
gatt: BluetoothGatt,
|
||||||
status: Int,
|
status: Int,
|
||||||
newState: Int
|
newState: Int
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
Log.d("read", "onConnectionStateChange $newState $status")
|
||||||
|
|
||||||
if (newState == BluetoothProfile.STATE_CONNECTED) {
|
if (newState == BluetoothProfile.STATE_CONNECTED) {
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S || ActivityCompat.checkSelfPermission(
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S || ActivityCompat.checkSelfPermission(
|
||||||
|
|
@ -574,7 +608,7 @@ class BleRepositoryImpl @Inject constructor(
|
||||||
Manifest.permission.BLUETOOTH_CONNECT
|
Manifest.permission.BLUETOOTH_CONNECT
|
||||||
) == PackageManager.PERMISSION_GRANTED
|
) == PackageManager.PERMISSION_GRANTED
|
||||||
) {
|
) {
|
||||||
gatt?.discoverServices()
|
gatt.discoverServices()
|
||||||
} else {
|
} else {
|
||||||
it.resume(Result.failure(BleException.PermissionDenied))
|
it.resume(Result.failure(BleException.PermissionDenied))
|
||||||
}
|
}
|
||||||
|
|
@ -584,14 +618,16 @@ class BleRepositoryImpl @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onServicesDiscovered(
|
override fun onServicesDiscovered(
|
||||||
gatt: BluetoothGatt?,
|
gatt: BluetoothGatt,
|
||||||
status: Int
|
status: Int
|
||||||
) {
|
) {
|
||||||
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 ->
|
||||||
service.uuid == serviceId
|
service.uuid == serviceId
|
||||||
}?.characteristics?.firstOrNull { characteristic ->
|
}?.characteristics?.firstOrNull { characteristic ->
|
||||||
characteristic.uuid == characteristicId
|
characteristic.uuid == characteristicId
|
||||||
|
|
@ -620,6 +656,9 @@ class BleRepositoryImpl @Inject constructor(
|
||||||
status: Int
|
status: Int
|
||||||
) {
|
) {
|
||||||
super.onCharacteristicRead(gatt, characteristic, value, status)
|
super.onCharacteristicRead(gatt, characteristic, value, status)
|
||||||
|
|
||||||
|
Log.d("read", "onCharacteristicRead $status")
|
||||||
|
|
||||||
if (ActivityCompat.checkSelfPermission(
|
if (ActivityCompat.checkSelfPermission(
|
||||||
app,
|
app,
|
||||||
Manifest.permission.BLUETOOTH_CONNECT
|
Manifest.permission.BLUETOOTH_CONNECT
|
||||||
|
|
@ -627,9 +666,17 @@ class BleRepositoryImpl @Inject constructor(
|
||||||
) {
|
) {
|
||||||
it.resume(Result.failure(BleException.PermissionDenied))
|
it.resume(Result.failure(BleException.PermissionDenied))
|
||||||
}else {
|
}else {
|
||||||
gatt.disconnect()
|
gatt.close()
|
||||||
it.resume(Result.success(value))
|
result = value
|
||||||
|
if(result != null){
|
||||||
|
it.resume(Result.success(result!!))
|
||||||
|
} else {
|
||||||
|
bleGatt?.close()
|
||||||
|
it.resume(Result.failure(BleException.UnexpectedResponse))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -641,7 +688,7 @@ class BleRepositoryImpl @Inject constructor(
|
||||||
) {
|
) {
|
||||||
it.resume(Result.failure(BleException.PermissionDenied))
|
it.resume(Result.failure(BleException.PermissionDenied))
|
||||||
} else {
|
} else {
|
||||||
device.connectGatt(app, true, callback)
|
bleGatt = device.connectGatt(app, true, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -653,14 +700,18 @@ class BleRepositoryImpl @Inject constructor(
|
||||||
writeData: ByteArray
|
writeData: ByteArray
|
||||||
) = suspendCancellableCoroutine {
|
) = suspendCancellableCoroutine {
|
||||||
|
|
||||||
|
var bleGatt: BluetoothGatt? = null
|
||||||
|
|
||||||
val callback = object : BluetoothGattCallback() {
|
val callback = object : BluetoothGattCallback() {
|
||||||
|
|
||||||
override fun onConnectionStateChange(
|
override fun onConnectionStateChange(
|
||||||
gatt: BluetoothGatt?,
|
gatt: BluetoothGatt,
|
||||||
status: Int,
|
status: Int,
|
||||||
newState: Int
|
newState: Int
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
Log.d("write", "onConnectionStateChange $newState")
|
||||||
|
|
||||||
if (newState == BluetoothProfile.STATE_CONNECTED) {
|
if (newState == BluetoothProfile.STATE_CONNECTED) {
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S || ActivityCompat.checkSelfPermission(
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S || ActivityCompat.checkSelfPermission(
|
||||||
|
|
@ -668,7 +719,13 @@ class BleRepositoryImpl @Inject constructor(
|
||||||
Manifest.permission.BLUETOOTH_CONNECT
|
Manifest.permission.BLUETOOTH_CONNECT
|
||||||
) == PackageManager.PERMISSION_GRANTED
|
) == PackageManager.PERMISSION_GRANTED
|
||||||
) {
|
) {
|
||||||
gatt?.discoverServices()
|
gatt.discoverServices()
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if(newState == BluetoothProfile.STATE_DISCONNECTED && status == BluetoothGatt.GATT_FAILURE){
|
||||||
|
bleGatt?.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -676,14 +733,14 @@ class BleRepositoryImpl @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onServicesDiscovered(
|
override fun onServicesDiscovered(
|
||||||
gatt: BluetoothGatt?,
|
gatt: BluetoothGatt,
|
||||||
status: Int
|
status: Int
|
||||||
) {
|
) {
|
||||||
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 ->
|
||||||
service.uuid == serviceId
|
service.uuid == serviceId
|
||||||
}?.characteristics?.firstOrNull { characteristic ->
|
}?.characteristics?.firstOrNull { characteristic ->
|
||||||
characteristic.uuid == characteristicId
|
characteristic.uuid == characteristicId
|
||||||
|
|
@ -712,10 +769,13 @@ class BleRepositoryImpl @Inject constructor(
|
||||||
|
|
||||||
override fun onCharacteristicWrite(
|
override fun onCharacteristicWrite(
|
||||||
gatt: BluetoothGatt,
|
gatt: BluetoothGatt,
|
||||||
characteristic: BluetoothGattCharacteristic?,
|
characteristic: BluetoothGattCharacteristic,
|
||||||
status: Int
|
status: Int
|
||||||
) {
|
) {
|
||||||
super.onCharacteristicWrite(gatt, characteristic, status)
|
super.onCharacteristicWrite(gatt, characteristic, status)
|
||||||
|
|
||||||
|
Log.d("write", "onCharacteristicWrite $status")
|
||||||
|
|
||||||
if (ActivityCompat.checkSelfPermission(
|
if (ActivityCompat.checkSelfPermission(
|
||||||
app,
|
app,
|
||||||
Manifest.permission.BLUETOOTH_CONNECT
|
Manifest.permission.BLUETOOTH_CONNECT
|
||||||
|
|
@ -723,7 +783,7 @@ class BleRepositoryImpl @Inject constructor(
|
||||||
) {
|
) {
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
gatt.disconnect()
|
gatt.close()
|
||||||
it.resume(Unit)
|
it.resume(Unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -731,7 +791,63 @@ class BleRepositoryImpl @Inject constructor(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
device.connectGatt(app, true, callback)
|
bleGatt = device.connectGatt(app, true, callback)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun findDeviceBySerial(serial: String): Result<BluetoothDevice, BleException> = suspendCancellableCoroutine {
|
||||||
|
|
||||||
|
val bleCallback = object : ScanCallback() {
|
||||||
|
|
||||||
|
override fun onScanResult(
|
||||||
|
callbackType: Int,
|
||||||
|
result: ScanResult
|
||||||
|
) {
|
||||||
|
|
||||||
|
super.onScanResult(callbackType, result)
|
||||||
|
|
||||||
|
if(it.isActive) {
|
||||||
|
|
||||||
|
if (ActivityCompat.checkSelfPermission(
|
||||||
|
app,
|
||||||
|
Manifest.permission.BLUETOOTH_CONNECT
|
||||||
|
) == PackageManager.PERMISSION_GRANTED
|
||||||
|
) {
|
||||||
|
|
||||||
|
|
||||||
|
it.resume(Result.success(result.device))
|
||||||
|
|
||||||
|
} else {
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
it.resume(
|
||||||
|
Result.failure(BleException.PermissionDenied)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
val bleScanner =
|
||||||
|
app.getSystemService(BluetoothManager::class.java).adapter.bluetoothLeScanner
|
||||||
|
|
||||||
|
bleScanner.startScan(
|
||||||
|
listOf(ScanFilter.Builder().setDeviceAddress(serial).build()),
|
||||||
|
ScanSettings.Builder()
|
||||||
|
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
|
||||||
|
.setCallbackType(ScanSettings.CALLBACK_TYPE_FIRST_MATCH)
|
||||||
|
.setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE)
|
||||||
|
.setNumOfMatches(ScanSettings.MATCH_NUM_ONE_ADVERTISEMENT)
|
||||||
|
.setReportDelay(400L)
|
||||||
|
.build(),
|
||||||
|
bleCallback)
|
||||||
|
|
||||||
|
it.invokeOnCancellation {
|
||||||
|
bleScanner.stopScan(bleCallback)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,4 +4,6 @@ sealed class BleException {
|
||||||
|
|
||||||
object PermissionDenied : BleException()
|
object PermissionDenied : BleException()
|
||||||
|
|
||||||
|
object UnexpectedResponse : BleException()
|
||||||
|
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue