解决连接过程中断开蓝牙产生的问题

This commit is contained in:
闫守旺
2021-07-02 11:34:28 +08:00
parent d4e80d7232
commit 92daec7450
2 changed files with 44 additions and 48 deletions

View File

@ -9,7 +9,6 @@ import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.os.Build
import android.os.DeadObjectException
import android.os.Handler
import android.os.ParcelUuid
import android.util.Log
@ -52,6 +51,7 @@ class BluetoothLowEnergyPlugin : FlutterPlugin, MethodCallHandler, StreamHandler
private const val NOTIFY_CHARACTERISTIC_FAILED = 7
private const val READ_DESCRIPTOR_FAILED = 8
private const val WRITE_DESCRIPTOR_FAILED = 9
private const val BLUETOOTH_ADAPTER_CLOSED = 10
private const val REQUEST_CODE = 443
}
@ -165,15 +165,18 @@ class BluetoothLowEnergyPlugin : FlutterPlugin, MethodCallHandler, StreamHandler
BluetoothGatt.GATT_SUCCESS -> {
when (newState) {
BluetoothProfile.STATE_DISCONNECTED -> {
// Maybe disconnect succeed, connect failed, or connection lost when an adaptor closed event triggered.
gatts.remove(address)!!.close()
val disconnect = disconnects.remove(address)
if (disconnect != null) handler.post { disconnect.success() }
else {
// An adapter closed event
val connect = connects.remove(address)
if (connect != null) handler.post { connect.error(BLUETOOTH_ADAPTER_CLOSED) }
else {
val id = gatt.hashCode()
val connectionLost = ConnectionLost.newBuilder()
.setId(id)
.setErrorCode(status)
.setErrorCode(BLUETOOTH_ADAPTER_CLOSED)
.build()
val event = Message.newBuilder()
.setCategory(GATT_CONNECTION_LOST)
@ -183,38 +186,28 @@ class BluetoothLowEnergyPlugin : FlutterPlugin, MethodCallHandler, StreamHandler
handler.post { sink?.success(event) }
}
}
}
BluetoothProfile.STATE_CONNECTED -> {
val code = when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> {
// TODO: how to get exact MTU size of this device here?
if (gatt.requestMtu(512)) NO_ERROR
else REQUEST_MTU_FAILED
}
else -> {
if (gatt.discoverServices()) {
// Just use 23 as MTU before LOLLIPOP.
mtus[address] = 23
NO_ERROR
} else DISCOVER_SERVICES_FAILED
}
}
if (code != NO_ERROR) {
// Must be connect succeed.
val requested = gatt.requestMtu(512)
if (!requested) {
gatts.remove(address)!!.close()
val connect = connects.remove(address)!!
handler.post { connect.error(code) }
handler.post { connect.error(REQUEST_MTU_FAILED) }
}
}
else -> throw NotImplementedError() // should never be called.
}
}
else -> {
// Maybe connect failed, disconnect failed or connection lost when an adaptor closed event triggered.
gatts.remove(address)!!.close()
val connect = connects.remove(address)
if (connect != null) handler.post { connect.error(status) }
else {
val disconnect = disconnects.remove(address)
when {
connect != null -> handler.post { connect.error(status) }
disconnect != null -> handler.post { disconnect.error(status) }
else -> {
if (disconnect != null) handler.post { disconnect.error(status) }
else {
val id = gatt.hashCode()
val connectionLost = ConnectionLost.newBuilder()
.setId(id)
@ -237,7 +230,8 @@ class BluetoothLowEnergyPlugin : FlutterPlugin, MethodCallHandler, StreamHandler
val address = gatt!!.device.address
val code = when (status) {
BluetoothGatt.GATT_SUCCESS -> {
if (gatt.discoverServices()) {
val discovered = gatt.discoverServices()
if (discovered) {
mtus[address] = mtu
NO_ERROR
} else DISCOVER_SERVICES_FAILED
@ -418,7 +412,7 @@ class BluetoothLowEnergyPlugin : FlutterPlugin, MethodCallHandler, StreamHandler
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
val category = call.category
if (category != BLUETOOTH_AVAILABLE && category != BLUETOOTH_STATE && !bluetoothAdapter.state.opened) result.error(INVALID_REQUEST)
if (category != BLUETOOTH_AVAILABLE && category != BLUETOOTH_STATE && !bluetoothAdapter.state.opened) result.error(BLUETOOTH_ADAPTER_CLOSED)
else when (category) {
BLUETOOTH_AVAILABLE -> result.success(bluetoothAvailable)
BLUETOOTH_STATE -> result.success(bluetoothAdapter.state.opened)

View File

@ -40,14 +40,17 @@ class _HomeViewState extends State<HomeView> with WidgetsBindingObserver {
void initState() {
super.initState();
WidgetsBinding.instance!.addObserver(this);
stateSubscription = central.stateChanged.listen((state) {
stateSubscription = central.stateChanged.listen(
(state) {
final invisible = !ModalRoute.of(context)!.isCurrent;
if (invisible) return;
if (state) {
startDiscovery();
} else {
discoveries.value = {};
discovering.value = false;
}
});
},
);
discoverySubscription = central.discovered.listen(
(discovery) {
discoveries.value[discovery.address] = discovery;
@ -85,16 +88,15 @@ class _HomeViewState extends State<HomeView> with WidgetsBindingObserver {
}
void startDiscovery() async {
final state = await central.state;
if (!state) return;
if (discovering.value || !await central.state) return;
await central.startDiscovery();
discovering.value = true;
}
void stopDiscovery() async {
final state = await central.state;
if (!state) return;
if (!discovering.value || !await central.state) return;
await central.stopDiscovery();
discoveries.value = {};
discovering.value = false;
}