解决连接过程中断开蓝牙产生的问题
This commit is contained in:
@ -9,7 +9,6 @@ import android.content.Intent
|
|||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.DeadObjectException
|
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.ParcelUuid
|
import android.os.ParcelUuid
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
@ -52,6 +51,7 @@ class BluetoothLowEnergyPlugin : FlutterPlugin, MethodCallHandler, StreamHandler
|
|||||||
private const val NOTIFY_CHARACTERISTIC_FAILED = 7
|
private const val NOTIFY_CHARACTERISTIC_FAILED = 7
|
||||||
private const val READ_DESCRIPTOR_FAILED = 8
|
private const val READ_DESCRIPTOR_FAILED = 8
|
||||||
private const val WRITE_DESCRIPTOR_FAILED = 9
|
private const val WRITE_DESCRIPTOR_FAILED = 9
|
||||||
|
private const val BLUETOOTH_ADAPTER_CLOSED = 10
|
||||||
private const val REQUEST_CODE = 443
|
private const val REQUEST_CODE = 443
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,56 +165,49 @@ class BluetoothLowEnergyPlugin : FlutterPlugin, MethodCallHandler, StreamHandler
|
|||||||
BluetoothGatt.GATT_SUCCESS -> {
|
BluetoothGatt.GATT_SUCCESS -> {
|
||||||
when (newState) {
|
when (newState) {
|
||||||
BluetoothProfile.STATE_DISCONNECTED -> {
|
BluetoothProfile.STATE_DISCONNECTED -> {
|
||||||
|
// Maybe disconnect succeed, connect failed, or connection lost when an adaptor closed event triggered.
|
||||||
gatts.remove(address)!!.close()
|
gatts.remove(address)!!.close()
|
||||||
val disconnect = disconnects.remove(address)
|
val disconnect = disconnects.remove(address)
|
||||||
if (disconnect != null) handler.post { disconnect.success() }
|
if (disconnect != null) handler.post { disconnect.success() }
|
||||||
else {
|
else {
|
||||||
// An adapter closed event
|
val connect = connects.remove(address)
|
||||||
val id = gatt.hashCode()
|
if (connect != null) handler.post { connect.error(BLUETOOTH_ADAPTER_CLOSED) }
|
||||||
val connectionLost = ConnectionLost.newBuilder()
|
else {
|
||||||
.setId(id)
|
val id = gatt.hashCode()
|
||||||
.setErrorCode(status)
|
val connectionLost = ConnectionLost.newBuilder()
|
||||||
.build()
|
.setId(id)
|
||||||
val event = Message.newBuilder()
|
.setErrorCode(BLUETOOTH_ADAPTER_CLOSED)
|
||||||
.setCategory(GATT_CONNECTION_LOST)
|
.build()
|
||||||
.setConnectionLost(connectionLost)
|
val event = Message.newBuilder()
|
||||||
.build()
|
.setCategory(GATT_CONNECTION_LOST)
|
||||||
.toByteArray()
|
.setConnectionLost(connectionLost)
|
||||||
handler.post { sink?.success(event) }
|
.build()
|
||||||
|
.toByteArray()
|
||||||
|
handler.post { sink?.success(event) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BluetoothProfile.STATE_CONNECTED -> {
|
BluetoothProfile.STATE_CONNECTED -> {
|
||||||
val code = when {
|
// Must be connect succeed.
|
||||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> {
|
val requested = gatt.requestMtu(512)
|
||||||
// TODO: how to get exact MTU size of this device here?
|
if (!requested) {
|
||||||
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) {
|
|
||||||
gatts.remove(address)!!.close()
|
gatts.remove(address)!!.close()
|
||||||
val connect = connects.remove(address)!!
|
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 -> throw NotImplementedError() // should never be called.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
// Maybe connect failed, disconnect failed or connection lost when an adaptor closed event triggered.
|
||||||
gatts.remove(address)!!.close()
|
gatts.remove(address)!!.close()
|
||||||
val connect = connects.remove(address)
|
val connect = connects.remove(address)
|
||||||
val disconnect = disconnects.remove(address)
|
if (connect != null) handler.post { connect.error(status) }
|
||||||
when {
|
else {
|
||||||
connect != null -> handler.post { connect.error(status) }
|
val disconnect = disconnects.remove(address)
|
||||||
disconnect != null -> handler.post { disconnect.error(status) }
|
if (disconnect != null) handler.post { disconnect.error(status) }
|
||||||
else -> {
|
else {
|
||||||
val id = gatt.hashCode()
|
val id = gatt.hashCode()
|
||||||
val connectionLost = ConnectionLost.newBuilder()
|
val connectionLost = ConnectionLost.newBuilder()
|
||||||
.setId(id)
|
.setId(id)
|
||||||
@ -237,7 +230,8 @@ class BluetoothLowEnergyPlugin : FlutterPlugin, MethodCallHandler, StreamHandler
|
|||||||
val address = gatt!!.device.address
|
val address = gatt!!.device.address
|
||||||
val code = when (status) {
|
val code = when (status) {
|
||||||
BluetoothGatt.GATT_SUCCESS -> {
|
BluetoothGatt.GATT_SUCCESS -> {
|
||||||
if (gatt.discoverServices()) {
|
val discovered = gatt.discoverServices()
|
||||||
|
if (discovered) {
|
||||||
mtus[address] = mtu
|
mtus[address] = mtu
|
||||||
NO_ERROR
|
NO_ERROR
|
||||||
} else DISCOVER_SERVICES_FAILED
|
} else DISCOVER_SERVICES_FAILED
|
||||||
@ -418,7 +412,7 @@ class BluetoothLowEnergyPlugin : FlutterPlugin, MethodCallHandler, StreamHandler
|
|||||||
|
|
||||||
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
|
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
|
||||||
val category = call.category
|
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) {
|
else when (category) {
|
||||||
BLUETOOTH_AVAILABLE -> result.success(bluetoothAvailable)
|
BLUETOOTH_AVAILABLE -> result.success(bluetoothAvailable)
|
||||||
BLUETOOTH_STATE -> result.success(bluetoothAdapter.state.opened)
|
BLUETOOTH_STATE -> result.success(bluetoothAdapter.state.opened)
|
||||||
|
@ -40,14 +40,17 @@ class _HomeViewState extends State<HomeView> with WidgetsBindingObserver {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
WidgetsBinding.instance!.addObserver(this);
|
WidgetsBinding.instance!.addObserver(this);
|
||||||
stateSubscription = central.stateChanged.listen((state) {
|
stateSubscription = central.stateChanged.listen(
|
||||||
if (state) {
|
(state) {
|
||||||
startDiscovery();
|
final invisible = !ModalRoute.of(context)!.isCurrent;
|
||||||
} else {
|
if (invisible) return;
|
||||||
discoveries.value = {};
|
if (state) {
|
||||||
discovering.value = false;
|
startDiscovery();
|
||||||
}
|
} else {
|
||||||
});
|
discovering.value = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
discoverySubscription = central.discovered.listen(
|
discoverySubscription = central.discovered.listen(
|
||||||
(discovery) {
|
(discovery) {
|
||||||
discoveries.value[discovery.address] = discovery;
|
discoveries.value[discovery.address] = discovery;
|
||||||
@ -85,16 +88,15 @@ class _HomeViewState extends State<HomeView> with WidgetsBindingObserver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void startDiscovery() async {
|
void startDiscovery() async {
|
||||||
final state = await central.state;
|
if (discovering.value || !await central.state) return;
|
||||||
if (!state) return;
|
|
||||||
await central.startDiscovery();
|
await central.startDiscovery();
|
||||||
discovering.value = true;
|
discovering.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void stopDiscovery() async {
|
void stopDiscovery() async {
|
||||||
final state = await central.state;
|
if (!discovering.value || !await central.state) return;
|
||||||
if (!state) return;
|
|
||||||
await central.stopDiscovery();
|
await central.stopDiscovery();
|
||||||
|
discoveries.value = {};
|
||||||
discovering.value = false;
|
discovering.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user