Ble connection retry

This commit is contained in:
Vineyro 2023-11-21 16:22:38 +07:00
parent fb616a9f29
commit 824e6f0064
2 changed files with 218 additions and 188 deletions

View File

@ -13,8 +13,8 @@ android {
applicationId "llc.arma.ble"
minSdk 26
targetSdk 33
versionCode 12
versionName "1.2.12"
versionCode 13
versionName "1.2.13"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {

View File

@ -1022,143 +1022,158 @@ class BleRepositoryImpl @Inject constructor(
device: BluetoothDevice,
serviceId: UUID,
characteristicId: UUID
): Result<ByteArray, BleException> = suspendCancellableCoroutine {
): Result<ByteArray, BleException> {
var result: ByteArray?
var result: Result<ByteArray, BleException> = Result.failure(BleException.UnexpectedResponse)
val callback = object : BluetoothGattCallback() {
repeat(5){
result = suspendCancellableCoroutine {
override fun onConnectionStateChange(
gatt: BluetoothGatt,
status: Int,
newState: Int
) {
var result: ByteArray?
if(status == BluetoothGatt.GATT_SUCCESS) {
val callback = object : BluetoothGattCallback() {
if (newState == BluetoothProfile.STATE_CONNECTED) {
override fun onConnectionStateChange(
gatt: BluetoothGatt,
status: Int,
newState: Int
) {
if (checkPermission()) {
if(status == BluetoothGatt.GATT_SUCCESS) {
gatt.discoverServices()
if (newState == BluetoothProfile.STATE_CONNECTED) {
if (checkPermission()) {
gatt.discoverServices()
} else {
it.resume(Result.failure(BleException.PermissionDenied))
gatt.disconnect()
}
} else {
gatt.close()
}
} else {
it.resume(Result.failure(BleException.PermissionDenied))
gatt.disconnect()
}
}
override fun onServicesDiscovered(
gatt: BluetoothGatt,
status: Int
) {
super.onServicesDiscovered(gatt, status)
if (status == BluetoothGatt.GATT_SUCCESS) {
gatt.services?.firstOrNull { service ->
service.uuid == serviceId
}?.characteristics?.firstOrNull { characteristic ->
characteristic.uuid == characteristicId
}?.let { char ->
if (checkPermission()) {
gatt.readCharacteristic(char)
} else {
gatt.disconnect()
it.resume(Result.failure(BleException.PermissionDenied))
}
return
}
gatt.disconnect()
it.resume(Result.failure(BleException.UnexpectedResponse))
} else {
gatt.disconnect()
it.resume(Result.failure(BleException.UnexpectedResponse))
}
}
override fun onCharacteristicRead(
gatt: BluetoothGatt,
characteristic: BluetoothGattCharacteristic,
status: Int
) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
super.onCharacteristicRead(gatt, characteristic, status)
onCommonCharacteristicRead(gatt, characteristic, characteristic.value, status)
}
}
override fun onCharacteristicRead(
gatt: BluetoothGatt,
characteristic: BluetoothGattCharacteristic,
value: ByteArray,
status: Int
) {
super.onCharacteristicRead(gatt, characteristic, value, status)
onCommonCharacteristicRead(gatt, characteristic, value, status)
}
fun onCommonCharacteristicRead(
gatt: BluetoothGatt,
characteristic: BluetoothGattCharacteristic,
value: ByteArray,
status: Int
) {
Log.d("read", "onCharacteristicRead $status")
if(status == BluetoothGatt.GATT_SUCCESS) {
if (checkPermission()) {
result = value
it.resume(Result.success(result!!))
} else {
it.resume(Result.failure(BleException.PermissionDenied))
}
gatt.disconnect()
} else {
it.resume(Result.failure(BleException.UnexpectedResponse))
gatt.disconnect()
}
} else {
gatt.close()
}
} else {
}
if (checkPermission()) {
device.connectGatt(app, false, callback)
} else {
it.resume(Result.failure(BleException.PermissionDenied))
gatt.disconnect()
}
}
override fun onServicesDiscovered(
gatt: BluetoothGatt,
status: Int
) {
super.onServicesDiscovered(gatt, status)
if (status == BluetoothGatt.GATT_SUCCESS) {
gatt.services?.firstOrNull { service ->
service.uuid == serviceId
}?.characteristics?.firstOrNull { characteristic ->
characteristic.uuid == characteristicId
}?.let { char ->
if (checkPermission()) {
gatt.readCharacteristic(char)
} else {
gatt.disconnect()
it.resume(Result.failure(BleException.PermissionDenied))
}
return
}
gatt.disconnect()
it.resume(Result.failure(BleException.UnexpectedResponse))
} else {
gatt.disconnect()
it.resume(Result.failure(BleException.UnexpectedResponse))
}
}
override fun onCharacteristicRead(
gatt: BluetoothGatt,
characteristic: BluetoothGattCharacteristic,
status: Int
) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
super.onCharacteristicRead(gatt, characteristic, status)
onCommonCharacteristicRead(gatt, characteristic, characteristic.value, status)
}
}
override fun onCharacteristicRead(
gatt: BluetoothGatt,
characteristic: BluetoothGattCharacteristic,
value: ByteArray,
status: Int
) {
super.onCharacteristicRead(gatt, characteristic, value, status)
onCommonCharacteristicRead(gatt, characteristic, value, status)
}
fun onCommonCharacteristicRead(
gatt: BluetoothGatt,
characteristic: BluetoothGattCharacteristic,
value: ByteArray,
status: Int
) {
Log.d("read", "onCharacteristicRead $status")
if(status == BluetoothGatt.GATT_SUCCESS) {
if (checkPermission()) {
result = value
it.resume(Result.success(result!!))
} else {
it.resume(Result.failure(BleException.PermissionDenied))
}
gatt.disconnect()
} else {
it.resume(Result.failure(BleException.UnexpectedResponse))
gatt.disconnect()
}
if(result.isSuccess || (result.getErrorOrNull() is BleException.UnexpectedResponse).not()){
return result
}
}
if (checkPermission()) {
device.connectGatt(app, false, callback)
} else {
it.resume(Result.failure(BleException.PermissionDenied))
}
return result
}
@ -1167,109 +1182,130 @@ class BleRepositoryImpl @Inject constructor(
serviceId: UUID,
characteristicId: UUID,
writeData: ByteArray
): Result<Unit, BleException> = suspendCancellableCoroutine {
): Result<Unit, BleException> {
var bleGatt: BluetoothGatt? = null
var result: Result<Unit, BleException> = Result.failure(BleException.UnexpectedResponse)
val callback = object : BluetoothGattCallback() {
repeat(5){
result = suspendCancellableCoroutine {
override fun onConnectionStateChange(
gatt: BluetoothGatt,
status: Int,
newState: Int
) {
var bleGatt: BluetoothGatt? = null
if (status == BluetoothGatt.GATT_SUCCESS) {
val callback = object : BluetoothGattCallback() {
if (newState == BluetoothProfile.STATE_CONNECTED) {
override fun onConnectionStateChange(
gatt: BluetoothGatt,
status: Int,
newState: Int
) {
if (checkPermission()) {
if (status == BluetoothGatt.GATT_SUCCESS) {
gatt.discoverServices()
if (newState == BluetoothProfile.STATE_CONNECTED) {
if (checkPermission()) {
gatt.discoverServices()
} else {
bleGatt?.disconnect()
it.resume(Result.failure(BleException.PermissionDenied))
}
} else {
bleGatt?.close()
}
} else {
bleGatt?.disconnect()
it.resume(Result.failure(BleException.PermissionDenied))
it.resume(Result.failure(BleException.UnexpectedResponse))
}
} else {
bleGatt?.close()
}
} else {
override fun onServicesDiscovered(
gatt: BluetoothGatt,
status: Int
) {
super.onServicesDiscovered(gatt, status)
bleGatt?.disconnect()
it.resume(Result.failure(BleException.UnexpectedResponse))
if (status == BluetoothGatt.GATT_SUCCESS) {
}
gatt.services?.firstOrNull { service ->
service.uuid == serviceId
}?.characteristics?.firstOrNull { characteristic ->
characteristic.uuid == characteristicId
}?.let { char ->
}
if (checkPermission()) {
override fun onServicesDiscovered(
gatt: BluetoothGatt,
status: Int
) {
super.onServicesDiscovered(gatt, status)
gatt.writeCharacteristic(char, writeData)
if (status == BluetoothGatt.GATT_SUCCESS) {
} else {
gatt.services?.firstOrNull { service ->
service.uuid == serviceId
}?.characteristics?.firstOrNull { characteristic ->
characteristic.uuid == characteristicId
}?.let { char ->
bleGatt?.disconnect()
it.resume(Result.failure(BleException.PermissionDenied))
if (checkPermission()) {
}
gatt.writeCharacteristic(char, writeData)
return
}
Log.d("write", "service not found")
bleGatt?.disconnect()
it.resume(Result.failure(BleException.UnexpectedResponse))
} else {
bleGatt?.disconnect()
it.resume(Result.failure(BleException.UnexpectedResponse))
}
}
override fun onCharacteristicWrite(
gatt: BluetoothGatt,
characteristic: BluetoothGattCharacteristic,
status: Int
) {
super.onCharacteristicWrite(gatt, characteristic, status)
if (checkPermission()) {
if(status == BluetoothGatt.GATT_SUCCESS) {
it.resume(Result.success(Unit))
} else {
it.resume(Result.failure(BleException.UnexpectedResponse))
}
} else {
it.resume(Result.failure(BleException.PermissionDenied))
}
return
gatt.disconnect()
}
Log.d("write", "service not found")
bleGatt?.disconnect()
it.resume(Result.failure(BleException.UnexpectedResponse))
} else {
bleGatt?.disconnect()
it.resume(Result.failure(BleException.UnexpectedResponse))
}
}
override fun onCharacteristicWrite(
gatt: BluetoothGatt,
characteristic: BluetoothGattCharacteristic,
status: Int
) {
super.onCharacteristicWrite(gatt, characteristic, status)
if (checkPermission()) {
if(status == BluetoothGatt.GATT_SUCCESS) {
it.resume(Result.success(Unit))
} else {
it.resume(Result.failure(BleException.UnexpectedResponse))
}
bleGatt = device.connectGatt(app, false, callback)
} else {
@ -1277,21 +1313,15 @@ class BleRepositoryImpl @Inject constructor(
}
gatt.disconnect()
}
if(result.isSuccess || (result.getErrorOrNull() is BleException.UnexpectedResponse).not()){
return result
}
}
if (checkPermission()) {
bleGatt = device.connectGatt(app, false, callback)
} else {
it.resume(Result.failure(BleException.PermissionDenied))
}
return result
}