解决连接过程中断开蓝牙产生的问题
This commit is contained in:
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user