修复 setUp 和 clearServices 错误 (#39)
This commit is contained in:
@ -1,10 +1,15 @@
|
|||||||
|
## 5.0.3
|
||||||
|
|
||||||
|
* `Android` Fix the wrong blutooth low energy state caused by multi permission requests at the same time.
|
||||||
|
* `Android` Fix the ConcurrentModificationException when `PeripheralManager#clearServices` is called.
|
||||||
|
|
||||||
## 5.0.2
|
## 5.0.2
|
||||||
|
|
||||||
* Fix the issue that [discoverGATT failed caused by CoW](https://github.com/yanshouwang/bluetooth_low_energy/issues/36).
|
* `iOS` Fix the issue that [discoverGATT failed](https://github.com/yanshouwang/bluetooth_low_energy/issues/36) caused by CoW.
|
||||||
|
|
||||||
## 5.0.1
|
## 5.0.1
|
||||||
|
|
||||||
* Fix the issue that [completion was called duplicately caused by CoW](https://github.com/yanshouwang/bluetooth_low_energy/issues/36).
|
* `iOS` Fix the issue that [completion was called duplicately](https://github.com/yanshouwang/bluetooth_low_energy/issues/36) caused by CoW.
|
||||||
|
|
||||||
## 5.0.0
|
## 5.0.0
|
||||||
|
|
||||||
|
@ -23,15 +23,15 @@ packages:
|
|||||||
path: ".."
|
path: ".."
|
||||||
relative: true
|
relative: true
|
||||||
source: path
|
source: path
|
||||||
version: "5.0.2"
|
version: "5.0.3"
|
||||||
bluetooth_low_energy_android:
|
bluetooth_low_energy_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: bluetooth_low_energy_android
|
name: bluetooth_low_energy_android
|
||||||
sha256: "502382b2bc6d0bf9e7aa635bafa28057cb8538d6f2dd9c2eceb6d0111bcee94a"
|
sha256: "703faeeecce61887af4fa34bce5e0f5c25019d585f2e05723948332512c4eedc"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.0.0"
|
version: "5.0.2"
|
||||||
bluetooth_low_energy_darwin:
|
bluetooth_low_energy_darwin:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
name: bluetooth_low_energy
|
name: bluetooth_low_energy
|
||||||
description: A Flutter plugin for controlling the bluetooth low energy, supports central and peripheral apis.
|
description: A Flutter plugin for controlling the bluetooth low energy, supports central and peripheral apis.
|
||||||
version: 5.0.2
|
version: 5.0.3
|
||||||
homepage: https://github.com/yanshouwang/bluetooth_low_energy
|
homepage: https://github.com/yanshouwang/bluetooth_low_energy
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
@ -11,7 +11,7 @@ dependencies:
|
|||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
bluetooth_low_energy_platform_interface: ^5.0.0
|
bluetooth_low_energy_platform_interface: ^5.0.0
|
||||||
bluetooth_low_energy_android: ^5.0.0
|
bluetooth_low_energy_android: ^5.0.2
|
||||||
bluetooth_low_energy_darwin: ^5.0.2
|
bluetooth_low_energy_darwin: ^5.0.2
|
||||||
bluetooth_low_energy_windows: ^5.0.0
|
bluetooth_low_energy_windows: ^5.0.0
|
||||||
bluetooth_low_energy_linux: ^5.0.0
|
bluetooth_low_energy_linux: ^5.0.0
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
## 5.0.2
|
||||||
|
|
||||||
|
* Fix the ConcurrentModificationException when `PeripheralManager#clearServices` is called.
|
||||||
|
* Fix the `CentralManager#setUp` and `PeripheralManager#setUp` were blocked.
|
||||||
|
|
||||||
|
## 5.0.1
|
||||||
|
|
||||||
|
* Fix the wrong blutooth low energy state caused by multi permission requests at the same time.
|
||||||
|
|
||||||
## 5.0.0
|
## 5.0.0
|
||||||
|
|
||||||
* Now `CentralManager#writeCharacteristic` and `PeripheralManager#writeCharacteristic` will fragment the value automatically, the maximum write length is 512 bytes.
|
* Now `CentralManager#writeCharacteristic` and `PeripheralManager#writeCharacteristic` will fragment the value automatically, the maximum write length is 512 bytes.
|
||||||
|
@ -50,8 +50,10 @@ enum class MyBluetoothLowEnergyStateArgs(val raw: Int) {
|
|||||||
UNKNOWN(0),
|
UNKNOWN(0),
|
||||||
UNSUPPORTED(1),
|
UNSUPPORTED(1),
|
||||||
UNAUTHORIZED(2),
|
UNAUTHORIZED(2),
|
||||||
POWEREDOFF(3),
|
OFF(3),
|
||||||
POWEREDON(4);
|
TURNINGON(4),
|
||||||
|
ON(5),
|
||||||
|
TURNINGOFF(6);
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun ofRaw(raw: Int): MyBluetoothLowEnergyStateArgs? {
|
fun ofRaw(raw: Int): MyBluetoothLowEnergyStateArgs? {
|
||||||
@ -327,7 +329,7 @@ private object MyCentralManagerHostApiCodec : StandardMessageCodec() {
|
|||||||
|
|
||||||
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
|
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
|
||||||
interface MyCentralManagerHostApi {
|
interface MyCentralManagerHostApi {
|
||||||
fun setUp()
|
fun setUp(callback: (Result<Unit>) -> Unit)
|
||||||
fun startDiscovery(callback: (Result<Unit>) -> Unit)
|
fun startDiscovery(callback: (Result<Unit>) -> Unit)
|
||||||
fun stopDiscovery()
|
fun stopDiscovery()
|
||||||
fun connect(addressArgs: String, callback: (Result<Unit>) -> Unit)
|
fun connect(addressArgs: String, callback: (Result<Unit>) -> Unit)
|
||||||
@ -353,14 +355,14 @@ interface MyCentralManagerHostApi {
|
|||||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralManagerHostApi.setUp", codec)
|
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralManagerHostApi.setUp", codec)
|
||||||
if (api != null) {
|
if (api != null) {
|
||||||
channel.setMessageHandler { _, reply ->
|
channel.setMessageHandler { _, reply ->
|
||||||
var wrapped: List<Any?>
|
api.setUp() { result: Result<Unit> ->
|
||||||
try {
|
val error = result.exceptionOrNull()
|
||||||
api.setUp()
|
if (error != null) {
|
||||||
wrapped = listOf<Any?>(null)
|
reply.reply(wrapError(error))
|
||||||
} catch (exception: Throwable) {
|
} else {
|
||||||
wrapped = wrapError(exception)
|
reply.reply(wrapResult(null))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
reply.reply(wrapped)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
channel.setMessageHandler(null)
|
channel.setMessageHandler(null)
|
||||||
@ -795,7 +797,7 @@ private object MyPeripheralManagerHostApiCodec : StandardMessageCodec() {
|
|||||||
|
|
||||||
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
|
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
|
||||||
interface MyPeripheralManagerHostApi {
|
interface MyPeripheralManagerHostApi {
|
||||||
fun setUp()
|
fun setUp(callback: (Result<Unit>) -> Unit)
|
||||||
fun addService(serviceArgs: MyGattServiceArgs, callback: (Result<Unit>) -> Unit)
|
fun addService(serviceArgs: MyGattServiceArgs, callback: (Result<Unit>) -> Unit)
|
||||||
fun removeService(hashCodeArgs: Long)
|
fun removeService(hashCodeArgs: Long)
|
||||||
fun clearServices()
|
fun clearServices()
|
||||||
@ -816,14 +818,14 @@ interface MyPeripheralManagerHostApi {
|
|||||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerHostApi.setUp", codec)
|
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerHostApi.setUp", codec)
|
||||||
if (api != null) {
|
if (api != null) {
|
||||||
channel.setMessageHandler { _, reply ->
|
channel.setMessageHandler { _, reply ->
|
||||||
var wrapped: List<Any?>
|
api.setUp() { result: Result<Unit> ->
|
||||||
try {
|
val error = result.exceptionOrNull()
|
||||||
api.setUp()
|
if (error != null) {
|
||||||
wrapped = listOf<Any?>(null)
|
reply.reply(wrapError(error))
|
||||||
} catch (exception: Throwable) {
|
} else {
|
||||||
wrapped = wrapError(exception)
|
reply.reply(wrapResult(null))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
reply.reply(wrapped)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
channel.setMessageHandler(null)
|
channel.setMessageHandler(null)
|
||||||
|
@ -131,8 +131,11 @@ fun MyGattServiceArgs.toService(): BluetoothGattService {
|
|||||||
//region ToArgs
|
//region ToArgs
|
||||||
fun Int.toBluetoothLowEnergyStateArgs(): MyBluetoothLowEnergyStateArgs {
|
fun Int.toBluetoothLowEnergyStateArgs(): MyBluetoothLowEnergyStateArgs {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
BluetoothAdapter.STATE_ON -> MyBluetoothLowEnergyStateArgs.POWEREDON
|
BluetoothAdapter.STATE_OFF -> MyBluetoothLowEnergyStateArgs.OFF
|
||||||
else -> MyBluetoothLowEnergyStateArgs.POWEREDOFF
|
BluetoothAdapter.STATE_TURNING_ON -> MyBluetoothLowEnergyStateArgs.TURNINGON
|
||||||
|
BluetoothAdapter.STATE_ON -> MyBluetoothLowEnergyStateArgs.ON
|
||||||
|
BluetoothAdapter.STATE_TURNING_OFF -> MyBluetoothLowEnergyStateArgs.TURNINGOFF
|
||||||
|
else -> MyBluetoothLowEnergyStateArgs.UNKNOWN
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,8 +14,6 @@ import io.flutter.plugin.common.PluginRegistry.RequestPermissionsResultListener
|
|||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import java.util.concurrent.Executor
|
import java.util.concurrent.Executor
|
||||||
|
|
||||||
typealias MyBluetoothLowEnergyState = MyBluetoothLowEnergyStateArgs
|
|
||||||
|
|
||||||
abstract class MyBluetoothLowEnergyManager(context: Context) {
|
abstract class MyBluetoothLowEnergyManager(context: Context) {
|
||||||
companion object {
|
companion object {
|
||||||
val CLIENT_CHARACTERISTIC_CONFIG_UUID =
|
val CLIENT_CHARACTERISTIC_CONFIG_UUID =
|
||||||
@ -40,33 +38,26 @@ abstract class MyBluetoothLowEnergyManager(context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected val executor get() = ContextCompat.getMainExecutor(mContext) as Executor
|
protected val executor get() = ContextCompat.getMainExecutor(mContext) as Executor
|
||||||
|
protected val hasFeature get() = mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)
|
||||||
protected val manager
|
protected val manager
|
||||||
get() = ContextCompat.getSystemService(
|
get() = ContextCompat.getSystemService(
|
||||||
mContext, BluetoothManager::class.java
|
mContext, BluetoothManager::class.java
|
||||||
) as BluetoothManager
|
) as BluetoothManager
|
||||||
protected val adapter get() = manager.adapter as BluetoothAdapter
|
protected val adapter get() = manager.adapter as BluetoothAdapter
|
||||||
|
|
||||||
protected fun initialize() {
|
protected fun checkPermissions(): Boolean {
|
||||||
val hasFeature =
|
return permissions.all { permission ->
|
||||||
mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)
|
ActivityCompat.checkSelfPermission(
|
||||||
if (hasFeature) {
|
mContext, permission
|
||||||
val authorized = permissions.all { permission ->
|
) == PackageManager.PERMISSION_GRANTED
|
||||||
ActivityCompat.checkSelfPermission(
|
|
||||||
mContext, permission
|
|
||||||
) == PackageManager.PERMISSION_GRANTED
|
|
||||||
}
|
|
||||||
if (authorized) {
|
|
||||||
mOnAuthorizationStateChanged(true)
|
|
||||||
} else {
|
|
||||||
val activity = mBinding.activity
|
|
||||||
ActivityCompat.requestPermissions(activity, permissions, requestCode)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
val state = MyBluetoothLowEnergyState.UNSUPPORTED
|
|
||||||
onStateChanged(state)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected fun requestPermissions() {
|
||||||
|
val activity = mBinding.activity
|
||||||
|
ActivityCompat.requestPermissions(activity, permissions, requestCode)
|
||||||
|
}
|
||||||
|
|
||||||
fun onAttachedToActivity(binding: ActivityPluginBinding) {
|
fun onAttachedToActivity(binding: ActivityPluginBinding) {
|
||||||
binding.addRequestPermissionsResultListener(mRequestPermissionsResultListener)
|
binding.addRequestPermissionsResultListener(mRequestPermissionsResultListener)
|
||||||
mBinding = binding
|
mBinding = binding
|
||||||
@ -82,8 +73,9 @@ abstract class MyBluetoothLowEnergyManager(context: Context) {
|
|||||||
if (this.requestCode != requestCode) {
|
if (this.requestCode != requestCode) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
val authorized = results.all { r -> r == PackageManager.PERMISSION_GRANTED }
|
val granted =
|
||||||
mOnAuthorizationStateChanged(authorized)
|
permissions.contentEquals(this.permissions) && results.all { r -> r == PackageManager.PERMISSION_GRANTED }
|
||||||
|
onPermissionsRequested(granted)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,23 +84,11 @@ abstract class MyBluetoothLowEnergyManager(context: Context) {
|
|||||||
if (action != BluetoothAdapter.ACTION_STATE_CHANGED) {
|
if (action != BluetoothAdapter.ACTION_STATE_CHANGED) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val extra = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_OFF)
|
val state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_OFF)
|
||||||
val state = extra.toBluetoothLowEnergyStateArgs()
|
onAdapterStateChanged(state)
|
||||||
onStateChanged(state)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mOnAuthorizationStateChanged(authorized: Boolean) {
|
protected fun registerReceiver() {
|
||||||
val state = if (authorized) {
|
|
||||||
mRegisterReceiver()
|
|
||||||
if (adapter.state == BluetoothAdapter.STATE_ON) MyBluetoothLowEnergyState.POWEREDON
|
|
||||||
else MyBluetoothLowEnergyState.POWEREDOFF
|
|
||||||
} else {
|
|
||||||
MyBluetoothLowEnergyState.UNAUTHORIZED
|
|
||||||
}
|
|
||||||
onStateChanged(state)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun mRegisterReceiver() {
|
|
||||||
if (mRegistered) {
|
if (mRegistered) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -119,6 +99,8 @@ abstract class MyBluetoothLowEnergyManager(context: Context) {
|
|||||||
|
|
||||||
abstract val permissions: Array<String>
|
abstract val permissions: Array<String>
|
||||||
abstract val requestCode: Int
|
abstract val requestCode: Int
|
||||||
abstract fun onStateChanged(state: MyBluetoothLowEnergyState)
|
|
||||||
|
abstract fun onPermissionsRequested(granted: Boolean)
|
||||||
|
abstract fun onAdapterStateChanged(state: Int)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ class MyCentralManager(context: Context, binaryMessenger: BinaryMessenger) :
|
|||||||
private val mCharacteristics: MutableMap<String, Map<Long, BluetoothGattCharacteristic>>
|
private val mCharacteristics: MutableMap<String, Map<Long, BluetoothGattCharacteristic>>
|
||||||
private val mDescriptors: MutableMap<String, Map<Long, BluetoothGattDescriptor>>
|
private val mDescriptors: MutableMap<String, Map<Long, BluetoothGattDescriptor>>
|
||||||
|
|
||||||
|
private var mSetUpCallback: ((Result<Unit>) -> Unit)?
|
||||||
private var mStartDiscoveryCallback: ((Result<Unit>) -> Unit)?
|
private var mStartDiscoveryCallback: ((Result<Unit>) -> Unit)?
|
||||||
private val mConnectCallbacks: MutableMap<String, (Result<Unit>) -> Unit>
|
private val mConnectCallbacks: MutableMap<String, (Result<Unit>) -> Unit>
|
||||||
private val mDisconnectCallbacks: MutableMap<String, (Result<Unit>) -> Unit>
|
private val mDisconnectCallbacks: MutableMap<String, (Result<Unit>) -> Unit>
|
||||||
@ -61,6 +62,7 @@ class MyCentralManager(context: Context, binaryMessenger: BinaryMessenger) :
|
|||||||
mCharacteristics = mutableMapOf()
|
mCharacteristics = mutableMapOf()
|
||||||
mDescriptors = mutableMapOf()
|
mDescriptors = mutableMapOf()
|
||||||
|
|
||||||
|
mSetUpCallback = null
|
||||||
mStartDiscoveryCallback = null
|
mStartDiscoveryCallback = null
|
||||||
mConnectCallbacks = mutableMapOf()
|
mConnectCallbacks = mutableMapOf()
|
||||||
mDisconnectCallbacks = mutableMapOf()
|
mDisconnectCallbacks = mutableMapOf()
|
||||||
@ -93,9 +95,25 @@ class MyCentralManager(context: Context, binaryMessenger: BinaryMessenger) :
|
|||||||
override val requestCode: Int
|
override val requestCode: Int
|
||||||
get() = REQUEST_CODE
|
get() = REQUEST_CODE
|
||||||
|
|
||||||
override fun setUp() {
|
override fun setUp(callback: (Result<Unit>) -> Unit) {
|
||||||
mClearState()
|
try {
|
||||||
initialize()
|
mClearState()
|
||||||
|
val stateArgs = if (hasFeature) {
|
||||||
|
val granted = checkPermissions()
|
||||||
|
if (granted) {
|
||||||
|
registerReceiver()
|
||||||
|
adapter.state.toBluetoothLowEnergyStateArgs()
|
||||||
|
} else {
|
||||||
|
requestPermissions()
|
||||||
|
mSetUpCallback = callback
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else MyBluetoothLowEnergyStateArgs.UNSUPPORTED
|
||||||
|
mOnStateChanged(stateArgs)
|
||||||
|
callback(Result.success(Unit))
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
callback(Result.failure(e))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun startDiscovery(callback: (Result<Unit>) -> Unit) {
|
override fun startDiscovery(callback: (Result<Unit>) -> Unit) {
|
||||||
@ -104,10 +122,10 @@ class MyCentralManager(context: Context, binaryMessenger: BinaryMessenger) :
|
|||||||
val settings =
|
val settings =
|
||||||
ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build()
|
ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build()
|
||||||
mScanner.startScan(filters, settings, mScanCallback)
|
mScanner.startScan(filters, settings, mScanCallback)
|
||||||
mStartDiscoveryCallback = callback
|
|
||||||
executor.execute {
|
executor.execute {
|
||||||
onScanSucceed()
|
onScanSucceed()
|
||||||
}
|
}
|
||||||
|
mStartDiscoveryCallback = callback
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
callback(Result.failure(e))
|
callback(Result.failure(e))
|
||||||
}
|
}
|
||||||
@ -319,9 +337,19 @@ class MyCentralManager(context: Context, binaryMessenger: BinaryMessenger) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStateChanged(state: MyBluetoothLowEnergyState) {
|
override fun onPermissionsRequested(granted: Boolean) {
|
||||||
val stateNumberArgs = state.raw.toLong()
|
val callback = mSetUpCallback ?: return
|
||||||
mApi.onStateChanged(stateNumberArgs) {}
|
val stateArgs = if (granted) {
|
||||||
|
registerReceiver()
|
||||||
|
adapter.state.toBluetoothLowEnergyStateArgs()
|
||||||
|
} else MyBluetoothLowEnergyStateArgs.UNAUTHORIZED
|
||||||
|
mOnStateChanged(stateArgs)
|
||||||
|
callback(Result.success(Unit))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onAdapterStateChanged(state: Int) {
|
||||||
|
val stateArgs = state.toBluetoothLowEnergyStateArgs()
|
||||||
|
mOnStateChanged(stateArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onScanSucceed() {
|
private fun onScanSucceed() {
|
||||||
@ -554,6 +582,7 @@ class MyCentralManager(context: Context, binaryMessenger: BinaryMessenger) :
|
|||||||
mCharacteristics.clear()
|
mCharacteristics.clear()
|
||||||
mDescriptors.clear()
|
mDescriptors.clear()
|
||||||
|
|
||||||
|
mSetUpCallback = null
|
||||||
mStartDiscoveryCallback = null
|
mStartDiscoveryCallback = null
|
||||||
mConnectCallbacks.clear()
|
mConnectCallbacks.clear()
|
||||||
mDisconnectCallbacks.clear()
|
mDisconnectCallbacks.clear()
|
||||||
@ -566,6 +595,11 @@ class MyCentralManager(context: Context, binaryMessenger: BinaryMessenger) :
|
|||||||
mWriteDescriptorCallbacks.clear()
|
mWriteDescriptorCallbacks.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun mOnStateChanged(stateArgs: MyBluetoothLowEnergyStateArgs) {
|
||||||
|
val stateNumberArgs = stateArgs.raw.toLong()
|
||||||
|
mApi.onStateChanged(stateNumberArgs) {}
|
||||||
|
}
|
||||||
|
|
||||||
private fun mRetrieveCharacteristic(
|
private fun mRetrieveCharacteristic(
|
||||||
addressArgs: String, hashCodeArgs: Long
|
addressArgs: String, hashCodeArgs: Long
|
||||||
): BluetoothGattCharacteristic? {
|
): BluetoothGattCharacteristic? {
|
||||||
|
@ -19,7 +19,7 @@ import io.flutter.plugin.common.BinaryMessenger
|
|||||||
class MyPeripheralManager(context: Context, binaryMessenger: BinaryMessenger) :
|
class MyPeripheralManager(context: Context, binaryMessenger: BinaryMessenger) :
|
||||||
MyBluetoothLowEnergyManager(context), MyPeripheralManagerHostApi {
|
MyBluetoothLowEnergyManager(context), MyPeripheralManagerHostApi {
|
||||||
companion object {
|
companion object {
|
||||||
const val REQUEST_CODE = 444
|
const val REQUEST_CODE = 445
|
||||||
}
|
}
|
||||||
|
|
||||||
private val advertiser get() = adapter.bluetoothLeAdvertiser
|
private val advertiser get() = adapter.bluetoothLeAdvertiser
|
||||||
@ -89,9 +89,25 @@ class MyPeripheralManager(context: Context, binaryMessenger: BinaryMessenger) :
|
|||||||
override val requestCode: Int
|
override val requestCode: Int
|
||||||
get() = REQUEST_CODE
|
get() = REQUEST_CODE
|
||||||
|
|
||||||
override fun setUp() {
|
override fun setUp(callback: (Result<Unit>) -> Unit) {
|
||||||
mClearState()
|
try {
|
||||||
initialize()
|
mClearState()
|
||||||
|
val stateArgs = if (hasFeature) {
|
||||||
|
val granted = checkPermissions()
|
||||||
|
if (granted) {
|
||||||
|
registerReceiver()
|
||||||
|
adapter.state.toBluetoothLowEnergyStateArgs()
|
||||||
|
} else {
|
||||||
|
requestPermissions()
|
||||||
|
mSetUpCallback = callback
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else MyBluetoothLowEnergyStateArgs.UNSUPPORTED
|
||||||
|
mOnStateChanged(stateArgs)
|
||||||
|
callback(Result.success(Unit))
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
callback(Result.failure(e))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addService(serviceArgs: MyGattServiceArgs, callback: (Result<Unit>) -> Unit) {
|
override fun addService(serviceArgs: MyGattServiceArgs, callback: (Result<Unit>) -> Unit) {
|
||||||
@ -143,28 +159,45 @@ class MyPeripheralManager(context: Context, binaryMessenger: BinaryMessenger) :
|
|||||||
}
|
}
|
||||||
mAddServiceCallback = callback
|
mAddServiceCallback = callback
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
mClearService(serviceArgs)
|
|
||||||
callback(Result.failure(e))
|
callback(Result.failure(e))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun removeService(hashCodeArgs: Long) {
|
override fun removeService(hashCodeArgs: Long) {
|
||||||
val service = mServices[hashCodeArgs] as BluetoothGattService
|
val service = mServices.remove(hashCodeArgs) as BluetoothGattService
|
||||||
val hashCode = service.hashCode()
|
|
||||||
val serviceArgs = mServicesArgs[hashCode] as MyGattServiceArgs
|
|
||||||
val removed = mServer.removeService(service)
|
val removed = mServer.removeService(service)
|
||||||
if (!removed) {
|
if (!removed) {
|
||||||
throw IllegalStateException()
|
throw IllegalStateException()
|
||||||
}
|
}
|
||||||
mClearService(serviceArgs)
|
val hashCode = service.hashCode()
|
||||||
|
val serviceArgs = mServicesArgs.remove(hashCode) as MyGattServiceArgs
|
||||||
|
val characteristicsArgs = serviceArgs.characteristicsArgs.filterNotNull()
|
||||||
|
for (characteristicArgs in characteristicsArgs) {
|
||||||
|
val characteristicHashCodeArgs = characteristicArgs.hashCodeArgs
|
||||||
|
val characteristic =
|
||||||
|
mCharacteristics.remove(characteristicHashCodeArgs) as BluetoothGattCharacteristic
|
||||||
|
val characteristicHashCode = characteristic.hashCode()
|
||||||
|
mCharacteristicsArgs.remove(characteristicHashCode)
|
||||||
|
val descriptorsArgs = characteristicArgs.descriptorsArgs.filterNotNull()
|
||||||
|
for (descriptorArgs in descriptorsArgs) {
|
||||||
|
val descriptorHashCodeArgs = descriptorArgs.hashCodeArgs
|
||||||
|
val descriptor =
|
||||||
|
mDescriptors.remove(descriptorHashCodeArgs) as BluetoothGattDescriptor
|
||||||
|
val descriptorHashCode = descriptor.hashCode()
|
||||||
|
mDescriptorsArgs.remove(descriptorHashCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun clearServices() {
|
override fun clearServices() {
|
||||||
mServer.clearServices()
|
mServer.clearServices()
|
||||||
val servicesArgs = this.mServicesArgs.values
|
mServices.clear()
|
||||||
for (serviceArgs in servicesArgs) {
|
mCharacteristics.clear()
|
||||||
mClearService(serviceArgs)
|
mDescriptors.clear()
|
||||||
}
|
|
||||||
|
mServicesArgs.clear()
|
||||||
|
mCharacteristicsArgs.clear()
|
||||||
|
mDescriptorsArgs.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun startAdvertising(
|
override fun startAdvertising(
|
||||||
@ -235,14 +268,19 @@ class MyPeripheralManager(context: Context, binaryMessenger: BinaryMessenger) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStateChanged(state: MyBluetoothLowEnergyState) {
|
override fun onPermissionsRequested(granted: Boolean) {
|
||||||
when (state) {
|
val callback = mSetUpCallback ?: return
|
||||||
MyBluetoothLowEnergyStateArgs.POWEREDOFF -> mCloseGattServer()
|
val stateArgs = if (granted) {
|
||||||
MyBluetoothLowEnergyStateArgs.POWEREDON -> mOpenGattServer()
|
registerReceiver()
|
||||||
else -> {}
|
adapter.state.toBluetoothLowEnergyStateArgs()
|
||||||
}
|
} else MyBluetoothLowEnergyStateArgs.UNAUTHORIZED
|
||||||
val stateNumberArgs = state.raw.toLong()
|
mOnStateChanged(stateArgs)
|
||||||
mApi.onStateChanged(stateNumberArgs) {}
|
callback(Result.success(Unit))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onAdapterStateChanged(state: Int) {
|
||||||
|
val stateArgs = state.toBluetoothLowEnergyStateArgs()
|
||||||
|
mOnStateChanged(stateArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onServiceAdded(status: Int, service: BluetoothGattService) {
|
fun onServiceAdded(status: Int, service: BluetoothGattService) {
|
||||||
@ -253,9 +291,6 @@ class MyPeripheralManager(context: Context, binaryMessenger: BinaryMessenger) :
|
|||||||
} else {
|
} else {
|
||||||
val error = IllegalStateException("Read rssi failed with status: $status")
|
val error = IllegalStateException("Read rssi failed with status: $status")
|
||||||
callback(Result.failure(error))
|
callback(Result.failure(error))
|
||||||
val hashCode = service.hashCode()
|
|
||||||
val serviceArgs = mServicesArgs[hashCode] ?: return
|
|
||||||
mClearService(serviceArgs)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -403,7 +438,18 @@ class MyPeripheralManager(context: Context, binaryMessenger: BinaryMessenger) :
|
|||||||
mNotifyCharacteristicValueChangedCallbacks.clear()
|
mNotifyCharacteristicValueChangedCallbacks.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mOpenGattServer() {
|
private fun mOnStateChanged(stateArgs: MyBluetoothLowEnergyStateArgs) {
|
||||||
|
val stateNumberArgs = stateArgs.raw.toLong()
|
||||||
|
mApi.onStateChanged(stateNumberArgs) {}
|
||||||
|
// Renew GATT server when bluetooth adapter state changed.
|
||||||
|
when (stateArgs) {
|
||||||
|
MyBluetoothLowEnergyStateArgs.OFF -> mCloseServer()
|
||||||
|
MyBluetoothLowEnergyStateArgs.ON -> mOpenServer()
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun mOpenServer() {
|
||||||
if (mOpening) {
|
if (mOpening) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -411,32 +457,11 @@ class MyPeripheralManager(context: Context, binaryMessenger: BinaryMessenger) :
|
|||||||
mOpening = true
|
mOpening = true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mCloseGattServer() {
|
private fun mCloseServer() {
|
||||||
if (!mOpening) {
|
if (!mOpening) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mServer.close()
|
mServer.close()
|
||||||
mOpening = false
|
mOpening = false
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mClearService(serviceArgs: MyGattServiceArgs) {
|
|
||||||
val characteristicsArgs = serviceArgs.characteristicsArgs.filterNotNull()
|
|
||||||
for (characteristicArgs in characteristicsArgs) {
|
|
||||||
val descriptorsArgs = characteristicArgs.descriptorsArgs.filterNotNull()
|
|
||||||
for (descriptorArgs in descriptorsArgs) {
|
|
||||||
val descriptorHashCodeArgs = descriptorArgs.hashCodeArgs
|
|
||||||
val descriptor = mDescriptors.remove(descriptorHashCodeArgs) ?: continue
|
|
||||||
val descriptorHashCode = descriptor.hashCode()
|
|
||||||
mDescriptorsArgs.remove(descriptorHashCode)
|
|
||||||
}
|
|
||||||
val characteristicHashCodeArgs = characteristicArgs.hashCodeArgs
|
|
||||||
val characteristic = mCharacteristics.remove(characteristicHashCodeArgs) ?: continue
|
|
||||||
val characteristicHashCode = characteristic.hashCode()
|
|
||||||
mCharacteristicsArgs.remove(characteristicHashCode)
|
|
||||||
}
|
|
||||||
val serviceHashCodeArgs = serviceArgs.hashCodeArgs
|
|
||||||
val service = mServices.remove(serviceHashCodeArgs) ?: return
|
|
||||||
val serviceHashCode = service.hashCode()
|
|
||||||
mServicesArgs.remove(serviceHashCode)
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -15,7 +15,7 @@ packages:
|
|||||||
path: ".."
|
path: ".."
|
||||||
relative: true
|
relative: true
|
||||||
source: path
|
source: path
|
||||||
version: "5.0.0"
|
version: "5.0.1"
|
||||||
bluetooth_low_energy_platform_interface:
|
bluetooth_low_energy_platform_interface:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -14,7 +14,20 @@ export 'my_api.g.dart';
|
|||||||
// ToObject
|
// ToObject
|
||||||
extension MyBluetoothLowEnergyStateArgsX on MyBluetoothLowEnergyStateArgs {
|
extension MyBluetoothLowEnergyStateArgsX on MyBluetoothLowEnergyStateArgs {
|
||||||
BluetoothLowEnergyState toState() {
|
BluetoothLowEnergyState toState() {
|
||||||
return BluetoothLowEnergyState.values[index];
|
switch (this) {
|
||||||
|
case MyBluetoothLowEnergyStateArgs.unknown:
|
||||||
|
return BluetoothLowEnergyState.unknown;
|
||||||
|
case MyBluetoothLowEnergyStateArgs.unsupported:
|
||||||
|
return BluetoothLowEnergyState.unsupported;
|
||||||
|
case MyBluetoothLowEnergyStateArgs.unauthorized:
|
||||||
|
return BluetoothLowEnergyState.unauthorized;
|
||||||
|
case MyBluetoothLowEnergyStateArgs.off:
|
||||||
|
case MyBluetoothLowEnergyStateArgs.turningOn:
|
||||||
|
return BluetoothLowEnergyState.poweredOff;
|
||||||
|
case MyBluetoothLowEnergyStateArgs.on:
|
||||||
|
case MyBluetoothLowEnergyStateArgs.turningOff:
|
||||||
|
return BluetoothLowEnergyState.poweredOn;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,8 +29,10 @@ enum MyBluetoothLowEnergyStateArgs {
|
|||||||
unknown,
|
unknown,
|
||||||
unsupported,
|
unsupported,
|
||||||
unauthorized,
|
unauthorized,
|
||||||
poweredOff,
|
off,
|
||||||
poweredOn,
|
turningOn,
|
||||||
|
on,
|
||||||
|
turningOff,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum MyGattCharacteristicPropertyArgs {
|
enum MyGattCharacteristicPropertyArgs {
|
||||||
|
@ -15,8 +15,10 @@ enum MyBluetoothLowEnergyStateArgs {
|
|||||||
unknown,
|
unknown,
|
||||||
unsupported,
|
unsupported,
|
||||||
unauthorized,
|
unauthorized,
|
||||||
poweredOff,
|
off,
|
||||||
poweredOn,
|
turningOn,
|
||||||
|
on,
|
||||||
|
turningOff,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum MyGattCharacteristicPropertyArgs {
|
enum MyGattCharacteristicPropertyArgs {
|
||||||
@ -124,6 +126,7 @@ class MyGattServiceArgs {
|
|||||||
|
|
||||||
@HostApi()
|
@HostApi()
|
||||||
abstract class MyCentralManagerHostApi {
|
abstract class MyCentralManagerHostApi {
|
||||||
|
@async
|
||||||
void setUp();
|
void setUp();
|
||||||
@async
|
@async
|
||||||
void startDiscovery();
|
void startDiscovery();
|
||||||
@ -182,6 +185,7 @@ abstract class MyCentralManagerFlutterApi {
|
|||||||
|
|
||||||
@HostApi()
|
@HostApi()
|
||||||
abstract class MyPeripheralManagerHostApi {
|
abstract class MyPeripheralManagerHostApi {
|
||||||
|
@async
|
||||||
void setUp();
|
void setUp();
|
||||||
@async
|
@async
|
||||||
void addService(MyGattServiceArgs serviceArgs);
|
void addService(MyGattServiceArgs serviceArgs);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
name: bluetooth_low_energy_android
|
name: bluetooth_low_energy_android
|
||||||
description: Android implementation of the bluetooth_low_energy plugin.
|
description: Android implementation of the bluetooth_low_energy plugin.
|
||||||
version: 5.0.0
|
version: 5.0.2
|
||||||
homepage: https://github.com/yanshouwang/bluetooth_low_energy
|
homepage: https://github.com/yanshouwang/bluetooth_low_energy
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
Reference in New Issue
Block a user